Package org.jpokemon.pokemon

Source Code of org.jpokemon.pokemon.Pokemon

package org.jpokemon.pokemon;

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

import org.jpokemon.pokemon.move.Move;
import org.jpokemon.pokemon.move.MoveBlock;
import org.jpokemon.pokemon.stat.Stat;
import org.jpokemon.pokemon.stat.StatBlock;
import org.jpokemon.pokemon.stat.StatType;
import org.zachtaylor.jnodalxml.XmlException;
import org.zachtaylor.jnodalxml.XmlNode;

public class Pokemon {
  public static final String XML_NODE_NAME = "pokemon";

  public Pokemon(int num) {
    _number = num;
    _moves = new MoveBlock(_number);
    _species = PokemonInfo.get(_number);
    _stats = new StatBlock(_species);
  }

  public Pokemon(int num, int lvl) {
    this(num);
    _level = lvl;
    _stats.level(lvl);
    _moves.randomize(lvl);
  }

  public int number() {
    return _number;
  }

  public String name() {
    if (_name == null) return species();

    return _name;
  }

  public void name(String s) {
    _name = s;
  }

  public String species() {
    return _species.getName();
  }

  public int level() {
    return _level;
  }

  public int evolutionLevel() {
    return _species.getEvolutionlevel();
  }

  public int catchRate() {
    return _species.getCatchrate();
  }

  public void level(int l) {
    _level = l;
    _stats.level(l);

    checkNewMoves();

    conditionEffects = new ArrayList<ConditionEffect>();
  }

  public void incLevel() {
    // Truncate to tell if the next one crosses the whole number
    int thisLevelIncrement = (int) (level() / StatBlock.bonuslevelrate);
    int nextLevelIncrement = (int) (level() + 1 / StatBlock.bonuslevelrate);

    // Loop in case the difference is greater than 1
    while (nextLevelIncrement > thisLevelIncrement) {
      _stats.points(_stats.points() + 1);
      nextLevelIncrement--;
    }

    level(level() + 1);
  }

  public Type type1() {
    return Type.valueOf(_species.getType1());
  }

  public Type type2() {
    return Type.valueOf(_species.getType2());
  }

  public String getTrainerName() {
    return _ot;
  }

  public void setTrainerName(String s) {
    if (_ot != null)
      _hasOriginalTrainer = false;
    else {
      _hasOriginalTrainer = true;
      _ot = s;
    }
  }

  public boolean hasOriginalTrainer() {
    return _hasOriginalTrainer;
  }

  public int xp() {
    return _xp;
  }

  /**
   * Adds the xp specified to the Pokemon. If the Pokemon has enough, level is increased
   *
   * @param amount Amount of xp to add
   */
  public void xp(int amount) {
    int xpNeededAtLevel = xpNeededAtLevel();

    _xp += amount;

    while (_xp >= xpNeededAtLevel) {
      _xp -= xpNeededAtLevel;
      incLevel();
    }
  }

  /**
   * XP this Pokemon needs to level
   *
   * @return The amount of XP needed to gain a level
   */
  public int xpNeeded() {
    return xpNeededAtLevel() - xp();
  }

  public int xpYield() {
    return _species.getXpyield();
  }

  public Stat getStat(StatType s) {
    return _stats.get(s);
  }

  public int availableStatPoints() {
    return _stats.points();
  }

  public void statPoints(StatType s, int amount) {
    _stats.usePoints(s, amount);
  }

  public int health() {
    int val = getStat(StatType.HEALTH).cur();
    return val;
  }

  public int maxHealth() {
    return getStat(StatType.HEALTH).max();
  }

  public int attack() {
    return getStat(StatType.ATTACK).cur();
  }

  public int specattack() {
    return getStat(StatType.SPECATTACK).cur();
  }

  public int defense() {
    return getStat(StatType.DEFENSE).cur();
  }

  public int specdefense() {
    return getStat(StatType.SPECDEFENSE).cur();
  }

  public int speed() {
    return getStat(StatType.SPEED).cur();
  }

  public List<EffortValue> effortValues() {
    return _species.getEffortValues();
  }

  public void addEV(List<EffortValue> evs) {
    _stats.addEV(evs);
  }

  public Move move(int index) {
    return _moves.get(index);
  }

  public void addMove(int number) {
    _moves.add(number);
  }

  public int moveCount() {
    return _moves.count();
  }

  public void removeAllMoves() {
    _moves.removeAll();
  }

  /**
   * Takes a specified amount of damage. If damage is greater than available health, the Pokemon is knocked out.
   *
   * @param damage The amount of damage to be taken
   * @return the awake state of the Pokemon
   */
  public void takeDamage(int damage) {
    getStat(StatType.HEALTH).effect(-damage);
  }

