Kaynağa Gözat

Olympiad Update. Requires [DP5697].

Check http://www.l2jserver.com/forum/thread.php?threadid=32301 for details.
GodKratos 16 yıl önce
ebeveyn
işleme
245652c9ab
39 değiştirilmiş dosya ile 3559 ekleme ve 2704 silme
  1. 15 0
      L2_GameServer/java/config/General.properties
  2. 9 7
      L2_GameServer/java/net/sf/l2j/Config.java
  3. 1 0
      L2_GameServer/java/net/sf/l2j/gameserver/GameServer.java
  4. 0 2458
      L2_GameServer/java/net/sf/l2j/gameserver/Olympiad.java
  5. 5 11
      L2_GameServer/java/net/sf/l2j/gameserver/Shutdown.java
  6. 3 10
      L2_GameServer/java/net/sf/l2j/gameserver/handler/admincommandhandlers/AdminAdmin.java
  7. 6 3
      L2_GameServer/java/net/sf/l2j/gameserver/handler/skillhandlers/Blow.java
  8. 3 0
      L2_GameServer/java/net/sf/l2j/gameserver/handler/skillhandlers/Pdam.java
  9. 9 3
      L2_GameServer/java/net/sf/l2j/gameserver/handler/usercommandhandlers/OlympiadStat.java
  10. 1 1
      L2_GameServer/java/net/sf/l2j/gameserver/model/L2ItemInstance.java
  11. 2 2
      L2_GameServer/java/net/sf/l2j/gameserver/model/L2Summon.java
  12. 1 1
      L2_GameServer/java/net/sf/l2j/gameserver/model/actor/instance/L2CubicInstance.java
  13. 5 5
      L2_GameServer/java/net/sf/l2j/gameserver/model/actor/instance/L2NpcInstance.java
  14. 31 28
      L2_GameServer/java/net/sf/l2j/gameserver/model/actor/instance/L2OlympiadManagerInstance.java
  15. 29 20
      L2_GameServer/java/net/sf/l2j/gameserver/model/actor/instance/L2PcInstance.java
  16. 0 16
      L2_GameServer/java/net/sf/l2j/gameserver/model/actor/instance/L2VillageMasterInstance.java
  17. 2 0
      L2_GameServer/java/net/sf/l2j/gameserver/model/actor/status/CharStatus.java
  18. 1 1
      L2_GameServer/java/net/sf/l2j/gameserver/model/entity/Hero.java
  19. 1 1
      L2_GameServer/java/net/sf/l2j/gameserver/model/entity/TvTEvent.java
  20. 3 1
      L2_GameServer/java/net/sf/l2j/gameserver/model/itemcontainer/Inventory.java
  21. 1501 0
      L2_GameServer/java/net/sf/l2j/gameserver/model/olympiad/Olympiad.java
  22. 1234 0
      L2_GameServer/java/net/sf/l2j/gameserver/model/olympiad/OlympiadGame.java
  23. 440 0
      L2_GameServer/java/net/sf/l2j/gameserver/model/olympiad/OlympiadManager.java
  24. 110 0
      L2_GameServer/java/net/sf/l2j/gameserver/model/olympiad/OlympiadStadium.java
  25. 22 20
      L2_GameServer/java/net/sf/l2j/gameserver/network/SystemMessageId.java
  26. 10 0
      L2_GameServer/java/net/sf/l2j/gameserver/network/clientpackets/Action.java
  27. 3 2
      L2_GameServer/java/net/sf/l2j/gameserver/network/clientpackets/EnterWorld.java
  28. 1 1
      L2_GameServer/java/net/sf/l2j/gameserver/network/clientpackets/Logout.java
  29. 5 0
      L2_GameServer/java/net/sf/l2j/gameserver/network/clientpackets/RequestBypassToServer.java
  30. 7 2
      L2_GameServer/java/net/sf/l2j/gameserver/network/clientpackets/RequestOlympiadMatchList.java
  31. 1 1
      L2_GameServer/java/net/sf/l2j/gameserver/network/clientpackets/RequestRestart.java
  32. 7 7
      L2_GameServer/java/net/sf/l2j/gameserver/network/clientpackets/UseItem.java
  33. 1 1
      L2_GameServer/java/net/sf/l2j/gameserver/network/serverpackets/ExHeroList.java
  34. 43 0
      L2_GameServer/java/net/sf/l2j/gameserver/network/serverpackets/ExOlympiadMatchEnd.java
  35. 6 6
      L2_GameServer/java/net/sf/l2j/gameserver/network/serverpackets/ExOlympiadSpelledInfo.java
  36. 17 15
      L2_GameServer/java/net/sf/l2j/gameserver/network/serverpackets/ExOlympiadUserInfo.java
  37. 0 69
      L2_GameServer/java/net/sf/l2j/gameserver/network/serverpackets/ExOlympiadUserInfoSpectator.java
  38. 20 0
      L2_GameServer/java/net/sf/l2j/gameserver/skills/funcs/FuncEnchant.java
  39. 4 12
      L2_GameServer/java/net/sf/l2j/gameserver/taskmanager/tasks/TaskOlympiadSave.java

+ 15 - 0
L2_GameServer/java/config/General.properties

@@ -402,9 +402,24 @@ AltOlyGPPerPoint = 1000
 # Noblesse points awarded to Heros. Retail 300
 AltOlyHeroPoints = 300
 
+# Hero tables show last months winners or current status
+# Retail = true
+AltOlyShowMonthlyWinners = true
+
+# Olympiad Managers announce each start of fight
+# Retail = true
+AltOlyAnnounceGames = true
+
 # Restrict same item in olympiad. ItemID's need to be separated whit comma (ex. 1,200,350)
 AltOlyRestrictedItems = 0
 
+# Enchant limit for Olympiad battles.
+# (Maximum enchant level allowed for an item to be equipped, -1 to disable)
+AltOlyEnchantLimit = -1
+
+# Log all Olympiad fights and outcome to olympiad.csv file.
+AlyOlyLogFights = false
+
 #============================================================#
 #                           Manor                            #
 #============================================================#

+ 9 - 7
L2_GameServer/java/net/sf/l2j/Config.java

@@ -440,8 +440,6 @@ public final class Config
     public static int		ALT_OLY_MIN;
     public static long		ALT_OLY_CPERIOD;
     public static long		ALT_OLY_BATTLE;
-    public static long		ALT_OLY_BWAIT;
-    public static long		ALT_OLY_IWAIT;
     public static long		ALT_OLY_WPERIOD;
     public static long		ALT_OLY_VPERIOD;
     public static int		ALT_OLY_CLASSED;
@@ -453,8 +451,11 @@ public final class Config
     public static int		ALT_OLY_GP_PER_POINT;
     public static int		ALT_OLY_MIN_POINT_FOR_EXCH;
     public static int		ALT_OLY_HERO_POINTS;
-    public static String	ALT_OLY_RESTRICTED_ITEMS;
+    public static boolean	ALT_OLY_LOG_FIGHTS;
+    public static boolean	ALT_OLY_SHOW_MONTHLY_WINNERS;
+    public static boolean	ALT_OLY_ANNOUNCE_GAMES;
     public static List<Integer> LIST_OLY_RESTRICTED_ITEMS = new FastList<Integer>();
+    public static int		ALT_OLY_ENCHANT_LIMIT;
     public static int		ALT_MANOR_REFRESH_TIME;
     public static int		ALT_MANOR_REFRESH_MIN;
     public static int		ALT_MANOR_APPROVE_TIME;
@@ -1567,8 +1568,6 @@ public final class Config
 	                ALT_OLY_MIN									= Integer.parseInt(General.getProperty("AltOlyMin","00"));
 	                ALT_OLY_CPERIOD								= Long.parseLong(General.getProperty("AltOlyCPeriod","21600000"));
 	                ALT_OLY_BATTLE								= Long.parseLong(General.getProperty("AltOlyBattle","360000"));
-	                ALT_OLY_BWAIT								= Long.parseLong(General.getProperty("AltOlyBWait","600000"));
-	                ALT_OLY_IWAIT								= Long.parseLong(General.getProperty("AltOlyIWait","300000"));
 	                ALT_OLY_WPERIOD								= Long.parseLong(General.getProperty("AltOlyWPeriod","604800000"));
 	                ALT_OLY_VPERIOD								= Long.parseLong(General.getProperty("AltOlyVPeriod","86400000"));
 	                ALT_OLY_CLASSED								= Integer.parseInt(General.getProperty("AltOlyClassedParticipants","5"));
@@ -1580,12 +1579,15 @@ public final class Config
 	                ALT_OLY_GP_PER_POINT						= Integer.parseInt(General.getProperty("AltOlyGPPerPoint","1000"));
 	                ALT_OLY_MIN_POINT_FOR_EXCH					= Integer.parseInt(General.getProperty("AltOlyMinPointForExchange","50"));
 	                ALT_OLY_HERO_POINTS							= Integer.parseInt(General.getProperty("AltOlyHeroPoints","300"));
-	                ALT_OLY_RESTRICTED_ITEMS					= General.getProperty("AltOlyRestrictedItems","0");
+	                ALT_OLY_LOG_FIGHTS							= Boolean.parseBoolean(General.getProperty("AlyOlyLogFights","false"));
+	                ALT_OLY_SHOW_MONTHLY_WINNERS				= Boolean.parseBoolean(General.getProperty("AltOlyShowMonthlyWinners","true"));
+	                ALT_OLY_ANNOUNCE_GAMES						= Boolean.parseBoolean(General.getProperty("AltOlyAnnounceGames","true"));
 	                LIST_OLY_RESTRICTED_ITEMS					= new FastList<Integer>();
-	                                							for (String id : ALT_OLY_RESTRICTED_ITEMS.split(","))
+	                                							for (String id : General.getProperty("AltOlyRestrictedItems","0").split(","))
 	                                							{
 	                                								LIST_OLY_RESTRICTED_ITEMS.add(Integer.parseInt(id));
 	                                							}
+	                ALT_OLY_ENCHANT_LIMIT						= Integer.parseInt(General.getProperty("AltOlyEnchantLimit","-1"));
 	                ALT_MANOR_REFRESH_TIME						= Integer.parseInt(General.getProperty("AltManorRefreshTime","20"));
 	                ALT_MANOR_REFRESH_MIN						= Integer.parseInt(General.getProperty("AltManorRefreshMin","00"));
 	                ALT_MANOR_APPROVE_TIME						= Integer.parseInt(General.getProperty("AltManorApproveTime","6"));

+ 1 - 0
L2_GameServer/java/net/sf/l2j/gameserver/GameServer.java

@@ -100,6 +100,7 @@ import net.sf.l2j.gameserver.model.L2PetDataTable;
 import net.sf.l2j.gameserver.model.L2World;
 import net.sf.l2j.gameserver.model.entity.Hero;
 import net.sf.l2j.gameserver.model.entity.TvTManager;
+import net.sf.l2j.gameserver.model.olympiad.Olympiad;
 import net.sf.l2j.gameserver.network.L2GameClient;
 import net.sf.l2j.gameserver.network.L2GamePacketHandler;
 import net.sf.l2j.gameserver.pathfinding.PathFinding;

+ 0 - 2458
L2_GameServer/java/net/sf/l2j/gameserver/Olympiad.java

