Jelajahi Sumber

Changes in Instance system:
- Adding support for emptyDestroyTime of Instances.
- Adding support for InstanceWorld.
- fixing problem when npcs are spawned by scripts these npcs were not removed when instance is destroyed.

Gigiikun 16 tahun lalu
induk
melakukan
b926b1e70e

+ 33 - 0
L2_GameServer/java/net/sf/l2j/gameserver/instancemanager/InstanceManager.java

@@ -17,8 +17,10 @@ package net.sf.l2j.gameserver.instancemanager;
 import java.io.FileNotFoundException;
 import java.util.logging.Logger;
 
+import javolution.util.FastList;
 import javolution.util.FastMap;
 
+import net.sf.l2j.gameserver.model.actor.instance.L2PcInstance;
 import net.sf.l2j.gameserver.model.entity.Instance;
 
 /** 
@@ -29,8 +31,37 @@ public class InstanceManager
 {
 	private final static Logger _log = Logger.getLogger(InstanceManager.class.getName());
 	private FastMap<Integer, Instance> _instanceList = new FastMap<Integer, Instance>();
+	private FastMap<Integer, InstanceWorld> _instanceWorlds = new FastMap<Integer, InstanceWorld>();
 	private int _dynamic = 300000;
 	
+	public class InstanceWorld
+	{
+		public int instanceId;
+		public FastList<L2PcInstance> allowed = new FastList<L2PcInstance>();
+		public int status;
+	}
+	
+	public void addWorld(InstanceWorld world)
+	{
+		_instanceWorlds.put(world.instanceId, world);
+	}
+	
+	public InstanceWorld getWorld(int instanceId)
+	{
+		return _instanceWorlds.get(instanceId);
+	}
+	
+	public InstanceWorld getPlayerWorld(L2PcInstance player)
+	{
+		for (InstanceWorld temp : _instanceWorlds.values())
+		{
+			// check if the player have a World Instance where he/she is allowed to enter
+			if (temp.allowed.contains(player))
+				return temp;
+		}
+		return null;
+	}
+	
 	private InstanceManager()
 	{
 		_log.info("Initializing InstanceManager");
@@ -67,6 +98,8 @@ public class InstanceManager
 			temp.removeDoors();
 			temp.cancelTimer();
 			_instanceList.remove(instanceid);
+			if (_instanceWorlds.containsKey(instanceid))
+				_instanceWorlds.remove(instanceid);
 		}
 	}
 	

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

@@ -19,6 +19,7 @@ import net.sf.l2j.gameserver.idfactory.IdFactory;
 import net.sf.l2j.gameserver.instancemanager.InstanceManager;
 import net.sf.l2j.gameserver.instancemanager.ItemsOnGroundManager;
 import net.sf.l2j.gameserver.model.actor.L2Character;
+import net.sf.l2j.gameserver.model.actor.L2Npc;
 import net.sf.l2j.gameserver.model.actor.instance.L2PcInstance;
 import net.sf.l2j.gameserver.model.actor.knownlist.ObjectKnownList;
 import net.sf.l2j.gameserver.model.actor.poly.ObjectPoly;
@@ -129,7 +130,14 @@ public abstract class L2Object
 			
 			if (((L2PcInstance)this).getPet() != null)
 				((L2PcInstance)this).getPet().setInstanceId(instanceId);
-		} 
+		}
+		else if (this instanceof L2Npc)
+		{
+			if (_instanceId > 0)
+				InstanceManager.getInstance().getInstance(_instanceId).removeNpc(((L2Npc)this).getSpawn());
+			if (instanceId > 0)
+				InstanceManager.getInstance().getInstance(instanceId).addNpc(((L2Npc)this));
+		}
 		
 		_instanceId = instanceId;
 

+ 59 - 2
L2_GameServer/java/net/sf/l2j/gameserver/model/entity/Instance.java

@@ -49,6 +49,9 @@ public class Instance
 	private FastList<L2DoorInstance> _doors = new FastList<L2DoorInstance>();
 	private int[] _spawnLoc = new int[3];
 	private boolean _allowSummon = true;
+	private long _emptyDestroyTime = -1;
+	private long _lastLeft = -1;
+	private long _instanceEndTime = -1;
 	private boolean _isPvPInstance = false;
 
 	protected ScheduledFuture<?> _CheckTimeUpTask = null;
@@ -120,7 +123,7 @@ public class Instance
 		if (_CheckTimeUpTask != null)
 			_CheckTimeUpTask.cancel(true);
 
-		_CheckTimeUpTask = ThreadPoolManager.getInstance().scheduleGeneral(new CheckTimeUp(duration * 60000), 15000);
+		_CheckTimeUpTask = ThreadPoolManager.getInstance().scheduleGeneral(new CheckTimeUp(duration), 500);
 	}
 
 	/**
@@ -153,6 +156,11 @@ public class Instance
 	{
 		if (_players.contains(objectId))
 			_players.remove(objectId);
+		if (_players.isEmpty() && _emptyDestroyTime >= 0)
+		{
+			_lastLeft = System.currentTimeMillis();
+			setDuration((int) (_instanceEndTime - System.currentTimeMillis() - 1000));
+		}
 	}
 
 	/**
@@ -173,6 +181,11 @@ public class Instance
 		}
 	}
 
+	public void addNpc(L2Npc npc)
+	{
+		_npcs.add(npc);
+	}
+
 	public void removeNpc(L2Spawn spawn)
 	{
 		_npcs.remove(spawn);
@@ -344,7 +357,10 @@ public class Instance
 			{
 				a = n.getAttributes().getNamedItem("val");
 				if (a != null)
+				{
 					_CheckTimeUpTask = ThreadPoolManager.getInstance().scheduleGeneral(new CheckTimeUp(Integer.parseInt(a.getNodeValue()) * 60000), 15000);
+					_instanceEndTime = System.currentTimeMillis() + Long.parseLong(a.getNodeValue()) * 60000 + 15000;
+				}
 			}
 			/*			else if ("timeDelay".equalsIgnoreCase(n.getNodeName()))
 						{
@@ -358,6 +374,12 @@ public class Instance
 				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 ("PvPInstance".equalsIgnoreCase(n.getNodeName()))
 			{
 				a = n.getAttributes().getNamedItem("val");
@@ -445,7 +467,42 @@ public class Instance
 		int timeLeft;
 		int interval;
 
-		if (remaining > 300000)
+		if (_players.isEmpty() && _emptyDestroyTime == 0)
+		{
+			remaining = 0;
+			interval = 500;
+		}
+		else if (_players.isEmpty() && _emptyDestroyTime > 0)
+		{
+			
+			Long emptyTimeLeft = _lastLeft + _emptyDestroyTime - System.currentTimeMillis();
+			if (emptyTimeLeft <= 0)
+			{
+				interval = 0;
+				remaining = 0;
+			}
+			else if (remaining > 300000 && emptyTimeLeft > 300000)
+			{
+				interval = 300000;
+				remaining = remaining - 300000;
+			}
+			else if (remaining > 60000 && emptyTimeLeft > 60000)
+			{
+				interval = 60000;
+				remaining = remaining - 60000;
+			}
+			else if (remaining > 30000 && emptyTimeLeft > 30000)
+			{
+				interval = 30000;
+				remaining = remaining - 30000;
+			}
+			else
+			{
+				interval = 10000;
+				remaining = remaining - 10000;
+			}
+		}
+		else if (remaining > 300000)
 		{
 			timeLeft = remaining / 60000;
 			interval = 300000;