Package org.pokenet.server.battle.mechanics

Source Code of org.pokenet.server.battle.mechanics.AdvanceMechanics

package org.pokenet.server.battle.mechanics;

import org.pokenet.server.battle.BattleField;
import org.pokenet.server.battle.Pokemon;
import org.pokenet.server.battle.mechanics.moves.MoveList;
import org.pokenet.server.battle.mechanics.moves.PokemonMove;
import org.pokenet.server.battle.mechanics.statuses.StatChangeEffect;
import org.pokenet.server.battle.mechanics.statuses.field.FieldEffect;

/**
* This class represents the mechanics in the advanced generation of pokemon.
* @author Colin
*/
public class AdvanceMechanics extends BattleMechanics {
   
    private static final long serialVersionUID = -2238204671194997172L;
    @SuppressWarnings("unused")
  private static int m_log = 0;
   
    /** Creates a new instance of AdvanceMechanics */
    public AdvanceMechanics(int bytes) {
        super(bytes);
    }
   
    public int calculateStat(Pokemon p, int i) throws StatException {
        if ((i < 0) || (i > 5)) throw new StatException();
        int common =
                (int)((int)(((2.0 * p.getBase(i))
                + p.getIv(i)
                + (p.getEv(i) / 4.0)))
                * (p.getLevel() / 100.0));
        if (i == Pokemon.S_HP) {
            if (p.getSpeciesName().equals("Shedinja")) {
                // Shedinja always has 1 hp.
                return 1;
            } else {
                return common + 10 + p.getLevel();
            }
        }
        return (int)((common + 5) * p.getNature().getEffect(i));
    }
   
    /**
     * Return whether the move hit.
     */
    public boolean attemptHit(PokemonMove move, Pokemon user, Pokemon target) {
        BattleField field = user.getField();
        double accuracy = move.getAccuracy();
        boolean hit;
        if ((accuracy != 0.0)
                && (user.hasAbility("No Guard") || target.hasAbility("No Guard") ||
                       user.hasEffect(MoveList.LockOnEffect.class))
                ) {
            hit = true;
        } else {
            double effective = (accuracy
                    * user.getAccuracy().getMultiplier())
                    / target.getEvasion().getMultiplier();
            if (effective > 1.0) effective = 1.0;

            hit = (field.getRandom().nextDouble() <= effective);
        }
        if (!hit) {
            field.showMessage(user.getName() + "'s attack missed!");
        }
        return hit;
    }
   
    public boolean isCriticalHit(PokemonMove move, Pokemon user, Pokemon target) {
        if (target.isCriticalImmune()) {
            return false;
        }
       
        FieldEffect effect = user.getField().getEffectByType(MoveList.LuckyChantEffect.class);
        if (effect != null) {
            MoveList.LuckyChantEffect eff = (MoveList.LuckyChantEffect)effect;
            if (eff.isActive(target.getParty())) {
                return false;
            }
        }
       
        int moveFactor = 0;
        if (move.hasHighCriticalHitRate()) {
            moveFactor = (this instanceof JewelMechanics) ? 1 : 3;
        }
       
        int factor = user.getCriticalHitFactor()
            + (user.hasItem("Scope Lens") ? 1 : 0) /* TODO: + (FE/L * 1) */
            + moveFactor;
        double chance = 0.0;
        switch (factor) {
            case 1:
                chance = 0.0625;
                break;
            case 2:
                chance = 0.125;
                break;
            case 3:
                chance = 0.25;
                break;
            case 4:
                chance = 0.332;
                break;
            default:
                chance = 0.5;
                break;
        }
        return (user.getField().getRandom().nextDouble() <= chance);
    }
   
    /**
     * Return whether a given move deals special damage.
     */
    public boolean isMoveSpecial(PokemonMove move) {
        return move.getType().isSpecial();
    }
   
    public strictfp int calculateDamage(
            PokemonMove move,
            Pokemon attacker, Pokemon defender, boolean silent) {
       
        final BattleField field = attacker.getField();
        PokemonType moveType = move.getType();
        final boolean special = isMoveSpecial(move);
       
        boolean isCritical = move.canCriticalHit() &&
                isCriticalHit(move, attacker, defender);
       
        double attack = attacker.getStat(special
            ? Pokemon.S_SPATTACK
            : Pokemon.S_ATTACK);
       
        int defStat = special
            ? Pokemon.S_SPDEFENCE
            : Pokemon.S_DEFENCE;
       
        StatMultiplier mul = defender.getMultiplier(defStat);
        double defMultiplier = mul.getMultiplier();
        if (isCritical && (defMultiplier > 1.0)) {
            defMultiplier = mul.getSecondaryMultiplier();
        }
        double defence = defender.getStat(defStat, defMultiplier);
       
        final int random = field.getRandom().nextInt(16) + 85;
       
        double multiplier = move.getEffectiveness(attacker, defender);
       
        if (multiplier > 1.0) {
            if (!silent) {
                field.showMessage("It's super effective!");
            }
        } else if (multiplier == 0.0) {
            if (!silent) {
                field.showMessage("It doesn't affect " + defender.getName() + "...");
            }
            // Just return now to prevent a critical hit from occurring.
            return 0;
        } else if (multiplier < 1.0) {
            if (!silent) {
                field.showMessage("It's not very effective...");
            }
        }
       
        final boolean stab = attacker.isType(moveType);
        double stabFactor = attacker.hasAbility("Adaptability") ? 2.0 : 1.5;
       
        int damage = (int)(((int)((int)(((int)((2 * attacker.getLevel()) / 5.0 + 2.0)
        * attack
        * move.getPower())
        / defence)
        / 50.0)
        + 2)
        * (random / 100.0)
        * (stab ? stabFactor : 1.0)
        * multiplier);
       
        if (isCritical) {
            damage *= attacker.hasAbility("Sniper") ? 3 : 2;
            if (defender.hasAbility("Anger Point")) {
                if (!silent) {
                    field.showMessage(defender.getName()
                            + "'s Anger Point raised its attack!");
                }
                StatChangeEffect eff = new StatChangeEffect(
                        Pokemon.S_ATTACK,true, 12);
                eff.setDescription(null);
                defender.addStatus(defender, eff);
            }
            if (!silent) {
                field.showMessage("A critical hit!");
            }
        }
       
        return ((damage < 1) ? 1 : damage);
    }
   
    /**
     * There are several conditions to validate. The total number of effort
     * points must be less than or equal to 510. There can be no more than 255
     * effort points per stat. There can be no more than 31 individual
     * points per stat. The pokemon's level must be in the interval [1, 100].
     */
    public void validateHiddenStats(Pokemon p) throws ValidationException {
        int level = p.getLevel();
        if ((level < 1) || (level > 100))
            throw new ValidationException("Level must be between 1 and 100.");
       
        int evs = 0;
        for (int i = 0; i < 6; ++i) {
            int ev = p.getEv(i);
            evs += ev;
            if (ev > 255)
                throw new ValidationException(
                        "No stat can be allocated more than 255 EVs.");
            if (ev < 0) {
                throw new ValidationException("EVs cannot be negative.");
            }
               
            int iv = p.getIv(i);
            if (iv > 31)
                throw new ValidationException(
                        "No stat can be given more than 31 IVs.");
            if (iv < 0) {
                throw new ValidationException("IVs cannot be negative.");
            }
        }
        if (evs > 510) {
            throw new ValidationException(
                    "A pokemon cannot have more than 510 EVs in total.");
        }
    }
   
}
TOP

Related Classes of org.pokenet.server.battle.mechanics.AdvanceMechanics

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.