Package org.pokenet.server.battle.impl

Source Code of org.pokenet.server.battle.impl.PvPBattleField

package org.pokenet.server.battle.impl;

import org.pokenet.server.backend.entity.PlayerChar;
import org.pokenet.server.battle.BattleField;
import org.pokenet.server.battle.BattleTurn;
import org.pokenet.server.battle.Pokemon;
import org.pokenet.server.battle.mechanics.BattleMechanics;
import org.pokenet.server.battle.mechanics.MoveQueueException;
import org.pokenet.server.battle.mechanics.statuses.StatusEffect;
import org.pokenet.server.battle.mechanics.statuses.field.FieldEffect;
import org.pokenet.server.battle.mechanics.statuses.field.HailEffect;
import org.pokenet.server.battle.mechanics.statuses.field.RainEffect;
import org.pokenet.server.battle.mechanics.statuses.field.SandstormEffect;
import org.pokenet.server.feature.TimeService;
import org.pokenet.server.network.TcpProtocolHandler;
import org.pokenet.server.network.message.battle.BattleEndMessage;
import org.pokenet.server.network.message.battle.BattleInitMessage;
import org.pokenet.server.network.message.battle.BattleMessage;
import org.pokenet.server.network.message.battle.BattleMoveMessage;
import org.pokenet.server.network.message.battle.BattleMoveRequest;
import org.pokenet.server.network.message.battle.EnemyDataMessage;
import org.pokenet.server.network.message.battle.FaintMessage;
import org.pokenet.server.network.message.battle.HealthChangeMessage;
import org.pokenet.server.network.message.battle.NoPPMessage;
import org.pokenet.server.network.message.battle.StatusChangeMessage;
import org.pokenet.server.network.message.battle.SwitchMessage;
import org.pokenet.server.network.message.battle.SwitchRequest;
import org.pokenet.server.network.message.battle.BattleEndMessage.BattleEnd;

/**
* A battlefield for PvP battles
* @author shadowkanji
*
*/
public class PvPBattleField extends BattleField {
  private PlayerChar[] m_players;
  private BattleTurn[] m_turn = new BattleTurn[2];
  private boolean m_finished = false;

  /**
   * Constructor
   *
   * @param mech
   * @param p1
   * @param p2
   */
  public PvPBattleField(BattleMechanics mech, PlayerChar p1, PlayerChar p2) {
    super(mech, new Pokemon[][] { p1.getParty(), p2.getParty() });
    /*
     * Store the players
     */
    m_players = new PlayerChar[2];
    m_players[0] = p1;
    m_players[1] = p2;
    /*
     *Set the player to battling
     */
    p1.setBattling(true);
    p2.setBattling(true);
    /*
     * Set the battlefield for the players
     */
    p2.setBattleField(this);
    /*
     * Set battle ids
     */
    p1.setBattleId(0);
    p2.setBattleId(1);

    /*
     * Send battle initialisation packets
     */
    TcpProtocolHandler.writeMessage(p1.getTcpSession(),
        new BattleInitMessage(false, p2.getPartyCount()));
    TcpProtocolHandler.writeMessage(p2.getTcpSession(),
        new BattleInitMessage(false, p1.getPartyCount()));
    /* Send the enemy's name to both players*/
    p1.getTcpSession().write("bn" + p2.getName());
    p2.getTcpSession().write("bn" + p1.getName());
    /* Send pokemon data to both players */
    sendPokemonData(p1, p2);
    sendPokemonData(p2, p1);
    /* Apply weather and request moves */
    applyWeather();
    requestMoves();
  }

  /**
   * Sends pokemon data for PlayerChar p to receiver
   *
   * @param p
   * @param receiver
   */
  private void sendPokemonData(PlayerChar p, PlayerChar receiver) {
    for (int i = 0; i < p.getParty().length; i++) {
      if (p.getParty()[i] != null) {
        TcpProtocolHandler.writeMessage(receiver.getTcpSession(),
            new EnemyDataMessage(i, p.getParty()[i]));
      }
    }
  }

