Forráskód Böngészése

BETA: Some reworks and cleanup:
* DoorTable:
* Trove -> HashMap migration.
* Removing hashCode usage its wrong please quit using it!
* Cleanup.
* Instance:
* _spawnLoc int[] -> Location by [[Zoey76]]'s request.
* Using IL2Procedure for the Packet broadcast and eject by [[Zoey76]]'s request.
* _doors List<L2DoorInstance> -> Map<Integer, L2DoorInstance> for faster doorId lookup.
* Cleanup.
* AbstractPlayerGroup:
* FastList -> ArrayList migration.
* Cleanup.
* StatsSet:
* Changing constructor to provide support for any kind of map (It can be used for example with TreeMap for alphabetical key order or HashMap for fifo = first in / first out order)
* And some misc code update/cleanup.

Rumen Nikiforov 12 éve
szülő
commit
06c1ed114b

+ 57 - 42
L2J_Server_BETA/java/com/l2jserver/gameserver/datatables/DoorTable.java

@@ -14,11 +14,11 @@
  */
 package com.l2jserver.gameserver.datatables;
 
-import gnu.trove.map.hash.TIntObjectHashMap;
-
 import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
 import java.util.HashSet;
-import java.util.List;
+import java.util.Map;
 import java.util.Set;
 import java.util.logging.Logger;
 
@@ -38,9 +38,9 @@ public class DoorTable extends DocumentParser
 {
 	private static final Logger _log = Logger.getLogger(DoorTable.class.getName());
 	
-	private final TIntObjectHashMap<L2DoorInstance> _doors = new TIntObjectHashMap<>();
-	private static final TIntObjectHashMap<Set<Integer>> _groups = new TIntObjectHashMap<>();
-	private final TIntObjectHashMap<ArrayList<L2DoorInstance>> _regions = new TIntObjectHashMap<>();
+	private final Map<Integer, L2DoorInstance> _doors = new HashMap<>();
+	private static final Map<String, Set<Integer>> _groups = new HashMap<>();
+	private final Map<Integer, Collection<L2DoorInstance>> _regions = new HashMap<>();
 	
 	protected DoorTable()
 	{
@@ -77,7 +77,7 @@ public class DoorTable extends DocumentParser
 					{
 						attrs = b.getAttributes();
 						set = new StatsSet();
-						set.set("baseHpMax", 1);  // Avoid doors without HP value created dead due to default value 0 in L2CharTemplate
+						set.set("baseHpMax", 1); // Avoid doors without HP value created dead due to default value 0 in L2CharTemplate
 						for (int i = 0; i < attrs.getLength(); i++)
 						{
 							att = attrs.item(i);
@@ -89,7 +89,7 @@ public class DoorTable extends DocumentParser
 			}
 		}
 		
-		_log.info("DoorTable: Loaded " + _doors.size() + " Door Templates for " + _regions.size() + " regions."); 
+		_log.info("DoorTable: Loaded " + _doors.size() + " Door Templates for " + _regions.size() + " regions.");
 	}
 	
 	public void insertCollisionData(StatsSet set)
@@ -105,8 +105,10 @@ public class DoorTable extends DocumentParser
 		int collisionRadius; // (max) radius for movement checks
 		collisionRadius = Math.min(Math.abs(nodeX - posX), Math.abs(nodeY - posY));
 		if (collisionRadius < 20)
+		{
 			collisionRadius = 20;
-
+		}
+		
 		set.set("collision_radius", collisionRadius);
 		set.set("collision_height", height);
 	}
@@ -123,7 +125,7 @@ public class DoorTable extends DocumentParser
 		door.spawnMe(template.posX, template.posY, template.posZ);
 		putDoor(door, MapRegionManager.getInstance().getMapRegionLocId(door.getX(), door.getY()));
 	}