@@ -1,2458 +0,0 @@
-/*
- * 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/>.
- */
-
-/**
- * @author godson
- */
-
-package net.sf.l2j.gameserver;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.sql.Connection;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.util.Calendar;
-import java.util.Map;
-import java.util.Properties;
-import java.util.concurrent.ScheduledFuture;
-import java.util.logging.Logger;
-
-import javolution.util.FastMap;
-import net.sf.l2j.Config;
-import net.sf.l2j.L2DatabaseFactory;
-import net.sf.l2j.gameserver.datatables.DoorTable;
-import net.sf.l2j.gameserver.datatables.HeroSkillTable;
-import net.sf.l2j.gameserver.datatables.NpcTable;
-import net.sf.l2j.gameserver.datatables.SpawnTable;
-import net.sf.l2j.gameserver.instancemanager.OlympiadStadiaManager;
-import net.sf.l2j.gameserver.model.L2ItemInstance;
-import net.sf.l2j.gameserver.model.L2Party;
-import net.sf.l2j.gameserver.model.L2Skill;
-import net.sf.l2j.gameserver.model.L2Spawn;
-import net.sf.l2j.gameserver.model.L2Summon;
-import net.sf.l2j.gameserver.model.L2World;
-import net.sf.l2j.gameserver.model.actor.instance.L2CubicInstance;
-import net.sf.l2j.gameserver.model.actor.instance.L2PcInstance;
-import net.sf.l2j.gameserver.model.actor.instance.L2PetInstance;
-import net.sf.l2j.gameserver.model.entity.Hero;
-import net.sf.l2j.gameserver.model.entity.TvTEvent;
-import net.sf.l2j.gameserver.model.itemcontainer.Inventory;
-import net.sf.l2j.gameserver.network.SystemMessageId;
-import net.sf.l2j.gameserver.network.serverpackets.ExAutoSoulShot;
-import net.sf.l2j.gameserver.network.serverpackets.ExOlympiadMode;
-import net.sf.l2j.gameserver.network.serverpackets.ExOlympiadUserInfoSpectator;
-import net.sf.l2j.gameserver.network.serverpackets.InventoryUpdate;
-import net.sf.l2j.gameserver.network.serverpackets.SystemMessage;
-import net.sf.l2j.gameserver.templates.StatsSet;
-import net.sf.l2j.gameserver.templates.chars.L2NpcTemplate;
-import net.sf.l2j.util.L2FastList;
-import net.sf.l2j.util.Rnd;
-
-public class Olympiad
-{
-	/**
-	 *
-	 * @author  ascharot
-	 * 
-	 */
-	private class OlympiadGameTask implements Runnable
-	{
-		public L2OlympiadGame _game = null;
-        private SystemMessage _sm;
-        private SystemMessage _sm2;
-        
-		private boolean _terminated = false;
-		public boolean isTerminated()
-		{
-			return _terminated;
-		}
-		
-		private boolean _started = false;
-		public boolean isStarted()
-		{
-			return _started;
-		}
-		
-		public OlympiadGameTask(L2OlympiadGame game)
-		{
-			_game = game;
-		}
-		
-		protected boolean checkBattleStatus()
-    	{
-			boolean _pOneCrash = (_game._playerOne == null || _game._playerOneDisconnected);
-			boolean _pTwoCrash = (_game._playerTwo == null || _game._playerTwoDisconnected);
-			if(_pOneCrash || _pTwoCrash || _game._aborted) {
-	    		return false; 
-			}
-			return true;
-    	}
-		
-		protected boolean checkStatus()
-    	{
-			boolean _pOneCrash = (_game._playerOne == null || _game._playerOneDisconnected);
-			boolean _pTwoCrash = (_game._playerTwo == null || _game._playerTwoDisconnected);
-			
-			StatsSet playerOneStat;
-			StatsSet playerTwoStat;
-			
-			playerOneStat = _nobles.get(_game._playerOneID);
-			playerTwoStat = _nobles.get(_game._playerTwoID);
-			
-			int playerOnePlayed = playerOneStat.getInteger(COMP_DONE);
-			int playerTwoPlayed = playerTwoStat.getInteger(COMP_DONE);
-			
-			if(_pOneCrash || _pTwoCrash || _game._aborted) {
-	    		if (_pOneCrash && !_pTwoCrash){
-					try{						
-						int playerOnePoints = playerOneStat.getInteger(POINTS);
-						int transferPoints = playerOnePoints / 5;
-						playerOneStat.set(POINTS, playerOnePoints - transferPoints);
-						
-						if (Config.DEBUG)
-							_log.info("Olympia Result: "+_game._playerOneName+" vs "+_game._playerTwoName+" ... "+_game._playerOneName+" lost "+transferPoints+" points for crash");						
-						
-						int playerTwoPoints = playerTwoStat.getInteger(POINTS);
-						playerTwoStat.set(POINTS, playerTwoPoints + transferPoints);
-						
-						if (Config.DEBUG)
-							_log.info("Olympia Result: "+_game._playerOneName+" vs "+_game._playerTwoName+" ... "+_game._playerTwoName+" Win "+transferPoints+" points");
-					
-						_sm = new SystemMessage(SystemMessageId.C1_HAS_WON_THE_GAME);
-						_sm2 = new SystemMessage(SystemMessageId.S1_HAS_GAINED_S2_OLYMPIAD_POINTS);
-						_sm.addString(_game._playerTwoName);
-						broadcastMessage(_sm, true);
-						_sm2.addString(_game._playerTwoName);
-						_sm2.addNumber(transferPoints);
-						broadcastMessage(_sm2, true);
-					} catch(Exception e){e.printStackTrace();}
-
-	    		}
-	    		if (_pTwoCrash && !_pOneCrash){
-	    			try{
-	    				int playerTwoPoints = playerTwoStat.getInteger(POINTS);
-	    				int transferPoints = playerTwoPoints / 5;
-	    				playerTwoStat.set(POINTS, playerTwoPoints - transferPoints);
-	    				
-	    				if (Config.DEBUG)
-	    					_log.info("Olympia Result: "+_game._playerTwoName+" vs "+_game._playerOneName+" ... "+_game._playerTwoName+" lost "+transferPoints+" points for crash");
-	    				
-	    				int playerOnePoints = playerOneStat.getInteger(POINTS);
-	    				playerOneStat.set(POINTS, playerOnePoints + transferPoints);
-	    				
-	    				if (Config.DEBUG)
-	    					_log.info("Olympia Result: "+_game._playerTwoName+" vs "+_game._playerOneName+" ... "+_game._playerOneName+" Win "+transferPoints+" points");
-					
-	    				_sm = new SystemMessage(SystemMessageId.C1_HAS_WON_THE_GAME);
-	    				_sm2 = new SystemMessage(SystemMessageId.S1_HAS_GAINED_S2_OLYMPIAD_POINTS);
-	    				_sm.addString(_game._playerOneName);
-	    				broadcastMessage(_sm, true);
-	    				_sm2.addString(_game._playerOneName);
-	    				_sm2.addNumber(transferPoints);
-	                	broadcastMessage(_sm2, true);
-	    			} catch(Exception e){e.printStackTrace();}
-	    		}
-	    		playerOneStat.set(COMP_DONE, playerOnePlayed + 1);
-	    		playerTwoStat.set(COMP_DONE, playerTwoPlayed + 1);
-	    		
-	    		_terminated = true;
-	    		_game._gamestarted = false;
-    			_game.closeDoors();    		
-    			_game.PlayersStatusBack();
-    			try{
-    				_game.portPlayersBack();
-    			}catch(Exception e){e.printStackTrace();}
-                _game = null;
-				return false; 
-			}
-			return true;
-    	}
-		
-		public void run()
-		{
-			_started = true;
-			if(_game != null)
-			{
-				if(_game._playerOne != null && _game._playerTwo != null)
-				{
-					//Waiting for teleport to arena
-		    		for (int i=120;i>10;i-=5)
-		    		{
-		    			switch(i) {
-		    				case 120:
-		    				case 60:
-		    				case 30:
-		    				case 15: 
-		    					_game.sendMessageToPlayers(false,i);
-		    					break;
-		    			}
-						try{ Thread.sleep(5000); }catch (InterruptedException e){}
-		    		}
-		    		for (int i=5;i>0;i--)
-		    		{
-		    			_game.sendMessageToPlayers(false,i);		    			
-		    			try{ Thread.sleep(1000); }catch (InterruptedException e){}
-		    		}
-		    		
-		    		//Checking for openents and teleporting to arena
-		    		if(!checkStatus()) { return; }
-			    	_game.closeDoors();
-		            _game.removals();
-		    		_game.portPlayersToArena();
-		    		try{ Thread.sleep(5000); }catch (InterruptedException e){}
-		    		
-		            synchronized(this){
-		            if(!_battleStarted)
-			            	_battleStarted = true;
-		            }
-		    		for (int i=60;i>10;i-=10)
-		    		{
-	    				_game.sendMessageToPlayers(true,i);	    				
-		    			try{ Thread.sleep(10000); }catch (InterruptedException e){}		    			
-	    				if (i==20) 
-	    				{ 
-	    					_game._damageP1 = 0;
-	    					_game._damageP2 = 0;
-	    					_game.openDoors();
-	    					_game.sendMessageToPlayers(true,10);
-	    					try{ Thread.sleep(5000); }catch (InterruptedException e){}
-	    				}
-		    		}
-		    		for (int i=5;i>0;i--)
-		    		{
-		    			_game.sendMessageToPlayers(true,i);		    			
-		    			try{ Thread.sleep(1000); }catch (InterruptedException e){}
-		    		}
-		    		
-		    		if(!checkStatus()) { return; }
-		    		UnSpawnBuffer(_game._spawnOne);
-		    		UnSpawnBuffer(_game._spawnTwo);
-		    		_game._playerOne.sendPacket(new ExOlympiadUserInfoSpectator(_game._playerTwo, 1));
-		    		_game._playerTwo.sendPacket(new ExOlympiadUserInfoSpectator(_game._playerOne, 1));
-		            if (_game._spectators != null)
-		            {
-		                for (L2PcInstance  spec : _game.getSpectators())
-		                {
-		                    try {         
-		                    	spec.sendPacket(new ExOlympiadUserInfoSpectator(_game._playerTwo, 2));
-		                    	spec.sendPacket(new ExOlympiadUserInfoSpectator(_game._playerOne, 1));
-		                    } catch (NullPointerException e) {}
-		                }
-		            }
-		    		_game.makeCompetitionStart();		    		
-		    			
-		    		//Wait 3 mins (Battle)
-		    		for(int i=0; i<BATTLE_PERIOD; i += 10000)
-		    		{
-			    		try{
-			    			Thread.sleep(10000);
-			    			//If game haveWinner thean stop waiting battle_period and validate winner
-			    			if(_game.haveWinner() || !checkBattleStatus())
-			    				break;
-			    		} catch (InterruptedException e){}
-		    		}		    		
-		    		if(!checkStatus()) { return; }
-		    		_terminated = true;
-		    		_game._gamestarted = false;
-		    		try{
-		    			_game.validateWinner();
-			    		_game.PlayersStatusBack();
-			    		_game.removals();
-		    			_game.portPlayersBack();
-		    		}catch(Exception e){e.printStackTrace();}
-	                _game = null;
-				}
-			}
-		}
-        private void broadcastMessage(SystemMessage sm, boolean toAll)
-        {
-        	try { 
-        		_game._playerOne.sendPacket(sm);
-        		_game._playerTwo.sendPacket(sm); 
-        	} catch (Exception e) {}
-        	
-            if (toAll && _game._spectators != null)
-            {
-                for (L2PcInstance spec : _game._spectators)
-                {
-                    try { spec.sendPacket(sm); } catch (NullPointerException e) {}
-                }
-            }
-        }
-	}
-
-	protected static final Logger _log = Logger.getLogger(Olympiad.class.getName());
-
-    private static Olympiad _instance;
-    
-    protected static Map<Integer, StatsSet> _nobles;
-    protected static L2FastList<StatsSet> _heroesToBe;
-    protected static L2FastList<L2PcInstance> _nonClassBasedRegisters;
-    protected static Map<Integer, L2FastList<L2PcInstance>> _classBasedRegisters;
-
-    private static final String OLYMPIAD_DATA_FILE = "config/olympiad.properties";
-    public static final String OLYMPIAD_HTML_FILE = "data/html/olympiad/";
-    private static final String OLYMPIAD_LOAD_NOBLES = "SELECT * FROM olympiad_nobles";
-    private static final String OLYMPIAD_SAVE_NOBLES = "INSERT INTO olympiad_nobles " +
-            "VALUES (?,?,?,?,?)";
-    private static final String OLYMPIAD_UPDATE_NOBLES = "UPDATE olympiad_nobles SET " +
-            "olympiad_points = ?, competitions_done = ? WHERE charId = ?";
-    private static final String OLYMPIAD_GET_HEROS = "SELECT charId, char_name FROM " +
-    		"olympiad_nobles WHERE class_id = ? AND competitions_done >= 9 ORDER BY " +
-    		"olympiad_points DESC, competitions_done DESC";
-    private static final String GET_EACH_CLASS_LEADER = "SELECT char_name FROM " +
-    		"olympiad_nobles WHERE class_id = ? ORDER BY olympiad_points DESC, " +
-    		"competitions_done DESC";
-    private static final String OLYMPIAD_DELETE_ALL = "DELETE FROM olympiad_nobles";
-    private static final int[] HERO_IDS = {88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,
-        106,107,108,109,110,111,112,113,114,115,116,117,118,131,132,133,134};
-
-    private static final int COMP_START = Config.ALT_OLY_START_TIME; // 6PM
-    private static final int COMP_MIN = Config.ALT_OLY_MIN; // 00 mins
-    private static final long COMP_PERIOD = Config.ALT_OLY_CPERIOD; // 6 hours
-    protected static final long BATTLE_PERIOD = Config.ALT_OLY_BATTLE; // 6 mins
-    protected static final long BATTLE_WAIT = Config.ALT_OLY_BWAIT; // 10mins
-    protected static final long INITIAL_WAIT = Config.ALT_OLY_IWAIT;  // 5mins
-    protected static final long WEEKLY_PERIOD = Config.ALT_OLY_WPERIOD; // 1 week
-    protected static final long VALIDATION_PERIOD = Config.ALT_OLY_VPERIOD; // 24 hours
-
-    /* FOR TESTING
-    private static final int COMP_START = 8; // 1PM - 2PM
-    private static final int COMP_MIN = 15; // 20mins
-    private static final long COMP_PERIOD = 7200000; // 2hours
-    private static final long BATTLE_PERIOD = 180000; // 3mins
-    private static final long BATTLE_WAIT = 600000; // 10mins
-    private static final long INITIAL_WAIT = 300000;  // 5mins
-    private static final long WEEKLY_PERIOD = 7200000; // 2 hours
-    private static final long VALIDATION_PERIOD = 3600000; // 1 hour */
-
-
-    private static final int DEFAULT_POINTS = 18;
-    protected static final int WEEKLY_POINTS = 3;
-
-    public static final String CHAR_ID = "charId";
-    public static final String CLASS_ID = "class_id";
-    public static final String CHAR_NAME = "char_name";
-    public static final String POINTS = "olympiad_points";
-    public static final String COMP_DONE = "competitions_done";
-    
-    public static DoorTable   _doorTable;
-    
-    protected long _olympiadEnd;
-    protected long _validationEnd;
-    protected int _period;
-    protected long _nextWeeklyChange;
-    protected int _currentCycle;
-    private long _compEnd;
-    private Calendar _compStart;
-    protected static boolean _inCompPeriod;
-    protected static boolean _isOlympiadEnd;
-    protected static boolean _compStarted = false;
-    protected static boolean _battleStarted;
-    protected static boolean _cycleTerminated;
-    protected ScheduledFuture<?> _scheduledCompStart;
-    protected ScheduledFuture<?> _scheduledCompEnd;
-    protected ScheduledFuture<?> _scheduledOlympiadEnd;
-    protected ScheduledFuture<?> _scheduledManagerTask;
-    protected ScheduledFuture<?> _scheduledWeeklyTask;
-    protected ScheduledFuture<?> _scheduledValdationTask;
-
-    public static class Stadia
-    {
-    	private boolean _freeToUse = true;
-    	public boolean isFreeToUse()
-    	{
-    		return _freeToUse;
-    	}
-    	public void setStadiaBusy()
-    	{
-    		_freeToUse = false;
-    	}
-    	public void setStadiaFree()
-    	{
-    		_freeToUse = true;
-    	}
-    	private int[] _coords = new int[3];
-    	private int[] _doors = new int[2];
-    	public int[] getCoordinates()
-    	{
-    		return _coords;
-    	}
-    	public int[] getDoorID()
-    	{
-    		return _doors;
-    	}
-    	public Stadia(int[] coords, int[] doors)
-    	{
-    		_coords = coords;
-    		_doors = doors;
-    	}
-    	public Stadia(int x, int y, int z, int d1, int d2)
-    	{
-    		_coords[0] = x;
-    		_coords[1] = y;
-    		_coords[2] = z;
-    		_doors[0] = d1;
-    		_doors[1] = d2;
-    	}
-    }
-    
-    protected static final Stadia[] STADIUMS = 
-    {
-    	new Stadia(-20838, -21075, -3028, 19170001, 19170002),
-    	new Stadia(-88000, -252637, -3331, 17100001, 17100002),
-    	new Stadia(-83760, -252637, -3331, 17100003, 17100004),
-    	new Stadia(-79600, -252637, -3331, 17100005, 17100006),
-    	new Stadia(-75648, -252637, -3331, 17100007, 17100008),
-    	new Stadia(-88000, -249762, -3331, 17100009, 17100010),
-    	new Stadia(-83760, -249762, -3331, 17100011, 17100012),
-    	new Stadia(-79600, -249762, -3331, 17100013, 17100014),
-    	new Stadia(-75648, -249762, -3331, 17100015, 17100016),
-    	new Stadia(-88000, -246951, -3331, 17100017, 17100018),
-    	new Stadia(-83760, -246951, -3331, 17100019, 17100020),
-    	new Stadia(-79600, -246951, -3331, 17100021, 17100022),
-    	new Stadia(-75648, -246951, -3331, 17100023, 17100024),
-    	new Stadia(-88000, -244290, -3331, 17100025, 17100026),
-    	new Stadia(-83760, -244290, -3331, 17100027, 17100028),
-    	new Stadia(-79600, -244290, -3331, 17100029, 17100030),
-    	new Stadia(-75648, -244290, -3331, 17100031, 17100032),
-    	new Stadia(-88000, -241490, -3331, 17100033, 17100034),
-    	new Stadia(-83760, -241490, -3331, 17100035, 17100036),
-    	new Stadia(-79600, -241490, -3331, 17100037, 17100038),
-    	new Stadia(-75648, -241490, -3331, 17100039, 17100040),
-    	new Stadia(-88000, -238825, -3331, 17100041, 17100042),
-    	new Stadia(-83760, -238825, -3331, 17100043, 17100044)
-    };
-
-    private static enum COMP_TYPE
-    {
-    	CLASSED,
-    	NON_CLASSED
-    }
-
-    protected static OlympiadManager _manager;
-
-    public static Olympiad getInstance()
-    {
-        if (_instance == null)
-            _instance = new Olympiad();
-        return _instance;
-    }
-
-    public Olympiad()
-    {
-    	try
-        {
-            load();
-        }
-        catch(IOException e)
-        {
-            e.printStackTrace();
-        }
-        catch(SQLException s)
-        {
-            s.printStackTrace();
-        }
-
-        if (_period == 0) init();
-    }
-
-    private void load() throws IOException, SQLException
-    {
-        _nobles = new FastMap<Integer, StatsSet>();
-
-        Properties OlympiadProperties = new Properties();
-        InputStream is =  new FileInputStream(new File("./" + OLYMPIAD_DATA_FILE));
-        OlympiadProperties.load(is);
-        is.close();
-
-        _currentCycle = Integer.parseInt(OlympiadProperties.getProperty("CurrentCycle", "1"));
-        _period = Integer.parseInt(OlympiadProperties.getProperty("Period", "0"));
-        _olympiadEnd = Long.parseLong(OlympiadProperties.getProperty("OlympiadEnd", "0"));
-        _validationEnd = Long.parseLong(OlympiadProperties.getProperty("ValdationEnd", "0"));
-        _nextWeeklyChange = Long.parseLong(OlympiadProperties.getProperty("NextWeeklyChange", "0"));
-
-        switch(_period)
-        {
-            case 0:
-                if (_olympiadEnd == 0 || _olympiadEnd < Calendar.getInstance().getTimeInMillis())
-                    setNewOlympiadEnd();
-                else
-                    _isOlympiadEnd = false;
-                break;
-            case 1:
-                if (_validationEnd > Calendar.getInstance().getTimeInMillis())
-                {
-                    _isOlympiadEnd = true;
-
-                    _scheduledValdationTask  = ThreadPoolManager.getInstance().scheduleGeneral(new Runnable() {
-                        public void run()
-                        {
-                            _period = 0;
-                            _currentCycle++;
-                            deleteNobles();
-                            setNewOlympiadEnd();
-                            init();
-                        }
-                    }, getMillisToValidationEnd());
-                }
-                else
-                {
-                    _currentCycle++;
-                    _period = 0;
-                    deleteNobles();
-                    setNewOlympiadEnd();
-                }
-                break;
-                default:
-                    _log.warning("Olympiad System: Omg something went wrong in loading!! Period = " + _period);
-                return;
-        }
-
-        try
-        {
-            Connection con = L2DatabaseFactory.getInstance().getConnection();
-            PreparedStatement statement = con.prepareStatement(OLYMPIAD_LOAD_NOBLES);
-            ResultSet rset = statement.executeQuery();
-
-            while(rset.next())
-            {
-                StatsSet statDat = new StatsSet();
-                int charId = rset.getInt(CHAR_ID);
-                statDat.set(CLASS_ID, rset.getInt(CLASS_ID));
-                statDat.set(CHAR_NAME, rset.getString(CHAR_NAME));
-                statDat.set(POINTS, rset.getInt(POINTS));
-                statDat.set(COMP_DONE, rset.getInt(COMP_DONE));
-                statDat.set("to_save", false);
-
-                _nobles.put(charId, statDat);
-            }
-
-            rset.close();
-            statement.close();
-            con.close();
-        }
-        catch(Exception e)
-        {
-            e.printStackTrace();
-        }
-
-        synchronized(this)
-        {
-            _log.info("Olympiad System: Loading Olympiad System....");
-            if (_period == 0)
-                _log.info("Olympiad System: Currently in Olympiad Period");
-            else
-                _log.info("Olympiad System: Currently in Validation Period");
-
-            _log.info("Olympiad System: Period Ends....");
-
-            long milliToEnd;
-            if (_period == 0)
-                milliToEnd = getMillisToOlympiadEnd();
-            else
-                milliToEnd = getMillisToValidationEnd();
-
-            double numSecs = (milliToEnd / 1000) % 60;
-            double countDown = ((milliToEnd / 1000) - numSecs) / 60;
-            int numMins = (int) Math.floor(countDown % 60);
-            countDown = (countDown - numMins) / 60;
-            int numHours = (int) Math.floor(countDown % 24);
-            int numDays = (int) Math.floor((countDown - numHours) / 24);
-
-            _log.info("Olympiad System: In " + numDays + " days, " + numHours
-                + " hours and " + numMins + " mins.");
-
-            if (_period == 0)
-            {
-                _log.info("Olympiad System: Next Weekly Change is in....");
-
-                milliToEnd = getMillisToWeekChange();
-
-                double numSecs2 = (milliToEnd / 1000) % 60;
-                double countDown2 = ((milliToEnd / 1000) - numSecs2) / 60;
-                int numMins2 = (int) Math.floor(countDown2 % 60);
-                countDown2 = (countDown2 - numMins2) / 60;
-                int numHours2 = (int) Math.floor(countDown2 % 24);
-                int numDays2 = (int) Math.floor((countDown2 - numHours2) / 24);
-
-                _log.info("Olympiad System: " + numDays2 + " days, " + numHours2
-                    + " hours and " + numMins2 + " mins.");
-            }
-        }
-
-        _log.info("Olympiad System: Loaded " + _nobles.size() + " Nobles");
-
-    }
-
-    protected void init()
-    {
-        if (_period == 1)
-            return;
-    	_nonClassBasedRegisters = new L2FastList<L2PcInstance>();
-        _classBasedRegisters = new FastMap<Integer, L2FastList<L2PcInstance>>();
-
-        _compStart = Calendar.getInstance();
-        _compStart.set(Calendar.HOUR_OF_DAY, COMP_START);
-        _compStart.set(Calendar.MINUTE, COMP_MIN);
-        _compEnd = _compStart.getTimeInMillis() + COMP_PERIOD;
-
-    	_scheduledOlympiadEnd = ThreadPoolManager.getInstance().scheduleGeneral(new Runnable(){
-    		public void run()
-    		{
-                SystemMessage sm = new SystemMessage(SystemMessageId.OLYMPIAD_PERIOD_S1_HAS_ENDED);
-                sm.addNumber(_currentCycle);
-
-                Announcements.getInstance().announceToAll(sm);
-                Announcements.getInstance().announceToAll("Olympiad Validation Period has began");
-
-    			_isOlympiadEnd = true;
-                if (_scheduledManagerTask != null)
-                    _scheduledManagerTask.cancel(true);
-                if (_scheduledWeeklyTask != null)
-                    _scheduledWeeklyTask.cancel(true);
-
-                Calendar validationEnd = Calendar.getInstance();
-                _validationEnd = validationEnd.getTimeInMillis() + VALIDATION_PERIOD;
-
-                saveNobleData();
-
-                _period = 1;
-
-                sortHerosToBe();
-
-                giveHeroBonus();
-
-                Hero.getInstance().computeNewHeroes(_heroesToBe);
-
-                try {
-                    save();
-                }
-                catch (Exception e) {
-                    _log.warning("Olympiad System: Failed to save Olympiad configuration: " + e);
-                }
-
-                _scheduledValdationTask  = ThreadPoolManager.getInstance().scheduleGeneral(new Runnable() {
-                    public void run()
-                    {
-                        Announcements.getInstance().announceToAll("Olympiad Validation Period has ended");
-                        _period = 0;
-                        _currentCycle++;
-                        deleteNobles();
-                        setNewOlympiadEnd();
-                        init();
-                    }
-                }, getMillisToValidationEnd());
-    		}
-    	}, getMillisToOlympiadEnd());
-
-        updateCompStatus();
-    	scheduleWeeklyChange();
-    }
-
-    public boolean registerNoble(L2PcInstance noble, boolean classBased)
-    {
-        SystemMessage sm;
-
-        /*
-        if (_compStarted)
-        {
-            noble.sendMessage("Cant Register whilst competition is under way");
-            return false;
-        }
-        */
-
-        if (!_inCompPeriod)
-        {
-            sm = new SystemMessage(SystemMessageId.THE_OLYMPIAD_GAME_IS_NOT_CURRENTLY_IN_PROGRESS);
-            noble.sendPacket(sm);
-            return false;
-        }
-
-        if (noble.isCursedWeaponEquipped())
-        {
-        	noble.sendMessage("You can't participate to Olympiad while holding a cursed weapon.");
-        	return false;
-        }
-
-        if (!noble.isNoble())
-        {
-            sm = new SystemMessage(SystemMessageId.ONLY_NOBLESS_CAN_PARTICIPATE_IN_THE_OLYMPIAD);
-            noble.sendPacket(sm);
-        	return false;
-        }
-
-        if (noble.getBaseClass() != noble.getClassId().getId())
-        {
-            sm = new SystemMessage(SystemMessageId.YOU_CANT_JOIN_THE_OLYMPIAD_WITH_A_SUB_JOB_CHARACTER);
-            noble.sendPacket(sm);
-        	return false;
-        }
-
-        if (!_nobles.containsKey(noble.getObjectId()))
-        {
-        	StatsSet statDat = new StatsSet();
-        	statDat.set(CLASS_ID, noble.getClassId().getId());
-        	statDat.set(CHAR_NAME, noble.getName());
-            statDat.set(POINTS, DEFAULT_POINTS);
-            statDat.set(COMP_DONE, 0);
-            statDat.set("to_save", true);
-
-            _nobles.put(noble.getObjectId(), statDat);
-        }
-
-        if (_classBasedRegisters.containsKey(noble.getClassId().getId()))
-        {
-        	L2FastList<L2PcInstance> classed = _classBasedRegisters.get(noble.getClassId().getId());
-            for (L2PcInstance partecipant: classed)
-            {
-            	if (partecipant.getObjectId()==noble.getObjectId())
-            		{
-            		sm = new SystemMessage(SystemMessageId.YOU_ARE_ALREADY_ON_THE_WAITING_LIST_TO_PARTICIPATE_IN_THE_GAME_FOR_YOUR_CLASS);
-            		noble.sendPacket(sm);
-            		return false;
-            		}
-            }
-        }
-
-        for (L2PcInstance partecipant: _nonClassBasedRegisters)
-        {
-        	if (partecipant.getObjectId()==noble.getObjectId())
-        		{
-        		sm = new SystemMessage(SystemMessageId.YOU_ARE_ALREADY_ON_THE_WAITING_LIST_FOR_ALL_CLASSES_WAITING_TO_PARTICIPATE_IN_THE_GAME);
-        		noble.sendPacket(sm);
-        		return false;
-        		}
-        }
-
-        for (L2OlympiadGame g : _manager.getOlympiadGames().values())
-        {
-        	if (g == null || g.getPlayers() == null)
-        		continue;
-        	
-        	for(L2PcInstance player : g.getPlayers())
-        	{
-        		if(player.getObjectId() == noble.getObjectId())
-            	{
-            		sm = new SystemMessage(SystemMessageId.YOU_ARE_ALREADY_ON_THE_WAITING_LIST_FOR_ALL_CLASSES_WAITING_TO_PARTICIPATE_IN_THE_GAME);
-            		noble.sendPacket(sm);
-            		return false;
-            	}
-        	}
-        	
-        }
-        
-        if (classBased && getNoblePoints(noble.getObjectId()) < 3)
-        {
-            noble.sendMessage("Cant register when you have less than 3 points");
-            return false;
-        }
-        if (!classBased && getNoblePoints(noble.getObjectId()) < 5)
-        {
-            noble.sendMessage("Cant register when you have less than 5 points");
-            return false;
-        }
-
-        if (classBased)
-        {
-            if (_classBasedRegisters.containsKey(noble.getClassId().getId()))
-            {
-            	L2FastList<L2PcInstance> classed = _classBasedRegisters.get(noble.getClassId().getId());
-                classed.add(noble);
-
-                _classBasedRegisters.remove(noble.getClassId().getId());
-                _classBasedRegisters.put(noble.getClassId().getId(), classed);
-
-                sm = new SystemMessage(SystemMessageId.YOU_HAVE_BEEN_REGISTERED_IN_A_WAITING_LIST_OF_CLASSIFIED_GAMES);
-                noble.sendPacket(sm);
-            }
-            else
-            {
-            	L2FastList<L2PcInstance> classed = new L2FastList<L2PcInstance>();
-                classed.add(noble);
-
-                _classBasedRegisters.put(noble.getClassId().getId(), classed);
-
-                sm = new SystemMessage(SystemMessageId.YOU_HAVE_BEEN_REGISTERED_IN_A_WAITING_LIST_OF_CLASSIFIED_GAMES);
-                noble.sendPacket(sm);
-
-            }
-        }
-        else
-        {
-        	_nonClassBasedRegisters.add(noble);
-            sm = new SystemMessage(SystemMessageId.YOU_HAVE_BEEN_REGISTERED_IN_A_WAITING_LIST_OF_NO_CLASS_GAMES);
-            noble.sendPacket(sm);
-        }
-
-        return true;
-    }
-
-    public boolean isRegistered(L2PcInstance noble)
-    {
-    	if(_nonClassBasedRegisters == null) return false;
-    	if(_classBasedRegisters == null) return false;
-    	if (!_nonClassBasedRegisters.contains(noble))
-        {
-        	if (!_classBasedRegisters.containsKey(noble.getClassId().getId()))
-            {
-        		return false;
-            }
-            else
-            {
-            	L2FastList<L2PcInstance> classed = _classBasedRegisters.get(noble.getClassId().getId());
-                if (!classed.contains(noble))
-                {
-                    return false;
-                }
-            }
-        }
-        return true;
-    }
-
-    public boolean unRegisterNoble(L2PcInstance noble)
-    {
-        SystemMessage sm;
-        /*
-    	if (_compStarted)
-    	{
-    		noble.sendMessage("Cant Unregister whilst competition is under way");
-    		return false;
-    	}
-    	*/
-
-        if (!_inCompPeriod)
-        {
-            sm = new SystemMessage(SystemMessageId.THE_OLYMPIAD_GAME_IS_NOT_CURRENTLY_IN_PROGRESS);
-            noble.sendPacket(sm);
-            return false;
-        }
-
-    	if (!noble.isNoble())
-        {
-            sm = new SystemMessage(SystemMessageId.ONLY_NOBLESS_CAN_PARTICIPATE_IN_THE_OLYMPIAD);
-            noble.sendPacket(sm);
-            return false;
-        }
-
-    	if (!isRegistered(noble))
-    	{
-    		sm = new SystemMessage(SystemMessageId.YOU_HAVE_NOT_BEEN_REGISTERED_IN_A_WAITING_LIST_OF_A_GAME);
-            noble.sendPacket(sm);
-            return false;
-        }
-
-        if (_nonClassBasedRegisters.contains(noble))
-            _nonClassBasedRegisters.remove(noble);
-        else
-        {
-        	L2FastList<L2PcInstance> classed = _classBasedRegisters.get(noble.getClassId().getId());
-            classed.remove(noble);
-
-            _classBasedRegisters.remove(noble.getClassId().getId());
-            _classBasedRegisters.put(noble.getClassId().getId(), classed);
-        }
-        
-        for(L2OlympiadGame game: _manager.getOlympiadGames().values())
-        {
-        	if (game == null)
-        		continue;
-        	
-        	if(game._playerOne.getObjectId() == noble.getObjectId() || game._playerTwo.getObjectId() == noble.getObjectId())
-        	{
-        		noble.sendMessage("Cant Unregister whilst you are already selected for a game");
-        		return false;
-        	}
-        }
-
-        sm = new SystemMessage(SystemMessageId.YOU_HAVE_BEEN_DELETED_FROM_THE_WAITING_LIST_OF_A_GAME);
-        noble.sendPacket(sm);
-
-    	return true;
-    }
-    
-    public void removeDisconnectedCompetitor(L2PcInstance player)
-    {
-        if (_manager == null || (_manager.getOlympiadInstance(player.getOlympiadGameId()) == null)) return;
-
-        _manager.getOlympiadInstance(player.getOlympiadGameId()).handleDisconnect(player);
-    }
-
-    public void notifyCompetitorDamage(int objId, int damage, int gameId)
-    {
-    	if (_manager.getOlympiadGames().get(gameId) == null) return;
-
-    	if (_manager.getOlympiadGames().get(gameId)._playerOneID == objId)
-    		_manager.getOlympiadGames().get(gameId)._damageP1 += damage;
-    	else _manager.getOlympiadGames().get(gameId)._damageP2 += damage;
-    }
-
-    private void updateCompStatus()
-    {
-    	//_compStarted = false;
-
-        synchronized(this)
-        {
-            long milliToStart = getMillisToCompBegin();
-
-            double numSecs = (milliToStart / 1000) % 60;
-            double countDown = ((milliToStart / 1000) - numSecs) / 60;
-            int numMins = (int) Math.floor(countDown % 60);
-            countDown = (countDown - numMins) / 60;
-            int numHours = (int) Math.floor(countDown % 24);
-            int numDays = (int) Math.floor((countDown - numHours) / 24);
-
-            _log.info("Olympiad System: Competition Period Starts in "
-                      + numDays + " days, " + numHours
-                + " hours and " + numMins + " mins.");
-
-            _log.info("Olympiad System: Event starts/started : " + _compStart.getTime());
-        }
-
-    	_scheduledCompStart = ThreadPoolManager.getInstance().scheduleGeneral(new Runnable(){
-    		public void run()
-    		{
-                if (isOlympiadEnd())
-                    return;
-
-    			_inCompPeriod = true;
-    			OlympiadManager om = new OlympiadManager();
-
-                Announcements.getInstance().announceToAll(new SystemMessage(SystemMessageId.THE_OLYMPIAD_GAME_HAS_STARTED));
-                _log.info("Olympiad System: Olympiad Game Started");
-
-                Thread olyCycle = new Thread(om);
-                olyCycle.start();
-                
-                //_scheduledManagerTask = ThreadPoolManager.getInstance().scheduleGeneralAtFixedRate(om, INITIAL_WAIT, BATTLE_WAIT);
-   
-    			_scheduledCompEnd = ThreadPoolManager.getInstance().scheduleGeneral(new Runnable(){
-    				public void run()
-    				{
-                        if (isOlympiadEnd())
-                            return;
-                        //_scheduledManagerTask.cancel(true);
-    					_inCompPeriod = false;
-                        Announcements.getInstance().announceToAll(new SystemMessage(SystemMessageId.THE_OLYMPIAD_GAME_HAS_ENDED));
-                        _log.info("Olympiad System: Olympiad Game Ended");
-
-                        try {
-                        	while(_battleStarted){
-	                        	try{
-	                        		//wait 1 minutes for end of pendings games
-	        		    			Thread.sleep(60000);
-	        		    		}catch (InterruptedException e){}
-                        	}
-                            save();
-                        }
-                        catch (Exception e) {
-                            _log.warning("Olympiad System: Failed to save Olympiad configuration: " + e);
-                        }
-
-                        init();
-    				}
-    				}, getMillisToCompEnd());
-    		}
-    		}, getMillisToCompBegin());
-    }
-
-    private long getMillisToOlympiadEnd()
-    {
-        //if (_olympiadEnd > Calendar.getInstance().getTimeInMillis())
-            return (_olympiadEnd - Calendar.getInstance().getTimeInMillis());
-        //return 10L;
-    }
-
-    public void manualSelectHeroes()
-    {
-        SystemMessage sm = new SystemMessage(SystemMessageId.OLYMPIAD_PERIOD_S1_HAS_ENDED);
-        sm.addNumber(_currentCycle);
-
-        Announcements.getInstance().announceToAll(sm);
-        Announcements.getInstance().announceToAll("Olympiad Validation Period has began");
-
-        _isOlympiadEnd = true;
-        if (_scheduledManagerTask != null)
-            _scheduledManagerTask.cancel(true);
-        if (_scheduledWeeklyTask != null)
-            _scheduledWeeklyTask.cancel(true);
-        if(_scheduledOlympiadEnd != null)
-            _scheduledOlympiadEnd.cancel(true);
-
-        Calendar validationEnd = Calendar.getInstance();
-        _validationEnd = validationEnd.getTimeInMillis() + VALIDATION_PERIOD;
-
-        saveNobleData();
-
-        _period = 1;
-
-        sortHerosToBe();
-
-        giveHeroBonus();
-
-        Hero.getInstance().computeNewHeroes(_heroesToBe);
-
-        try {
-            save();
-        }
-        catch (Exception e) {
-            _log.warning("Olympiad System: Failed to save Olympiad configuration: " + e);
-        }
-
-        _scheduledValdationTask  = ThreadPoolManager.getInstance().scheduleGeneral(new Runnable() {
-            public void run()
-            {
-                Announcements.getInstance().announceToAll("Olympiad Validation Period has ended");
-                _period = 0;
-                _currentCycle++;
-                deleteNobles();
-                setNewOlympiadEnd();
-                init();
-            }
-        }, getMillisToValidationEnd());
-    }
-
-    protected long getMillisToValidationEnd()
-    {
-        if (_validationEnd > Calendar.getInstance().getTimeInMillis())
-            return (_validationEnd - Calendar.getInstance().getTimeInMillis());
-        return 10L;
-    }
-
-    public boolean isOlympiadEnd()
-    {
-    	return _isOlympiadEnd;
-    }
-
-    protected void setNewOlympiadEnd()
-    {
-        SystemMessage sm = new SystemMessage(SystemMessageId.OLYMPIAD_PERIOD_S1_HAS_STARTED);
-        sm.addNumber(_currentCycle);
-
-        Announcements.getInstance().announceToAll(sm);
-
-        Calendar currentTime = Calendar.getInstance();
-        currentTime.add(Calendar.MONTH, 1);
-        currentTime.set(Calendar.DAY_OF_MONTH, 1);
-        currentTime.set(Calendar.AM_PM, Calendar.AM);
-        currentTime.set(Calendar.HOUR, 12);
-        currentTime.set(Calendar.MINUTE, 0);
-        currentTime.set(Calendar.SECOND, 0);
-        _olympiadEnd = currentTime.getTimeInMillis();
-
-        Calendar nextChange = Calendar.getInstance();
-        _nextWeeklyChange = nextChange.getTimeInMillis() + WEEKLY_PERIOD;
-
-        _isOlympiadEnd = false;
-    }
-
-    public boolean inCompPeriod()
-    {
-    	return _inCompPeriod;
-    }
-
-    private long getMillisToCompBegin()
-    {
-        if (_compStart.getTimeInMillis() < Calendar.getInstance().getTimeInMillis() &&
-                _compEnd > Calendar.getInstance().getTimeInMillis())
-            return 10L;
-
-        if (_compStart.getTimeInMillis() > Calendar.getInstance().getTimeInMillis())
-            return (_compStart.getTimeInMillis() - Calendar.getInstance().getTimeInMillis());
-
-        return setNewCompBegin();
-    }
-
-    private long setNewCompBegin()
-    {
-        _compStart = Calendar.getInstance();
-        _compStart.set(Calendar.HOUR_OF_DAY, COMP_START);
-        _compStart.set(Calendar.MINUTE, COMP_MIN);
-        _compStart.add(Calendar.HOUR_OF_DAY, 24);
-        _compEnd = _compStart.getTimeInMillis() + COMP_PERIOD;
-
-        _log.info("Olympiad System: New Schedule @ " + _compStart.getTime());
-
-        return (_compStart.getTimeInMillis() - Calendar.getInstance().getTimeInMillis());
-    }
-
-    protected long getMillisToCompEnd()
-    {
-        //if (_compEnd > Calendar.getInstance().getTimeInMillis())
-            return (_compEnd - Calendar.getInstance().getTimeInMillis());
-        //return 10L;
-    }
-
-    private long getMillisToWeekChange()
-    {
-        if (_nextWeeklyChange > Calendar.getInstance().getTimeInMillis())
-            return (_nextWeeklyChange - Calendar.getInstance().getTimeInMillis());
-        return 10L;
-    }
-
-    private void scheduleWeeklyChange()
-    {
-    	_scheduledWeeklyTask = ThreadPoolManager.getInstance().scheduleGeneralAtFixedRate(new Runnable() {
-    		public void run()
-    		{
-    			addWeeklyPoints();
-                _log.info("Olympiad System: Added weekly points to nobles");
-
-                Calendar nextChange = Calendar.getInstance();
-                _nextWeeklyChange = nextChange.getTimeInMillis() + WEEKLY_PERIOD;
-    		}
-    	}, getMillisToWeekChange(), WEEKLY_PERIOD);
-    }
-
-    protected synchronized void addWeeklyPoints()
-    {
-        if (_period == 1)
-            return;
-
-        for (Integer nobleId : _nobles.keySet())
-        {
-            StatsSet nobleInfo = _nobles.get(nobleId);
-            int currentPoints = nobleInfo.getInteger(POINTS);
-            currentPoints += WEEKLY_POINTS;
-            nobleInfo.set(POINTS, currentPoints);
-
-            _nobles.remove(nobleId);
-            _nobles.put(nobleId, nobleInfo);
-        }
-    }
-
-    public String[] getMatchList()
-    {
-    	return (_manager == null)? null : _manager.getAllTitles();
-    }
-
-    // returns the players for the given olympiad game Id 
-    public L2PcInstance[] getPlayers(int Id)
-    {
-        if (_manager == null || (_manager.getOlympiadInstance(Id) == null))
-        {
-            return null;
-        }
-
-        L2PcInstance[] players = _manager.getOlympiadInstance(Id).getPlayers();
-
-        return players;
-    }
-
-    public int getCurrentCycle()
-    {
-        return _currentCycle;
-    }
-
-    public void addSpectator(int id, L2PcInstance spectator)
-    {
-    	if (isRegistered(spectator) || spectator.getOlympiadGameId() != -1)
-    	{
-    		spectator.sendMessage("You are already registered for a competition");
-        	return;
-    	}	
-    	if (!TvTEvent.isInactive() && TvTEvent.isPlayerParticipant(spectator.getObjectId()))
-    	{
-    		spectator.sendMessage("You can not observe games while registered for TvT");
-        	return;
-    	}
-    	if (_manager == null || (_manager.getOlympiadInstance(id) == null))
-        {
-            spectator.sendPacket(new SystemMessage(SystemMessageId.THE_OLYMPIAD_GAME_IS_NOT_CURRENTLY_IN_PROGRESS));
-            return;
-        }
-
-    	L2PcInstance[] players = _manager.getOlympiadInstance(id).getPlayers();
-
-        if (players == null) return;
-
-        spectator.enterOlympiadObserverMode(STADIUMS[id].getCoordinates()[0], STADIUMS[id].getCoordinates()[1], STADIUMS[id].getCoordinates()[2], id);
-
-        _manager.getOlympiadInstance(id).addSpectator(spectator);
-    }
-
-	
-	public void UnSpawnBuffer(L2Spawn spawn)
-	{
-		spawn.getLastSpawn().decayMe();
-	}
-
-    public void removeSpectator(int id, L2PcInstance spectator)
-    {
-        if (_manager == null || (_manager.getOlympiadInstance(id) == null)) return;
-
-        _manager.getOlympiadInstance(id).removeSpectator(spectator);
-    }
-
-    public L2FastList<L2PcInstance> getSpectators(int id)
-    {
-        if (_manager == null || _manager.getOlympiadInstance(id) == null) 
-            return null;
-        return _manager.getOlympiadInstance(id).getSpectators();
-    }
-
-    public Map<Integer, L2OlympiadGame> getOlympiadGames()
-    {
-    	return _manager.getOlympiadGames();
-    }
-
-    public boolean playerInStadia(L2PcInstance player)
-    {
-        return (OlympiadStadiaManager.getInstance().getStadium(player) != null);
-    }
-
-    public int[] getWaitingList()
-    {
-        int[] array = new int[2];
-
-        if (!inCompPeriod())
-            return null;
-
-        int classCount = 0;
-
-        if (_classBasedRegisters.size() != 0)
-            for (L2FastList<L2PcInstance> classed : _classBasedRegisters.values())
-            {
-                classCount += classed.size();
-            }
-
-        array[0] = classCount;
-        array[1] = _nonClassBasedRegisters.size();
-
-        return array;
-    }
-
-    protected synchronized void saveNobleData()
-    {
-        Connection con = null;
-
-        if (_nobles == null)
-            return;
-
-        try
-        {
-            con = L2DatabaseFactory.getInstance().getConnection();
-            PreparedStatement statement;
-
-            for (Integer nobleId : _nobles.keySet())
-            {
-                StatsSet nobleInfo = _nobles.get(nobleId);
-                
-                if (nobleInfo == null)
-                	continue;
-
-                int charId = nobleId;
-                int classId = nobleInfo.getInteger(CLASS_ID);
-                String charName = nobleInfo.getString(CHAR_NAME);
-                int points = nobleInfo.getInteger(POINTS);
-                int compDone = nobleInfo.getInteger(COMP_DONE);
-                boolean toSave = nobleInfo.getBool("to_save");
-
-                if (toSave)
-                {
-                    statement = con.prepareStatement(OLYMPIAD_SAVE_NOBLES);
-                    statement.setInt(1, charId);
-                    statement.setInt(2, classId);
-                    statement.setString(3, charName);
-                    statement.setInt(4, points);
-                    statement.setInt(5, compDone);
-                    statement.execute();
-
-                    statement.close();
-
-                    nobleInfo.set("to_save", false);
-
-                    _nobles.remove(nobleId);
-                    _nobles.put(nobleId, nobleInfo);
-                }
-                else
-                {
-                    statement = con.prepareStatement(OLYMPIAD_UPDATE_NOBLES);
-                    statement.setInt(1, points);
-                    statement.setInt(2, compDone);
-                    statement.setInt(3, charId);
-                    statement.execute();
-                    statement.close();
-                }
-            }
-        }
-        catch(SQLException e) {_log.warning("Olympiad System: Couldnt save nobles info in db");}
-        finally
-        {
-            try{con.close();}catch(Exception e){e.printStackTrace();}
-        }
-    }
-
-    protected void sortHerosToBe()
-    {
-        if (_period != 1) return;
-
-         _heroesToBe = new L2FastList<StatsSet>();
-
-         Connection con = null;
-
-         try
-         {
-             con = L2DatabaseFactory.getInstance().getConnection();
-             PreparedStatement statement;
-             ResultSet rset;
-             StatsSet hero;
-
-             for (int i = 0; i < HERO_IDS.length; i++)
-             {
-                 statement = con.prepareStatement(OLYMPIAD_GET_HEROS);
-                 statement.setInt(1, HERO_IDS[i]);
-                 rset = statement.executeQuery();
-
-                 if (rset.next())
-                 {
-                     hero = new StatsSet();
-                     hero.set(CLASS_ID, HERO_IDS[i]);
-                     hero.set(CHAR_ID, rset.getInt(CHAR_ID));
-                     hero.set(CHAR_NAME, rset.getString(CHAR_NAME));
-
-                     _heroesToBe.add(hero);
-                 }
-
-                 statement.close();
-                 rset.close();
-             }
-         }
-         catch(SQLException e){_log.warning("Olympiad System: Couldnt heros from db");}
-         finally
-         {
-             try{con.close();}catch(Exception e){e.printStackTrace();}
-         }
-
-    }
-
-    public L2FastList<String> getClassLeaderBoard(int classId)
-    {
-        //if (_period != 1) return;
-
-    	L2FastList<String> names = new L2FastList<String>();
-
-         Connection con = null;
-
-         try
-         {
-             con = L2DatabaseFactory.getInstance().getConnection();
-             PreparedStatement statement;
-             ResultSet rset;
-             statement = con.prepareStatement(GET_EACH_CLASS_LEADER);
-             statement.setInt(1, classId);
-             rset = statement.executeQuery();
-
-             while (rset.next())
-             {
-                 names.add(rset.getString(CHAR_NAME));
-             }
-
-             statement.close();
-             rset.close();
-
-             return names;
-         }
-         catch(SQLException e){_log.warning("Olympiad System: Couldnt heros from db");}
-         finally
-         {
-             try{con.close();}catch(Exception e){e.printStackTrace();}
-         }
-
-         return names;
-
-    }
-
-    protected void giveHeroBonus()
-    {
-        if (_heroesToBe.size() == 0)
-            return;
-
-        for (StatsSet hero : _heroesToBe)
-        {
-            int charId = hero.getInteger(CHAR_ID);
-
-            StatsSet noble = _nobles.get(charId);
-            int currentPoints = noble.getInteger(POINTS);
-            currentPoints += Config.ALT_OLY_HERO_POINTS;
-            noble.set(POINTS, currentPoints);
-
-            _nobles.remove(charId);
-            _nobles.put(charId, noble);
-        }
-    }
-
-    public int getNoblessePasses(int objId)
-    {
-        if (_period != 1 || _nobles.size() == 0)
-            return 0;
-
-        StatsSet noble = _nobles.get(objId);
-        if (noble == null)
-            return 0;
-        int points = noble.getInteger(POINTS);
-        if (points <= Config.ALT_OLY_MIN_POINT_FOR_EXCH)
-            return 0;
-
-        noble.set(POINTS, 0);
-        _nobles.remove(objId);
-        _nobles.put(objId, noble);
-
-        points *= Config.ALT_OLY_GP_PER_POINT;
-
-        return points;
-    }
-
-    public boolean isRegisteredInComp(L2PcInstance player)
-    {
-        boolean result = false;
-
-        if (_nonClassBasedRegisters != null && _nonClassBasedRegisters.contains(player))
-            result = true;
-
-        else if (_classBasedRegisters != null && _classBasedRegisters.containsKey(player.getClassId().getId()))
-        {
-        	L2FastList<L2PcInstance> classed = _classBasedRegisters.get(player.getClassId().getId());
-            if (classed.contains(player))
-                result = true;
-        }
-        if (!_inCompPeriod){}
-        else {
-        	for(L2OlympiadGame game: _manager.getOlympiadGames().values())
-        	{
-        		if(game._playerOne.getObjectId() == player.getObjectId() || game._playerTwo.getObjectId() == player.getObjectId())
-        		{
-        			result = true;
-        			break;
-        		}
-        	}
-        }
-
-        return result;
-    }
-
-    public int getNoblePoints(int objId)
-    {
-        if (_nobles.size() ==  0)
-            return 0;
-
-        StatsSet noble = _nobles.get(objId);
-        if (noble == null)
-            return 0;
-        int points = noble.getInteger(POINTS);
-
-        return points;
-    }
-
-    public int getCompetitionDone(int objId)
-    {
-        if (_nobles.size() ==  0)
-            return 0;
-
-        StatsSet noble = _nobles.get(objId);
-        if (noble == null)
-            return 0;
-        int points = noble.getInteger(COMP_DONE);
-
-        return points;
-    }
-
-    protected void deleteNobles()
-    {
-        Connection con = null;
-
-        try
-        {
-            con = L2DatabaseFactory.getInstance().getConnection();
-            PreparedStatement statement = con.prepareStatement(OLYMPIAD_DELETE_ALL);
-            statement.execute();
-            statement.close();
-        }
-        catch(SQLException e){_log.warning("Olympiad System: Couldnt delete nobles from db");}
-        finally
-        {
-            try{con.close();}catch(Exception e){e.printStackTrace();}
-        }
-
-        _nobles.clear();
-    }
-
-    public void save() throws IOException
-    {
-        saveNobleData();
-
-        Properties OlympiadProperties = new Properties();
-        FileOutputStream fos = new FileOutputStream(new File("./" + OLYMPIAD_DATA_FILE));
-
-        OlympiadProperties.setProperty("CurrentCycle", String.valueOf(_currentCycle));
-        OlympiadProperties.setProperty("Period", String.valueOf(_period));
-        OlympiadProperties.setProperty("OlympiadEnd", String.valueOf(_olympiadEnd));
-        OlympiadProperties.setProperty("ValdationEnd", String.valueOf(_validationEnd));
-        OlympiadProperties.setProperty("NextWeeklyChange", String.valueOf(_nextWeeklyChange));
-
-        OlympiadProperties.store(fos, "Olympiad Properties");
-        fos.close();
-    }
-
-    private class OlympiadManager implements Runnable
-    {
-    	private Map<Integer, L2OlympiadGame> _olympiadInstances;
-
-    	public OlympiadManager()
-    	{
-    		_olympiadInstances = new FastMap<Integer, L2OlympiadGame>();
-    		_manager = this;
-    	}
-
-    	public synchronized void run()
-    	{
-    		_cycleTerminated = false;
-    		if (isOlympiadEnd())
-    		{
-    			_scheduledManagerTask.cancel(true);
-    			_cycleTerminated = true;
-    			return;
-    		}
-    		Map<Integer, OlympiadGameTask> _gamesQueue = new FastMap<Integer, OlympiadGameTask>();
-    		while(inCompPeriod())
-    		{
-    			if (_nobles.size() == 0)
-    			{
-    				try{
-    					wait(60000);
-    				}catch(InterruptedException ex){}
-    				continue;
-    			}
-    			
-    			//_compStarted = true;
-    			int classBasedPgCount = 0;
-    			for(L2FastList<L2PcInstance> classList : _classBasedRegisters.values())
-    				classBasedPgCount += classList.size();
-    			while((_gamesQueue.size() > 0 || classBasedPgCount >= Config.ALT_OLY_CLASSED || _nonClassBasedRegisters.size() >= Config.ALT_OLY_NONCLASSED) && inCompPeriod())
-    			{
-    				//first cycle do nothing
-    				int _gamesQueueSize = 0;
-    				_gamesQueueSize = _gamesQueue.size();
-    				for(int i=0; i<_gamesQueueSize;i++)
-					{
-						if(_gamesQueue.get(i) == null || _gamesQueue.get(i).isTerminated() || _gamesQueue.get(i)._game == null)
-						{
-							if(_gamesQueue.containsKey(i)) {
-								//removes terminated games from the queue
-									try {
-									_olympiadInstances.remove(i);
-									_gamesQueue.remove(i);
-									STADIUMS[i].setStadiaFree();
-								} catch(Exception e) {e.printStackTrace();}
-							} else {
-								_gamesQueueSize = _gamesQueueSize+1;
-							}
-						}else if(_gamesQueue.get(i) != null && !_gamesQueue.get(i).isStarted())
-						{
-							//start new games
-							Thread T = new Thread(_gamesQueue.get(i));
-							T.start();
-						}
-					}
-    				//set up the games queue   				
-    	            for(int i=0; i<STADIUMS.length; i++)
-    				{
-    	            	if(!existNextOpponents(_nonClassBasedRegisters) && !existNextOpponents(getRandomClassList(_classBasedRegisters)))
-						{
-							break;
-						}
-    					if(STADIUMS[i].isFreeToUse())
-    					{
-    						if (existNextOpponents(_nonClassBasedRegisters))
-    		                {	
-    							try{
-	    		                    _olympiadInstances.put(i, new L2OlympiadGame(i, COMP_TYPE.NON_CLASSED, nextOpponents(_nonClassBasedRegisters), STADIUMS[i].getCoordinates()));
-	    		                    _gamesQueue.put(i,new OlympiadGameTask(_olympiadInstances.get(i)));
-	    		                    STADIUMS[i].setStadiaBusy();
-    							}catch(Exception ex)
-    							{
-    								if(_olympiadInstances.get(i) != null){
-    									for(L2PcInstance player : _olympiadInstances.get(i).getPlayers())
-    									{
-    										player.sendMessage("Your olympiad registration was canceled due to an error");
-    										player.setIsInOlympiadMode(false);
-    						    			player.setIsOlympiadStart(false);
-    						                player.setOlympiadSide(-1);
-    						                player.setOlympiadGameId(-1);
-    									}
-    									_olympiadInstances.remove(i);
-    								}
-    								if(_gamesQueue.get(i)!= null)
-    									_gamesQueue.remove(i);
-    								STADIUMS[i].setStadiaFree();
-    								
-    								//try to reuse this stadia next time
-    								i--;
-    							}
-    		                }
-    						else if (existNextOpponents(getRandomClassList(_classBasedRegisters)))
-    		                {
-    							try{
-    								_olympiadInstances.put(i, new L2OlympiadGame(i, COMP_TYPE.CLASSED, nextOpponents(getRandomClassList(_classBasedRegisters)), STADIUMS[i].getCoordinates()));
-	    		                    _gamesQueue.put(i,new OlympiadGameTask(_olympiadInstances.get(i)));
-	    		                    STADIUMS[i].setStadiaBusy();
-    							}catch(Exception ex)
-    							{
-    								if(_olympiadInstances.get(i) != null){
-    									for(L2PcInstance player : _olympiadInstances.get(i).getPlayers())
-    									{
-    										player.sendMessage("Your olympiad registration was canceled due to an error");
-    										player.setIsInOlympiadMode(false);
-    						    			player.setIsOlympiadStart(false);
-    						                player.setOlympiadSide(-1);
-    						                player.setOlympiadGameId(-1);
-    									}
-    									_olympiadInstances.remove(i);
-    								}
-    								if(_gamesQueue.get(i)!= null)
-    									_gamesQueue.remove(i);
-    								STADIUMS[i].setStadiaFree();
-    								
-    								//try to reuse this stadia next time
-    								i--;
-    							}
-    		                }
-    					}
-    				}
-    	            //wait 30 sec for !stress the server
-    	            try{
-    	    			wait(30000);
-    	    		}catch (InterruptedException e){}
-    			}
-    			//wait 30 sec for !stress the server
-	            try{
-	    			wait(30000);
-	    		}catch (InterruptedException e){}
-    		}
-
-    		//when comp time finish wait for all games terminated before execute the cleanup code
-    		boolean allGamesTerminated = false;
-    		//wait for all games terminated
-    		while(!allGamesTerminated)
-    		{
-     			try{
-	    			wait(30000);
-	    		}catch (InterruptedException e){}
-	    		
-	    		if(_gamesQueue.size() == 0)
-	    		{
-	    			allGamesTerminated = true;
-	    		}else{
-		    		for(OlympiadGameTask game : _gamesQueue.values())
-		    		{
-		    			allGamesTerminated = allGamesTerminated || game.isTerminated();
-		    		}
-	    		}
-     		}
-    		_cycleTerminated = true;
-    		//when all games terminated clear all 
-    		_gamesQueue.clear();
-    		/*_classBasedParticipants.clear();
-    		_nonClassBasedParticipants.clear();*/
-    		//Wait 20 seconds
-    		_olympiadInstances.clear();
-            _classBasedRegisters.clear();
-            _nonClassBasedRegisters.clear();
-
-            _battleStarted = false;
-    		//_compStarted = false;
-
-    	}
-
-    	protected L2OlympiadGame getOlympiadInstance(int index)
-    	{
-    		if (_olympiadInstances != null && _olympiadInstances.size() > 0)
-    		{
-    			return _olympiadInstances.get(index);
-    		}
-    		return null;
-    	}
-
-    	protected Map<Integer, L2OlympiadGame> getOlympiadGames()
-    	{
-    		return (_olympiadInstances == null)? null : _olympiadInstances;
-    	}
-    	
-    	private L2FastList<L2PcInstance> getRandomClassList(Map<Integer, L2FastList<L2PcInstance>> list)
-    	{
-    		if(list.size() == 0)
-    			return null;
-    		
-    		Map<Integer, L2FastList<L2PcInstance>> tmp = new FastMap<Integer, L2FastList<L2PcInstance>>();
-    		int tmpIndex = 0;
-    		for(L2FastList<L2PcInstance> l : list.values())
-    		{
-    			tmp.put(tmpIndex++, l);
-    		}
-    		
-    		L2FastList<L2PcInstance> rndList = new L2FastList<L2PcInstance>();
-    		int classIndex = 0;
-    		if(tmp.size() == 1)
-    			classIndex = 0;
-    		else
-    			classIndex = Rnd.nextInt(tmp.size());
-    		rndList = tmp.get(classIndex);
-    		return rndList;
-    	}
-    	private L2FastList<L2PcInstance> nextOpponents(L2FastList<L2PcInstance> list)
-    	{
-    		L2FastList<L2PcInstance> opponents = new L2FastList<L2PcInstance>();
-            if (list.size() == 0)
-                return opponents;
-    		int loopCount = (list.size() / 2);
-    		
-    		int first;
-    		int second;
-    		
-    		if (loopCount < 1)
-    			return opponents;
-    			
-			first = Rnd.nextInt(list.size());
-			opponents.add(list.get(first));
-			list.remove(first);
-			
-			second = Rnd.nextInt(list.size());
-			opponents.add(list.get(second));
-			list.remove(second);
-			
-			return opponents;
-        
-        }
-    	private boolean existNextOpponents(L2FastList<L2PcInstance> list)
-    	{
-    		if(list == null)
-    			return false;
-            if (list.size() == 0)
-                return false;
-    		int loopCount = list.size() >> 1;
-    		
-    		if (loopCount < 1)
-    			return false;
-    		else
-    			return true;
-    		
-        
-        }
-
-    	protected String[] getAllTitles()
-    	{
-    		/*if(!_compStarted)
-    			return null;*/
-
-    		String[] msg = new String[_olympiadInstances.size()];
-    		int count = 0;
-    		int match = 1;
-    		int showbattle = 0;
-
-    		for (L2OlympiadGame instance : _olympiadInstances.values())
-    		{
-    			if (instance._gamestarted == true) { showbattle = 1; } else { showbattle = 0; }
-    			msg[count++] = "<"+showbattle+"><"+instance._stadiumID+"> In Progress " + instance.getTitle();
-    			match++;
-    		}
-
-    		return msg;
-    	}
-    }
-
-    private class L2OlympiadGame
-    {
-    	protected COMP_TYPE _type;
-    	public boolean _aborted;
-    	public boolean _gamestarted;
-    	public boolean _playerOneDisconnected;
-    	public boolean _playerTwoDisconnected;
-    	public String _playerOneName;
-    	public String _playerTwoName;
-    	public int _playerOneID = 0;
-    	public int _playerTwoID = 0;
-    	public static final int OLY_BUFFER = 36402;
-
-    	public int _damageP1 = 0;
-    	public int _damageP2 = 0;
-
-    	public L2PcInstance _playerOne;
-    	public L2PcInstance _playerTwo;
-    	public L2Spawn _spawnOne;
-    	public L2Spawn _spawnTwo;
-    	private L2FastList<L2PcInstance> _players;
-        private int[] _stadiumPort;
-        private int x1, y1, z1, x2, y2, z2;
-        public int _stadiumID;
-        public L2FastList<L2PcInstance> _spectators;
-        private SystemMessage _sm;
-        private SystemMessage _sm2;
-        private SystemMessage _sm3;
-
-    	protected L2OlympiadGame(int id, COMP_TYPE type, L2FastList<L2PcInstance> list, int[] stadiumPort)
-    	{
-    		_aborted = false;
-    		_gamestarted = false;
-    		_stadiumID = id;
-    		_playerOneDisconnected = false;
-    		_playerTwoDisconnected = false;
-    		_type = type;
-            _stadiumPort = stadiumPort;
-            _spectators = new L2FastList<L2PcInstance>();
-
-    		if (list != null)
-    		{
-    			_players = list;
-    			_playerOne = list.get(0);
-    			_playerTwo = list.get(1);
-
-                try {
-                	_playerOneName = _playerOne.getName();
-                	_playerTwoName = _playerTwo.getName();
-                	_playerOne.setOlympiadGameId(id);
-                	_playerTwo.setOlympiadGameId(id);
-                	_playerOneID = _playerOne.getObjectId();
-                	_playerTwoID = _playerTwo.getObjectId();
-                }
-                catch (Exception e)  {
-                	_aborted = true;
-                	clearPlayers();
-                }
-                
-                if (Config.DEBUG)
-                	_log.info("Olympiad System: Game - " + id + ": " + _playerOne.getName() + " Vs " + _playerTwo.getName());
-    		}
-            else {
-            	_aborted = true;
-            	clearPlayers();
-            	return;
-            }
-    	}
-    	
-    	public boolean isAborted()
-    	{
-    	    return _aborted;
-    	}
-    	
-        protected void clearPlayers()
-        {
-            _playerOne = null;
-            _playerTwo = null;
-            _players = null;
-            _playerOneName = "";
-            _playerTwoName = "";
-            _playerOneID = 0;
-            _playerTwoID = 0;
-        }
-        
-        protected void handleDisconnect(L2PcInstance player)
-        {
-            if (player == _playerOne)
-                _playerOneDisconnected = true;
-            else if (player == _playerTwo)
-                _playerTwoDisconnected = true;
-        }
-        
-		public void openDoors()
-		{
-			_doorTable = DoorTable.getInstance();
-			try {
-				_doorTable.getDoor(STADIUMS[_stadiumID].getDoorID()[0]).openMe();
-				_doorTable.getDoor(STADIUMS[_stadiumID].getDoorID()[1]).openMe();
-				//_log.info("open doors"+STADIUMS[_stadiumID].getDoorID()[0]+"<>"+STADIUMS[_stadiumID].getDoorID()[1]);
-			} catch (Exception e) {}
-		}
-		
-		public void closeDoors()
-		{
-			_doorTable = DoorTable.getInstance();
-			try {
-				_doorTable.getDoor(STADIUMS[_stadiumID].getDoorID()[0]).closeMe();
-				_doorTable.getDoor(STADIUMS[_stadiumID].getDoorID()[1]).closeMe();
-				//_log.info("close doors"+STADIUMS[_stadiumID].getDoorID()[0]+"<>"+STADIUMS[_stadiumID].getDoorID()[1]);
-			} catch (Exception e) {}	
-		}
-		
-		public L2Spawn SpawnBuffer(int xPos, int yPos, int zPos, int npcId)
-		{
-		        L2NpcTemplate template;
-		        template = NpcTable.getInstance().getTemplate(npcId);
-		        try {
-		        	L2Spawn spawn = new L2Spawn(template);
-		        	spawn.setLocx(xPos);
-		        	spawn.setLocy(yPos);
-		        	spawn.setLocz(zPos);
-		        	spawn.setAmount(1);
-		        	spawn.setHeading(0);
-		        	spawn.setRespawnDelay(1);					
-		        	SpawnTable.getInstance().addNewSpawn(spawn, false);
-		        	spawn.init();
-		        	return spawn;
-		        } catch (Exception e) { return null; }		     
-		}
-
-    	protected void removals()
-    	{
-    		if (_aborted) return;
-
-            if (_playerOne == null || _playerTwo == null) return;
-            if (_playerOneDisconnected  || _playerTwoDisconnected) return;
-            
-    		for (L2PcInstance player : _players)
-    		{
-    		  try{
-    			//Remove Clan Skills
-				if (player.getClan() != null)
-				{
-					for(L2Skill skill: player.getClan().getAllSkills())
-						player.removeSkill(skill,false);
-				}
-				//Abort casting if player casting  
-				if (player.isCastingNow())
-				{
-					player.abortCast();  
-				}
-				
-				//Force the character to be vissible
-				player.getAppearance().setVisible();
-
-				//Remove Hero Skills
-				if (player.isHero())
-				{
-					for(L2Skill skill: HeroSkillTable.getHeroSkills())
-						player.removeSkill(skill,false);
-				}
-				
-				// Heal Player fully
-				player.setCurrentCp(player.getMaxCp());
-				player.setCurrentHp(player.getMaxHp());
-				player.setCurrentMp(player.getMaxMp());
-				
-				//Remove Buffs
-				player.stopAllEffects();
-				
-				//Remove Summon's Buffs
-				if (player.getPet() != null)
-				{
-					L2Summon summon = player.getPet();
-					summon.stopAllEffects();
-					
-					if (summon instanceof L2PetInstance)
-						summon.unSummon(player);
-		    	}
-                
-                if (player.getCubics() != null)
-                {
-                    boolean removed = false;
-                    for(L2CubicInstance cubic : player.getCubics().values())
-                    {
-                        if (cubic.givenByOther())
-                        {
-                        	cubic.stopAction();
-                        	player.delCubic(cubic.getId());
-                        	removed = true;
-                        }
-                    }
-                    if (removed) player.broadcastUserInfo();
-                }
-				
-				//Remove player from his party
-				if (player.getParty() != null)
-				{
-					L2Party party = player.getParty();
-					party.removePartyMember(player);
-				}
-
-				//Remove Hero Weapons
-				// check to prevent the using of weapon/shield on strider/wyvern
-				L2ItemInstance wpn = player.getInventory().getPaperdollItem(Inventory.PAPERDOLL_RHAND);
-				if (wpn == null) wpn = player.getInventory().getPaperdollItem(Inventory.PAPERDOLL_LRHAND);
-                if (wpn != null && (wpn.isHeroItem() || wpn.isOlyRestrictedItem()))
-                {
-					L2ItemInstance[] unequiped = player.getInventory().unEquipItemInBodySlotAndRecord(wpn.getItem().getBodyPart());
-					InventoryUpdate iu = new InventoryUpdate();
-					for (int i = 0; i < unequiped.length; i++)
-						iu.addModifiedItem(unequiped[i]);
-					player.sendPacket(iu);
-					player.abortAttack();
-					player.broadcastUserInfo();
-
-					// this can be 0 if the user pressed the right mouse button twice very fast
-					if (unequiped.length > 0)
-					{
-						if (unequiped[0].isWear())
-							return;
-						SystemMessage sm = null;
-						if (unequiped[0].getEnchantLevel() > 0){
-							sm = new SystemMessage(SystemMessageId.EQUIPMENT_S1_S2_REMOVED);
-							sm.addNumber(unequiped[0].getEnchantLevel());
-							sm.addItemName(unequiped[0]);
-						}else{
-							sm = new SystemMessage(SystemMessageId.S1_DISARMED);
-							sm.addItemName(unequiped[0]);
-						}
-						player.sendPacket(sm);
-					}
-				}
-
-				//Remove shot automation
-				Map<Integer, Integer> activeSoulShots = player.getAutoSoulShot();
-				for (int itemId : activeSoulShots.values())
-				{
- 					player.removeAutoSoulShot(itemId);
-					ExAutoSoulShot atk = new ExAutoSoulShot(itemId, 0);
-					player.sendPacket(atk);
-				}
-				player.sendSkillList();
-    		  }
-    		  catch (Exception e) {}
-    		}
-    	}
-
-    	protected boolean portPlayersToArena()
-    	{
-    		boolean _playerOneCrash = (_playerOne == null || _playerOneDisconnected);
-    		boolean _playerTwoCrash = (_playerTwo == null || _playerTwoDisconnected);
-
-    		if (_playerOneCrash || _playerTwoCrash || _aborted)
-    		{
-    			_playerOne=null;
-    			_playerTwo=null;
-    			_aborted = true;
-    			return false;
-    		}
-
-    		try {
-    			x1 = _playerOne.getX();
-    			y1 = _playerOne.getY();
-    			z1 = _playerOne.getZ();
-
-    			x2 = _playerTwo.getX();
-    			y2 = _playerTwo.getY();
-    			z2 = _playerTwo.getZ();
-
-    			if (_playerOne.isSitting())
-    				_playerOne.standUp();
-
-    			if (_playerTwo.isSitting())
-    				_playerTwo.standUp();
-
-    			_playerOne.setTarget(null);
-    			_playerTwo.setTarget(null);
-    			
-    			_playerOne.setInstanceId(0);
-    			_playerTwo.setInstanceId(0);
-
-    			_playerOne.teleToLocation(_stadiumPort[0]+1200, _stadiumPort[1], _stadiumPort[2], false);
-    			_playerTwo.teleToLocation(_stadiumPort[0]-1200, _stadiumPort[1], _stadiumPort[2], false);
-
-    			_playerOne.sendPacket(new ExOlympiadMode(2));
-    			_playerTwo.sendPacket(new ExOlympiadMode(2));
-
-    			_spawnOne = SpawnBuffer(_stadiumPort[0]+1100, _stadiumPort[1], _stadiumPort[2], OLY_BUFFER);
-    			_spawnTwo = SpawnBuffer(_stadiumPort[0]-1100, _stadiumPort[1], _stadiumPort[2], OLY_BUFFER);
-
-    			_playerOne.setIsInOlympiadMode(true);
-    			_playerOne.setIsOlympiadStart(false);
-    			_playerOne.setOlympiadSide(1);
-    			_playerOne.olyBuff = 5;
-
-    			_playerTwo.setIsInOlympiadMode(true);
-    			_playerTwo.setIsOlympiadStart(false);
-    			_playerTwo.setOlympiadSide(2);
-    			_playerTwo.olyBuff = 5;
-    			_gamestarted = true;
-    		} catch (NullPointerException e)
-    		{ 
-    		    return false; 
-    		}
-    		return true;
-    	}
-    	
-    	protected void sendMessageToPlayers(boolean toBattleBegin, int nsecond)
-    	{
-            if(!toBattleBegin)
-                _sm = new SystemMessage(SystemMessageId.YOU_WILL_ENTER_THE_OLYMPIAD_STADIUM_IN_S1_SECOND_S);
-            else
-                _sm = new SystemMessage(SystemMessageId.THE_GAME_WILL_START_IN_S1_SECOND_S);
-            
-            _sm.addNumber(nsecond);
-            try {    		
-            	for (L2PcInstance player : _players)
-            		player.sendPacket(_sm);
-            } catch (Exception e) {}
-    	}
-    	
-    	protected void portPlayersBack()
-    	{
-    		if (_playerOne != null)
-    			_playerOne.teleToLocation(x1, y1, z1, true);
-    		
-    		if (_playerTwo != null)
-    		_playerTwo.teleToLocation(x2, y2, z2, true);
-    	}
-    	
-    	protected void PlayersStatusBack()
-    	{
-    		for (L2PcInstance player : _players)
-    		{
-    		  try {
-    			if(player.isDead() == true) { player.setIsDead(false); }
-                player.getStatus().startHpMpRegeneration();
-                player.setCurrentCp(player.getMaxCp());
-                player.setCurrentHp(player.getMaxHp());
-                player.setCurrentMp(player.getMaxMp());
-    			player.setIsInOlympiadMode(false);
-    			player.setIsOlympiadStart(false);
-                player.setOlympiadSide(-1);
-                player.setOlympiadGameId(-1);
-                player.sendPacket(new ExOlympiadMode(0));
-
-                //Add Clan Skills
-				if (player.getClan() != null)
-				{
-					for(L2Skill skill: player.getClan().getAllSkills())
-					{
-						if ( skill.getMinPledgeClass() <= player.getPledgeClass() )
-							player.addSkill(skill,false);
-				 	}
-				}
-
-                //Add Hero Skills
-				if (player.isHero())
-				{
-					for(L2Skill skill: HeroSkillTable.getHeroSkills())
-						player.addSkill(skill,false);
-				}
-				player.sendSkillList();
-    		  } catch (Exception e) {}
-    		}
-    	}
-
-    	protected boolean haveWinner()
-    	{
-    		boolean retval = false;
-			if (_aborted || _playerOne == null || _playerTwo == null)
-			{					
-				return true;
-			}
- 		
-			double playerOneHp = 0;
-
-			try{
-				if (_playerOne != null && _playerOne.getOlympiadGameId() != -1)
-				{
-					playerOneHp = _playerOne.getCurrentHp();
-				}
-			}catch (Exception e){
-				playerOneHp = 0;
-			}
-
-			double playerTwoHp = 0;
-			try{
-				if (_playerTwo != null && _playerTwo.getOlympiadGameId()!=-1)
-				{
-					playerTwoHp = _playerTwo.getCurrentHp();
-				}
-			}catch (Exception e){
-				playerTwoHp = 0;
-			}
-            
-            if (playerTwoHp==0 || playerOneHp==0)
-    		{
-            	return true;
-            }
-            
-            return retval;
-    	}
-    	
-     	protected void validateWinner()
-    	{
-			if (_aborted || _playerOne == null || _playerTwo == null || _playerOneDisconnected || _playerTwoDisconnected)
-			{					
-				return;
-			}
-
-    		StatsSet playerOneStat;
-    		StatsSet playerTwoStat;
-    		
-    		playerOneStat = _nobles.get(_playerOneID);
-			playerTwoStat = _nobles.get(_playerTwoID);
-			
-			int _div;
-			int _gpreward;
-			
-			int playerOnePlayed = playerOneStat.getInteger(COMP_DONE);
-			int playerTwoPlayed = playerTwoStat.getInteger(COMP_DONE);
-			
-			int playerOnePoints = playerOneStat.getInteger(POINTS);
-			int playerTwoPoints = playerTwoStat.getInteger(POINTS);
-
-			double playerOneHp = 0;
-			try
-			{
-				if (_playerOne != null && !_playerOneDisconnected)
-				{
-					if (!_playerOne.isDead())
-					{
-						playerOneHp = _playerOne.getCurrentHp()+_playerOne.getCurrentCp();
-					}
-				}
-			}
-			catch (Exception e)
-			{
-				playerOneHp = 0;
-			}
-
-			double playerTwoHp = 0;
-			try
-			{
-				if (_playerTwo != null && !_playerTwoDisconnected)
-				{
-					if (!_playerTwo.isDead())
-					{
-						playerTwoHp = _playerTwo.getCurrentHp()+_playerTwo.getCurrentCp();
-					}
-				}
-			}
-			catch (Exception e)
-			{
-				playerTwoHp = 0;
-			}
-
-            _sm = new SystemMessage(SystemMessageId.C1_HAS_WON_THE_GAME);
-    		_sm2 = new SystemMessage(SystemMessageId.S1_HAS_GAINED_S2_OLYMPIAD_POINTS);
-            _sm3 = new SystemMessage(SystemMessageId.S1_HAS_LOST_S2_OLYMPIAD_POINTS);
-
-            String result = "";
-
-            // if players crashed, search if they've relogged
-            _playerOne =  L2World.getInstance().getPlayer(_playerOneName);
-            _players.set(0, _playerOne);
-            _playerTwo =  L2World.getInstance().getPlayer(_playerTwoName);
-            _players.set(1, _playerTwo);
-
-            switch(_type){
-            	case NON_CLASSED: _div=5; _gpreward=Config.ALT_OLY_NONCLASSED_RITEM_C; break;
-            	default: _div=3; _gpreward=Config.ALT_OLY_CLASSED_RITEM_C; break;
-            }
-
-            if (_playerOne == null && _playerTwo == null)
-            {
-            	result=" tie";
-    			_sm = new SystemMessage(SystemMessageId.THE_GAME_ENDED_IN_A_TIE);
-                broadcastMessage(_sm, true);
-            }
-            else if (_playerTwo == null || _playerTwo.isOnline() == 0 || (playerTwoHp == 0 && playerOneHp != 0) || (_damageP1 > _damageP2 && playerTwoHp != 0 && playerOneHp != 0))
-    		{
-            	int pointDiff;
-            	pointDiff = playerTwoPoints / _div;
-    			playerOneStat.set(POINTS, playerOnePoints + pointDiff);
-    			playerTwoStat.set(POINTS, playerTwoPoints - pointDiff);
-
-                _sm.addString(_playerOneName);
-                broadcastMessage(_sm, true);
-                _sm2.addString(_playerOneName);
-                _sm2.addNumber(pointDiff);
-                broadcastMessage(_sm2, true);
-                _sm3.addString(_playerTwoName);
-                _sm3.addNumber(pointDiff);
-                broadcastMessage(_sm3, true);
-
-                try {
-        			result=" ("+playerOneHp+"hp vs "+playerTwoHp+"hp - "+_damageP1+"dmg vs "+_damageP2+"dmg) "+_playerOneName+" win "+pointDiff+" points";
-        			L2ItemInstance item = _playerOne.getInventory().addItem("Olympiad", Config.ALT_OLY_BATTLE_REWARD_ITEM, _gpreward, _playerOne, null);
-        			InventoryUpdate iu = new InventoryUpdate();
-        			iu.addModifiedItem(item);
-        			_playerOne.sendPacket(iu);
-
-        			SystemMessage sm = new SystemMessage(SystemMessageId.EARNED_S2_S1_S);
-        			sm.addItemName(item);
-        			sm.addNumber(_gpreward);
-        			_playerOne.sendPacket(sm);
-                } catch (Exception e) { }
-    		}
-            else if (_playerOne == null || _playerOne.isOnline() == 0 || (playerOneHp == 0 && playerTwoHp != 0) || (_damageP2 > _damageP1 && playerOneHp != 0 && playerTwoHp != 0))
-    		{
-            	int pointDiff;
-            	pointDiff = playerOnePoints / _div;
-    			playerTwoStat.set(POINTS, playerTwoPoints + pointDiff);
-    			playerOneStat.set(POINTS, playerOnePoints - pointDiff);
-
-                _sm.addString(_playerTwoName);
-                broadcastMessage(_sm, true);
-                _sm2.addString(_playerTwoName);
-                _sm2.addNumber(pointDiff);
-                broadcastMessage(_sm2, true);
-                _sm3.addString(_playerOneName);
-                _sm3.addNumber(pointDiff);
-                broadcastMessage(_sm3, true);
-
-                try {
-                	result=" ("+playerOneHp+"hp vs "+playerTwoHp+"hp - "+_damageP1+"dmg vs "+_damageP2+"dmg) "+_playerTwoName+" win "+pointDiff+" points";
-                	L2ItemInstance item = _playerTwo.getInventory().addItem("Olympiad", Config.ALT_OLY_BATTLE_REWARD_ITEM, _gpreward, _playerTwo, null);
-                	InventoryUpdate iu = new InventoryUpdate();
-                	iu.addModifiedItem(item);
-                	_playerTwo.sendPacket(iu);
-
-                	SystemMessage sm = new SystemMessage(SystemMessageId.EARNED_S2_S1_S);
-                	sm.addItemName(item);
-        			sm.addNumber(_gpreward);
-                	_playerTwo.sendPacket(sm);
-                } catch (Exception e) { }
-    		}
-    		else
-    		{
-    			result=" tie";
-    			_sm = new SystemMessage(SystemMessageId.THE_GAME_ENDED_IN_A_TIE);
-                broadcastMessage(_sm, true);
-                int pointOneDiff = playerOnePoints / 5;
-                int pointTwoDiff = playerTwoPoints / 5;
-                playerOneStat.set(POINTS, playerOnePoints - pointOneDiff);
-                playerTwoStat.set(POINTS, playerTwoPoints - pointTwoDiff);
-                _sm2 = new SystemMessage(SystemMessageId.S1_HAS_LOST_S2_OLYMPIAD_POINTS);
-                _sm2.addString(_playerOneName);
-                _sm2.addNumber(pointOneDiff);
-                broadcastMessage(_sm2, true);
-                _sm3 = new SystemMessage(SystemMessageId.S1_HAS_LOST_S2_OLYMPIAD_POINTS);
-                _sm3.addString(_playerTwoName);
-                _sm3.addNumber(pointTwoDiff);
-                broadcastMessage(_sm3, true);
-    		}
-            
-            if (Config.DEBUG)
-            	_log.info("Olympia Result: "+_playerOneName+" vs "+_playerTwoName+" ... "+result);
-            
-    		playerOneStat.set(COMP_DONE, playerOnePlayed + 1);
-    		playerTwoStat.set(COMP_DONE, playerTwoPlayed + 1);
-    		
-    		_nobles.remove(_playerOneID);
-    		_nobles.remove(_playerTwoID);
-    		
-    		_nobles.put(_playerOneID, playerOneStat);
-    		_nobles.put(_playerTwoID, playerTwoStat);
-            
-    		for (int i=40;i>10;i-=10)
-    		{
-    			_sm = new SystemMessage(SystemMessageId.YOU_WILL_BE_MOVED_TO_TOWN_IN_S1_SECONDS);
-    			_sm.addNumber(i);
-    			broadcastMessage(_sm, false);
-    			try{ Thread.sleep(10000); }catch (InterruptedException e){}
-    			if (i==20) {
-    				_sm = new SystemMessage(SystemMessageId.YOU_WILL_BE_MOVED_TO_TOWN_IN_S1_SECONDS);
-    				_sm.addNumber(10);
-    				broadcastMessage(_sm, false);
-    				try{ Thread.sleep(5000); }catch (InterruptedException e){}
-    			}
-    		}
-    		for (int i=5;i>0;i--)
-    		{
-    			_sm = new SystemMessage(SystemMessageId.YOU_WILL_BE_MOVED_TO_TOWN_IN_S1_SECONDS);
-    			_sm.addNumber(i);
-    			broadcastMessage(_sm, false);
-    			try{ Thread.sleep(1000); }catch (InterruptedException e){}
-    		}
-    	}
-    	
-    	protected boolean makeCompetitionStart()
-    	{
-    	    if (_aborted) return false;
-           
-    	    _sm = new SystemMessage(SystemMessageId.STARTS_THE_GAME);
-    	    broadcastMessage(_sm, true);
-    		try {
-    			for (L2PcInstance player : _players)
-    			{
-    				player.setIsOlympiadStart(true);
-    			}
-    		} catch (Exception e) { 
-    			_aborted = true;
-    			return false; 
-    		}
-    		return true;
-    	}
-
-    	protected String getTitle()
-    	{
-    		String msg = "";
-    		msg+= _playerOneName + " : " + _playerTwoName;
-    		return msg;
-    	}
-    	
-    	protected L2PcInstance[] getPlayers()
-    	{
-            L2PcInstance[] players = new L2PcInstance[2];
-            
-            if (_playerOne == null || _playerTwo == null) return null;
-            
-    		players[0] = _playerOne;
-    		players[1] = _playerTwo;
-    		
-    		return players;
-    	}
-        
-        protected L2FastList<L2PcInstance> getSpectators()
-        {
-            return _spectators;
-        }
-        
-        protected void addSpectator(L2PcInstance spec)
-        {
-            _spectators.add(spec);
-        }
-        
-        protected void removeSpectator(L2PcInstance spec)
-        {
-            if (_spectators != null && _spectators.contains(spec))
-                _spectators.remove(spec);
-        }
-        
-        protected void clearSpectators()
-        { 
-            if (_spectators != null)
-            {
-                for (L2PcInstance pc : _spectators)
-                {
-                    try {
-                    	if(!pc.inObserverMode()) continue;
-                    	pc.leaveOlympiadObserverMode();
-                    } catch (NullPointerException e) {}
-                }
-                _spectators.clear();
-            }
-        }
-        
-        private void broadcastMessage(SystemMessage sm, boolean toAll)
-        {
-        	try { 
-        	    _playerOne.sendPacket(sm);
-        	    _playerTwo.sendPacket(sm); 
-        	} catch (Exception e) {}
-        	
-            if (toAll && _spectators != null)
-            {
-                for (L2PcInstance spec : _spectators)
-                {
-                    try { spec.sendPacket(sm); } catch (NullPointerException e) {}
-                }
-            }
-        }
-    }
-}

