Bladeren bron

Improving checkIfDoorsBetween(), thanks rage. The z-axis was
handled poorly. Still the direct line check doesn't handle
all cases.

Sami 16 jaren geleden
bovenliggende
commit
887665b96e

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

@@ -295,27 +295,52 @@ public class DoorTable
 			return false;
 		}
 		
+		// there are quite many doors, maybe they should be splitted
 		for (L2DoorInstance doorInst : getDoors())
 		{
-			if (doorInst.getMapRegion() != region)
+			if (doorInst.getMapRegion() != region) 
 				continue;
 			if (doorInst.getXMax() == 0)
 				continue;
 			
 			// line segment goes through box
-			// heavy approximation disabling some shooting angles especially near 2-piece doors
-			// but most calculations should stop short
+			// first basic checks to stop most calculations short
 			// phase 1, x
 			if (x <= doorInst.getXMax() && tx >= doorInst.getXMin() || tx <= doorInst.getXMax() && x >= doorInst.getXMin())
 			{
 				//phase 2, y
 				if (y <= doorInst.getYMax() && ty >= doorInst.getYMin() || ty <= doorInst.getYMax() && y >= doorInst.getYMin())
 				{
-					// phase 3, z (there's a small problem when the other is above/under door level..)
-					if (z >= doorInst.getZMin() && z <= doorInst.getZMax() && tz >= doorInst.getZMin() && tz <= doorInst.getZMax())
+					// 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() != 0) 
 					{
-						if (!(doorInst.getCurrentHp() <= 0 || doorInst.getOpen() == 0))
-							return true;
+						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 (((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
 					}
 				}
 			}

+ 22 - 1
L2_GameServer/java/net/sf/l2j/gameserver/model/actor/instance/L2DoorInstance.java

@@ -71,6 +71,12 @@ public class L2DoorInstance extends L2Character
     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;
@@ -470,7 +476,12 @@ public class L2DoorInstance extends L2Character
             html1.append("<tr><td>S.Y.L. Says:</td></tr>");
             html1.append("<tr><td>Current HP  "+getCurrentHp()+ "</td></tr>");
             html1.append("<tr><td>Max HP      "+getMaxHp()+"</td></tr>");
-
+            html1.append("<tr><td>Max X      "+getXMax()+"</td></tr>");
+            html1.append("<tr><td>Max Y      "+getYMax()+"</td></tr>");
+            html1.append("<tr><td>Max Z      "+getZMax()+"</td></tr>");
+            html1.append("<tr><td>Min X      "+getXMin()+"</td></tr>");
+            html1.append("<tr><td>Min Y      "+getYMin()+"</td></tr>");
+            html1.append("<tr><td>Min Z      "+getZMin()+"</td></tr>");
             html1.append("<tr><td>Object ID: " + getObjectId() + "</td></tr>");
             html1.append("<tr><td>Door ID:<br>"+getDoorId()+"</td></tr>");
             html1.append("<tr><td><br></td></tr>");
@@ -591,6 +602,11 @@ public class L2DoorInstance extends L2Character
     	_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()
@@ -618,4 +634,9 @@ public class L2DoorInstance extends L2Character
 		}
         return result;
     }
+
+    public int getA(){ return _A; }
+    public int getB(){ return _B; }
+    public int getC(){ return _C; }
+    public int getD(){ return _D; }
 }