Browse Source

BETA: Convert door data to XML format.

Thanks to JIV for initial design.
GodKratos 13 years ago
parent
commit
b59b416fe0

+ 2 - 2
L2J_Server_BETA/java/com/l2jserver/gameserver/GeoEngine.java

@@ -100,7 +100,7 @@ public class GeoEngine extends GeoData
 	@Override
 	@Override
 	public boolean canSeeTarget(L2Object cha, Point3D target)
 	public boolean canSeeTarget(L2Object cha, Point3D target)
 	{
 	{
-		if (DoorTable.getInstance().checkIfDoorsBetween(cha.getX(), cha.getY(), cha.getZ(), target.getX(), target.getY(), target.getZ(), cha.getInstanceId()))
+		if (DoorTable.getInstance().checkIfDoorsBetween(cha.getX(), cha.getY(), cha.getZ(), target.getX(), target.getY(), target.getZ(), cha.getInstanceId(), true))
 			return false;
 			return false;
 		if (cha.getZ() >= target.getZ())
 		if (cha.getZ() >= target.getZ())
 			return canSeeTarget(cha.getX(), cha.getY(), cha.getZ(), target.getX(), target.getY(), target.getZ());
 			return canSeeTarget(cha.getX(), cha.getY(), cha.getZ(), target.getX(), target.getY(), target.getZ());
@@ -126,7 +126,7 @@ public class GeoEngine extends GeoData
 			z += 30; // well they don't move closer to balcony fence at the moment :(
 			z += 30; // well they don't move closer to balcony fence at the moment :(
 		int z2 = target.getZ() + 45;
 		int z2 = target.getZ() + 45;
 		if (!(target instanceof L2DoorInstance)
 		if (!(target instanceof L2DoorInstance)
-				&& DoorTable.getInstance().checkIfDoorsBetween(cha.getX(), cha.getY(), z, target.getX(), target.getY(), z2, cha.getInstanceId()))
+				&& DoorTable.getInstance().checkIfDoorsBetween(cha.getX(), cha.getY(), z, target.getX(), target.getY(), z2, cha.getInstanceId(), true))
 			return false;
 			return false;
 		if (target instanceof L2DoorInstance)
 		if (target instanceof L2DoorInstance)
 			return true; // door coordinates are hinge coords..
 			return true; // door coordinates are hinge coords..

+ 139 - 374
L2J_Server_BETA/java/com/l2jserver/gameserver/datatables/DoorTable.java

@@ -16,445 +16,222 @@ package com.l2jserver.gameserver.datatables;
 
 
 import gnu.trove.map.hash.TIntObjectHashMap;
 import gnu.trove.map.hash.TIntObjectHashMap;
 
 
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.FileReader;
-import java.io.IOException;
-import java.io.LineNumberReader;
 import java.util.ArrayList;
 import java.util.ArrayList;
-import java.util.StringTokenizer;
-import java.util.logging.Level;
+import java.util.HashSet;
+import java.util.Set;
 import java.util.logging.Logger;
 import java.util.logging.Logger;
 
 
-import com.l2jserver.Config;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+
+import com.l2jserver.gameserver.engines.DocumentParser;
 import com.l2jserver.gameserver.idfactory.IdFactory;
 import com.l2jserver.gameserver.idfactory.IdFactory;
-import com.l2jserver.gameserver.instancemanager.ClanHallManager;
 import com.l2jserver.gameserver.instancemanager.InstanceManager;
 import com.l2jserver.gameserver.instancemanager.InstanceManager;
 import com.l2jserver.gameserver.instancemanager.MapRegionManager;
 import com.l2jserver.gameserver.instancemanager.MapRegionManager;
 import com.l2jserver.gameserver.model.StatsSet;
 import com.l2jserver.gameserver.model.StatsSet;
 import com.l2jserver.gameserver.model.actor.instance.L2DoorInstance;
 import com.l2jserver.gameserver.model.actor.instance.L2DoorInstance;
-import com.l2jserver.gameserver.model.actor.templates.L2CharTemplate;
-import com.l2jserver.gameserver.model.entity.ClanHall;
-import com.l2jserver.gameserver.model.entity.clanhall.SiegableHall;
+import com.l2jserver.gameserver.model.actor.templates.L2DoorTemplate;
 import com.l2jserver.gameserver.pathfinding.AbstractNodeLoc;
 import com.l2jserver.gameserver.pathfinding.AbstractNodeLoc;
 
 
-public class DoorTable
+public class DoorTable extends DocumentParser
 {
 {
 	private static final Logger _log = Logger.getLogger(DoorTable.class.getName());
 	private static final Logger _log = Logger.getLogger(DoorTable.class.getName());
 	
 	
-	private final TIntObjectHashMap<L2DoorInstance> _staticItems;
-	private final TIntObjectHashMap<ArrayList<L2DoorInstance>> _regions;
+	private final TIntObjectHashMap<L2DoorInstance> _doors = new TIntObjectHashMap<L2DoorInstance>();
+	private static final TIntObjectHashMap<Set<Integer>> _groups = new TIntObjectHashMap<Set<Integer>>();
+	private final TIntObjectHashMap<ArrayList<L2DoorInstance>> _regions = new TIntObjectHashMap<ArrayList<L2DoorInstance>>();
 	
 	
 	protected DoorTable()
 	protected DoorTable()
 	{
 	{
-		_staticItems = new TIntObjectHashMap<L2DoorInstance>();
-		_regions = new TIntObjectHashMap<ArrayList<L2DoorInstance>>();
-		parseData();
-		onStart();
+		load();
 	}
 	}
 	
 	
-	public void reloadAll()
+	@Override
+	public void load()
 	{
 	{
-		respawn();
+		parseDatapackFile("data/doorData.xml");
 	}
 	}
 	
 	
-	public void respawn()
+	public void reloadAll()
 	{
 	{
-		_staticItems.clear();
+		_doors.clear();
+		_groups.clear();
 		_regions.clear();
 		_regions.clear();
-		parseData();
+		load();
 	}
 	}
 	
 	
-	public void parseData()
+	@Override
+	protected void parseDocument()
 	{
 	{
-		final File doorData = new File(Config.DATAPACK_ROOT, "data/door.csv");
-		try (
-			FileReader fr = new FileReader(doorData);
-			BufferedReader br = new BufferedReader(fr);
-			LineNumberReader lnr = new LineNumberReader(br))
+		NamedNodeMap attrs;
+		Node att;
+		StatsSet set;
+		for (Node a = getCurrentDocument().getFirstChild(); a != null; a = a.getNextSibling())
 		{
 		{
-			String line = null;
-			_log.info("Searching clan halls doors:");
-			
-			while ((line = lnr.readLine()) != null)
+			if ("list".equalsIgnoreCase(a.getNodeName()))
 			{
 			{
-				if ((line.trim().length() == 0) || line.startsWith("#"))
+				for (Node b = a.getFirstChild(); b != null; b = b.getNextSibling())
 				{
 				{
-					continue;
+					if ("door".equalsIgnoreCase(b.getNodeName()))
+					{
+						attrs = b.getAttributes();
+						set = new StatsSet();
+						for (int i = 0; i < attrs.getLength(); i++)
+						{
+							att = attrs.item(i);
+							set.set(att.getNodeName(), att.getNodeValue());
+						}
+						makeDoor(set);
+					}
 				}
 				}
-				
-				L2DoorInstance door = parseList(line, false);
-				putDoor(door);
-				door.spawnMe(door.getX(), door.getY(), door.getZ());
 			}
 			}
-			
-			_log.info("DoorTable: Loaded " + _staticItems.size() + " Door Templates for " + _regions.size() + " regions.");
-		}
-		catch (FileNotFoundException e)
-		{
-			_log.warning("door.csv is missing in data folder");
-		}
-		catch (IOException e)
-		{
-			_log.log(Level.WARNING, "Error while creating door table " + e.getMessage(), e);
 		}
 		}
+		
+		_log.info("DoorTable: Loaded " + _doors.size() + " Door Templates for " + _regions.size() + " regions."); 
+	}
+	
+	public void insertCollisionData(StatsSet set)
+	{
+		int posX, posY, nodeX, nodeY, height;
+		height = set.getInteger("height");
+		String[] pos = set.getString("node1").split(",");
+		nodeX = Integer.parseInt(pos[0]);
+		nodeY = Integer.parseInt(pos[1]);
+		pos = set.getString("node2").split(",");
+		posX = Integer.parseInt(pos[0]);
+		posY = Integer.parseInt(pos[1]);
+		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);
 	}
 	}
 	
 	
 	/**
 	/**
-	 * Parses door list.
-	 * @param line string
-	 * @param commanderDoor whether the door is commander door (fortress)
-	 * @return created door instance
+	 * @param set
 	 */
 	 */
-	public static L2DoorInstance parseList(final String line, final boolean commanderDoor)
+	private void makeDoor(StatsSet set)
 	{
 	{
-		StringTokenizer st = new StringTokenizer(line, ";");
-		L2DoorInstance door = null;
-		try
-		{
-			String name = st.nextToken();
-			int id = Integer.parseInt(st.nextToken());
-			int x = Integer.parseInt(st.nextToken());
-			int y = Integer.parseInt(st.nextToken());
-			int z = Integer.parseInt(st.nextToken());
-			int rangeXMin = Integer.parseInt(st.nextToken());
-			int rangeYMin = Integer.parseInt(st.nextToken());
-			int rangeZMin = Integer.parseInt(st.nextToken());
-			int rangeXMax = Integer.parseInt(st.nextToken());
-			int rangeYMax = Integer.parseInt(st.nextToken());
-			int rangeZMax = Integer.parseInt(st.nextToken());
-			int hp = Integer.parseInt(st.nextToken());
-			int pdef = Integer.parseInt(st.nextToken());
-			int mdef = Integer.parseInt(st.nextToken());
-			int emitter = Integer.parseInt(st.nextToken());
-			boolean unlockable = false;
-			if (st.hasMoreTokens())
-			{
-				unlockable = Boolean.parseBoolean(st.nextToken());
-			}
-			boolean startOpen = false;
-			if (st.hasMoreTokens())
-			{
-				startOpen = Boolean.parseBoolean(st.nextToken());
-			}
-			boolean targetable = true;
-			if (st.hasMoreTokens())
-			{
-				targetable = Boolean.parseBoolean(st.nextToken());
-			}
-			int hallId = 0;
-			if (st.hasMoreTokens())
-			{
-				hallId = Integer.parseInt(st.nextToken());
-			}
-			
-			if (rangeXMin > rangeXMax)
-			{
-				_log.severe("Error in door data, XMin > XMax, ID:" + id);
-			}
-			if (rangeYMin > rangeYMax)
-			{
-				_log.severe("Error in door data, YMin > YMax, ID:" + id);
-			}
-			if (rangeZMin > rangeZMax)
-			{
-				_log.severe("Error in door data, ZMin > ZMax, ID:" + id);
-			}
-			int collisionRadius; // (max) radius for movement checks
-			if ((rangeXMax - rangeXMin) > (rangeYMax - rangeYMin))
-			{
-				collisionRadius = rangeYMax - rangeYMin;
-			}
-			else
-			{
-				collisionRadius = rangeXMax - rangeXMin;
-			}
-			
-			StatsSet npcDat = new StatsSet();
-			npcDat.set("npcId", id);
-			npcDat.set("level", 0);
-			npcDat.set("jClass", "door");
-			
-			npcDat.set("baseSTR", 0);
-			npcDat.set("baseCON", 0);
-			npcDat.set("baseDEX", 0);
-			npcDat.set("baseINT", 0);
-			npcDat.set("baseWIT", 0);
-			npcDat.set("baseMEN", 0);
-			
-			npcDat.set("baseShldDef", 0);
-			npcDat.set("baseShldRate", 0);
-			npcDat.set("baseAccCombat", 38);
-			npcDat.set("baseEvasRate", 38);
-			npcDat.set("baseCritRate", 38);
-			
-			// npcDat.set("name", "");
-			npcDat.set("collision_radius", collisionRadius);
-			npcDat.set("collision_height", rangeZMax - rangeZMin);
-			npcDat.set("sex", "male");
-			npcDat.set("type", "");
-			npcDat.set("baseAtkRange", 0);
-			npcDat.set("baseMpMax", 0);
-			npcDat.set("baseCpMax", 0);
-			npcDat.set("rewardExp", 0);
-			npcDat.set("rewardSp", 0);
-			npcDat.set("basePAtk", 0);
-			npcDat.set("baseMAtk", 0);
-			npcDat.set("basePAtkSpd", 0);
-			npcDat.set("aggroRange", 0);
-			npcDat.set("baseMAtkSpd", 0);
-			npcDat.set("rhand", 0);
-			npcDat.set("lhand", 0);
-			npcDat.set("armor", 0);
-			npcDat.set("baseWalkSpd", 0);
-			npcDat.set("baseRunSpd", 0);
-			npcDat.set("name", name);
-			npcDat.set("baseHpMax", hp);
-			npcDat.set("baseHpReg", 3.e-3f);
-			npcDat.set("baseMpReg", 3.e-3f);
-			npcDat.set("basePDef", pdef);
-			npcDat.set("baseMDef", mdef);
-			
-			L2CharTemplate template = new L2CharTemplate(npcDat);
-			door = new L2DoorInstance(IdFactory.getInstance().getNextId(), template, id, name, unlockable);
-			door.setRange(rangeXMin, rangeYMin, rangeZMin, rangeXMax, rangeYMax, rangeZMax);
-			door.setCurrentHpMp(door.getMaxHp(), door.getMaxMp());
-			door.setXYZInvisible(x, y, z);
-			door.setMapRegion(MapRegionManager.getInstance().getMapRegionLocId(x, y));
-			door.setEmitter(emitter);
-			door.setTargetable(targetable);
-			
-			if (hallId > 0)
-			{
-				ClanHall hall = ClanHallManager.getAllClanHalls().get(hallId);
-				if (hall != null)
-				{
-					door.setClanHall(hall);
-					hall.getDoors().add(door);
-					
-					if (hall.isSiegableHall())
-					{
-						((SiegableHall) hall).getDoorDefault().add(line);
-					}
-				}
-			}
-			
-			if (commanderDoor)
-			{
-				door.setIsCommanderDoor(startOpen);
-			}
-			else
-			{
-				door.setOpen(startOpen);
-			}
-		}
-		catch (Exception e)
-		{
-			_log.log(Level.SEVERE, "Error in door data at line: " + line, e);
-		}
-		return door;
+		insertCollisionData(set);
+		L2DoorTemplate template = new L2DoorTemplate(set);
+		L2DoorInstance door = new L2DoorInstance(IdFactory.getInstance().getNextId(), template, set);
+		door.setCurrentHp(door.getMaxHp());
+		door.spawnMe(template.posX, template.posY, template.posZ);
+		putDoor(door, MapRegionManager.getInstance().getMapRegionLocId(door.getX(), door.getY()));
 	}
 	}
-	
-	public L2DoorInstance getDoor(Integer id)
+
+	public L2DoorTemplate getDoorTemplate(int doorId)
 	{
 	{
-		return _staticItems.get(id);
+		return _doors.get(doorId).getTemplate();
 	}
 	}
 	
 	
-	public void putDoor(L2DoorInstance door)
+	public L2DoorInstance getDoor(int doorId)
+	{
+		return _doors.get(doorId);
+	}
+
+	public void putDoor(L2DoorInstance door, int region)
 	{
 	{
-		_staticItems.put(door.getDoorId(), door);
+		_doors.put(door.getDoorId(), door);
 		
 		
-		if (_regions.contains(door.getMapRegion()))
+		if (_regions.contains(region))
+			_regions.get(region).add(door);
+		else
 		{
 		{
-			_regions.get(door.getMapRegion()).add(door);
+			final ArrayList<L2DoorInstance> list = new ArrayList<L2DoorInstance>();
+			list.add(door);
+			_regions.put(region, list);
+		}
+	}
+
+	public static void addDoorGroup(String groupName, int doorId)
+	{
+		Set<Integer> set = _groups.get(groupName.hashCode());
+		if (set == null)
+		{
+			set = new HashSet<Integer>();
+			set.add(doorId);
+			_groups.put(groupName.hashCode(), set);
 		}
 		}
 		else
 		else
 		{
 		{
-			final ArrayList<L2DoorInstance> region = new ArrayList<L2DoorInstance>();
-			region.add(door);
-			_regions.put(door.getMapRegion(), region);
+			set.add(doorId);
 		}
 		}
 	}
 	}
 	
 	
-	public L2DoorInstance[] getDoors()
+	public static Set<Integer> getDoorsByGroup(String groupName)
 	{
 	{
-		return _staticItems.values(new L2DoorInstance[0]);
+		return _groups.get(groupName.hashCode());
 	}
 	}
 	
 	
-	/**
-	 * Performs a check and sets up a scheduled task for those doors that require auto opening/closing.
-	 */
-	public void checkAutoOpen()
+	public L2DoorInstance[] getDoors()
 	{
 	{
-		for (L2DoorInstance doorInst : getDoors())
-		{
-			// Tower of Insolence (open_time 120 seconds)
-			// TODO: (close_time 120 seconds & random_time 120 seconds)
-			if (doorInst.getDoorName().startsWith("toi_"))
-			{
-				doorInst.setAutoActionDelay(120000);
-			}
-			
-			// Devil Isle (open_time 120 seconds)
-			// TODO: (close_time 120 seconds & random_time 30 seconds)
-			else if (doorInst.getDoorName().startsWith("di_"))
-			{
-				doorInst.setAutoActionDelay(120000);
-			}
-			
-			// Garden of Eva (open_time 300 seconds)
-			// TODO: (close_time 20 seconds & random_time 120 seconds)
-			else if (doorInst.getDoorName().startsWith("goe_"))
-			{
-				doorInst.setAutoActionDelay(300000);
-			}
-			
-			// Kratei's Cube (open_time 20 seconds)
-			// TODO: (close_time 15 seconds & random_time 10 seconds)
-			else if (doorInst.getDoorName().startsWith("kc20_"))
-			{
-				doorInst.setAutoActionDelay(20000);
-			}
-			
-			// Kratei's Cube (open_time 30 seconds)
-			// TODO: (close_time 15 seconds & random_time 10 seconds)
-			else if (doorInst.getDoorName().startsWith("kc30_"))
-			{
-				doorInst.setAutoActionDelay(30000);
-			}
-			
-			// Kratei's Cube (open_time 25 seconds)
-			// TODO: (close_time 15 seconds & random_time 10 seconds)
-			else if (doorInst.getDoorName().startsWith("kc25_"))
-			{
-				doorInst.setAutoActionDelay(25000);
-			}
-			
-			// Kratei's Cube (open_time 15 seconds)
-			// TODO: (close_time 15 seconds & random_time 10 seconds)
-			else if (doorInst.getDoorName().startsWith("kc15_"))
-			{
-				doorInst.setAutoActionDelay(15000);
-			}
-			
-			// Kratei's Cube (open_time 10 seconds)
-			// TODO: (close_time 15 seconds & random_time 5 seconds)
-			else if (doorInst.getDoorName().startsWith("kc10_"))
-			{
-				doorInst.setAutoActionDelay(10000);
-			}
-			
-			// Kratei's Cube (open_time 10 seconds)
-			// TODO: (close_time 15 seconds & random_time 10 seconds)
-			else if (doorInst.getDoorName().startsWith("kc10b_"))
-			{
-				doorInst.setAutoActionDelay(10000);
-			}
-			
-			// Kratei's Cube (open_time 14 seconds)
-			// TODO: (close_time 15 seconds & random_time 10 seconds)
-			else if (doorInst.getDoorName().startsWith("kc14_"))
-			{
-				doorInst.setAutoActionDelay(14000);
-			}
-			
-			// Kratei's Cube (open_time 23 seconds)
-			// TODO: (close_time 15 seconds & random_time 10 seconds)
-			else if (doorInst.getDoorName().startsWith("kc23_"))
-			{
-				doorInst.setAutoActionDelay(23000);
-			}
-			
-			// Kratei's Cube (open_time 18 seconds)
-			// TODO: (close_time 15 seconds & random_time 10 seconds)
-			else if (doorInst.getDoorName().startsWith("kc18_"))
-			{
-				doorInst.setAutoActionDelay(18000);
-			}
-			
-			// Kratei's Cube (open_time 26 seconds)
-			// TODO: (close_time 15 seconds & random_time 10 seconds)
-			else if (doorInst.getDoorName().startsWith("kc26_"))
-			{
-				doorInst.setAutoActionDelay(26000);
-			}
-		}
+		return _doors.values(new L2DoorInstance[0]);
 	}
 	}
-	
+
 	public boolean checkIfDoorsBetween(AbstractNodeLoc start, AbstractNodeLoc end, int instanceId)
 	public boolean checkIfDoorsBetween(AbstractNodeLoc start, AbstractNodeLoc end, int instanceId)
 	{
 	{
 		return checkIfDoorsBetween(start.getX(), start.getY(), start.getZ(), end.getX(), end.getY(), end.getZ(), instanceId);
 		return checkIfDoorsBetween(start.getX(), start.getY(), start.getZ(), end.getX(), end.getY(), end.getZ(), instanceId);
 	}
 	}
 	
 	
 	public boolean checkIfDoorsBetween(int x, int y, int z, int tx, int ty, int tz, int instanceId)
 	public boolean checkIfDoorsBetween(int x, int y, int z, int tx, int ty, int tz, int instanceId)
+	{
+		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
+	 */
+	public boolean checkIfDoorsBetween(int x, int y, int z, int tx, int ty, int tz, int instanceId, boolean doubleFaceCheck)
 	{
 	{
 		ArrayList<L2DoorInstance> allDoors;
 		ArrayList<L2DoorInstance> allDoors;
-		if ((instanceId > 0) && (InstanceManager.getInstance().getInstance(instanceId) != null))
-		{
+		if (instanceId > 0 && InstanceManager.getInstance().getInstance(instanceId) != null)
 			allDoors = InstanceManager.getInstance().getInstance(instanceId).getDoors();
 			allDoors = InstanceManager.getInstance().getInstance(instanceId).getDoors();
-		}
 		else
 		else
-		{
 			allDoors = _regions.get(MapRegionManager.getInstance().getMapRegionLocId(x, y));
 			allDoors = _regions.get(MapRegionManager.getInstance().getMapRegionLocId(x, y));
-		}
 		
 		
 		if (allDoors == null)
 		if (allDoors == null)
-		{
 			return false;
 			return false;
-		}
 		
 		
 		for (L2DoorInstance doorInst : allDoors)
 		for (L2DoorInstance doorInst : allDoors)
 		{
 		{
-			if (doorInst.getXMax() == 0)
-			{
+			//check dead and open
+			if (doorInst.isDead() || doorInst.getOpen() || !doorInst.checkCollision() || doorInst.getX(0) == 0)
 				continue;
 				continue;
-			}
 			
 			
-			// line segment goes through box
-			// first basic checks to stop most calculations short
-			// phase 1, x
-			if (((x <= doorInst.getXMax()) && (tx >= doorInst.getXMin())) || ((tx <= doorInst.getXMax()) && (x >= doorInst.getXMin())))
+			boolean intersectFace = false;
+			for (int i = 0; i < 4; i++)
 			{
 			{
-				// phase 2, y
-				if (((y <= doorInst.getYMax()) && (ty >= doorInst.getYMin())) || ((ty <= doorInst.getYMax()) && (y >= doorInst.getYMin())))
+				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));
+				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)
 				{
 				{
-					// phase 3, basically only z remains but now we calculate it with another formula (by rage)
-					// in some cases the direct line check (only) in the beginning isn't sufficient,
-					// when char z changes a lot along the path
-					if ((doorInst.getCurrentHp() > 0) && !doorInst.getOpen())
+					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())
 					{
 					{
-						int px1 = doorInst.getXMin();
-						int py1 = doorInst.getYMin();
-						int pz1 = doorInst.getZMin();
-						int px2 = doorInst.getXMax();
-						int py2 = doorInst.getYMax();
-						int pz2 = doorInst.getZMax();
-						
-						int l = tx - x;
-						int m = ty - y;
-						int n = tz - z;
-						
-						int dk;
-						
-						if ((dk = ((doorInst.getA() * l) + (doorInst.getB() * m) + (doorInst.getC() * n))) == 0)
-						{
-							continue; // Parallel
-						}
-						
-						float p = (float) ((doorInst.getA() * x) + (doorInst.getB() * y) + (doorInst.getC() * z) + doorInst.getD()) / (float) dk;
-						
-						int fx = (int) (x - (l * p));
-						int fy = (int) (y - (m * p));
-						int fz = (int) (z - (n * p));
-						
-						if (((Math.min(x, tx) <= fx) && (fx <= Math.max(x, tx))) && ((Math.min(y, ty) <= fy) && (fy <= Math.max(y, ty))) && ((Math.min(z, tz) <= fz) && (fz <= Math.max(z, tz))))
-						{
-							if ((((fx >= px1) && (fx <= px2)) || ((fx >= px2) && (fx <= px1))) && (((fy >= py1) && (fy <= py2)) || ((fy >= py2) && (fy <= py1))) && (((fz >= pz1) && (fz <= pz2)) || ((fz >= pz2) && (fz <= pz1))))
-							{
-								return true; // Door between
-							}
-						}
+						if (!doubleFaceCheck || intersectFace)
+							return true;
+						intersectFace = true;
 					}
 					}
 				}
 				}
 			}
 			}
@@ -462,18 +239,6 @@ public class DoorTable
 		return false;
 		return false;
 	}
 	}
 	
 	
-	private void onStart()
-	{
-		try
-		{
-			checkAutoOpen();
-		}
-		catch (NullPointerException e)
-		{
-			_log.log(Level.WARNING, "There are errors in your Door.csv file. Update door.csv", e);
-		}
-	}
-	
 	public static DoorTable getInstance()
 	public static DoorTable getInstance()
 	{
 	{
 		return SingletonHolder._instance;
 		return SingletonHolder._instance;

+ 275 - 292
L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/instance/L2DoorInstance.java

@@ -15,31 +15,35 @@
 package com.l2jserver.gameserver.model.actor.instance;
 package com.l2jserver.gameserver.model.actor.instance;
 
 
 import java.util.Collection;
 import java.util.Collection;
-import java.util.concurrent.ScheduledFuture;
-import java.util.logging.Level;
+import java.util.Set;
+import java.util.concurrent.Future;
 import java.util.logging.Logger;
 import java.util.logging.Logger;
 
 
 import javolution.util.FastList;
 import javolution.util.FastList;
 
 
-import com.l2jserver.Config;
 import com.l2jserver.gameserver.ThreadPoolManager;
 import com.l2jserver.gameserver.ThreadPoolManager;
 import com.l2jserver.gameserver.ai.L2CharacterAI;
 import com.l2jserver.gameserver.ai.L2CharacterAI;
 import com.l2jserver.gameserver.ai.L2DoorAI;
 import com.l2jserver.gameserver.ai.L2DoorAI;
+import com.l2jserver.gameserver.datatables.DoorTable;
 import com.l2jserver.gameserver.instancemanager.CastleManager;
 import com.l2jserver.gameserver.instancemanager.CastleManager;
+import com.l2jserver.gameserver.instancemanager.ClanHallManager;
 import com.l2jserver.gameserver.instancemanager.FortManager;
 import com.l2jserver.gameserver.instancemanager.FortManager;
+import com.l2jserver.gameserver.instancemanager.InstanceManager;
 import com.l2jserver.gameserver.instancemanager.TerritoryWarManager;
 import com.l2jserver.gameserver.instancemanager.TerritoryWarManager;
 import com.l2jserver.gameserver.model.L2CharPosition;
 import com.l2jserver.gameserver.model.L2CharPosition;
 import com.l2jserver.gameserver.model.L2Clan;
 import com.l2jserver.gameserver.model.L2Clan;
 import com.l2jserver.gameserver.model.L2Object;
 import com.l2jserver.gameserver.model.L2Object;
+import com.l2jserver.gameserver.model.StatsSet;
 import com.l2jserver.gameserver.model.actor.L2Character;
 import com.l2jserver.gameserver.model.actor.L2Character;
 import com.l2jserver.gameserver.model.actor.L2Playable;
 import com.l2jserver.gameserver.model.actor.L2Playable;
 import com.l2jserver.gameserver.model.actor.knownlist.DoorKnownList;
 import com.l2jserver.gameserver.model.actor.knownlist.DoorKnownList;
 import com.l2jserver.gameserver.model.actor.stat.DoorStat;
 import com.l2jserver.gameserver.model.actor.stat.DoorStat;
 import com.l2jserver.gameserver.model.actor.status.DoorStatus;
 import com.l2jserver.gameserver.model.actor.status.DoorStatus;
-import com.l2jserver.gameserver.model.actor.templates.L2CharTemplate;
+import com.l2jserver.gameserver.model.actor.templates.L2DoorTemplate;
 import com.l2jserver.gameserver.model.entity.Castle;
 import com.l2jserver.gameserver.model.entity.Castle;
 import com.l2jserver.gameserver.model.entity.ClanHall;
 import com.l2jserver.gameserver.model.entity.ClanHall;
 import com.l2jserver.gameserver.model.entity.Fort;
 import com.l2jserver.gameserver.model.entity.Fort;
+import com.l2jserver.gameserver.model.entity.Instance;
 import com.l2jserver.gameserver.model.entity.clanhall.SiegableHall;
 import com.l2jserver.gameserver.model.entity.clanhall.SiegableHall;
 import com.l2jserver.gameserver.model.items.L2Weapon;
 import com.l2jserver.gameserver.model.items.L2Weapon;
 import com.l2jserver.gameserver.model.items.instance.L2ItemInstance;
 import com.l2jserver.gameserver.model.items.instance.L2ItemInstance;
@@ -49,6 +53,7 @@ import com.l2jserver.gameserver.network.serverpackets.DoorStatusUpdate;
 import com.l2jserver.gameserver.network.serverpackets.OnEventTrigger;
 import com.l2jserver.gameserver.network.serverpackets.OnEventTrigger;
 import com.l2jserver.gameserver.network.serverpackets.StaticObject;
 import com.l2jserver.gameserver.network.serverpackets.StaticObject;
 import com.l2jserver.gameserver.network.serverpackets.SystemMessage;
 import com.l2jserver.gameserver.network.serverpackets.SystemMessage;
+import com.l2jserver.util.Rnd;
 
 
 /**
 /**
  * This class ...
  * This class ...
@@ -59,42 +64,66 @@ public class L2DoorInstance extends L2Character
 {
 {
 	protected static final Logger log = Logger.getLogger(L2DoorInstance.class.getName());
 	protected static final Logger log = Logger.getLogger(L2DoorInstance.class.getName());
 	
 	
+	private static final byte OPEN_BY_CLICK = 1;
+	private static final byte OPEN_BY_TIME = 2;
+	private static final byte OPEN_BY_ITEM = 4;
+	private static final byte OPEN_BY_SKILL = 8;
+	private static final byte OPEN_BY_CYCLE = 16;
+	
 	/** The castle index in the array of L2Castle this L2NpcInstance belongs to */
 	/** The castle index in the array of L2Castle this L2NpcInstance belongs to */
 	private int _castleIndex = -2;
 	private int _castleIndex = -2;
-	private int _mapRegion = -1;
 	/** The fort index in the array of L2Fort this L2NpcInstance belongs to */
 	/** The fort index in the array of L2Fort this L2NpcInstance belongs to */
 	private int _fortIndex = -2;
 	private int _fortIndex = -2;
-	
-	// when door is closed, the dimensions are
-	private int _rangeXMin = 0;
-	private int _rangeYMin = 0;
-	private int _rangeZMin = 0;
-	private int _rangeXMax = 0;
-	private int _rangeYMax = 0;
-	private int _rangeZMax = 0;
-	
-	// these variables assist in see-through calculation only
-	private int _A = 0;
-	private int _B = 0;
-	private int _C = 0;
-	private int _D = 0;
-	
-	protected final int _doorId;
-	protected final String _name;
-	private boolean _open;
-	private boolean _isCommanderDoor;
-	private final boolean _unlockable;
+	private ClanHall _clanHall;
+	private boolean _open = false;
 	private boolean _isAttackableDoor = false;
 	private boolean _isAttackableDoor = false;
-	private boolean _isWall = false; // is castle wall ?
-	private boolean _ShowHp = false;
+	private boolean _isTargetable;
+	private boolean _checkCollision;
+	private int _openType = 0;
 	private int _meshindex = 1;
 	private int _meshindex = 1;
-	private int _emitter = 0;
-	private boolean _targetable = true;
-	
-	private ClanHall _clanHall;
+	private int _level = 0;
+	int _closeTime = -1;
+	int _openTime = -1;
+	int _randomTime = -1;
+	// used for autoclose on open
+	private Future<?> _autoCloseTask;
 	
 	
-	protected int _autoActionDelay = -1;
-	private ScheduledFuture<?> _autoActionTask;
+	/**
+	 * @param objectId
+	 * @param template
+	 * @param data
+	 */
+	public L2DoorInstance(int objectId, L2DoorTemplate template, StatsSet data)
+	{
+		super(objectId, template);
+		setInstanceType(InstanceType.L2DoorInstance);
+		setIsInvul(false);
+		_isTargetable = data.getBool("targetable", true);
+		if (getGroupName() != null)
+			DoorTable.addDoorGroup(getGroupName(), getDoorId());
+		if (data.getString("default_status","close").equals("open"))
+			_open = true;
+		_closeTime = data.getInteger("close_time", -1);
+		_level = data.getInteger("level", 0);
+		_openType = data.getInteger("open_method", 0);
+		_checkCollision = data.getBool("check_collision", true);
+		if (isOpenableByTime())
+		{
+			_closeTime = data.getInteger("open_time");
+			_randomTime = data.getInteger("random_time", -1);
+			startTimerOpen();
+		}
+		int clanhallId = data.getInteger("clanhall_id", 0);
+		if(clanhallId > 0)
+		{
+			ClanHall hall = ClanHallManager.getAllClanHalls().get(clanhallId);
+			if(hall != null)
+			{
+				this.setClanHall(hall);
+				hall.getDoors().add(this);
+			}
+		}
+	}
 	
 	
 	/** This class may be created only by L2Character and only for AI */
 	/** This class may be created only by L2Character and only for AI */
 	public class AIAccessor extends L2Character.AIAccessor
 	public class AIAccessor extends L2Character.AIAccessor
@@ -150,71 +179,13 @@ public class L2DoorInstance extends L2Character
 		}
 		}
 		return ai;
 		return ai;
 	}
 	}
