Noticias:

No tienes permiso para ver los enlaces. Para poder verlos Registrate o Conectate.

Menú Principal

Evento Biohazard

Iniciado por Swarlog, Jun 29, 2025, 12:00 AM

Tema anterior - Siguiente tema

Swarlog

### Eclipse Workspace Patch 1.0
#P L2J_Server
Index: java/com/l2jserver/Config.java
===================================================================
--- java/com/l2jserver/Config.java	(revision 4767)
+++ java/com/l2jserver/Config.java	(working copy)
@@ -56,6 +56,7 @@
 	//--------------------------------------------------
 	// L2J Property File Definitions
 	//--------------------------------------------------
+	public static final String BIO_CONFIG_FILE = "./config/biohazard.properties";
 	public static final String CHARACTER_CONFIG_FILE = "./config/Character.properties";
 	public static final String FEATURE_CONFIG_FILE = "./config/Feature.properties";
 	public static final String FORTSIEGE_CONFIGURATION_FILE = "./config/fortsiege.properties";
@@ -86,6 +87,19 @@
 	
 	
 	//--------------------------------------------------
+	// Biohazard Config
+	//--------------------------------------------------
+	public static boolean BIOHAZARD_EVENT_ENABLED;
+	public static String[] BIOHAZARD_EVENT_INTERVAL;
+	public static boolean ALLOWPVPPKBIO;
+	public static int BIOHAZARDMINPLAYERS;
+	public static int BIOHAZARD_X;
+	public static int BIOHAZARD_Y;
+	public static int BIOHAZARD_Z;
+	public static int BIOHAZARDREWARDID;
+	public static int BIOHAZARDREWARDAMOUNT;
+	
+	//--------------------------------------------------
 	// L2J Variable Definitions
 	//--------------------------------------------------
 	public static int MASTERACCESS_LEVEL;