  @Override
  public void applyWeather() {
    if (m_players[0].getMap().isWeatherForced()) {
      switch (m_players[0].getMap().getWeather()) {
      case NORMAL:
        return;
      case RAIN:
        this.applyEffect(new RainEffect());
        return;
      case HAIL:
        this.applyEffect(new HailEffect());
        return;
      case SANDSTORM:
        this.applyEffect(new SandstormEffect());
        return;
      default:
        return;
      }
    } else {
      FieldEffect f = TimeService.getWeatherEffect();
      if (f != null) {
        this.applyEffect(f);
      }
    }
  }

  @Override
  public void clearQueue() {
    m_turn[0] = null;
    m_turn[1] = null;
  }

  @Override
  public BattleTurn[] getQueuedTurns() {
    return m_turn;
  }

  @Override
  public String getTrainerName(int idx) {
    return m_players[idx].getName();
  }

  @Override
  public void informPokemonFainted(int trainer, int idx) {
    if(m_players != null) {
      TcpProtocolHandler.writeMessage(m_players[0].getTcpSession(),
          new FaintMessage(getParty(trainer)[idx].getSpeciesName()));
      TcpProtocolHandler.writeMessage(m_players[1].getTcpSession(),
          new FaintMessage(getParty(trainer)[idx].getSpeciesName()));
    }
  }

  @Override
  public void informPokemonHealthChanged(Pokemon poke, int change) {
    if (m_players != null && poke != null) {
      if (poke.compareTo(getActivePokemon()[0]) == 0) {
        TcpProtocolHandler.writeMessage(m_players[0].getTcpSession(),
            new HealthChangeMessage(0 , change));
        TcpProtocolHandler.writeMessage(m_players[1].getTcpSession(),
            new HealthChangeMessage(1 , change));
      } else if(poke.compareTo(getActivePokemon()[1]) == 0) {
        TcpProtocolHandler.writeMessage(m_players[1].getTcpSession(),
            new HealthChangeMessage(0 , change));
        TcpProtocolHandler.writeMessage(m_players[0].getTcpSession(),
            new HealthChangeMessage(1 , change));
      } else {
        int index = getPokemonPartyIndex(0, poke);
        if(index > -1) {
          m_players[0].getTcpSession().write("Ph" + String.valueOf(index) + poke.getHealth());
          //TODO: Add support for enemy pokemon healing for pokemon in pokeballs
          return;
        }
        index = getPokemonPartyIndex(1, poke);
        if(index > -1) {
          m_players[1].getTcpSession().write("Ph" + String.valueOf(index) + poke.getHealth());
          //TODO: Add support for enemy pokemon healing for pokemon in pokeballs
          return;
        }
      }
    }
  }

  @Override
  public void informStatusApplied(Pokemon poke, StatusEffect eff) {
    if(m_finished)
      return;
    if (m_players != null && poke != null) {
      if (poke.compareTo(getActivePokemon()[0]) == 0) {
        TcpProtocolHandler.writeMessage(m_players[0].getTcpSession(),
            new StatusChangeMessage(0,
                poke.getSpeciesName(),
                eff.getName(), false));
        TcpProtocolHandler.writeMessage(m_players[1].getTcpSession(),
            new StatusChangeMessage(1,
                poke.getSpeciesName(),
                eff.getName(), false));
      } else if(poke.compareTo(getActivePokemon()[1]) == 0) {
        TcpProtocolHandler.writeMessage(m_players[0].getTcpSession(),
            new StatusChangeMessage(1,
                poke.getSpeciesName(),
                eff.getName(), false));
        TcpProtocolHandler.writeMessage(m_players[1].getTcpSession(),
            new StatusChangeMessage(0,
                poke.getSpeciesName(),
                eff.getName(), false));
      }
    }
  }