-	
-	class CloseTask implements Runnable
-	{
-		@Override
-		public void run()
-		{
-			try
-			{
-				onClose();
-			}
-			catch (Exception e)
-			{
-				_log.log(Level.SEVERE, "", e);
-			}
-		}
-	}
-	
-	/**
-	 * Manages the auto open and closing of a door.
-	 */
-	class AutoOpenClose implements Runnable
-	{
-		@Override
-		public void run()
-		{
-			try
-			{
-				String doorAction;
-				
-				if (!getOpen())
-				{
-					doorAction = "opened";
-					openMe();
-				}
-				else
-				{
-					doorAction = "closed";
-					closeMe();
-				}
-				
-				if (Config.DEBUG)
-					_log.info("Auto " + doorAction + " door ID " + _doorId + " (" + _name + ") for " + (_autoActionDelay / 60000) + " minute(s).");
-			}
-			catch (Exception e)
-			{
-				_log.warning("Could not auto open/close door ID " + _doorId + " (" + _name + ")");
-			}
-		}
-	}
-	
-	/**
-	 * @param objectId 
-	 * @param template 
-	 * @param doorId 
-	 * @param name 
-	 * @param unlockable 
-	 */
-	public L2DoorInstance(int objectId, L2CharTemplate template, int doorId, String name, boolean unlockable)
+
+	private void startTimerOpen()
 	{
 	{
-		super(objectId, template);
-		setInstanceType(InstanceType.L2DoorInstance);
-		setIsInvul(false);
-		_doorId = doorId;
-		_name = name;
-		_unlockable = unlockable;
+		int delay = _open ? _openTime : _closeTime;
+		if (_randomTime > 0)
+			delay += Rnd.get(_randomTime);
+		ThreadPoolManager.getInstance().scheduleGeneral(new TimerOpen(), delay*1000);
 	}
 	}
 	
 	
 	@Override
 	@Override
