Package instances

Source Code of instances.GvGInstance$BattleEnd

package instances;

import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.ScheduledFuture;

import org.apache.commons.lang3.mutable.MutableInt;
import lineage2.commons.lang.reference.HardReference;
import lineage2.commons.lang.reference.HardReferences;
import lineage2.commons.threading.RunnableImpl;
import lineage2.gameserver.ThreadPoolManager;
import lineage2.gameserver.instancemanager.ReflectionManager;
import lineage2.gameserver.listener.actor.OnDeathListener;
import lineage2.gameserver.listener.actor.player.OnPlayerPartyLeaveListener;
import lineage2.gameserver.listener.actor.player.OnTeleportListener;
import lineage2.gameserver.model.Creature;
import lineage2.gameserver.model.Party;
import lineage2.gameserver.model.Player;
import lineage2.gameserver.model.Skill;
import lineage2.gameserver.model.Zone;
import lineage2.gameserver.model.entity.Reflection;
import lineage2.gameserver.model.instances.NpcInstance;
import lineage2.gameserver.network.serverpackets.ExCubeGameAddPlayer;
import lineage2.gameserver.network.serverpackets.ExCubeGameChangePoints;
import lineage2.gameserver.network.serverpackets.ExCubeGameCloseUI;
import lineage2.gameserver.network.serverpackets.ExCubeGameEnd;
import lineage2.gameserver.network.serverpackets.ExCubeGameExtendedChangePoints;
import lineage2.gameserver.network.serverpackets.ExCubeGameRemovePlayer;
import lineage2.gameserver.network.serverpackets.ExShowScreenMessage;
import lineage2.gameserver.network.serverpackets.ExShowScreenMessage.ScreenMessageAlign;
import lineage2.gameserver.network.serverpackets.L2GameServerPacket;
import lineage2.gameserver.network.serverpackets.Revive;
import lineage2.gameserver.scripts.Functions;
import lineage2.gameserver.tables.SkillTable;
import lineage2.gameserver.utils.Location;

import events.GvG.GvG;
import gnu.trove.map.hash.TIntObjectHashMap;

/**
*
* @author pchayka
*/
public class GvGInstance extends Reflection
{
  private final static int BOX_ID = 18822;
  private final static int BOSS_ID = 25655;

  private final static int SCORE_BOX = 20;
  private final static int SCORE_BOSS = 100;
  private final static int SCORE_KILL = 5;
  private final static int SCORE_DEATH = 3;

  private int eventTime = 1200;
  private long bossSpawnTime = 10 * 60 * 1000L;

  private boolean active = false;

  private Party team1;
  private Party team2;
  private List<HardReference<Player>> bothTeams = new CopyOnWriteArrayList<HardReference<Player>>();

  private TIntObjectHashMap<MutableInt> score = new TIntObjectHashMap<MutableInt>();
  private int team1Score = 0;
  private int team2Score = 0;

  private long startTime;

  private ScheduledFuture<?> _bossSpawnTask;
  private ScheduledFuture<?> _countDownTask;
  private ScheduledFuture<?> _battleEndTask;

  private DeathListener _deathListener = new DeathListener();
  private TeleportListener _teleportListener = new TeleportListener();
  private PlayerPartyLeaveListener _playerPartyLeaveListener = new PlayerPartyLeaveListener();

  private Zone zonepvp;

  private Zone peace1;

  private Zone peace2;

  public void setTeam1(Party party1)
  {
    team1 = party1;
  }

  public void setTeam2(Party party2)
  {
    team2 = party2;
  }

  public GvGInstance()
  {
    super();
  }

