Package games.stendhal.server.script

Source Code of games.stendhal.server.script.Unblock$KeepFreeArea

/* $Id: Unblock.java,v 1.9 2010/12/20 22:01:25 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.script;

import games.stendhal.common.Direction;
import games.stendhal.server.core.engine.SingletonRepository;
import games.stendhal.server.core.engine.StendhalRPWorld;
import games.stendhal.server.core.engine.StendhalRPZone;
import games.stendhal.server.core.events.TurnListener;
import games.stendhal.server.core.events.TurnNotifier;
import games.stendhal.server.core.scripting.ScriptImpl;
import games.stendhal.server.entity.player.Player;
import games.stendhal.server.util.Area;

import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

/**
* Moves players away that spend to much time in an restricted area
*
* @author hendrik
*/
public class Unblock extends ScriptImpl implements TurnListener {
  private static final int CHECK_INTERVAL = 10;
  private static final int GRACE_PERIOD_IN_TURNS = 200;
  private Set<PlayerPositionEntry> playerPositions = new HashSet<PlayerPositionEntry>();
  private Set<KeepFreeArea> keepFreeAreas = new HashSet<KeepFreeArea>();
 
  /**
   * records a player position in a specific turn
   */
  static class PlayerPositionEntry {
    private String playerName;
    private String zoneName;
    private int x;
    private int y;
    private int turn;
    private KeepFreeArea keepFreeArea;

    /**
     * creates a new PlayerPositionEntry
     *
     * @param player Player
     * @param keepFreeArea area to keep free
     */
    public PlayerPositionEntry(Player player, KeepFreeArea keepFreeArea) {
      super();
      this.playerName = player.getName();
      this.zoneName = player.getZone().getName();
      this.x = player.getX();
      this.y = player.getY();
      this.turn = SingletonRepository.getRuleProcessor().getTurn();
      this.keepFreeArea = keepFreeArea;
    }

    @Override
    public int hashCode() {
      final int prime = 31;
      int result = 1;
      result = prime * result+ playerName.hashCode();
      result = prime * result + x;
      result = prime * result + y;
      result = prime * result + zoneName.hashCode();
      return result;
    }

    @Override
    public boolean equals(Object obj) {
      if (obj == null) {
        return false;
      }
      if (!(obj instanceof PlayerPositionEntry)) {
        return false;
      }
      PlayerPositionEntry other = (PlayerPositionEntry) obj;
      if (!playerName.equals(other.playerName)) {
        return false;
      }
      if (x != other.x) {
        return false;
      }
      if (y != other.y) {
        return false;
      }
      if (!zoneName.equals(other.zoneName)) {
        return false;
      }
      return true;
    }

    /**
     * has the player moved away including leaving the zone or logging out
     *
     * @return true if the player moved away, false if he is still in the restricted area
     */
    public boolean hasPlayerMovedAway() {
      Player player = SingletonRepository.getRuleProcessor().getPlayer(playerName);
      if (player == null) {
        return true;
      }
      if (!player.getZone().getName().equals(zoneName)) {
        return true;
      }
      if (player.getX() != x) {
        return true;
      }
      if (player.getY() != y) {
        return true;
      }
      return false;
    }

    /**
     * gets the turn this entry was created
     *
     * @return turn
     */
    public int getTurn() {
      return turn;
    }

    /**
     * gets the KeepFreeArea
     *
     * @return KeepFreeArea
     */
    public KeepFreeArea getKeepFreeArea() {
      return keepFreeArea;
    }

    /**
     * gets the Player
     *
     * @return player or <code>null</code> in case the player logged out
     */
    public Player getPlayer() {
      return SingletonRepository.getRuleProcessor().getPlayer(playerName);
    }
  }

  /**
   * an area to keep free with an associated teleportation target spot
   */
  static class KeepFreeArea {
    private Area area;
    private int x;
    private int y;