  /**
   * Heals specified damage. If healed amount is greater than missing health, Pokemon is brought to full health.
   *
   * @param heal The amount healed by
   */
  public void healDamage(int heal) {
    getStat(StatType.HEALTH).effect(heal);
  }

  public boolean awake() {
    return health() > 0;
  }

  public void addConditionEffect(ConditionEffect e) {
    _stats.addConditionEffect(e);

    if (conditionEffects.contains(e)) {
      conditionEffects.remove(e);
    }

    conditionEffects.add(e);
  }

  public boolean hasConditionEffect(ConditionEffect e) {
    return conditionEffects.contains(e);
  }

  public List<ConditionEffect> getConditionEffects() {
    return conditionEffects;
  }

  public boolean removeConditionEffect(ConditionEffect e) {
    _stats.removeConditionEffect(e);
    return conditionEffects.remove(e);
  }

  public double catchBonus() {
    double best = 1;

    for (ConditionEffect e : conditionEffects) {
      best *= e.catchBonus();
    }

    return Math.min(best, 2.0);
  }

  /**
   * Changes a Pokemon into another one. This can be regular evolution (Charmander to Charmeleon) or other complicated changes (fire stone changes Eevee into
   * Flareon).
   */
  public void evolve(int... num) {
    if (num.length != 0)
      _number = num[0]; // special value
    else
      _number++;

    _moves.setPokemonNumber(_number);

    _species = PokemonInfo.get(_number);
    _stats.rebase(_species);

    checkNewMoves();
  }

  public XmlNode toXml() {
    XmlNode node = new XmlNode(XML_NODE_NAME);

    if (_name != null) {
      node.setAttribute("name", _name);
    }

    node.setAttribute("number", _number);
    node.setAttribute("level", _level);
    node.setAttribute("xp", _xp);
    node.setAttribute("ot", _ot);
    node.setAttribute("has_original_trainer", _hasOriginalTrainer);

    XmlNode conditionNode = new XmlNode("condition");
    conditionNode.setValue(conditionEffects.toString());
    node.addChild(conditionNode);

    node.addChild(_stats.toXml());
    node.addChild(_moves.toXml());

    return node;
  }

  public void loadXml(XmlNode node) {
    if (!XML_NODE_NAME.equals(node.getName())) throw new XmlException("Cannot read node");

    _name = node.getAttribute("name");
    _number = node.getIntAttribute("number");
    _moves.setPokemonNumber(_number);
    _species = PokemonInfo.get(_number);
    _stats.rebase(_species);

    _level = node.getIntAttribute("level");
    _stats.level(_level);

    _xp = node.getIntAttribute("xp");

    _ot = node.getAttribute("ot");

    _hasOriginalTrainer = node.getBoolAttribute("has_original_trainer");

    _moves.loadXml(node.getChildren(MoveBlock.XML_NODE_NAME).get(0));
    _stats.loadXml(node.getChildren(StatBlock.XML_NODE_NAME).get(0));

    String conditionString = node.getChildren("condition").get(0).getValue();
    if (conditionString != null) {
      for (String ce : conditionString.replace('[', ' ').replace(']', ' ').trim().split(",")) {
        if (ce.isEmpty()) {
          continue;
        }

        addConditionEffect(ConditionEffect.valueOf(ce.trim()));
      }
    }
  }

  private void checkNewMoves() {
    if (!_moves.newMoves(level()).isEmpty())
    ; // TODO : notify of new moves
  }

  private int xpNeededAtLevel() {
    GrowthRate rate = GrowthRate.valueOf(_species.getGrowthrate());

    return rate.xp(level());
  }

  @Override
  public boolean equals(Object o) {
    if (!(o instanceof Pokemon)) return false;

    Pokemon p = (Pokemon) o;

    if (number() != p.number()) return false;
    if (level() != p.level()) return false;
    if (xp() != p.xp()) return false;
    if (!name().equals(p.name())) return false;
    // Probably good enough...

    return true;
  }

  @Override
  public int hashCode() {
    return (name().hashCode() & 255) + _number + _level;
  }

  private MoveBlock _moves;
  private StatBlock _stats;
  private String _name, _ot;
  private PokemonInfo _species;
  private int _number, _level, _xp;
  private boolean _hasOriginalTrainer;
  private List<ConditionEffect> conditionEffects = new ArrayList<ConditionEffect>();
}
TOP

Related Classes of org.jpokemon.pokemon.Pokemon

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.