+ 5 - 11
L2_GameServer/java/net/sf/l2j/gameserver/Shutdown.java

@@ -28,6 +28,7 @@ import net.sf.l2j.gameserver.instancemanager.QuestManager;
 import net.sf.l2j.gameserver.instancemanager.RaidBossSpawnManager;
 import net.sf.l2j.gameserver.model.L2World;
 import net.sf.l2j.gameserver.model.actor.instance.L2PcInstance;
+import net.sf.l2j.gameserver.model.olympiad.Olympiad;
 import net.sf.l2j.gameserver.network.L2GameClient;
 import net.sf.l2j.gameserver.network.gameserverpackets.ServerStatus;
 import net.sf.l2j.gameserver.network.serverpackets.ServerClose;
@@ -502,17 +503,10 @@ public class Shutdown extends Thread
 		System.err.println("GrandBossManager: All Grand Boss info saved!!");
 		TradeController.getInstance().dataCountStore();
 		System.err.println("TradeController: All count Item Saved");
-		try
-		{
-			Olympiad.getInstance().save();
-		}
-		catch (Exception e)
-		{
-			e.printStackTrace();
-		}
-		System.err.println("Olympiad System: Data saved!!");
-		
-		// Save Cursed Weapons data before closing.
+		Olympiad.getInstance().saveOlympiadStatus();
+        System.err.println("Olympiad System: Data saved!!");
+        
+        // Save Cursed Weapons data before closing.
 		CursedWeaponsManager.getInstance().saveData();
 		
 		// Save all manor data

