浏览代码

Update fort handling and auto doors fix. Thx Kerberos :)

GodKratos 16 年之前
父节点
当前提交
3255d02dd9

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

@@ -292,7 +292,7 @@ public class GameServer
 		SpawnTable.getInstance();
 		RaidBossSpawnManager.getInstance();
 		DayNightSpawnManager.getInstance().notifyChangeMode();
-		GrandBossManager.getInstance();
+		GrandBossManager.getInstance().initZones();
 		RaidBossPointsManager.init();
 		FourSepulchersManager.getInstance().init();
 		DimensionalRiftManager.getInstance();

+ 7 - 3
L2_GameServer/java/net/sf/l2j/gameserver/datatables/DoorTable.java

@@ -144,9 +144,9 @@ public class DoorTable
 		boolean unlockable = false;
 		if (st.hasMoreTokens())
 			unlockable = Boolean.parseBoolean(st.nextToken());
-		boolean isCommanderDoor = false;
+		boolean startOpen = false;
 		if (st.hasMoreTokens())
-			isCommanderDoor = Boolean.parseBoolean(st.nextToken());
+			startOpen = Boolean.parseBoolean(st.nextToken());
 		
 		if (rangeXMin > rangeXMax)
 			_log.severe("Error in door data, ID:" + id);
@@ -217,9 +217,13 @@ public class DoorTable
 			_log.severe("Error in door data, ID:" + id);
 		}
 		door.setCurrentHpMp(door.getMaxHp(), door.getMaxMp());
-		door.setIsCommanderDoor(isCommanderDoor);
 		door.setXYZInvisible(x, y, z);
 		
+		if (door.getFort() != null)
+			door.setIsCommanderDoor(startOpen);
+		else
+			door.setOpen(startOpen);
+		
 		return door;
 	}
 	

+ 6 - 384
L2_GameServer/java/net/sf/l2j/gameserver/instancemanager/FortManager.java

@@ -14,7 +14,6 @@
  */
 package net.sf.l2j.gameserver.instancemanager;
 
-import java.sql.Connection;
 import java.sql.PreparedStatement;
 import java.sql.ResultSet;
 import java.util.List;
@@ -23,29 +22,17 @@ import java.util.logging.Logger;
 import javolution.util.FastList;
 import javolution.util.FastMap;
 import net.sf.l2j.L2DatabaseFactory;
-import net.sf.l2j.gameserver.ThreadPoolManager;
-import net.sf.l2j.gameserver.datatables.NpcTable;
-import net.sf.l2j.gameserver.datatables.SpawnTable;
 import net.sf.l2j.gameserver.model.L2Clan;
 import net.sf.l2j.gameserver.model.L2Object;
-import net.sf.l2j.gameserver.model.L2Spawn;
 import net.sf.l2j.gameserver.model.entity.Fort;