  /**
   * General instance initialization and assigning global variables
   */
  public void start()
  {
    zonepvp = getZone("[gvg_battle_zone]");
    peace1 = getZone("[gvg_1_peace]");
    peace2 = getZone("[gvg_2_peace]");
    //Box spawns
    Location boxes[] = {
        new Location(142696, 139704, -15264, 0),
        new Location(142696, 145944, -15264, 0),
        new Location(145784, 142824, -15264, 0),
        new Location(145768, 139704, -15264, 0),
        new Location(145768, 145944, -15264, 0),
        new Location(141752, 142760, -15624, 0),
        new Location(145720, 142008, -15880, 0),
        new Location(145720, 143640, -15880, 0),
        new Location(139592, 142824, -15264, 0) };

    for(int i = 0; i < boxes.length; i++)
      addSpawnWithoutRespawn(BOX_ID, boxes[i], 0);

    addSpawnWithoutRespawn(35423, new Location(139640, 139736, -15264), 0); //Red team flag
    addSpawnWithoutRespawn(35426, new Location(139672, 145896, -15264), 0); //Blue team flag

    _bossSpawnTask = ThreadPoolManager.getInstance().schedule(new BossSpawn(), bossSpawnTime); //
    _countDownTask = ThreadPoolManager.getInstance().schedule(new CountingDown(), (eventTime - 1) * 1000L);
    _battleEndTask = ThreadPoolManager.getInstance().schedule(new BattleEnd(), (eventTime - 6) * 1000L); // -6 is about to prevent built-in BlockChecker countdown task

    //Assigning players to teams
    for(Player member : team1.getPartyMembers())
    {
      bothTeams.add(member.getRef());
      member.addListener(_deathListener);
      member.addListener(_teleportListener);
      member.addListener(_playerPartyLeaveListener);
    }

    for(Player member : team2.getPartyMembers())
    {
      bothTeams.add(member.getRef());
      member.addListener(_deathListener);
      member.addListener(_teleportListener);
      member.addListener(_playerPartyLeaveListener);
    }

    startTime = System.currentTimeMillis() + eventTime * 1000L; //Used in packet broadcasting

    //Forming packets to send everybody
    final ExCubeGameChangePoints initialPoints = new ExCubeGameChangePoints(eventTime, team1Score, team2Score);
    final ExCubeGameCloseUI cui = new ExCubeGameCloseUI();
    ExCubeGameExtendedChangePoints clientSetUp;

    for(Player tm : HardReferences.unwrap(bothTeams))
    {
      score.put(tm.getObjectId(), new MutableInt());

      tm.setCurrentCp(tm.getMaxCp());
      tm.setCurrentHp(tm.getMaxHp(), false);
      tm.setCurrentMp(tm.getMaxMp());
      clientSetUp = new ExCubeGameExtendedChangePoints(eventTime, team1Score, team2Score, isRedTeam(tm), tm, 0);
      tm.sendPacket(clientSetUp);
      tm.sendActionFailed(); //useless? copy&past from BlockChecker
      tm.sendPacket(initialPoints);
      tm.sendPacket(cui); //useless? copy&past from BlockChecker
      broadCastPacketToBothTeams(new ExCubeGameAddPlayer(tm, isRedTeam(tm)));
    }

    active = true;
  }

  /**
   * @param packet Broadcasting packet to every member of instance
   */
  private void broadCastPacketToBothTeams(L2GameServerPacket packet)
  {
    for(Player tm : HardReferences.unwrap(bothTeams))
      tm.sendPacket(packet);
  }

  /**
   * @return Whether event is active. active starts with instance dungeon and ends with team victory
   */
  private boolean isActive()
  {
    return active;
  }

  /**
   * @param player
   * @return Whether player belongs to Red Team (team2)
   */
  private boolean isRedTeam(Player player)
  {
    if(team2.containsMember(player))
      return true;
    return false;
  }

  /**
   * Handles the end of event
   */
  private void end()
  {
    active = false;

    startCollapseTimer(60 * 1000L);

    paralyzePlayers();
    ThreadPoolManager.getInstance().schedule(new Finish(), 55 * 1000L);

    if(_bossSpawnTask != null)
    {
      _bossSpawnTask.cancel(false);
      _bossSpawnTask = null;
    }
    if(_countDownTask != null)
    {
      _countDownTask.cancel(false);
      _countDownTask = null;
    }
    if(_battleEndTask != null)
    {
      _battleEndTask.cancel(false);
      _battleEndTask = null;
    }

    boolean isRedWinner = false;

    isRedWinner = getRedScore() >= getBlueScore();

    final ExCubeGameEnd end = new ExCubeGameEnd(isRedWinner);
    broadCastPacketToBothTeams(end);

    reward(isRedWinner ? team2 : team1);
    GvG.updateWinner(isRedWinner ? team2.getPartyLeader() : team1.getPartyLeader());

    zonepvp.setActive(false);
    peace1.setActive(false);
    peace2.setActive(false);
  }