+ 3 - 10
L2_GameServer/java/net/sf/l2j/gameserver/handler/admincommandhandlers/AdminAdmin.java

@@ -18,7 +18,6 @@ import java.util.StringTokenizer;
 
 import net.sf.l2j.Config;
 import net.sf.l2j.gameserver.GmListTable;
-import net.sf.l2j.gameserver.Olympiad;
 import net.sf.l2j.gameserver.cache.HtmCache;
 import net.sf.l2j.gameserver.datatables.AccessLevels;
 import net.sf.l2j.gameserver.datatables.AdminCommandAccessRights;
@@ -32,6 +31,7 @@ import net.sf.l2j.gameserver.instancemanager.Manager;
 import net.sf.l2j.gameserver.instancemanager.QuestManager;
 import net.sf.l2j.gameserver.model.L2Multisell;
 import net.sf.l2j.gameserver.model.actor.instance.L2PcInstance;
+import net.sf.l2j.gameserver.model.olympiad.Olympiad;
 import net.sf.l2j.gameserver.network.SystemMessageId;
 import net.sf.l2j.gameserver.network.serverpackets.SystemMessage;
 
@@ -106,15 +106,8 @@ public class AdminAdmin implements IAdminCommandHandler
 		}
 		else if (command.startsWith("admin_saveolymp"))
 		{
-			try
-			{
-				Olympiad.getInstance().save();
-			}
-			catch (Exception e)
-			{
-				e.printStackTrace();
-			}
-			activeChar.sendMessage("olympiad stuff saved!!");
+			Olympiad.getInstance().saveOlympiadStatus();
+			activeChar.sendMessage("olympiad system saved.");
 		}
 		else if (command.startsWith("admin_endolympiad"))
 		{

+ 6 - 3
L2_GameServer/java/net/sf/l2j/gameserver/handler/skillhandlers/Blow.java

@@ -14,7 +14,8 @@
  */
 package net.sf.l2j.gameserver.handler.skillhandlers;
 
-import net.sf.l2j.gameserver.Olympiad;
+import net.sf.l2j.gameserver.model.olympiad.Olympiad;
+import net.sf.l2j.gameserver.ai.CtrlIntention;
 import net.sf.l2j.gameserver.handler.ISkillHandler;
 import net.sf.l2j.gameserver.model.L2Character;
 import net.sf.l2j.gameserver.model.L2Effect;
@@ -154,7 +155,9 @@ public class Blow implements ISkillHandler
 									player.getStatus().stopHpMpRegeneration();
 									player.setIsDead(true);
 									player.setIsPendingRevive(true);
-								}
+									if (player.getPet() != null)
+										player.getPet().getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE, null);
+				                }
 								else
 									player.doDie(activeChar);
 							}
@@ -188,7 +191,7 @@ public class Blow implements ISkillHandler
 			        		((L2PcInstance)target).isInOlympiadMode() &&
 			        		((L2PcInstance)target).getOlympiadGameId() == activePlayer.getOlympiadGameId())
 			        {
-			        	Olympiad.getInstance().notifyCompetitorDamage(activePlayer.getObjectId(), (int) damage, activePlayer.getOlympiadGameId());
+			        	Olympiad.getInstance().notifyCompetitorDamage(activePlayer, (int) damage, activePlayer.getOlympiadGameId());
 			        }
 				}
 			}

+ 3 - 0
L2_GameServer/java/net/sf/l2j/gameserver/handler/skillhandlers/Pdam.java

@@ -17,6 +17,7 @@ package net.sf.l2j.gameserver.handler.skillhandlers;
 import java.util.logging.Logger;
 
 import net.sf.l2j.Config;
+import net.sf.l2j.gameserver.ai.CtrlIntention;
 import net.sf.l2j.gameserver.datatables.SkillTable;
 import net.sf.l2j.gameserver.handler.ISkillHandler;
 import net.sf.l2j.gameserver.lib.Log;
@@ -196,6 +197,8 @@ public class Pdam implements ISkillHandler
 											player.getStatus().stopHpMpRegeneration();
 											player.setIsDead(true);
 											player.setIsPendingRevive(true);
+											if (player.getPet() != null)
+												player.getPet().getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE, null);
 										}
 										else
 											player.doDie(activeChar);

+ 9 - 3
L2_GameServer/java/net/sf/l2j/gameserver/handler/usercommandhandlers/OlympiadStat.java

@@ -14,9 +14,11 @@
  */
 package net.sf.l2j.gameserver.handler.usercommandhandlers;
 
-import net.sf.l2j.gameserver.Olympiad;
 import net.sf.l2j.gameserver.handler.IUserCommandHandler;
 import net.sf.l2j.gameserver.model.actor.instance.L2PcInstance;
+import net.sf.l2j.gameserver.model.olympiad.Olympiad;
+import net.sf.l2j.gameserver.network.SystemMessageId;
+import net.sf.l2j.gameserver.network.serverpackets.SystemMessage;
 
 /**
  * Support for /olympiadstat command
@@ -37,8 +39,12 @@ public class OlympiadStat implements IUserCommandHandler
 	{
 		if (id != COMMAND_IDS[0])
 			return false;
-		
-		activeChar.sendMessage("Your current record for this Grand Olympiad is " + Olympiad.getInstance().getCompetitionDone(activeChar.getObjectId()) + " match(s) played. You have earned " + Olympiad.getInstance().getNoblePoints(activeChar.getObjectId()) + " Olympiad Point(s)");
+		SystemMessage sm = new SystemMessage(SystemMessageId.THE_CURRENT_RECORD_FOR_THIS_OLYMPIAD_SESSION_IS_S1_MATCHES_S2_WINS_S3_DEFEATS_YOU_HAVE_EARNED_S4_OLYMPIAD_POINTS);
+		sm.addNumber(Olympiad.getInstance().getCompetitionDone(activeChar.getObjectId()));
+		sm.addNumber(Olympiad.getInstance().getCompetitionWon(activeChar.getObjectId()));
+		sm.addNumber(Olympiad.getInstance().getCompetitionLost(activeChar.getObjectId()));
+		sm.addNumber(Olympiad.getInstance().getNoblePoints(activeChar.getObjectId()));
+		activeChar.sendPacket(sm);
 		return true;
 	}
 	

+ 1 - 1
L2_GameServer/java/net/sf/l2j/gameserver/model/L2ItemInstance.java

@@ -619,7 +619,7 @@ public final class L2ItemInstance extends L2Object
     
     public boolean isOlyRestrictedItem()
     {
-        return Config.LIST_OLY_RESTRICTED_ITEMS.contains(_itemId);
+        return (Config.LIST_OLY_RESTRICTED_ITEMS.contains(_itemId));
     }
 
     /**

+ 2 - 2
L2_GameServer/java/net/sf/l2j/gameserver/model/L2Summon.java

@@ -18,7 +18,6 @@ import java.util.Collection;
 
 import net.sf.l2j.Config;
 import net.sf.l2j.gameserver.GeoData;
-import net.sf.l2j.gameserver.Olympiad;
 import net.sf.l2j.gameserver.ai.CtrlIntention;
 import net.sf.l2j.gameserver.ai.L2CharacterAI;
 import net.sf.l2j.gameserver.ai.L2SummonAI;
@@ -35,6 +34,7 @@ import net.sf.l2j.gameserver.model.actor.stat.SummonStat;
 import net.sf.l2j.gameserver.model.actor.status.SummonStatus;
 import net.sf.l2j.gameserver.model.base.Experience;
 import net.sf.l2j.gameserver.model.itemcontainer.PetInventory;
+import net.sf.l2j.gameserver.model.olympiad.Olympiad;
 import net.sf.l2j.gameserver.network.SystemMessageId;
 import net.sf.l2j.gameserver.network.serverpackets.ActionFailed;
 import net.sf.l2j.gameserver.network.serverpackets.ExPartyPetWindowAdd;
@@ -826,7 +826,7 @@ public abstract class L2Summon extends L2PlayableInstance
 					((L2PcInstance)target).isInOlympiadMode() &&
 					((L2PcInstance)target).getOlympiadGameId() == getOwner().getOlympiadGameId())
 			{
-				Olympiad.getInstance().notifyCompetitorDamage(getOwner().getObjectId(), damage, getOwner().getOlympiadGameId());
+				Olympiad.getInstance().notifyCompetitorDamage(getOwner(), damage, getOwner().getOlympiadGameId());
 			}
 
 			SystemMessage sm;

+ 1 - 1
L2_GameServer/java/net/sf/l2j/gameserver/model/actor/instance/L2CubicInstance.java

@@ -21,7 +21,6 @@ import java.util.logging.Logger;
 
 import javolution.util.FastList;
 import net.sf.l2j.Config;
-import net.sf.l2j.gameserver.Olympiad;
 import net.sf.l2j.gameserver.ThreadPoolManager;
 import net.sf.l2j.gameserver.datatables.SkillTable;
 import net.sf.l2j.gameserver.handler.ISkillHandler;
@@ -38,6 +37,7 @@ import net.sf.l2j.gameserver.model.L2Party;
 import net.sf.l2j.gameserver.model.L2Skill;
 import net.sf.l2j.gameserver.model.entity.TvTEvent;
 import net.sf.l2j.gameserver.model.entity.TvTEventTeam;
+import net.sf.l2j.gameserver.model.olympiad.Olympiad;
 import net.sf.l2j.gameserver.network.serverpackets.MagicSkillUse;
 import net.sf.l2j.gameserver.skills.l2skills.L2SkillDrain;
 import net.sf.l2j.gameserver.taskmanager.AttackStanceTaskManager;

+ 5 - 5
L2_GameServer/java/net/sf/l2j/gameserver/model/actor/instance/L2NpcInstance.java

@@ -24,7 +24,6 @@ import java.util.logging.Level;
 import javolution.text.TextBuilder;
 import javolution.util.FastList;
 import net.sf.l2j.Config;
-import net.sf.l2j.gameserver.Olympiad;
 import net.sf.l2j.gameserver.SevenSigns;
 import net.sf.l2j.gameserver.SevenSignsFestival;
 import net.sf.l2j.gameserver.ThreadPoolManager;
@@ -62,6 +61,7 @@ import net.sf.l2j.gameserver.model.entity.Castle;
 import net.sf.l2j.gameserver.model.entity.Fort;
 import net.sf.l2j.gameserver.model.entity.L2Event;
 import net.sf.l2j.gameserver.model.itemcontainer.NpcInventory;
+import net.sf.l2j.gameserver.model.olympiad.Olympiad;
 import net.sf.l2j.gameserver.model.quest.Quest;
 import net.sf.l2j.gameserver.model.quest.QuestState;
 import net.sf.l2j.gameserver.model.quest.State;
@@ -2174,7 +2174,7 @@ public class L2NpcInstance extends L2Character
 				break;
 			case 31688:
 				if (player.isNoble())
-					filename = Olympiad.OLYMPIAD_HTML_FILE + "noble_main.htm";
+					filename = Olympiad.OLYMPIAD_HTML_PATH + "noble_main.htm";
 				else
 					filename = (getHtmlPath(npcId, val));
 				break;
@@ -2184,15 +2184,15 @@ public class L2NpcInstance extends L2Character
 			case 31771:
 			case 31772:
 				if (player.isHero())
-					filename = Olympiad.OLYMPIAD_HTML_FILE + "hero_main.htm";
+					filename = Olympiad.OLYMPIAD_HTML_PATH + "hero_main.htm";
 				else
 					filename = (getHtmlPath(npcId, val));
 				break;
 			case 36402:
 				if (player.olyBuff > 0 && !player.inObserverMode())
-					filename = Olympiad.OLYMPIAD_HTML_FILE + "olympiad_buffs.htm";
+					filename = Olympiad.OLYMPIAD_HTML_PATH + "olympiad_buffs.htm";
 				else
-					filename = Olympiad.OLYMPIAD_HTML_FILE + "olympiad_nobuffs.htm";
+					filename = Olympiad.OLYMPIAD_HTML_PATH + "olympiad_nobuffs.htm";
 				break;
 			default:
 				if (npcId >= 31865 && npcId <= 31918)

+ 31 - 28
L2_GameServer/java/net/sf/l2j/gameserver/model/actor/instance/L2OlympiadManagerInstance.java

@@ -17,13 +17,14 @@ package net.sf.l2j.gameserver.model.actor.instance;
 import java.util.logging.Logger;
 
 import javolution.text.TextBuilder;
+import javolution.util.FastMap;
 import net.sf.l2j.Config;
-import net.sf.l2j.gameserver.Olympiad;
 import net.sf.l2j.gameserver.datatables.NpcBufferTable;
 import net.sf.l2j.gameserver.datatables.SkillTable;
 import net.sf.l2j.gameserver.model.L2ItemInstance;
 import net.sf.l2j.gameserver.model.L2Multisell;
 import net.sf.l2j.gameserver.model.L2Skill;
+import net.sf.l2j.gameserver.model.olympiad.Olympiad;
 import net.sf.l2j.gameserver.network.SystemMessageId;
 import net.sf.l2j.gameserver.network.serverpackets.ExHeroList;
 import net.sf.l2j.gameserver.network.serverpackets.InventoryUpdate;
@@ -199,13 +200,13 @@ public class L2OlympiadManagerInstance extends L2FolkInstance
         	
         	if (player.olyBuff > 0)
            	{
-            	html.setFile(Olympiad.OLYMPIAD_HTML_FILE + "olympiad_buffs.htm");
+            	html.setFile(Olympiad.OLYMPIAD_HTML_PATH + "olympiad_buffs.htm");
             	html.replace("%objectId%", String.valueOf(getObjectId()));
             	player.sendPacket(html);
             } 
         	else
             {
-            	html.setFile(Olympiad.OLYMPIAD_HTML_FILE + "olympiad_nobuffs.htm");
+            	html.setFile(Olympiad.OLYMPIAD_HTML_PATH + "olympiad_nobuffs.htm");
             	html.replace("%objectId%", String.valueOf(getObjectId()));
             	player.sendPacket(html);
             	this.deleteMe();                    	
@@ -221,30 +222,32 @@ public class L2OlympiadManagerInstance extends L2FolkInstance
             switch (val)
             {
                 case 1:
-                    String[] matches = Olympiad.getInstance().getMatchList();
-                    int stad;
-                    int showbattle;
-                    replyMSG.append("Grand Olympiad Competition View<br>" +
-                            "Warning: If you watch an Olympiad game, the " +
-                            "summoning of your Servitors or Pets will be " +
-                            "cancelled.<br><br>");
-
-                    if (matches == null)
-                        replyMSG.append("<br>There are no matches at the moment");
-                    else
+                	FastMap<Integer, String> matches = Olympiad.getInstance().getMatchList();
+                    replyMSG.append("<br>Grand Olympiad Competition View <br> Warning: " +
+                    		"If you choose to watch an Olympiad game, any summoning of Servitors " +
+                    		"or Pets will be canceled. <br><br>");
+
+                    for (int i = 0; i < Olympiad.getStadiumCount(); i++)
                     {
-                        for (int i = 0; i < matches.length; i++)
+                    	int arenaID = i + 1;
+                    	String title = "";
+                    	if (matches.containsKey(i))
+                    	{
+                        	title = matches.get(i);
+                        }
+                        else
                         {
-                        	showbattle = Integer.parseInt(matches[i].substring(1,2));
-                        	stad = Integer.parseInt(matches[i].substring(4,5));
-                        	if (showbattle == 1) {
-                        		replyMSG.append("<br><a action=\"bypass -h npc_"+getObjectId()+"_Olympiad 3_" + stad + "\">" +
-                                    matches[i] + "</a>");
-                        	}
-
+                        	title = "Initial State";
                         }
+                    	replyMSG.append("<a action=\"bypass -h npc_"+getObjectId()+"_Olympiad 3_" + i + "\">" +
+                                "Arena " + arenaID + "&nbsp;&nbsp;&nbsp;" + title + "</a><br>");
                     }
-                    replyMSG.append("</body></html>");
+                    
+                    replyMSG.append("<img src=\"L2UI.SquareWhite\" width=270 height=1> <img src=\"L2UI.SquareBlank\" width=1 height=3>");
+                    replyMSG.append("<table width=270 border=0 cellpadding=0 cellspacing=0>");
+                    replyMSG.append("<tr><td width=90 height=20 align=center>");
+                    replyMSG.append("<button value=\"Back\" action=\"bypass -h npc_"+getObjectId()+"_Chat 0\" width=80 height=27 back=\"L2UI_CT1.Button_DF_Down\" fore=\"L2UI_CT1.Button_DF\">");
+                    replyMSG.append("</td></tr></table></body></html>");
 
                     reply.setHtml(replyMSG.toString());
                     player.sendPacket(reply);
@@ -276,7 +279,7 @@ public class L2OlympiadManagerInstance extends L2FolkInstance
                         }
 
                         replyMSG.append("<img src=\"L2UI.SquareWhite\" width=270 height=1> <img src=\"L2UI.SquareBlank\" width=1 height=3>");
-                        replyMSG.append("</center>");
+                        replyMSG.append("<button value=\"Back\" action=\"bypass -h npc_"+getObjectId()+"_OlympiadDesc 3a\" width=80 height=26 back=\"L2UI_ct1.button_df\" fore=\"L2UI_ct1.button_df\"></center>");
                         replyMSG.append("</body></html>");
 
                         reply.setHtml(replyMSG.toString());
@@ -285,7 +288,7 @@ public class L2OlympiadManagerInstance extends L2FolkInstance
                     break;
                 case 3:
                     int id = Integer.parseInt(command.substring(11));
-                    Olympiad.getInstance().addSpectator(id, player);
+                    Olympiad.addSpectator(id, player, true);
                     break;
                 case 4:
                     player.sendPacket(new ExHeroList());
@@ -301,13 +304,13 @@ public class L2OlympiadManagerInstance extends L2FolkInstance
 
     private void showChatWindow(L2PcInstance player, int val, String suffix)
     {
-        String filename = Olympiad.OLYMPIAD_HTML_FILE;
+        String filename = Olympiad.OLYMPIAD_HTML_PATH;
 
         filename += "noble_desc" + val;
         filename += (suffix != null)? suffix + ".htm" : ".htm";
 
-        if (filename.equals(Olympiad.OLYMPIAD_HTML_FILE + "noble_desc0.htm"))
-            filename = Olympiad.OLYMPIAD_HTML_FILE + "noble_main.htm";
+        if (filename.equals(Olympiad.OLYMPIAD_HTML_PATH + "noble_desc0.htm"))
+            filename = Olympiad.OLYMPIAD_HTML_PATH + "noble_main.htm";
 
         showChatWindow(player, filename);
     }

+ 29 - 20
L2_GameServer/java/net/sf/l2j/gameserver/model/actor/instance/L2PcInstance.java

@@ -37,7 +37,6 @@ import net.sf.l2j.gameserver.GeoData;
 import net.sf.l2j.gameserver.GmListTable;
 import net.sf.l2j.gameserver.ItemsAutoDestroy;
 import net.sf.l2j.gameserver.LoginServerThread;
-import net.sf.l2j.gameserver.Olympiad;
 import net.sf.l2j.gameserver.RecipeController;
 import net.sf.l2j.gameserver.SevenSigns;
 import net.sf.l2j.gameserver.SevenSignsFestival;
@@ -52,6 +51,7 @@ import net.sf.l2j.gameserver.cache.WarehouseCacheManager;
 import net.sf.l2j.gameserver.communitybbs.BB.Forum;
 import net.sf.l2j.gameserver.communitybbs.Manager.ForumsBBSManager;
 import net.sf.l2j.gameserver.datatables.AccessLevels;
+import net.sf.l2j.gameserver.datatables.AdminCommandAccessRights;
 import net.sf.l2j.gameserver.datatables.CharTemplateTable;
 import net.sf.l2j.gameserver.datatables.ClanTable;
 import net.sf.l2j.gameserver.datatables.FishTable;
@@ -135,6 +135,7 @@ import net.sf.l2j.gameserver.model.itemcontainer.PcFreight;
 import net.sf.l2j.gameserver.model.itemcontainer.PcInventory;
 import net.sf.l2j.gameserver.model.itemcontainer.PcWarehouse;
 import net.sf.l2j.gameserver.model.itemcontainer.PetInventory;
+import net.sf.l2j.gameserver.model.olympiad.Olympiad;
 import net.sf.l2j.gameserver.model.quest.Quest;
 import net.sf.l2j.gameserver.model.quest.QuestState;
 import net.sf.l2j.gameserver.model.quest.State;
@@ -152,7 +153,7 @@ import net.sf.l2j.gameserver.network.serverpackets.ExFishingEnd;
 import net.sf.l2j.gameserver.network.serverpackets.ExFishingStart;
 import net.sf.l2j.gameserver.network.serverpackets.ExOlympiadMode;
 import net.sf.l2j.gameserver.network.serverpackets.ExOlympiadSpelledInfo;
-import net.sf.l2j.gameserver.network.serverpackets.ExOlympiadUserInfoSpectator;
+import net.sf.l2j.gameserver.network.serverpackets.ExOlympiadUserInfo;
 import net.sf.l2j.gameserver.network.serverpackets.ExSetCompassZoneCode;
 import net.sf.l2j.gameserver.network.serverpackets.ExSpawnEmitter;
 import net.sf.l2j.gameserver.network.serverpackets.GMHide;
@@ -3895,7 +3896,7 @@ public final class L2PcInstance extends L2PlayableInstance
 							        + player.getName() + "). CP: "
 							        + getCurrentCp() + " HP: " + getCurrentHp()
 							        + " MP: " + getCurrentMp());
-						player.sendPacket(new ExOlympiadUserInfoSpectator(this, 1));
+						player.sendPacket(new ExOlympiadUserInfo(this, 1));
 					}
 				}
 			}
@@ -3904,7 +3905,7 @@ public final class L2PcInstance extends L2PlayableInstance
                 for(L2PcInstance spectator : Olympiad.getInstance().getSpectators(_olympiadGameId))
                 {
                     if (spectator == null) continue;
-                    spectator.sendPacket(new ExOlympiadUserInfoSpectator(this, getOlympiadSide()));
+                    spectator.sendPacket(new ExOlympiadUserInfo(this, getOlympiadSide()));
                 }
             }
         }
@@ -3962,7 +3963,7 @@ public final class L2PcInstance extends L2PlayableInstance
                         effect.addIcon(mi);
                     if (ps != null)
                         effect.addPartySpelledIcon(ps);
-                    if (os != null)
+                    if (os != null && !effect.getSkill().isToggle())
                         effect.addOlympiadSpelledIcon(os);
                 }
             }
@@ -9017,7 +9018,7 @@ public final class L2PcInstance extends L2PlayableInstance
 		broadcastUserInfo();
 	}
 
-	public void enterOlympiadObserverMode(int x, int y, int z, int id)
+	public void enterOlympiadObserverMode(int x, int y, int z, int id, boolean storeCoords)
     {
         if (getPet() != null)
             getPet().unSummon(this);
@@ -9032,13 +9033,19 @@ public final class L2PcInstance extends L2PlayableInstance
 
             getCubics().clear();
         }
+        
+        if (getParty() != null)
+        	getParty().removePartyMember(this);
 
     	_olympiadGameId = id;
-        _obsX = getX();
         if (isSitting())
             standUp();
-        _obsY = getY();
-        _obsZ = getZ();
+        if (storeCoords)
+        {
+	        _obsX = getX();
+	        _obsY = getY();
+	        _obsZ = getZ();
+        }
         setTarget(null);
         setIsInvul(true);
         getAppearance().setInvisible();
@@ -9054,10 +9061,11 @@ public final class L2PcInstance extends L2PlayableInstance
 		setTarget(null);
 		setXYZ(_obsX, _obsY, _obsZ);
 		setIsParalyzed(false);
-		getAppearance().setVisible();
 		sendPacket(new GMHide(0));
-        setIsInvul(false);
-
+		if (!AdminCommandAccessRights.getInstance().hasAccess("admin_invis", getAccessLevel()))
+			getAppearance().setVisible();
+		if (!AdminCommandAccessRights.getInstance().hasAccess("admin_invul", getAccessLevel()))
+			setIsInvul(false);
 		if (getAI() != null)
 			getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE);
 
@@ -9071,14 +9079,15 @@ public final class L2PcInstance extends L2PlayableInstance
 		setTarget(null);
 		sendPacket(new ExOlympiadMode(0));
         teleToLocation(_obsX, _obsY, _obsZ, true);
-        getAppearance().setVisible();
         sendPacket(new GMHide(0));
-        setIsInvul(false);
-        if (getAI() != null)
-		{
+        if (!AdminCommandAccessRights.getInstance().hasAccess("admin_invis", getAccessLevel()))
+			getAppearance().setVisible();
+		if (!AdminCommandAccessRights.getInstance().hasAccess("admin_invul", getAccessLevel()))
+			setIsInvul(false);
+		if (getAI() != null)
             getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE);
-        }
-        Olympiad.getInstance().removeSpectator(_olympiadGameId, this);
+
+        Olympiad.removeSpectator(_olympiadGameId, this);
         _olympiadGameId = -1;
         _observerMode = false;
 		broadcastUserInfo();
@@ -10506,7 +10515,7 @@ public final class L2PcInstance extends L2PlayableInstance
 				_log.log(Level.SEVERE, "deleteMe()", e);
 			}
 		
-		if (getOlympiadGameId() != -1) // handle removal from olympiad game
+		if (Olympiad.getInstance().isRegistered(this) || getOlympiadGameId() != -1) // handle removal from olympiad game
 			Olympiad.getInstance().removeDisconnectedCompetitor(this);
 		
 		// If the L2PcInstance has Pet, unsummon it
@@ -11783,7 +11792,7 @@ public final class L2PcInstance extends L2PlayableInstance
         		((L2PcInstance)target).isInOlympiadMode() &&
         		((L2PcInstance)target).getOlympiadGameId() == getOlympiadGameId())
         {
-        	Olympiad.getInstance().notifyCompetitorDamage(getObjectId(), damage, getOlympiadGameId());
+        	Olympiad.getInstance().notifyCompetitorDamage(this, damage, getOlympiadGameId());
         }
 
 		SystemMessage sm = new SystemMessage(SystemMessageId.S1_GAVE_S2_DAMAGE_OF_S3);

+ 0 - 16
L2_GameServer/java/net/sf/l2j/gameserver/model/actor/instance/L2VillageMasterInstance.java

@@ -19,7 +19,6 @@ import java.util.Set;
 
 import javolution.text.TextBuilder;
 import net.sf.l2j.Config;
-import net.sf.l2j.gameserver.Olympiad;
 import net.sf.l2j.gameserver.datatables.CharTemplateTable;
 import net.sf.l2j.gameserver.datatables.ClanTable;
 import net.sf.l2j.gameserver.datatables.SkillTreeTable;
@@ -286,13 +285,6 @@ public final class L2VillageMasterInstance extends L2FolkInstance
                         allowAddition = false;
                     }
 
-                    if (Olympiad.getInstance().isRegisteredInComp(player)
-                        || player.getOlympiadGameId() > 0)
-                    {
-                        player.sendPacket(new SystemMessage(SystemMessageId.YOU_HAVE_ALREADY_BEEN_REGISTERED_IN_A_WAITING_LIST_OF_AN_EVENT));
-                        return;
-                    }
-
                     if (allowAddition)
                     {
                         if (!player.getSubClasses().isEmpty())
@@ -379,14 +371,6 @@ public final class L2VillageMasterInstance extends L2FolkInstance
                      * Note: paramOne = classIndex
                      */
 