@@ -1110,6 +1124,29 @@
 			{
 				try
 				{
+					L2Properties BIOSettings = new L2Properties();
+					is = new FileInputStream(new File(BIO_CONFIG_FILE));
+					BIOSettings.load(is);
+					
+					BIOHAZARD_EVENT_ENABLED = Boolean.parseBoolean(BIOSettings.getProperty("BiohazardEventEnabled", "false"));
+					BIOHAZARD_EVENT_INTERVAL = BIOSettings.getProperty("BiohazardEventInterval", "20:00").split(",");
+					ALLOWPVPPKBIO =  Boolean.parseBoolean(BIOSettings.getProperty("BiohazardAllowPvPPkCount", "false"));
+					BIOHAZARDMINPLAYERS = Integer.parseInt(BIOSettings.getProperty("Biohazardminplayers", "2"));
+					BIOHAZARD_X = Integer.parseInt(BIOSettings.getProperty("setX", "-17507"));
+					BIOHAZARD_Y = Integer.parseInt(BIOSettings.getProperty("setY", "143206"));
+					BIOHAZARD_Z = Integer.parseInt(BIOSettings.getProperty("setZ", "-3911"));
+					BIOHAZARDREWARDID = Integer.parseInt(BIOSettings.getProperty("BiohazardRewardId", "57"));
+					BIOHAZARDREWARDAMOUNT = Integer.parseInt(BIOSettings.getProperty("BiohazardRewardAmount", "1000"));
+				
+				}
+				catch (Exception e)
+				{
+					e.printStackTrace();
+					throw new Error("Failed to Load "+BIO_CONFIG_FILE+" File.");
+				}
+				
+				try
+				{
 					L2Properties serverSettings = new L2Properties();
 					is = new FileInputStream(new File(CONFIGURATION_FILE));
 					serverSettings.load(is);
Index: java/config/biohazard.properties
===================================================================
--- java/config/biohazard.properties	(revision 0)
+++ java/config/biohazard.properties	(revision 0)
@@ -0,0 +1,23 @@
+# ---------------------------------------------------------------------------
+# Biohazard Event Engine
+# ---------------------------------------------------------------------------
+# Enable/Disable BiohazardEvent System
+BiohazardEventEnabled = False
+ 
+# Times Biohazard will occur (24h format).
+BiohazardEventInterval = 9:00,15:00,21:00,3:00
+
+# set True to allow PvP PK points
+BiohazardAllowPvPPkCount = False
+
+# Min amount of players allowed in the event.
+Biohazardminplayers = 2
+
+# Set Location x,y,z for this event.
+setX = -17507
+setY = 143206
+setZ = -3911
+
+# Reward for winning team.
+BiohazardRewardId = 57
+BiohazardRewardAmount = 1000
\ No newline at end of file
Index: java/com/l2jserver/gameserver/model/entity/Biohazard.java
===================================================================
--- java/com/l2jserver/gameserver/model/entity/Biohazard.java	(revision 0)
+++ java/com/l2jserver/gameserver/model/entity/Biohazard.java	(revision 0)
@@ -0,0 +1,310 @@
+/*
+ * This program is free software: you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later
+ * version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.l2jserver.gameserver.model.entity;
+ 
+ 
+import java.util.Random;
+import javolution.util.FastSet;
+ 
+import com.l2jserver.Config;
+import com.l2jserver.gameserver.Announcements;
+import com.l2jserver.gameserver.instancemanager.TransformationManager;
+import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
+import com.l2jserver.gameserver.model.olympiad.OlympiadManager;
+import com.l2jserver.util.Rnd;
+ 
+public class Biohazard
+{
+   enum EventState
+   {
+      INACTIVE,
+      INACTIVATING,
+      REGISTERING,
+      STARTED,
+      REWARDING
+   }
+ 
+    private static EventState _state = EventState.INACTIVE;
+   
+   public static FastSet<L2PcInstance> _participants = new FastSet<L2PcInstance>();
+   public static FastSet<L2PcInstance> _infected = new FastSet<L2PcInstance>();
+   public static FastSet<L2PcInstance> _notInfected = new FastSet<L2PcInstance>();
+   
+   public static boolean isStarted()
+   {
+      if (_state == EventState.STARTED)
+         return true;
+      return false;
+   }
+   
+   public static boolean isRegistering()
+   {
+      if (_state == EventState.REGISTERING)
+         return true;
+      return false;
+   }
+   
+   public static void startRegistering()
+   {
+      if (_state == EventState.REGISTERING || _state == EventState.STARTED)
+         return;
+      Announcements.getInstance().announceToAll("Biohazard: Registration is open.");
+      Announcements.getInstance().announceToAll("Biohazard: Type \".bhreg\" to register to event.");
+      Announcements.getInstance().announceToAll("Biohazard: Type \".bhunreg\" to unregister from event.");
+      _state = EventState.REGISTERING;
+      int step = 0;
+      int after = 0;
+      for (int i = 40; i > 0; i-=10)
+      {
+         switch(i)
+         {
+            case 40:
+               step = 5;
+               after = 15;
+               break;
+            case 30:
+               step = 5;
+               after = 10;
+               break;
+            case 20:
+               step = 4;
+               after = 5;
+               break;
+            case 10:
+               step = 1;
+               after = 1;
+               break;
+         }
+         if (_state == EventState.INACTIVE)
+            return;
+         Announcements.getInstance().announceToAll("Biohazard: Registration will be closed in " + after + " minute(s).");
+         try{Thread.sleep(step*60000);}catch (Exception e){}
+      }
+      //sound = "";
+      try{Thread.sleep(10000);}catch (Exception e){}
+      if (_state == EventState.INACTIVE)
+         return;
+      if (_participants.size() >= Config.BIOHAZARDMINPLAYERS)
+      {
+         Announcements.getInstance().announceToAll("Biohazard: Teleporting players in 15 seconds.");
+         try{Thread.sleep(15000);}catch (Exception e){}
+         _state = EventState.STARTED;
+         startEventAndTelePl();
+      }
+      else
+         Announcements.getInstance().announceToAll("Biohazard: Event aborted due to lack of participants.");
+   }
+   
+   public static void addParticipant(L2PcInstance player)
+   {
+      if (OlympiadManager.getInstance().isRegistered(player) || TvTEvent.isPlayerParticipant(player.getObjectId()))
+      {
+         player.sendMessage("You cannot register because of registration in another event");
+         return;
+      }
+      if (_state == EventState.REGISTERING && !_participants.contains(player))
+      {
+         _participants.add(player);
+         player.sendMessage("You have successfully registered to this event");
+      }
+      else
+         player.sendMessage("You are already registered or it's not registration time.");
+   }
+   
+   public static void removeParticipant(L2PcInstance player)
+   {
+      if (_state == EventState.REGISTERING)
+      {
+         if (_participants.contains(player))
+         {
+            _participants.remove(player);
+         	player.sendMessage("You have unregistered to this event.");
+         }
+         else
+            player.sendMessage("You aren't registered in this event.");
+         player.setIsInBiohazard(false);
+      }
+      else
+         player.sendMessage("It's not registration time.");
+   }
+   
+   public static void startEventAndTelePl()
+   {
+	   int time;
+	   Random r = new Random();
+	   time = r.nextInt(35000); // 35000 = 35 Seconds
+	   
+	   if (_state == EventState.INACTIVE)
+         return;
+      synchronized(_participants)
+      {
+         for (L2PcInstance pl : _participants)
+            if (pl.isOnline())
+            {
+               _notInfected.add(pl);
+               pl.stopAllEffects();
+               pl._oldX = pl.getX();
+               pl._oldY = pl.getY();
+               pl._oldZ = pl.getZ();
+               pl.teleToLocation(Config.BIOHAZARD_X,Config.BIOHAZARD_Y,Config.BIOHAZARD_Z);
+               pl.setTeam(0);
+               pl.setIsInBiohazard(true);
+               pl.untransform();
+            }
+      }
+   Announcements.getInstance().announceToAll("Biohazard: In some seconds a virus will take over anyone and he will become zombie!");
+   try{Thread.sleep(time);}catch (Exception e){}
+   int num = Math.round(Rnd.get(_notInfected.size()-1));
+   L2PcInstance infectFirst = getAllNotInfected()[num];
+   infectPlayer(infectFirst);
+   Announcements.getInstance().announceToAll("Biohazard: Virus took over " + infectFirst.getName() + " body and he wants to infect everybody else!");
+   }
+   
+   public static void infectPlayer(L2PcInstance zombie)
+   {
+      if (_state == EventState.INACTIVE)
+         return;
+      zombie.setIsZombie(true);
+      _notInfected.remove(zombie);
+      _infected.add(zombie);
+      TransformationManager.getInstance().transformPlayer(303, zombie);
+      	zombie.stopAllEffects();
+		zombie.setCurrentHp(zombie.getMaxHp());
+		zombie.setCurrentMp(zombie.getMaxMp());
+		zombie.setCurrentCp(zombie.getMaxCp());
+      if (_notInfected.size() == 0)
+         zombiesWin();
+   }
+   
+   public static void onLogout(L2PcInstance playerInstance)
+   {
+      if (_state == EventState.REGISTERING)
+         removeParticipant(playerInstance);
+      else if (_state == EventState.STARTED)
+      {
+         playerInstance.setXYZ(playerInstance._oldX,playerInstance._oldY,playerInstance._oldZ);
+         if (!playerInstance.isZombie())
+            _notInfected.remove(playerInstance);
+         else if (playerInstance.isZombie())
+            _infected.remove(playerInstance);
+         if (_notInfected.size() == 0)
+            zombiesWin();
+         if (_infected.size() == 0)
+            playersWin();
+      }
+   }
+   
+   public static void zombiesWin()
+   {
+      if (_state == EventState.INACTIVE)
+         return;
+      Announcements.getInstance().announceToAll("Biohazard: Zombies won.");
+      Announcements.getInstance().announceToAll("Biohazard: Rewarding and teleporting participants back to village in 20 seconds.");
+      _state = EventState.REWARDING;
+      try{Thread.sleep(15000);}catch (Exception e){}
+      synchronized(_infected)
+      {
+         for (L2PcInstance pl : _infected)
+            if (pl.isOnline())
+            	pl.addItem("Biohazard", Config.BIOHAZARDREWARDID, Config.BIOHAZARDREWARDAMOUNT, pl, true);
+         		Biohazard.teleport();
+      }
+   }
+   
+   public static void playersWin()
+   {
+      Announcements.getInstance().announceToAll("Biohazard: Players won.");
+      Announcements.getInstance().announceToAll("Biohazard: Rewarding and teleporting participants back to village in 15 seconds.");
+      _state = EventState.REWARDING;
+      try{Thread.sleep(15000);}catch (Exception e){}
+      synchronized(_notInfected)
+      {
+         for (L2PcInstance pl : _notInfected)
+            if (pl.isOnline())
+            	pl.addItem("Biohazard", Config.BIOHAZARDREWARDID, Config.BIOHAZARDREWARDAMOUNT, pl, true);
+         		Biohazard.teleport();
+      }
+   }
+   
+   public static void teleport()
+   {
+	   synchronized(_participants)
+      {
+		  synchronized(_notInfected)
+    	  {
+			  for (L2PcInstance pl : _notInfected)
+    			  if (pl.isOnline())
+    			  {
+    				  pl.stopAllEffects();
+    			  	  pl.setIsInBiohazard(false);
+//   			  if (pl.inWorld() == 1)
+//					  pl.setTeam(pl.getFactionId());
+    			  }
+    	  }
+		  synchronized(_infected)
+    	  {
+    		  for (L2PcInstance pl : _infected)
+    			  if (pl.isOnline())
+    			  {
+    				  	  pl.doRevive();
+    				  	  pl.stopAllEffects();
+    				  if (pl.isTransformed())
+    					  pl.untransform();
+    				  	  pl.setIsZombie(false);
+    				  	  pl.setIsInBiohazard(false);
+//					  if (pl.inWorld() == 1)
+//						  pl.setTeam(pl.getFactionId());
+   		  		  }
+    	  }
+		  try{Thread.sleep(4000);}catch (Exception e){}
+		  for (L2PcInstance pl : _participants)
+		  pl.teleToLocation(pl._oldX,pl._oldY,pl._oldZ);
+      }
+      _participants.clear();
+      _infected.clear();
+      _notInfected.clear();
+      _state = EventState.INACTIVE;
+   }
+   
+   public static L2PcInstance[] getAllNotInfected()
+   {
+      synchronized(_notInfected)
+      {
+         return _notInfected.toArray(new L2PcInstance[_notInfected.size()]);
+      }
+   }
+   
+   public static void abortEvent()
+   {
+      _state = EventState.INACTIVE;
+      _participants.clear();
+      _notInfected.clear();
+      _infected.clear();
+      Announcements.getInstance().announceToAll("Biohazard: Event aborted.");
+   }
+   
+   public static boolean isInactive()
+	{
+		boolean isInactive;
+		
+		synchronized (_state)
+		{
+			isInactive = _state == EventState.INACTIVE;
+		}
+		
+		return isInactive;
+	}
+   
+}
\ No newline at end of file
Index: java/com/l2jserver/gameserver/model/actor/instance/L2PcInstance.java
===================================================================
--- java/com/l2jserver/gameserver/model/actor/instance/L2PcInstance.java	(revision 4767)
+++ java/com/l2jserver/gameserver/model/actor/instance/L2PcInstance.java	(working copy)
@@ -150,6 +150,7 @@
 import com.l2jserver.gameserver.model.base.PlayerClass;
 import com.l2jserver.gameserver.model.base.Race;
 import com.l2jserver.gameserver.model.base.SubClass;
+import com.l2jserver.gameserver.model.entity.Biohazard;
 import com.l2jserver.gameserver.model.entity.Castle;
 import com.l2jserver.gameserver.model.entity.Duel;
 import com.l2jserver.gameserver.model.entity.Fort;
@@ -480,6 +481,26 @@
 		}
 	}
 	
+	/** Biohazard */
+	private static boolean _inBiohazard = false;
+	public boolean _isZombie = false;
+	public void setIsZombie(boolean a)
+	{
+		_isZombie = a;
+	}
+	public boolean isZombie()
+	{
+		return _isZombie;
+	}
+	private boolean inBiohazard() 
+	{
+		return _inBiohazard;
+	}
+	public void setIsInBiohazard(boolean b)
+	{
+		_inBiohazard = b;	
+	}
+	
 	/** Olympiad */
 	private boolean _inOlympiadMode = false;
 	private boolean _OlympiadStart = false;
@@ -4892,6 +4913,10 @@
 	@Override
 	public synchronized void untransform()
 	{
+		// Biohazard
+		if (inBiohazard() && Biohazard.isStarted() && _transformation != null && isZombie())
+			return;
+	
 		if (_transformation != null)
 		{
 			setQueuedSkill(null, false, false);
@@ -5324,6 +5349,23 @@
 		// Kill the L2PcInstance
 		if (!super.doDie(killer))
 			return false;
+			
+		// Biohazard
+		if (killer instanceof L2PcInstance)
+			{
+				L2PcInstance pl = (L2PcInstance) killer;
+				if (inBiohazard() && !isZombie() && pl.inBiohazard() && pl.isZombie() && Biohazard.isStarted())
+				{
+					pl.abortAttack();
+					pl.abortCast();
+					doRevive();
+					Biohazard.infectPlayer(this);
+					stopAllEffects();
+			     	setCurrentHp(getMaxHp());
+			     	setCurrentMp(getMaxMp());
+			     	setCurrentCp(getMaxCp());
+				}
+			}
 		
 		if (isMounted())
 			stopFeed();
@@ -5483,6 +5525,17 @@
 		{
 			reviveRequest(this, null, false);
 		}
+		// Biohazard
+		if (isZombie() && inBiohazard())
+		{
+			if(Biohazard._infected.contains(this))
+			{
+				Biohazard._infected.remove(this);
+				untransform();
+				if (Biohazard._infected.size() == 0)
+					Biohazard.playersWin();
+			}
+		}
 		return true;
 	}
 	
@@ -5677,6 +5730,13 @@
 		if (target instanceof L2PcInstance
 				&& AntiFeedManager.getInstance().check(this, target))
 		{
+			// Add by Biohazard Event
+			if(Config.ALLOWPVPPKBIO)
+			{
+				if (Biohazard.isStarted() && _inBiohazard)
+					return;
+			}
+			
 			// Add karma to attacker and increase its PK counter
 			setPvpKills(getPvpKills() + 1);
 			
@@ -5738,6 +5798,13 @@
 		if (getKarma() > (Integer.MAX_VALUE - newKarma))
 			newKarma = Integer.MAX_VALUE - getKarma();
 		
+		// Add by Biohazard Event
+		if(Config.ALLOWPVPPKBIO)
+		{
+			if (Biohazard.isStarted() && _inBiohazard)
+				return;
+		}
+					
 		// Add karma to attacker and increase its PK counter
 		setKarma(getKarma() + newKarma);
 		if (target instanceof L2PcInstance
@@ -8459,6 +8526,17 @@
 		// Check if the attacker isn't the L2PcInstance Pet
 		if (attacker == this || attacker == getPet())
 			return false;
+			
+		// Biohazard
+		L2PcInstance player = null;
+		if (attacker instanceof L2PcInstance)
+			player = (L2PcInstance) attacker;
+		if (attacker instanceof L2SummonInstance)
+			player = ((L2SummonInstance) attacker).getOwner();
+ 		
+		if (player != null)
+			if (Biohazard.isStarted() && player.inBiohazard() && inBiohazard() && player.isZombie() != isZombie())
+				return true;
 		
 		// TODO: check for friendly mobs
 		// Check if the attacker is a L2MonsterInstance
@@ -8859,6 +8937,10 @@
 			return false;
 		}
 		
+		// Biohazard
+		if (skill.getId() == 619 && inBiohazard() && isZombie())
+			return false;
+		
 		//************************************* Check Skill Type *******************************************
 		
 		// Check if this is offensive magic skill
@@ -8869,6 +8951,25 @@
 				// If L2Character or target is in a peace zone, send a system message TARGET_IN_PEACEZONE a Server->Client packet ActionFailed
 				sendPacket(SystemMessage.getSystemMessage(SystemMessageId.TARGET_IN_PEACEZONE));
 				sendPacket(ActionFailed.STATIC_PACKET);
+				
+				// Biohazard
+				boolean cond = true;
+				L2PcInstance trgtF = null;
+				if (target instanceof L2PcInstance)
+					trgtF = (L2PcInstance)target;
+				else if (target instanceof L2SummonInstance)
+					trgtF = ((L2SummonInstance)target).getOwner();
+				if (trgtF != null)
+					if (Biohazard.isStarted() && trgtF.inBiohazard() && inBiohazard())
+					{
+						if (trgtF.isZombie() != isZombie())
+							cond = true;
+						if (trgtF.isZombie() == isZombie())
+							cond = false;
+					}
+		
+				if (!cond)
+				
 				return false;
 			}
 			
@@ -9294,6 +9395,9 @@
 			SkillDat skilldatpet = getCurrentPetSkill();
 			if(skill.isPvpSkill()) // pvp skill
 			{
+				// Biohazard
+				if (Biohazard.isStarted() && inBiohazard() && ((L2PcInstance)target).inBiohazard() && isZombie() != ((L2PcInstance)target).isZombie())
+					return true;
 				if(getClan() != null && ((L2PcInstance)target).getClan() != null)
 				{
 					if(getClan().isAtWarWith(((L2PcInstance)target).getClan().getClanId()) && ((L2PcInstance)target).getClan().isAtWarWith(getClan().getClanId()))
@@ -11778,6 +11882,15 @@
 			_log.log(Level.SEVERE, "deleteMe()", e);
 		}
 		
+		try
+		{
+			Biohazard.onLogout(this);
+		}
+		catch (Exception e)
+		{
+			_log.log(Level.SEVERE, "deleteMe()", e);
+		}
+		
 		// Update database with items in its inventory and remove them from the world
 		try
 		{
@@ -12985,6 +13098,11 @@
 	private int _eventEffectId = 0;
 	private boolean _isInSiege;
 	
+	// Biohazard
+	public int _oldX;
+	public int _oldY;
+	public int _oldZ;
+	
 	public Collection<TimeStamp> getReuseTimeStamps()
 	{
 		return _reuseTimeStamps.values();
Index: java/com/l2jserver/gameserver/GameServer.java
===================================================================
--- java/com/l2jserver/gameserver/GameServer.java	(revision 4767)
+++ java/com/l2jserver/gameserver/GameServer.java	(working copy)
@@ -119,6 +119,7 @@
 import com.l2jserver.gameserver.model.L2World;
 import com.l2jserver.gameserver.model.PartyMatchRoomList;
 import com.l2jserver.gameserver.model.PartyMatchWaitingList;
+import com.l2jserver.gameserver.model.entity.BiohazardManager;
 import com.l2jserver.gameserver.model.entity.Hero;
 import com.l2jserver.gameserver.model.entity.TvTManager;
 import com.l2jserver.gameserver.model.olympiad.Olympiad;
@@ -399,6 +400,7 @@
 		
 		_log.info("IdFactory: Free ObjectID's remaining: " + IdFactory.getInstance().size());
 		
+		BiohazardManager.getInstance();
 		TvTManager.getInstance();
 		KnownListUpdateTaskManager.getInstance();
 		
Index: java/com/l2jserver/gameserver/model/entity/BiohazardManager.java
===================================================================
--- java/com/l2jserver/gameserver/model/entity/BiohazardManager.java	(revision 0)
+++ java/com/l2jserver/gameserver/model/entity/BiohazardManager.java	(revision 0)
@@ -0,0 +1,146 @@
+/*
+ * This program is free software: you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later
+ * version.
+ * 
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.l2jserver.gameserver.model.entity;
+
+import java.util.Calendar;
+import java.util.concurrent.ScheduledFuture;
+import java.util.logging.Logger;
+
+import com.l2jserver.Config;
+import com.l2jserver.gameserver.model.entity.Biohazard;
+import com.l2jserver.gameserver.ThreadPoolManager;
+
+
+public class BiohazardManager
+{
+	protected static final Logger _log = Logger.getLogger(BiohazardManager.class.getName());
+		
+	/** Task for event cycles<br> */
+	private BiohazardStartTask _task;
+	
+	/**
+	 * New instance only by getInstance()<br>
+	 */
+	 private BiohazardManager()
+	 {
+		if (Config.BIOHAZARD_EVENT_ENABLED)
+		{
+			this.scheduleEventStart();
+			_log.info("[Biohazard] EventEngine: Engine started.");
+		}
+		else
+		{
+			_log.info("[Biohazard] EventEngine: Engine is disabled.");
+		}
+	}
+
+	public static BiohazardManager getInstance()
+	{
+		return SingletonHolder._instance;
+	}
+	
+	public void scheduleEventStart()
+	{
+		try
+		{
+			final Calendar currentTime = Calendar.getInstance();
+			Calendar nextStartTime = null;
+			Calendar testStartTime = null;
+			for (String timeOfDay : Config.BIOHAZARD_EVENT_INTERVAL)
+			{
+				// Creating a Calendar object from the specified interval value
+				testStartTime = Calendar.getInstance();
+				testStartTime.setLenient(true);
+				String[] splitTimeOfDay = timeOfDay.split(":");
+				testStartTime.set(Calendar.HOUR_OF_DAY, Integer.parseInt(splitTimeOfDay[0]));
+				testStartTime.set(Calendar.MINUTE, Integer.parseInt(splitTimeOfDay[1]));
+				// If the date is in the past, make it the next day (Example: Checking for "1:00", when the time is 23:57.)
+				if (testStartTime.getTimeInMillis() < currentTime.getTimeInMillis())
+					testStartTime.add(Calendar.DAY_OF_MONTH, 1);
+
+				// Check for the test date to be the minimum (smallest in the specified list)
+				if (nextStartTime == null || testStartTime.getTimeInMillis() < nextStartTime.getTimeInMillis())
+					nextStartTime = testStartTime;
+
+			}
+			_task = new BiohazardStartTask(nextStartTime.getTimeInMillis());
+			ThreadPoolManager.getInstance().executeTask(_task);
+		}
+		catch (Exception e)
+		{
+			_log.warning("BiohazardEventEngine[BiohazardManager.scheduleEventStart()]: Error figuring out a start time. Check BiohazardEventInterval in config file.");
+		}
+	}
+
+	public void startEvent()
+	{
+		Biohazard.startRegistering();
+		this.scheduleEventStart();
+
+	}
+
+	public void skipDelay()
+	{
+		if (_task.nextRun.cancel(false))
+		{
+			_task.setStartTime(System.currentTimeMillis());
+			ThreadPoolManager.getInstance().executeTask(_task);
+		}
+	}
+	
+	class BiohazardStartTask implements Runnable
+	{
+		private long _startTime;
+		public ScheduledFuture<?> nextRun;
+		
+		public BiohazardStartTask(long startTime)
+		{
+			_startTime = startTime;
+		}
+		
+		public void setStartTime(long startTime)
+		{
+			_startTime = startTime;
+		}
+		
+		public void run()
+		{
+			final int delay = (int) Math.round((_startTime - System.currentTimeMillis()) / 1000.0);
+			
+			// start
+			if(delay <= 0)
+			{				
+				if (Biohazard.isInactive())
+					startEvent();
+				return;
+			}
+			
+			int nextMsg = 0;
+			if (delay > 0)
+			{
+				nextMsg = delay;
+			}
+
+			nextRun = ThreadPoolManager.getInstance().scheduleGeneral(this, nextMsg * 1000);
+
+		}
+	}
+
+	@SuppressWarnings("synthetic-access")
+	private static class SingletonHolder
+	{
+		protected static final BiohazardManager _instance = new BiohazardManager();
+	}
+}
\ No newline at end of file
#P L2J_DataPack
Index: data/scripts/handlers/usercommandhandlers/Escape.java
===================================================================
--- data/scripts/handlers/usercommandhandlers/Escape.java	(revision 8221)
+++ data/scripts/handlers/usercommandhandlers/Escape.java	(working copy)
@@ -57,6 +57,13 @@
 			return false;
 		}
 		
+		// Biohazard
+		if (activeChar.isinBiohazard())
+		{
+			activeChar.sendPacket(ActionFailed.STATIC_PACKET);
+			return false;
+		}
+		
 		
 		int unstuckTimer = (activeChar.getAccessLevel().isGm() ? 1000 : Config.UNSTUCK_INTERVAL * 1000);
 		
Index: data/scripts/handlers/MasterHandler.java
===================================================================
--- data/scripts/handlers/MasterHandler.java	(revision 8221)
+++ data/scripts/handlers/MasterHandler.java	(working copy)
@@ -244,6 +244,7 @@
 import handlers.usercommandhandlers.PartyInfo;
 import handlers.usercommandhandlers.Time;
 import handlers.voicedcommandhandlers.Banking;
+import handlers.voicedcommandhandlers.biohazard;
 import handlers.voicedcommandhandlers.ChatAdmin;
 import handlers.voicedcommandhandlers.Debug;
 import handlers.voicedcommandhandlers.Lang;
@@ -550,6 +551,7 @@
 	
 	private static void loadVoicedHandlers()
 	{
+		VOICE.registerVoicedCommandHandler(new biohazard());
 		VOICE.registerVoicedCommandHandler(new stats());
 		if (Config.L2JMOD_ALLOW_WEDDING)
 			VOICE.registerVoicedCommandHandler(new Wedding());
Index: data/scripts/handlers/voicedcommandhandlers/biohazard.java
===================================================================
--- data/scripts/handlers/voicedcommandhandlers/biohazard.java	(revision 0)
+++ data/scripts/handlers/voicedcommandhandlers/biohazard.java	(revision 0)
@@ -0,0 +1,38 @@
+/*
+ * 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 handlers.voicedcommandhandlers;
+
+import com.l2jserver.gameserver.handler.IVoicedCommandHandler;
+import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
+import com.l2jserver.gameserver.model.entity.Biohazard;
+
+public class biohazard implements IVoicedCommandHandler
+{
+	private static final String[] VOICED_COMMANDS = { "bhreg", "bhunreg" };
+	
+	public boolean useVoicedCommand(String command, L2PcInstance activeChar, String params)
+	{
+		if (command.equalsIgnoreCase("bhreg"))
+			Biohazard.addParticipant(activeChar);
+		else if (command.equalsIgnoreCase("bhunreg"))
+			Biohazard.removeParticipant(activeChar);
+		return true;
+	}
+	
+	public String[] getVoicedCommandList()
+	{
+		return VOICED_COMMANDS;
+	}
+}
\ No newline at end of file