/* * 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 <http://www.gnu.org/licenses/>. */ package com.l2jserver.gameserver.model.entity; import java.util.Calendar; import java.util.concurrent.ScheduledFuture; import java.util.logging.Logger; import com.l2jserver.Config; import com.l2jserver.gameserver.Announcements; import com.l2jserver.gameserver.ThreadPoolManager; import com.l2jserver.gameserver.datatables.MessageTable; /** * @author FBIagent */ public class TvTManager { protected static final Logger _log = Logger.getLogger(TvTManager.class.getName()); /** Task for event cycles<br> */ private TvTStartTask _task; /** * New instance only by getInstance()<br> */ protected TvTManager() { if (Config.TVT_EVENT_ENABLED) { TvTEvent.init(); scheduleEventStart(); _log.info("TvTEventEngine[TvTManager.TvTManager()]: Started."); } else { _log.info("TvTEventEngine[TvTManager.TvTManager()]: Engine is disabled."); } } /** * Initialize new/Returns the one and only instance<br> * <br> * @return TvTManager<br> */ public static TvTManager getInstance() { return SingletonHolder._instance; } /** * Starts TvTStartTask */ public void scheduleEventStart() { try { Calendar currentTime = Calendar.getInstance(); Calendar nextStartTime = null; Calendar testStartTime = null; for (String timeOfDay : Config.TVT_EVENT_INTERVAL) { // Creating a Calendar object from the specified interval value testStartTime = Calendar.getInstance(); testStartTime.setLenient(true); String[] splitTimeOfDay = timeOfDay.split(":"); testStartTime.set(Calendar.HOUR_OF_DAY, Integer.parseInt(splitTimeOfDay[0])); testStartTime.set(Calendar.MINUTE, Integer.parseInt(splitTimeOfDay[1])); // If the date is in the past, make it the next day (Example: Checking for "1:00", when the time is 23:57.) if (testStartTime.getTimeInMillis() < currentTime.getTimeInMillis()) { testStartTime.add(Calendar.DAY_OF_MONTH, 1); } // Check for the test date to be the minimum (smallest in the specified list) if ((nextStartTime == null) || (testStartTime.getTimeInMillis() < nextStartTime.getTimeInMillis())) { nextStartTime = testStartTime; } } if (nextStartTime != null) { _task = new TvTStartTask(nextStartTime.getTimeInMillis()); ThreadPoolManager.getInstance().executeGeneral(_task); } } catch (Exception e) { _log.warning("TvTEventEngine[TvTManager.scheduleEventStart()]: Error figuring out a start time. Check TvTEventInterval in config file."); } } public void teamReInit() { // TvTEvent.setTvTPattern() はXML読み込み、実行したいTvTPatternIdを選択、チームを再定義します。falseは例外が流れたとき。 boolean setTvTPatternLegalFlag = TvTEvent.setTvTPattern(); if (setTvTPatternLegalFlag == false) { _log.warning("TvTEventEngine[TvTManager.run()]: Error setTvTPattern"); scheduleEventStart(); return; } } /** * Method to start participation */ public void startReg() { // TvTEvent.startParticipation() は参加受付NPCをSpawnさせTvTEventsetState(EventState.PARTICIPATING)する。falseは例外が流れたとき。 boolean participationLegalFlag = TvTEvent.startParticipation(); if (participationLegalFlag == false) { // TVTイベント:イベントがキャンセルされた。 // TvT Event: Event was cancelled. Announcements.getInstance().announceToAll(MessageTable.Messages[464].getMessage()); _log.warning("TvTEventEngine[TvTManager.run()]: Error spawning event npc for participation."); scheduleEventStart(); return; } TvTPattern pattern = TvTPatternContainer.getCurrentPattern(); // TVTイベント:登録はのためにオープン;分 // TvT Event: Registration opened for ; minute(s). Announcements.getInstance().announceToAll(MessageTable.Messages[465].getExtra(1) + pattern.TvTEventParticipationTime + MessageTable.Messages[465].getExtra(2)); // schedule registration end _task.setStartTime(System.currentTimeMillis() + (60000L * pattern.TvTEventParticipationTime)); ThreadPoolManager.getInstance().executeGeneral(_task); } /** * Method to pre start the fight */ public void startPreEvent() { // TvTEvent.startFight() は // * 1. stateをEventState.STARTINGにする<br> // * 2. チームのバランスを調整する<br> // * 3. 参加者が十分いない時はfalseを返し<br> // * 4. 参加費を徴収<br> // * 5. インスタントダンジョン(ID)をコンフィグに応じて生成<br> // * 6. ドアをコンフィグに応じて閉じる<br> // * 7. stateをEventState.STARTEDにする<br> // * 8. プレイヤーをテレポーターにセット。<br> // する。(汗) falseは参加の不足があったとき。 boolean preFightLegalFlag = TvTEvent.startPreFight(); if (preFightLegalFlag == false) { // TVTイベント:イベントによる参加の不足のためキャンセル。 // TvT Event: Event cancelled due to lack of Participation. Announcements.getInstance().announceToAll(MessageTable.Messages[466].getMessage()); _log.info("TvTEventEngine[TvTManager.run()]: Lack of registration, abort event."); scheduleEventStart(); } // TvT Event: Teleporting participants to an arena in ; second(s). // TVTイベント:アリーナ内に参加者をテレポート;秒 TvTEvent.sysMsgToAllParticipants(MessageTable.Messages[467].getExtra(1) + Config.TVT_EVENT_START_LEAVE_TELEPORT_DELAY + MessageTable.Messages[467].getExtra(2)); _task.setStartTime(System.currentTimeMillis() + (60000L * TvTPatternContainer.getCurrentPattern().TvTEventMeetingTime)); ThreadPoolManager.getInstance().executeGeneral(_task); } /** * Method to start the fight */ public void startEvent() { // TvTEvent.startFight() は 特に何もしないがチャットの制限等が掛かるようにする TvTEvent.startFight(); _task.setStartTime(System.currentTimeMillis() + (60000L * TvTPatternContainer.getCurrentPattern().TvTEventRunningTime)); ThreadPoolManager.getInstance().executeGeneral(_task); } /** * Method to end the event and reward */ public void endEvent() { // TvTEvent.calculateRewardsは、報酬を付与します。 TvTEvent.calculateRewards(); Announcements.getInstance().announceToAll(TvTEvent.getResultMessage()); // TvT Event: Teleporting back to the registration npc in ; second(s). // TVTイベント:バック登録全人代でのテレポート;秒 TvTEvent.sysMsgToAllParticipants(MessageTable.Messages[468].getExtra(1) + Config.TVT_EVENT_START_LEAVE_TELEPORT_DELAY + MessageTable.Messages[468].getExtra(2)); TvTEvent.stopFight(); scheduleEventStart(); } public void skipDelay() { if (_task.nextRun.cancel(false)) { _task.setStartTime(System.currentTimeMillis()); ThreadPoolManager.getInstance().executeGeneral(_task); } } /** * Class for TvT cycles */ class TvTStartTask implements Runnable { private long _startTime; public ScheduledFuture<?> nextRun; public TvTStartTask(long startTime) { _startTime = startTime; } public void setStartTime(long startTime) { _startTime = startTime; } @Override public void run() { int delay = (int) Math.round((_startTime - System.currentTimeMillis()) / 1000.0); if (delay > 0) { announce(delay); } int nextMsg = 0; if (delay > 3600) { nextMsg = delay - 3600; } else if (delay > 1800) { nextMsg = delay - 1800; } else if (delay > 900) { nextMsg = delay - 900; } else if (delay > 600) { nextMsg = delay - 600; } else if (delay > 300) { nextMsg = delay - 300; } else if (delay > 60) { nextMsg = delay - 60; } else if (delay > 5) { nextMsg = delay - 5; } else if (delay > 0) { nextMsg = delay; } else { // start if (TvTEvent.isInactive()) { teamReInit(); startReg(); } else if (TvTEvent.isParticipating()) { startPreEvent(); } else if (TvTEvent.isMeeting()) { startEvent(); } else { endEvent(); } } if (delay > 0) { nextRun = ThreadPoolManager.getInstance().scheduleGeneral(this, nextMsg * 1000); } } private void announce(long time) { if ((time >= 3600) && ((time % 3600) == 0)) { if (TvTEvent.isParticipating()) { /* MessageTable Announcements.getInstance().announceToAll("TvT Event: " + (time / 60 / 60) + " hour(s) until registration is closed!"); */ Announcements.getInstance().announceToAll(MessageTable.Messages[469].getMessage() + (time / 60 / 60) + MessageTable.Messages[470].getMessage()); } else if (TvTEvent.isMeeting()) { TvTEvent.sysMsgToAllParticipants("TvT Event:" + (time / 60 / 60) + " hour(s) until meeting is finished!"); } else if (TvTEvent.isStarted()) { /* MessageTable TvTEvent.sysMsgToAllParticipants("TvT Event: " + (time / 60 / 60) + " hour(s) until event is finished!"); */ TvTEvent.sysMsgToAllParticipants(MessageTable.Messages[469].getMessage() + (time / 60 / 60) + MessageTable.Messages[471].getMessage()); } } else if (time >= 60) { if (TvTEvent.isParticipating()) { /* MessageTable Announcements.getInstance().announceToAll("TvT Event: " + (time / 60) + " minute(s) until registration is closed!"); */ Announcements.getInstance().announceToAll(MessageTable.Messages[469].getMessage() + (time / 60) + MessageTable.Messages[472].getMessage()); } else if (TvTEvent.isMeeting()) { TvTEvent.sysMsgToAllParticipants("TvT Event:" + (time / 60) + " minute(s) until meeting is finished!"); } else if (TvTEvent.isStarted()) { /* MessageTable TvTEvent.sysMsgToAllParticipants("TvT Event: " + (time / 60) + " minute(s) until the event is finished!"); */ TvTEvent.sysMsgToAllParticipants(MessageTable.Messages[469].getMessage() + (time / 60) + MessageTable.Messages[473].getMessage()); } } else { if (TvTEvent.isParticipating()) { /* MessageTable Announcements.getInstance().announceToAll("TvT Event: " + time + " second(s) until registration is closed!"); */ Announcements.getInstance().announceToAll(MessageTable.Messages[469].getMessage() + time + MessageTable.Messages[474].getMessage()); } else if (TvTEvent.isMeeting()) { TvTEvent.sysMsgToAllParticipants("TvT Event:" + time + " second(s) until meeting is finished!"); } else if (TvTEvent.isStarted()) { /* MessageTable TvTEvent.sysMsgToAllParticipants("TvT Event: " + time + " second(s) until the event is finished!"); */ TvTEvent.sysMsgToAllParticipants(MessageTable.Messages[469].getMessage() + time + MessageTable.Messages[475].getMessage()); } } } } private static class SingletonHolder { protected static final TvTManager _instance = new TvTManager(); } }