386 lines
11 KiB
Java
386 lines
11 KiB
Java
/*
|
|
* Copyright (C) 2004-2015 L2J Server
|
|
*
|
|
* This file is part of L2J Server.
|
|
*
|
|
* L2J Server 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 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* L2J Server 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, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
package com.l2jserver.gameserver.instancemanager;
|
|
|
|
import java.util.Collections;
|
|
import java.util.HashMap;
|
|
import java.util.HashSet;
|
|
import java.util.Map;
|
|
import java.util.Set;
|
|
|
|
import com.l2jserver.Config;
|
|
import com.l2jserver.gameserver.ThreadPoolManager;
|
|
import com.l2jserver.gameserver.enums.Team;
|
|
import com.l2jserver.gameserver.instancemanager.tasks.PenaltyRemoveTask;
|
|
import com.l2jserver.gameserver.model.ArenaParticipantsHolder;
|
|
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
|
import com.l2jserver.gameserver.model.itemcontainer.PcInventory;
|
|
import com.l2jserver.gameserver.model.olympiad.OlympiadManager;
|
|
import com.l2jserver.gameserver.model.zone.ZoneId;
|
|
import com.l2jserver.gameserver.network.SystemMessageId;
|
|
import com.l2jserver.gameserver.network.serverpackets.ExCubeGameAddPlayer;
|
|
import com.l2jserver.gameserver.network.serverpackets.ExCubeGameChangeTeam;
|
|
import com.l2jserver.gameserver.network.serverpackets.ExCubeGameRemovePlayer;
|
|
import com.l2jserver.gameserver.network.serverpackets.SystemMessage;
|
|
|
|
/**
|
|
* This class manage the player add/remove, team change and event arena status,<br>
|
|
* as the clearance of the participants list or liberate the arena.
|
|
* @author BiggBoss
|
|
*/
|
|
public final class HandysBlockCheckerManager
|
|
{
|
|
// All the participants and their team classified by arena
|
|
private static final ArenaParticipantsHolder[] _arenaPlayers = new ArenaParticipantsHolder[4];
|
|
|
|
// Arena votes to start the game
|
|
private static final Map<Integer, Integer> _arenaVotes = new HashMap<>();
|
|
|
|
// Arena Status, True = is being used, otherwise, False
|
|
private static final Map<Integer, Boolean> _arenaStatus = new HashMap<>();
|
|
|
|
// Registration request penalty (10 seconds)
|
|
protected static Set<Integer> _registrationPenalty = Collections.synchronizedSet(new HashSet<Integer>());
|
|
|
|
/**
|
|
* Return the number of event-start votes for the specified arena id
|
|
* @param arenaId
|
|
* @return int (number of votes)
|
|
*/
|
|
public synchronized int getArenaVotes(int arenaId)
|
|
{
|
|
return _arenaVotes.get(arenaId);
|
|
}
|
|
|
|
/**
|
|
* Add a new vote to start the event for the specified arena id
|
|
* @param arena
|
|
*/
|
|
public synchronized void increaseArenaVotes(int arena)
|
|
{
|
|
int newVotes = _arenaVotes.get(arena) + 1;
|
|
ArenaParticipantsHolder holder = _arenaPlayers[arena];
|
|
|
|
if ((newVotes > (holder.getAllPlayers().size() / 2)) && !holder.getEvent().isStarted())
|
|
{
|
|
clearArenaVotes(arena);
|
|
if ((holder.getBlueTeamSize() == 0) || (holder.getRedTeamSize() == 0))
|
|
{
|
|
return;
|
|
}
|
|
if (Config.HBCE_FAIR_PLAY)
|
|
{
|
|
holder.checkAndShuffle();
|
|
}
|
|
ThreadPoolManager.getInstance().executeGeneral(holder.getEvent().new StartEvent());
|
|
}
|
|
else
|
|
{
|
|
_arenaVotes.put(arena, newVotes);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Will clear the votes queue (of event start) for the specified arena id
|
|
* @param arena
|
|
*/
|
|
public synchronized void clearArenaVotes(int arena)
|
|
{
|
|
_arenaVotes.put(arena, 0);
|
|
}
|
|
|
|
protected HandysBlockCheckerManager()
|
|
{
|
|
// Initialize arena status
|
|
_arenaStatus.put(0, false);
|
|
_arenaStatus.put(1, false);
|
|
_arenaStatus.put(2, false);
|
|
_arenaStatus.put(3, false);
|
|
|
|
// Initialize arena votes
|
|
_arenaVotes.put(0, 0);
|
|
_arenaVotes.put(1, 0);
|
|
_arenaVotes.put(2, 0);
|
|
_arenaVotes.put(3, 0);
|
|
}
|
|
|
|
/**
|
|
* Returns the players holder
|
|
* @param arena
|
|
* @return ArenaParticipantsHolder
|
|
*/
|
|
public ArenaParticipantsHolder getHolder(int arena)
|
|
{
|
|
return _arenaPlayers[arena];
|
|
}
|
|
|
|
/**
|
|
* Initializes the participants holder
|
|
*/
|
|
public void startUpParticipantsQueue()
|
|
{
|
|
for (int i = 0; i < 4; ++i)
|
|
{
|
|
_arenaPlayers[i] = new ArenaParticipantsHolder(i);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Add the player to the specified arena (through the specified arena manager) and send the needed server -> client packets
|
|
* @param player
|
|
* @param arenaId
|
|
* @return
|
|
*/
|
|
public boolean addPlayerToArena(L2PcInstance player, int arenaId)
|
|
{
|
|
ArenaParticipantsHolder holder = _arenaPlayers[arenaId];
|
|
|
|
synchronized (holder)
|
|
{
|
|
boolean isRed;
|
|
|
|
for (int i = 0; i < 4; i++)
|
|
{
|
|
if (_arenaPlayers[i].getAllPlayers().contains(player))
|
|
{
|
|
SystemMessage msg = SystemMessage.getSystemMessage(SystemMessageId.C1_IS_ALREADY_REGISTERED_ON_THE_MATCH_WAITING_LIST);
|
|
msg.addCharName(player);
|
|
player.sendPacket(msg);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
if (player.isCursedWeaponEquipped())
|
|
{
|
|
player.sendPacket(SystemMessageId.YOU_CANNOT_REGISTER_WHILE_IN_POSSESSION_OF_A_CURSED_WEAPON);
|
|
return false;
|
|
}
|
|
|
|
if (player.isOnEvent() || player.isInOlympiadMode())
|
|
{
|
|
player.sendMessage("Couldnt register you due other event participation");
|
|
return false;
|
|
}
|
|
|
|
if (OlympiadManager.getInstance().isRegistered(player))
|
|
{
|
|
OlympiadManager.getInstance().unRegisterNoble(player);
|
|
player.sendPacket(SystemMessageId.APPLICANTS_FOR_THE_OLYMPIAD_UNDERGROUND_COLISEUM_OR_KRATEI_S_CUBE_MATCHES_CANNOT_REGISTER);
|
|
}
|
|
|
|
// if(UnderGroundColiseum.getInstance().isRegisteredPlayer(player))
|
|
// {
|
|
// UngerGroundColiseum.getInstance().removeParticipant(player);
|
|
// player.sendPacket(SystemMessageId.APPLICANTS_FOR_THE_OLYMPIAD_UNDERGROUND_COLISEUM_OR_KRATEI_S_CUBE_MATCHES_CANNOT_REGISTER));
|
|
// }
|
|
// if(KrateiCubeManager.getInstance().isRegisteredPlayer(player))
|
|
// {
|
|
// KrateiCubeManager.getInstance().removeParticipant(player);
|
|
// player.sendPacket(SystemMessageId.APPLICANTS_FOR_THE_OLYMPIAD_UNDERGROUND_COLISEUM_OR_KRATEI_S_CUBE_MATCHES_CANNOT_REGISTER));
|
|
// }
|
|
|
|
if (_registrationPenalty.contains(player.getObjectId()))
|
|
{
|
|
player.sendPacket(SystemMessageId.YOU_MUST_WAIT_10_SECONDS_BEFORE_ATTEMPTING_TO_REGISTER_AGAIN);
|
|
return false;
|
|
}
|
|
|
|
if (holder.getBlueTeamSize() < holder.getRedTeamSize())
|
|
{
|
|
holder.addPlayer(player, 1);
|
|
isRed = false;
|
|
}
|
|
else
|
|
{
|
|
holder.addPlayer(player, 0);
|
|
isRed = true;
|
|
}
|
|
holder.broadCastPacketToTeam(new ExCubeGameAddPlayer(player, isRed));
|
|
return true;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Will remove the specified player from the specified team and arena and will send the needed packet to all his team mates / enemy team mates
|
|
* @param player
|
|
* @param arenaId
|
|
* @param team
|
|
*/
|
|
public void removePlayer(L2PcInstance player, int arenaId, int team)
|
|
{
|
|
ArenaParticipantsHolder holder = _arenaPlayers[arenaId];
|
|
synchronized (holder)
|
|
{
|
|
boolean isRed = team == 0 ? true : false;
|
|
|
|
holder.removePlayer(player, team);
|
|
holder.broadCastPacketToTeam(new ExCubeGameRemovePlayer(player, isRed));
|
|
|
|
// End event if theres an empty team
|
|
int teamSize = isRed ? holder.getRedTeamSize() : holder.getBlueTeamSize();
|
|
if (teamSize == 0)
|
|
{
|
|
holder.getEvent().endEventAbnormally();
|
|
}
|
|
|
|
_registrationPenalty.add(player.getObjectId());
|
|
schedulePenaltyRemoval(player.getObjectId());
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Will change the player from one team to other (if possible) and will send the needed packets
|
|
* @param player
|
|
* @param arena
|
|
* @param team
|
|
*/
|
|
public void changePlayerToTeam(L2PcInstance player, int arena, int team)
|
|
{
|
|
ArenaParticipantsHolder holder = _arenaPlayers[arena];
|
|
|
|
synchronized (holder)
|
|
{
|
|
boolean isFromRed = holder.getRedPlayers().contains(player);
|
|
|
|
if (isFromRed && (holder.getBlueTeamSize() == 6))
|
|
{
|
|
player.sendMessage("The team is full");
|
|
return;
|
|
}
|
|
else if (!isFromRed && (holder.getRedTeamSize() == 6))
|
|
{
|
|
player.sendMessage("The team is full");
|
|
return;
|
|
}
|
|
|
|
int futureTeam = isFromRed ? 1 : 0;
|
|
holder.addPlayer(player, futureTeam);
|
|
|
|
if (isFromRed)
|
|
{
|
|
holder.removePlayer(player, 0);
|
|
}
|
|
else
|
|
{
|
|
holder.removePlayer(player, 1);
|
|
}
|
|
holder.broadCastPacketToTeam(new ExCubeGameChangeTeam(player, isFromRed));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Will erase all participants from the specified holder
|
|
* @param arenaId
|
|
*/
|
|
public synchronized void clearPaticipantQueueByArenaId(int arenaId)
|
|
{
|
|
_arenaPlayers[arenaId].clearPlayers();
|
|
}
|
|
|
|
/**
|
|
* Returns true if arena is holding an event at this momment
|
|
* @param arenaId
|
|
* @return boolean
|
|
*/
|
|
public boolean arenaIsBeingUsed(int arenaId)
|
|
{
|
|
if ((arenaId < 0) || (arenaId > 3))
|
|
{
|
|
return false;
|
|
}
|
|
return _arenaStatus.get(arenaId);
|
|
}
|
|
|
|
/**
|
|
* Set the specified arena as being used
|
|
* @param arenaId
|
|
*/
|
|
public void setArenaBeingUsed(int arenaId)
|
|
{
|
|
_arenaStatus.put(arenaId, true);
|
|
}
|
|
|
|
/**
|
|
* Set as free the specified arena for future events
|
|
* @param arenaId
|
|
*/
|
|
public void setArenaFree(int arenaId)
|
|
{
|
|
_arenaStatus.put(arenaId, false);
|
|
}
|
|
|
|
/**
|
|
* Called when played logs out while participating in Block Checker Event
|
|
* @param player
|
|
*/
|
|
public void onDisconnect(L2PcInstance player)
|
|
{
|
|
int arena = player.getBlockCheckerArena();
|
|
int team = getHolder(arena).getPlayerTeam(player);
|
|
HandysBlockCheckerManager.getInstance().removePlayer(player, arena, team);
|
|
if (player.getTeam() != Team.NONE)
|
|
{
|
|
player.stopAllEffects();
|
|
// Remove team aura
|
|
player.setTeam(Team.NONE);
|
|
|
|
// Remove the event items
|
|
PcInventory inv = player.getInventory();
|
|
|
|
if (inv.getItemByItemId(13787) != null)
|
|
{
|
|
long count = inv.getInventoryItemCount(13787, 0);
|
|
inv.destroyItemByItemId("Handys Block Checker", 13787, count, player, player);
|
|
}
|
|
if (inv.getItemByItemId(13788) != null)
|
|
{
|
|
long count = inv.getInventoryItemCount(13788, 0);
|
|
inv.destroyItemByItemId("Handys Block Checker", 13788, count, player, player);
|
|
}
|
|
player.setInsideZone(ZoneId.PVP, false);
|
|
// Teleport Back
|
|
player.teleToLocation(-57478, -60367, -2370);
|
|
}
|
|
}
|
|
|
|
public void removePenalty(int objectId)
|
|
{
|
|
_registrationPenalty.remove(objectId);
|
|
}
|
|
|
|
private void schedulePenaltyRemoval(int objId)
|
|
{
|
|
ThreadPoolManager.getInstance().scheduleGeneral(new PenaltyRemoveTask(objId), 10000);
|
|
}
|
|
|
|
/**
|
|
* Gets the single instance of {@code HandysBlockCheckerManager}.
|
|
* @return single instance of {@code HandysBlockCheckerManager}
|
|
*/
|
|
public static HandysBlockCheckerManager getInstance()
|
|
{
|
|
return SingletonHolder._instance;
|
|
}
|
|
|
|
private static class SingletonHolder
|
|
{
|
|
protected static final HandysBlockCheckerManager _instance = new HandysBlockCheckerManager();
|
|
}
|
|
}
|