@@ -234,6 +205,13 @@ public class L2DoorInstance extends L2Character
 	{
 	{
 		return (DoorStat) super.getStat();
 		return (DoorStat) super.getStat();
 	}
 	}
+
+	@Override
+	public L2DoorTemplate getTemplate()
+	{
+		return (L2DoorTemplate) super.getTemplate();
+		
+	}
 	
 	
 	@Override
 	@Override
 	public void initCharStat()
 	public void initCharStat()
@@ -252,16 +230,36 @@ public class L2DoorInstance extends L2Character
 	{
 	{
 		setStatus(new DoorStatus(this));
 		setStatus(new DoorStatus(this));
 	}
 	}
+
+	public final boolean isOpenableBySkill()
+	{
+		return (_openType & OPEN_BY_SKILL) != 0;
+	}
 	
 	
-	public final boolean isUnlockable()
+	public final boolean isOpenableByItem()
 	{
 	{
-		return _unlockable;
+		return (_openType & OPEN_BY_ITEM) != 0;
+	}
+	
+	public final boolean isOpenableByClick()
+	{
+		return (_openType & OPEN_BY_CLICK) != 0;
+	}
+	
+	public final boolean isOpenableByTime()
+	{
+		return (_openType & OPEN_BY_TIME) != 0;
+	}
+	
+	public final boolean isOpenableByCycle()
+	{
+		return (_openType & OPEN_BY_CYCLE) != 0;
 	}
 	}
 	
 	
 	@Override
 	@Override
 	public final int getLevel()
 	public final int getLevel()
 	{
 	{
-		return 1;
+		return _level;
 	}
 	}
 	
 	
 	/**
 	/**
@@ -269,7 +267,7 @@ public class L2DoorInstance extends L2Character
 	 */
 	 */
 	public int getDoorId()
 	public int getDoorId()
 	{
 	{
-		return _doorId;
+		return getTemplate().doorId;
 	}
 	}
 	
 	
 	/**
 	/**
@@ -279,30 +277,17 @@ public class L2DoorInstance extends L2Character
 	{
 	{
 		return _open;
 		return _open;
 	}
 	}
-	
+
 	/**
 	/**
 	 * @param open The open to set.
 	 * @param open The open to set.
 	 */
 	 */
 	public void setOpen(boolean open)
 	public void setOpen(boolean open)
 	{
 	{
 		_open = open;
 		_open = open;
-	}
-	
-	/**
-	 * @param val Used for Fortresses to determine if doors can be attacked during siege or not
-	 */
-	public void setIsCommanderDoor(boolean val)
-	{
-		_isCommanderDoor = val;
-	}
-	
-	/**
-	 * @return Doors that cannot be attacked during siege
-	 * these doors will be auto opened if u take control of all commanders buildings
-	 */
-	public boolean getIsCommanderDoor()
-	{
-		return _isCommanderDoor;
+		if (getChildId() > 0)
+		{
+			getSiblingDoor(getChildId()).notifyChildEvent(open);
+		}
 	}
 	}
 	
 	
 	public boolean getIsAttackableDoor()
 	public boolean getIsAttackableDoor()