  @Override
  public void informStatusRemoved(Pokemon poke, StatusEffect eff) {
    if(m_finished)
      return;
    if (poke != null && m_players != null) {
      if (poke.compareTo(getActivePokemon()[0]) == 0 &&
          !getActivePokemon()[0].isFainted()) {
        TcpProtocolHandler.writeMessage(m_players[0].getTcpSession(),
            new StatusChangeMessage(0,
                poke.getSpeciesName(),
                eff.getName(), true));
        TcpProtocolHandler.writeMessage(m_players[1].getTcpSession(),
            new StatusChangeMessage(1,
                poke.getSpeciesName(),
                eff.getName(), true));
      } else if(poke.compareTo(getActivePokemon()[1]) == 0 &&
          !getActivePokemon()[1].isFainted()) {
        TcpProtocolHandler.writeMessage(m_players[0].getTcpSession(),
            new StatusChangeMessage(1,
                poke.getSpeciesName(),
                eff.getName(), true));
        TcpProtocolHandler.writeMessage(m_players[1].getTcpSession(),
            new StatusChangeMessage(0,
                poke.getSpeciesName(),
                eff.getName(), true));
      }
    }
  }

  @Override
  public void informSwitchInPokemon(int trainer, Pokemon poke) {
    int pokeIndex = getPokemonPartyIndex(trainer, poke);
    if(m_players != null) {
      if (trainer == 0) {
        TcpProtocolHandler.writeMessage(m_players[0].getTcpSession(),
            new SwitchMessage(m_players[0].getName(),
                poke.getSpeciesName(),
                0,
                pokeIndex));
        TcpProtocolHandler.writeMessage(m_players[1].getTcpSession(),
            new SwitchMessage(m_players[0].getName(),
                poke.getSpeciesName(),
                1,
                pokeIndex));
      } else {
        TcpProtocolHandler.writeMessage(m_players[0].getTcpSession(),
            new SwitchMessage(m_players[1].getName(),
                poke.getSpeciesName(),
                1,
                pokeIndex));
        TcpProtocolHandler.writeMessage(m_players[1].getTcpSession(),
            new SwitchMessage(m_players[1].getName(),
                poke.getSpeciesName(),
                0,
                pokeIndex));
      }
    }
  }

  @Override
  public void informUseMove(Pokemon poke, String name) {
    if(m_players != null) {
      TcpProtocolHandler.writeMessage(m_players[0].getTcpSession(),
          new BattleMoveMessage(poke.getSpeciesName(), name));
      TcpProtocolHandler.writeMessage(m_players[1].getTcpSession(),
          new BattleMoveMessage(poke.getSpeciesName(), name));
    }
  }

  @Override
  public void informVictory(int winner) {
    m_finished = true;
    m_players[0].removeTempStatusEffects();
    m_players[1].removeTempStatusEffects();
    if (winner == 0) {
      TcpProtocolHandler.writeMessage(m_players[0].getTcpSession(),
          new BattleEndMessage(BattleEnd.WON));
      TcpProtocolHandler.writeMessage(m_players[1].getTcpSession(),
          new BattleEndMessage(BattleEnd.LOST));
      m_players[1].lostBattle();
    } else {
      TcpProtocolHandler.writeMessage(m_players[0].getTcpSession(),
          new BattleEndMessage(BattleEnd.LOST));
      TcpProtocolHandler.writeMessage(m_players[1].getTcpSession(),
          new BattleEndMessage(BattleEnd.WON));
      m_players[0].lostBattle();
    }
    m_players[0].setBattling(false);
    m_players[1].setBattling(false);
    dispose();
    if (m_dispatch != null) {
      /*
       * This very bad programming but shoddy does it and forces us to do
       * it
       */
      //Thread t = m_dispatch;
      //m_dispatch = null;
      //t.stop(); let the thread manually return.
    }
  }