  private void reward(Party party)
  {
    for(Player member : party.getPartyMembers())
    {
      member.sendMessage("Ваша группа выиграла GvG турнир, лидер группы добавлен в рейтинг победителей.");
      member.setFame(member.getFame() + 500, "GvG"); // fame
      Functions.addItem(member, 13067, 30); // Fantasy Isle Coin
    }
  }

  private class DeathListener implements OnDeathListener
  {
    @Override
    public void onDeath(Creature self, Creature killer)
    {
      if(!isActive())
        return;

      if(self.getReflection() != killer.getReflection() || self.getReflection() != GvGInstance.this)
        return;

      if(self.isPlayer() && killer.isPlayable()) //if PvP kill
      {
        if(team1.containsMember(self.getPlayer()) && team2.containsMember(killer.getPlayer()))
        {
          addPlayerScore(killer.getPlayer());
          changeScore(1, SCORE_KILL, SCORE_DEATH, true, true, killer.getPlayer());
        }
        else if(team2.containsMember(self.getPlayer()) && team1.containsMember(killer.getPlayer()))
        {
          addPlayerScore(killer.getPlayer());
          changeScore(2, SCORE_KILL, SCORE_DEATH, true, true, killer.getPlayer());
        }
        resurrectAtBase(self.getPlayer());
      }
      else if(self.isPlayer() && !killer.isPlayable()) //if not-PvP kill
        resurrectAtBase(self.getPlayer());
      else if(self.isNpc() && killer.isPlayable())
        if(self.getNpcId() == BOX_ID)
        {
          if(team1.containsMember(killer.getPlayer()))
            changeScore(1, SCORE_BOX, 0, false, false, killer.getPlayer());
          else if(team2.containsMember(killer.getPlayer()))
            changeScore(2, SCORE_BOX, 0, false, false, killer.getPlayer());
        }
        else if(self.getNpcId() == BOSS_ID)
        {
          if(team1.containsMember(killer.getPlayer()))
            changeScore(1, SCORE_BOSS, 0, false, false, killer.getPlayer());
          else if(team2.containsMember(killer.getPlayer()))
            changeScore(2, SCORE_BOSS, 0, false, false, killer.getPlayer());

          broadCastPacketToBothTeams(new ExShowScreenMessage("Охранник Сокровищ Геральда погиб от руки " + killer.getName(), 5000, ScreenMessageAlign.MIDDLE_CENTER, true));
          end();
        }
    }
  }

  /**
   * @param teamId
   * @param toAdd             - how much points to add
   * @param toSub             - how much points to remove
   * @param subbing           - whether change is reducing points
   * @param affectAnotherTeam - change can affect only teamId or both
   * @param player            Any score change are handled here.
   */
  private synchronized void changeScore(int teamId, int toAdd, int toSub, boolean subbing, boolean affectAnotherTeam, Player player)
  {
    int timeLeft = (int) ((startTime - System.currentTimeMillis()) / 1000);
    if(teamId == 1)
    {
      if(subbing)
      {
        team1Score -= toSub;
        if(team1Score < 0)
          team1Score = 0;
        if(affectAnotherTeam)
        {
          team2Score += toAdd;
          broadCastPacketToBothTeams(new ExCubeGameExtendedChangePoints(timeLeft, team1Score, team2Score, true, player, getPlayerScore(player)));
        }
        broadCastPacketToBothTeams(new ExCubeGameExtendedChangePoints(timeLeft, team1Score, team2Score, false, player, getPlayerScore(player)));
      }
      else
      {
        team1Score += toAdd;
        if(affectAnotherTeam)
        {
          team2Score -= toSub;
          if(team2Score < 0)
            team2Score = 0;
          broadCastPacketToBothTeams(new ExCubeGameExtendedChangePoints(timeLeft, team1Score, team2Score, true, player, getPlayerScore(player)));
        }
        broadCastPacketToBothTeams(new ExCubeGameExtendedChangePoints(timeLeft, team1Score, team2Score, false, player, getPlayerScore(player)));
      }
    }
    else if(teamId == 2)
      if(subbing)
      {
        team2Score -= toSub;
        if(team2Score < 0)
          team2Score = 0;
        if(affectAnotherTeam)
        {
          team1Score += toAdd;
          broadCastPacketToBothTeams(new ExCubeGameExtendedChangePoints(timeLeft, team1Score, team2Score, false, player, getPlayerScore(player)));
        }
        broadCastPacketToBothTeams(new ExCubeGameExtendedChangePoints(timeLeft, team1Score, team2Score, true, player, getPlayerScore(player)));
      }
      else
      {
        team2Score += toAdd;
        if(affectAnotherTeam)
        {
          team1Score -= toSub;
          if(team1Score < 0)
            team1Score = 0;
          broadCastPacketToBothTeams(new ExCubeGameExtendedChangePoints(timeLeft, team1Score, team2Score, false, player, getPlayerScore(player)));
        }
        broadCastPacketToBothTeams(new ExCubeGameExtendedChangePoints(timeLeft, team1Score, team2Score, true, player, getPlayerScore(player)));
      }
  }