-                    if (Olympiad.getInstance().isRegisteredInComp(player)
-                        || player.getOlympiadGameId() > 0)
-                    {
-                        player.sendPacket(new SystemMessage(
-                                                            SystemMessageId.YOU_HAVE_ALREADY_BEEN_REGISTERED_IN_A_WAITING_LIST_OF_AN_EVENT));
-                        return;
-                    }
-                    
                     /*
                      * DrHouse: Despite this is not 100% retail like, it is here to avoid some exploits during subclass changes, specially
                      * on small servers. TODO: On retail, each village master doesn't offer any subclass that is not given by itself so player

+ 2 - 0
L2_GameServer/java/net/sf/l2j/gameserver/model/actor/status/CharStatus.java

@@ -226,6 +226,8 @@ public class CharStatus
                     stopHpMpRegeneration();
                     getActiveChar().setIsDead(true);
                     getActiveChar().setIsPendingRevive(true);
+                    if (getActiveChar().getPet() != null)
+                    	getActiveChar().getPet().getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE, null);
                     return;
                 }
             }

+ 1 - 1
L2_GameServer/java/net/sf/l2j/gameserver/model/entity/Hero.java

@@ -30,12 +30,12 @@ import java.util.logging.Logger;
 import javolution.util.FastMap;
 import net.sf.l2j.Config;
 import net.sf.l2j.L2DatabaseFactory;
-import net.sf.l2j.gameserver.Olympiad;
 import net.sf.l2j.gameserver.datatables.ClanTable;
 import net.sf.l2j.gameserver.model.L2Clan;
 import net.sf.l2j.gameserver.model.L2ItemInstance;
 import net.sf.l2j.gameserver.model.L2World;
 import net.sf.l2j.gameserver.model.actor.instance.L2PcInstance;
+import net.sf.l2j.gameserver.model.olympiad.Olympiad;
 import net.sf.l2j.gameserver.network.SystemMessageId;
 import net.sf.l2j.gameserver.network.serverpackets.InventoryUpdate;
 import net.sf.l2j.gameserver.network.serverpackets.PledgeShowInfoUpdate;

+ 1 - 1
L2_GameServer/java/net/sf/l2j/gameserver/model/entity/TvTEvent.java

@@ -20,7 +20,6 @@ import java.util.logging.Logger;
 
 import javolution.util.FastMap;
 import net.sf.l2j.Config;
-import net.sf.l2j.gameserver.Olympiad;
 import net.sf.l2j.gameserver.datatables.DoorTable;
 import net.sf.l2j.gameserver.datatables.ItemTable;
 import net.sf.l2j.gameserver.datatables.NpcTable;
@@ -34,6 +33,7 @@ import net.sf.l2j.gameserver.model.actor.instance.L2PcInstance;
 import net.sf.l2j.gameserver.model.actor.instance.L2PetInstance;
 import net.sf.l2j.gameserver.model.actor.instance.L2SummonInstance;
 import net.sf.l2j.gameserver.model.itemcontainer.PcInventory;
+import net.sf.l2j.gameserver.model.olympiad.Olympiad;
 import net.sf.l2j.gameserver.network.SystemMessageId;
 import net.sf.l2j.gameserver.network.clientpackets.Say2;
 import net.sf.l2j.gameserver.network.serverpackets.CreatureSay;

+ 3 - 1
L2_GameServer/java/net/sf/l2j/gameserver/model/itemcontainer/Inventory.java

@@ -86,6 +86,8 @@ public abstract class Inventory extends ItemContainer
     public static final int PAPERDOLL_DECO4 = 27;
     public static final int PAPERDOLL_DECO5 = 28;
     public static final int PAPERDOLL_DECO6 = 29;
+    
+    public static final int PAPERDOLL_TOTALSLOTS = 30;
 
     //Speed percentage mods
     public static final double MAX_ARMOR_WEIGHT = 12000;
@@ -759,7 +761,7 @@ public abstract class Inventory extends ItemContainer
 	{
 		return _paperdoll[slot];
 	}
-	
+
 	/**
 	 * Returns the item in the paperdoll L2Item slot
 	 * @param L2Item slot identifier

+ 1501 - 0
L2_GameServer/java/net/sf/l2j/gameserver/model/olympiad/Olympiad.java

@@ -0,0 +1,1501 @@
+/*
+ * 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/>.
+ */
+
+/**
+ * @author godson
+ */
+
+package net.sf.l2j.gameserver.model.olympiad;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.Map;
+import java.util.Properties;
+import java.util.concurrent.ScheduledFuture;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javolution.text.TextBuilder;
+import javolution.util.FastMap;
+import net.sf.l2j.Config;
+import net.sf.l2j.L2DatabaseFactory;
+import net.sf.l2j.gameserver.Announcements;
+import net.sf.l2j.gameserver.ThreadPoolManager;
+import net.sf.l2j.gameserver.instancemanager.OlympiadStadiaManager;
+import net.sf.l2j.gameserver.model.actor.instance.L2PcInstance;
+import net.sf.l2j.gameserver.model.entity.Hero;
+import net.sf.l2j.gameserver.model.entity.TvTEvent;
+import net.sf.l2j.gameserver.network.SystemMessageId;
+import net.sf.l2j.gameserver.network.serverpackets.NpcHtmlMessage;
+import net.sf.l2j.gameserver.network.serverpackets.SystemMessage;
+import net.sf.l2j.gameserver.templates.StatsSet;
+import net.sf.l2j.util.L2FastList;
+
+public class Olympiad
+{
+	protected static final Logger _log = Logger.getLogger(Olympiad.class.getName());
+	private static Olympiad _instance;
+	
+	private static Map<Integer, StatsSet> _nobles;
+	protected static L2FastList<StatsSet> _heroesToBe;
+	private static L2FastList<L2PcInstance> _nonClassBasedRegisters;
+	private static Map<Integer, L2FastList<L2PcInstance>> _classBasedRegisters;
+	
+	private static final String OLYMPIAD_DATA_FILE = "config/olympiad.properties";
+	public static final String OLYMPIAD_HTML_PATH = "data/html/olympiad/";
+	private static final String OLYMPIAD_LOAD_NOBLES = "SELECT olympiad_nobles.charId, olympiad_nobles.class_id, "
+	        + "characters.char_name, olympiad_nobles.olympiad_points, olympiad_nobles.competitions_done, "
+	        + "olympiad_nobles.competitions_won, olympiad_nobles.competitions_lost, olympiad_nobles.competitions_drawn "
+	        + "FROM olympiad_nobles, characters WHERE characters.charId = olympiad_nobles.charId";
+	private static final String OLYMPIAD_SAVE_NOBLES = "INSERT INTO olympiad_nobles "
+		    + "(`charId`,`class_id`,`olympiad_points`,`competitions_done`,`competitions_won`,`competitions_lost`,"
+		    + "`competitions_drawn`) VALUES (?,?,?,?,?,?,?)";
+	private static final String OLYMPIAD_UPDATE_NOBLES = "UPDATE olympiad_nobles SET "
+	        + "olympiad_points = ?, competitions_done = ?, competitions_won = ?, competitions_lost = ?, competitions_drawn = ? WHERE charId = ?";
+	private static final String OLYMPIAD_GET_HEROS = "SELECT olympiad_nobles.charId, characters.char_name "
+	        + "FROM olympiad_nobles, characters WHERE characters.charId = olympiad_nobles.charId "
+	        + "AND olympiad_nobles.class_id = ? AND olympiad_nobles.competitions_done >= 9 "
+	        + "ORDER BY olympiad_nobles.olympiad_points DESC, olympiad_nobles.competitions_done DESC";
+	private static final String GET_EACH_CLASS_LEADER = "SELECT characters.char_name from olympiad_nobles_eom, characters "
+	        + "WHERE characters.charId = olympiad_nobles_eom.charId AND olympiad_nobles_eom.class_id = ? "
+	        + "ORDER BY olympiad_nobles_eom.olympiad_points DESC, olympiad_nobles_eom.competitions_done DESC LIMIT 10";
+	private static final String GET_EACH_CLASS_LEADER_CURRENT = "SELECT characters.char_name from olympiad_nobles, characters "
+        + "WHERE characters.charId = olympiad_nobles.charId AND olympiad_nobles.class_id = ? "
+        + "ORDER BY olympiad_nobles.olympiad_points DESC, olympiad_nobles.competitions_done DESC LIMIT 10";
+	private static final String OLYMPIAD_DELETE_ALL = "TRUNCATE olympiad_nobles";
+	private static final String OLYMPIAD_MONTH_CLEAR = "TRUNCATE olympiad_nobles_eom";
+	private static final String OLYMPIAD_MONTH_CREATE = "INSERT INTO olympiad_nobles_eom SELECT * FROM olympiad_nobles";
+	private static final int[] HERO_IDS = { 88, 89, 90, 91, 92, 93, 94, 95, 96,
+	        97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110,
+	        111, 112, 113, 114, 115, 116, 117, 118, 131, 132, 133, 134 };
+	
+	private static final int COMP_START = Config.ALT_OLY_START_TIME; // 6PM
+	private static final int COMP_MIN = Config.ALT_OLY_MIN; // 00 mins
+	private static final long COMP_PERIOD = Config.ALT_OLY_CPERIOD; // 6 hours
+	protected static final long WEEKLY_PERIOD = Config.ALT_OLY_WPERIOD; // 1 week
+	protected static final long VALIDATION_PERIOD = Config.ALT_OLY_VPERIOD; // 24 hours
+	
+	private static final int DEFAULT_POINTS = 18;
+	protected static final int WEEKLY_POINTS = 3;
+	
+	public static final String CHAR_ID = "charId";
+	public static final String CLASS_ID = "class_id";
+	public static final String CHAR_NAME = "char_name";
+	public static final String POINTS = "olympiad_points";
+	public static final String COMP_DONE = "competitions_done";
+	public static final String COMP_WON = "competitions_won";
+	public static final String COMP_LOST = "competitions_lost";
+	public static final String COMP_DRAWN = "competitions_drawn";
+	
+	protected long _olympiadEnd;
+	protected long _validationEnd;
+	
+	/**
+	 * The current period of the olympiad.<br>
+	 * <b>0 -</b> Competition period<br>
+	 * <b>1 -</b> Validation Period
+	 */
+	protected int _period;
+	protected long _nextWeeklyChange;
+	protected int _currentCycle;
+	private long _compEnd;
+	private Calendar _compStart;
+	protected static boolean _inCompPeriod;
+	protected static boolean _compStarted = false;
+	protected ScheduledFuture<?> _scheduledCompStart;
+	protected ScheduledFuture<?> _scheduledCompEnd;
+	protected ScheduledFuture<?> _scheduledOlympiadEnd;
+	protected ScheduledFuture<?> _scheduledWeeklyTask;
+	protected ScheduledFuture<?> _scheduledValdationTask;
+	
+	protected static enum COMP_TYPE
+	{
+		CLASSED,
+		NON_CLASSED
+	}
+	
+	public static Olympiad getInstance()
+	{
+		if (_instance == null)
+			_instance = new Olympiad();
+		return _instance;
+	}
+	
+	public Olympiad()
+	{
+		load();
+		
+		if (_period == 0)
+			init();
+	}
+	
+	public static Integer getStadiumCount()
+	{
+		return OlympiadManager.STADIUMS.length;
+	}
+	
+	private void load()
+	{
+		_nobles = new FastMap<Integer, StatsSet>();
+		
+		Properties OlympiadProperties = new Properties();
+		InputStream is = null;
+		try
+		{
+			is = new FileInputStream(new File("./" + OLYMPIAD_DATA_FILE));
+			OlympiadProperties.load(is);
+		}
+		catch (Exception e)
+		{
+			_log.log(Level.SEVERE, "Olympiad System: Error loading olympiad properties: ", e);
+			return;
+		}
+		finally
+		{
+			try
+			{
+				is.close();
+			}
+			catch (Exception e)
+			{
+			}
+		}
+		
+		_currentCycle = Integer.parseInt(OlympiadProperties.getProperty("CurrentCycle", "1"));
+		_period = Integer.parseInt(OlympiadProperties.getProperty("Period", "0"));
+		_olympiadEnd = Long.parseLong(OlympiadProperties.getProperty("OlympiadEnd", "0"));
+		_validationEnd = Long.parseLong(OlympiadProperties.getProperty("ValdationEnd", "0"));
+		_nextWeeklyChange = Long.parseLong(OlympiadProperties.getProperty("NextWeeklyChange", "0"));
+		
+		switch (_period)
+		{
+			case 0:
+				if (_olympiadEnd == 0
+				        || _olympiadEnd < Calendar.getInstance().getTimeInMillis())
+					setNewOlympiadEnd();
+				break;
+			case 1:
+				if (_validationEnd > Calendar.getInstance().getTimeInMillis())
+				{
+					_scheduledValdationTask = ThreadPoolManager.getInstance().scheduleGeneral(new ValidationEndTask(), getMillisToValidationEnd());
+				}
+				else
+				{
+					_currentCycle++;
+					_period = 0;
+					deleteNobles();
+					setNewOlympiadEnd();
+				}
+				break;
+			default:
+				_log.warning("Olympiad System: Omg something went wrong in loading!! Period = " + _period);
+				return;
+		}
+
+		Connection con = null;
+		try
+		{
+			con = L2DatabaseFactory.getInstance().getConnection();
+			PreparedStatement statement = con.prepareStatement(OLYMPIAD_LOAD_NOBLES);
+			ResultSet rset = statement.executeQuery();
+			
+			while (rset.next())
+			{
+				StatsSet statData = new StatsSet();
+				int charId = rset.getInt(CHAR_ID);
+				statData.set(CLASS_ID, rset.getInt(CLASS_ID));
+				statData.set(CHAR_NAME, rset.getString(CHAR_NAME));
+				statData.set(POINTS, rset.getInt(POINTS));
+				statData.set(COMP_DONE, rset.getInt(COMP_DONE));
+				statData.set(COMP_WON, rset.getInt(COMP_WON));
+				statData.set(COMP_LOST, rset.getInt(COMP_LOST));
+				statData.set(COMP_DRAWN, rset.getInt(COMP_DRAWN));
+				statData.set("to_save", false);
+				
+				_nobles.put(charId, statData);
+			}
+			
+			rset.close();
+			statement.close();
+		}
+		catch (Exception e)
+		{
+			_log.log(Level.WARNING, "Olympiad System: Error loading noblesse data from database: ", e);
+		}
+		finally
+		{
+			try
+			{
+				con.close();
+			}
+			catch (Exception e)
+			{
+			}
+		}
+		
+		synchronized (this)
+		{
+			_log.info("Olympiad System: Loading Olympiad System....");
+			if (_period == 0)
+				_log.info("Olympiad System: Currently in Olympiad Period");
+			else
+				_log.info("Olympiad System: Currently in Validation Period");
+			
+			long milliToEnd;
+			if (_period == 0)
+				milliToEnd = getMillisToOlympiadEnd();
+			else
+				milliToEnd = getMillisToValidationEnd();
+			
+			_log.info("Olympiad System: " + Math.round(milliToEnd / 60000) + " minutes until period ends");
+			
+			if (_period == 0)
+			{
+				milliToEnd = getMillisToWeekChange();
+				
+				_log.info("Olympiad System: Next weekly change is in " + Math.round(milliToEnd / 60000) + " minutes");
+			}
+		}
+		
+		_log.info("Olympiad System: Loaded " + _nobles.size() + " Nobles");
+		
+	}
+	
+	protected void init()
+	{
+		if (_period == 1)
+			return;
+		
+		_nonClassBasedRegisters = new L2FastList<L2PcInstance>();
+		_classBasedRegisters = new FastMap<Integer, L2FastList<L2PcInstance>>();
+		
+		_compStart = Calendar.getInstance();
+		_compStart.set(Calendar.HOUR_OF_DAY, COMP_START);
+		_compStart.set(Calendar.MINUTE, COMP_MIN);
+		_compEnd = _compStart.getTimeInMillis() + COMP_PERIOD;
+		
+		if (_scheduledOlympiadEnd != null)
+			_scheduledOlympiadEnd.cancel(true);
+		
+		_scheduledOlympiadEnd = ThreadPoolManager.getInstance().scheduleGeneral(new OlympiadEndTask(), getMillisToOlympiadEnd());
+		
+		updateCompStatus();
+		scheduleWeeklyChange();
+	}
+	
+	protected class OlympiadEndTask implements Runnable
+	{
+		public void run()
+		{
+			SystemMessage sm = new SystemMessage(SystemMessageId.OLYMPIAD_PERIOD_S1_HAS_ENDED);
+			sm.addNumber(_currentCycle);
+			
+			Announcements.getInstance().announceToAll(sm);
+			Announcements.getInstance().announceToAll("Olympiad Validation Period has began");
+			
+			if (_scheduledWeeklyTask != null)
+				_scheduledWeeklyTask.cancel(true);
+			
+			saveNobleData();
+			
+			_period = 1;
+			sortHerosToBe();
+			giveHeroBonus();
+			Hero.getInstance().computeNewHeroes(_heroesToBe);
+			
+			saveOlympiadStatus();
+			updateMonthlyData();
+			
+			Calendar validationEnd = Calendar.getInstance();
+			_validationEnd = validationEnd.getTimeInMillis() + VALIDATION_PERIOD;
+			
+			_scheduledValdationTask = ThreadPoolManager.getInstance().scheduleGeneral(new ValidationEndTask(), getMillisToValidationEnd());
+		}
+	}
+	
+	protected class ValidationEndTask implements Runnable
+	{
+		public void run()
+		{
+			Announcements.getInstance().announceToAll("Olympiad Validation Period has ended");
+			_period = 0;
+			_currentCycle++;
+			deleteNobles();
+			setNewOlympiadEnd();
+			init();
+		}
+	}
+	
+	public boolean registerNoble(L2PcInstance noble, boolean classBased)
+	{
+		SystemMessage sm;
+		
+		/*
+		 * if (_compStarted) {
+		 * noble.sendMessage("Cant Register whilst competition is under way");
+		 * return false; }
+		 */
+
+		if (!_inCompPeriod)
+		{
+			sm = new SystemMessage(SystemMessageId.THE_OLYMPIAD_GAME_IS_NOT_CURRENTLY_IN_PROGRESS);
+			noble.sendPacket(sm);
+			return false;
+		}
+		
+		if (!noble.isNoble())
+		{
+			sm = new SystemMessage(SystemMessageId.C1_DOES_NOT_MEET_REQUIREMENTS_ONLY_NOBLESS_CAN_PARTICIPATE_IN_THE_OLYMPIAD);
+			sm.addString(noble.getName());
+			noble.sendPacket(sm);
+			return false;
+		}
+		
+		/** Begin Olympiad Restrictions */
+        if (noble.getBaseClass() != noble.getClassId().getId())
+		{
+			sm = new SystemMessage(SystemMessageId.C1_CANT_JOIN_THE_OLYMPIAD_WITH_A_SUB_CLASS_CHARACTER);
+			sm.addString(noble.getName());
+			noble.sendPacket(sm);
+			return false;
+		}
+        if (noble.isCursedWeaponEquipped())
+        {
+        	sm = new SystemMessage(SystemMessageId.CANNOT_JOIN_OLYMPIAD_POSSESSING_S1);
+			sm.addItemName(noble.getCursedWeaponEquippedId());
+			noble.sendPacket(sm);
+			return false;
+        }
+		if (noble.getInventoryLimit()*0.8 <= noble.getInventory().getSize())
+		{
+			sm = new SystemMessage(SystemMessageId.C1_CANNOT_PARTICIPATE_IN_OLYMPIAD_INVENTORY_SLOT_EXCEEDS_80_PERCENT);
+			sm.addPcName(noble);
+			noble.sendPacket(sm);
+			return false;
+		}
+		if (getMillisToCompEnd() < 600000)
+		{
+			sm = new SystemMessage(SystemMessageId.GAME_REQUEST_CANNOT_BE_MADE);
+			noble.sendPacket(sm);
+			return false;
+		}
+		/** End Olympiad Restrictions */
+		
+		if (_classBasedRegisters.containsKey(noble.getClassId().getId()))
+		{
+			L2FastList<L2PcInstance> classed = _classBasedRegisters.get(noble.getClassId().getId());
+			for (L2PcInstance participant : classed)
+			{
+				if (participant.getObjectId() == noble.getObjectId())
+				{
+					sm = new SystemMessage(SystemMessageId.C1_IS_ALREADY_REGISTERED_ON_THE_CLASS_MATCH_WAITING_LIST);
+					sm.addString(noble.getName());
+					noble.sendPacket(sm);
+					return false;
+				}
+			}
+		}
+		
+		if (isRegisteredInComp(noble))
+		{
+			sm = new SystemMessage(SystemMessageId.C1_IS_ALREADY_REGISTERED_ON_THE_NON_CLASS_LIMITED_MATCH_WAITING_LIST);
+			sm.addString(noble.getName());
+			noble.sendPacket(sm);
+			return false;
+		}
+		
+		if (!_nobles.containsKey(noble.getObjectId()))
+		{
+			StatsSet statDat = new StatsSet();
+			statDat.set(CLASS_ID, noble.getClassId().getId());
+			statDat.set(CHAR_NAME, noble.getName());
+			statDat.set(POINTS, DEFAULT_POINTS);
+			statDat.set(COMP_DONE, 0);
+			statDat.set(COMP_WON, 0);
+			statDat.set(COMP_LOST, 0);
+			statDat.set(COMP_DRAWN, 0);
+			statDat.set("to_save", true);
+			
+			_nobles.put(noble.getObjectId(), statDat);
+		}
+
+		if (classBased && getNoblePoints(noble.getObjectId()) < 3)
+		{
+			noble.sendMessage("Cant register when you have less than 3 points");
+			return false;
+		}
+		if (!classBased && getNoblePoints(noble.getObjectId()) < 5)
+		{
+			noble.sendMessage("Cant register when you have less than 5 points");
+			return false;
+		}
+
+		if (classBased)
+		{
+			if (_classBasedRegisters.containsKey(noble.getClassId().getId()))
+			{
+				L2FastList<L2PcInstance> classed = _classBasedRegisters.get(noble.getClassId().getId());
+				classed.add(noble);
+				
+				_classBasedRegisters.remove(noble.getClassId().getId());
+				_classBasedRegisters.put(noble.getClassId().getId(), classed);
+			}
+			else
+			{
+				L2FastList<L2PcInstance> classed = new L2FastList<L2PcInstance>();
+				classed.add(noble);
+				
+				_classBasedRegisters.put(noble.getClassId().getId(), classed);
+			}
+			sm = new SystemMessage(SystemMessageId.YOU_HAVE_BEEN_REGISTERED_IN_A_WAITING_LIST_OF_CLASSIFIED_GAMES);
+			noble.sendPacket(sm);
+		}
+		else
+		{
+			_nonClassBasedRegisters.add(noble);
+			sm = new SystemMessage(SystemMessageId.YOU_HAVE_BEEN_REGISTERED_IN_A_WAITING_LIST_OF_NO_CLASS_GAMES);
+			noble.sendPacket(sm);
+		}
+		
+		return true;
+	}
+	
+	protected static int getNobleCount()
+	{
+		return _nobles.size();
+	}
+	
+	protected static StatsSet getNobleStats(int playerId)
+	{
+		return _nobles.get(playerId);
+	}
+	
+	protected static synchronized void updateNobleStats(int playerId, StatsSet stats)
+	{
+		_nobles.remove(playerId);
+		_nobles.put(playerId, stats);
+	}
+	
+	protected static L2FastList<L2PcInstance> getRegisteredNonClassBased()
+	{
+		return _nonClassBasedRegisters;
+	}
+	
+	protected static Map<Integer, L2FastList<L2PcInstance>> getRegisteredClassBased()
+	{
+		return _classBasedRegisters;
+	}
+	
+	protected static L2FastList<Integer> hasEnoughRegisteredClassed()
+	{
+		L2FastList<Integer> result = new L2FastList<Integer>();
+
+		for (Integer classList : getRegisteredClassBased().keySet())
+		{
+			if (getRegisteredClassBased().get(classList).size() >= Config.ALT_OLY_CLASSED)
+			{
+				result.add(classList);
+			}
+		}
+		
+		if (result.size() > 0)
+		{
+			return result;
+		}
+		return null;
+	}
+
+	protected static boolean hasEnoughRegisteredNonClassed()
+	{
+		return Olympiad.getRegisteredNonClassBased().size() >= Config.ALT_OLY_NONCLASSED;
+	}
+
+	protected static void clearRegistered()
+	{
+		_nonClassBasedRegisters.clear();
+		_classBasedRegisters.clear();
+	}
+	
+	public boolean isRegistered(L2PcInstance noble)
+	{
+		boolean result = false;
+		
+		if (_nonClassBasedRegisters != null && _nonClassBasedRegisters.contains(noble))
+			result = true;
+		
+		else if (_classBasedRegisters != null && _classBasedRegisters.containsKey(noble.getClassId().getId()))
+		{
+			L2FastList<L2PcInstance> classed = _classBasedRegisters.get(noble.getClassId().getId());
+			if (classed != null && classed.contains(noble))
+				result = true;
+		}
+		
+		return result;
+	}
+	
+	public boolean unRegisterNoble(L2PcInstance noble)
+	{
+		SystemMessage sm;
+		/*
+		 * if (_compStarted) {
+		 * noble.sendMessage("Cant Unregister whilst competition is under way");
+		 * return false; }
+		 */
+
+		if (!_inCompPeriod)
+		{
+			sm = new SystemMessage(SystemMessageId.THE_OLYMPIAD_GAME_IS_NOT_CURRENTLY_IN_PROGRESS);
+			noble.sendPacket(sm);
+			return false;
+		}
+		
+		if (!noble.isNoble())
+		{
+			sm = new SystemMessage(SystemMessageId.C1_DOES_NOT_MEET_REQUIREMENTS_ONLY_NOBLESS_CAN_PARTICIPATE_IN_THE_OLYMPIAD);
+			sm.addString(noble.getName());
+			noble.sendPacket(sm);
+			return false;
+		}
+		
+		if (!isRegistered(noble))
+		{
+			sm = new SystemMessage(SystemMessageId.YOU_HAVE_NOT_BEEN_REGISTERED_IN_A_WAITING_LIST_OF_A_GAME);
+			noble.sendPacket(sm);
+			return false;
+		}
+
+		for (OlympiadGame game : OlympiadManager.getInstance().getOlympiadGames().values())
+		{
+			if (game == null)
+				continue;
+			
+			if (game._playerOneID == noble.getObjectId()
+			        || game._playerTwoID == noble.getObjectId())
+			{
+				noble.sendMessage("Can't deregister whilst you are already selected for a game");
+				return false;
+			}
+		}
+		
+		if (_nonClassBasedRegisters.contains(noble))
+			_nonClassBasedRegisters.remove(noble);
+		else
+		{
+			L2FastList<L2PcInstance> classed = _classBasedRegisters.get(noble.getClassId().getId());
+			classed.remove(noble);
+			
+			_classBasedRegisters.remove(noble.getClassId().getId());
+			_classBasedRegisters.put(noble.getClassId().getId(), classed);
+		}
+		
+		sm = new SystemMessage(SystemMessageId.YOU_HAVE_BEEN_DELETED_FROM_THE_WAITING_LIST_OF_A_GAME);
+		noble.sendPacket(sm);
+		
+		return true;
+	}
+	
+	public void removeDisconnectedCompetitor(L2PcInstance player)
+	{
+		if (OlympiadManager.getInstance().getOlympiadGame(player.getOlympiadGameId()) != null)
+			OlympiadManager.getInstance().getOlympiadGame(player.getOlympiadGameId()).handleDisconnect(player);
+		
+		L2FastList<L2PcInstance> classed = _classBasedRegisters.get(player.getClassId().getId());
+		
+		if (_nonClassBasedRegisters.contains(player))
+			_nonClassBasedRegisters.remove(player);
+		else if (classed != null && classed.contains(player))
+		{
+			classed.remove(player);
+			
+			_classBasedRegisters.remove(player.getClassId().getId());
+			_classBasedRegisters.put(player.getClassId().getId(), classed);
+		}		
+	}
+	
+	public void notifyCompetitorDamage(L2PcInstance player, int damage, int gameId)
+	{
+		if (OlympiadManager.getInstance().getOlympiadGames().get(gameId) != null)
+			OlympiadManager.getInstance().getOlympiadGames().get(gameId).addDamage(player, damage);
+	}
+	
+	private void updateCompStatus()
+	{
+		// _compStarted = false;
+		
+		synchronized (this)
+		{
+			long milliToStart = getMillisToCompBegin();
+			
+			double numSecs = (milliToStart / 1000) % 60;
+			double countDown = ((milliToStart / 1000) - numSecs) / 60;
+			int numMins = (int) Math.floor(countDown % 60);
+			countDown = (countDown - numMins) / 60;
+			int numHours = (int) Math.floor(countDown % 24);
+			int numDays = (int) Math.floor((countDown - numHours) / 24);
+			
+			_log.info("Olympiad System: Competition Period Starts in "
+			        + numDays + " days, " + numHours + " hours and " + numMins
+			        + " mins.");
+			
+			_log.info("Olympiad System: Event starts/started : "
+			        + _compStart.getTime());
+		}
+		
+		_scheduledCompStart = ThreadPoolManager.getInstance().scheduleGeneral(new Runnable() {
+			public void run()
+			{
+				if (isOlympiadEnd())
+					return;
+				
+				_inCompPeriod = true;
+				OlympiadManager om = new OlympiadManager();
+				
+				Announcements.getInstance().announceToAll(new SystemMessage(SystemMessageId.THE_OLYMPIAD_GAME_HAS_STARTED));
+				_log.info("Olympiad System: Olympiad Game Started");
+				
+				Thread olyCycle = new Thread(om);
+				olyCycle.start();
+				
+				long regEnd = getMillisToCompEnd() - 600000;
+				if (regEnd > 0)
+				{
+					ThreadPoolManager.getInstance().scheduleGeneral(new Runnable() {
+						public void run()
+						{
+							Announcements.getInstance().announceToAll(new SystemMessage(SystemMessageId.OLYMPIAD_REGISTRATION_PERIOD_ENDED));
+						}
+					}, regEnd);
+				}
+				
+				_scheduledCompEnd = ThreadPoolManager.getInstance().scheduleGeneral(new Runnable() {
+					public void run()
+					{
+						if (isOlympiadEnd())
+							return;
+						_inCompPeriod = false;
+						Announcements.getInstance().announceToAll(new SystemMessage(SystemMessageId.THE_OLYMPIAD_GAME_HAS_ENDED));
+						_log.info("Olympiad System: Olympiad Game Ended");
+						
+						while (OlympiadGame._battleStarted)
+						{
+							try
+							{
+								// wait 1 minutes for end of pendings games
+								Thread.sleep(60000);
+							}
+							catch (InterruptedException e)
+							{
+							}
+						}
+						saveOlympiadStatus();
+						
+						init();
+					}
+				}, getMillisToCompEnd());
+			}
+		}, getMillisToCompBegin());
+	}
+	
+	private long getMillisToOlympiadEnd()
+	{
+		// if (_olympiadEnd > Calendar.getInstance().getTimeInMillis())
+		return (_olympiadEnd - Calendar.getInstance().getTimeInMillis());
+		// return 10L;
+	}
+	
+	public void manualSelectHeroes()
+	{
+		if (_scheduledOlympiadEnd != null)
+			_scheduledOlympiadEnd.cancel(true);
+		
+		_scheduledOlympiadEnd = ThreadPoolManager.getInstance().scheduleGeneral(new OlympiadEndTask(), 0);
+	}
+	
+	protected long getMillisToValidationEnd()
+	{
+		if (_validationEnd > Calendar.getInstance().getTimeInMillis())
+			return (_validationEnd - Calendar.getInstance().getTimeInMillis());
+		return 10L;
+	}
+	
+	public boolean isOlympiadEnd()
+	{
+		return (_period != 0);
+	}
+	
+	protected void setNewOlympiadEnd()
+	{
+		SystemMessage sm = new SystemMessage(SystemMessageId.OLYMPIAD_PERIOD_S1_HAS_STARTED);
+		sm.addNumber(_currentCycle);
+		
+		Announcements.getInstance().announceToAll(sm);
+		
+		Calendar currentTime = Calendar.getInstance();
+		currentTime.add(Calendar.MONTH, 1);
+		currentTime.set(Calendar.DAY_OF_MONTH, 1);
+		currentTime.set(Calendar.AM_PM, Calendar.AM);
+		currentTime.set(Calendar.HOUR, 12);
+		currentTime.set(Calendar.MINUTE, 0);
+		currentTime.set(Calendar.SECOND, 0);
+		_olympiadEnd = currentTime.getTimeInMillis();
+		
+		Calendar nextChange = Calendar.getInstance();
+		_nextWeeklyChange = nextChange.getTimeInMillis() + WEEKLY_PERIOD;
+	}
+	
+	public boolean inCompPeriod()
+	{
+		return _inCompPeriod;
+	}
+	
+	private long getMillisToCompBegin()
+	{
+		if (_compStart.getTimeInMillis() < Calendar.getInstance().getTimeInMillis()
+		        && _compEnd > Calendar.getInstance().getTimeInMillis())
+			return 10L;
+		
+		if (_compStart.getTimeInMillis() > Calendar.getInstance().getTimeInMillis())
+			return (_compStart.getTimeInMillis() - Calendar.getInstance().getTimeInMillis());
+		
+		return setNewCompBegin();
+	}
+	
+	private long setNewCompBegin()
+	{
+		_compStart = Calendar.getInstance();
+		_compStart.set(Calendar.HOUR_OF_DAY, COMP_START);
+		_compStart.set(Calendar.MINUTE, COMP_MIN);
+		_compStart.add(Calendar.HOUR_OF_DAY, 24);
+		_compEnd = _compStart.getTimeInMillis() + COMP_PERIOD;
+		
+		_log.info("Olympiad System: New Schedule @ " + _compStart.getTime());
+		
+		return (_compStart.getTimeInMillis() - Calendar.getInstance().getTimeInMillis());
+	}
+	
+	protected long getMillisToCompEnd()
+	{
+		// if (_compEnd > Calendar.getInstance().getTimeInMillis())
+		return (_compEnd - Calendar.getInstance().getTimeInMillis());
+		// return 10L;
+	}
+	
+	private long getMillisToWeekChange()
+	{
+		if (_nextWeeklyChange > Calendar.getInstance().getTimeInMillis())
+			return (_nextWeeklyChange - Calendar.getInstance().getTimeInMillis());
+		return 10L;
+	}
+	
+	private void scheduleWeeklyChange()
+	{
+		_scheduledWeeklyTask = ThreadPoolManager.getInstance().scheduleGeneralAtFixedRate(new Runnable() {
+			public void run()
+			{
+				addWeeklyPoints();
+				_log.info("Olympiad System: Added weekly points to nobles");
+				
+				Calendar nextChange = Calendar.getInstance();
+				_nextWeeklyChange = nextChange.getTimeInMillis()
+				        + WEEKLY_PERIOD;
+			}
+		}, getMillisToWeekChange(), WEEKLY_PERIOD);
+	}
+	
+	protected synchronized void addWeeklyPoints()
+	{
+		if (_period == 1)
+			return;
+		
+		for (Integer nobleId : _nobles.keySet())
+		{
+			StatsSet nobleInfo = _nobles.get(nobleId);
+			int currentPoints = nobleInfo.getInteger(POINTS);
+			currentPoints += WEEKLY_POINTS;
+			nobleInfo.set(POINTS, currentPoints);
+			
+			updateNobleStats(nobleId, nobleInfo);
+		}
+	}
+	
+	public FastMap<Integer, String> getMatchList()
+	{
+		return OlympiadManager.getInstance().getAllTitles();
+	}
+	
+	// returns the players for the given olympiad game Id
+	public L2PcInstance[] getPlayers(int Id)
+	{
+		if (OlympiadManager.getInstance().getOlympiadGame(Id) == null)
+			return null;
+		else
+			return OlympiadManager.getInstance().getOlympiadGame(Id).getPlayers();
+	}
+	
+	public int getCurrentCycle()
+	{
+		return _currentCycle;
+	}
+	
+	public static void addSpectator(int id, L2PcInstance spectator, boolean storeCoords)
+	{
+		if (getInstance().isRegisteredInComp(spectator))
+		{
+			spectator.sendPacket(new SystemMessage(SystemMessageId.WHILE_YOU_ARE_ON_THE_WAITING_LIST_YOU_ARE_NOT_ALLOWED_TO_WATCH_THE_GAME));
+			return;
+		}
+		if (!TvTEvent.isInactive()
+		        && TvTEvent.isPlayerParticipant(spectator.getObjectId()))
+		{
+			spectator.sendMessage("You can not observe games while registered for TvT");
+			return;
+		}
+		
+		OlympiadManager.STADIUMS[id].addSpectator(id, spectator, storeCoords);
+	}
+	
+	public static int getSpectatorArena(L2PcInstance player)
+	{
+		for (int i = 0; i < OlympiadManager.STADIUMS.length; i++)
+		{
+			if (OlympiadManager.STADIUMS[i].getSpectators().contains(player))
+				return i;
+		}
+		return -1;
+	}
+	
+	public static void removeSpectator(int id, L2PcInstance spectator)
+	{
+		OlympiadManager.STADIUMS[id].removeSpectator(spectator);
+	}
+	
+	public L2FastList<L2PcInstance> getSpectators(int id)
+	{
+		if (OlympiadManager.getInstance().getOlympiadGame(id) == null)
+			return null;
+		return OlympiadManager.STADIUMS[id].getSpectators();
+	}
+	
+	public Map<Integer, OlympiadGame> getOlympiadGames()
+	{
+		return OlympiadManager.getInstance().getOlympiadGames();
+	}
+	
+	public boolean playerInStadia(L2PcInstance player)
+	{
+		return (OlympiadStadiaManager.getInstance().getStadium(player) != null);
+	}
+	
+	public int[] getWaitingList()
+	{
+		int[] array = new int[2];
+		
+		if (!inCompPeriod())
+			return null;
+		
+		int classCount = 0;
+		
+		if (_classBasedRegisters.size() != 0)
+			for (L2FastList<L2PcInstance> classed : _classBasedRegisters.values())
+			{
+				classCount += classed.size();
+			}
+		
+		array[0] = classCount;
+		array[1] = _nonClassBasedRegisters.size();
+		
+		return array;
+	}
+	
+	/**
+	 * Save noblesse data to database
+	 */
+	protected synchronized void saveNobleData()
+	{
+		if (_nobles == null || _nobles.isEmpty())
+			return;
+		
+		Connection con = null;
+		try
+		{
+			con = L2DatabaseFactory.getInstance().getConnection();
+			PreparedStatement statement;
+			
+			for (Integer nobleId : _nobles.keySet())
+			{
+				StatsSet nobleInfo = _nobles.get(nobleId);
+				
+				if (nobleInfo == null)
+					continue;
+				
+				int charId = nobleId;
+				int classId = nobleInfo.getInteger(CLASS_ID);
+				int points = nobleInfo.getInteger(POINTS);
+				int compDone = nobleInfo.getInteger(COMP_DONE);
+				int compWon = nobleInfo.getInteger(COMP_WON);
+				int compLost = nobleInfo.getInteger(COMP_LOST);
+				int compDrawn = nobleInfo.getInteger(COMP_DRAWN);
+				boolean toSave = nobleInfo.getBool("to_save");
+				
+				if (toSave)
+				{
+					statement = con.prepareStatement(OLYMPIAD_SAVE_NOBLES);
+					statement.setInt(1, charId);
+					statement.setInt(2, classId);
+					statement.setInt(3, points);
+					statement.setInt(4, compDone);
+					statement.setInt(5, compWon);
+					statement.setInt(6, compLost);
+					statement.setInt(7, compDrawn);
+					
+					nobleInfo.set("to_save", false);
+					
+					updateNobleStats(nobleId, nobleInfo);
+				}
+				else
+				{
+					statement = con.prepareStatement(OLYMPIAD_UPDATE_NOBLES);
+					statement.setInt(1, points);
+					statement.setInt(2, compDone);
+					statement.setInt(3, compWon);
+					statement.setInt(4, compLost);
+					statement.setInt(5, compDrawn);
+					statement.setInt(6, charId);
+				}
+				statement.execute();
+				statement.close();
+			}
+		}
+		catch (SQLException e)
+		{
+			_log.log(Level.SEVERE, "Olympiad System: Failed to save noblesse data to database: ", e);
+		}
+		finally
+		{
+			try
+			{
+				con.close();
+			}
+			catch (Exception e)
+			{
+				e.printStackTrace();
+			}
+		}
+	}
+	
+	/**
+	 *  Save olympiad.properties file with current olympiad status and update noblesse table in database
+	 */
+	public void saveOlympiadStatus()
+	{
+		saveNobleData();
+		
+		Properties OlympiadProperties = new Properties();
+		FileOutputStream fos = null;
+		try
+		{
+			fos = new FileOutputStream(new File("./" + OLYMPIAD_DATA_FILE));
+			
+			OlympiadProperties.setProperty("CurrentCycle", String.valueOf(_currentCycle));
+			OlympiadProperties.setProperty("Period", String.valueOf(_period));
+			OlympiadProperties.setProperty("OlympiadEnd", String.valueOf(_olympiadEnd));
+			OlympiadProperties.setProperty("ValdationEnd", String.valueOf(_validationEnd));
+			OlympiadProperties.setProperty("NextWeeklyChange", String.valueOf(_nextWeeklyChange));
+			
+			OlympiadProperties.store(fos, "Olympiad Properties");
+		}
+		catch (Exception e)
+		{
+			_log.log(Level.WARNING, "Olympiad System: Unable to save olympiad properties to file: ", e);
+		}
+		finally
+		{
+			try
+			{
+				fos.close();
+			}
+			catch (Exception e)
+			{
+			}
+		}
+	}
+	
+	protected void updateMonthlyData()
+	{
+		Connection con = null;
+		try
+		{
+			con = L2DatabaseFactory.getInstance().getConnection();
+			PreparedStatement statement;
+			
+			statement = con.prepareStatement(OLYMPIAD_MONTH_CLEAR);
+			statement.execute();
+			statement.close();
+			statement = con.prepareStatement(OLYMPIAD_MONTH_CREATE);
+			statement.execute();
+			statement.close();
+		}
+		catch (SQLException e)
+		{
+			_log.log(Level.SEVERE, "Olympiad System: Failed to update monthly noblese data: ", e);
+		}
+		finally
+		{
+			try
+			{
+				con.close();
+			}
+			catch (Exception e)
+			{
+			}
+		}
+	}
+	
+	protected void sortHerosToBe()
+	{
+		if (_period != 1)
+			return;
+		
+		if (_nobles != null)
+		{
+			for (Integer nobleId : _nobles.keySet())
+			{
+				StatsSet nobleInfo = _nobles.get(nobleId);
+				
+				if (nobleInfo == null)
+					continue;
+				
+				int charId = nobleId;
+				int classId = nobleInfo.getInteger(CLASS_ID);
+				String charName = nobleInfo.getString(CHAR_NAME);
+				int points = nobleInfo.getInteger(POINTS);
+				int compDone = nobleInfo.getInteger(COMP_DONE);
+				
+				logResult(charName, "", Double.valueOf(charId), Double.valueOf(classId), compDone, points, "noble-charId-classId-compdone-points", 0, "");
+			}
+		}
+		
+		_heroesToBe = new L2FastList<StatsSet>();
+		
+		Connection con = null;
+		
+		try
+		{
+			con = L2DatabaseFactory.getInstance().getConnection();
+			PreparedStatement statement;
+			ResultSet rset;
+			StatsSet hero;
+			L2FastList<StatsSet> soulHounds = new L2FastList<StatsSet>();
+			for (int i = 0; i < HERO_IDS.length; i++)
+			{
+				statement = con.prepareStatement(OLYMPIAD_GET_HEROS);
+				statement.setInt(1, HERO_IDS[i]);
+				rset = statement.executeQuery();
+				
+				if (rset.next())
+				{
+					hero = new StatsSet();
+					hero.set(CLASS_ID, HERO_IDS[i]);
+					hero.set(CHAR_ID, rset.getInt(CHAR_ID));
+					hero.set(CHAR_NAME, rset.getString(CHAR_NAME));
+					
+					if (HERO_IDS[i] == 132 || HERO_IDS[i] == 133) // Male & Female Soulhounds rank as one hero class
+					{
+						hero = _nobles.get(hero.getInteger(CHAR_ID));
+						hero.set(CHAR_ID, rset.getInt(CHAR_ID));
+						soulHounds.add(hero);
+					}
+					else
+					{
+						logResult(hero.getString(CHAR_NAME), "", hero.getDouble(CHAR_ID), hero.getDouble(CLASS_ID), 0, 0, "awarded hero", 0, "");
+						_heroesToBe.add(hero);
+					}
+				}
+				
+				statement.close();
+				rset.close();
+			}
+			switch (soulHounds.size())
+			{
+				case 0:
+				{
+					break;
+				}
+				case 1:
+				{
+					hero = new StatsSet();
+					StatsSet winner = soulHounds.get(0);
+					hero.set(CLASS_ID, winner.getInteger(CLASS_ID));
+					hero.set(CHAR_ID, winner.getInteger(CHAR_ID));
+					hero.set(CHAR_NAME, winner.getString(CHAR_NAME));
+					logResult(hero.getString(CHAR_NAME), "", hero.getDouble(CHAR_ID), hero.getDouble(CLASS_ID), 0, 0, "awarded hero", 0, "");
+					_heroesToBe.add(hero);
+					break;
+				}
+				case 2:
+				{
+					hero = new StatsSet();
+					StatsSet winner;
+					StatsSet hero1 = soulHounds.get(0);
+					StatsSet hero2 = soulHounds.get(1);
+					int hero1Points = hero1.getInteger(POINTS);
+					int hero2Points = hero2.getInteger(POINTS);
+					int hero1Comps = hero1.getInteger(COMP_DONE);
+					int hero2Comps = hero2.getInteger(COMP_DONE);
+					
+					if (hero1Points > hero2Points)
+						winner = hero1;
+					else if (hero2Points > hero1Points)
+						winner = hero2;
+					else
+					{
+						if (hero1Comps > hero2Comps)
+							winner = hero1;
+						else
+							winner = hero2;
+					}
+
+					hero.set(CLASS_ID, winner.getInteger(CLASS_ID));
+					hero.set(CHAR_ID, winner.getInteger(CHAR_ID));
+					hero.set(CHAR_NAME, winner.getString(CHAR_NAME));
+					logResult(hero.getString(CHAR_NAME), "", hero.getDouble(CHAR_ID), hero.getDouble(CLASS_ID), 0, 0, "awarded hero", 0, "");
+					_heroesToBe.add(hero);
+					break;
+				}
+			}
+		}
+		catch (SQLException e)
+		{
+			_log.warning("Olympiad System: Couldnt load heros from DB");
+		}
+		finally
+		{
+			try
+			{
+				con.close();
+			}
+			catch (Exception e)
+			{
+				e.printStackTrace();
+			}
+		}
+		
+	}
+	
+	public L2FastList<String> getClassLeaderBoard(int classId)
+	{
+		// if (_period != 1) return;
+		
+		L2FastList<String> names = new L2FastList<String>();
+		
+		Connection con = null;
+		
+		try
+		{
+			con = L2DatabaseFactory.getInstance().getConnection();
+			PreparedStatement statement;
+			ResultSet rset;
+			if (Config.ALT_OLY_SHOW_MONTHLY_WINNERS)
+				statement = con.prepareStatement(GET_EACH_CLASS_LEADER);
+			else
+				statement = con.prepareStatement(GET_EACH_CLASS_LEADER_CURRENT);
+			statement.setInt(1, classId);
+			rset = statement.executeQuery();
+			
+			while (rset.next())
+			{
+				names.add(rset.getString(CHAR_NAME));
+			}
+			
+			if (classId == 132) // Male & Female SoulHounds are ranked together
+			{
+				statement.setInt(1, 133);
+				rset = statement.executeQuery();
+				while (rset.next())
+				{
+					names.add(rset.getString(CHAR_NAME));
+				}
+			}
+			
+			statement.close();
+			rset.close();
+			
+			return names;
+		}
+		catch (SQLException e)
+		{
+			_log.warning("Olympiad System: Couldnt load olympiad leaders from DB");
+		}
+		finally
+		{
+			try
+			{
+				con.close();
+			}
+			catch (Exception e)
+			{
+				e.printStackTrace();
+			}
+		}
+		
+		return names;
+		
+	}
+	
+	protected void giveHeroBonus()
+	{
+		if (_heroesToBe.size() == 0)
+			return;
+		
+		for (StatsSet hero : _heroesToBe)
+		{
+			int charId = hero.getInteger(CHAR_ID);
+			
+			StatsSet noble = _nobles.get(charId);
+			int currentPoints = noble.getInteger(POINTS);
+			currentPoints += Config.ALT_OLY_HERO_POINTS;
+			noble.set(POINTS, currentPoints);
+			
+			updateNobleStats(charId, noble);
+		}
+	}
+	
+	public int getNoblessePasses(int objId)
+	{
+		if (_period != 1 || _nobles.size() == 0)
+			return 0;
+		
+		StatsSet noble = _nobles.get(objId);
+		if (noble == null)
+			return 0;
+		int points = noble.getInteger(POINTS);
+		if (points <= Config.ALT_OLY_MIN_POINT_FOR_EXCH)
+			return 0;
+		
+		noble.set(POINTS, 0);
+		updateNobleStats(objId, noble);
+		
+		points *= Config.ALT_OLY_GP_PER_POINT;
+		
+		return points;
+	}
+	
+	public boolean isRegisteredInComp(L2PcInstance player)
+	{
+		boolean result = isRegistered(player);
+		
+		if (_inCompPeriod)
+		{
+			for (OlympiadGame game : OlympiadManager.getInstance().getOlympiadGames().values())
+			{
+				if ((game._playerOneID == player.getObjectId())
+				        || (game._playerTwoID == player.getObjectId()))
+				{
+					result = true;
+					break;
+				}
+			}
+		}
+		
+		return result;
+	}
+	
+	public int getNoblePoints(int objId)
+	{
+		if (_nobles.size() == 0)
+			return 0;
+		
+		StatsSet noble = _nobles.get(objId);
+		if (noble == null)
+			return 0;
+		int points = noble.getInteger(POINTS);
+		
+		return points;
+	}
+	
+	public int getCompetitionDone(int objId)
+	{
+		if (_nobles.size() == 0)
+			return 0;
+		
+		StatsSet noble = _nobles.get(objId);
+		if (noble == null)
+			return 0;
+		int points = noble.getInteger(COMP_DONE);
+		
+		return points;
+	}
+
+	public int getCompetitionWon(int objId)
+	{
+		if (_nobles.size() == 0)
+			return 0;
+		
+		StatsSet noble = _nobles.get(objId);
+		if (noble == null)
+			return 0;
+		int points = noble.getInteger(COMP_WON);
+		
+		return points;
+	}
+
+	public int getCompetitionLost(int objId)
+	{
+		if (_nobles.size() == 0)
+			return 0;
+		
+		StatsSet noble = _nobles.get(objId);
+		if (noble == null)
+			return 0;
+		int points = noble.getInteger(COMP_LOST);
+		
+		return points;
+	}
+
+	protected void deleteNobles()
+	{
+		Connection con = null;
+		
+		try
+		{
+			con = L2DatabaseFactory.getInstance().getConnection();
+			PreparedStatement statement = con.prepareStatement(OLYMPIAD_DELETE_ALL);
+			statement.execute();
+			statement.close();
+		}
+		catch (SQLException e)
+		{
+			_log.warning("Olympiad System: Couldnt delete nobles from DB");
+		}
+		finally
+		{
+			try
+			{
+				con.close();
+			}
+			catch (Exception e)
+			{
+				e.printStackTrace();
+			}
+		}
+		
+		_nobles.clear();
+	}
+	
+	/**
+	 * Logs result of Olympiad to a csv file.
+	 * 
+	 * @param playerOne
+	 * @param playerTwo
+	 * @param p1hp
+	 * @param p2hp
+	 * @param p1dmg
+	 * @param p2dmg
+	 * @param result
+	 * @param points
+	 */
+	public static synchronized void logResult(String playerOne, String playerTwo, Double p1hp, Double p2hp,
+			int p1dmg, int p2dmg, String result, int points, String classed)
+	{
+		if (!Config.ALT_OLY_LOG_FIGHTS) return;
+		
+		SimpleDateFormat formatter;
+		formatter = new SimpleDateFormat("dd/MM/yyyy H:mm:ss");
+		String date = formatter.format(new Date());
+		FileWriter save = null;
+		try
+		{
+			File file = new File("log/olympiad.csv");
+			
+			boolean writeHead = false;
+			if (!file.exists())
+				writeHead = true;
+			
+			save = new FileWriter(file, true);
+
+			if (writeHead)
+			{
+				String header = "Date,Player1,Player2,Player1 HP,Player2 HP,Player1 Damage,Player2 Damage,Result,Points,Classed\r\n";
+				save.write(header);
+			}
+			
+			String out = date + "," + playerOne + "," + playerTwo + "," + p1hp + "," + p2hp + ","
+					+ p1dmg + "," + p2dmg + "," + result + "," + points + "," + classed + "\r\n";
+			save.write(out);
+		}
+		catch (IOException e)
+		{
+			_log.log(Level.WARNING, "Olympiad System: Olympiad log could not be saved: ", e);
+		}
+		finally
+		{
+			try
+			{
+				save.close();
+			}
+			catch (Exception e)
+			{
+			}
+		}
+	}
+	
+	public static void sendMatchList(L2PcInstance player)
+	{
+		NpcHtmlMessage message = new NpcHtmlMessage(0);
+		TextBuilder replyMSG = new TextBuilder("<html><body>");
+		replyMSG.append("<center><br>Grand Olympiad Game View<table width=270 border=0 bgcolor=\"000000\">");
+		replyMSG.append("<tr><td fixwidth=30>NO.</td><td fixwidth=60>Status</td><td>Player1 / Player2</td></tr>");
+
+		FastMap<Integer, String> matches = getInstance().getMatchList();
+        for (int i = 0; i < Olympiad.getStadiumCount(); i++)
+        {
+        	int arenaID = i + 1;
+        	String players = "&nbsp;";
+        	String state = "Initial State";
+        	if (matches.containsKey(i))
+        	{
+        		state = "In Progress";
+            	players = matches.get(i);
+            }
+        	replyMSG.append("<tr><td fixwidth=30><a action=\"bypass -h OlympiadArenaChange " + i + "\">" +
+        			arenaID + "</a></td><td fixwidth=60>" + state + "</td><td>" + players + "</td></tr>");
+        }
+        replyMSG.append("</table></center></body></html>");
+
+        message.setHtml(replyMSG.toString());
+        player.sendPacket(message);
+	}
+	
+	public static void bypassChangeArena(String command, L2PcInstance player)
+	{
+		String [] commands = command.split(" ");
+		int id = Integer.parseInt(commands[1]);
+        int arena = getSpectatorArena(player);
+        if (arena >= 0)
+        		Olympiad.removeSpectator(arena, player);
+        Olympiad.addSpectator(id, player, false);
+	}
+}