-import net.sf.l2j.gameserver.templates.chars.L2NpcTemplate;
 
 public class FortManager
 {
 	protected static final Logger _log = Logger.getLogger(FortManager.class.getName());
 	// =========================================================
 	private static FortManager _instance;
-	protected FastMap<Integer, Integer> _envoyCastles = new FastMap<Integer, Integer>();
-	protected FastMap<Integer, FastList<L2Spawn>> _npcCommanders = new FastMap<Integer, FastList<L2Spawn>>();
-	protected FastMap<Integer, FastList<L2Spawn>> _siegeNpcs = new FastMap<Integer, FastList<L2Spawn>>();
-	protected FastMap<Integer, FastList<L2Spawn>> _specialEnvoys = new FastMap<Integer, FastList<L2Spawn>>();
-	protected FastList<L2Spawn> _npcCommandersSpawns;
-	protected FastList<L2Spawn> _siegeNpcsSpawns;
-	protected FastList<L2Spawn> _specialEnvoysSpawns;
-	protected int _respawnTime;
-
+	public FastMap<Integer, Integer> _envoyCastles = new FastMap<Integer, Integer>();
+	
 	public static final FortManager getInstance()
     {
         if (_instance == null)
@@ -59,29 +46,14 @@ public class FortManager
     
     // =========================================================
     // Data Field
-    private Fort _fort;
     private List<Fort> _forts;
     
     // =========================================================
     // Constructor
-    public FortManager() {}
-	public FortManager(Fort fort)
-	{
-		_fort = fort;
-		initNpcs(); // load and spawn npcs
-		initSiegeNpcs(); // load suspicious merchants
-		spawnSuspiciousMerchant();// spawn suspicious merchants
-		initNpcCommanders(); // npc Commanders (not monsters)
-		spawnNpcCommanders(); // spawn npc Commanders
-		initSpecialEnvoys(); // envoys from castles
-		if (_fort.getOwnerClan() != null && _fort.getFortState() == 0)
-		{
-			spawnSpecialEnvoys();
-			ThreadPoolManager.getInstance().scheduleGeneral(_fort.new ScheduleSpecialEnvoysDeSpawn(_fort), 1*60*60*1000); // Prepare 1hr task for special envoys despawn
-		}
-	}
-    // =========================================================
-    // Method - Public
+    public FortManager()
+    {
+    	
+    }
 
     public final int findNearestFortIndex(L2Object obj)
     {
@@ -231,357 +203,7 @@ public class FortManager
         if (_forts == null) _forts = new FastList<Fort>();
         return _forts;
     }
-	public final Fort getFort()
-	{
-		return _fort;
-	}
     
-    private void initNpcs()
-    {
-    	Connection con = null;
-
-    	try
-		{
-			con = L2DatabaseFactory.getInstance().getConnection();
-			PreparedStatement statement = con.prepareStatement("SELECT * FROM fort_spawnlist Where fortId = ? and spawnType = ? ");
-			statement.setInt(1, getFort().getFortId());
-			statement.setInt(2, 0);
-			ResultSet rset = statement.executeQuery();
-			
-			L2Spawn spawnDat;
-			L2NpcTemplate template1;
-			
-			while (rset.next())
-			{
-				template1 = NpcTable.getInstance().getTemplate(rset.getInt("npcId"));
-				if (template1 != null)
-				{
-					spawnDat = new L2Spawn(template1);
-					spawnDat.setAmount(1);
-					spawnDat.setLocx(rset.getInt("x"));
-					spawnDat.setLocy(rset.getInt("y"));
-					spawnDat.setLocz(rset.getInt("z"));
-					spawnDat.setHeading(rset.getInt("heading"));
-					spawnDat.setRespawnDelay(60);
-					SpawnTable.getInstance().addNewSpawn(spawnDat, false);
-					spawnDat.doSpawn();
-					spawnDat.startRespawn();
-				}
-				else
-				{
-					_log.warning("FortManager.initNpcs: Data missing in NPC table for ID: "
-					        + rset.getInt("npcId") + ".");
-				}
-			}
-			
-			rset.close();
-			statement.close();
-		}
-		catch (Exception e)
-		{
-			// problem with initializing spawn, go to next one
-			_log.warning("FortManager.initNpcs: Spawn could not be initialized: "+ e.getMessage());
-			e.printStackTrace();
-		}
-		finally
-		{
-			try
-			{
-				con.close();
-			}
-			catch (Exception e)
-			{
-            	_log.warning(""+e.getMessage());
-            	e.printStackTrace();
-			}
-		}
-    }
-    private void initNpcCommanders()
-    {
-    	Connection con = null;
-    	_npcCommanders.clear();
-    	try
-		{
-			con = L2DatabaseFactory.getInstance().getConnection();
-			PreparedStatement statement1 = con.prepareStatement("SELECT Distinct fortId FROM fort_spawnlist Where spawnType = ? ORDER BY fortId");
-
-			statement1.setInt(1, 1);
-			ResultSet rset1 = statement1.executeQuery();
-
-			while (rset1.next())
-			{
-				int fortId = rset1.getInt("fortId");
-				PreparedStatement statement2 = con.prepareStatement("SELECT id, npcId, x, y, z, heading FROM fort_spawnlist Where fortId = ? and spawnType = ? ORDER BY id");
-				statement2.setInt(1, getFort().getFortId());
-				statement2.setInt(2, 1);
-				ResultSet rset2 = statement2.executeQuery();
-				
-				L2Spawn spawnDat;
-				L2NpcTemplate template1;
-				_npcCommandersSpawns = new FastList<L2Spawn>();
-				while (rset2.next())
-				{
-					template1 = NpcTable.getInstance().getTemplate(rset2.getInt("npcId"));
-					if (template1 != null)
-					{
-						spawnDat = new L2Spawn(template1);
-						spawnDat.setAmount(1);
-						spawnDat.setLocx(rset2.getInt("x"));
-						spawnDat.setLocy(rset2.getInt("y"));
-						spawnDat.setLocz(rset2.getInt("z"));
-						spawnDat.setHeading(rset2.getInt("heading"));
-						spawnDat.setRespawnDelay(60);
-						_npcCommandersSpawns.add(spawnDat);
-					}
-					else
-					{
-						_log.warning("FortManager.initNpcCommanders: Data missing in NPC table for ID: "
-					        + rset2.getInt("npcId") + ".");
-					}
-				}
-				rset2.close();
-				statement2.close();
-				_npcCommanders.put(fortId, _npcCommandersSpawns);
-			}
-			rset1.close();
-			statement1.close();
-		}
-		catch (Exception e)
-		{
-			// problem with initializing spawn, go to next one
-			_log.warning("FortManager.initNpcCommanders: Spawn could not be initialized: "
-			        + e.getMessage());
-			e.printStackTrace();
-		}
-		finally
-		{
-			try
-			{
-				con.close();
-			}
-			catch (Exception e)
-			{
-            	_log.warning(""+e.getMessage());
-            	e.printStackTrace();
-			}
-		}
-    }
-    private void initSiegeNpcs()
-    {
-    	Connection con = null;
-    	_siegeNpcs.clear();
-    	try
-		{
-			con = L2DatabaseFactory.getInstance().getConnection();
-			PreparedStatement statement1 = con.prepareStatement("SELECT Distinct fortId FROM fort_spawnlist Where spawnType = ? ORDER BY fortId");
-
-			statement1.setInt(1, 2);
-			ResultSet rset1 = statement1.executeQuery();
-
-			while (rset1.next())
-			{
-				int fortId = rset1.getInt("fortId");
-				PreparedStatement statement2 = con.prepareStatement("SELECT id, npcId, x, y, z, heading FROM fort_spawnlist Where fortId = ? and spawnType = ? ORDER BY id");
-				statement2.setInt(1, getFort().getFortId());
-				statement2.setInt(2, 2);
-				ResultSet rset2 = statement2.executeQuery();
-				
-				L2Spawn spawnDat;
-				L2NpcTemplate template1;
-				_siegeNpcsSpawns = new FastList<L2Spawn>();
-				while (rset2.next())
-				{
-					template1 = NpcTable.getInstance().getTemplate(rset2.getInt("npcId"));
-					if (template1 != null)
-					{
-						spawnDat = new L2Spawn(template1);
-						spawnDat.setAmount(1);
-						spawnDat.setLocx(rset2.getInt("x"));
-						spawnDat.setLocy(rset2.getInt("y"));
-						spawnDat.setLocz(rset2.getInt("z"));
-						spawnDat.setHeading(rset2.getInt("heading"));
-						spawnDat.setRespawnDelay(60);
-						_siegeNpcsSpawns.add(spawnDat);
-					}
-					else
-					{
-						_log.warning("FortManager.initSiegeNpcs: Data missing in NPC table for ID: "
-					        + rset2.getInt("npcId") + ".");
-					}
-				}
-				rset2.close();
-				statement2.close();
-				_siegeNpcs.put(fortId, _siegeNpcsSpawns);
-			}
-			rset1.close();
-			statement1.close();
-		}
-		catch (Exception e)
-		{
-			// problem with initializing spawn, go to next one
-			_log.warning("FortManager.initSiegeNpcs: Spawn could not be initialized: "
-			        + e.getMessage());
-			e.printStackTrace();
-		}
-		finally
-		{
-			try
-			{
-				con.close();
-			}
-			catch (Exception e)
-			{
-            	_log.warning(""+e.getMessage());
-            	e.printStackTrace();
-			}
-		}
-    }
-    private void initSpecialEnvoys()
-    {
-    	Connection con = null;
-    	_specialEnvoys.clear();
-    	_envoyCastles.clear();
-    	try
-		{
-			con = L2DatabaseFactory.getInstance().getConnection();
-			PreparedStatement statement1 = con.prepareStatement("SELECT Distinct fortId FROM fort_spawnlist Where spawnType = ? ORDER BY fortId");
-
-			statement1.setInt(1, 3);
-			ResultSet rset1 = statement1.executeQuery();
-
-			while (rset1.next())
-			{
-				int fortId = rset1.getInt("fortId");
-				PreparedStatement statement2 = con.prepareStatement("SELECT id, npcId, x, y, z, heading, castleId FROM fort_spawnlist Where fortId = ? and spawnType = ? ORDER BY id");
-				statement2.setInt(1, getFort().getFortId());
-				statement2.setInt(2, 3);
-				ResultSet rset2 = statement2.executeQuery();
-				
-				L2Spawn spawnDat;
-				L2NpcTemplate template1;
-				_specialEnvoysSpawns = new FastList<L2Spawn>();
-				while (rset2.next())
-				{
-					int castleId = rset2.getInt("castleId");
-					int npcId = rset2.getInt("npcId");
-					template1 = NpcTable.getInstance().getTemplate(npcId);
-					if (template1 != null)
-					{
-						spawnDat = new L2Spawn(template1);
-						spawnDat.setAmount(1);
-						spawnDat.setLocx(rset2.getInt("x"));
-						spawnDat.setLocy(rset2.getInt("y"));
-						spawnDat.setLocz(rset2.getInt("z"));
-						spawnDat.setHeading(rset2.getInt("heading"));
-						spawnDat.setRespawnDelay(60);
-						_specialEnvoysSpawns.add(spawnDat);
-						_envoyCastles.put(npcId, castleId);
-					}
-					else
-					{
-						_log.warning("FortManager.initSpecialEnvoys: Data missing in NPC table for ID: "
-					        + rset2.getInt("npcId") + ".");
-					}
-				}
-				rset2.close();
-				statement2.close();
-				_specialEnvoys.put(fortId, _specialEnvoysSpawns);
-			}
-			rset1.close();
-			statement1.close();
-		}
-		catch (Exception e)
-		{
-			// problem with initializing spawn, go to next one
-			_log.warning("FortManager.initSpecialEnvoys: Spawn could not be initialized: "
-			        + e.getMessage());
-			e.printStackTrace();
-		}
-		finally
-		{
-			try
-			{
-				con.close();
-			}
-			catch (Exception e)
-			{
-            	_log.warning(""+e.getMessage());
-            	e.printStackTrace();
-			}
-		}
-    }
-    public void spawnNpcCommanders()
-    {
-    	FastList<L2Spawn> monsterList = _npcCommanders.get(getFort().getFortId());
-    	if (monsterList != null)
-		{
-			for (L2Spawn spawnDat : monsterList)
-			{
-				spawnDat.doSpawn();
-				spawnDat.startRespawn();
-			}
-		}
-    }
-    public void despawnNpcCommanders()
-    {
-    	FastList<L2Spawn> monsterList = _npcCommanders.get(getFort().getFortId());
-    	if (monsterList != null)
-		{
-			for (L2Spawn spawnDat : monsterList)
-			{
-				spawnDat.stopRespawn();
-				spawnDat.getLastSpawn().deleteMe();
-			}
-		}
-    }
-    public void spawnSuspiciousMerchant()
-    {
-    	FastList<L2Spawn> monsterList = _siegeNpcs.get(getFort().getFortId());
-    	if (monsterList != null)
-		{
-			for (L2Spawn spawnDat : monsterList)
-			{
-				spawnDat.doSpawn();
-				spawnDat.startRespawn();
-			}
-		}
-    }
-    public void despawnSuspiciousMerchant()
-    {
-    	FastList<L2Spawn> monsterList = _siegeNpcs.get(getFort().getFortId());
-    	if (monsterList != null)
-		{
-			for (L2Spawn spawnDat : monsterList)
-			{
-				spawnDat.stopRespawn();
-				spawnDat.getLastSpawn().deleteMe();
-			}
-		}
-    }
-    public void spawnSpecialEnvoys()
-    {
-    	FastList<L2Spawn> monsterList = _specialEnvoys.get(getFort().getFortId());
-    	if (monsterList != null)
-		{
-			for (L2Spawn spawnDat : monsterList)
-			{
-				spawnDat.doSpawn();
-				spawnDat.startRespawn();
-			}
-		}
-    }
-	public void despawnSpecialEnvoys()
-	{
-		FastList<L2Spawn> monsterList = _specialEnvoys.get(getFort().getFortId());
-		if (monsterList != null)
-		{
-			for (L2Spawn spawnDat : monsterList)
-			{
-				spawnDat.stopRespawn();
-				spawnDat.getLastSpawn().deleteMe();
-			}
-		}
-	}
 	public int getEnvoyCastle(int npcId)
 	{
 		return _envoyCastles.get(npcId);

+ 0 - 2
L2_GameServer/java/net/sf/l2j/gameserver/instancemanager/ZoneManager.java

@@ -390,8 +390,6 @@ public class ZoneManager
 			}
 		}
 
-		GrandBossManager.getInstance().initZones();
-		
 		_log.info("Done: loaded " + zoneCount + " zones.");
 	}
 	

