Package games.stendhal.server.maps.semos.plains

Source Code of games.stendhal.server.maps.semos.plains.CreatureInfo

/* $Id: CreatureInfo.java,v 1.25 2011/04/02 15:44:20 kymara 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.maps.semos.plains;

import games.stendhal.common.Rand;
import games.stendhal.common.grammar.Grammar;
import games.stendhal.server.core.engine.SingletonRepository;
import games.stendhal.server.core.engine.StendhalRPZone;
import games.stendhal.server.core.rule.defaultruleset.DefaultCreature;
import games.stendhal.server.entity.creature.Creature;
import games.stendhal.server.entity.creature.impl.DropItem;
import games.stendhal.server.entity.mapstuff.spawner.CreatureRespawnPoint;
import games.stendhal.server.entity.player.Player;
import games.stendhal.server.util.TimeUtil;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Map.Entry;

import marauroa.common.game.IRPZone;

public class CreatureInfo {

  private final Map<Double, String> probabilityLiterals;

  private final Map<Integer, String> amountLiterals;

  private final Map<Double, String> dangerLiterals;

  private final String[] lineStartTexts;

  private final String[] respawnTexts;

  private final String[] carryTexts;

  private final String[] carryNothingTexts;

  private final String[] locationTexts;

  private final String[] locationUnknownTexts;

  /**
   * The zonenames that are not listed as the creature locations.
   */
  private static final List<String> skippedZoneNames = Arrays.asList(new String[] {
      "int_admin_playground", "int_pathfinding" });

  /**
   * Create an instance of creatureInfo.
   *
   * @param probabilityLiterals
   *            templates for probabilities. %s is replaced with item
   *            description (name and amount)
   * @param amountLiterals
   *            templates for item amounts. %s is replaced with singular item
   *            name, %a with "a/an item name" depending on the item name
   * @param dangerLiterals
   *            templates for how dangerous a creature is based on the
   *            percentual difference to player level. %s is replaced with
   *            singular creature name, %S with plural
   * @param lineStartTexts
   *            templates for line starts. %s is replaced with singular
   *            creature name, %S plural
   * @param respawnTexts
   *            templates for respawn texts. %1 = time to respawn.
   * @param carryTexts
   *            templates for drops. %1 = list of items dropped.
   * @param carryNothingTexts
   *            templates for no drops.
   * @param locationTexts
   *            templates for creature locations. %1 = list of locations
   * @param locationUnknownTexts
   *            templates for unknown location. %1 = name of the creature
   */
  public CreatureInfo(final Map<Double, String> probabilityLiterals,
      final Map<Integer, String> amountLiterals,
      final Map<Double, String> dangerLiterals, final String[] lineStartTexts,
      final String[] respawnTexts, final String[] carryTexts,
      final String[] carryNothingTexts, final String[] locationTexts,
      final String[] locationUnknownTexts) {
    this.probabilityLiterals = probabilityLiterals;
    this.amountLiterals = amountLiterals;
    this.dangerLiterals = dangerLiterals;
    this.lineStartTexts = lineStartTexts.clone();
    this.respawnTexts = respawnTexts.clone();
    this.carryTexts = carryTexts.clone();
    this.carryNothingTexts = carryNothingTexts.clone();
    this.locationTexts = locationTexts.clone();
    this.locationUnknownTexts = locationUnknownTexts.clone();
  }

  /**
   * get information on a creature.
   *
   * @param player
   * @param creature
   * @param maxLocations
   *            max number of locations listed
   * @param maxDrops
   * @param respawn
   * @return string containing creature information
   */
  public String getCreatureInfo(final Player player,
      final DefaultCreature creature, final int maxLocations, final int maxDrops,
      final boolean respawn) {
    if (player == null) {
      throw new IllegalArgumentException("player is null");
    }
    if (creature == null) {
      throw new IllegalArgumentException("creature is null");
    }
    String dropInfo;
    if (maxDrops <= 0) {
      dropInfo = "";
    } else {
      dropInfo = getDropItemsInfo(creature,
          maxDrops);
    }
    String locationInfo;
    if (maxLocations <= 0) {
      locationInfo = "";
    } else {
      locationInfo = getLocationInfo(
          creature.getCreatureName(), maxLocations);
    }
    String respawnInfo;
    if (respawn) {
      respawnInfo = getRespawnInfo(creature);
    } else {
      respawnInfo = "";
    }
    StringBuilder result = new StringBuilder(getCreatureBasicInfo(player, creature));
    if (respawn) {
      if (respawnInfo != null && respawnInfo.length() > 0) {
        result.append(getRandomString(respawnTexts, respawnInfo)).append(' ');
      }
    }
    if (maxDrops > 0) {
      if (dropInfo != null && dropInfo.length() > 0) {
        result.append(getRandomString(carryTexts, dropInfo)).append(' ');
      } else {
        result.append(getRandomString(carryNothingTexts)).append(' ');
      }
    }
    if (maxLocations > 0) {
      if (locationInfo != null && locationInfo.length() > 0) {
        result.append(getRandomString(locationTexts, locationInfo)).append(' ');
      } else {
        result.append(getRandomString(locationUnknownTexts,
            Grammar.a_noun(creature.getCreatureName()))).append(' ');
      }
    }
    return result.toString();
  }

  /**
   * get the approximate respawn time of a creature.
   *
   * @param creature
   * @return a string representing the next respawntime of a creature
   */
  private String getRespawnInfo(final DefaultCreature creature) {
    return TimeUtil.approxTimeUntil((int) (creature.getRespawnTime() * 0.3));
  }

  /**
   * get creature respawn locations.
   *
   * @param creatureName
   * @param maxNumberOfLocations
   *            how many (most frequent) respawn locations are listed
   * @return a string containing the names of the zones
   */
  private String getLocationInfo(final String creatureName, final int maxNumberOfLocations) {
    String prefix = "";
    final Map<String, Integer> zoneCounts = getCreatureZoneCounts(creatureName);
    final Set<String> places = new HashSet<String>();
    int counter = 0;
    for (final Map.Entry<String, Integer> entry : zoneCounts.entrySet()) {
      if (!skippedZoneNames.contains(entry.getKey())) {
        final String placeName = StendhalRPZone.describe(entry.getKey());
        if (placeName != null && placeName.length() > 0) {
          places.add(placeName);
        }
        if (++counter >= maxNumberOfLocations) {
          prefix = "for example ";
          break;
        }
      }
    }
    if (places.isEmpty()) {
      return "";
    } else {
      return prefix + " "
          + Grammar.enumerateCollection(places);
    }
  }

  /**
   * get the count of specified creature for all zones.
   *
   * @param creatureName
   * @return map of zonenames with creature counts
   */
  public Map<String, Integer> getCreatureZoneCounts(final String creatureName) {
    final Map<String, Integer> zoneCounts = new HashMap<String, Integer>();

    /* count creatures for each zone */
    for (final IRPZone zone : SingletonRepository.getRPWorld()) {
      for (final CreatureRespawnPoint p : ((StendhalRPZone) zone).getRespawnPointList()) {
        final Creature c = p.getPrototypeCreature();
        if (creatureName.equals(c.getName())) {
          final String zoneName = zone.getID().getID();
          if (zoneCounts.containsKey(zoneName)) {
            zoneCounts.put(zoneName, zoneCounts.get(zoneName) + 1);
          } else {
            zoneCounts.put(zoneName, 1);
          }
        }
      }
    }
    return zoneCounts;
  }

  /**
   * Get basic information of the creature: initial string + how dangerous the
   * creature is.
   *
   * @param player
   * @param creature
   * @return basic information about the creature.
   */
  public String getCreatureBasicInfo(final Player player,
      final DefaultCreature creature) {
    if (creature == null) {
      throw new IllegalArgumentException("creature is null");
    }
    String result = lineStartTexts[(int) (Math.random() * lineStartTexts.length)];
    result = result.replaceAll("%s", creature.getCreatureName());
    result = result.replaceAll("%S",
        Grammar.plural(creature.getCreatureName()));
    result = result.replaceAll("%a",
        Grammar.a_noun(creature.getCreatureName()))
        + " ";
    result += getHowDangerous(player, creature, dangerLiterals) + " ";
    return result;
  }

  /**
   * Get verbal presentation of how dangerous the creature is to the player.
   *
   * @param player
   * @param creature
   * @param dangerLiterals
   *            lookup table (map) for texts: formula for key value is
   *            creature level / player level. Text replacements: %s is
   *            replaced with creature name; %S is replaced with plural
   *            creature name.
   * @return verbal presentation of how dangerous the creature is to player.
   */
  public String getHowDangerous(final Player player, final DefaultCreature creature,
      final Map<Double, String> dangerLiterals) {
    String s = getLiteral(dangerLiterals,
        ((double) creature.getLevel())
            / ((double) player.getLevel()), 0.0);
    s = s.replaceAll("%s", creature.getCreatureName());
    s = s.replaceAll("%S", Grammar.plural(creature.getCreatureName()));
    return s.substring(0, 1).toUpperCase() + s.substring(1);
  }

  /**
   * Get verbal presentation of the items dropped by given creature.
   *
   * @param creature
   * @param maxNumberOfItems
   *            maximum number of items with most frequent drops first
   * @return string of the items dropped by given creature.
   */
  private String getDropItemsInfo(final DefaultCreature creature,
      final int maxNumberOfItems) {
    final StringBuilder result = new StringBuilder();
    final List<DropItem> dropItems = creature.getDropItems();
    Collections.sort(dropItems, new Comparator<DropItem>() {
      public int compare(final DropItem o1, final DropItem o2) {
        if (o1.probability < o2.probability) {
          return 1;
        } else if (o1.probability > o2.probability) {
          return -1;
        } else {
          return 0;
        }
      }
    });
    List<String> items = new ArrayList<String>();
    String prevProbability = null;
    int counter = 0;
    String prefix = "";
    for (final DropItem item : dropItems) {
      final String probability = getLiteral(probabilityLiterals, item.probability, 0.0);

      if (prevProbability != null && !probability.equals(prevProbability)) {
        if (result.length() > 0) {
          result.append(", ");
        }
       
        prevProbability = prevProbability.replaceAll("%s",
            Grammar.enumerateCollection(items));
        prevProbability = prevProbability.replaceAll("%a",
            Grammar.a_noun(item.name));
        result.append(prevProbability);
        items = new ArrayList<String>();
      }
      String s = getLiteral(amountLiterals, item.max, 1);
      s = s.replaceAll("%s", item.name);
      s = s.replaceAll("%a", Grammar.a_noun(item.name));
      items.add(s);
      prevProbability = probability;
      if (++counter >= maxNumberOfItems) {
        prefix = "for example ";
        break;
      }
    }

    if (result.length() > 0) {
      result.append(", ");
    }
    if (prevProbability != null) {
      result.append(prevProbability.replaceAll("%s",
          Grammar.enumerateCollection(items)));
    }

    return (prefix + result.toString()).replaceAll("_", " ");
  }

  /**
   * Utility method for returning a random string from array of strings.
   *
   * @param texts
   * @param params
   * @return string chosen
   */
  private String getRandomString(final String[] texts, final String... params) {
    String result = Rand.rand(texts);
    if (params != null) {
      for (int i = 0; i < params.length; i++) {
        result = result.replaceAll("%" + (i + 1), params[i]);
      }
    }
    return result;
  }

  /**
   * utility method for turning numeric value into a literal string from a
   * list.
   * @param <T>
   *
   * @param literals
   *            map of the literal strings
   * @param val
   *            the numeric value
   * @param defValue
   *            numeric value if given value is out of bounds
   * @return a literal string
   */
  private <T extends Number> String getLiteral(final Map<T, String> literals,
      final T val, final T defValue) {
    String result = literals.get(defValue);
    for (final Entry<T, String> entry  : literals.entrySet()) {
      if (entry.getKey().doubleValue() <= val.doubleValue()) {
        result = entry.getValue();
        break;
      }
    }
    return result;
  }
}
TOP

Related Classes of games.stendhal.server.maps.semos.plains.CreatureInfo

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.