  /**
   * @param player Handles the increase of personal player points
   */
  private void addPlayerScore(Player player)
  {
    MutableInt points = score.get(player.getObjectId());
    points.increment();
  }

  /**
   * @param player
   * @return Returns personal player score
   */
  public int getPlayerScore(Player player)
  {
    MutableInt points = score.get(player.getObjectId());
    return points.intValue();
  }

  /**
   * Paralyzes everybody in instance to prevent any actions while event is !isActive
   */
  public void paralyzePlayers()
  {
    for(Player tm : HardReferences.unwrap(bothTeams))
    {
      if(tm.isDead())
      {
        tm.setCurrentHp(tm.getMaxHp(), true);
        tm.broadcastPacket(new Revive(tm));
      }
      else
        tm.setCurrentHp(tm.getMaxHp(), false);

      tm.setCurrentMp(tm.getMaxMp());
      tm.setCurrentCp(tm.getMaxCp());

      tm.getEffectList().stopEffect(Skill.SKILL_MYSTIC_IMMUNITY);
      tm.block();
    }
  }

  /**
   * Romoves paralization
   */
  public void unParalyzePlayers()
  {
    for(Player tm : HardReferences.unwrap(bothTeams))
    {
      tm.unblock();
      removePlayer(tm, true);
    }
  }

  /**
   * Cleans up every list and task
   */
  private void cleanUp()
  {
    team1 = null;
    team2 = null;
    bothTeams.clear();
    team1Score = 0;
    team2Score = 0;
    score.clear();
  }

  /**
   * @param player
   * @param refId  Called by onDeath. Handles the resurrection at the proper base.
   */
  public void resurrectAtBase(Player player)
  {
    if(player.isDead())
    {
      //player.setCurrentCp(player.getMaxCp());
      player.setCurrentHp(0.7 * player.getMaxHp(), true);
      //player.setCurrentMp(player.getMaxMp());
      player.broadcastPacket(new Revive(player));
    }
    player.altOnMagicUseTimer(player, SkillTable.getInstance().getInfo(5660, 2)); // Battlefield Death Syndrome

    Location pos;
    if(team1.containsMember(player))
      pos = Location.findPointToStay(GvG.TEAM1_LOC, 0, 150, getGeoIndex());
    else
      pos = Location.findPointToStay(GvG.TEAM2_LOC, 0, 150, getGeoIndex());

    player.teleToLocation(pos, this);
  }

