l2j_mobius/trunk/java/com/l2jmobius/gameserver/instancemanager/CeremonyOfChaosManager.java
2016-06-12 01:34:09 +00:00

439 lines
14 KiB
Java

/*
* This file is part of the L2J Mobius project.
*
* 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 3 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, see <http://www.gnu.org/licenses/>.
*/
package com.l2jmobius.gameserver.instancemanager;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.util.Comparator;
import java.util.List;
import java.util.logging.Logger;
import java.util.stream.Collectors;
import com.l2jmobius.commons.database.DatabaseFactory;
import com.l2jmobius.commons.util.Rnd;
import com.l2jmobius.gameserver.enums.CategoryType;
import com.l2jmobius.gameserver.enums.CeremonyOfChaosState;
import com.l2jmobius.gameserver.model.L2Clan;
import com.l2jmobius.gameserver.model.L2World;
import com.l2jmobius.gameserver.model.StatsSet;
import com.l2jmobius.gameserver.model.actor.L2Npc;
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
import com.l2jmobius.gameserver.model.ceremonyofchaos.CeremonyOfChaosEvent;
import com.l2jmobius.gameserver.model.ceremonyofchaos.CeremonyOfChaosMember;
import com.l2jmobius.gameserver.model.eventengine.AbstractEventManager;
import com.l2jmobius.gameserver.model.eventengine.ScheduleTarget;
import com.l2jmobius.gameserver.model.events.EventType;
import com.l2jmobius.gameserver.model.events.ListenerRegisterType;
import com.l2jmobius.gameserver.model.events.annotations.RegisterEvent;
import com.l2jmobius.gameserver.model.events.annotations.RegisterType;
import com.l2jmobius.gameserver.model.events.impl.character.player.OnPlayerBypass;
import com.l2jmobius.gameserver.model.events.impl.character.player.OnPlayerLogin;
import com.l2jmobius.gameserver.model.events.impl.character.player.OnPlayerLogout;
import com.l2jmobius.gameserver.model.events.returns.TerminateReturn;
import com.l2jmobius.gameserver.model.olympiad.OlympiadManager;
import com.l2jmobius.gameserver.model.punishment.PunishmentAffect;
import com.l2jmobius.gameserver.model.punishment.PunishmentType;
import com.l2jmobius.gameserver.model.variables.PlayerVariables;
import com.l2jmobius.gameserver.model.zone.ZoneId;
import com.l2jmobius.gameserver.network.SystemMessageId;
import com.l2jmobius.gameserver.network.serverpackets.IClientOutgoingPacket;
import com.l2jmobius.gameserver.network.serverpackets.SystemMessage;
import com.l2jmobius.gameserver.network.serverpackets.ceremonyofchaos.ExCuriousHouseState;
/**
* @author Sdw
*/
public class CeremonyOfChaosManager extends AbstractEventManager<CeremonyOfChaosEvent>
{
protected static final Logger LOGGER = Logger.getLogger(CeremonyOfChaosManager.class.getName());
public static final String INITIAL_BUFF_KEY = "initial_buff";
public static final String INITIAL_ITEMS_KEY = "initial_items";
public static final String MAX_PLAYERS_KEY = "max_players";
public static final String MAX_ARENAS_KEY = "max_arenas";
public static final String INSTANCE_TEMPLATES_KEY = "instance_templates";
public static final String END_BUFFS_KEYH = "end_buffs";
protected CeremonyOfChaosManager()
{
}
@Override
public void onInitialized()
{
if (getState() == null)
{
setState(CeremonyOfChaosState.SCHEDULED);
}
}
@ScheduleTarget
private void onPeriodEnd(String text)
{
try (Connection con = DatabaseFactory.getInstance().getConnection();
PreparedStatement ps = con.prepareStatement("DELETE FROM character_variables WHERE var = ?"))
{
ps.setString(1, PlayerVariables.CEREMONY_OF_CHAOS_PROHIBITED_PENALTIES);
ps.execute();
}
catch (Exception e)
{
LOGGER.severe(getClass().getSimpleName() + ": Could not reset Ceremony Of Chaos penalties: " + e);
}
// Update data for online players.
L2World.getInstance().getPlayers().stream().forEach(player ->
{
player.getVariables().remove(PlayerVariables.CEREMONY_OF_CHAOS_PROHIBITED_PENALTIES);
player.getVariables().storeMe();
});
LOGGER.info(getClass().getSimpleName() + ": Ceremony of Chaos penalties have been reset.");
LOGGER.info(getClass().getSimpleName() + ": Ceremony of Chaos period has ended!");
}
@ScheduleTarget
private void onEventStart()
{
LOGGER.info(getClass().getSimpleName() + ": Ceremony of Chaos event has started!");
}
@ScheduleTarget
private void onEventEnd()
{
PunishmentManager.getInstance().stopPunishment(PunishmentAffect.CHARACTER, PunishmentType.COC_BAN);
LOGGER.info(getClass().getSimpleName() + ": Ceremony of Chaos event has ended!");
}
@ScheduleTarget
private void onRegistrationStart()
{
if (getState() != CeremonyOfChaosState.SCHEDULED)
{
return;
}
setState(CeremonyOfChaosState.REGISTRATION);
for (L2PcInstance player : L2World.getInstance().getPlayers())
{
if (player.isOnline())
{
player.sendPacket(SystemMessageId.REGISTRATION_FOR_THE_CEREMONY_OF_CHAOS_HAS_BEGUN);
if (canRegister(player, false))
{
player.sendPacket(ExCuriousHouseState.REGISTRATION_PACKET);
}
}
}
}
@ScheduleTarget
private void onRegistrationEnd()
{
if (getState() != CeremonyOfChaosState.REGISTRATION)
{
return;
}
setState(CeremonyOfChaosState.PREPARING_FOR_TELEPORT);
for (L2PcInstance player : L2World.getInstance().getPlayers())
{
if (player.isOnline())
{
player.sendPacket(SystemMessageId.REGISTRATION_FOR_THE_CEREMONY_OF_CHAOS_HAS_ENDED);
if (!isRegistered(player))
{
player.sendPacket(ExCuriousHouseState.IDLE_PACKET);
}
}
}
getTimers().addTimer("count_down", StatsSet.valueOf("time", 60), 60 * 1000, null, null);
}
@ScheduleTarget
private void onPrepareForFight()
{
if (getState() != CeremonyOfChaosState.PREPARING_FOR_TELEPORT)
{
return;
}
setState(CeremonyOfChaosState.PREPARING_FOR_FIGHT);
int eventId = 0;
int position = 1;
CeremonyOfChaosEvent event = null;
final List<L2PcInstance> players = getRegisteredPlayers().stream().sorted(Comparator.comparingInt(L2PcInstance::getLevel)).collect(Collectors.toList());
final int maxPlayers = getMaxPlayersInArena();
final List<Integer> templates = getVariables().getList(INSTANCE_TEMPLATES_KEY, Integer.class);
for (L2PcInstance player : players)
{
if (player.isOnline() && canRegister(player, true))
{
if ((event == null) || (event.getMembers().size() >= maxPlayers))
{
final int template = templates.get(Rnd.get(templates.size()));
event = new CeremonyOfChaosEvent(eventId++, InstanceManager.getInstance().getInstanceTemplate(template));
position = 1;
getEvents().add(event);
}
event.addMember(new CeremonyOfChaosMember(player, event, position++));
}
else
{
player.prohibiteCeremonyOfChaos();
player.sendPacket(ExCuriousHouseState.IDLE_PACKET);
}
}
// Clear previously registrated players
getRegisteredPlayers().clear();
// Prepare all event's players for start
getEvents().forEach(CeremonyOfChaosEvent::preparePlayers);
}
@ScheduleTarget
private void onStartFight()
{
if (getState() != CeremonyOfChaosState.PREPARING_FOR_FIGHT)
{
return;
}
setState(CeremonyOfChaosState.RUNNING);
getEvents().forEach(CeremonyOfChaosEvent::startFight);
}
@ScheduleTarget
private void onEndFight()
{
if (getState() != CeremonyOfChaosState.RUNNING)
{
return;
}
setState(CeremonyOfChaosState.SCHEDULED);
getEvents().forEach(CeremonyOfChaosEvent::stopFight);
getEvents().clear();
}
@Override
public void onTimerEvent(String event, StatsSet params, L2Npc npc, L2PcInstance player)
{
switch (event)
{
case "count_down":
{
final int time = params.getInt("time", 0);
final SystemMessage countdown = SystemMessage.getSystemMessage(SystemMessageId.YOU_WILL_BE_MOVED_TO_THE_ARENA_IN_S1_SECOND_S);
countdown.addByte(time);
broadcastPacket(countdown);
// Reschedule
if (time == 60)
{
getTimers().addTimer(event, params.set("time", 10), 50 * 1000, null, null);
}
else if (time == 10)
{
getTimers().addTimer(event, params.set("time", 5), 5 * 1000, null, null);
}
else if ((time > 1) && (time <= 5))
{
getTimers().addTimer(event, params.set("time", time - 1), 1000, null, null);
}
break;
}
}
}
public final void broadcastPacket(IClientOutgoingPacket... packets)
{
getRegisteredPlayers().forEach(member -> member.sendPacket(packets));
}
@Override
public boolean canRegister(L2PcInstance player, boolean sendMessage)
{
boolean canRegister = true;
final L2Clan clan = player.getClan();
SystemMessageId sm = null;
if (player.getLevel() < 85)
{
sm = SystemMessageId.ONLY_CHARACTERS_LEVEL_85_OR_ABOVE_MAY_PARTICIPATE_IN_THE_TOURNAMENT;
canRegister = false;
}
else if (player.isFlyingMounted())
{
sm = SystemMessageId.YOU_CANNOT_PARTICIPATE_IN_THE_CEREMONY_OF_CHAOS_AS_A_FLYING_TRANSFORMED_OBJECT;
canRegister = false;
}
else if (!player.isInCategory(CategoryType.AWAKEN_GROUP))
{
sm = SystemMessageId.ONLY_CHARACTERS_WHO_HAVE_COMPLETED_THE_3RD_CLASS_TRANSFER_MAY_PARTICIPATE;
canRegister = false;
}
else if (!player.isInventoryUnder80(false) || (player.getWeightPenalty() != 0))
{
sm = SystemMessageId.UNABLE_TO_PROCESS_THIS_REQUEST_UNTIL_YOUR_INVENTORY_S_WEIGHT_AND_SLOT_COUNT_ARE_LESS_THAN_80_PERCENT_OF_CAPACITY;
canRegister = false;
}
else if ((clan == null) || (clan.getLevel() < 6))
{
sm = SystemMessageId.ONLY_CHARACTERS_WHO_ARE_A_PART_OF_A_CLAN_OF_LEVEL_6_OR_ABOVE_MAY_PARTICIPATE;
canRegister = false;
}
else if (getRegisteredPlayers().size() >= (getVariables().getInt(MAX_ARENAS_KEY, 5) * getMaxPlayersInArena()))
{
sm = SystemMessageId.THERE_ARE_TOO_MANY_CHALLENGERS_YOU_CANNOT_PARTICIPATE_NOW;
canRegister = false;
}
else if (player.isCursedWeaponEquipped() || (player.getReputation() < 0))
{
sm = SystemMessageId.WAITING_LIST_REGISTRATION_IS_NOT_ALLOWED_WHILE_THE_CURSED_SWORD_IS_BEING_USED_OR_THE_STATUS_IS_IN_A_CHAOTIC_STATE;
canRegister = false;
}
else if (player.isInDuel())
{
sm = SystemMessageId.YOU_CANNOT_REGISTER_IN_THE_WAITING_LIST_DURING_A_DUEL;
canRegister = false;
}
else if (player.isInOlympiadMode() || OlympiadManager.getInstance().isRegistered(player))
{
sm = SystemMessageId.YOU_CANNOT_REGISTER_IN_THE_WAITING_LIST_WHILE_PARTICIPATING_IN_OLYMPIAD;
canRegister = false;
}
else if (player.isOnEvent(CeremonyOfChaosEvent.class) || (player.getBlockCheckerArena() > -1)) // TODO underground coliseum and kratei checks.
{
sm = SystemMessageId.YOU_CANNOT_REGISTER_FOR_THE_WAITING_LIST_WHILE_PARTICIPATING_IN_THE_BLOCK_CHECKER_COLISEUM_OLYMPIAD_KRATEI_S_CUBE_CEREMONY_OF_CHAOS;
canRegister = false;
}
else if (player.isInInstance())
{
sm = SystemMessageId.YOU_MAY_NOT_REGISTER_WHILE_USING_THE_INSTANT_ZONE;
canRegister = false;
}
else if (player.isInSiege())
{
sm = SystemMessageId.YOU_CANNOT_REGISTER_FOR_THE_WAITING_LIST_ON_THE_BATTLEFIELD_CASTLE_SIEGE_FORTRESS_SIEGE;
canRegister = false;
}
else if (player.isInsideZone(ZoneId.SIEGE))
{
sm = SystemMessageId.YOU_CANNOT_REGISTER_IN_THE_WAITING_LIST_WHILE_BEING_INSIDE_OF_A_BATTLEGROUND_CASTLE_SIEGE_FORTRESS_SIEGE;
canRegister = false;
}
else if (player.isFlyingMounted())
{
sm = SystemMessageId.YOU_CANNOT_PARTICIPATE_IN_THE_CEREMONY_OF_CHAOS_AS_A_FLYING_TRANSFORMED_OBJECT;
canRegister = false;
}
else if (player.isFishing())
{
sm = SystemMessageId.YOU_CANNOT_PARTICIPATE_IN_THE_CEREMONY_OF_CHAOS_WHILE_FISHING;
canRegister = false;
}
else if (player.isCeremonyOfChaosProhibited())
{
canRegister = false;
}
// TODO : One player can take part in 16 matches per day.
if ((sm != null) && sendMessage)
{
player.sendPacket(sm);
}
return canRegister;
}
@RegisterEvent(EventType.ON_PLAYER_BYPASS)
@RegisterType(ListenerRegisterType.GLOBAL_PLAYERS)
private TerminateReturn OnPlayerBypass(OnPlayerBypass event)
{
final L2PcInstance player = event.getActiveChar();
if (player == null)
{
return null;
}
if (event.getCommand().equalsIgnoreCase("pledgegame?command=apply"))
{
if (registerPlayer(player))
{
player.sendPacket(SystemMessageId.YOU_ARE_NOW_ON_THE_WAITING_LIST_YOU_WILL_AUTOMATICALLY_BE_TELEPORTED_WHEN_THE_TOURNAMENT_STARTS_AND_WILL_BE_REMOVED_FROM_THE_WAITING_LIST_IF_YOU_LOG_OUT_IF_YOU_CANCEL_REGISTRATION_WITHIN_THE_LAST_MINUTE_OF_ENTERING_THE_ARENA_AFTER_SIGNING_UP_30_TIMES_OR_MORE_OR_FORFEIT_AFTER_ENTERING_THE_ARENA_30_TIMES_OR_MORE_DURING_A_CYCLE_YOU_BECOME_INELIGIBLE_FOR_PARTICIPATION_IN_THE_CEREMONY_OF_CHAOS_UNTIL_THE_NEXT_CYCLE_ALL_THE_BUFFS_EXCEPT_THE_VITALITY_BUFF_WILL_BE_REMOVED_ONCE_YOU_ENTER_THE_ARENAS);
player.sendPacket(SystemMessageId.EXCEPT_THE_VITALITY_BUFF_ALL_BUFFS_INCLUDING_ART_OF_SEDUCTION_WILL_BE_DELETED);
player.sendPacket(ExCuriousHouseState.PREPARE_PACKET);
}
return new TerminateReturn(true, false, false);
}
return null;
}
@RegisterEvent(EventType.ON_PLAYER_LOGIN)
@RegisterType(ListenerRegisterType.GLOBAL_PLAYERS)
private void OnPlayerLogin(OnPlayerLogin event)
{
if (getState() == CeremonyOfChaosState.REGISTRATION)
{
final L2PcInstance player = event.getActiveChar();
if (canRegister(player, false))
{
player.sendPacket(ExCuriousHouseState.REGISTRATION_PACKET);
}
}
}
@RegisterEvent(EventType.ON_PLAYER_LOGOUT)
@RegisterType(ListenerRegisterType.GLOBAL_PLAYERS)
private void OnPlayerLogout(OnPlayerLogout event)
{
if (getState() == CeremonyOfChaosState.REGISTRATION)
{
final L2PcInstance player = event.getActiveChar();
if (getRegisteredPlayers().contains(player))
{
getRegisteredPlayers().remove(player);
}
}
}
// player leave clan
public int getMaxPlayersInArena()
{
return getVariables().getInt(MAX_PLAYERS_KEY, 18);
}
public static CeremonyOfChaosManager getInstance()
{
return SingletonHolder._instance;
}
private static class SingletonHolder
{
protected static final CeremonyOfChaosManager _instance = new CeremonyOfChaosManager();
}
}