+ 28 - 18
L2_GameServer/java/net/sf/l2j/gameserver/model/entity/Castle.java

@@ -35,6 +35,7 @@ import net.sf.l2j.gameserver.datatables.DoorTable;
 import net.sf.l2j.gameserver.instancemanager.CastleManager;
 import net.sf.l2j.gameserver.instancemanager.CastleManorManager;
 import net.sf.l2j.gameserver.instancemanager.FortManager;
+import net.sf.l2j.gameserver.instancemanager.ZoneManager;
 import net.sf.l2j.gameserver.instancemanager.CastleManorManager.CropProcure;
 import net.sf.l2j.gameserver.instancemanager.CastleManorManager.SeedProduction;
 import net.sf.l2j.gameserver.model.L2Clan;
@@ -42,6 +43,7 @@ import net.sf.l2j.gameserver.model.L2Manor;
 import net.sf.l2j.gameserver.model.L2Object;
 import net.sf.l2j.gameserver.model.actor.instance.L2DoorInstance;
 import net.sf.l2j.gameserver.model.actor.instance.L2PcInstance;
+import net.sf.l2j.gameserver.model.zone.L2ZoneType;
 import net.sf.l2j.gameserver.model.zone.type.L2CastleTeleportZone;
 import net.sf.l2j.gameserver.model.zone.type.L2CastleZone;
 import net.sf.l2j.gameserver.network.serverpackets.PlaySound;