+ 1234 - 0
L2_GameServer/java/net/sf/l2j/gameserver/model/olympiad/OlympiadGame.java

@@ -0,0 +1,1234 @@
+/*
+ * 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 net.sf.l2j.gameserver.model.olympiad;
+
+import java.util.Map;
+import java.util.logging.Logger;
+
+import net.sf.l2j.Config;
+import net.sf.l2j.gameserver.datatables.HeroSkillTable;
+import net.sf.l2j.gameserver.datatables.NpcTable;
+import net.sf.l2j.gameserver.datatables.SpawnTable;
+import net.sf.l2j.gameserver.model.L2ItemInstance;
+import net.sf.l2j.gameserver.model.L2Party;
+import net.sf.l2j.gameserver.model.L2Skill;
+import net.sf.l2j.gameserver.model.L2Spawn;
+import net.sf.l2j.gameserver.model.L2Summon;
+import net.sf.l2j.gameserver.model.L2World;
+import net.sf.l2j.gameserver.model.actor.instance.L2CubicInstance;
+import net.sf.l2j.gameserver.model.actor.instance.L2PcInstance;
+import net.sf.l2j.gameserver.model.actor.instance.L2PetInstance;
+import net.sf.l2j.gameserver.model.itemcontainer.Inventory;
+import net.sf.l2j.gameserver.model.olympiad.Olympiad.COMP_TYPE;
+import net.sf.l2j.gameserver.network.SystemMessageId;
+import net.sf.l2j.gameserver.network.serverpackets.CreatureSay;
+import net.sf.l2j.gameserver.network.serverpackets.ExAutoSoulShot;
+import net.sf.l2j.gameserver.network.serverpackets.ExOlympiadMatchEnd;
+import net.sf.l2j.gameserver.network.serverpackets.ExOlympiadMode;
+import net.sf.l2j.gameserver.network.serverpackets.ExOlympiadSpelledInfo;
+import net.sf.l2j.gameserver.network.serverpackets.ExOlympiadUserInfo;
+import net.sf.l2j.gameserver.network.serverpackets.InventoryUpdate;
+import net.sf.l2j.gameserver.network.serverpackets.SystemMessage;
+import net.sf.l2j.gameserver.templates.StatsSet;
+import net.sf.l2j.gameserver.templates.chars.L2NpcTemplate;
+import net.sf.l2j.util.L2FastList;
+
+/**
+ * 
+ * @author GodKratos
+ */
+class OlympiadGame
+{
+	protected static final Logger _log = Logger.getLogger(OlympiadGame.class.getName());
+	protected COMP_TYPE _type;
+	protected boolean _aborted;
+	protected boolean _gamestarted;
+	protected boolean _playerOneDisconnected;
+	protected boolean _playerTwoDisconnected;
+	protected boolean _playerOneDefaulted;
+	protected boolean _playerTwoDefaulted;
+	protected String _playerOneName;
+	protected String _playerTwoName;
+	protected int _playerOneID = 0;
+	protected int _playerTwoID = 0;
+	protected static final int OLY_BUFFER = 36402;
+	protected static final int OLY_MANAGER = 31688;
+	private static final String POINTS = "olympiad_points";
+	private static final String COMP_DONE = "competitions_done";
+	private static final String COMP_WON = "competitions_won";
+	private static final String COMP_LOST = "competitions_lost";
+	private static final String COMP_DRAWN = "competitions_drawn";
+	protected static boolean _battleStarted;
+	
+	public int _damageP1 = 0;
+	public int _damageP2 = 0;
+	
+	public L2PcInstance _playerOne;
+	public L2PcInstance _playerTwo;
+	public L2Spawn _spawnOne;
+	public L2Spawn _spawnTwo;
+	protected L2FastList<L2PcInstance> _players;
+	private int[] _stadiumPort;
+	private int x1, y1, z1, x2, y2, z2;
+	public int _stadiumID;
+	private SystemMessage _sm;
+	private SystemMessage _sm2;
+	private SystemMessage _sm3;
+	
+	protected OlympiadGame(int id, COMP_TYPE type, L2FastList<L2PcInstance> list)
+	{
+		_aborted = false;
+		_gamestarted = false;
+		_stadiumID = id;
+		_playerOneDisconnected = false;
+		_playerTwoDisconnected = false;
+		_type = type;
+		_stadiumPort = OlympiadManager.STADIUMS[id].getCoordinates();
+		
+		if (list != null)
+		{
+			_players = list;
+			_playerOne = list.get(0);
+			_playerTwo = list.get(1);
+			
+			try
+			{
+				_playerOneName = _playerOne.getName();
+				_playerTwoName = _playerTwo.getName();
+				_playerOne.setOlympiadGameId(id);
+				_playerTwo.setOlympiadGameId(id);
+				_playerOneID = _playerOne.getObjectId();
+				_playerTwoID = _playerTwo.getObjectId();
+			}
+			catch (Exception e)
+			{
+				_aborted = true;
+				clearPlayers();
+			}
+			
+			if (Config.DEBUG)
+				_log.info("Olympiad System: Game - " + id + ": "
+				        + _playerOne.getName() + " Vs " + _playerTwo.getName());
+		}
+		else
+		{
+			_aborted = true;
+			clearPlayers();
+			return;
+		}
+	}
+	
+	public boolean isAborted()
+	{
+		return _aborted;
+	}
+	
+	protected void clearPlayers()
+	{
+		_playerOne = null;
+		_playerTwo = null;
+		_players = null;
+		_playerOneName = "";
+		_playerTwoName = "";
+		_playerOneID = 0;
+		_playerTwoID = 0;
+	}
+	
+	protected void handleDisconnect(L2PcInstance player)
+	{
+		if (_gamestarted)
+		{
+			if (player == _playerOne)
+				_playerOneDisconnected = true;
+			else if (player == _playerTwo)
+				_playerTwoDisconnected = true;
+		}
+	}
+	
+	public L2Spawn SpawnBuffer(int xPos, int yPos, int zPos, int npcId)
+	{
+		L2NpcTemplate template;
+		template = NpcTable.getInstance().getTemplate(npcId);
+		try
+		{
+			L2Spawn spawn = new L2Spawn(template);
+			spawn.setLocx(xPos);
+			spawn.setLocy(yPos);
+			spawn.setLocz(zPos);
+			spawn.setAmount(1);
+			spawn.setHeading(0);
+			spawn.setRespawnDelay(1);
+			SpawnTable.getInstance().addNewSpawn(spawn, false);
+			spawn.init();
+			return spawn;
+		}
+		catch (Exception e)
+		{
+			return null;
+		}
+	}
+	
+	protected void removals()
+	{
+		if (_aborted)
+			return;
+		
+		if (_playerOne == null || _playerTwo == null)
+			return;
+		if (_playerOneDisconnected || _playerTwoDisconnected)
+			return;
+		
+		for (L2PcInstance player : _players)
+		{
+			try
+			{
+				// Remove Clan Skills
+				if (player.getClan() != null)
+				{
+					for (L2Skill skill : player.getClan().getAllSkills())
+						player.removeSkill(skill, false);
+				}
+				// Abort casting if player casting
+				if (player.isCastingNow())
+				{
+					player.abortCast();
+				}
+				
+				// Force the character to be visible
+				player.getAppearance().setVisible();
+				
+				// Remove Hero Skills
+				if (player.isHero())
+				{
+					for (L2Skill skill : HeroSkillTable.getHeroSkills())
+						player.removeSkill(skill, false);
+				}
+				
+				// Heal Player fully
+				player.setCurrentCp(player.getMaxCp());
+				player.setCurrentHp(player.getMaxHp());
+				player.setCurrentMp(player.getMaxMp());
+				
+				// Remove Buffs
+				player.stopAllEffects();
+				
+				// Remove Summon's Buffs
+				if (player.getPet() != null)
+				{
+					L2Summon summon = player.getPet();
+					summon.stopAllEffects();
+					
+					if (summon instanceof L2PetInstance)
+						summon.unSummon(player);
+				}
+				
+				if (player.getCubics() != null)
+				{
+					boolean removed = false;
+					for (L2CubicInstance cubic : player.getCubics().values())
+					{
+						if (cubic.givenByOther())
+						{
+							cubic.stopAction();
+							player.delCubic(cubic.getId());
+							removed = true;
+						}
+					}
+					if (removed)
+						player.broadcastUserInfo();
+				}
+				
+				// Remove player from his party
+				if (player.getParty() != null)
+				{
+					L2Party party = player.getParty();
+					party.removePartyMember(player);
+				}
+
+				// Remove over enchanted items and hero weapons
+				for (int i = 0; i < Inventory.PAPERDOLL_TOTALSLOTS; i++)
+				{
+					L2ItemInstance equippedItem = player.getInventory().getPaperdollItem(i);
+					
+					if (equippedItem != null && (equippedItem.isHeroItem() || equippedItem.isOlyRestrictedItem()))
+					{
+						player.getInventory().unEquipItemInSlotAndRecord(i);
+						if (equippedItem.isWear())
+							continue;
+						SystemMessage sm = null;
+						if (equippedItem.getEnchantLevel() > 0)
+						{
+							sm = new SystemMessage(SystemMessageId.EQUIPMENT_S1_S2_REMOVED);
+							sm.addNumber(equippedItem.getEnchantLevel());
+							sm.addItemName(equippedItem);
+						}
+						else
+						{
+							sm = new SystemMessage(SystemMessageId.S1_DISARMED);
+							sm.addItemName(equippedItem);
+						}
+						player.sendPacket(sm);
+					}
+				}
+
+				// Remove shot automation
+				Map<Integer, Integer> activeSoulShots = player.getAutoSoulShot();
+				for (int itemId : activeSoulShots.values())
+				{
+					player.removeAutoSoulShot(itemId);
+					ExAutoSoulShot atk = new ExAutoSoulShot(itemId, 0);
+					player.sendPacket(atk);
+				}
+				player.sendSkillList();
+			}
+			catch (Exception e)
+			{
+			}
+		}
+	}
+	
+	protected boolean portPlayersToArena()
+	{
+		boolean _playerOneCrash = (_playerOne == null || _playerOneDisconnected);
+		boolean _playerTwoCrash = (_playerTwo == null || _playerTwoDisconnected);
+		
+		if (_playerOneCrash || _playerTwoCrash || _aborted)
+		{
+			_playerOne = null;
+			_playerTwo = null;
+			_aborted = true;
+			return false;
+		}
+		
+		try
+		{
+			x1 = _playerOne.getX();
+			y1 = _playerOne.getY();
+			z1 = _playerOne.getZ();
+			
+			x2 = _playerTwo.getX();
+			y2 = _playerTwo.getY();
+			z2 = _playerTwo.getZ();
+			
+			if (_playerOne.isSitting())
+				_playerOne.standUp();
+			
+			if (_playerTwo.isSitting())
+				_playerTwo.standUp();
+			
+			_playerOne.setTarget(null);
+			_playerTwo.setTarget(null);
+			
+			_gamestarted = true;
+			
+			_playerOne.teleToLocation(_stadiumPort[0] + 1200, _stadiumPort[1], _stadiumPort[2], false);
+			_playerTwo.teleToLocation(_stadiumPort[0] - 1200, _stadiumPort[1], _stadiumPort[2], false);
+			
+			_playerOne.sendPacket(new ExOlympiadMode(2));
+			_playerTwo.sendPacket(new ExOlympiadMode(2));
+			
+			_spawnOne = SpawnBuffer(_stadiumPort[0] + 1100, _stadiumPort[1], _stadiumPort[2], OLY_BUFFER);
+			_spawnTwo = SpawnBuffer(_stadiumPort[0] - 1100, _stadiumPort[1], _stadiumPort[2], OLY_BUFFER);
+			
+			_playerOne.setIsInOlympiadMode(true);
+			_playerOne.setIsOlympiadStart(false);
+			_playerOne.setOlympiadSide(1);
+			_playerOne.olyBuff = 5;
+			
+			_playerTwo.setIsInOlympiadMode(true);
+			_playerTwo.setIsOlympiadStart(false);
+			_playerTwo.setOlympiadSide(2);
+			_playerTwo.olyBuff = 5;
+		}
+		catch (NullPointerException e)
+		{
+			return false;
+		}
+		return true;
+	}
+	
+	protected void sendMessageToPlayers(boolean toBattleBegin, int nsecond)
+	{
+		if (!toBattleBegin)
+			_sm = new SystemMessage(SystemMessageId.YOU_WILL_ENTER_THE_OLYMPIAD_STADIUM_IN_S1_SECOND_S);
+		else
+			_sm = new SystemMessage(SystemMessageId.THE_GAME_WILL_START_IN_S1_SECOND_S);
+		
+		_sm.addNumber(nsecond);
+		try
+		{
+			for (L2PcInstance player : _players)
+				player.sendPacket(_sm);
+		}
+		catch (Exception e)
+		{
+		}
+	}
+	
+	protected void portPlayersBack()
+	{
+		if (_playerOne != null)
+			_playerOne.teleToLocation(x1, y1, z1, true);
+		
+		if (_playerTwo != null)
+			_playerTwo.teleToLocation(x2, y2, z2, true);
+	}
+	
+	protected void PlayersStatusBack()
+	{
+		for (L2PcInstance player : _players)
+		{
+			try
+			{
+				if (player.isDead() == true)
+				{
+					player.setIsDead(false);
+				}
+				player.getStatus().startHpMpRegeneration();
+				player.setCurrentCp(player.getMaxCp());
+				player.setCurrentHp(player.getMaxHp());
+				player.setCurrentMp(player.getMaxMp());
+				player.setIsInOlympiadMode(false);
+				player.setIsOlympiadStart(false);
+				player.setOlympiadSide(-1);
+				player.setOlympiadGameId(-1);
+				player.sendPacket(new ExOlympiadMode(0));
+				
+				// Add Clan Skills
+				if (player.getClan() != null)
+				{
+					for (L2Skill skill : player.getClan().getAllSkills())
+					{
+						if (skill.getMinPledgeClass() <= player.getPledgeClass())
+							player.addSkill(skill, false);
+					}
+				}
+				
+				// Add Hero Skills
+				if (player.isHero())
+				{
+					for (L2Skill skill : HeroSkillTable.getHeroSkills())
+						player.addSkill(skill, false);
+				}
+				player.sendSkillList();
+			}
+			catch (Exception e)
+			{
+			}
+		}
+	}
+	
+	protected boolean haveWinner()
+	{
+		if (_aborted || _playerOne == null || _playerTwo == null ||
+				_playerOneDisconnected || _playerTwoDisconnected)
+		{
+			return true;
+		}
+		
+		double playerOneHp = 0;
+		
+		try
+		{
+			if (_playerOne != null && _playerOne.getOlympiadGameId() != -1)
+			{
+				playerOneHp = _playerOne.getCurrentHp();
+			}
+		}
+		catch (Exception e)
+		{
+			playerOneHp = 0;
+		}
+		
+		double playerTwoHp = 0;
+		try
+		{
+			if (_playerTwo != null && _playerTwo.getOlympiadGameId() != -1)
+			{
+				playerTwoHp = _playerTwo.getCurrentHp();
+			}
+		}
+		catch (Exception e)
+		{
+			playerTwoHp = 0;
+		}
+		
+		if (playerTwoHp <= 0 || playerOneHp <= 0)
+		{
+			return true;
+		}
+		
+		return false;
+	}
+	
+	protected void validateWinner()
+	{
+		if (_aborted)
+			return;
+		
+		boolean _pOneCrash = (_playerOne == null || _playerOneDisconnected);
+		boolean _pTwoCrash = (_playerTwo == null || _playerTwoDisconnected);
+		
+		int _div;
+		int _gpreward;
+		
+		String classed;
+		switch (_type)
+		{
+			case NON_CLASSED:
+				_div = 5;
+				_gpreward = Config.ALT_OLY_NONCLASSED_RITEM_C;
+				classed = "no";
+				break;
+			default:
+				_div = 3;
+				_gpreward = Config.ALT_OLY_CLASSED_RITEM_C;
+				classed = "yes";
+				break;
+		}
+
+		StatsSet playerOneStat = Olympiad.getNobleStats(_playerOneID);
+		StatsSet playerTwoStat = Olympiad.getNobleStats(_playerTwoID);
+		
+		int playerOnePlayed = playerOneStat.getInteger(COMP_DONE);
+		int playerTwoPlayed = playerTwoStat.getInteger(COMP_DONE);
+		int playerOneWon = playerOneStat.getInteger(COMP_WON);
+		int playerTwoWon = playerTwoStat.getInteger(COMP_WON);
+		int playerOneLost = playerOneStat.getInteger(COMP_LOST);
+		int playerTwoLost = playerTwoStat.getInteger(COMP_LOST);
+		int playerOneDrawn = playerOneStat.getInteger(COMP_DRAWN);
+		int playerTwoDrawn = playerTwoStat.getInteger(COMP_DRAWN);
+		
+		int playerOnePoints = playerOneStat.getInteger(POINTS);
+		int playerTwoPoints = playerTwoStat.getInteger(POINTS);
+		int pointDiff = Math.min(playerOnePoints, playerTwoPoints) / _div;
+
+		// Check for if a player defaulted before battle started
+		if (_playerOneDefaulted || _playerTwoDefaulted)
+		{
+			if (_playerOneDefaulted)
+			{
+				int lostPoints = playerOnePoints / 3;
+				playerOneStat.set(POINTS, playerOnePoints - lostPoints);
+				Olympiad.updateNobleStats(_playerOneID, playerOneStat);
+				SystemMessage sm = new SystemMessage(SystemMessageId.S1_HAS_LOST_S2_OLYMPIAD_POINTS);
+				sm.addString(_playerOneName);
+				sm.addNumber(lostPoints);
+				broadcastMessage(sm, false);
+
+				if (Config.DEBUG)
+					_log.info("Olympia Result: " + _playerOneName + " lost " + lostPoints + " points for defaulting");
+				
+				Olympiad.logResult(_playerOneName,_playerTwoName,0D,0D,0,0,_playerOneName+" default",lostPoints,classed);
+			}
+			if (_playerTwoDefaulted)
+			{
+				int lostPoints = playerTwoPoints / 3;
+				playerTwoStat.set(POINTS, playerTwoPoints - lostPoints);
+				Olympiad.updateNobleStats(_playerTwoID, playerTwoStat);
+				SystemMessage sm = new SystemMessage(SystemMessageId.S1_HAS_LOST_S2_OLYMPIAD_POINTS);
+				sm.addString(_playerTwoName);
+				sm.addNumber(lostPoints);
+				broadcastMessage(sm, false);
+
+				if (Config.DEBUG)
+					_log.info("Olympia Result: " + _playerTwoName + " lost " + lostPoints + " points for defaulting");
+				
+				Olympiad.logResult(_playerOneName,_playerTwoName,0D,0D,0,0,_playerTwoName+" default",lostPoints,classed);
+			}
+			return;
+		}
+		
+		// Create results for players if a player crashed
+		if (_pOneCrash || _pTwoCrash)
+		{
+			if (_pOneCrash && !_pTwoCrash)
+			{
+				try
+				{
+					playerOneStat.set(POINTS, playerOnePoints - pointDiff);
+					playerOneStat.set(COMP_LOST, playerOneLost + 1);
+					
+					if (Config.DEBUG)
+						_log.info("Olympia Result: " + _playerOneName + " vs " + _playerTwoName + " ... "
+						        + _playerOneName + " lost " + pointDiff + " points for crash");
+					
+					Olympiad.logResult(_playerOneName,_playerTwoName,0D,0D,0,0,_playerOneName+" crash",pointDiff,classed);
+					
+					playerTwoStat.set(POINTS, playerTwoPoints + pointDiff);
+					playerTwoStat.set(COMP_WON, playerTwoWon + 1);
+					
+					if (Config.DEBUG)
+						_log.info("Olympia Result: " + _playerOneName + " vs " + _playerTwoName + " ... "
+						        + _playerTwoName + " Win " + pointDiff + " points");
+					
+					_sm = new SystemMessage(SystemMessageId.C1_HAS_WON_THE_GAME);
+					_sm2 = new SystemMessage(SystemMessageId.S1_HAS_GAINED_S2_OLYMPIAD_POINTS);
+					_sm.addString(_playerTwoName);
+					broadcastMessage(_sm, true);
+					_sm2.addString(_playerTwoName);
+					_sm2.addNumber(pointDiff);
+					broadcastMessage(_sm2, false);
+				}
+				catch (Exception e)
+				{
+					e.printStackTrace();
+				}
+				
+			}
+			else if (_pTwoCrash && !_pOneCrash)
+			{
+				try
+				{
+					playerTwoStat.set(POINTS, playerTwoPoints - pointDiff);
+					playerTwoStat.set(COMP_LOST, playerTwoLost + 1);
+					
+					if (Config.DEBUG)
+						_log.info("Olympia Result: " + _playerTwoName + " vs " + _playerOneName + " ... " 
+								+ _playerTwoName + " lost " + pointDiff + " points for crash");
+					
+					Olympiad.logResult(_playerOneName,_playerTwoName,0D,0D,0,0,_playerTwoName+" crash",pointDiff,classed);
+					
+					playerOneStat.set(POINTS, playerOnePoints + pointDiff);
+					playerOneStat.set(COMP_WON, playerOneWon + 1);
+					
+					if (Config.DEBUG)
+						_log.info("Olympia Result: " + _playerTwoName + " vs " + _playerOneName + " ... "
+						        + _playerOneName + " Win " + pointDiff + " points");
+					
+					_sm = new SystemMessage(SystemMessageId.C1_HAS_WON_THE_GAME);
+					_sm2 = new SystemMessage(SystemMessageId.S1_HAS_GAINED_S2_OLYMPIAD_POINTS);
+					_sm.addString(_playerOneName);
+					broadcastMessage(_sm, true);
+					_sm2.addString(_playerOneName);
+					_sm2.addNumber(pointDiff);
+					broadcastMessage(_sm2, false);
+				}
+				catch (Exception e)
+				{
+					e.printStackTrace();
+				}
+			}
+			else if (_pOneCrash && _pTwoCrash)
+			{
+				try
+				{
+					playerOneStat.set(POINTS, playerOnePoints - pointDiff);
+					playerOneStat.set(COMP_LOST, playerOneLost + 1);
+					
+					playerTwoStat.set(POINTS, playerTwoPoints - pointDiff);
+					playerTwoStat.set(COMP_LOST, playerTwoLost + 1);
+					
+					if (Config.DEBUG)
+						_log.info("Olympia Result: " + _playerOneName + " vs " + _playerTwoName + " ... " 
+								+ " both lost " + pointDiff + " points for crash");
+					
+					Olympiad.logResult(_playerOneName,_playerTwoName,0D,0D,0,0,"both crash",pointDiff,classed);
+				}
+				catch (Exception e)
+				{
+					e.printStackTrace();
+				}
+			}
+			playerOneStat.set(COMP_DONE, playerOnePlayed + 1);
+			playerTwoStat.set(COMP_DONE, playerTwoPlayed + 1);
+			
+			Olympiad.updateNobleStats(_playerOneID, playerOneStat);
+			Olympiad.updateNobleStats(_playerTwoID, playerTwoStat);
+			
+			return;
+		}
+		
+		double playerOneHp = 0;
+		if (!_playerOne.isDead())
+		{
+			playerOneHp = _playerOne.getCurrentHp() + _playerOne.getCurrentCp();
+		}
+		
+		double playerTwoHp = 0;
+		if (!_playerTwo.isDead())
+		{
+			playerTwoHp = _playerTwo.getCurrentHp() + _playerTwo.getCurrentCp();
+		}
+		
+		_sm = new SystemMessage(SystemMessageId.C1_HAS_WON_THE_GAME);
+		_sm2 = new SystemMessage(SystemMessageId.S1_HAS_GAINED_S2_OLYMPIAD_POINTS);
+		_sm3 = new SystemMessage(SystemMessageId.S1_HAS_LOST_S2_OLYMPIAD_POINTS);
+		
+		String result = "";
+		
+		// if players crashed, search if they've relogged
+		_playerOne = L2World.getInstance().getPlayer(_playerOneName);
+		_players.set(0, _playerOne);
+		_playerTwo = L2World.getInstance().getPlayer(_playerTwoName);
+		_players.set(1, _playerTwo);
+		
+		String winner = "draw";
+		
+		if (_playerOne == null && _playerTwo == null)
+		{
+			playerOneStat.set(COMP_DRAWN, playerOneDrawn + 1);
+			playerTwoStat.set(COMP_DRAWN, playerTwoDrawn + 1);
+			result = " tie";
+			_sm = new SystemMessage(SystemMessageId.THE_GAME_ENDED_IN_A_TIE);
+			broadcastMessage(_sm, true);
+		}
+		else if (_playerTwo == null
+		        || _playerTwo.isOnline() == 0
+		        || (playerTwoHp == 0 && playerOneHp != 0)
+		        || (_damageP1 > _damageP2 && playerTwoHp != 0 && playerOneHp != 0))
+		{
+			playerOneStat.set(POINTS, playerOnePoints + pointDiff);
+			playerTwoStat.set(POINTS, playerTwoPoints - pointDiff);
+			playerOneStat.set(COMP_WON, playerOneWon + 1);
+			playerTwoStat.set(COMP_LOST, playerTwoLost + 1);
+			
+			_sm.addString(_playerOneName);
+			broadcastMessage(_sm, true);
+			_sm2.addString(_playerOneName);
+			_sm2.addNumber(pointDiff);
+			broadcastMessage(_sm2, false);
+			_sm3.addString(_playerTwoName);
+			_sm3.addNumber(pointDiff);
+			broadcastMessage(_sm3, false);
+			winner = _playerOneName + " won";
+			
+			try
+			{
+				result = " (" + playerOneHp + "hp vs " + playerTwoHp + "hp - "
+				        + _damageP1 + "dmg vs " + _damageP2 + "dmg) "
+				        + _playerOneName + " win " + pointDiff + " points";
+				L2ItemInstance item = _playerOne.getInventory().addItem("Olympiad", Config.ALT_OLY_BATTLE_REWARD_ITEM, _gpreward, _playerOne, null);
+				InventoryUpdate iu = new InventoryUpdate();
+				iu.addModifiedItem(item);
+				_playerOne.sendPacket(iu);
+				
+				SystemMessage sm = new SystemMessage(SystemMessageId.EARNED_S2_S1_S);
+				sm.addItemName(item);
+				sm.addNumber(_gpreward);
+				_playerOne.sendPacket(sm);
+			}
+			catch (Exception e)
+			{
+			}
+		}
+		else if (_playerOne == null
+		        || _playerOne.isOnline() == 0
+		        || (playerOneHp == 0 && playerTwoHp != 0)
+		        || (_damageP2 > _damageP1 && playerOneHp != 0 && playerTwoHp != 0))
+		{
+			playerTwoStat.set(POINTS, playerTwoPoints + pointDiff);
+			playerOneStat.set(POINTS, playerOnePoints - pointDiff);
+			playerTwoStat.set(COMP_WON, playerTwoWon + 1);
+			playerOneStat.set(COMP_LOST, playerOneLost + 1);
+			
+			_sm.addString(_playerTwoName);
+			broadcastMessage(_sm, true);
+			_sm2.addString(_playerTwoName);
+			_sm2.addNumber(pointDiff);
+			broadcastMessage(_sm2, false);
+			_sm3.addString(_playerOneName);
+			_sm3.addNumber(pointDiff);
+			broadcastMessage(_sm3, false);
+			winner = _playerTwoName + " won";
+			
+			try
+			{
+				result = " (" + playerOneHp + "hp vs " + playerTwoHp + "hp - "
+				        + _damageP1 + "dmg vs " + _damageP2 + "dmg) "
+				        + _playerTwoName + " win " + pointDiff + " points";
+				L2ItemInstance item = _playerTwo.getInventory().addItem("Olympiad", Config.ALT_OLY_BATTLE_REWARD_ITEM, _gpreward, _playerTwo, null);
+				InventoryUpdate iu = new InventoryUpdate();
+				iu.addModifiedItem(item);
+				_playerTwo.sendPacket(iu);
+				
+				SystemMessage sm = new SystemMessage(SystemMessageId.EARNED_S2_S1_S);
+				sm.addItemName(item);
+				sm.addNumber(_gpreward);
+				_playerTwo.sendPacket(sm);
+			}
+			catch (Exception e)
+			{
+			}
+		}
+		else
+		{
+			result = " tie";
+			_sm = new SystemMessage(SystemMessageId.THE_GAME_ENDED_IN_A_TIE);
+			broadcastMessage(_sm, true);
+			int pointOneDiff = playerOnePoints / 5;
+		 	int pointTwoDiff = playerTwoPoints / 5;
+		 	playerOneStat.set(POINTS, playerOnePoints - pointOneDiff);
+		 	playerTwoStat.set(POINTS, playerTwoPoints - pointTwoDiff);
+		 	playerOneStat.set(COMP_DRAWN, playerOneDrawn + 1);
+			playerTwoStat.set(COMP_DRAWN, playerTwoDrawn + 1);
+			_sm2 = new SystemMessage(SystemMessageId.S1_HAS_LOST_S2_OLYMPIAD_POINTS);
+		 	_sm2.addString(_playerOneName);
+		 	_sm2.addNumber(pointOneDiff);
+		 	broadcastMessage(_sm2, false);
+		 	_sm3 = new SystemMessage(SystemMessageId.S1_HAS_LOST_S2_OLYMPIAD_POINTS);
+		 	_sm3.addString(_playerTwoName);
+		 	_sm3.addNumber(pointTwoDiff);
+		 	broadcastMessage(_sm3, false);
+		}
+		
+		if (Config.DEBUG)
+			_log.info("Olympia Result: " + _playerOneName + " vs " + _playerTwoName + " ... " + result);
+		
+		playerOneStat.set(COMP_DONE, playerOnePlayed + 1);
+		playerTwoStat.set(COMP_DONE, playerTwoPlayed + 1);
+		
+		Olympiad.updateNobleStats(_playerOneID, playerOneStat);
+		Olympiad.updateNobleStats(_playerTwoID, playerTwoStat);
+		
+		Olympiad.logResult(_playerOneName, _playerTwoName, playerOneHp, playerTwoHp, _damageP1, _damageP2, winner, pointDiff, classed);
+		
+		for (int i = 40; i > 10; i -= 10)
+		{
+			_sm = new SystemMessage(SystemMessageId.YOU_WILL_BE_MOVED_TO_TOWN_IN_S1_SECONDS);
+			_sm.addNumber(i);
+			broadcastMessage(_sm, false);
+			try
+			{
+				Thread.sleep(10000);
+			}
+			catch (InterruptedException e)
+			{
+			}
+			if (i == 20)
+			{
+				_sm = new SystemMessage(SystemMessageId.YOU_WILL_BE_MOVED_TO_TOWN_IN_S1_SECONDS);
+				_sm.addNumber(10);
+				broadcastMessage(_sm, false);
+				try
+				{
+					Thread.sleep(5000);
+				}
+				catch (InterruptedException e)
+				{
+				}
+			}
+		}
+		for (int i = 5; i > 0; i--)
+		{
+			_sm = new SystemMessage(SystemMessageId.YOU_WILL_BE_MOVED_TO_TOWN_IN_S1_SECONDS);
+			_sm.addNumber(i);
+			broadcastMessage(_sm, false);
+			try
+			{
+				Thread.sleep(1000);
+			}
+			catch (InterruptedException e)
+			{
+			}
+		}
+	}
+	
+	protected boolean makeCompetitionStart()
+	{
+		if (_aborted)
+			return false;
+		
+		_sm = new SystemMessage(SystemMessageId.STARTS_THE_GAME);
+		broadcastMessage(_sm, true);
+		try
+		{
+			for (L2PcInstance player : _players)
+			{
+				player.setIsOlympiadStart(true);
+			}
+		}
+		catch (Exception e)
+		{
+			_aborted = true;
+			return false;
+		}
+		return true;
+	}
+	
+	protected void addDamage(L2PcInstance player, int damage)
+	{
+		if (_playerOne == null || _playerTwo == null)
+			return;
+		if (player == _playerOne)
+			_damageP1 += damage;
+		else if (player == _playerTwo)
+			_damageP2 += damage;
+	}
+	
+	protected String getTitle()
+	{
+		String msg = "";
+		msg += _playerOneName + " / " + _playerTwoName;
+		return msg;
+	}
+	
+	protected L2PcInstance[] getPlayers()
+	{
+		L2PcInstance[] players = new L2PcInstance[2];
+		
+		if (_playerOne == null || _playerTwo == null)
+			return null;
+		
+		players[0] = _playerOne;
+		players[1] = _playerTwo;
+		
+		return players;
+	}
+	
+	private void broadcastMessage(SystemMessage sm, boolean toAll)
+	{
+		try
+		{
+			_playerOne.sendPacket(sm);
+			_playerTwo.sendPacket(sm);
+		}
+		catch (Exception e)
+		{
+		}
+		
+		if (toAll && OlympiadManager.STADIUMS[_stadiumID].getSpectators() != null)
+		{
+			for (L2PcInstance spec : OlympiadManager.STADIUMS[_stadiumID].getSpectators())
+			{
+				try
+				{
+					spec.sendPacket(sm);
+				}
+				catch (NullPointerException e)
+				{
+				}
+			}
+		}
+	}
+	
+	protected void announceGame() 
+ 	{
+		for (L2Spawn manager : SpawnTable.getInstance().getSpawnTable().values())
+		{
+			if (manager != null && manager.getNpcid() == OLY_MANAGER)
+			{
+				int objId = manager.getLastSpawn().getObjectId();
+				String npcName = manager.getLastSpawn().getName();
+				manager.getLastSpawn().broadcastPacket(new CreatureSay(objId, 1, npcName, "Olympiad is going to begin in Arena " + (_stadiumID + 1) + " in a moment."));
+			}
+		}
+	}
+}
+
+/**
+ * 
+ * @author ascharot
+ * 
+ */
+class OlympiadGameTask implements Runnable
+{
+	protected static final Logger _log = Logger.getLogger(OlympiadGameTask.class.getName());
+	public OlympiadGame _game = null;
+	protected static final long BATTLE_PERIOD = Config.ALT_OLY_BATTLE; // 6 mins
+	
+	private boolean _terminated = false;
+	private boolean _started = false;
+	
+	public boolean isTerminated()
+	{
+		return _terminated || _game._aborted;
+	}
+	
+	public boolean isStarted()
+	{
+		return _started;
+	}
+	
+	public OlympiadGameTask(OlympiadGame game)
+	{
+		_game = game;
+	}
+	
+	protected boolean checkBattleStatus()
+	{
+		boolean _pOneCrash = (_game._playerOne == null || _game._playerOneDisconnected);
+		boolean _pTwoCrash = (_game._playerTwo == null || _game._playerTwoDisconnected);
+		if (_pOneCrash || _pTwoCrash || _game._aborted)
+		{
+			return false;
+		}
+		
+		return true;
+	}
+	
+	protected boolean checkDefaulted()
+	{
+		_game._playerOne = L2World.getInstance().getPlayer(_game._playerOneName);
+		_game._players.set(0, _game._playerOne);
+		_game._playerTwo = L2World.getInstance().getPlayer(_game._playerTwoName);
+		_game._players.set(1, _game._playerTwo);
+		
+		for (int i = 0; i < 2; i++)
+		{
+			boolean defaulted = false;
+			L2PcInstance player = _game._players.get(i);
+			if (player != null)
+				player.setOlympiadGameId(_game._stadiumID);
+			L2PcInstance otherPlayer = _game._players.get(i^1);
+			SystemMessage sm = null;
+			
+			if (player == null)
+			{
+				defaulted = true;
+			}
+			else if (player.isDead())
+			{
+				sm = new SystemMessage(SystemMessageId.C1_CANNOT_PARTICIPATE_OLYMPIAD_WHILE_DEAD);
+				sm.addPcName(player);
+				defaulted = true;
+			}
+			else if (player.isSubClassActive())
+			{
+				sm = new SystemMessage(SystemMessageId.C1_CANNOT_PARTICIPATE_IN_OLYMPIAD_WHILE_CHANGED_TO_SUB_CLASS);
+				sm.addPcName(player);
+				defaulted = true;
+			}
+			else if (player.isCursedWeaponEquipped())
+			{
+				sm = new SystemMessage(SystemMessageId.CANNOT_JOIN_OLYMPIAD_POSSESSING_S1);
+				sm.addItemName(player.getCursedWeaponEquippedId());
+				defaulted = true;
+			}
+			else if (player.getInventoryLimit()*0.8 <= player.getInventory().getSize())
+			{
+				sm = new SystemMessage(SystemMessageId.C1_CANNOT_PARTICIPATE_IN_OLYMPIAD_INVENTORY_SLOT_EXCEEDS_80_PERCENT);
+				sm.addPcName(player);
+				defaulted = true;
+			}
+			
+			if (defaulted)
+			{
+				if (player != null)
+					player.sendPacket(sm);
+				if (otherPlayer != null)
+					otherPlayer.sendPacket(new SystemMessage(SystemMessageId.THE_GAME_HAS_BEEN_CANCELLED_BECAUSE_THE_OTHER_PARTY_DOES_NOT_MEET_THE_REQUIREMENTS_FOR_JOINING_THE_GAME));
+				if (i == 0)
+					_game._playerOneDefaulted = true;
+				else
+					_game._playerTwoDefaulted = true;
+			}
+		}
+		return _game._playerOneDefaulted || _game._playerTwoDefaulted;
+	}
+	
+	public void run()
+	{
+		_started = true;
+		if (_game != null)
+		{
+			if (_game._playerOne == null || _game._playerTwo == null)
+			{
+				return;
+			}
+			
+			if (teleportCountdown())
+				runGame();
+			
+			_terminated = true;
+			_game.validateWinner();
+			_game.PlayersStatusBack();
+			
+			if (_game._gamestarted)
+			{
+				_game._gamestarted = false;
+				OlympiadManager.STADIUMS[_game._stadiumID].closeDoors();
+				try
+				{
+					_game.portPlayersBack();
+				}
+				catch (Exception e)
+				{
+					e.printStackTrace();
+				}
+			}
+
+			if (OlympiadManager.STADIUMS[_game._stadiumID].getSpectators() != null)
+			{
+				for (L2PcInstance spec : OlympiadManager.STADIUMS[_game._stadiumID].getSpectators())
+				{
+					spec.sendPacket(new ExOlympiadMatchEnd());
+				}
+			}
+			
+			if (_game._spawnOne != null)
+			{
+				_game._spawnOne.getLastSpawn().deleteMe();
+				_game._spawnOne = null;
+			}
+			if (_game._spawnTwo != null)
+			{
+				_game._spawnTwo.getLastSpawn().deleteMe();
+				_game._spawnTwo = null;
+			}
+			
+			_game.clearPlayers();
+			OlympiadManager.getInstance().removeGame(_game);
+			_game = null;
+		}
+	}
+	
+	private boolean runGame()
+	{
+		// Checking for opponents and teleporting to arena
+		if (checkDefaulted())
+		{
+			return false;
+		}
+		OlympiadManager.STADIUMS[_game._stadiumID].closeDoors();
+		_game.removals();
+		_game.portPlayersToArena();
+		if (Config.ALT_OLY_ANNOUNCE_GAMES)
+			_game.announceGame();
+		try
+		{
+			Thread.sleep(5000);
+		}
+		catch (InterruptedException e)
+		{
+		}
+		
+		synchronized (this)
+		{
+			if (!OlympiadGame._battleStarted)
+				OlympiadGame._battleStarted = true;
+		}
+		
+		for (int i = 60; i > 10; i -= 10)
+		{
+			_game.sendMessageToPlayers(true, i);
+			try
+			{
+				Thread.sleep(10000);
+			}
+			catch (InterruptedException e)
+			{
+			}
+			if (i == 20)
+			{
+				_game._damageP1 = 0;
+				_game._damageP2 = 0;
+				OlympiadManager.STADIUMS[_game._stadiumID].openDoors();
+				_game.sendMessageToPlayers(true, 10);
+				try
+				{
+					Thread.sleep(5000);
+				}
+				catch (InterruptedException e)
+				{
+				}
+			}
+		}
+		for (int i = 5; i > 0; i--)
+		{
+			_game.sendMessageToPlayers(true, i);
+			try
+			{
+				Thread.sleep(1000);
+			}
+			catch (InterruptedException e)
+			{
+			}
+		}
+		
+		if (!checkBattleStatus())
+		{
+			return false;
+		}
+		_game._playerOne.sendPacket(new ExOlympiadUserInfo(_game._playerTwo, 1));
+		_game._playerTwo.sendPacket(new ExOlympiadUserInfo(_game._playerOne, 1));
+		if (OlympiadManager.STADIUMS[_game._stadiumID].getSpectators() != null)
+		{
+			for (L2PcInstance spec : OlympiadManager.STADIUMS[_game._stadiumID].getSpectators())
+			{
+				spec.sendPacket(new ExOlympiadUserInfo(_game._playerOne, 1));
+				spec.sendPacket(new ExOlympiadUserInfo(_game._playerTwo, 2));
+				spec.sendPacket(new ExOlympiadSpelledInfo(_game._playerOne));
+				spec.sendPacket(new ExOlympiadSpelledInfo(_game._playerTwo));
+			}
+		}
+
+		_game._spawnOne.getLastSpawn().deleteMe();
+		_game._spawnTwo.getLastSpawn().deleteMe();
+		_game._spawnOne = null;
+		_game._spawnTwo = null;
+		
+		if (!_game.makeCompetitionStart())
+		{
+			return false;
+		}
+		
+		// Wait 3 mins (Battle)
+		for (int i = 0; i < BATTLE_PERIOD; i += 10000)
+		{
+			try
+			{
+				Thread.sleep(10000);
+				// If game haveWinner then stop waiting battle_period
+				// and validate winner
+				if (_game.haveWinner())
+					break;
+			}
+			catch (InterruptedException e)
+			{
+			}
+		}
+		
+		return checkBattleStatus();
+	}
+	
+	private boolean teleportCountdown()
+	{
+		// Waiting for teleport to arena
+		for (int i = 120; i > 10; i -= 5)
+		{
+			switch (i)
+			{
+				case 120:
+				case 60:
+				case 30:
+				case 15:
+					_game.sendMessageToPlayers(false, i);
+					break;
+			}
+			try
+			{
+				Thread.sleep(5000);
+			}
+			catch (InterruptedException e)
+			{
+				return false;
+			}
+		}
+		for (int i = 5; i > 0; i--)
+		{
+			_game.sendMessageToPlayers(false, i);
+			try
+			{
+				Thread.sleep(1000);
+			}
+			catch (InterruptedException e)
+			{
+				return false;
+			}
+		}
+		return true;
+	}
+}

