/* * Copyright (C) 2004-2014 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 . */ package com.l2jserver.gameserver.model.entity; import java.util.Timer; import java.util.TimerTask; import java.util.concurrent.Future; import javolution.util.FastList; import com.l2jserver.Config; import com.l2jserver.gameserver.ThreadPoolManager; import com.l2jserver.gameserver.instancemanager.DimensionalRiftManager; import com.l2jserver.gameserver.instancemanager.QuestManager; import com.l2jserver.gameserver.model.L2Party; import com.l2jserver.gameserver.model.Location; import com.l2jserver.gameserver.model.actor.L2Npc; import com.l2jserver.gameserver.model.actor.instance.L2PcInstance; import com.l2jserver.gameserver.model.quest.Quest; import com.l2jserver.gameserver.model.quest.QuestState; import com.l2jserver.gameserver.network.serverpackets.Earthquake; import com.l2jserver.util.Rnd; /** * Thanks to L2Fortress and balancer.ru - kombat */ public class DimensionalRift { protected byte _type; protected L2Party _party; protected FastList _completedRooms = new FastList<>(); private static final long seconds_5 = 5000L; // private static final int MILLISECONDS_IN_MINUTE = 60000; protected byte jumps_current = 0; private Timer teleporterTimer; private TimerTask teleporterTimerTask; private Timer spawnTimer; private TimerTask spawnTimerTask; private Future earthQuakeTask; protected byte _choosenRoom = -1; private boolean _hasJumped = false; protected FastList deadPlayers = new FastList<>(); protected FastList revivedInWaitingRoom = new FastList<>(); private boolean isBossRoom = false; public DimensionalRift(L2Party party, byte type, byte room) { DimensionalRiftManager.getInstance().getRoom(type, room).setPartyInside(true); _type = type; _party = party; _choosenRoom = room; int[] coords = getRoomCoord(room); party.setDimensionalRift(this); for (L2PcInstance p : party.getMembers()) { final Quest riftQuest = QuestManager.getInstance().getQuest(635); if (riftQuest != null) { QuestState qs = p.getQuestState(riftQuest.getName()); if (qs == null) { qs = riftQuest.newQuestState(p); } if (!qs.isStarted()) { qs.startQuest(); } } p.teleToLocation(new Location(coords[0], coords[1], coords[2])); } createSpawnTimer(_choosenRoom); createTeleporterTimer(true); } public byte getType() { return _type; } public byte getCurrentRoom() { return _choosenRoom; } protected void createTeleporterTimer(final boolean reasonTP) { if (_party == null) { return; } if (teleporterTimerTask != null) { teleporterTimerTask.cancel(); teleporterTimerTask = null; } if (teleporterTimer != null) { teleporterTimer.cancel(); teleporterTimer = null; } if (earthQuakeTask != null) { earthQuakeTask.cancel(false); earthQuakeTask = null; } teleporterTimer = new Timer(); teleporterTimerTask = new TimerTask() { @Override public void run() { if (_choosenRoom > -1) { DimensionalRiftManager.getInstance().getRoom(_type, _choosenRoom).unspawn().setPartyInside(false); } if (reasonTP && (jumps_current < getMaxJumps()) && (_party.getMemberCount() > deadPlayers.size())) { jumps_current++; _completedRooms.add(_choosenRoom); _choosenRoom = -1; for (L2PcInstance p : _party.getMembers()) { if (!revivedInWaitingRoom.contains(p)) { teleportToNextRoom(p); } } createTeleporterTimer(true); createSpawnTimer(_choosenRoom); } else { for (L2PcInstance p : _party.getMembers()) { if (!revivedInWaitingRoom.contains(p)) { teleportToWaitingRoom(p); } } killRift(); cancel(); } } }; if (reasonTP) { long jumpTime = calcTimeToNextJump(); teleporterTimer.schedule(teleporterTimerTask, jumpTime); // Teleporter task, 8-10 minutes earthQuakeTask = ThreadPoolManager.getInstance().scheduleGeneral(new Runnable() { @Override public void run() { for (L2PcInstance p : _party.getMembers()) { if (!revivedInWaitingRoom.contains(p)) { p.sendPacket(new Earthquake(p.getX(), p.getY(), p.getZ(), 65, 9)); } } } }, jumpTime - 7000); } else { teleporterTimer.schedule(teleporterTimerTask, seconds_5); // incorrect party member invited. } } public void createSpawnTimer(final byte room) { if (spawnTimerTask != null) { spawnTimerTask.cancel(); spawnTimerTask = null; } if (spawnTimer != null) { spawnTimer.cancel(); spawnTimer = null; } spawnTimer = new Timer(); spawnTimerTask = new TimerTask() { @Override public void run() { DimensionalRiftManager.getInstance().getRoom(_type, room).spawn(); } }; spawnTimer.schedule(spawnTimerTask, Config.RIFT_SPAWN_DELAY); } public void partyMemberInvited() { createTeleporterTimer(false); } public void partyMemberExited(L2PcInstance player) { if (deadPlayers.contains(player)) { deadPlayers.remove(player); } if (revivedInWaitingRoom.contains(player)) { revivedInWaitingRoom.remove(player); } if ((_party.getMemberCount() < Config.RIFT_MIN_PARTY_SIZE) || (_party.getMemberCount() == 1)) { for (L2PcInstance p : _party.getMembers()) { teleportToWaitingRoom(p); } killRift(); } } public void manualTeleport(L2PcInstance player, L2Npc npc) { if (!player.isInParty() || !player.getParty().isInDimensionalRift()) { return; } if (player.getObjectId() != player.getParty().getLeaderObjectId()) { DimensionalRiftManager.getInstance().showHtmlFile(player, "data/html/seven_signs/rift/NotPartyLeader.htm", npc); return; } if (_hasJumped) { DimensionalRiftManager.getInstance().showHtmlFile(player, "data/html/seven_signs/rift/AlreadyTeleported.htm", npc); return; } _hasJumped = true; DimensionalRiftManager.getInstance().getRoom(_type, _choosenRoom).unspawn().setPartyInside(false); _completedRooms.add(_choosenRoom); _choosenRoom = -1; for (L2PcInstance p : _party.getMembers()) { teleportToNextRoom(p); } DimensionalRiftManager.getInstance().getRoom(_type, _choosenRoom).setPartyInside(true); createSpawnTimer(_choosenRoom); createTeleporterTimer(true); } public void manualExitRift(L2PcInstance player, L2Npc npc) { if (!player.isInParty() || !player.getParty().isInDimensionalRift()) { return; } if (player.getObjectId() != player.getParty().getLeaderObjectId()) { DimensionalRiftManager.getInstance().showHtmlFile(player, "data/html/seven_signs/rift/NotPartyLeader.htm", npc); return; } for (L2PcInstance p : player.getParty().getMembers()) { teleportToWaitingRoom(p); } killRift(); } protected void teleportToNextRoom(L2PcInstance player) { if (_choosenRoom == -1) { FastList emptyRooms; do { emptyRooms = DimensionalRiftManager.getInstance().getFreeRooms(_type); // Do not tp in the same room a second time emptyRooms.removeAll(_completedRooms); // If no room left, find any empty if (emptyRooms.isEmpty()) { emptyRooms = DimensionalRiftManager.getInstance().getFreeRooms(_type); } _choosenRoom = emptyRooms.get(Rnd.get(1, emptyRooms.size()) - 1); } while (DimensionalRiftManager.getInstance().getRoom(_type, _choosenRoom).isPartyInside()); } DimensionalRiftManager.getInstance().getRoom(_type, _choosenRoom).setPartyInside(true); checkBossRoom(_choosenRoom); int[] coords = getRoomCoord(_choosenRoom); player.teleToLocation(new Location(coords[0], coords[1], coords[2])); } protected void teleportToWaitingRoom(L2PcInstance player) { DimensionalRiftManager.getInstance().teleportToWaitingRoom(player); final Quest riftQuest = QuestManager.getInstance().getQuest(635); if (riftQuest != null) { final QuestState qs = player.getQuestState(riftQuest.getName()); if ((qs != null) && qs.isCond(1)) { qs.exitQuest(true, true); } } } public void killRift() { _completedRooms = null; if (_party != null) { _party.setDimensionalRift(null); } _party = null; revivedInWaitingRoom = null; deadPlayers = null; if (earthQuakeTask != null) { earthQuakeTask.cancel(false); earthQuakeTask = null; } DimensionalRiftManager.getInstance().getRoom(_type, _choosenRoom).unspawn().setPartyInside(false); DimensionalRiftManager.getInstance().killRift(this); } public Timer getTeleportTimer() { return teleporterTimer; } public TimerTask getTeleportTimerTask() { return teleporterTimerTask; } public Timer getSpawnTimer() { return spawnTimer; } public TimerTask getSpawnTimerTask() { return spawnTimerTask; } public void setTeleportTimer(Timer t) { teleporterTimer = t; } public void setTeleportTimerTask(TimerTask tt) { teleporterTimerTask = tt; } public void setSpawnTimer(Timer t) { spawnTimer = t; } public void setSpawnTimerTask(TimerTask st) { spawnTimerTask = st; } private long calcTimeToNextJump() { int time = Rnd.get(Config.RIFT_AUTO_JUMPS_TIME_MIN, Config.RIFT_AUTO_JUMPS_TIME_MAX) * 1000; if (isBossRoom) { return (long) (time * Config.RIFT_BOSS_ROOM_TIME_MUTIPLY); } return time; } public void memberDead(L2PcInstance player) { if (!deadPlayers.contains(player)) { deadPlayers.add(player); } } public void memberRessurected(L2PcInstance player) { if (deadPlayers.contains(player)) { deadPlayers.remove(player); } } public void usedTeleport(L2PcInstance player) { if (!revivedInWaitingRoom.contains(player)) { revivedInWaitingRoom.add(player); } if (!deadPlayers.contains(player)) { deadPlayers.add(player); } if ((_party.getMemberCount() - revivedInWaitingRoom.size()) < Config.RIFT_MIN_PARTY_SIZE) { // int pcm = _party.getMemberCount(); // int rev = revivedInWaitingRoom.size(); // int min = Config.RIFT_MIN_PARTY_SIZE; for (L2PcInstance p : _party.getMembers()) { if ((p != null) && !revivedInWaitingRoom.contains(p)) { teleportToWaitingRoom(p); } } killRift(); } } public FastList getDeadMemberList() { return deadPlayers; } public FastList getRevivedAtWaitingRoom() { return revivedInWaitingRoom; } public void checkBossRoom(byte room) { isBossRoom = DimensionalRiftManager.getInstance().getRoom(_type, room).isBossRoom(); } public int[] getRoomCoord(byte room) { return DimensionalRiftManager.getInstance().getRoom(_type, room).getTeleportCoorinates(); } public byte getMaxJumps() { if ((Config.RIFT_MAX_JUMPS <= 8) && (Config.RIFT_MAX_JUMPS >= 1)) { return (byte) Config.RIFT_MAX_JUMPS; } return 4; } }