@@ -312,7 +297,7 @@ public class L2DoorInstance extends L2Character
 	
 	
 	public boolean getIsShowHp()
 	public boolean getIsShowHp()
 	{
 	{
-		return _ShowHp;
+		return getTemplate().showHp;
 	}
 	}
 	
 	
 	public void setIsAttackableDoor(boolean val)
 	public void setIsAttackableDoor(boolean val)
@@ -320,38 +305,6 @@ public class L2DoorInstance extends L2Character
 		_isAttackableDoor = val;
 		_isAttackableDoor = val;
 	}
 	}
 	
 	
-	public void setIsShowHp(boolean val)
-	{
-		_ShowHp = val;
-	}
-	
-	/**
-	 * Sets the delay in milliseconds for automatic opening/closing
-	 * of this door instance.
-	 * <BR>
-	 * <B>Note:</B> A value of -1 cancels the auto open/close task.
-	 *
-	 * @param actionDelay
-	 */
-	public void setAutoActionDelay(int actionDelay)
-	{
-		if (_autoActionDelay == actionDelay)
-			return;
-		
-		if (actionDelay > -1)
-		{
-			AutoOpenClose ao = new AutoOpenClose();
-			ThreadPoolManager.getInstance().scheduleGeneralAtFixedRate(ao, actionDelay, actionDelay);
-		}
-		else
-		{
-			if (_autoActionTask != null)
-				_autoActionTask.cancel(false);
-		}
-		
-		_autoActionDelay = actionDelay;
-	}
-	
 	public int getDamage()
 	public int getDamage()
 	{
 	{
 		int dmg = 6 - (int) Math.ceil(getCurrentHp() / getMaxHp() * 6);
 		int dmg = 6 - (int) Math.ceil(getCurrentHp() / getMaxHp() * 6);
@@ -392,11 +345,11 @@ public class L2DoorInstance extends L2Character
 	
 	
 	public boolean isEnemy()
 	public boolean isEnemy()
 	{
 	{
-		if (getCastle() != null && getCastle().getCastleId() > 0 && getCastle().getZone().isActive())
+		if (getCastle() != null && getCastle().getCastleId() > 0 && getCastle().getZone().isActive() && getIsShowHp())
 			return true;
 			return true;
-		if (getFort() != null && getFort().getFortId() > 0 && getFort().getZone().isActive() && !getIsCommanderDoor())
+		if (getFort() != null && getFort().getFortId() > 0 && getFort().getZone().isActive() && getIsShowHp())
 			return true;
 			return true;
-		if(getClanHall() != null && getClanHall().isSiegableHall() && ((SiegableHall)getClanHall()).getSiegeZone().isActive())
+		if(getClanHall() != null && getClanHall().isSiegableHall() && ((SiegableHall)getClanHall()).getSiegeZone().isActive() && getIsShowHp())
 			return true;
 			return true;
 		return false;
 		return false;
 	}
 	}
@@ -404,12 +357,14 @@ public class L2DoorInstance extends L2Character
 	@Override
 	@Override
 	public boolean isAutoAttackable(L2Character attacker)
 	public boolean isAutoAttackable(L2Character attacker)
 	{
 	{
-		if (isUnlockable() && getFort() == null)
-			return true;
-		
 		// Doors can`t be attacked by NPCs
 		// Doors can`t be attacked by NPCs
 		if (!(attacker instanceof L2Playable))
 		if (!(attacker instanceof L2Playable))
 			return false;
 			return false;
+
+		if (getIsAttackableDoor())
+			return true;
+		if (!getIsShowHp())
+			return false;
 		
 		
 		L2PcInstance actingPlayer = attacker.getActingPlayer();
 		L2PcInstance actingPlayer = attacker.getActingPlayer();
 		
 		
@@ -423,7 +378,7 @@ public class L2DoorInstance extends L2Character
 		}
 		}
 		// Attackable  only during siege by everyone (not owner)
 		// Attackable  only during siege by everyone (not owner)
 		boolean isCastle = (getCastle() != null && getCastle().getCastleId() > 0 && getCastle().getZone().isActive());
 		boolean isCastle = (getCastle() != null && getCastle().getCastleId() > 0 && getCastle().getZone().isActive());
-		boolean isFort = (getFort() != null && getFort().getFortId() > 0 && getFort().getZone().isActive() && !getIsCommanderDoor());
+		boolean isFort = (getFort() != null && getFort().getFortId() > 0 && getFort().getZone().isActive());
 		int activeSiegeId = (getFort() != null ? getFort().getFortId() : (getCastle() != null ? getCastle().getCastleId() : 0));
 		int activeSiegeId = (getFort() != null ? getFort().getFortId() : (getCastle() != null ? getCastle().getCastleId() : 0));
 		
 		
 		if (TerritoryWarManager.getInstance().isTWInProgress())
 		if (TerritoryWarManager.getInstance().isTWInProgress())
@@ -444,7 +399,7 @@ public class L2DoorInstance extends L2Character
 			if (clan != null && clan.getClanId() == getCastle().getOwnerId())
 			if (clan != null && clan.getClanId() == getCastle().getOwnerId())
 				return false;
 				return false;
 		}
 		}
-		return (isCastle || isFort || getIsAttackableDoor());
+		return (isCastle || isFort);
 	}
 	}
 	
 	
 	public boolean isAttackable(L2Character attacker)
 	public boolean isAttackable(L2Character attacker)
@@ -457,28 +412,6 @@ public class L2DoorInstance extends L2Character
 	{
 	{
 	}
 	}
 	
 	
-	public int getDistanceToWatchObject(L2Object object)
-	{
-		if (!(object instanceof L2PcInstance))
-			return 0;
-		return 3000;
-	}
-	
-	/**
-	 * <B><U> Values </U> :</B><BR><BR>
-	 * <li> object is a L2PcInstance : 4000</li>
-	 * <li> object is not a L2PcInstance : 0 </li><BR><BR>
-	 * @param object 
-	 * @return the distance after which the object must be remove from _knownObject according to the type of the object.
-	 */
-	public int getDistanceToForgetObject(L2Object object)
-	{
-		if (!(object instanceof L2PcInstance))
-			return 0;
-		
-		return 4000;
-	}
-	
 	/**
 	/**
 	 * Return null.<BR><BR>
 	 * Return null.<BR><BR>
 	 */
 	 */
