/*
* StatusEffect.java
*
* Created on December 16, 2006, 9:43 AM
*
* This file is a part of Shoddy Battle.
* Copyright (C) 2006 Colin Fitzpatrick
*
* 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.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, visit the Free Software Foundation, Inc.
* online at http://gnu.org.
*/
package org.pokenet.server.battle.mechanics.statuses;
import org.pokenet.server.battle.BattleTurn;
import org.pokenet.server.battle.Pokemon;
import org.pokenet.server.battle.mechanics.PokemonType;
import org.pokenet.server.battle.mechanics.moves.MoveListEntry;
/**
* This class represents a change in status of a pokemon.
* @author Colin
*/
public abstract class StatusEffect implements Cloneable {
/**
* A pokemon can have only one of freeze, burn, sleep, paralysis, and
* poison, so we protect against this by giving this class of effects
* a designated lock called SPECIAL_EFFECT_LOCK.
*/
public static final int SPECIAL_EFFECT_LOCK = 1;
/**
* There can be only be only weather effect in play.
*/
public static final int WEATHER_EFFECT_LOCK = 2;
/** States of a StatusEffect. */
public static final int STATE_ACTIVE = 0;
public static final int STATE_DEACTIVATED = 1;
public static final int STATE_REMOVABLE = 2;
private int m_state = STATE_ACTIVE;
protected int m_lock = 0;
private Pokemon m_inducer;
/**
* Set the pokemon who induced this effect.
*/
public void setInducer(Pokemon p) {
m_inducer = p;
}
/**
* Get the pokemon who induced this effect.
*/
public Pokemon getInducer() {
return m_inducer;
}
/**
* Get the lock of this effect.
*/
public int getLock() {
return m_lock;
}
/**
* Get the name of this status effect.
*/
public String getName() {
return null;
}
/**
* Return the total number of tiers. There will be six tiers eventually.
* This could also differ based on the mechanics used.
*/
public static final int getTierCount() {
return 6;
}
/**
* Can this status effect by baton passed? (Almost all can.)
*/
public boolean isPassable() {
return true;
}
/**
* Does this effect allow the application of the given status effect to
* a particular pokemon? This is called on the target pokemon.
*/
public boolean allowsStatus(StatusEffect eff, Pokemon source, Pokemon target) {
return true;
}
/**
* Return whether this effect can coexist with another effect.
* @param eff the effect to test exclusiveness with
*/
public boolean isExclusiveWith(StatusEffect eff) {
if (m_lock == 0) {
return false;
}
return (m_lock == eff.m_lock);
}
/**
* Disable this status effect (i.e. mark it as removable). This cannot
* be undone.
*/
public final void disable() {
m_state = STATE_REMOVABLE;
}
/**
* Deactivate this status effect, unless it is removable.
*/
public final void deactivate() {
if (m_state != STATE_REMOVABLE) {
m_state = STATE_DEACTIVATED;
}
}
/**
* Activate this status effect, unless it is removable.
*/
public final void activate() {
if (m_state != STATE_REMOVABLE) {
m_state = STATE_ACTIVE;
}
}
/**
* Is this status effect active?
*/
public final boolean isActive() {
return (m_state == STATE_ACTIVE);
}
/**
* Is this status effect waiting to be removed?
*/
public final boolean isRemovable() {
return (m_state == STATE_REMOVABLE);
}
/**
* Clone this status effect.
*/
public Object clone() {
try {
return super.clone();
} catch (CloneNotSupportedException e) {
/* unreachable */
return null;
}
}
/**
* Return whether this effect immobilises the pokemon.
*/
public boolean immobilises(Pokemon poke) {
return false;
}
/**
* Get a description of this status effect.
*/
public String getDescription() {
return null;
}
/**
* Called each turn that this status effect is applied to a pokemon.
* Returns whether the status was removed.
*/
public boolean tick(Pokemon p) {
return false;
}
/**
* Remove the tier of the after-turn effect.
*/
public int getTier() {
return -1;
}
/**
* Called when a pokemon with this status effect switches in.
*/
public void switchIn(Pokemon p) {
}
/**
* Called when a pokemon with this status effect switches out.
* Returns true if the status effect should be removed.
*/
public boolean switchOut(Pokemon p) {
return true;
}
/**
* Unapply this status effect.
*/
public void unapply(Pokemon p) {
}
/**
* The point of this method is to catch errors.
*/
public final boolean apply(Pokemon source, Pokemon p) {
throw new InternalError();
}
/**
* Applies the initial effects of the status to a pokemon but does not add
* the status to the list of statuses the pokemon has.
*/
public boolean apply(Pokemon p) {
return true;
}
/**
* Return whether this status effect can apply statuses through a
* substitute.
*/
public boolean hitsThroughSubstitute() {
return false;
}
/**
* Does this status effect transform effectivenesses?
*/
public boolean isEffectivenessTransformer(boolean enemy) {
return false;
}
/**
* This method is called when the pokemon to whom the status effect is
* applied is just about to execute his turn.
*/
public void executeTurn(Pokemon p, BattleTurn turn) {
}
/**
* Get transformed effectiveness based on this status effect.
* @param move type of the move
* @param pokemon type of the pokemon
* @param enemy whether the Pokemon using the move is an enemy
*/
public final double getEffectiveness(
PokemonType move, PokemonType pokemon, boolean enemy) {
if (enemy) {
return getEnemyTransformedEffectiveness(move, pokemon);
}
return getTransformedEffectiveness(move, pokemon);
}
protected double getTransformedEffectiveness(PokemonType move, PokemonType pokemon) {
return move.getMultiplier(pokemon);
}
protected double getEnemyTransformedEffectiveness(PokemonType move, PokemonType pokemon) {
return move.getMultiplier(pokemon);
}
/**
* Transform a move based on this status effect.
* @param move the move to transform; the method is free to modify it
* although it may also return a new MoveListEntry
* @param enemy whether the Pokemon p is an enemy
* @return the transformed move
*/
public final MoveListEntry getMove(
Pokemon p, MoveListEntry move, boolean enemy) {
if (enemy) {
return getEnemyTransformedMove(p, move);
}
return getTransformedMove(p, move);
}
protected MoveListEntry getEnemyTransformedMove(Pokemon p, MoveListEntry move) {
return move;
}
protected MoveListEntry getTransformedMove(Pokemon p, MoveListEntry move) {
return move;
}
/**
* Returns true if this status effect is capable of transforming moves.
* @param enemy whether this is an enemy move
*/
public boolean isMoveTransformer(boolean enemy) {
return false;
}
/**
* Return whether this effect listens for damage.
*/
public boolean isListener() {
return false;
}
/**
* React to damage.
*/
public void informDamaged(Pokemon source, Pokemon target, MoveListEntry move, int damage) {
}
/**
* Determine whether this effect deactivates a pokemon.
*/
public boolean deactivates(Pokemon p) {
return false;
}
/**
* Determine whether two status effects are equal semantically.
*/
public boolean equals(Object eff) {
if (!getClass().equals(eff.getClass())) {
// If they are different types of status effects then they are
// not equal.
return false;
}
// Otherwise they might be.
return isSingleton();
}
/**
* Determine whether this effect is a singleton -- i.e., whether only
* a single copy of it can be present on a pokemon.
*/
public boolean isSingleton() {
return true;
}
/**
* Inform that this effect was applied, unsuccessfully, a second time.
*/
public void informDuplicateEffect(Pokemon p) {
p.getField().showMessage("But it failed!");
}
/**
* Return whether this status effect allows switching.
*/
public boolean canSwitch(Pokemon p) {
return true;
}
/**
* This method catches errors.
*/
public boolean canSwitch() {
throw new InternalError();
}
/**
* Returns whether this status effect vetoes the choice of a particular
* move.
*/
public boolean vetoesMove(Pokemon p, MoveListEntry entry) {
return false;
}
/**
* Begin ticking this effect.
*/
public void beginTick() {
}
}