+ 440 - 0
L2_GameServer/java/net/sf/l2j/gameserver/model/olympiad/OlympiadManager.java

@@ -0,0 +1,440 @@
+/*
+ * 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 net.sf.l2j.gameserver.model.olympiad;
+
+import java.util.Map;
+import java.util.logging.Logger;
+
+import javolution.util.FastMap;
+import net.sf.l2j.gameserver.model.actor.instance.L2PcInstance;
+import net.sf.l2j.gameserver.model.olympiad.Olympiad.COMP_TYPE;
+import net.sf.l2j.gameserver.model.olympiad.OlympiadGame;
+import net.sf.l2j.gameserver.model.olympiad.OlympiadGameTask;
+import net.sf.l2j.util.L2FastList;
+import net.sf.l2j.util.Rnd;
+
+/**
+ * 
+ * @author GodKratos
+ */
+class OlympiadManager implements Runnable
+{
+	protected static final Logger _log = Logger.getLogger(OlympiadManager.class.getName());
+	private Map<Integer, OlympiadGame> _olympiadInstances;
+	protected static OlympiadManager _instance;
+	
+	protected static final OlympiadStadium[] STADIUMS = {
+	    new OlympiadStadium(-88000, -252637, -3331, 17100001, 17100002),
+	    new OlympiadStadium(-83760, -252637, -3331, 17100003, 17100004),
+	    new OlympiadStadium(-79600, -252637, -3331, 17100005, 17100006),
+	    new OlympiadStadium(-75648, -252637, -3331, 17100007, 17100008),
+	    new OlympiadStadium(-88000, -249762, -3331, 17100009, 17100010),
+	    new OlympiadStadium(-83760, -249762, -3331, 17100011, 17100012),
+	    new OlympiadStadium(-79600, -249762, -3331, 17100013, 17100014),
+	    new OlympiadStadium(-75648, -249762, -3331, 17100015, 17100016),
+	    new OlympiadStadium(-88000, -246951, -3331, 17100017, 17100018),
+	    new OlympiadStadium(-83760, -246951, -3331, 17100019, 17100020),
+	    new OlympiadStadium(-79600, -246951, -3331, 17100021, 17100022),
+	    new OlympiadStadium(-75648, -246951, -3331, 17100023, 17100024),
+	    new OlympiadStadium(-88000, -244290, -3331, 17100025, 17100026),
+	    new OlympiadStadium(-83760, -244290, -3331, 17100027, 17100028),
+	    new OlympiadStadium(-79600, -244290, -3331, 17100029, 17100030),
+	    new OlympiadStadium(-75648, -244290, -3331, 17100031, 17100032),
+	    new OlympiadStadium(-88000, -241490, -3331, 17100033, 17100034),
+	    new OlympiadStadium(-83760, -241490, -3331, 17100035, 17100036),
+	    new OlympiadStadium(-79600, -241490, -3331, 17100037, 17100038),
+	    new OlympiadStadium(-75648, -241490, -3331, 17100039, 17100040),
+	    new OlympiadStadium(-88000, -238825, -3331, 17100041, 17100042),
+	    new OlympiadStadium(-83760, -238825, -3331, 17100043, 17100044) };
+		
+	public OlympiadManager()
+	{
+		_olympiadInstances = new FastMap<Integer, OlympiadGame>();
+		_instance = this;
+	}
+	
+	public static OlympiadManager getInstance()
+	{
+		if (_instance == null)
+		{
+			_instance = new OlympiadManager();
+		}
+		return _instance;
+	}
+	
+	public synchronized void run()
+	{
+		if (Olympiad.getInstance().isOlympiadEnd())
+			return;
+
+		Map<Integer, OlympiadGameTask> _gamesQueue = new FastMap<Integer, OlympiadGameTask>();
+		while (Olympiad.getInstance().inCompPeriod())
+		{
+			if (Olympiad.getNobleCount() == 0)
+			{
+				try
+				{
+					wait(60000);
+				}
+				catch (InterruptedException ex)
+				{
+				}
+				continue;
+			}
+			
+			int _gamesQueueSize = 0;
+			
+			// _compStarted = true;
+			L2FastList<Integer> readyClasses = Olympiad.hasEnoughRegisteredClassed();
+			boolean readyNonClassed = Olympiad.hasEnoughRegisteredNonClassed();
+			if (readyClasses != null || readyNonClassed)
+			{
+				// first cycle do nothing
+				_gamesQueueSize = _gamesQueue.size();
+				for (int i = 0; i < _gamesQueueSize; i++)
+				{
+					if (_gamesQueue.get(i) == null
+					        || _gamesQueue.get(i).isTerminated()
+					        || _gamesQueue.get(i)._game == null)
+					{
+						if (_gamesQueue.containsKey(i))
+						{
+							// removes terminated games from the queue
+							try
+							{
+								_olympiadInstances.remove(i);
+								_gamesQueue.remove(i);
+								STADIUMS[i].setStadiaFree();
+							}
+							catch (Exception e)
+							{
+								e.printStackTrace();
+							}
+						}
+						else
+						{
+							_gamesQueueSize = _gamesQueueSize + 1;
+						}
+					}
+				}
+				// set up the games queue
+				for (int i = 0; i < STADIUMS.length; i++)
+				{
+					if (!existNextOpponents(Olympiad.getRegisteredNonClassBased())
+					        && !existNextOpponents(getRandomClassList(Olympiad.getRegisteredClassBased(), readyClasses)))
+					{
+						break;
+					}
+					if (STADIUMS[i].isFreeToUse())
+					{
+						if (i < STADIUMS.length / 2)
+						{
+							if (readyNonClassed && existNextOpponents(Olympiad.getRegisteredNonClassBased()))
+							{
+								try
+								{
+									_olympiadInstances.put(i, new OlympiadGame(i, COMP_TYPE.NON_CLASSED, nextOpponents(Olympiad.getRegisteredNonClassBased())));
+									_gamesQueue.put(i, new OlympiadGameTask(_olympiadInstances.get(i)));
+									STADIUMS[i].setStadiaBusy();
+								}
+								catch (Exception ex)
+								{
+									if (_olympiadInstances.get(i) != null)
+									{
+										for (L2PcInstance player : _olympiadInstances.get(i).getPlayers())
+										{
+											player.sendMessage("Your olympiad registration was canceled due to an error");
+											player.setIsInOlympiadMode(false);
+											player.setIsOlympiadStart(false);
+											player.setOlympiadSide(-1);
+											player.setOlympiadGameId(-1);
+										}
+										_olympiadInstances.remove(i);
+									}
+									if (_gamesQueue.get(i) != null)
+										_gamesQueue.remove(i);
+									STADIUMS[i].setStadiaFree();
+									
+									// try to reuse this stadia next time
+									i--;
+								}
+							}
+							
+							else if (readyClasses != null && existNextOpponents(getRandomClassList(Olympiad.getRegisteredClassBased(), readyClasses)))
+							{
+								try
+								{
+									_olympiadInstances.put(i, new OlympiadGame(i, COMP_TYPE.CLASSED, nextOpponents(getRandomClassList(Olympiad.getRegisteredClassBased(), readyClasses))));
+									_gamesQueue.put(i, new OlympiadGameTask(_olympiadInstances.get(i)));
+									STADIUMS[i].setStadiaBusy();
+								}
+								catch (Exception ex)
+								{
+									if (_olympiadInstances.get(i) != null)
+									{
+										for (L2PcInstance player : _olympiadInstances.get(i).getPlayers())
+										{
+											player.sendMessage("Your olympiad registration was canceled due to an error");
+											player.setIsInOlympiadMode(false);
+											player.setIsOlympiadStart(false);
+											player.setOlympiadSide(-1);
+											player.setOlympiadGameId(-1);
+										}
+										_olympiadInstances.remove(i);
+									}
+									if (_gamesQueue.get(i) != null)
+										_gamesQueue.remove(i);
+									STADIUMS[i].setStadiaFree();
+									
+									// try to reuse this stadia next time
+									i--;
+								}
+							}
+						}
+						else
+						{
+							if (readyClasses != null && existNextOpponents(getRandomClassList(Olympiad.getRegisteredClassBased(), readyClasses)))
+							{
+								try
+								{
+									_olympiadInstances.put(i, new OlympiadGame(i, COMP_TYPE.CLASSED, nextOpponents(getRandomClassList(Olympiad.getRegisteredClassBased(), readyClasses))));
+									_gamesQueue.put(i, new OlympiadGameTask(_olympiadInstances.get(i)));
+									STADIUMS[i].setStadiaBusy();
+								}
+								catch (Exception ex)
+								{
+									if (_olympiadInstances.get(i) != null)
+									{
+										for (L2PcInstance player : _olympiadInstances.get(i).getPlayers())
+										{
+											player.sendMessage("Your olympiad registration was canceled due to an error");
+											player.setIsInOlympiadMode(false);
+											player.setIsOlympiadStart(false);
+											player.setOlympiadSide(-1);
+											player.setOlympiadGameId(-1);
+										}
+										_olympiadInstances.remove(i);
+									}
+									if (_gamesQueue.get(i) != null)
+										_gamesQueue.remove(i);
+									STADIUMS[i].setStadiaFree();
+									
+									// try to reuse this stadia next time
+									i--;
+								}
+							}
+							else if (readyNonClassed && existNextOpponents(Olympiad.getRegisteredNonClassBased()))
+							{
+								try
+								{
+									_olympiadInstances.put(i, new OlympiadGame(i, COMP_TYPE.NON_CLASSED, nextOpponents(Olympiad.getRegisteredNonClassBased())));
+									_gamesQueue.put(i, new OlympiadGameTask(_olympiadInstances.get(i)));
+									STADIUMS[i].setStadiaBusy();
+								}
+								catch (Exception ex)
+								{
+									if (_olympiadInstances.get(i) != null)
+									{
+										for (L2PcInstance player : _olympiadInstances.get(i).getPlayers())
+										{
+											player.sendMessage("Your olympiad registration was canceled due to an error");
+											player.setIsInOlympiadMode(false);
+											player.setIsOlympiadStart(false);
+											player.setOlympiadSide(-1);
+											player.setOlympiadGameId(-1);
+										}
+										_olympiadInstances.remove(i);
+									}
+									if (_gamesQueue.get(i) != null)
+										_gamesQueue.remove(i);
+									STADIUMS[i].setStadiaFree();
+									
+									// try to reuse this stadia next time
+									i--;
+								}
+							}
+						}
+					}
+				}
+				
+				/*try
+				{
+					wait(30000);
+				}
+				catch (InterruptedException e)
+				{
+				}*/
+				
+				// Start games
+				_gamesQueueSize = _gamesQueue.size();
+				for (int i = 0; i < _gamesQueueSize; i++)
+				{
+					if (_gamesQueue.get(i) != null
+							&& !_gamesQueue.get(i).isTerminated()
+					        && !_gamesQueue.get(i).isStarted())
+					{
+						// start new games
+						Thread T = new Thread(_gamesQueue.get(i));
+						T.start();
+					}
+					
+					// Pause one second between games starting to reduce OlympiadManager shout spam.
+					try
+					{
+						wait(1000);
+					}
+					catch (InterruptedException e)
+					{
+					}
+				}
+			}
+			
+			// wait 30 sec for !stress the server
+			try
+			{
+				wait(30000);
+			}
+			catch (InterruptedException e)
+			{
+			}
+		}
+		
+		// when comp time finish wait for all games terminated before execute
+		// the cleanup code
+		boolean allGamesTerminated = false;
+		// wait for all games terminated
+		while (!allGamesTerminated)
+		{
+			try
+			{
+				wait(30000);
+			}
+			catch (InterruptedException e)
+			{
+			}
+			
+			if (_gamesQueue.size() == 0)
+			{
+				allGamesTerminated = true;
+			}
+			else
+			{
+				for (OlympiadGameTask game : _gamesQueue.values())
+				{
+					allGamesTerminated = allGamesTerminated
+					        || game.isTerminated();
+				}
+			}
+		}
+		// when all games terminated clear all
+		_gamesQueue.clear();
+		_olympiadInstances.clear();
+		Olympiad.clearRegistered();
+		
+		OlympiadGame._battleStarted = false;
+	}
+	
+	protected OlympiadGame getOlympiadGame(int index)
+	{
+		if (_olympiadInstances != null && _olympiadInstances.size() > 0)
+		{
+			return _olympiadInstances.get(index);
+		}
+		return null;
+	}
+	
+	protected void removeGame(OlympiadGame game)
+	{
+		if (_olympiadInstances != null && _olympiadInstances.size() > 0)
+		{
+			for (int i = 0; i < _olympiadInstances.size(); i++)
+			{
+				if (_olympiadInstances.get(i) == game)
+				{
+					_olympiadInstances.remove(i);
+				}
+			}
+		}
+	}
+	
+	protected Map<Integer, OlympiadGame> getOlympiadGames()
+	{
+		return (_olympiadInstances == null) ? null : _olympiadInstances;
+	}
+	
+	protected L2FastList<L2PcInstance> getRandomClassList(Map<Integer, L2FastList<L2PcInstance>> list, L2FastList<Integer> classList)
+	{
+		if (list == null || classList == null || list.size() == 0 || classList.size() == 0)
+			return null;
+
+		return list.get(classList.get(Rnd.nextInt(classList.size())));
+	}
+	
+	protected L2FastList<L2PcInstance> nextOpponents(
+	        L2FastList<L2PcInstance> list)
+	{
+		L2FastList<L2PcInstance> opponents = new L2FastList<L2PcInstance>();
+		if (list.size() == 0)
+			return opponents;
+		int loopCount = (list.size() / 2);
+		
+		int first;
+		int second;
+		
+		if (loopCount < 1)
+			return opponents;
+		
+		first = Rnd.nextInt(list.size());
+		opponents.add(list.get(first));
+		list.remove(first);
+		
+		second = Rnd.nextInt(list.size());
+		opponents.add(list.get(second));
+		list.remove(second);
+		
+		return opponents;
+		
+	}
+	
+	protected boolean existNextOpponents(L2FastList<L2PcInstance> list)
+	{
+		if (list == null)
+			return false;
+		if (list.size() == 0)
+			return false;
+		int loopCount = list.size() >> 1;
+		
+		if (loopCount < 1)
+			return false;
+		else
+			return true;
+		
+	}
+	
+	protected FastMap<Integer, String> getAllTitles()
+	{
+		FastMap<Integer, String> titles = new FastMap<Integer, String>();
+		
+		for (OlympiadGame instance : _olympiadInstances.values())
+		{
+			if (instance._gamestarted != true)
+				continue;
+
+			titles.put(instance._stadiumID, instance.getTitle());
+		}
+		
+		return titles;
+	}
+}

