Package org.jpokemon.pokemon.move

Source Code of org.jpokemon.pokemon.move.Move

package org.jpokemon.pokemon.move;

import org.jpokemon.battle.slot.Slot;
import org.jpokemon.pokemon.Pokemon;
import org.jpokemon.pokemon.Type;
import org.jpokemon.pokemon.move.effect.MoveEffect;
import org.zachtaylor.jnodalxml.XmlException;
import org.zachtaylor.jnodalxml.XmlNode;

public class Move {
  public static final String XML_NODE_NAME = "move";

  public Move(int number) {
    setNumber(number);
  }

  /**
   * Tells the number of this Move
   *
   * @return Number used to identify this Move
   */
  public int number() {
    return _info.getNumber();
  }

  /**
   * Tells the name of this Move
   *
   * @return What people call this Move
   */
  public String name() {
    return _info.getName();
  }

  /**
   * Tells the power of this Move, as relevant to the MoveStyle
   *
   * @return The power of the Move, as applicable
   */
  public int power() {
    return _info.getPower();
  }

  /**
   * Tells the current available pp of this Move
   *
   * @return
   */
  public int pp() {
    return _pp;
  }

  /** Getter for the max pp of this move */
  public int ppMax() {
    return _ppMax;
  }

  /**
   * Tells the accuracy of this Move
   *
   * @return Number between 0 and 1 which represents the chance that this move will be effectively executed
   */
  public double accuracy() {
    return _info.getAccuracy();
  }

  /**
   * Tells the MoveStyle of this Move
   *
   * @return This Move's MoveStyle
   */
  public MoveStyle style() {
    return _style;
  }

  /**
   * Tells the Type of this Move
   *
   * @return This Move's Type
   */
  public Type type() {
    return _type;
  }

  /**
   * Tells the number of Turns it takes to fully execute this Move
   *
   * @return The number of times this move must be reAdded
   */
  public int turns() {
    if (style() == MoveStyle.DELAYNEXT || style() == MoveStyle.DELAYBEFORE) return 2;
    // TODO : add bide

    return 1;
  }

  /**
   * Tells whether this Move is enabled, and has sufficient PP to be used
   *
   * @return If this move can be used
   */
  public boolean enabled() {
    return _enabled & _pp > 0;
  }

  /**
   * Sets the enabled status of the Move, independent of any available PP
   *
   * @param b New usability status of this Move
   */
  public void enable(boolean b) {
    _enabled = b;
  }

  /**
   * Fully mutate this Move to a new instance of the specified number.
   *
   * @param number New move number
   */
  public void setNumber(int number) {
    if (number == -1) {
      _info = null;
    }
    else {
      _info = MoveInfo.get(number);
      _pp = _ppMax = _info.getPp();
      _type = Type.valueOf(_info.getType());
      _style = MoveStyle.valueOf(_info.getStyle());
    }
    _enabled = number > 0;
  }

  /**
   * Restores the PP of this Move to the maximum value, and removes any disabling effects
   */
  public void restore() {
    _pp = _ppMax;
    _enabled = true;
  }

  /**
   * An atomic way to test the accuracy and decrease the PP of a move
   *
   * @return If the move is used successfully
   */
  public boolean use() {
    boolean success = enabled() & accuracy() >= Math.random();

    if (success) _pp--;

    return success;
  }

  /**
   * Tells the Same Type Attack Bonus of the Move.<br />
   * <br />
   * This is 1.5 if the move is compatible with the given types, or 1.0 if not
   *
   * @param p Pokemon to check the types of, for a match
   * @return Modifier for the strength of the move, given the possibly matched types
   */
  public double STAB(Pokemon p) {
    return STAB(p.type1(), p.type2());
  }

  /**
   * Tells the Same Type Attack Bonus of the Move.<br />
   * <br />
   * This is 1.5 if the move is compatible with the given types, or 1.0 if not
   *
   * @param t1 First type which may match
   * @param t2 Second type which may match
   * @return Modifier for the strength of the move, given the possibly matched types
   */
  public double STAB(Type t1, Type t2) {
    Type type = type();
    return type == t1 || type == t2 ? 1.5 : 1.0;
  }

  /**
   * Tells the number of random number of repetitions a move has, if applicable
   *
   * @return Number of times this move strikes simultaneously
   */
  public int reps() {
    if (style() != MoveStyle.REPEAT) return 1;

    double chance = Math.random();
    if (chance >= 0.9947916667) // 1/192
      return 5;
    else if (chance >= 0.9583333333) // 1/24
      return 4;
    else if (chance >= 0.6666666667) // 1 / 3
      return 3;
    else
      return 2; // no luck
  }

  /**
   * Applies any additional effects of this Move to the appropriate Target
   *
   * @param user User of the move
   * @param target Victim of the move
   */
  public void applyEffects(Slot user, Slot target, int damage) {
    for (MoveEffect effect : _info.getEffects())
      effect.effect(user, target, damage);
  }

  /**
   * Tells whether the user of the move should be hurt if the move misses
   *
   * @return True if this move penalizes the user for missing
   */
  public boolean hurtUserOnMiss() {
    return (number() == 60 || number() == 69);
  }

  /**
   * Tells whether this move will cause damage to a target
   *
   * @return True if the target's health is lowered as a consequence of the Move
   */
  public boolean doesDamage() {
    return style() != MoveStyle.STATUS;
  }

  public boolean damageIsAbsolute() {
    // TODO : add dragon rage, bide
    return false;
  }

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

    node.setAttribute("number", number());
    node.setAttribute("pp", _pp);
    node.setAttribute("ppmax", _ppMax);
    node.setAttribute("enabled", _enabled);
    node.setSelfClosing(true);

    return node;
  }

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

    setNumber(Integer.parseInt(node.getAttribute("number")));
    _ppMax = node.getIntAttribute("ppmax");
    _pp = node.getIntAttribute("pp");
  }

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

    Move m = (Move) o;

    return _info == m._info && _ppMax == m._ppMax;
  }

  public int hashCode() {
    return _type.ordinal() * 1375 + _style.ordinal() * 71;
  }

  private Type _type;
  private MoveInfo _info;
  private int _pp, _ppMax;
  private boolean _enabled;
  private MoveStyle _style;
}
TOP

Related Classes of org.jpokemon.pokemon.move.Move

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.