    /**
     * creates a new KeepFreeArea
     *
     * @param area area to keep free
     * @param x teleportation target x
     * @param y teleportation target y
     */
    public KeepFreeArea(Area area, int x, int y) {
      super();
      this.area = area;
      this.x = x;
      this.y = y;
    }

    /**
     * gets a list of players who are within the restricted area
     *
     * @return list of players
     */
    public List<Player> getPlayers() {
      return area.getPlayers();
    }

    /**
     * gets the teleportation target x
     *
     * @return teleportation target x
     */
    public int getX() {
      return x;
    }

    /**
     * gets the teleportation target y
     *
     * @return teleportation target y
     */
    public int getY() {
      return y;
    }

    /**
     * gets the zone
     *
     * @return StendhalRPZone
     */
    public StendhalRPZone getZone() {
      return area.getZone();
    }
  }

  /**
   * checks
   */
  public void onTurnReached(int currentTurn) {
    TurnNotifier.get().notifyInSeconds(CHECK_INTERVAL, this);
    cleanupList();
    teleportAway(currentTurn);
    record();
  }

  /**
   * removes players that have moved away from the list
   */
  private void cleanupList() {
    Iterator<PlayerPositionEntry> itr = playerPositions.iterator();
    while (itr.hasNext()) {
      PlayerPositionEntry entry = itr.next();
      if (entry.hasPlayerMovedAway()) {
        itr.remove();
      }
    }
   
  }


  /**
   * teleports players out of the restricted area
   *
   * @param turn current turn
   */
  private void teleportAway(int turn) {
    Iterator<PlayerPositionEntry> itr = playerPositions.iterator();
    while (itr.hasNext()) {
      PlayerPositionEntry entry = itr.next();
      if (entry.getTurn() + GRACE_PERIOD_IN_TURNS < turn) {
        itr.remove();
        KeepFreeArea keepFreeArea = entry.getKeepFreeArea();
        Player player = entry.getPlayer();
        if (player == null) {
          continue;
        }
        player.teleport(keepFreeArea.getZone(), keepFreeArea.getX(), keepFreeArea.getY(), Direction.DOWN, player);
      }
    }
  }

  /**
   * recors players who are within the restricted zone.
   */
  private void record() {
    for (KeepFreeArea keepFreeArea : keepFreeAreas) {
      for (Player player : keepFreeArea.getPlayers()) {
        // we do something dirty here with hashCode and equals (turn is ignored)
        PlayerPositionEntry entry = new PlayerPositionEntry(player, keepFreeArea);
        if (!playerPositions.contains(entry)) {
          playerPositions.add(entry);
        }
      }
    }
   
  }

  /**
   * executes the script
   */
  @Override
  public void execute(Player admin, List<String> args) {
    super.execute(admin, args);
    TurnNotifier.get().dontNotify(this);

    StendhalRPWorld world = SingletonRepository.getRPWorld();

    // bank entrance
    keepFreeAreas.add(new KeepFreeArea(new Area(world.getZone("0_semos_city"), 17, 23, 3, 2), 23, 25));

    // bank exit
    keepFreeAreas.add(new KeepFreeArea(new Area(world.getZone("int_semos_bank"), 8, 28, 11, 29), 24, 27));

    // inn entrance
    keepFreeAreas.add(new KeepFreeArea(new Area(world.getZone("0_semos_city"), 40, 38, 4, 3), 50, 40));

    // inn exit
    keepFreeAreas.add(new KeepFreeArea(new Area(world.getZone("int_semos_tavern_0"), 21, 15, 3, 2), 22, 11));

    TurnNotifier.get().notifyInSeconds(CHECK_INTERVAL, this);
  }

  @Override
  public void unload(Player admin, List<String> args) {
    super.unload(admin, args);
    TurnNotifier.get().dontNotify(this);
  }

}
TOP

Related Classes of games.stendhal.server.script.Unblock$KeepFreeArea

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.