  @Override
  public void queueMove(int trainer, BattleTurn move)
      throws MoveQueueException {
    /* Checks the move exists */
    if(move.isMoveTurn() && move.getId() != -1 &&
        getActivePokemon()[trainer].getMove(move.getId()) == null) {
      requestMove(trainer);
      return;
    }
    /* Handle forced switches */
    if(m_isWaiting && m_replace != null && m_replace[trainer]) {
      if(!move.isMoveTurn()) {
        if(getActivePokemon()[trainer].compareTo(this.getParty(trainer)[move.getId()]) != 0) {
          this.switchInPokemon(trainer, move.getId());
          m_replace[trainer] = false;
          m_isWaiting = false;
          return;
        }
      }
      requestPokemonReplacement(trainer);
      return;
    }
    // The trainer has no turn queued.
    if (m_turn[trainer] == null) {
      /* Handle Pokemon being unhappy and ignoring you */
      if(!getActivePokemon()[trainer].isFainted()) {
        if(getActivePokemon()[trainer].getHappiness() <= 40) {
          /* Pokemon is unhappy, they'll do what they feel like */
          showMessage(getActivePokemon()[trainer].getSpeciesName() + " is unhappy!");
          int moveID = getMechanics().getRandom().nextInt(4);
          while (getActivePokemon()[trainer].getMove(moveID) == null)
            moveID = getMechanics().getRandom().nextInt(4);
          move = BattleTurn.getMoveTurn(moveID);
        } else if(getActivePokemon()[trainer].getHappiness() < 70) {
          /* Pokemon is partially unhappy, 50% chance they'll listen to you */
          if(getMechanics().getRandom().nextInt(2) == 1) {
            showMessage(getActivePokemon()[trainer].getSpeciesName() + " is unhappy!");
            int moveID = getMechanics().getRandom().nextInt(4);
            while (getActivePokemon()[trainer].getMove(moveID) == null)
              moveID = getMechanics().getRandom().nextInt(4);
            move = BattleTurn.getMoveTurn(moveID);
          }
        }
      }
      if (move.getId() == -1) {
        if (m_dispatch == null
            && ((trainer == 0 && m_turn[1] != null) ||
                (trainer == 1 && m_turn[0] != null))) {
          m_dispatch = new Thread(new Runnable() {
            public void run() {
              executeTurn(m_turn);
              m_dispatch = null;
            }
          });
          m_dispatch.start();
          return;
        }
      } else {
        // Handle a fainted pokemon
        if (this.getActivePokemon()[trainer].isFainted()) {
          if (!move.isMoveTurn() && this.getParty(trainer)[move.getId()] != null
              && this.getParty(trainer)[move.getId()].getHealth() > 0) {
            switchInPokemon(trainer, move.getId());
            requestMoves();
            return;
          } else {
            // The player still has pokemon left
            if (getAliveCount(trainer) > 0) {
              requestPokemonReplacement(trainer);
              return;
            } else {
              // the player has no pokemon left. Announce winner
              if (trainer == 0)
                this.informVictory(1);
              else
                this.informVictory(0);
              return;
            }
          }
        } else {
          // The turn was used to attack!
          if (move.isMoveTurn()) {
            // Handles Struggle
            if (getActivePokemon()[trainer].mustStruggle())
              m_turn[trainer] = BattleTurn.getMoveTurn(-1);
            else {
              // The move has no more PP. Tell the client!
              if (this.getActivePokemon()[trainer].getPp(move
                  .getId()) <= 0) {
                if (trainer == 0) {
                  TcpProtocolHandler.writeMessage(m_players[0].getTcpSession(),
                      new NoPPMessage(this.getActivePokemon()[trainer]
                        .getMoveName(move.getId())));
                } else {
                  TcpProtocolHandler.writeMessage(m_players[1].getTcpSession(),
                      new NoPPMessage(this.getActivePokemon()[trainer]
                        .getMoveName(move.getId())));
                }
                return;
              } else {
                // Assign the move to the turn
                m_turn[trainer] = move;
              }
            }
          } else {
            if (this.getActivePokemon()[trainer].isActive() &&
                this.getParty(trainer)[move.getId()] != null &&
                this.getParty(trainer)[move.getId()].getHealth() > 0) {
              m_turn[trainer] = move;
            } else {
              requestMove(trainer);
              return;
            }
          }
        }
      }
    }
    if (m_dispatch != null)
      return;
    // Both turns are ready to be performed
    if (m_turn[0] != null && m_turn[1] != null) {
      m_dispatch = new Thread(new Runnable() {
        public void run() {
          executeTurn(m_turn);
          for (int i = 0; i < m_participants; ++i) {
            m_turn[i] = null;
          }
          m_dispatch = null;
        }
      });
      m_dispatch.start();
    }
  }