@@ -516,15 +449,18 @@ public class L2DoorInstance extends L2Character
 		StaticObject su = new StaticObject(this, false);
 		StaticObject su = new StaticObject(this, false);
 		DoorStatusUpdate dsu = new DoorStatusUpdate(this);
 		DoorStatusUpdate dsu = new DoorStatusUpdate(this);
 		OnEventTrigger oe = null;
 		OnEventTrigger oe = null;
-		if (_emitter > 0)
+		if (getEmitter() > 0)
 			oe = new OnEventTrigger(this, getOpen());
 			oe = new OnEventTrigger(this, getOpen());
 
 
 		for (L2PcInstance player : knownPlayers)
 		for (L2PcInstance player : knownPlayers)
 		{
 		{
 			if (player == null)
 			if (player == null)
 				continue;
 				continue;
+
+			if (player.isGM())
+				su = new StaticObject(this, true);
 			
 			
-			if ((getCastle() != null && getCastle().getCastleId() > 0) || (getFort() != null && getFort().getFortId() > 0 && !getIsCommanderDoor()))
+			if ((getCastle() != null && getCastle().getCastleId() > 0) || (getFort() != null && getFort().getFortId() > 0))
 				su = new StaticObject(this, true);
 				su = new StaticObject(this, true);
 			
 			
 			player.sendPacket(su);
 			player.sendPacket(su);
@@ -533,94 +469,102 @@ public class L2DoorInstance extends L2Character
 				player.sendPacket(oe);
 				player.sendPacket(oe);
 		}
 		}
 	}
 	}
-	
-	public void onOpen()
-	{
-		ThreadPoolManager.getInstance().scheduleGeneral(new CloseTask(), 60000);
-	}
-	
-	public void onClose()
+
+	public final void openMe()
 	{
 	{
-		closeMe();
+		if (getGroupName() != null)
+		{
+			manageGroupOpen(true, getGroupName());
+			return;
+		}
+		setOpen(true);
+		broadcastStatusUpdate();
+		startAutoCloseTask();
 	}
 	}
-	
+
 	public final void closeMe()
 	public final void closeMe()
 	{
 	{
+		//remove close task
+		Future<?> oldTask = _autoCloseTask;
+		if (oldTask != null)
+		{
+			_autoCloseTask = null;
+			oldTask.cancel(false);
+		}
+		if (getGroupName() != null)
+		{
+			manageGroupOpen(false, getGroupName());
+			return;
+		}
 		setOpen(false);
 		setOpen(false);
 		broadcastStatusUpdate();
 		broadcastStatusUpdate();
 	}
 	}
-	
-	public final void openMe()
+
+	private void manageGroupOpen(boolean open, String groupName)
 	{
 	{
-		setOpen(true);
-		broadcastStatusUpdate();
+		Set<Integer> set = DoorTable.getDoorsByGroup(groupName);
+		L2DoorInstance first = null;
+		for (Integer id : set)
+		{
+			L2DoorInstance door = getSiblingDoor(id);
+			if (first == null)
+				first = door;
+			
+			if (door.getOpen() != open)
+			{
+				door.setOpen(open);
+				door.broadcastStatusUpdate();
+			}
+		}
+		if (first != null && open)
+			first.startAutoCloseTask(); //only one from group
 	}
 	}
 	
 	
+	/**
+	 * Door notify child about open state change
+	 * @param open true if opened
+	 */
+	private void notifyChildEvent(boolean open)
+	{
+		byte openThis = open ? getTemplate().masterDoorOpen : getTemplate().masterDoorClose;
+		
+		if (openThis == 0)
+			return;
+		else if (openThis == 1)
+			openMe();
+		else if (openThis == -1)
+			closeMe();
+	}
+
 	@Override
 	@Override
 	public String toString()
 	public String toString()
 	{
 	{
-		return "door " + _doorId;
+		return getClass().getSimpleName() +"["+ getTemplate().doorId + "]("+getObjectId()+")";
 	}
 	}
 	
 	
 	public String getDoorName()
 	public String getDoorName()
 	{
 	{
-		return _name;
+		return getTemplate().name;
 	}
 	}
 	
 	
-	public int getXMin()
+	public int getX(int i)
 	{
 	{
-		return _rangeXMin;
+		return getTemplate().nodeX[i];
 	}
 	}
 	
 	
-	public int getYMin()
+	public int getY(int i)
 	{
 	{
-		return _rangeYMin;
+		return getTemplate().nodeY[i];
 	}
 	}
 	
 	
 	public int getZMin()
 	public int getZMin()
 	{
 	{
-		return _rangeZMin;
-	}
-	
-	public int getXMax()
-	{
-		return _rangeXMax;
-	}
-	
-	public int getYMax()
-	{
-		return _rangeYMax;
+		return getTemplate().nodeZ;
 	}
 	}
 	
 	
 	public int getZMax()
 	public int getZMax()
 	{
 	{
-		return _rangeZMax;
-	}
-	
-	public void setRange(int xMin, int yMin, int zMin, int xMax, int yMax, int zMax)
-	{
-		_rangeXMin = xMin;
-		_rangeYMin = yMin;
-		_rangeZMin = zMin;
-		
-		_rangeXMax = xMax;
-		_rangeYMax = yMax;
-		_rangeZMax = zMax;
-		
-		_A = _rangeYMax * (_rangeZMax - _rangeZMin) + _rangeYMin * (_rangeZMin - _rangeZMax);
-		_B = _rangeZMin * (_rangeXMax - _rangeXMin) + _rangeZMax * (_rangeXMin - _rangeXMax);
-		_C = _rangeXMin * (_rangeYMax - _rangeYMin) + _rangeXMin * (_rangeYMin - _rangeYMax);
-		_D = -1 * (_rangeXMin * (_rangeYMax * _rangeZMax - _rangeYMin * _rangeZMax) + _rangeXMax * (_rangeYMin * _rangeZMin - _rangeYMin * _rangeZMax) + _rangeXMin * (_rangeYMin * _rangeZMax - _rangeYMax * _rangeZMin));
-	}
-	
-	public int getMapRegion()
-	{
-		return _mapRegion;
-	}
-	
-	public void setMapRegion(int region)
-	{
-		_mapRegion = region;
+		return getTemplate().nodeZ + getTemplate().height;
 	}
 	}
 	
 	
 	public Collection<L2DefenderInstance> getKnownDefenders()
 	public Collection<L2DefenderInstance> getKnownDefenders()
@@ -636,44 +580,7 @@ public class L2DoorInstance extends L2Character
 	
 	
 		return result;
 		return result;
 	}
 	}
-	
-	public int getA()
-	{
-		return _A;
-	}
-	
-	public int getB()
-	{
-		return _B;
-	}
-	
-	public int getC()
-	{
-		return _C;
-	}
-	
-	public int getD()
-	{
-		return _D;
-	}
-	
-	/**
-	 * Set this door as a castle wall, can be damaged by siege golem only.
-	 * @param b 
-	 */
-	public void setIsWall(boolean b)
-	{
-		_isWall = b;
-	}
-	
-	/**
-	 * @return true if door is a castle wall and can be damaged by siege golem only.
-	 */
-	public boolean isWall()
-	{
-		return _isWall;
-	}
-	
+
 	public void setMeshIndex(int mesh)
 	public void setMeshIndex(int mesh)
 	{
 	{
 		_meshindex = mesh;
 		_meshindex = mesh;
@@ -684,30 +591,30 @@ public class L2DoorInstance extends L2Character
 		return _meshindex;
 		return _meshindex;
 	}
 	}
 	
 	
-	public void setEmitter(int emitter)
+	public int getEmitter()
 	{
 	{
-		_emitter = emitter;
+		return getTemplate().emmiter;
 	}
 	}
-	
-	public int getEmitter()
+
+	public boolean isWall()
 	{
 	{
-		return _emitter;
+		return getTemplate().isWall;
 	}
 	}
 	
 	
-	public void setTargetable(boolean targetable)
+	public String getGroupName()
 	{
 	{
-		_targetable = targetable;
+		return getTemplate().groupName;
 	}
 	}
 	
 	
-	public boolean getTargetable()
+	public int getChildId()
 	{
 	{
-		return _targetable;
+		return getTemplate().childDoorId;
 	}
 	}
 	
 	
 	@Override
 	@Override
 	public void reduceCurrentHp(double damage, L2Character attacker, boolean awake, boolean isDOT, L2Skill skill)
 	public void reduceCurrentHp(double damage, L2Character attacker, boolean awake, boolean isDOT, L2Skill skill)
 	{
 	{
-		if (_isWall && !(attacker instanceof L2SiegeSummonInstance))
+		if (isWall() && !(attacker instanceof L2SiegeSummonInstance))
 			return;
 			return;
 		
 		
 		super.reduceCurrentHp(damage, attacker, awake, isDOT, skill);
 		super.reduceCurrentHp(damage, attacker, awake, isDOT, skill);
@@ -725,7 +632,7 @@ public class L2DoorInstance extends L2Character
 		if (!super.doDie(killer))
 		if (!super.doDie(killer))
 			return false;
 			return false;
 		
 		
-		boolean isFort = (getFort() != null && getFort().getFortId() > 0 && getFort().getSiege().getIsInProgress()) && !getIsCommanderDoor();
+		boolean isFort = (getFort() != null && getFort().getFortId() > 0 && getFort().getSiege().getIsInProgress());
 		boolean isCastle = (getCastle() != null	&& getCastle().getCastleId() > 0 && getCastle().getSiege().getIsInProgress());
 		boolean isCastle = (getCastle() != null	&& getCastle().getCastleId() > 0 && getCastle().getSiege().getIsInProgress());
 		boolean isHall = (getClanHall() != null && getClanHall().isSiegableHall() && ((SiegableHall)getClanHall()).isInSiege());
 		boolean isHall = (getClanHall() != null && getClanHall().isSiegableHall() && ((SiegableHall)getClanHall()).isInSiege());
 		
 		
@@ -737,10 +644,86 @@ public class L2DoorInstance extends L2Character
 	@Override
 	@Override
 	public void sendInfo(L2PcInstance activeChar)
 	public void sendInfo(L2PcInstance activeChar)
 	{
 	{
-		if (_emitter > 0)
+		if (getEmitter() > 0)
 			activeChar.sendPacket(new OnEventTrigger(this, getOpen()));
 			activeChar.sendPacket(new OnEventTrigger(this, getOpen()));
 		
 		
-		activeChar.sendPacket(new StaticObject(this, false));
+		activeChar.sendPacket(new StaticObject(this, activeChar.isGM()));
+	}
+
+	public void setTargetable(boolean b)
+	{
+		_isTargetable = b;
+		broadcastStatusUpdate();
+	}
+	
+	@Override
+	public boolean isTargetable()
+	{
+		return _isTargetable;
+	}
+	
+	public boolean checkCollision()
+	{
+		return _checkCollision;
+	}
+	
+	/**
+	 * All doors are stored at DoorTable except instance doors
+	 * @param doorId
+	 * @return
+	 */
+	private L2DoorInstance getSiblingDoor(int doorId)
+	{
+		if (getInstanceId() == 0)
+			return DoorTable.getInstance().getDoor(doorId);
+
+		Instance inst = InstanceManager.getInstance().getInstance(getInstanceId());
+		if (inst != null)
+			return inst.getDoor(doorId);
+
+		return null; // 2 late
+	}
+	
+	private void startAutoCloseTask()
+	{
+		if (_closeTime < 0 || isOpenableByTime())
+			return;
+		Future<?> oldTask = _autoCloseTask;
+		if (oldTask != null)
+		{
+			_autoCloseTask = null;
+			oldTask.cancel(false);
+		}
+		_autoCloseTask = ThreadPoolManager.getInstance().scheduleGeneral(new AutoClose(), _closeTime * 1000);
+	}
+	
+	class AutoClose implements Runnable
+	{
+		@Override
+		public void run()
+		{
+			if (getOpen())
+				closeMe();
+		}
+	}
+	
+	class TimerOpen implements Runnable
+	{
+		@Override
+		public void run()
+		{
+			boolean open = getOpen();
+			if (open)
+				closeMe();
+			else
+				openMe();
+			
+			//_log.info("Door "+L2DoorInstance.this+ " switched state "+open);
+			int delay = open ? _closeTime : _openTime;
+			if (_randomTime > 0)
+				delay += Rnd.get(_randomTime);
+			ThreadPoolManager.getInstance().scheduleGeneral(this, delay*1000);
+		}
 	}
 	}
 	
 	
 	@Override
 	@Override

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

@@ -9172,8 +9172,8 @@ public final class L2PcInstance extends L2Playable
 			boolean isFort = (((L2DoorInstance) target).getFort() != null
 			boolean isFort = (((L2DoorInstance) target).getFort() != null
 					&& ((L2DoorInstance) target).getFort().getFortId() > 0
 					&& ((L2DoorInstance) target).getFort().getFortId() > 0
 					&& ((L2DoorInstance) target).getFort().getSiege().getIsInProgress()
 					&& ((L2DoorInstance) target).getFort().getSiege().getIsInProgress()
-					&& !((L2DoorInstance) target).getIsCommanderDoor());
-			if ((!isCastle && !isFort)&&(((L2DoorInstance) target).isUnlockable() && skill.getSkillType() != L2SkillType.UNLOCK))
+					&& !((L2DoorInstance) target).getIsShowHp());
+			if ((!isCastle && !isFort)&&(((L2DoorInstance) target).isOpenableBySkill() && skill.getSkillType() != L2SkillType.UNLOCK))
 				return false;
 				return false;
 		}
 		}
 		
 		