@@ -79,7 +81,7 @@ public class Castle
 	private int _taxPercent = 0;
 	private double _taxRate = 0;
 	private int _treasury = 0;
-	private L2CastleZone _zone;
+	private L2CastleZone _zone = null;
 	private L2CastleTeleportZone _teleZone;
 	private L2Clan _formerOwner = null;
 	private int _nbArtifact = 1;
@@ -399,7 +401,7 @@ public class Castle
 	 */
 	public void banishForeigners()
 	{
-		_zone.banishForeigners(getOwnerId());
+		getZone().banishForeigners(getOwnerId());
 	}
 	
 	/**
@@ -407,30 +409,38 @@ public class Castle
 	 */
 	public boolean checkIfInZone(int x, int y, int z)
 	{
-		return _zone.isInsideZone(x, y, z);
-	}
-	
-	/**
-	 * Sets this castles zone
-	 * @param zone
-	 */
-	public void setZone(L2CastleZone zone)
-	{
-		_zone = zone;
+		return getZone().isInsideZone(x, y, z);
 	}
 	
 	public L2CastleZone getZone()
 	{
+		if (_zone == null)
+		{
+			for (L2ZoneType zone : ZoneManager.getInstance().getAllZones())
+			{
+				if (zone instanceof L2CastleZone && ((L2CastleZone)zone).getCastleId() == getCastleId())
+				{
+					_zone = (L2CastleZone)zone;
+					break;
+				}
+			}
+		}
 		return _zone;
 	}
 	
-	public void setTeleZone(L2CastleTeleportZone zone)
-	{
-		_teleZone = zone;
-	}
-	
 	public L2CastleTeleportZone getTeleZone()
 	{
+		if (_teleZone == null)
+		{
+			for (L2ZoneType zone : ZoneManager.getInstance().getAllZones())
+			{
+				if (zone instanceof L2CastleTeleportZone && ((L2CastleTeleportZone)zone).getCastleId() == getCastleId())
+				{
+					_teleZone = (L2CastleTeleportZone)zone;
+					break;
+				}
+			}
+		}
 		return _teleZone;
 	}
 	
@@ -446,7 +456,7 @@ public class Castle
 	 */
 	public double getDistance(L2Object obj)
 	{
-		return _zone.getDistanceToZone(obj);
+		return getZone().getDistanceToZone(obj);
 	}
 	
 	public void closeDoor(L2PcInstance activeChar, int doorId)

+ 350 - 20
L2_GameServer/java/net/sf/l2j/gameserver/model/entity/Fort.java

@@ -14,6 +14,7 @@
  */
 package net.sf.l2j.gameserver.model.entity;
 
+import java.sql.Connection;
 import java.sql.PreparedStatement;
 import java.sql.ResultSet;
 import java.util.Calendar;
@@ -30,19 +31,25 @@ import net.sf.l2j.gameserver.FortUpdater;
 import net.sf.l2j.gameserver.ThreadPoolManager;
 import net.sf.l2j.gameserver.datatables.ClanTable;
 import net.sf.l2j.gameserver.datatables.DoorTable;
+import net.sf.l2j.gameserver.datatables.NpcTable;
+import net.sf.l2j.gameserver.datatables.SpawnTable;
 import net.sf.l2j.gameserver.datatables.StaticObjects;
 import net.sf.l2j.gameserver.instancemanager.FortManager;
+import net.sf.l2j.gameserver.instancemanager.ZoneManager;
 import net.sf.l2j.gameserver.model.L2Clan;
 import net.sf.l2j.gameserver.model.L2Object;
+import net.sf.l2j.gameserver.model.L2Spawn;
 import net.sf.l2j.gameserver.model.L2World;
 import net.sf.l2j.gameserver.model.actor.instance.L2DoorInstance;
 import net.sf.l2j.gameserver.model.actor.instance.L2PcInstance;
 import net.sf.l2j.gameserver.model.actor.instance.L2StaticObjectInstance;
+import net.sf.l2j.gameserver.model.zone.L2ZoneType;
 import net.sf.l2j.gameserver.model.zone.type.L2FortZone;
 import net.sf.l2j.gameserver.network.SystemMessageId;
 import net.sf.l2j.gameserver.network.serverpackets.PlaySound;
 import net.sf.l2j.gameserver.network.serverpackets.PledgeShowInfoUpdate;
 import net.sf.l2j.gameserver.network.serverpackets.SystemMessage;
+import net.sf.l2j.gameserver.templates.chars.L2NpcTemplate;
 
 public class Fort
 {
@@ -56,7 +63,6 @@ public class Fort
 	private List<String> _doorDefault = new FastList<String>();
 	private List<String> _flagPoleStats = new FastList<String>();
 	private String _name = "";
-	private FortManager	_spawnManager;
 	private FortSiege _siege = null;
 	private Calendar _siegeDate;
 	private Calendar _lastOwnedTime;
@@ -66,6 +72,10 @@ public class Fort
 	private int _state = 0;
 	private int _castleId = 0;
 	private FastMap<Integer, FortFunction> _function;
+	// Spawn Data
+	protected FastList<L2Spawn> _siegeNpcs = new FastList<L2Spawn>();
+	protected FastList<L2Spawn> _npcCommanders = new FastList<L2Spawn>();
+	protected FastList<L2Spawn> _specialEnvoys = new FastList<L2Spawn>();
 	
 	/** Fortress Functions */
 	public static final int FUNC_TELEPORT = 1;
@@ -255,7 +265,17 @@ public class Fort
 			setVisibleFlag(true);
 			loadFunctions();
 		}
