Package games.stendhal.server.entity.npc.behaviour.impl

Source Code of games.stendhal.server.entity.npc.behaviour.impl.TeleporterBehaviour

// $Id: TeleporterBehaviour.java,v 1.3 2011/04/06 22:04:11 kymara Exp $
package games.stendhal.server.entity.npc.behaviour.impl;

import games.stendhal.common.Direction;
import games.stendhal.common.Rand;
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.pathfinder.FixedPath;
import games.stendhal.server.core.pathfinder.Node;
import games.stendhal.server.core.pathfinder.Path;
import games.stendhal.server.entity.npc.ConversationStates;
import games.stendhal.server.entity.npc.SpeakerNPC;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import marauroa.common.game.IRPZone;

import org.apache.log4j.Logger;

/**
* teleports the SpeakerNPC to a random location on the outside world and causes
* it to walk a random path
*
* @author hendrik
*/
public class TeleporterBehaviour implements TurnListener {

  private static Logger logger = Logger.getLogger(TeleporterBehaviour.class);

  private StendhalRPZone zone;

  private ArrayList<StendhalRPZone> zones;

  private final SpeakerNPC speakerNPC;
  private final String repeatedText;
 
  /**
   * Creates a new TeleporterBehaviour.
   *
   * @param speakerNPC
   *            SpeakerNPC
   * @param repeatedText
   *            text to repeat
   */
  public TeleporterBehaviour(final SpeakerNPC speakerNPC,
      final String repeatedText) {
    this.speakerNPC = speakerNPC;
    this.repeatedText = repeatedText;
    listZones();
    SingletonRepository.getTurnNotifier().notifyInTurns(60, this);
    // say something every minute so that can be noticed more easily
    SingletonRepository.getTurnNotifier().notifyInTurns(60, new TurnListener() {

      public void onTurnReached(final int currentTurn) {
        doRegularBehaviour();
        SingletonRepository.getTurnNotifier().notifyInTurns(60 * 3, this);
      }
    });
  }

  /**
   * Creates a new TeleporterBehaviour.
   *
   * @param speakerNPC
   *            SpeakerNPC
   * @param repeatedText
   *            text to repeat
   * @param useHighProbabilityZones
   *            true to make teleportation to a hand
   *            selected list of zones more likely
   */
  public TeleporterBehaviour(final SpeakerNPC speakerNPC, final String repeatedText, final boolean useHighProbabilityZones) {
    this(speakerNPC, repeatedText);
    if (useHighProbabilityZones) {
      addHighProbability();
    }
  }

  protected void doRegularBehaviour() {
    speakerNPC.say(repeatedText);
  }
 
  private void addHighProbability() {
    final StendhalRPWorld world = SingletonRepository.getRPWorld();
    for (int i = 0; i < 10; i++) {
      zones.add(world.getZone("0_semos_city"));
      zones.add(world.getZone("0_semos_village_w"));
      zones.add(world.getZone("0_semos_plains_n"));
      zones.add(world.getZone("0_semos_plains_ne"));
      zones.add(world.getZone("0_semos_road_e"));
      zones.add(world.getZone("0_semos_plains_s"));
    }
  }

  /**
   * Creates an ArrayList of "outside" zones for NPC.
   */
  private void listZones() {
    final Iterator<IRPZone> itr = SingletonRepository.getRPWorld().iterator();
    zones = new ArrayList<StendhalRPZone>();
    final List<String> badZones = new ArrayList<String>();
    // the following are too dangerous
    badZones.add("0_nalwor_city");
    badZones.add("0_orril_castle");
    badZones.add("0_ados_swamp");
    badZones.add("0_ados_outside_w");
    badZones.add("0_ados_wall_n");
    // the following have historically been very hard to find a path in
    badZones.add("0_ados_city_n")
    badZones.add("0_ados_ocean_e");
    badZones.add("0_athor_island_w");
    badZones.add("0_nalwor_forest_n");
    badZones.add("0_nalwor_river_s");
    while (itr.hasNext()) {
      final StendhalRPZone aZone = (StendhalRPZone) itr.next();
      final String zoneName = aZone.getName();
      if (zoneName.startsWith("0") && !badZones.contains(zoneName)) {
        zones.add(aZone);
      }
    }
  }

  public void onTurnReached(final int currentTurn) {
    if (speakerNPC.getEngine().getCurrentState() != ConversationStates.IDLE) {
      speakerNPC.say("Bye.");
      speakerNPC.setCurrentState(ConversationStates.IDLE);
    }
    // remove NPC from old zone
    zone = speakerNPC.getZone();
    zone.remove(speakerNPC);

    // Teleport to another random place
    boolean found = false;
    int x = -1;
    int y = -1;
    while (!found) {
      zone = zones.get(Rand.rand(zones.size()));
      x = Rand.rand(zone.getWidth() - 4) + 2;
      y = Rand.rand(zone.getHeight() - 5) + 2;
      if (!zone.collides(x, y) && !zone.collides(x, y + 1)) {
        speakerNPC.setPosition(x, y);
        speakerNPC.setDirection(Direction.RIGHT);

        zone.add(speakerNPC);
        found = true;
        logger.debug("Placing teleporting NPC at " + zone.getName()
            + " " + x + " " + y);
      } else {
        logger.info("Cannot place teleporting NPC " + speakerNPC.getName() + " at " + zone.getName()
            + " " + x + " " + y);
      }
    }

    // try to build a path (but give up after 10 failed tries)
    for (int i = 0; i < 10; i++) {
      final int tx = Rand.rand(zone.getWidth() - 4) + 2;
      final int ty = Rand.rand(zone.getHeight() - 5) + 2;
      final List<Node> path = Path.searchPath(speakerNPC, tx, ty);
      if ((path != null) && (path.size() > 1)) {
        // create path back
        for (int j = path.size() - 1; j > 0; j--) {
          path.add(path.get(j));
        }
        logger.debug(path);
        speakerNPC.setPath(new FixedPath(path, true));
        break;
      }
    }

    // Schedule so we are notified again in 5 minutes
    SingletonRepository.getTurnNotifier().notifyInTurns(5 * 60 * 3, this);
  }
}
TOP

Related Classes of games.stendhal.server.entity.npc.behaviour.impl.TeleporterBehaviour

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.