+ 1 - 1
L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/knownlist/DoorKnownList.java

@@ -45,6 +45,6 @@ public class DoorKnownList extends CharKnownList
 		if (object instanceof L2DefenderInstance) return 600;
 		if (object instanceof L2DefenderInstance) return 600;
 		if (!(object instanceof L2PcInstance))
 		if (!(object instanceof L2PcInstance))
 			return 0;
 			return 0;
-		return 3000;
+		return 3500;
 	}
 	}
 }
 }

+ 96 - 0
L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/templates/L2DoorTemplate.java

@@ -0,0 +1,96 @@
+/*
+ * 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.actor.templates;
+
+import com.l2jserver.gameserver.model.StatsSet;
+
+/**
+ * @author JIV
+ *
+ */
+public class L2DoorTemplate extends L2CharTemplate
+{
+	public final int doorId;
+	public final int nodeX[];
+	public final int nodeY[];
+	public final int nodeZ;
+	public final int height;
+	public final int posX;
+	public final int posY;
+	public final int posZ;
+	public final int emmiter;
+	public final int childDoorId;
+	public final String name;
+	public final String groupName;
+	public final boolean showHp;
+	public final boolean isWall;
+	// -1 close,  0 nothing, 1 open
+	public final byte masterDoorClose;
+	public final byte masterDoorOpen;
+	
+	public L2DoorTemplate(StatsSet set)
+	{
+		super(set);
+		
+		//stats
+		doorId = set.getInteger("id");
+		name = set.getString("name");
+
+		//position
+		String[] pos = set.getString("pos").split(";");
+		posX = Integer.parseInt(pos[0]);
+		posY = Integer.parseInt(pos[1]);
+		posZ = Integer.parseInt(pos[2]);
+		height = set.getInteger("height");
+		
+		// TODO: move to geodata system by creating door zones and load there
+		nodeZ = set.getInteger("nodeZ");
+		nodeX = new int[4]; // 4 * x
+		nodeY = new int[4]; // 4 * y
+		for (int i = 0; i < 4; i++)
+		{
+			String split[] = set.getString("node"+(i+1)).split(",");
+			nodeX[i] = Integer.parseInt(split[0]);
+			nodeY[i] = Integer.parseInt(split[1]);
+		}
+		
+		//optional
+		emmiter = set.getInteger("emitter_id", 0);
+		showHp = set.getBool("hp_showable", true);
+		isWall = set.getBool("is_wall", false);
+		groupName = set.getString("group", null);
+		
+		childDoorId = set.getInteger("child_id_event", -1);
+		// true if door is opening
+		String masterevent = set.getString("master_close_event", "act_nothing");
+		if (masterevent.equals("act_open"))
+			masterDoorClose = 1;
+		else if (masterevent.equals("act_close"))
+			masterDoorClose = -1;
+		else
+			masterDoorClose = 0;
+		//#2
+		masterevent = set.getString("master_open_event", "act_nothing");
+		if (masterevent.equals("act_open"))
+			masterDoorOpen = 1;
+		else if (masterevent.equals("act_close"))
+			masterDoorOpen = -1;
+		else
+			masterDoorOpen = 0;
+		
+		
+	}
+	
+}

+ 30 - 46
L2J_Server_BETA/java/com/l2jserver/gameserver/model/entity/Castle.java

@@ -79,7 +79,6 @@ public class Castle
 	
 	
 	private int _castleId = 0;
 	private int _castleId = 0;
 	private List<L2DoorInstance> _doors = new ArrayList<>();
 	private List<L2DoorInstance> _doors = new ArrayList<>();
-	private List<String> _doorDefault = new ArrayList<>();
 	private String _name = "";
 	private String _name = "";
 	private int _ownerId = 0;
 	private int _ownerId = 0;
 	private Siege _siege = null;
 	private Siege _siege = null;
@@ -256,7 +255,6 @@ public class Castle
 		 * if (_castleId == 7 || castleId == 9) // Goddard and Schuttgart _nbArtifact = 2;
 		 * if (_castleId == 7 || castleId == 9) // Goddard and Schuttgart _nbArtifact = 2;
 		 */
 		 */
 		load();
 		load();
-		loadDoor();
 		_function = new FastMap<Integer, CastleFunction>();
 		_function = new FastMap<Integer, CastleFunction>();
 		final List<L2SkillLearn> residentialSkills = SkillTreesData.getInstance().getAvailableResidentialSkills(castleId);
 		final List<L2SkillLearn> residentialSkills = SkillTreesData.getInstance().getAvailableResidentialSkills(castleId);
 		for (L2SkillLearn s : residentialSkills)
 		for (L2SkillLearn s : residentialSkills)
@@ -669,20 +667,18 @@ public class Castle
 	 */
 	 */
 	public void spawnDoor(boolean isDoorWeak)
 	public void spawnDoor(boolean isDoorWeak)
 	{
 	{
-		for (int i = 0; i < getDoors().size(); i++)
+		for (L2DoorInstance door : _doors)
 		{
 		{
-			L2DoorInstance door = getDoors().get(i);
-			if (door.getCurrentHp() <= 0)
+			if (door.isDead())
 			{
 			{
-				door.decayMe(); // Kill current if not killed already
-				door = DoorTable.parseList(_doorDefault.get(i), false);
-				DoorTable.getInstance().putDoor(door); // Readd the new door to the DoorTable By Erb
+				door.doRevive();
 				if (isDoorWeak)
 				if (isDoorWeak)
 					door.setCurrentHp(door.getMaxHp() / 2);
 					door.setCurrentHp(door.getMaxHp() / 2);
-				door.spawnMe(door.getX(), door.getY(), door.getZ());
-				getDoors().set(i, door);
+				else
+					door.setCurrentHp(door.getMaxHp());
 			}
 			}
-			else if (door.getOpen())
+			
+			if (door.getOpen())
 				door.closeMe();
 				door.closeMe();
 		}
 		}
 		loadDoorUpgrade(); // Check for any upgrade the doors may have
 		loadDoorUpgrade(); // Check for any upgrade the doors may have
@@ -855,47 +851,23 @@ public class Castle
 		}
 		}
 		return true;
 		return true;
 	}
 	}
-	
+
 	public void activateInstance()
 	public void activateInstance()
 	{
 	{
-		for (final L2DoorInstance door : _doors)
-		{
-			door.spawnMe(door.getX(), door.getY(), door.getZ());
-		}
+		loadDoor();
 	}
 	}
 	
 	
 	// This method loads castle door data from database
 	// This method loads castle door data from database
 	private void loadDoor()
 	private void loadDoor()
 	{
 	{
-		Connection con = null;
-		try
+		for (L2DoorInstance door : DoorTable.getInstance().getDoors())
 		{
 		{
-			con = L2DatabaseFactory.getInstance().getConnection();
-			PreparedStatement statement = con.prepareStatement("Select * from castle_door where castleId = ?");
-			statement.setInt(1, getCastleId());
-			ResultSet rs = statement.executeQuery();
-			
-			while (rs.next())
-			{
-				// Create list of the door default for use when respawning dead doors
-				_doorDefault.add(rs.getString("name") + ";" + rs.getInt("id") + ";" + rs.getInt("x") + ";" + rs.getInt("y") + ";" + rs.getInt("z") + ";" + rs.getInt("range_xmin") + ";" + rs.getInt("range_ymin") + ";" + rs.getInt("range_zmin") + ";" + rs.getInt("range_xmax") + ";" + rs.getInt("range_ymax") + ";" + rs.getInt("range_zmax") + ";" + rs.getInt("hp") + ";" + rs.getInt("pDef") + ";" + rs.getInt("mDef") + ";0");
-				
-				L2DoorInstance door = DoorTable.parseList(_doorDefault.get(_doorDefault.size() - 1), false);
-				door.setIsWall(rs.getBoolean("isWall"));
+			if (door.getCastle() != null && door.getCastle().getCastleId() == getCastleId())
 				_doors.add(door);
 				_doors.add(door);
-				DoorTable.getInstance().putDoor(door);
-			}
-			rs.close();
-			statement.close();
-		}
-		catch (Exception e)
-		{
-			_log.log(Level.WARNING, "Exception: loadCastleDoor(): " + e.getMessage(), e);
-		}
-		finally
-		{
-			L2DatabaseFactory.close(con);
 		}
 		}
+		
+		if (Config.DEBUG)
+			_log.info("Castle "+this+" loaded "+_doors.size()+" doors.");
 	}
 	}
 	
 	
 	// This method loads castle door upgrade data from database
 	// This method loads castle door upgrade data from database