-		_spawnManager = new FortManager(this);
+		initNpcs(); // load and spawn npcs (Always spawned)
+		initSiegeNpcs(); // load suspicious merchants (Despawned 10mins before siege)
+		spawnNpcs(_siegeNpcs);// spawn suspicious merchants
+		initNpcCommanders(); // npc Commanders (not monsters) (Spawned during siege)
+		spawnNpcs(_npcCommanders); // spawn npc Commanders
+		initSpecialEnvoys(); // envoys from castles  (Spawned after fort taken)
+		if (getOwnerClan() != null && getFortState() == 0)
+		{
+			spawnNpcs(_specialEnvoys);
+			ThreadPoolManager.getInstance().scheduleGeneral(new ScheduleSpecialEnvoysDeSpawn(this), 1*60*60*1000); // Prepare 1hr task for special envoys despawn
+		}
 	}
 		
 	/** Return function with id */
@@ -282,7 +302,7 @@ public class Fort
 				// if state not decided, change state to indenpendent
 				if (_fortInst.getFortState() == 0)
 					_fortInst.setFortState(1,0);
-				_fortInst.getSpawnManager().despawnSpecialEnvoys();
+				_fortInst.despawnNpcs(_specialEnvoys);
 			}
 			catch (Exception e)
 			{
@@ -309,7 +329,7 @@ public class Fort
 	 */
 	public void banishForeigners()
 	{
-		_zone.banishForeigners(getOwnerClan());
+		getZone().banishForeigners(getOwnerClan());
 	}
 	
 	/**
@@ -317,20 +337,22 @@ public class Fort
 	 */
 	public boolean checkIfInZone(int x, int y, int z)
 	{
-		return _zone.isInsideZone(x, y, z);
-	}
-	
-	/**
-	 * Sets this forts zone
-	 * @param zone
-	 */
-	public void setZone(L2FortZone zone)
-	{
-		_zone = zone;
+		return getZone().isInsideZone(x, y, z);
 	}
 	
 	public L2FortZone getZone()
 	{
+		if (_zone == null)
+		{
+			for (L2ZoneType zone : ZoneManager.getInstance().getAllZones())
+			{
+				if (zone instanceof L2FortZone && ((L2FortZone)zone).getFortId() == getFortId())
+				{
+					_zone = (L2FortZone)zone;
+					break;
+				}
+			}
+		}
 		return _zone;
 	}
 	
@@ -341,7 +363,7 @@ public class Fort
 	 */
 	public double getDistance(L2Object obj)
 	{
-		return _zone.getDistanceToZone(obj);
+		return getZone().getDistanceToZone(obj);
 	}
 	
 	public void closeDoor(L2PcInstance activeChar, int doorId)
@@ -401,7 +423,7 @@ public class Fort
 		}
 		else
 		{
-			getSpawnManager().spawnSpecialEnvoys();
+			spawnNpcs(_specialEnvoys);
 			ThreadPoolManager.getInstance().scheduleGeneral(new ScheduleSpecialEnvoysDeSpawn(this), 1*60*60*1000); // Prepare 1hr task for special envoys despawn
 			// if clan have already fortress, remove it
 			if (clan.getHasFort() > 0)
@@ -1073,7 +1095,7 @@ public class Fort
 
 	public final int getCastleIdFromEnvoy(int npcId)
 	{
-		return getSpawnManager().getEnvoyCastle(npcId);
+		return FortManager.getInstance().getEnvoyCastle(npcId);
 	}
 	/**
 	 * @return Returns amount of barracks.
@@ -1082,9 +1104,317 @@ public class Fort
 	{
 		return getFortType() == 0 ? 3 : 5;
 	}
-	
-	public FortManager getSpawnManager()
+
+    public void spawnNpcs(FastList<L2Spawn> spawnList)
+    {
+		for (L2Spawn spawnDat : spawnList)
+		{
+			spawnDat.doSpawn();
+			spawnDat.startRespawn();
+		}
+    }
+    
+    public void despawnNpcs(FastList<L2Spawn> spawnList)
+    {
+		for (L2Spawn spawnDat : spawnList)
+		{
+			spawnDat.stopRespawn();
+			spawnDat.getLastSpawn().deleteMe();
+		}
+    }
+
+    /** FIXME: deleted
+    public void spawnSuspiciousMerchant()
+    {
+		for (L2Spawn spawnDat : _siegeNpcs)
+		{
+			spawnDat.doSpawn();
+			spawnDat.startRespawn();
+		}
+    }
+    
+    public void despawnSuspiciousMerchant()
+    {
+		for (L2Spawn spawnDat : _siegeNpcs)
+		{
+			spawnDat.stopRespawn();
+			spawnDat.getLastSpawn().deleteMe();
+		}
+    }
+
+    public void spawnNpcCommanders()
+    {
+    	for (L2Spawn spawnDat : _npcCommanders)
+		{
+			spawnDat.doSpawn();
+			spawnDat.startRespawn();
+		}
+    }
+    
+    public void despawnNpcCommanders()
+    {
+    	for (L2Spawn spawnDat : _npcCommanders)
+		{
+			spawnDat.stopRespawn();
+			spawnDat.getLastSpawn().deleteMe();
+		}
+    }
+
+    public void spawnSpecialEnvoys()
+    {
+    	for (L2Spawn spawnDat : _specialEnvoys)
+		{
+			spawnDat.doSpawn();
+			spawnDat.startRespawn();
+		}
+    }
+    
+	public void despawnSpecialEnvoys()
 	{
-		return _spawnManager;
+		for (L2Spawn spawnDat : _specialEnvoys)
+		{
+			spawnDat.stopRespawn();
+			spawnDat.getLastSpawn().deleteMe();
+		}
 	}
+	**/
+	
+    private void initNpcs()
+    {
+    	Connection con = null;
+
+    	try
+		{
+			con = L2DatabaseFactory.getInstance().getConnection();
+			PreparedStatement statement = con.prepareStatement("SELECT * FROM fort_spawnlist Where fortId = ? and spawnType = ? ");
+			statement.setInt(1, getFortId());
+			statement.setInt(2, 0);
+			ResultSet rset = statement.executeQuery();
+			
+			L2Spawn spawnDat;
+			L2NpcTemplate template;
+			
+			while (rset.next())
+			{
+				template = NpcTable.getInstance().getTemplate(rset.getInt("npcId"));
+				if (template != null)
+				{
+					spawnDat = new L2Spawn(template);
+					spawnDat.setAmount(1);
+					spawnDat.setLocx(rset.getInt("x"));
+					spawnDat.setLocy(rset.getInt("y"));
+					spawnDat.setLocz(rset.getInt("z"));
+					spawnDat.setHeading(rset.getInt("heading"));
+					spawnDat.setRespawnDelay(60);
+					SpawnTable.getInstance().addNewSpawn(spawnDat, false);
+					spawnDat.doSpawn();
+					spawnDat.startRespawn();
+				}
+				else
+				{
+					_log.warning("Fort " + getFortId() + " initNpcs: Data missing in NPC table for ID: "
+					        + rset.getInt("npcId") + ".");
+				}
+			}
+			
+			rset.close();
+			statement.close();
+		}
+		catch (Exception e)
+		{
+			// problem with initializing spawn, go to next one
+			_log.warning("Fort " + getFortId() + " initNpcs: Spawn could not be initialized: "+ e.getMessage());
+			e.printStackTrace();
+		}
+		finally
+		{
+			try
+			{
+				con.close();
+			}
+			catch (Exception e)
+			{
+            	_log.warning(""+e.getMessage());
+            	e.printStackTrace();
+			}
+		}
+    }
+
+    private void initSiegeNpcs()
+    {
+    	Connection con = null;
+    	_siegeNpcs.clear();
+    	try
+		{
+			con = L2DatabaseFactory.getInstance().getConnection();
+			PreparedStatement statement = con.prepareStatement("SELECT id, npcId, x, y, z, heading FROM fort_spawnlist Where fortId = ? and spawnType = ? ORDER BY id");
+			statement.setInt(1, getFortId());
+			statement.setInt(2, 2);
+			ResultSet rset = statement.executeQuery();
+			
+			L2Spawn spawnDat;
+			L2NpcTemplate template;
+			while (rset.next())
+			{
+				template = NpcTable.getInstance().getTemplate(rset.getInt("npcId"));
+				if (template != null)
+				{
+					spawnDat = new L2Spawn(template);
+					spawnDat.setAmount(1);
+					spawnDat.setLocx(rset.getInt("x"));
+					spawnDat.setLocy(rset.getInt("y"));
+					spawnDat.setLocz(rset.getInt("z"));
+					spawnDat.setHeading(rset.getInt("heading"));
+					spawnDat.setRespawnDelay(60);
+					_siegeNpcs.add(spawnDat);
+				}
+				else
+				{
+					_log.warning("Fort " + getFortId() + " initSiegeNpcs: Data missing in NPC table for ID: "
+				        + rset.getInt("npcId") + ".");
+				}
+			}
+			rset.close();
+			statement.close();
+		}
+		catch (Exception e)
+		{
+			// problem with initializing spawn, go to next one
+			_log.warning("Fort " + getFortId() + " initSiegeNpcs: Spawn could not be initialized: "
+			        + e.getMessage());
+			e.printStackTrace();
+		}
+		finally
+		{
+			try
+			{
+				con.close();
+			}
+			catch (Exception e)
+			{
+            	_log.warning(""+e.getMessage());
+            	e.printStackTrace();
+			}
+		}
+    }
+
+    private void initNpcCommanders()
+    {
+    	Connection con = null;
+    	_npcCommanders.clear();
+    	try
+		{
+			con = L2DatabaseFactory.getInstance().getConnection();
+			PreparedStatement statement = con.prepareStatement("SELECT id, npcId, x, y, z, heading FROM fort_spawnlist Where fortId = ? and spawnType = ? ORDER BY id");
+			statement.setInt(1, getFortId());
+			statement.setInt(2, 1);
+			ResultSet rset = statement.executeQuery();
+			
+			L2Spawn spawnDat;
+			L2NpcTemplate template;
+			while (rset.next())
+			{
+				template = NpcTable.getInstance().getTemplate(rset.getInt("npcId"));
+				if (template != null)
+				{
+					spawnDat = new L2Spawn(template);
+					spawnDat.setAmount(1);
+					spawnDat.setLocx(rset.getInt("x"));
+					spawnDat.setLocy(rset.getInt("y"));
+					spawnDat.setLocz(rset.getInt("z"));
+					spawnDat.setHeading(rset.getInt("heading"));
+					spawnDat.setRespawnDelay(60);
+					_npcCommanders.add(spawnDat);
+				}
+				else
+				{
+					_log.warning("Fort " + getFortId() + " initNpcCommanders: Data missing in NPC table for ID: "
+				        + rset.getInt("npcId") + ".");
+				}
+			}
+			rset.close();
+			statement.close();
+		}
+		catch (Exception e)
+		{
+			// problem with initializing spawn, go to next one
+			_log.warning("Fort " + getFortId() + " initNpcCommanders: Spawn could not be initialized: "
+			        + e.getMessage());
+			e.printStackTrace();
+		}
+		finally
+		{
+			try
+			{
+				con.close();
+			}
+			catch (Exception e)
+			{
+            	_log.warning(""+e.getMessage());
+            	e.printStackTrace();
+			}
+		}
+    }
+
+    private void initSpecialEnvoys()
+    {
+    	Connection con = null;
+    	_specialEnvoys.clear();
+    	FortManager.getInstance()._envoyCastles.clear();
+    	try
+		{
+			con = L2DatabaseFactory.getInstance().getConnection();
+			PreparedStatement statement = con.prepareStatement("SELECT id, npcId, x, y, z, heading, castleId FROM fort_spawnlist Where fortId = ? and spawnType = ? ORDER BY id");
+			statement.setInt(1, getFortId());
+			statement.setInt(2, 3);
+			ResultSet rset = statement.executeQuery();
+			
+			L2Spawn spawnDat;
+			L2NpcTemplate template;
+			while (rset.next())
+			{
+				int castleId = rset.getInt("castleId");
+				int npcId = rset.getInt("npcId");
+				template = NpcTable.getInstance().getTemplate(npcId);
+				if (template != null)
+				{
+					spawnDat = new L2Spawn(template);
+					spawnDat.setAmount(1);
+					spawnDat.setLocx(rset.getInt("x"));
+					spawnDat.setLocy(rset.getInt("y"));
+					spawnDat.setLocz(rset.getInt("z"));
+					spawnDat.setHeading(rset.getInt("heading"));
+					spawnDat.setRespawnDelay(60);
+					_specialEnvoys.add(spawnDat);
+					FortManager.getInstance()._envoyCastles.put(npcId, castleId);
+				}
+				else
+				{
+					_log.warning("Fort " + getFortId() + " initSpecialEnvoys: Data missing in NPC table for ID: "
+				        + rset.getInt("npcId") + ".");
+				}
+			}
+			rset.close();
+			statement.close();
+		}
+		catch (Exception e)
+		{
+			// problem with initializing spawn, go to next one
+			_log.warning("Fort " + getFortId() + " initSpecialEnvoys: Spawn could not be initialized: "
+			        + e.getMessage());
+			e.printStackTrace();
+		}
+		finally
+		{
+			try
+			{
+				con.close();
+			}
+			catch (Exception e)
+			{
+            	_log.warning(""+e.getMessage());
+            	e.printStackTrace();
+			}
+		}
+    }
 }