+ 110 - 0
L2_GameServer/java/net/sf/l2j/gameserver/model/olympiad/OlympiadStadium.java

@@ -0,0 +1,110 @@
+/*
+ * 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 net.sf.l2j.gameserver.model.olympiad;
+
+import net.sf.l2j.gameserver.datatables.DoorTable;
+import net.sf.l2j.gameserver.model.actor.instance.L2PcInstance;
+import net.sf.l2j.util.L2FastList;
+
+/**
+ * @author GodKratos
+ */
+
+class OlympiadStadium
+{
+	private boolean _freeToUse = true;
+	private static DoorTable _doorTable;
+	private int[] _coords = new int[3];
+	private int[] _doors = new int[2];
+	private L2FastList<L2PcInstance> _spectators;
+	
+	public boolean isFreeToUse()
+	{
+		return _freeToUse;
+	}
+	
+	public void setStadiaBusy()
+	{
+		_freeToUse = false;
+	}
+	
+	public void setStadiaFree()
+	{
+		_freeToUse = true;
+	}
+	
+	public int[] getCoordinates()
+	{
+		return _coords;
+	}
+	
+	public int[] getDoorID()
+	{
+		return _doors;
+	}
+	
+	public OlympiadStadium(int x, int y, int z, int d1, int d2)
+	{
+		_coords[0] = x;
+		_coords[1] = y;
+		_coords[2] = z;
+		_doors[0] = d1;
+		_doors[1] = d2;
+		_spectators = new L2FastList<L2PcInstance>();
+	}
+	
+	public void openDoors()
+	{
+		_doorTable = DoorTable.getInstance();
+		try
+		{
+			_doorTable.getDoor(getDoorID()[0]).openMe();
+			_doorTable.getDoor(getDoorID()[1]).openMe();
+		}
+		catch (Exception e)
+		{
+		}
+	}
+	
+	public void closeDoors()
+	{
+		_doorTable = DoorTable.getInstance();
+		try
+		{
+			_doorTable.getDoor(getDoorID()[0]).closeMe();
+			_doorTable.getDoor(getDoorID()[1]).closeMe();
+		}
+		catch (Exception e)
+		{
+		}
+	}
+
+	protected void addSpectator(int id, L2PcInstance spec, boolean storeCoords)
+	{
+		spec.enterOlympiadObserverMode(getCoordinates()[0] + 1200, getCoordinates()[1], getCoordinates()[2], id, storeCoords);
+		_spectators.add(spec);
+	}
+
+	protected L2FastList<L2PcInstance> getSpectators()
+	{
+		return _spectators;
+	}
+	
+	protected void removeSpectator(L2PcInstance spec)
+	{
+		if (_spectators != null && _spectators.contains(spec))
+			_spectators.remove(spec);
+	}
+}

+ 22 - 20
L2_GameServer/java/net/sf/l2j/gameserver/network/SystemMessageId.java

@@ -8963,21 +8963,23 @@ public enum SystemMessageId
 
 	/**
 	* ID: 1500<br>
-	* Message: You cannot participate in the Grand Olympiad Games with a character in their subclass.
+	* Message: $c1% does not meet the participation requirements.
+	* A sub-class character cannot participate in the Olympiad.
 	*/
-	YOU_CANT_JOIN_THE_OLYMPIAD_WITH_A_SUB_JOB_CHARACTER(1500),
+	C1_CANT_JOIN_THE_OLYMPIAD_WITH_A_SUB_CLASS_CHARACTER(1500),
 
 	/**
 	* ID: 1501<br>
-	* Message: Only Noblesse can participate in the Olympiad.
+	* Message: $c1% does not meet the participation requirements.
+	* Only Noblesse can participate in the Olympiad.
 	*/
-	ONLY_NOBLESS_CAN_PARTICIPATE_IN_THE_OLYMPIAD(1501),
+	C1_DOES_NOT_MEET_REQUIREMENTS_ONLY_NOBLESS_CAN_PARTICIPATE_IN_THE_OLYMPIAD(1501),
 
 	/**
 	* ID: 1502<br>
-	* Message: You have already been registered in a waiting list of an event.
+	* Message: $c1 is already registered on the match waiting list.
 	*/
-	YOU_HAVE_ALREADY_BEEN_REGISTERED_IN_A_WAITING_LIST_OF_AN_EVENT(1502),
+	C1_IS_ALREADY_REGISTERED_ON_THE_MATCH_WAITING_LIST(1502),
 
 	/**
 	* ID: 1503<br>
@@ -9987,9 +9989,9 @@ public enum SystemMessageId
 
 	/**
 	* ID: 1673<br>
-	* Message: Your current record for this Grand Olympiad is $s1 match(es), $s2 win(s) and $s3 defeat(s). You heave earned $s4 Olympiad Point(s).
+	* Message: Your current record for this Grand Olympiad is $s1 match(es), $s2 win(s) and $s3 defeat(s). You have earned $s4 Olympiad Point(s).
 	*/
-	THE_PRESENT_RECORD_DURING_THE_CURRENT_OLYMPIAD_SESSION_IS_S1_WINS_S2_DEFEATS_YOU_HAVE_EARNED_S3_OLYMPIAD_POINTS(1673),
+	THE_CURRENT_RECORD_FOR_THIS_OLYMPIAD_SESSION_IS_S1_MATCHES_S2_WINS_S3_DEFEATS_YOU_HAVE_EARNED_S4_OLYMPIAD_POINTS(1673),
 
 	/**
 	* ID: 1674<br>
@@ -10083,29 +10085,29 @@ public enum SystemMessageId
 
 	/**
 	* ID: 1689<br>
-	* Message: You have already joined the waiting list for a class specific match.
+	* Message: $c1 is already registered on the class match waiting list.
 	*/
-	YOU_ARE_ALREADY_ON_THE_WAITING_LIST_TO_PARTICIPATE_IN_THE_GAME_FOR_YOUR_CLASS(1689),
+	C1_IS_ALREADY_REGISTERED_ON_THE_CLASS_MATCH_WAITING_LIST(1689),
 
 	/**
 	* ID: 1690<br>
-	* Message: You have already joined the waiting list for a non-class specific match.
+	* Message: $c1 is already registered on the waiting list for the non-class-limited individual match event.
 	*/
-	YOU_ARE_ALREADY_ON_THE_WAITING_LIST_FOR_ALL_CLASSES_WAITING_TO_PARTICIPATE_IN_THE_GAME(1690),
+	C1_IS_ALREADY_REGISTERED_ON_THE_NON_CLASS_LIMITED_MATCH_WAITING_LIST(1690),
 
 	/**
 	* ID: 1691<br>
-	* Message: You can't join a Grand Olympiad Game match with that much stuff on you! 
-	* Reduce your weight to below 80 percent full and request to join again!
+	* Message: $c1% does not meet the participation requirements.
+	* You cannot participate in the Olympiad because your inventory slot exceeds 80%.
 	*/
-	SINCE_80_PERCENT_OR_MORE_OF_YOUR_INVENTORY_SLOTS_ARE_FULL_YOU_CANNOT_PARTICIPATE_IN_THE_OLYMPIAD(1691),
+	C1_CANNOT_PARTICIPATE_IN_OLYMPIAD_INVENTORY_SLOT_EXCEEDS_80_PERCENT(1691),
 
 	/**
 	* ID: 1692<br>
-	* Message: You have changed from your main class to a subclass 
-	* and therefore are removed from the Grand Olympiad Games waiting list.
+	* Message: $c1% does not meet the participation requirements.
+	* You cannot participate in the Olympiad because you have changed to your sub-class.
 	*/
-	SINCE_YOU_HAVE_CHANGED_YOUR_CLASS_INTO_A_SUB_JOB_YOU_CANNOT_PARTICIPATE_IN_THE_OLYMPIAD(1692),
+	C1_CANNOT_PARTICIPATE_IN_OLYMPIAD_WHILE_CHANGED_TO_SUB_CLASS(1692),
 
 	/**
 	* ID: 1693<br>
@@ -11120,9 +11122,9 @@ public enum SystemMessageId
 
 	/**
 	 * ID: 1858<br>
-	 * Message: You cannot participate in the Olympiad while dead.
+	 * Message: $c1 is currently dead and cannot participate in the Olympiad.
 	 */
-	CANNOT_PARTICIPATE_OLYMPIAD_WHILE_DEAD(1858),
+	C1_CANNOT_PARTICIPATE_OLYMPIAD_WHILE_DEAD(1858),
 
 	/**
 	 * ID: 1859<br>

+ 10 - 0
L2_GameServer/java/net/sf/l2j/gameserver/network/clientpackets/Action.java

@@ -21,7 +21,9 @@ import net.sf.l2j.gameserver.model.L2Character;
 import net.sf.l2j.gameserver.model.L2Object;
 import net.sf.l2j.gameserver.model.L2World;
 import net.sf.l2j.gameserver.model.actor.instance.L2PcInstance;
+import net.sf.l2j.gameserver.network.SystemMessageId;
 import net.sf.l2j.gameserver.network.serverpackets.ActionFailed;
+import net.sf.l2j.gameserver.network.serverpackets.SystemMessage;
 
 /**
  * This class ...
@@ -67,6 +69,14 @@ public final class Action extends L2GameClientPacket
 		if (activeChar == null)
 			return;
 		
+		if (activeChar.inObserverMode())
+		{
+			SystemMessage sm = new SystemMessage(SystemMessageId.OBSERVERS_CANNOT_PARTICIPATE);
+			getClient().sendPacket(sm);
+			getClient().sendPacket(ActionFailed.STATIC_PACKET);
+			return;
+		}
+		
 		L2Object obj;
 		
 		if (activeChar.getTargetId() == _objectId)

+ 3 - 2
L2_GameServer/java/net/sf/l2j/gameserver/network/clientpackets/EnterWorld.java

@@ -25,7 +25,6 @@ import net.sf.l2j.Config;
 import net.sf.l2j.L2DatabaseFactory;
 import net.sf.l2j.gameserver.Announcements;
 import net.sf.l2j.gameserver.GmListTable;
-import net.sf.l2j.gameserver.Olympiad;
 import net.sf.l2j.gameserver.SevenSigns;
 import net.sf.l2j.gameserver.TaskPriority;
 import net.sf.l2j.gameserver.cache.HtmCache;
@@ -56,6 +55,7 @@ import net.sf.l2j.gameserver.model.entity.Hero;
 import net.sf.l2j.gameserver.model.entity.L2Event;
 import net.sf.l2j.gameserver.model.entity.Siege;
 import net.sf.l2j.gameserver.model.entity.TvTEvent;
+import net.sf.l2j.gameserver.model.olympiad.Olympiad;
 import net.sf.l2j.gameserver.model.quest.Quest;
 import net.sf.l2j.gameserver.model.quest.QuestState;
 import net.sf.l2j.gameserver.network.SystemMessageId;
@@ -343,7 +343,8 @@ public class EnterWorld extends L2GameClientPacket
 
         if (Olympiad.getInstance().playerInStadia(activeChar))
         {
-            activeChar.teleToLocation(MapRegionTable.TeleportWhereType.Town);
+        	activeChar.doRevive();
+        	activeChar.teleToLocation(MapRegionTable.TeleportWhereType.Town);
             activeChar.sendMessage("You have been teleported to the nearest town due to you being in an Olympiad Stadium");
         }
 

+ 1 - 1
L2_GameServer/java/net/sf/l2j/gameserver/network/clientpackets/Logout.java

@@ -20,7 +20,6 @@ import java.util.logging.Logger;
 
 import net.sf.l2j.Config;
 import net.sf.l2j.L2DatabaseFactory;
-import net.sf.l2j.gameserver.Olympiad;
 import net.sf.l2j.gameserver.SevenSignsFestival;
 import net.sf.l2j.gameserver.communitybbs.Manager.RegionBBSManager;
 import net.sf.l2j.gameserver.datatables.SkillTable;
@@ -28,6 +27,7 @@ import net.sf.l2j.gameserver.model.L2Party;
 import net.sf.l2j.gameserver.model.L2World;
 import net.sf.l2j.gameserver.model.actor.instance.L2PcInstance;
 import net.sf.l2j.gameserver.model.entity.TvTEvent;
+import net.sf.l2j.gameserver.model.olympiad.Olympiad;
 import net.sf.l2j.gameserver.network.SystemMessageId;
 import net.sf.l2j.gameserver.network.serverpackets.ActionFailed;
 import net.sf.l2j.gameserver.network.serverpackets.FriendList;

+ 5 - 0
L2_GameServer/java/net/sf/l2j/gameserver/network/clientpackets/RequestBypassToServer.java

@@ -30,6 +30,7 @@ import net.sf.l2j.gameserver.model.L2World;
 import net.sf.l2j.gameserver.model.actor.instance.L2NpcInstance;
 import net.sf.l2j.gameserver.model.actor.instance.L2PcInstance;
 import net.sf.l2j.gameserver.model.entity.L2Event;
+import net.sf.l2j.gameserver.model.olympiad.Olympiad;
 import net.sf.l2j.gameserver.network.serverpackets.ActionFailed;
 import net.sf.l2j.gameserver.network.serverpackets.NpcHtmlMessage;
 import net.sf.l2j.gameserver.util.GMAudit;
@@ -172,6 +173,10 @@ public final class RequestBypassToServer extends L2GameClientPacket
 				else
 					player.processQuestEvent(p.substring(0, idx), p.substring(idx).trim());
 			}
+			else if (_command.startsWith("OlympiadArenaChange"))
+			{
+					Olympiad.bypassChangeArena(_command, activeChar);
+			}
 		}
 		catch (Exception e)
 		{

+ 7 - 2
L2_GameServer/java/net/sf/l2j/gameserver/network/clientpackets/RequestOlympiadMatchList.java

@@ -14,6 +14,9 @@
  */
 package net.sf.l2j.gameserver.network.clientpackets;
 
+import net.sf.l2j.gameserver.model.actor.instance.L2PcInstance;
+import net.sf.l2j.gameserver.model.olympiad.Olympiad;
+
 /**
  * format ch
  * c: (id) 0xD0
@@ -35,8 +38,10 @@ public final class RequestOlympiadMatchList extends L2GameClientPacket
 	@Override
 	protected void runImpl()
 	{
-		// TODO Auto-generated method stub
-
+		L2PcInstance activeChar = getClient().getActiveChar();
+		if (activeChar == null)
+			return;
+		if (activeChar.inObserverMode()) Olympiad.sendMatchList(activeChar);
 	}
 
 	/* (non-Javadoc)

+ 1 - 1
L2_GameServer/java/net/sf/l2j/gameserver/network/clientpackets/RequestRestart.java

@@ -17,13 +17,13 @@ package net.sf.l2j.gameserver.network.clientpackets;
 import java.util.logging.Logger;
 
 import net.sf.l2j.Config;
-import net.sf.l2j.gameserver.Olympiad;
 import net.sf.l2j.gameserver.SevenSignsFestival;
 import net.sf.l2j.gameserver.communitybbs.Manager.RegionBBSManager;
 import net.sf.l2j.gameserver.datatables.SkillTable;
 import net.sf.l2j.gameserver.model.L2Party;
 import net.sf.l2j.gameserver.model.actor.instance.L2PcInstance;
 import net.sf.l2j.gameserver.model.entity.TvTEvent;
+import net.sf.l2j.gameserver.model.olympiad.Olympiad;
 import net.sf.l2j.gameserver.network.L2GameClient;
 import net.sf.l2j.gameserver.network.SystemMessageId;
 import net.sf.l2j.gameserver.network.L2GameClient.GameClientState;

+ 7 - 7
L2_GameServer/java/net/sf/l2j/gameserver/network/clientpackets/UseItem.java

@@ -287,6 +287,13 @@ public final class UseItem extends L2GameClientPacket
 					return;
 				}
 
+                // Don't allow hero equipment and restricted items during Olympiad
+                if (activeChar.isInOlympiadMode() && (item.isHeroItem() || item.isOlyRestrictedItem()))
+                {
+                    activeChar.sendPacket(new SystemMessage(SystemMessageId.THIS_ITEM_CANT_BE_EQUIPPED_FOR_THE_OLYMPIAD_EVENT));
+                    return;
+                }
+                
                 switch (item.getItem().getBodyPart())
                 {
                     case L2Item.SLOT_LR_HAND:
@@ -325,13 +332,6 @@ public final class UseItem extends L2GameClientPacket
                             return;
                         }
                         
-                        // Don't allow weapon/shield hero equipment during Olympiads
-                        if (activeChar.isInOlympiadMode() && (item.isHeroItem() || item.isOlyRestrictedItem()))
-                        {
-                            activeChar.sendPacket(new SystemMessage(SystemMessageId.CANNOT_EQUIP_ITEM_DUE_TO_BAD_CONDITION));
-                            return;
-                        }
-                        
                         // Don't allow other Race to Wear Kamael exclusive Weapons.
                         if (!item.isEquipped() && item.getItem() instanceof L2Weapon && !activeChar.isGM())
                         {

+ 1 - 1
L2_GameServer/java/net/sf/l2j/gameserver/network/serverpackets/ExHeroList.java

@@ -16,8 +16,8 @@ package net.sf.l2j.gameserver.network.serverpackets;
 
 import java.util.Map;
 
-import net.sf.l2j.gameserver.Olympiad;
 import net.sf.l2j.gameserver.model.entity.Hero;
+import net.sf.l2j.gameserver.model.olympiad.Olympiad;
 import net.sf.l2j.gameserver.templates.StatsSet;
 
 /**

+ 43 - 0
L2_GameServer/java/net/sf/l2j/gameserver/network/serverpackets/ExOlympiadMatchEnd.java

@@ -0,0 +1,43 @@
+/*
+ * 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 net.sf.l2j.gameserver.network.serverpackets;
+
+/**
+ *
+ * @author  GodKratos
+ */
+public class ExOlympiadMatchEnd extends L2GameServerPacket
+{
+	public ExOlympiadMatchEnd()
+	{
+		
+	}
+	
+	@Override
+	protected final void writeImpl()
+	{
+		writeC(0xFE);
+		writeH(0x2D);
+	}
+
+	/* (non-Javadoc)
+	 * @see net.sf.l2j.gameserver.serverpackets.ServerBasePacket#getType()
+	 */
+	@Override
+	public String getType()
+	{
+		return "[S] FE:2D ExOlympiadMatchEnd";
+	}
+}

+ 6 - 6
L2_GameServer/java/net/sf/l2j/gameserver/network/serverpackets/ExOlympiadSpelledInfo.java

@@ -38,13 +38,13 @@ public class ExOlympiadSpelledInfo extends L2GameServerPacket
 	private class Effect
 	{
 		protected int _skillId;
-		protected int _dat;
+		protected int _level;
 		protected int _duration;
 
-		public Effect(int pSkillId, int pDat, int pDuration)
+		public Effect(int pSkillId, int pLevel, int pDuration)
 		{
 			_skillId = pSkillId;
-			_dat = pDat;
+			_level = pLevel;
 			_duration = pDuration;
 		}
 	}
@@ -55,9 +55,9 @@ public class ExOlympiadSpelledInfo extends L2GameServerPacket
         _player = player;
 	}
 
-	public void addEffect(int skillId, int dat, int duration)
+	public void addEffect(int skillId, int level, int duration)
 	{
-		_effects.add(new Effect(skillId, dat, duration));
+		_effects.add(new Effect(skillId, level, duration));
 	}
 
 	@Override
@@ -72,7 +72,7 @@ public class ExOlympiadSpelledInfo extends L2GameServerPacket
         for (Effect temp : _effects)
         {
         	writeD(temp._skillId);
-        	writeH(temp._dat);
+        	writeH(temp._level);
         	writeD(temp._duration/1000);
         }
 	}

+ 17 - 15
L2_GameServer/java/net/sf/l2j/gameserver/network/serverpackets/ExOlympiadUserInfo.java

@@ -27,33 +27,35 @@ import net.sf.l2j.gameserver.model.actor.instance.L2PcInstance;
 public class ExOlympiadUserInfo extends L2GameServerPacket
 {
 	// chcdSddddd
-	private static final String _S__FE_29_OLYMPIADUSERINFO = "[S] FE:7a OlympiadUserInfo";
-	@SuppressWarnings("unused")
-	private static L2PcInstance _activeChar;
+	private static final String _S__FE_29_OLYMPIADUSERINFO = "[S] FE:7A ExOlympiadUserInfo";
+	private int _side;
+	private L2PcInstance _player;
 
 
 	/**
 	 * @param _player
 	 * @param _side (1 = right, 2 = left)
 	 */
-	public ExOlympiadUserInfo(L2PcInstance player)
+	public ExOlympiadUserInfo(L2PcInstance player, int side)
 	{
-		_activeChar = player;
+		_player = player;
+		_side = side;
 	}
 
 
 	@Override
 	protected final void writeImpl()
 	{
-		/*writeC(0xfe);
-		writeH(0x2c);
-		writeD(_activeChar.getObjectId());
-		writeS(_activeChar.getName());
-		writeD(_activeChar.getClassId().getId());
-		writeD((int)_activeChar.getCurrentHp());
-		writeD(_activeChar.getMaxHp());
-		writeD((int)_activeChar.getCurrentCp());
-		writeD(_activeChar.getMaxCp());*/
+		writeC(0xfe);
+		writeH(0x7a);
+		writeC(_side);
+		writeD(_player.getObjectId());
+		writeS(_player.getName());
+		writeD(_player.getClassId().getId());
+		writeD((int)_player.getCurrentHp());
+		writeD(_player.getMaxHp());
+		writeD((int)_player.getCurrentCp());
+		writeD(_player.getMaxCp());
 	}
 
 	/* (non-Javadoc)
@@ -64,4 +66,4 @@ public class ExOlympiadUserInfo extends L2GameServerPacket
 	{
 		return _S__FE_29_OLYMPIADUSERINFO;
 	}
-}
+}

+ 0 - 69
L2_GameServer/java/net/sf/l2j/gameserver/network/serverpackets/ExOlympiadUserInfoSpectator.java

@@ -1,69 +0,0 @@
-/*
- * 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 net.sf.l2j.gameserver.network.serverpackets;
-
-import net.sf.l2j.gameserver.model.actor.instance.L2PcInstance;
-
-
-/**
- * This class ...
- *
- * @version $Revision: 1.4.2.1.2.3 $ $Date: 2005/03/27 15:29:57 $
- *
- * @author godson
- */
-public class ExOlympiadUserInfoSpectator extends L2GameServerPacket
-{
-	// chcdSddddd
-	private static final String _S__FE_29_OLYMPIADUSERINFOSPECTATOR = "[S] FE:7a OlympiadUserInfoSpectator";
-	private int _side;
-	private L2PcInstance _player;
-
-
-	/**
-	 * @param _player
-	 * @param _side (1 = right, 2 = left)
-	 */
-	public ExOlympiadUserInfoSpectator(L2PcInstance player, int side)
-	{
-		_player = player;
-		_side = side;
-	}
-
-
-	@Override
-	protected final void writeImpl()
-	{
-		writeC(0xfe);
-		writeH(0x7a);
-		writeC(_side);
-		writeD(_player.getObjectId());
-		writeS(_player.getName());
-		writeD(_player.getClassId().getId());
-		writeD((int)_player.getCurrentHp());
-		writeD(_player.getMaxHp());
-		writeD((int)_player.getCurrentCp());
-		writeD(_player.getMaxCp());
-	}
-
-	/* (non-Javadoc)
-	 * @see net.sf.l2j.gameserver.serverpackets.ServerBasePacket#getType()
-	 */
-	@Override
-	public String getType()
-	{
-		return _S__FE_29_OLYMPIADUSERINFOSPECTATOR;
-	}
-}

+ 20 - 0
L2_GameServer/java/net/sf/l2j/gameserver/skills/funcs/FuncEnchant.java

@@ -14,7 +14,9 @@
  */
 package net.sf.l2j.gameserver.skills.funcs;
 
+import net.sf.l2j.Config;
 import net.sf.l2j.gameserver.model.L2ItemInstance;
+import net.sf.l2j.gameserver.model.actor.instance.L2PcInstance;
 import net.sf.l2j.gameserver.skills.Env;
 import net.sf.l2j.gameserver.skills.Stats;
 import net.sf.l2j.gameserver.templates.item.L2Item;
@@ -48,6 +50,24 @@ public class FuncEnchant extends Func
             enchant = 3;
         }
 
+        if (env.player != null && env.player instanceof L2PcInstance)
+        {
+        	L2PcInstance player = (L2PcInstance)env.player;
+        	if (player.isInOlympiadMode() && Config.ALT_OLY_ENCHANT_LIMIT >= 0 &&
+        			(enchant + overenchant) > Config.ALT_OLY_ENCHANT_LIMIT)
+        	{
+        		if (Config.ALT_OLY_ENCHANT_LIMIT > 3)
+        		{
+        			overenchant = Config.ALT_OLY_ENCHANT_LIMIT - 3;
+        		}
+        		else
+        		{
+        			overenchant = 0;
+        			enchant = Config.ALT_OLY_ENCHANT_LIMIT;
+        		}
+        	}
+        }
+        
         if (stat == Stats.MAGIC_DEFENCE || stat == Stats.POWER_DEFENCE)
         {
             env.value += enchant + 3 * overenchant;

+ 4 - 12
L2_GameServer/java/net/sf/l2j/gameserver/taskmanager/tasks/TaskOlympiadSave.java

@@ -16,7 +16,7 @@ package net.sf.l2j.gameserver.taskmanager.tasks;
 
 import java.util.logging.Logger;
 
-import net.sf.l2j.gameserver.Olympiad;
+import net.sf.l2j.gameserver.model.olympiad.Olympiad;
 import net.sf.l2j.gameserver.taskmanager.Task;
 import net.sf.l2j.gameserver.taskmanager.TaskManager;
 import net.sf.l2j.gameserver.taskmanager.TaskTypes;
@@ -49,18 +49,10 @@ public class TaskOlympiadSave extends Task
 	@Override
 	public void onTimeElapsed(ExecutedTask task)
 	{
-		try
+		if (Olympiad.getInstance().inCompPeriod())
 		{
-			if (Olympiad.getInstance().inCompPeriod())
-			{
-				Olympiad.getInstance().save();
-				_log.info("Olympiad System: Data updated successfully.");
-			}
-		}
-		catch (Exception e)
-		{
-			_log.warning("Olympiad System: Failed to save Olympiad configuration: "
-			        + e);
+			Olympiad.getInstance().saveOlympiadStatus();
+			_log.info("Olympiad System: Data updated.");
 		}
 	}