@@ -904,9 +876,12 @@ public class Castle
 		Connection con = null;
 		Connection con = null;
 		try
 		try
 		{
 		{
+			StringBuilder doorIds = new StringBuilder(100);
+			for (L2DoorInstance door : getDoors())
+				doorIds.append(door.getDoorId()).append(",");
+			doorIds.deleteCharAt(doorIds.length()-1);
 			con = L2DatabaseFactory.getInstance().getConnection();
 			con = L2DatabaseFactory.getInstance().getConnection();
-			PreparedStatement statement = con.prepareStatement("SELECT * FROM castle_doorupgrade WHERE doorId IN (SELECT Id FROM castle_door WHERE castleId = ?)");
-			statement.setInt(1, getCastleId());
+			PreparedStatement statement = con.prepareStatement("Select * from castle_doorupgrade where doorId in ("+doorIds.toString()+")");
 			ResultSet rs = statement.executeQuery();
 			ResultSet rs = statement.executeQuery();
 			
 			
 			while (rs.next())
 			while (rs.next())
@@ -931,9 +906,12 @@ public class Castle
 		Connection con = null;
 		Connection con = null;
 		try
 		try
 		{
 		{
+			StringBuilder doorIds = new StringBuilder(100);
+			for (L2DoorInstance door : getDoors())
+				doorIds.append(door.getDoorId()).append(",");
+			doorIds.deleteCharAt(doorIds.length()-1);
 			con = L2DatabaseFactory.getInstance().getConnection();
 			con = L2DatabaseFactory.getInstance().getConnection();
-			PreparedStatement statement = con.prepareStatement("delete from castle_doorupgrade where doorId in (select id from castle_door where castleId=?)");
-			statement.setInt(1, getCastleId());
+			PreparedStatement statement = con.prepareStatement("delete from castle_doorupgrade where doorId in ("+doorIds.toString()+")");
 			statement.execute();
 			statement.execute();
 			statement.close();
 			statement.close();
 		}
 		}
@@ -1659,4 +1637,10 @@ public class Castle
 			L2DatabaseFactory.close(con);
 			L2DatabaseFactory.close(con);
 		}
 		}
 	}
 	}
+	
+	@Override
+	public String toString()
+	{
+		return _name+"("+_castleId+")";
+	}
 }
 }

+ 4 - 5
L2J_Server_BETA/java/com/l2jserver/gameserver/model/entity/ClanHall.java

@@ -17,12 +17,11 @@ package com.l2jserver.gameserver.model.entity;
 import java.sql.Connection;
 import java.sql.Connection;
 import java.sql.PreparedStatement;
 import java.sql.PreparedStatement;
 import java.sql.ResultSet;
 import java.sql.ResultSet;
-import java.util.List;
+import java.util.ArrayList;
 import java.util.Map;
 import java.util.Map;
 import java.util.logging.Level;
 import java.util.logging.Level;
 import java.util.logging.Logger;
 import java.util.logging.Logger;
 
 
-import javolution.util.FastList;
 import javolution.util.FastMap;
 import javolution.util.FastMap;
 
 
 import com.l2jserver.Config;
 import com.l2jserver.Config;
@@ -42,7 +41,7 @@ public abstract class ClanHall
 	protected static final Logger _log = Logger.getLogger(ClanHall.class.getName());
 	protected static final Logger _log = Logger.getLogger(ClanHall.class.getName());
 	
 	
 	private int _clanHallId;
 	private int _clanHallId;
-	private List<L2DoorInstance> _doors;
+	private ArrayList<L2DoorInstance> _doors;
 	private String _name;
 	private String _name;
 	private int _ownerId;
 	private int _ownerId;
 	private String _desc;
 	private String _desc;
@@ -269,10 +268,10 @@ public abstract class ClanHall
 	/**
 	/**
 	 * @return all DoorInstance
 	 * @return all DoorInstance
 	 */
 	 */
-	public final List<L2DoorInstance> getDoors()
+	public final ArrayList<L2DoorInstance> getDoors()
 	{
 	{
 		if (_doors == null)
 		if (_doors == null)
-			_doors = new FastList<L2DoorInstance>();
+			_doors = new ArrayList<L2DoorInstance>();
 		return _doors;
 		return _doors;
 	}
 	}
 	
 	

+ 12 - 45
L2J_Server_BETA/java/com/l2jserver/gameserver/model/entity/Fort.java

@@ -20,6 +20,7 @@ import gnu.trove.procedure.TObjectProcedure;
 import java.sql.Connection;
 import java.sql.Connection;
 import java.sql.PreparedStatement;
 import java.sql.PreparedStatement;
 import java.sql.ResultSet;
 import java.sql.ResultSet;
+import java.util.ArrayList;
 import java.util.Calendar;
 import java.util.Calendar;
 import java.util.List;
 import java.util.List;
 import java.util.concurrent.ScheduledFuture;
 import java.util.concurrent.ScheduledFuture;
@@ -67,9 +68,8 @@ public class Fort
 	protected static final Logger _log = Logger.getLogger(Fort.class.getName());
 	protected static final Logger _log = Logger.getLogger(Fort.class.getName());
 	
 	
 	private int _fortId = 0;
 	private int _fortId = 0;
-	private List<L2DoorInstance> _doors = new FastList<L2DoorInstance>();
+	private List<L2DoorInstance> _doors = new ArrayList<L2DoorInstance>();
 	private L2StaticObjectInstance _flagPole = null;
 	private L2StaticObjectInstance _flagPole = null;
-	private List<String> _doorDefault = new FastList<String>();
 	private String _name = "";
 	private String _name = "";
 	private FortSiege _siege = null;
 	private FortSiege _siege = null;
 	private Calendar _siegeDate;
 	private Calendar _siegeDate;