+ 4 - 4
L2_GameServer/java/net/sf/l2j/gameserver/model/entity/FortSiege.java

@@ -112,7 +112,7 @@ public class FortSiege
 				}
 				else if (_time == 600) // 10min remains
 				{
-					getFort().getSpawnManager().despawnSuspiciousMerchant();
+					getFort().despawnNpcs(getFort()._siegeNpcs);
 					announceToPlayer(new SystemMessage(SystemMessageId.S1_MINUTES_UNTIL_THE_FORTRESS_BATTLE_STARTS),10,false);
 					ThreadPoolManager.getInstance().scheduleGeneral(new ScheduleStartSiegeTask(_fortInst,300), 300000); // Prepare task for 5 minutes left.
 				}
@@ -176,7 +176,7 @@ public class FortSiege
 			
 			try
 			{
-				_fortInst.getSpawnManager().spawnSuspiciousMerchant();
+				_fortInst.spawnNpcs(_fortInst._siegeNpcs);
 			}
 			catch (Exception e)
 			{
@@ -258,7 +258,7 @@ public class FortSiege
 			saveFortSiege(); // Save fort specific data
 			clearSiegeClan(); // Clear siege clan from db
 			removeCommanders(); // Remove commander from this fort
-			getFort().getSpawnManager().spawnNpcCommanders(); // Spawn NPC commanders
+			getFort().spawnNpcs(getFort()._npcCommanders); // Spawn NPC commanders
 			getSiegeGuardManager().unspawnSiegeGuard(); // Remove all spawned siege guard from this fort
 			getFort().resetDoors(); // Respawn door to fort
 			ThreadPoolManager.getInstance().scheduleGeneral(new ScheduleSuspicoiusMerchantSpawn(getFort()), FortSiegeManager.getInstance().getSuspiciousMerchantRespawnDelay()*60*1000); // Prepare 3hr task for suspicious merchant respawn
@@ -291,7 +291,7 @@ public class FortSiege
 			loadSiegeClan(); // Load siege clan from db
 			updatePlayerSiegeStateFlags(false);
 			teleportPlayer(FortSiege.TeleportWhoType.Attacker, MapRegionTable.TeleportWhereType.Town); // Teleport to the closest town
-			getFort().getSpawnManager().despawnNpcCommanders(); // Despawn NPC commanders
+			getFort().despawnNpcs(getFort()._npcCommanders); // Despawn NPC commanders
 			spawnCommanders(); // Spawn commanders
 			getFort().resetDoors(); // Spawn door
 			spawnSiegeGuard(); // Spawn siege guard

+ 5 - 7
L2_GameServer/java/net/sf/l2j/gameserver/model/zone/type/L2CastleTeleportZone.java

@@ -15,10 +15,8 @@
 package net.sf.l2j.gameserver.model.zone.type;
 
 import javolution.util.FastList;
-import net.sf.l2j.gameserver.instancemanager.CastleManager;
 import net.sf.l2j.gameserver.model.L2Character;
 import net.sf.l2j.gameserver.model.actor.instance.L2PcInstance;
-import net.sf.l2j.gameserver.model.entity.Castle;
 import net.sf.l2j.gameserver.model.zone.L2ZoneType;
 import net.sf.l2j.util.Rnd;
 
@@ -32,7 +30,6 @@ public class L2CastleTeleportZone extends L2ZoneType
 {
 	private int[] _spawnLoc;
 	private int _castleId;
-	private Castle _castle;
 	
 	public L2CastleTeleportZone(int id)
 	{
@@ -47,10 +44,6 @@ public class L2CastleTeleportZone extends L2ZoneType
 		if (name.equals("castleId"))
 		{
 			_castleId = Integer.parseInt(value);
-			
-			// Register self to the correct castle
-			_castle = CastleManager.getInstance().getCastleById(_castleId);
-			_castle.setTeleZone(this);
 		}
 		else if (name.equals("spawnMinX"))
 		{
@@ -134,6 +127,11 @@ public class L2CastleTeleportZone extends L2ZoneType
 		}
 	}
 	
+	public int getCastleId()
+	{
+		return _castleId;
+	}
+	
 	/**
 	 * Get the spawn locations
 	 * @return

+ 16 - 8
L2_GameServer/java/net/sf/l2j/gameserver/model/zone/type/L2CastleZone.java

@@ -33,7 +33,7 @@ import net.sf.l2j.gameserver.network.serverpackets.SystemMessage;
 public class L2CastleZone extends L2ZoneType
 {
 	private int _castleId;
-	private Castle _castle;
+	private Castle _castle = null;
 	private int[] _spawnLoc;
 	
 	public L2CastleZone(int id)
@@ -49,10 +49,6 @@ public class L2CastleZone extends L2ZoneType
 		if (name.equals("castleId"))
 		{
 			_castleId = Integer.parseInt(value);
-			
-			// Register self to the correct castle
-			_castle = CastleManager.getInstance().getCastleById(_castleId);
-			_castle.setZone(this);
 		}
 		else if (name.equals("spawnX"))
 		{
@@ -73,7 +69,7 @@ public class L2CastleZone extends L2ZoneType
 	@Override
 	protected void onEnter(L2Character character)
 	{
-		if (_castle.getSiege().getIsInProgress())
+		if (getCastle() != null && getCastle().getSiege().getIsInProgress())
 		{
 			character.setInsideZone(L2Character.ZONE_PVP, true);
 			character.setInsideZone(L2Character.ZONE_SIEGE, true);
@@ -88,7 +84,7 @@ public class L2CastleZone extends L2ZoneType
 	@Override
 	protected void onExit(L2Character character)
 	{
-		if (_castle.getSiege().getIsInProgress())
+		if (getCastle() != null && getCastle().getSiege().getIsInProgress())
 		{
 			character.setInsideZone(L2Character.ZONE_PVP, false);
 			character.setInsideZone(L2Character.ZONE_SIEGE, false);
@@ -122,7 +118,7 @@ public class L2CastleZone extends L2ZoneType
 	
 	public void updateZoneStatusForCharactersInside()
 	{
-		if (_castle.getSiege().getIsInProgress())
+		if (getCastle() != null && getCastle().getSiege().getIsInProgress())
 		{
 			for (L2Character character : _characterList.values())
 			{
@@ -207,6 +203,18 @@ public class L2CastleZone extends L2ZoneType
 		return players;
 	}
 	
+	public int getCastleId()
+	{
+		return _castleId;
+	}
+	
+	private final Castle getCastle()
+	{
+		if (_castle == null)
+			_castle = CastleManager.getInstance().getCastleById(_castleId);
+		return _castle;
+	}
+	
 	/**
 	 * Get the castles defender spawn
 	 * @return

+ 18 - 11
L2_GameServer/java/net/sf/l2j/gameserver/model/zone/type/L2FortZone.java

@@ -40,7 +40,7 @@ import net.sf.l2j.gameserver.network.serverpackets.SystemMessage;
 public class L2FortZone extends L2ZoneType
 {
 	private int _fortId;
-	private Fort _fort;
+	private Fort _fort = null;
 	private int[] _spawnLoc;
 	
 	public L2FortZone(int id)
@@ -56,10 +56,6 @@ public class L2FortZone extends L2ZoneType
 		if (name.equals("fortId"))
 		{
 			_fortId = Integer.parseInt(value);
-			
-			// Register self to the correct fort
-			_fort = FortManager.getInstance().getFortById(_fortId);
-			_fort.setZone(this);
 		}
 		else if (name.equals("spawnX"))
 		{
@@ -81,7 +77,7 @@ public class L2FortZone extends L2ZoneType
 	protected void onEnter(L2Character character)
 	{
 		character.setInsideZone(L2Character.ZONE_FORT, true);
-		if (_fort.getSiege().getIsInProgress())
+		if (getFort() != null && getFort().getSiege().getIsInProgress())
 		{
 			character.setInsideZone(L2Character.ZONE_PVP, true);
 			character.setInsideZone(L2Character.ZONE_SIEGE, true);
@@ -95,7 +91,7 @@ public class L2FortZone extends L2ZoneType
 	protected void onExit(L2Character character)
 	{
 		character.setInsideZone(L2Character.ZONE_FORT, false);
-		if (_fort.getSiege().getIsInProgress())
+		if (getFort() != null && getFort().getSiege().getIsInProgress())
 		{
 			character.setInsideZone(L2Character.ZONE_PVP, false);
 			character.setInsideZone(L2Character.ZONE_SIEGE, false);
@@ -136,7 +132,7 @@ public class L2FortZone extends L2ZoneType
 	@Override
 	public void onDieInside(L2Character character)
 	{
-		if (_fort.getSiege().getIsInProgress())
+		if (getFort() != null && getFort().getSiege().getIsInProgress())
 		{
 			// debuff participants only if they die inside siege zone
 			if (character instanceof L2PcInstance && ((L2PcInstance) character).getClan() != null)
@@ -154,7 +150,7 @@ public class L2FortZone extends L2ZoneType
 				}
 				L2Clan clan;
 				L2Skill skill;
-				if (_fort.getOwnerClan() == ((L2PcInstance)character).getClan())
+				if (getFort().getOwnerClan() == ((L2PcInstance)character).getClan())
 				{
 					skill = SkillTable.getInstance().getInfo(5660, lvl);
 					if (skill != null)
@@ -162,7 +158,7 @@ public class L2FortZone extends L2ZoneType
 				}
 				else
 				{
-					for (L2SiegeClan siegeclan : _fort.getSiege().getAttackerClans())
+					for (L2SiegeClan siegeclan : getFort().getSiege().getAttackerClans())
 					{
 						if (siegeclan == null)
 							continue;
@@ -185,7 +181,7 @@ public class L2FortZone extends L2ZoneType
 
 	public void updateZoneStatusForCharactersInside()
 	{
-		if (_fort.getSiege().getIsInProgress())
+		if (getFort() != null && getFort().getSiege().getIsInProgress())
 		{
 			for (L2Character character : _characterList.values())
 			{
@@ -270,6 +266,17 @@ public class L2FortZone extends L2ZoneType
 		return players;
 	}
 	
+	public int getFortId()
+	{
+		return _fortId;
+	}
+	
+	private final Fort getFort()
+	{
+		if (_fort == null)
+			_fort = FortManager.getInstance().getFortById(_fortId);
+		return _fort;
+	}
 	/**
 	 * Get the forts defender spawn
 	 * @return