  @Override
  public void refreshActivePokemon() {
    if(m_players != null) {
      m_players[0].getTcpSession().write(
          "bh0" + this.getActivePokemon()[0].getHealth());
      m_players[0].getTcpSession().write(
          "bh1" + this.getActivePokemon()[1].getHealth());

      m_players[1].getTcpSession().write(
          "bh0" + this.getActivePokemon()[1].getHealth());
      m_players[1].getTcpSession().write(
          "bh1" + this.getActivePokemon()[0].getHealth());
    }
  }

  @Override
  public void requestAndWaitForSwitch(int party) {
    requestPokemonReplacement(party);
    if (!m_replace[party]) {
      return;
    }
    m_isWaiting = true;
    do {
      synchronized (m_dispatch) {
        try {
          m_dispatch.wait(1000);
        } catch (InterruptedException e) {
        }
      }
    } while ((m_replace != null) && m_replace[party]);
  }

  @Override
  protected void requestMove(int trainer) {
    TcpProtocolHandler.writeMessage(m_players[trainer].getTcpSession(),
        new BattleMoveRequest());
  }

  @Override
  protected void requestMoves() {
    clearQueue();
    if (this.getActivePokemon()[0].isActive()
        && this.getActivePokemon()[1].isActive()) {
      TcpProtocolHandler.writeMessage(m_players[0].getTcpSession(),
          new BattleMoveRequest());
      TcpProtocolHandler.writeMessage(m_players[1].getTcpSession(),
          new BattleMoveRequest());
    }
  }

  @Override
  protected void requestPokemonReplacement(int i) {
    TcpProtocolHandler.writeMessage(m_players[i].getTcpSession(),
        new SwitchRequest());
  }

  @Override
  public void showMessage(String message) {
    if(m_finished)
      return;
    if(m_players != null) {
      if(m_players[0] != null)
        TcpProtocolHandler.writeMessage(m_players[0].getTcpSession(),
          new BattleMessage(message));
      if(m_players[1] != null)
        TcpProtocolHandler.writeMessage(m_players[1].getTcpSession(),
          new BattleMessage(message));
    }
  }
 
  /**
   * Handles a disconnect from a player
   * Rewards other player with some money
   * @param trainer
   */
  public void disconnect(int trainer) {
    if(m_players != null) {
      if(trainer == 0) {
/*        if(m_players[0].getMoney() >= 100) {
          m_players[0].setMoney(m_players[0].getMoney() - 100);
          m_players[1].setMoney(m_players[1].getMoney() + 100);
        } else {
          m_players[1].setMoney(m_players[1].getMoney() + m_players[0].getMoney());
          m_players[0].setMoney(0);
        }
        m_players[1].updateClientMoney();
*/        TcpProtocolHandler.writeMessage(m_players[1].getTcpSession(),
            new BattleEndMessage(BattleEnd.WON));
        m_players[1].setBattling(false);
      } else {
/*        if(m_players[1].getMoney() >= 100) {
          m_players[1].setMoney(m_players[0].getMoney() - 100);
          m_players[0].setMoney(m_players[1].getMoney() + 100);
        } else {
          m_players[0].setMoney(m_players[1].getMoney() + m_players[0].getMoney());
          m_players[1].setMoney(0);
        }
        m_players[0].updateClientMoney();
*/        TcpProtocolHandler.writeMessage(m_players[0].getTcpSession(),
            new BattleEndMessage(BattleEnd.WON));
        m_players[0].setBattling(false);
      }
    }
  }

  @Override
  public void forceExecuteTurn() {
    if(m_turn[0] == null) {
      m_turn[0] = BattleTurn.getMoveTurn(-1);
    }
    if(m_turn[1] == null) {
      m_turn[1] = BattleTurn.getMoveTurn(-1);
    }
    executeTurn(m_turn);
  }
}
TOP

Related Classes of org.pokenet.server.battle.impl.PvPBattleField

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.