  /**
   * @param player
   * @param legalQuit - whether quit was called by event or by player escape
   *                  Removes player from every list or instance, teleports him and stops the event timer
   */
  private void removePlayer(Player player, boolean legalQuit)
  {
    bothTeams.remove(player.getRef());

    broadCastPacketToBothTeams(new ExCubeGameRemovePlayer(player, isRedTeam(player)));
    player.removeListener(_deathListener);
    player.removeListener(_teleportListener);
    player.removeListener(_playerPartyLeaveListener);
    player.leaveParty();
    if(!legalQuit)
      player.sendPacket(new ExCubeGameEnd(false));
    player.teleToLocation(Location.findPointToStay(GvG.RETURN_LOC, 0, 150, ReflectionManager.DEFAULT.getGeoIndex()), 0);
  }

  /**
   * @param isRed Handles the team withdraw from the area of event. Can only be called when !isActive
   */
  private void teamWithdraw(Party party)
  {
    if(party == team1)
    {
      for(Player player : team1.getPartyMembers())
        removePlayer(player, false);

      Player player = team2.getPartyLeader();
      changeScore(2, 200, 0, false, false, player); //adding 200 to the team score for enemy team withdrawal. player - leader of the team who's left in the instance
    }
    else
    {
      for(Player player : team2.getPartyMembers())
        removePlayer(player, false);

      Player player = team1.getPartyLeader();
      changeScore(1, 200, 0, false, false, player); //adding 200 to the team score for enemy team withdrawal. player - leader of the team who's left in the instance
    }

    broadCastPacketToBothTeams(new ExShowScreenMessage("", 4000, ScreenMessageAlign.MIDDLE_CENTER, true));
    end();
  }

  private int getBlueScore()
  {
    return team1Score;
  }

  private int getRedScore()
  {
    return team2Score;
  }

  public class BossSpawn extends RunnableImpl
  {
    @Override
    public void runImpl() throws Exception
    {
      broadCastPacketToBothTeams(new ExShowScreenMessage("", 5000, ScreenMessageAlign.MIDDLE_CENTER, true));
      addSpawnWithoutRespawn(BOSS_ID, new Location(147304, 142824, -15864, 32768), 0);
      openDoor(24220042);
    }
  }

  public class CountingDown extends RunnableImpl
  {
    @Override
    public void runImpl() throws Exception
    {
      broadCastPacketToBothTeams(new ExShowScreenMessage("", 4000, ScreenMessageAlign.MIDDLE_CENTER, true));
    }
  }

  public class BattleEnd extends RunnableImpl
  {
    @Override
    public void runImpl() throws Exception
    {
      broadCastPacketToBothTeams(new ExShowScreenMessage("", 4000, ScreenMessageAlign.BOTTOM_RIGHT, true));
      end();
    }
  }

  public class Finish extends RunnableImpl
  {
    @Override
    public void runImpl() throws Exception
    {
      unParalyzePlayers();
      cleanUp();
    }
  }

  /**
   * @param npcId
   * @param loc
   * @param randomOffset
   * @param refId        Custom instanced spawn method
   */
  @Override
  public NpcInstance addSpawnWithoutRespawn(int npcId, Location loc, int randomOffset)
  {
    NpcInstance npc = super.addSpawnWithoutRespawn(npcId, loc, randomOffset);
    npc.addListener(_deathListener);
    return npc;
  }

  /**
   * Handles any Teleport action of any player inside
   */
  private class TeleportListener implements OnTeleportListener
  {
    @Override
    public void onTeleport(Player player, int x, int y, int z, Reflection reflection)
    {
      if(zonepvp.checkIfInZone(x, y, z, reflection) || peace1.checkIfInZone(x, y, z, reflection) || peace2.checkIfInZone(x, y, z, reflection))
        return;

      removePlayer(player, false);
      player.sendMessage("");
    }
  }

  /**
   * Handles quit from the group
   */
  private class PlayerPartyLeaveListener implements OnPlayerPartyLeaveListener
  {
    @Override
    public void onPartyLeave(Player player)
    {
      if(!isActive())
        return;

      Party party = player.getParty();

      if(party.getMemberCount() >= 3) //when getMemberCount() >= 3 the party won't be dissolved.
      {
        removePlayer(player, false);
        return;
      }

      // else if getMemberCount() < 3 the party will be dissolved -> launching team withdrawal method
      teamWithdraw(party);
    }
  }
}
TOP

Related Classes of instances.GvGInstance$BattleEnd

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.