@@ -246,7 +246,6 @@ public class Fort
 	{
 	{
 		_fortId = fortId;
 		_fortId = fortId;
 		load();
 		load();
-		loadDoor();
 		loadFlagPoles();
 		loadFlagPoles();
 		_function = new FastMap<Integer, FortFunction>();
 		_function = new FastMap<Integer, FortFunction>();
 		final List<L2SkillLearn> residentialSkills = SkillTreesData.getInstance().getAvailableResidentialSkills(fortId);
 		final List<L2SkillLearn> residentialSkills = SkillTreesData.getInstance().getAvailableResidentialSkills(fortId);
@@ -579,12 +578,11 @@ public class Fort
 	 */
 	 */
 	public void resetDoors()
 	public void resetDoors()
 	{
 	{
-		for (int i = 0; i < getDoors().size(); i++)
+		for (L2DoorInstance door : _doors)
 		{
 		{
-			L2DoorInstance door = getDoors().get(i);
 			if (door.getOpen())
 			if (door.getOpen())
 				door.closeMe();
 				door.closeMe();
-			if (door.getCurrentHp() <= 0)
+			if (door.isDead())
 				door.doRevive();
 				door.doRevive();
 			if (door.getCurrentHp() < door.getMaxHp())
 			if (door.getCurrentHp() < door.getMaxHp())
 				door.setCurrentHp(door.getMaxHp());
 				door.setCurrentHp(door.getMaxHp());
@@ -777,48 +775,19 @@ public class Fort
 	
 	
 	public void activateInstance()
 	public void activateInstance()
 	{
 	{
-		for (final L2DoorInstance door : _doors)
-		{
-			door.spawnMe(door.getX(), door.getY(), door.getZ());
-		}
+		loadDoor();
 	}
 	}
 	
 	
 	// This method loads fort door data from database
 	// This method loads fort door data from database
 	private void loadDoor()
 	private void loadDoor()
 	{
 	{
-		Connection con = null;
-		try
+		for (L2DoorInstance door : DoorTable.getInstance().getDoors())
 		{
 		{
-			con = L2DatabaseFactory.getInstance().getConnection();
-			PreparedStatement statement = con.prepareStatement("SELECT * FROM fort_staticobjects WHERE fortId = ? AND objectType = ?");
-			statement.setInt(1, getFortId());
-			statement.setInt(2, 0);
-			ResultSet rs = statement.executeQuery();
-			
-			while (rs.next())
-			{
-				// Create list of the door default for use when respawning dead doors
-				_doorDefault.add(rs.getString("name") + ";" + rs.getInt("id") + ";" + rs.getInt("x") + ";" + rs.getInt("y") + ";"
-						+ rs.getInt("z") + ";" + rs.getInt("range_xmin") + ";" + rs.getInt("range_ymin") + ";" + rs.getInt("range_zmin")
-						+ ";" + rs.getInt("range_xmax") + ";" + rs.getInt("range_ymax") + ";" + rs.getInt("range_zmax") + ";"
-						+ rs.getInt("hp") + ";" + rs.getInt("pDef") + ";" + rs.getInt("mDef") + ";0;" + rs.getBoolean("openType") + ";"
-						+ rs.getBoolean("commanderDoor"));
-				L2DoorInstance door;
-				_doors.add(door = DoorTable.parseList(_doorDefault.get(_doorDefault.size() - 1), true));
-				DoorTable.getInstance().putDoor(door);
-			}
-			
-			rs.close();
-			statement.close();
-		}
-		catch (Exception e)
-		{
-			_log.log(Level.WARNING, "Exception: loadFortDoor(): " + e.getMessage(), e);
-		}
-		finally
-		{
-			L2DatabaseFactory.close(con);
+			if (door.getFort() != null && door.getFort().getFortId() == getFortId())
+				_doors.add(door);
 		}
 		}
+		if (Config.DEBUG)
+			_log.info("Fort "+this+" loaded "+_doors.size()+" doors.");
 	}
 	}
 	
 	
 	private void loadFlagPoles()
 	private void loadFlagPoles()
@@ -844,9 +813,8 @@ public class Fort
 		try
 		try
 		{
 		{
 			con = L2DatabaseFactory.getInstance().getConnection();
 			con = L2DatabaseFactory.getInstance().getConnection();
-			PreparedStatement statement = con.prepareStatement("SELECT * FROM fort_doorupgrade WHERE doorId IN (SELECT Id FROM fort_staticobjects WHERE fortId = ? AND objectType = ?)");
+			PreparedStatement statement = con.prepareStatement("SELECT * FROM fort_doorupgrade WHERE fortId = ?");
 			statement.setInt(1, getFortId());
 			statement.setInt(1, getFortId());
-			statement.setInt(2, 0);
 			ResultSet rs = statement.executeQuery();
 			ResultSet rs = statement.executeQuery();
 			
 			
 			while (rs.next())
 			while (rs.next())
@@ -872,9 +840,8 @@ public class Fort
 		try
 		try
 		{
 		{
 			con = L2DatabaseFactory.getInstance().getConnection();
 			con = L2DatabaseFactory.getInstance().getConnection();
-			PreparedStatement statement = con.prepareStatement("DELETE FROM fort_doorupgrade WHERE doorId IN (SELECT id FROM fort_staticobjects WHERE fortId=? AND objectType = ?)");
+			PreparedStatement statement = con.prepareStatement("DELETE FROM fort_doorupgrade WHERE WHERE fortId = ?");
 			statement.setInt(1, getFortId());
 			statement.setInt(1, getFortId());
-			statement.setInt(2, 0);
 			statement.execute();
 			statement.execute();
 			statement.close();
 			statement.close();
 		}
 		}

+ 2 - 1
L2J_Server_BETA/java/com/l2jserver/gameserver/model/entity/FortSiege.java

@@ -628,9 +628,10 @@ public class FortSiege implements Siegable
 					// open doors in main building
 					// open doors in main building
 					for (L2DoorInstance door : getFort().getDoors())
 					for (L2DoorInstance door : getFort().getDoors())
 					{
 					{
-						if (!door.getIsCommanderDoor())
+						if (door.getIsShowHp())
 							continue;
 							continue;
 						
 						
+						//TODO this also opens control room door at big fort
 						door.openMe();
 						door.openMe();
 					}
 					}
 					getFort().getSiege().announceToPlayer(SystemMessage.getSystemMessage(SystemMessageId.ALL_BARRACKS_OCCUPIED));
 					getFort().getSiege().announceToPlayer(SystemMessage.getSystemMessage(SystemMessageId.ALL_BARRACKS_OCCUPIED));

+ 22 - 25
L2J_Server_BETA/java/com/l2jserver/gameserver/model/entity/Instance.java

@@ -15,6 +15,7 @@ import javax.xml.parsers.DocumentBuilderFactory;
 import javolution.util.FastList;
 import javolution.util.FastList;
 
 
 import org.w3c.dom.Document;
 import org.w3c.dom.Document;
+import org.w3c.dom.NamedNodeMap;
 import org.w3c.dom.Node;
 import org.w3c.dom.Node;
 
 
 import com.l2jserver.Config;
 import com.l2jserver.Config;
@@ -28,10 +29,12 @@ import com.l2jserver.gameserver.instancemanager.MapRegionManager;
 import com.l2jserver.gameserver.model.L2Spawn;
 import com.l2jserver.gameserver.model.L2Spawn;
 import com.l2jserver.gameserver.model.L2World;
 import com.l2jserver.gameserver.model.L2World;
 import com.l2jserver.gameserver.model.L2WorldRegion;
 import com.l2jserver.gameserver.model.L2WorldRegion;
+import com.l2jserver.gameserver.model.StatsSet;
 import com.l2jserver.gameserver.model.actor.L2Attackable;
 import com.l2jserver.gameserver.model.actor.L2Attackable;
 import com.l2jserver.gameserver.model.actor.L2Npc;
 import com.l2jserver.gameserver.model.actor.L2Npc;
 import com.l2jserver.gameserver.model.actor.instance.L2DoorInstance;
 import com.l2jserver.gameserver.model.actor.instance.L2DoorInstance;
 import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
 import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
+import com.l2jserver.gameserver.model.actor.templates.L2DoorTemplate;
 import com.l2jserver.gameserver.model.actor.templates.L2NpcTemplate;
 import com.l2jserver.gameserver.model.actor.templates.L2NpcTemplate;
 import com.l2jserver.gameserver.network.SystemMessageId;
 import com.l2jserver.gameserver.network.SystemMessageId;
 import com.l2jserver.gameserver.network.clientpackets.Say2;
 import com.l2jserver.gameserver.network.clientpackets.Say2;
@@ -223,10 +226,10 @@ public class Instance
 	
 	
 	/**
 	/**
 	 * Adds a door into the instance
 	 * Adds a door into the instance
-	 * @param doorId - from doors.csv
-	 * @param open - initial state of the door
+	 * @param doorId - from doorData.xml
+	 * @param set - statset for initializing door
 	 */
 	 */
-	private void addDoor(int doorId, boolean open)
+	private void addDoor(int doorId, StatsSet set)
 	{
 	{
 		if (_doors == null)
 		if (_doors == null)
 			_doors = new ArrayList<L2DoorInstance>(2);
 			_doors = new ArrayList<L2DoorInstance>(2);
@@ -240,25 +243,11 @@ public class Instance
 			}
 			}
 		}
 		}
 		
 		
-		L2DoorInstance temp = DoorTable.getInstance().getDoor(doorId);
-		L2DoorInstance newdoor = new L2DoorInstance(IdFactory.getInstance().getNextId(), temp.getTemplate(), temp.getDoorId(), temp.getName(), temp.isUnlockable());
+		L2DoorTemplate temp = DoorTable.getInstance().getDoorTemplate(doorId);
+		L2DoorInstance newdoor = new L2DoorInstance(IdFactory.getInstance().getNextId(), temp, set);
 		newdoor.setInstanceId(getId());
 		newdoor.setInstanceId(getId());
-		newdoor.setRange(temp.getXMin(), temp.getYMin(), temp.getZMin(), temp.getXMax(), temp.getYMax(), temp.getZMax());
-		try
-		{
-			newdoor.setMapRegion(MapRegionManager.getInstance().getMapRegionLocId(temp));
-		}
-		catch (Exception e)
-		{
-			_log.severe("Error in door data, ID:" + temp.getDoorId());
-		}
-		newdoor.getStatus().setCurrentHpMp(newdoor.getMaxHp(), newdoor.getMaxMp());
-		newdoor.setOpen(open);
-		newdoor.getPosition().setXYZInvisible(temp.getX(), temp.getY(), temp.getZ());
-		newdoor.spawnMe(newdoor.getX(), newdoor.getY(), newdoor.getZ());
-		newdoor.setEmitter(temp.getEmitter());
-		newdoor.setTargetable(temp.getTargetable());
-		newdoor.setMeshIndex(temp.getMeshIndex());
+		newdoor.setCurrentHp(newdoor.getMaxHp());
+		newdoor.spawnMe(temp.posX, temp.posY, temp.posZ);
 		_doors.add(newdoor);
 		_doors.add(newdoor);
 	}
 	}
 	
 	
@@ -471,13 +460,21 @@ public class Instance
 				for (Node d = n.getFirstChild(); d != null; d = d.getNextSibling())
 				for (Node d = n.getFirstChild(); d != null; d = d.getNextSibling())
 				{
 				{
 					int doorId = 0;
 					int doorId = 0;
-					boolean doorState = false;
 					if ("door".equalsIgnoreCase(d.getNodeName()))
 					if ("door".equalsIgnoreCase(d.getNodeName()))
 					{
 					{
 						doorId = Integer.parseInt(d.getAttributes().getNamedItem("doorId").getNodeValue());
 						doorId = Integer.parseInt(d.getAttributes().getNamedItem("doorId").getNodeValue());
-						if (d.getAttributes().getNamedItem("open") != null)
-							doorState = Boolean.parseBoolean(d.getAttributes().getNamedItem("open").getNodeValue());
-						addDoor(doorId, doorState);
+						StatsSet set = new StatsSet();
+						for (Node bean = d.getFirstChild(); bean != null; bean = bean.getNextSibling())
+						{
+							if ("set".equalsIgnoreCase(bean.getNodeName()))
+							{
+								NamedNodeMap attrs = bean.getAttributes();
+								String setname = attrs.getNamedItem("name").getNodeValue();
+								String value = attrs.getNamedItem("val").getNodeValue();
+								set.set(setname, value);
+							}
+						}
+						addDoor(doorId, set);
 					}
 					}
 				}
 				}
 			}
 			}

+ 7 - 21
L2J_Server_BETA/java/com/l2jserver/gameserver/model/entity/clanhall/SiegableHall.java

@@ -17,13 +17,9 @@ package com.l2jserver.gameserver.model.entity.clanhall;
 import java.sql.Connection;
 import java.sql.Connection;
 import java.sql.PreparedStatement;
 import java.sql.PreparedStatement;
 import java.util.Calendar;
 import java.util.Calendar;
-import java.util.List;
 import java.util.logging.Level;
 import java.util.logging.Level;
 
 
-import javolution.util.FastList;
-
 import com.l2jserver.L2DatabaseFactory;
 import com.l2jserver.L2DatabaseFactory;
-import com.l2jserver.gameserver.datatables.DoorTable;
 import com.l2jserver.gameserver.model.L2Clan;
 import com.l2jserver.gameserver.model.L2Clan;
 import com.l2jserver.gameserver.model.L2SiegeClan;
 import com.l2jserver.gameserver.model.L2SiegeClan;
 import com.l2jserver.gameserver.model.L2SiegeClan.SiegeClanType;
 import com.l2jserver.gameserver.model.L2SiegeClan.SiegeClanType;
@@ -42,8 +38,6 @@ public final class SiegableHall extends ClanHall
 {	
 {	
 	private static final String SQL_SAVE = "UPDATE siegable_clanhall SET ownerId=?, nextSiege=? WHERE clanHallId=?";
 	private static final String SQL_SAVE = "UPDATE siegable_clanhall SET ownerId=?, nextSiege=? WHERE clanHallId=?";
 		
 		
-	protected List<String> _doorDefault;
-	
 	private Calendar _nextSiege;
 	private Calendar _nextSiege;
 	private long _siegeLength;
 	private long _siegeLength;
 	private int[] _scheduleConfig = {7,0,0,12,0};
 	private int[] _scheduleConfig = {7,0,0,12,0};
@@ -56,7 +50,6 @@ public final class SiegableHall extends ClanHall
 	public SiegableHall(StatsSet set)
 	public SiegableHall(StatsSet set)
 	{
 	{
 		super(set);
 		super(set);
-		_doorDefault = new FastList<String>();
 		_siegeLength = set.getLong("siegeLenght");
 		_siegeLength = set.getLong("siegeLenght");
 		String[] rawSchConfig = set.getString("scheduleConfig").split(";");
 		String[] rawSchConfig = set.getString("scheduleConfig").split(";");
 		if(rawSchConfig.length == 5)
 		if(rawSchConfig.length == 5)
@@ -83,11 +76,6 @@ public final class SiegableHall extends ClanHall
 		else
 		else
 			_nextSiege.setTimeInMillis(nextSiege);
 			_nextSiege.setTimeInMillis(nextSiege);
 	}
 	}
-			
-	public List<String> getDoorDefault()
-	{
-		return _doorDefault;
-	}
 	
 	
 	public void spawnDoor()
 	public void spawnDoor()
 	{
 	{
@@ -96,20 +84,18 @@ public final class SiegableHall extends ClanHall
 	
 	
 	public void spawnDoor(boolean isDoorWeak)
 	public void spawnDoor(boolean isDoorWeak)
 	{
 	{
-		for (int i = 0; i < getDoors().size(); i++)
+		for (L2DoorInstance door : this.getDoors())
 		{
 		{
-			L2DoorInstance door = getDoors().get(i);
-			if (door.getCurrentHp() <= 0)
+			if (door.isDead())
 			{
 			{
-				door.decayMe(); // Kill current if not killed already
-				door = DoorTable.parseList(_doorDefault.get(i), false);
-				DoorTable.getInstance().putDoor(door); //Readd the new door to the DoorTable By Erb
+				door.doRevive();
 				if (isDoorWeak)
 				if (isDoorWeak)
 					door.setCurrentHp(door.getMaxHp() / 2);
 					door.setCurrentHp(door.getMaxHp() / 2);
-				door.spawnMe(door.getX(), door.getY(), door.getZ());
-				getDoors().set(i, door);
+				else
+					door.setCurrentHp(door.getMaxHp());
 			}
 			}
-			else if (door.getOpen())
+			
+			if (door.getOpen())
 				door.closeMe();
 				door.closeMe();
 		}
 		}
 	}
 	}

+ 3 - 3
L2J_Server_BETA/java/com/l2jserver/gameserver/network/serverpackets/StaticObject.java

@@ -51,18 +51,18 @@ public class StaticObject extends L2GameServerPacket
 		_damageGrade = 0;
 		_damageGrade = 0;
 	}
 	}
 	
 	
-	public StaticObject(L2DoorInstance door, boolean showHp)
+	public StaticObject(L2DoorInstance door, boolean targetable)
 	{
 	{
 		_staticObjectId = door.getDoorId();
 		_staticObjectId = door.getDoorId();
 		_objectId = door.getObjectId();
 		_objectId = door.getObjectId();
 		_type = 1;
 		_type = 1;
-		_isTargetable = door.getTargetable();
+		_isTargetable = door.isTargetable() || targetable;
 		_meshIndex = door.getMeshIndex();
 		_meshIndex = door.getMeshIndex();
 		_isClosed = !door.getOpen();
 		_isClosed = !door.getOpen();
 		_isEnemy = door.isEnemy();
 		_isEnemy = door.isEnemy();
 		_maxHp = door.getMaxVisibleHp();
 		_maxHp = door.getMaxVisibleHp();
 		_currentHp = (int) door.getCurrentHp();
 		_currentHp = (int) door.getCurrentHp();
-		_showHp = door.getIsShowHp() || showHp;
+		_showHp = door.getIsShowHp();
 		_damageGrade = door.getDamage();
 		_damageGrade = door.getDamage();
 	}
 	}