-
+	
 	public L2DoorTemplate getDoorTemplate(int doorId)
 	{
 		return _doors.get(doorId).getTemplate();
@@ -133,13 +135,15 @@ public class DoorTable extends DocumentParser
 	{
 		return _doors.get(doorId);
 	}
-
+	
 	public void putDoor(L2DoorInstance door, int region)
 	{
 		_doors.put(door.getDoorId(), door);
 		
-		if (_regions.contains(region))
+		if (_regions.containsKey(region))
+		{
 			_regions.get(region).add(door);
+		}
 		else
 		{
 			final ArrayList<L2DoorInstance> list = new ArrayList<>();
@@ -147,15 +151,15 @@ public class DoorTable extends DocumentParser
 			_regions.put(region, list);
 		}
 	}
-
+	
 	public static void addDoorGroup(String groupName, int doorId)
 	{
-		Set<Integer> set = _groups.get(groupName.hashCode());
+		Set<Integer> set = _groups.get(groupName);
 		if (set == null)
 		{
 			set = new HashSet<>();
 			set.add(doorId);
-			_groups.put(groupName.hashCode(), set);
+			_groups.put(groupName, set);
 		}
 		else
 		{
@@ -165,14 +169,14 @@ public class DoorTable extends DocumentParser
 	
 	public static Set<Integer> getDoorsByGroup(String groupName)
 	{
-		return _groups.get(groupName.hashCode());
+		return _groups.get(groupName);
 	}
 	
-	public L2DoorInstance[] getDoors()
+	public Collection<L2DoorInstance> getDoors()
 	{
-		return _doors.values(new L2DoorInstance[0]);
+		return _doors.values();
 	}
-
+	
 	public boolean checkIfDoorsBetween(AbstractNodeLoc start, AbstractNodeLoc end, int instanceId)
 	{
 		return checkIfDoorsBetween(start.getX(), start.getY(), start.getZ(), end.getX(), end.getY(), end.getZ(), instanceId);
@@ -182,57 +186,68 @@ public class DoorTable extends DocumentParser
 	{
 		return checkIfDoorsBetween(x, y, z, tx, ty, tz, instanceId, false);
 	}
-
+	
 	/**
-	 * @param x 
-	 * @param y 
-	 * @param z 
-	 * @param tx 
-	 * @param ty 
-	 * @param tz 
-	 * @param instanceId 
-	 * @param doubleFaceCheck 
-	 * @return
-	 *  
-	 * TODO: remove geodata checks from door table and convert door nodes to geo zones
+	 * GodKratos: TODO: remove GeoData checks from door table and convert door nodes to Geo zones
+	 * @param x
+	 * @param y
+	 * @param z
+	 * @param tx
+	 * @param ty
+	 * @param tz
+	 * @param instanceId
+	 * @param doubleFaceCheck
+	 * @return {@code boolean}
 	 */
 	public boolean checkIfDoorsBetween(int x, int y, int z, int tx, int ty, int tz, int instanceId, boolean doubleFaceCheck)
 	{
-		List<L2DoorInstance> allDoors;
-		if (instanceId > 0 && InstanceManager.getInstance().getInstance(instanceId) != null)
+		Collection<L2DoorInstance> allDoors;
+		if ((instanceId > 0) && (InstanceManager.getInstance().getInstance(instanceId) != null))
+		{
 			allDoors = InstanceManager.getInstance().getInstance(instanceId).getDoors();
+		}
 		else
+		{
 			allDoors = _regions.get(MapRegionManager.getInstance().getMapRegionLocId(x, y));
+		}
 		
 		if (allDoors == null)
+		{
 			return false;
+		}
 		
 		for (L2DoorInstance doorInst : allDoors)
 		{
-			//check dead and open
-			if (doorInst.isDead() || doorInst.getOpen() || !doorInst.checkCollision() || doorInst.getX(0) == 0)
+			// check dead and open
+			if (doorInst.isDead() || doorInst.getOpen() || !doorInst.checkCollision() || (doorInst.getX(0) == 0))
+			{
 				continue;
+			}
 			
 			boolean intersectFace = false;
 			for (int i = 0; i < 4; i++)
 			{
-				int j = i + 1 < 4 ? i + 1 : 0;
+				int j = (i + 1) < 4 ? i + 1 : 0;
 				// lower part of the multiplier fraction, if it is 0 we avoid an error and also know that the lines are parallel
-				int denominator = (ty - y) * (doorInst.getX(i) - doorInst.getX(j)) - (tx - x) * (doorInst.getY(i) - doorInst.getY(j));
+				int denominator = ((ty - y) * (doorInst.getX(i) - doorInst.getX(j))) - ((tx - x) * (doorInst.getY(i) - doorInst.getY(j)));
 				if (denominator == 0)
+				{
 					continue;
+				}
 				
 				// multipliers to the equations of the lines. If they are lower than 0 or bigger than 1, we know that segments don't intersect
-				float multiplier1 = (float)((doorInst.getX(j) - doorInst.getX(i)) * (y - doorInst.getY(i)) - (doorInst.getY(j) - doorInst.getY(i)) * (x - doorInst.getX(i))) / denominator;
-				float multiplier2 = (float)((tx - x) * (y - doorInst.getY(i)) - (ty - y) * (x - doorInst.getX(i))) / denominator;
-				if (multiplier1 >= 0 && multiplier1 <= 1 && multiplier2 >= 0 && multiplier2 <= 1)
+				float multiplier1 = (float) (((doorInst.getX(j) - doorInst.getX(i)) * (y - doorInst.getY(i))) - ((doorInst.getY(j) - doorInst.getY(i)) * (x - doorInst.getX(i)))) / denominator;
+				float multiplier2 = (float) (((tx - x) * (y - doorInst.getY(i))) - ((ty - y) * (x - doorInst.getX(i)))) / denominator;
+				if ((multiplier1 >= 0) && (multiplier1 <= 1) && (multiplier2 >= 0) && (multiplier2 <= 1))
 				{
-					int intersectZ = Math.round(z + multiplier1 * (tz - z));
+					int intersectZ = Math.round(z + (multiplier1 * (tz - z)));
 					// now checking if the resulting point is between door's min and max z
-					if (intersectZ > doorInst.getZMin() && intersectZ < doorInst.getZMax())
+					if ((intersectZ > doorInst.getZMin()) && (intersectZ < doorInst.getZMax()))
 					{
 						if (!doubleFaceCheck || intersectFace)
+						{
 							return true;
+						}
 						intersectFace = true;
 					}
 				}

+ 4 - 4
L2J_Server_BETA/java/com/l2jserver/gameserver/instancemanager/MapRegionManager.java

@@ -260,7 +260,7 @@ public class MapRegionManager extends DocumentParser
 	 */
 	public Location getTeleToLocation(L2Character activeChar, TeleportWhereType teleportWhere)
 	{
-		int[] coord;
+		Location loc;
 		
 		if (activeChar instanceof L2PcInstance)
 		{
@@ -460,10 +460,10 @@ public class MapRegionManager extends DocumentParser
 				Instance inst = InstanceManager.getInstance().getInstance(player.getInstanceId());
 				if (inst != null)
 				{
-					coord = inst.getSpawnLoc();
-					if ((coord[0] != 0) && (coord[1] != 0) && (coord[2] != 0))
+					loc = inst.getSpawnLoc();
+					if (loc != null)
 					{
-						return new Location(coord[0], coord[1], coord[2]);
+						return loc;
 					}
 				}
 			}

+ 2 - 7
L2J_Server_BETA/java/com/l2jserver/gameserver/model/AbstractPlayerGroup.java

@@ -14,10 +14,9 @@
  */
 package com.l2jserver.gameserver.model;
 
+import java.util.ArrayList;
 import java.util.List;
 
-import javolution.util.FastList;
-
 import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
 import com.l2jserver.gameserver.network.SystemMessageId;
 import com.l2jserver.gameserver.network.serverpackets.CreatureSay;
@@ -27,7 +26,6 @@ import com.l2jserver.util.Rnd;
 
 /**
  * @author Battlecruiser
- * @thx Probe for comments
  */
 public abstract class AbstractPlayerGroup
 {
@@ -41,10 +39,9 @@ public abstract class AbstractPlayerGroup
 	 */
 	public List<Integer> getMembersObjectId()
 	{
-		final List<Integer> ids = new FastList<>();
+		final List<Integer> ids = new ArrayList<>();
 		forEachMember(new IL2Procedure<L2PcInstance>()
 		{
-			
 			@Override
 			public boolean execute(L2PcInstance member)
 			{
@@ -89,7 +86,6 @@ public abstract class AbstractPlayerGroup
 	{
 		forEachMember(new IL2Procedure<L2PcInstance>()
 		{
-			
 			@Override
 			public boolean execute(L2PcInstance member)
 			{
@@ -124,7 +120,6 @@ public abstract class AbstractPlayerGroup
 	{
 		forEachMember(new IL2Procedure<L2PcInstance>()
 		{
-			
 			@Override
 			public boolean execute(L2PcInstance member)
 			{

+ 24 - 8
L2J_Server_BETA/java/com/l2jserver/gameserver/model/L2Object.java

@@ -324,6 +324,7 @@ public abstract class L2Object
 	}
 	
 	/**
+	 * UnAfraid: TODO: Add listener here.
 	 * @param instanceId The id of the instance zone the object is in - id 0 is global
 	 */
 	public void setInstanceId(int instanceId)
@@ -337,8 +338,9 @@ public abstract class L2Object
 		if (newI == null)
 			return;
 		
-		if (this instanceof L2PcInstance)
+		if (isPlayer())
 		{
+			L2PcInstance player = getActingPlayer();
 			if (_instanceId > 0 && oldI != null)
 			{
 				oldI.removePlayer(getObjectId());
@@ -347,9 +349,13 @@ public abstract class L2Object
 					int startTime = (int) ((System.currentTimeMillis() - oldI.getInstanceStartTime()) / 1000);
 					int endTime = (int) ((oldI.getInstanceEndTime() - oldI.getInstanceStartTime()) / 1000);
 					if (oldI.isTimerIncrease())
+					{
 						sendPacket(new ExSendUIEvent(this, true, true, startTime, endTime, oldI.getTimerText()));
+					}
 					else
+					{
 						sendPacket(new ExSendUIEvent(this, true, false, endTime - startTime, 0, oldI.getTimerText()));
+					}
 				}
 			}
 			if (instanceId > 0)
@@ -360,21 +366,32 @@ public abstract class L2Object
 					int startTime = (int) ((System.currentTimeMillis() - newI.getInstanceStartTime()) / 1000);
 					int endTime = (int) ((newI.getInstanceEndTime() - newI.getInstanceStartTime()) / 1000);
 					if (newI.isTimerIncrease())
+					{
 						sendPacket(new ExSendUIEvent(this, false, true, startTime, endTime, newI.getTimerText()));
+					}
 					else
+					{
 						sendPacket(new ExSendUIEvent(this, false, false, endTime - startTime, 0, newI.getTimerText()));
+					}
 				}
 			}
 			
-			if (((L2PcInstance) this).getPet() != null)
-				((L2PcInstance) this).getPet().setInstanceId(instanceId);
+			if (player.getPet() != null)
+			{
+				player.getPet().setInstanceId(instanceId);
+			}
 		}
-		else if (this instanceof L2Npc)
+		else if (isNpc())
 		{
+			L2Npc npc = (L2Npc) this;
 			if (_instanceId > 0 && oldI != null)
-				oldI.removeNpc(((L2Npc) this));
+			{
+				oldI.removeNpc(npc);
+			}
 			if (instanceId > 0)
-				newI.addNpc(((L2Npc) this));
+			{
+				newI.addNpc(npc);
+			}
 		}
 		
 		_instanceId = instanceId;
@@ -382,9 +399,8 @@ public abstract class L2Object
 		// If we change it for visible objects, me must clear & revalidates knownlists
 		if (_isVisible && _knownList != null)
 		{
-			if (this instanceof L2PcInstance)
+			if (isPlayer())
 			{
-				
 				// We don't want some ugly looking disappear/appear effects, so don't update
 				// the knownlist here, but players usually enter instancezones through teleporting
 				// and the teleport will do the revalidation for us.

+ 5 - 7
L2J_Server_BETA/java/com/l2jserver/gameserver/model/StatsSet.java

@@ -30,18 +30,17 @@ import javolution.util.FastMap;
  */
 public final class StatsSet
 {
-	
 	private static final Logger _log = Logger.getLogger(StatsSet.class.getName());
 	private final Map<String, Object> _set;
 	
 	public StatsSet()
 	{
-		_set = new FastMap<>();
+		this(new FastMap<String, Object>());
 	}
 	
-	public StatsSet(StatsSet set)
+	public StatsSet(Map<String, Object> map)
 	{
-		_set = new FastMap<>(set.getSet());
+		_set = map;
 	}
 	
 	/**
@@ -156,11 +155,10 @@ public final class StatsSet
 		}
 	}
 	
-
 	/**
 	 * Returns the byte[] associated to the key put in parameter ("name"). If the value associated to the key is null, this method returns the value of the parameter deflt.
 	 * @param name : String designating the key in the set
-	 * @param splitOn 
+	 * @param splitOn
 	 * @return byte[] : value associated to the key
 	 */
 	public byte[] getByteArray(String name, String splitOn)
@@ -302,7 +300,7 @@ public final class StatsSet
 	/**
 	 * Returns the int[] associated to the key put in parameter ("name"). If the value associated to the key is null, this method returns the value of the parameter deflt.
 	 * @param name : String designating the key in the set
-	 * @param splitOn 
+	 * @param splitOn
 	 * @return int[] : value associated to the key
 	 */
 	public int[] getIntegerArray(String name, String splitOn)

+ 11 - 8
L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/instance/L2PcInstance.java

@@ -3884,7 +3884,10 @@ public final class L2PcInstance extends L2Playable
 			playerIU.addItem(item);
 			sendPacket(playerIU);
 		}
-		else sendPacket(new ItemList(this, false));
+		else
+		{
+			sendPacket(new ItemList(this, false));
+		}
 		
 		// Update current load as well
 		StatusUpdate su = new StatusUpdate(this);
@@ -3901,7 +3904,7 @@ public final class L2PcInstance extends L2Playable
 				sm.addItemNumber(count);
 				sendPacket(sm);
 			}
-			else 
+			else
 			{
 				SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.S1_DISAPPEARED);
 				sm.addItemName(itemId);
@@ -11939,15 +11942,15 @@ public final class L2PcInstance extends L2Playable
 				if (inst != null)
 				{
 					inst.removePlayer(getObjectId());
-					final int[] spawn = inst.getSpawnLoc();
-					if (spawn[0] != 0 && spawn[1] != 0 && spawn[2] != 0)
+					final Location loc = inst.getSpawnLoc();
+					if (loc != null)
 					{
-						final int x = spawn[0] + Rnd.get(-30, 30);
-						final int y = spawn[1] + Rnd.get(-30, 30);
-						setXYZInvisible(x, y, spawn[2]);
+						final int x = loc.getX() + Rnd.get(-30, 30);
+						final int y = loc.getY() + Rnd.get(-30, 30);
+						setXYZInvisible(x, y, loc.getZ());
 						if (getPet() != null) // dead pet
 						{
-							getPet().teleToLocation(x, y, spawn[2]);
+							getPet().teleToLocation(loc, true);
 							getPet().setInstanceId(0);
 						}
 					}

+ 130 - 81
L2J_Server_BETA/java/com/l2jserver/gameserver/model/entity/Instance.java

@@ -2,16 +2,15 @@ package com.l2jserver.gameserver.model.entity;
 
 import java.io.File;
 import java.io.IOException;
-import java.util.ArrayList;
+import java.util.Collection;
 import java.util.List;
+import java.util.Map;
 import java.util.concurrent.ScheduledFuture;
 import java.util.logging.Level;
 import java.util.logging.Logger;
 
 import javax.xml.parsers.DocumentBuilderFactory;
 
-import javolution.util.FastList;
-
 import org.w3c.dom.Document;
 import org.w3c.dom.NamedNodeMap;
 import org.w3c.dom.Node;
@@ -24,9 +23,11 @@ import com.l2jserver.gameserver.datatables.NpcTable;
 import com.l2jserver.gameserver.idfactory.IdFactory;
 import com.l2jserver.gameserver.instancemanager.InstanceManager;
 import com.l2jserver.gameserver.instancemanager.MapRegionManager;
+import com.l2jserver.gameserver.model.IL2Procedure;
 import com.l2jserver.gameserver.model.L2Spawn;
 import com.l2jserver.gameserver.model.L2World;
 import com.l2jserver.gameserver.model.L2WorldRegion;
+import com.l2jserver.gameserver.model.Location;
 import com.l2jserver.gameserver.model.StatsSet;
 import com.l2jserver.gameserver.model.actor.L2Attackable;
 import com.l2jserver.gameserver.model.actor.L2Npc;
@@ -37,7 +38,10 @@ import com.l2jserver.gameserver.model.actor.templates.L2NpcTemplate;
 import com.l2jserver.gameserver.network.SystemMessageId;
 import com.l2jserver.gameserver.network.clientpackets.Say2;
 import com.l2jserver.gameserver.network.serverpackets.CreatureSay;
+import com.l2jserver.gameserver.network.serverpackets.L2GameServerPacket;
 import com.l2jserver.gameserver.network.serverpackets.SystemMessage;
+import com.l2jserver.util.L2FastList;
+import com.l2jserver.util.L2FastMap;
 
 /**
  * @author evill33t, GodKratos
@@ -46,13 +50,13 @@ public class Instance
 {
 	private static final Logger _log = Logger.getLogger(Instance.class.getName());
 	
-	private int _id;
+	private final int _id;
 	private String _name;
 	
-	private List<Integer> _players = new FastList<Integer>().shared();
-	private List<L2Npc> _npcs = new FastList<L2Npc>().shared();
-	private List<L2DoorInstance> _doors = null;
-	private int[] _spawnLoc = new int[3]; // TODO: Zoey76: Replace with Location object.
+	private final L2FastList<Integer> _players = new L2FastList<>(true);
+	private final List<L2Npc> _npcs = new L2FastList<>(true);
+	private final Map<Integer, L2DoorInstance> _doors = new L2FastMap<>(true);
+	private Location _spawnLoc = null;
 	private boolean _allowSummon = true;
 	private long _emptyDestroyTime = -1;
 	private long _lastLeft = -1;
@@ -102,7 +106,7 @@ public class Instance
 	
 	/**
 	 * Sets the status for the instance for summon friend type skills
-	 * @param b 
+	 * @param b
 	 */
 	public void setAllowSummon(boolean b)
 	{
@@ -111,7 +115,7 @@ public class Instance
 	
 	/**
 	 * Returns true if entire instance is PvP zone
-	 * @return 
+	 * @return
 	 */
 	public boolean isPvPInstance()
 	{
@@ -120,7 +124,7 @@ public class Instance
 	
 	/**
 	 * Sets PvP zone status of the instance
-	 * @param b 
+	 * @param b
 	 */
 	public void setPvPInstance(boolean b)
 	{
@@ -134,7 +138,9 @@ public class Instance
 	public void setDuration(int duration)
 	{
 		if (_CheckTimeUpTask != null)
+		{
 			_CheckTimeUpTask.cancel(true);
+		}
 		
 		_CheckTimeUpTask = ThreadPoolManager.getInstance().scheduleGeneral(new CheckTimeUp(duration), 500);
 		_instanceEndTime = System.currentTimeMillis() + duration + 500;
@@ -176,7 +182,7 @@ public class Instance
 	{
 		_players.remove(objectId);
 		
-		if (_players.isEmpty() && _emptyDestroyTime >= 0)
+		if (_players.isEmpty() && (_emptyDestroyTime >= 0))
 		{
 			_lastLeft = System.currentTimeMillis();
 			setDuration((int) (_instanceEndTime - System.currentTimeMillis() - 500));
@@ -190,14 +196,18 @@ public class Instance
 	public void ejectPlayer(int objectId)
 	{
 		L2PcInstance player = L2World.getInstance().getPlayer(objectId);
-		if (player != null && player.getInstanceId() == this.getId())
+		if ((player != null) && (player.getInstanceId() == getId()))
 		{
 			player.setInstanceId(0);
 			player.sendMessage("You were removed from the instance");
-			if (getSpawnLoc()[0] != 0 && getSpawnLoc()[1] != 0 && getSpawnLoc()[2] != 0)
-				player.teleToLocation(getSpawnLoc()[0], getSpawnLoc()[1], getSpawnLoc()[2]);
+			if (getSpawnLoc() != null)
+			{
+				player.teleToLocation(getSpawnLoc(), true);
+			}
 			else
+			{
 				player.teleToLocation(MapRegionManager.TeleportWhereType.Town);
+			}
 		}
 	}
 	
@@ -209,8 +219,9 @@ public class Instance
 	public void removeNpc(L2Npc npc)
 	{
 		if (npc.getSpawn() != null)
+		{
 			npc.getSpawn().stopRespawn();
-		//npc.deleteMe();
+		}
 		_npcs.remove(npc);
 	}
 	
@@ -221,16 +232,10 @@ public class Instance
 	 */
 	private void addDoor(int doorId, StatsSet set)
 	{
-		if (_doors == null)
-			_doors = new ArrayList<>(2);
-		
-		for (L2DoorInstance door: _doors)
+		if (_doors.containsKey(doorId))
 		{
-			if (door.getDoorId() == doorId)
-			{
-				_log.warning("Door ID " + doorId + " already exists in instance " + this.getId());
-				return;
-			}
+			_log.warning("Door ID " + doorId + " already exists in instance " + getId());
+			return;
 		}
 		
 		L2DoorTemplate temp = DoorTable.getInstance().getDoorTemplate(doorId);
@@ -238,7 +243,7 @@ public class Instance
 		newdoor.setInstanceId(getId());
 		newdoor.setCurrentHp(newdoor.getMaxHp());
 		newdoor.spawnMe(temp.posX, temp.posY, temp.posZ);
-		_doors.add(newdoor);
+		_doors.put(doorId, newdoor);
 	}
 	
 	public List<Integer> getPlayers()
@@ -251,19 +256,14 @@ public class Instance
 		return _npcs;
 	}
 	
-	public List<L2DoorInstance> getDoors()
+	public Collection<L2DoorInstance> getDoors()
 	{
-		return _doors;
+		return _doors.values();
 	}
 	
 	public L2DoorInstance getDoor(int id)
 	{
-		for (L2DoorInstance temp : _doors)
-		{
-			if (temp.getDoorId() == id)
-				return temp;
-		}
-		return null;
+		return _doors.get(id);
 	}
 	
 	public long getInstanceEndTime()
@@ -292,32 +292,25 @@ public class Instance
 	}
 	
 	/**
-	 * Returns the spawn location for this instance to be used when leaving the instance
-	 * @return int[3]
+	 * @return the spawn location for this instance to be used when leaving the instance
 	 */
-	public int[] getSpawnLoc()
+	public Location getSpawnLoc()
 	{
 		return _spawnLoc;
 	}
 	
 	/**
 	 * Sets the spawn location for this instance to be used when leaving the instance
-	 * @param loc 
+	 * @param loc
 	 */
-	public void setSpawnLoc(int[] loc)
+	public void setSpawnLoc(Location loc)
 	{
-		if (loc == null || loc.length < 3)
-			return;
-		System.arraycopy(loc, 0, _spawnLoc, 0, 3);
+		_spawnLoc = loc;
 	}
 	
 	public void removePlayers()
 	{
-		// TODO: Zoey76: Implement IL2Procedure?
-		for (int objId : _players)
-		{
-			ejectPlayer(objId);
-		}
+		_players.forEach(new EjectProcedure());
 		_players.clear();
 	}
 	
@@ -328,7 +321,9 @@ public class Instance
 			if (mob != null)
 			{
 				if (mob.getSpawn() != null)
+				{
 					mob.getSpawn().stopRespawn();
+				}
 				mob.deleteMe();
 			}
 		}
@@ -337,10 +332,7 @@ public class Instance
 	
 	public void removeDoors()
 	{
-		if (_doors == null)
-			return;
-		
-		for (L2DoorInstance door: _doors)
+		for (L2DoorInstance door : _doors.values())
 		{
 			if (door != null)
 			{
@@ -348,14 +340,15 @@ public class Instance
 				door.decayMe();
 				
 				if (region != null)
+				{
 					region.removeVisibleObject(door);
+				}
 				
 				door.getKnownList().removeAllKnownObjects();
 				L2World.getInstance().removeObject(door);
 			}
 		}
 		_doors.clear();
-		_doors = null;
 	}
 	
 	public void loadInstanceTemplate(String filename)
@@ -406,44 +399,60 @@ public class Instance
 				if (a != null)
 				{
 					_CheckTimeUpTask = ThreadPoolManager.getInstance().scheduleGeneral(new CheckTimeUp(Integer.parseInt(a.getNodeValue()) * 60000), 15000);
-					_instanceEndTime = System.currentTimeMillis() + Long.parseLong(a.getNodeValue()) * 60000 + 15000;
+					_instanceEndTime = System.currentTimeMillis() + (Long.parseLong(a.getNodeValue()) * 60000) + 15000;
 				}
 			}
-			/*			else if ("timeDelay".equalsIgnoreCase(n.getNodeName()))
-						{
-							a = n.getAttributes().getNamedItem("val");
-							if (a != null)
-								instance.setTimeDelay(Integer.parseInt(a.getNodeValue()));
-						}*/
+			//@formatter:off
+			/*			
+ 			else if ("timeDelay".equalsIgnoreCase(n.getNodeName()))
+			{
+				a = n.getAttributes().getNamedItem("val");
+				if (a != null)
+					instance.setTimeDelay(Integer.parseInt(a.getNodeValue()));
+			}
+			*/
+			//@formatter:on
 			else if ("allowSummon".equalsIgnoreCase(n.getNodeName()))
 			{
 				a = n.getAttributes().getNamedItem("val");
 				if (a != null)
+				{
 					setAllowSummon(Boolean.parseBoolean(a.getNodeValue()));
+				}
 			}
 			else if ("emptyDestroyTime".equalsIgnoreCase(n.getNodeName()))
 			{
 				a = n.getAttributes().getNamedItem("val");
 				if (a != null)
+				{
 					_emptyDestroyTime = Long.parseLong(a.getNodeValue()) * 1000;
+				}
 			}
 			else if ("showTimer".equalsIgnoreCase(n.getNodeName()))
 			{
 				a = n.getAttributes().getNamedItem("val");
 				if (a != null)
+				{
 					_showTimer = Boolean.parseBoolean(a.getNodeValue());
+				}
 				a = n.getAttributes().getNamedItem("increase");
 				if (a != null)
+				{
 					_isTimerIncrease = Boolean.parseBoolean(a.getNodeValue());
+				}
 				a = n.getAttributes().getNamedItem("text");
 				if (a != null)
+				{
 					_timerText = a.getNodeValue();
+				}
 			}
 			else if ("PvPInstance".equalsIgnoreCase(n.getNodeName()))
 			{
 				a = n.getAttributes().getNamedItem("val");
 				if (a != null)
+				{
 					setPvPInstance(Boolean.parseBoolean(a.getNodeValue()));
+				}
 			}
 			else if ("doorlist".equalsIgnoreCase(n.getNodeName()))
 			{
@@ -484,7 +493,9 @@ public class Instance
 						heading = Integer.parseInt(d.getAttributes().getNamedItem("heading").getNodeValue());
 						respawn = Integer.parseInt(d.getAttributes().getNamedItem("respawn").getNodeValue());
 						if (d.getAttributes().getNamedItem("onKillDelay") != null)
+						{
 							delay = Integer.parseInt(d.getAttributes().getNamedItem("onKillDelay").getNodeValue());
+						}
 						
 						npcTemplate = NpcTable.getInstance().getTemplate(npcId);
 						if (npcTemplate != null)
@@ -497,13 +508,19 @@ public class Instance
 							spawnDat.setHeading(heading);
 							spawnDat.setRespawnDelay(respawn);
 							if (respawn == 0)
+							{
 								spawnDat.stopRespawn();
+							}
 							else
+							{
 								spawnDat.startRespawn();
+							}
 							spawnDat.setInstanceId(getId());
 							L2Npc spawned = spawnDat.doSpawn();
-							if (delay >= 0 && spawned instanceof L2Attackable)
-								((L2Attackable)spawned).setOnKillDelay(delay);
+							if ((delay >= 0) && (spawned instanceof L2Attackable))
+							{
+								((L2Attackable) spawned).setOnKillDelay(delay);
+							}
 						}
 						else
 						{
@@ -516,19 +533,22 @@ public class Instance
 			{
 				try
 				{
-					_spawnLoc[0] = Integer.parseInt(n.getAttributes().getNamedItem("spawnX").getNodeValue());
-					_spawnLoc[1] = Integer.parseInt(n.getAttributes().getNamedItem("spawnY").getNodeValue());
-					_spawnLoc[2] = Integer.parseInt(n.getAttributes().getNamedItem("spawnZ").getNodeValue());
+					int x = Integer.parseInt(n.getAttributes().getNamedItem("spawnX").getNodeValue());
+					int y = Integer.parseInt(n.getAttributes().getNamedItem("spawnY").getNodeValue());
+					int z = Integer.parseInt(n.getAttributes().getNamedItem("spawnZ").getNodeValue());
+					_spawnLoc = new Location(x, y, z);
 				}
 				catch (Exception e)
 				{
 					_log.log(Level.WARNING, "Error parsing instance xml: " + e.getMessage(), e);
-					_spawnLoc = new int[3];
+					_spawnLoc = null;
 				}
 			}
 		}
 		if (Config.DEBUG)
+		{
 			_log.info(name + " Instance Template for Instance " + getId() + " loaded");
+		}
 	}
 	
 	protected void doCheckTimeUp(int remaining)
@@ -537,31 +557,31 @@ public class Instance
 		int timeLeft;
 		int interval;
 		
-		if (_players.isEmpty() && _emptyDestroyTime == 0)
+		if (_players.isEmpty() && (_emptyDestroyTime == 0))
 		{
 			remaining = 0;
 			interval = 500;
 		}
-		else if (_players.isEmpty() && _emptyDestroyTime > 0)
+		else if (_players.isEmpty() && (_emptyDestroyTime > 0))
 		{
 			
-			Long emptyTimeLeft = _lastLeft + _emptyDestroyTime - System.currentTimeMillis();
+			Long emptyTimeLeft = (_lastLeft + _emptyDestroyTime) - System.currentTimeMillis();
 			if (emptyTimeLeft <= 0)
 			{
 				interval = 0;
 				remaining = 0;
 			}
-			else if (remaining > 300000 && emptyTimeLeft > 300000)
+			else if ((remaining > 300000) && (emptyTimeLeft > 300000))
 			{
 				interval = 300000;
 				remaining = remaining - 300000;
 			}
-			else if (remaining > 60000 && emptyTimeLeft > 60000)
+			else if ((remaining > 60000) && (emptyTimeLeft > 60000))
 			{
 				interval = 60000;
 				remaining = remaining - 60000;
 			}
-			else if (remaining > 30000 && emptyTimeLeft > 30000)
+			else if ((remaining > 30000) && (emptyTimeLeft > 30000))
 			{
 				interval = 30000;
 				remaining = remaining - 30000;
@@ -606,32 +626,30 @@ public class Instance
 		}
 		if (cs != null)
 		{
-			// TODO: Zoey76: Implement IL2Procedure?
-			for (int objId : _players)
-			{
-				L2PcInstance player = L2World.getInstance().getPlayer(objId);
-				if (player.getInstanceId() == getId())
-				{
-					player.sendPacket(cs);
-				}
-			}
+			_players.forEach(new BroadcastPacket(cs));
 		}
 		cancelTimer();
 		if (remaining >= 10000)
+		{
 			_CheckTimeUpTask = ThreadPoolManager.getInstance().scheduleGeneral(new CheckTimeUp(remaining), interval);
+		}
 		else
+		{
 			_CheckTimeUpTask = ThreadPoolManager.getInstance().scheduleGeneral(new TimeUp(), interval);
+		}
 	}
 	
 	public void cancelTimer()
 	{
 		if (_CheckTimeUpTask != null)
+		{
 			_CheckTimeUpTask.cancel(true);
+		}
 	}
 	
 	public class CheckTimeUp implements Runnable
 	{
-		private int	_remaining;
+		private final int _remaining;
 		
 		public CheckTimeUp(int remaining)
 		{
@@ -653,4 +671,35 @@ public class Instance
 			InstanceManager.getInstance().destroyInstance(getId());
 		}
 	}
+	
+	public final class EjectProcedure implements IL2Procedure<Integer>
+	{
+		@Override
+		public boolean execute(Integer objectId)
+		{
+			ejectPlayer(objectId);
+			return true;
+		}
+	}
+	
+	public final class BroadcastPacket implements IL2Procedure<Integer>
+	{
+		private final L2GameServerPacket _packet;
+		
+		public BroadcastPacket(L2GameServerPacket packet)
+		{
+			_packet = packet;
+		}
+		
+		@Override
+		public boolean execute(Integer objectId)
+		{
+			L2PcInstance player = L2World.getInstance().getPlayer(objectId);
+			if (player != null && player.getInstanceId() == getId())
+			{
+				player.sendPacket(_packet);
+			}
+			return true;
+		}
+	}
 }