|
@@ -18,137 +18,218 @@
|
|
|
*/
|
|
|
package com.l2jserver.gameserver;
|
|
|
|
|
|
-import java.io.FileInputStream;
|
|
|
-import java.lang.reflect.Constructor;
|
|
|
-import java.nio.file.Paths;
|
|
|
-import java.util.Properties;
|
|
|
+import java.io.FileNotFoundException;
|
|
|
+import java.nio.file.Path;
|
|
|
import java.util.logging.Level;
|
|
|
import java.util.logging.Logger;
|
|
|
|
|
|
import com.l2jserver.Config;
|
|
|
import com.l2jserver.gameserver.datatables.DoorTable;
|
|
|
-import com.l2jserver.gameserver.geoengine.Direction;
|
|
|
-import com.l2jserver.gameserver.geoengine.NullDriver;
|
|
|
-import com.l2jserver.gameserver.geoengine.abstraction.IGeoDriver;
|
|
|
import com.l2jserver.gameserver.model.L2Object;
|
|
|
+import com.l2jserver.gameserver.model.L2World;
|
|
|
import com.l2jserver.gameserver.model.Location;
|
|
|
import com.l2jserver.gameserver.model.interfaces.ILocational;
|
|
|
import com.l2jserver.gameserver.util.GeoUtils;
|
|
|
import com.l2jserver.gameserver.util.LinePointIterator;
|
|
|
import com.l2jserver.gameserver.util.LinePointIterator3D;
|
|
|
+import com.l2jserver.geodriver.Cell;
|
|
|
+import com.l2jserver.geodriver.GeoDriver;
|
|
|
|
|
|
|
|
|
* @author -Nemesiss-, HorridoJoho
|
|
|
*/
|
|
|
-public class GeoData implements IGeoDriver
|
|
|
+public class GeoData
|
|
|
{
|
|
|
private static final Logger LOGGER = Logger.getLogger(GeoData.class.getName());
|
|
|
+ private static final String FILE_NAME_FORMAT = "%d_%d.l2j";
|
|
|
private static final int ELEVATED_SEE_OVER_DISTANCE = 2;
|
|
|
private static final int MAX_SEE_OVER_HEIGHT = 48;
|
|
|
+ private static final int Z_DELTA_LIMIT = 100;
|
|
|
|
|
|
- private final IGeoDriver _driver;
|
|
|
+ private final GeoDriver _driver = new GeoDriver();
|
|
|
|
|
|
protected GeoData()
|
|
|
{
|
|
|
- if (Config.GEODATA > 0)
|
|
|
+ if (Config.GEODATA == 0)
|
|
|
{
|
|
|
- IGeoDriver driver = null;
|
|
|
- try
|
|
|
+ LOGGER.info(getClass().getSimpleName() + ": Disabled.");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ int loadedRegions = 0;
|
|
|
+ try
|
|
|
+ {
|
|
|
+ for (int regionX = L2World.TILE_X_MIN; regionX <= L2World.TILE_X_MAX; regionX++)
|
|
|
{
|
|
|
- Class<?> cls = Class.forName(Config.GEODATA_DRIVER);
|
|
|
- if (!IGeoDriver.class.isAssignableFrom(cls))
|
|
|
- {
|
|
|
- throw new ClassCastException("Geodata driver class needs to implement IGeoDriver!");
|
|
|
- }
|
|
|
- Constructor<?> ctor = cls.getConstructor(Properties.class);
|
|
|
- Properties props = new Properties();
|
|
|
- try (FileInputStream fis = new FileInputStream(Paths.get("config", "GeoDriver.properties").toString()))
|
|
|
+ for (int regionY = L2World.TILE_Y_MIN; regionY <= L2World.TILE_Y_MAX; regionY++)
|
|
|
{
|
|
|
- props.load(fis);
|
|
|
+ final Path geoFilePath = Config.GEODATA_PATH.resolve(String.format(FILE_NAME_FORMAT, regionX, regionY));
|
|
|
+ final Boolean loadFile = Config.GEODATA_REGIONS.get(regionX + "_" + regionY);
|
|
|
+ if (loadFile != null)
|
|
|
+ {
|
|
|
+ if (loadFile)
|
|
|
+ {
|
|
|
+ LOGGER.info(getClass().getSimpleName() + ": Loading " + geoFilePath.getFileName() + "...");
|
|
|
+ _driver.loadRegion(geoFilePath, regionX, regionY);
|
|
|
+ loadedRegions++;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else if (Config.TRY_LOAD_UNSPECIFIED_REGIONS)
|
|
|
+ {
|
|
|
+ try
|
|
|
+ {
|
|
|
+ LOGGER.info(getClass().getSimpleName() + ": Loading " + geoFilePath.getFileName() + "...");
|
|
|
+ _driver.loadRegion(geoFilePath, regionX, regionY);
|
|
|
+ loadedRegions++;
|
|
|
+ }
|
|
|
+ catch (Exception e)
|
|
|
+ {
|
|
|
+
|
|
|
+ if (!(e instanceof FileNotFoundException))
|
|
|
+ {
|
|
|
+ LOGGER.log(Level.WARNING, getClass().getSimpleName() + ": Failed to load " + geoFilePath.getFileName() + "!", e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
- driver = (IGeoDriver) ctor.newInstance(props);
|
|
|
}
|
|
|
- catch (Exception ex)
|
|
|
- {
|
|
|
- LOGGER.log(Level.SEVERE, "Failed to load geodata driver!", ex);
|
|
|
- System.exit(1);
|
|
|
- }
|
|
|
-
|
|
|
- _driver = driver;
|
|
|
}
|
|
|
- else
|
|
|
+ catch (Exception e)
|
|
|
{
|
|
|
- _driver = new NullDriver(null);
|
|
|
+ LOGGER.log(Level.SEVERE, getClass().getSimpleName() + ": Failed to load geodata!", e);
|
|
|
+ System.exit(1);
|
|
|
}
|
|
|
+
|
|
|
+ LOGGER.info(getClass().getSimpleName() + ": Loaded " + loadedRegions + " regions.");
|
|
|
}
|
|
|
|
|
|
- @Override
|
|
|
- public int getGeoX(int worldX)
|
|
|
+ public boolean hasGeoPos(int geoX, int geoY)
|
|
|
{
|
|
|
- return _driver.getGeoX(worldX);
|
|
|
+ return _driver.hasGeoPos(geoX, geoY);
|
|
|
}
|
|
|
|
|
|
- @Override
|
|
|
- public int getGeoY(int worldY)
|
|
|
+ public boolean checkNearestNswe(int geoX, int geoY, int worldZ, int nswe)
|
|
|
{
|
|
|
- return _driver.getGeoY(worldY);
|
|
|
+ return _driver.checkNearestNswe(geoX, geoY, worldZ, nswe);
|
|
|
}
|
|
|
|
|
|
- @Override
|
|
|
- public int getWorldX(int geoX)
|
|
|
+ public boolean checkNearestNswe(int geoX, int geoY, int worldZ, int nswe, int zDeltaLimit)
|
|
|
{
|
|
|
- return _driver.getWorldX(geoX);
|
|
|
+ return _driver.checkNearestNswe(geoX, geoY, worldZ, nswe, zDeltaLimit);
|
|
|
}
|
|
|
|
|
|
- @Override
|
|
|
- public int getWorldY(int geoY)
|
|
|
+ public boolean checkNearestNsweAntiCornerCut(int geoX, int geoY, int worldZ, int nswe)
|
|
|
{
|
|
|
- return _driver.getWorldY(geoY);
|
|
|
+ boolean can = true;
|
|
|
+ if ((nswe & Cell.NSWE_NORTH_EAST) != 0)
|
|
|
+ {
|
|
|
+
|
|
|
+ can = checkNearestNswe(geoX, geoY - 1, worldZ, Cell.NSWE_EAST) && checkNearestNswe(geoX + 1, geoY, worldZ, Cell.NSWE_NORTH);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (can && ((nswe & Cell.NSWE_NORTH_WEST) != 0))
|
|
|
+ {
|
|
|
+
|
|
|
+ can = checkNearestNswe(geoX, geoY - 1, worldZ, Cell.NSWE_WEST) && checkNearestNswe(geoX, geoY - 1, worldZ, Cell.NSWE_NORTH);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (can && ((nswe & Cell.NSWE_SOUTH_EAST) != 0))
|
|
|
+ {
|
|
|
+
|
|
|
+ can = checkNearestNswe(geoX, geoY + 1, worldZ, Cell.NSWE_EAST) && checkNearestNswe(geoX + 1, geoY, worldZ, Cell.NSWE_SOUTH);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (can && ((nswe & Cell.NSWE_SOUTH_WEST) != 0))
|
|
|
+ {
|
|
|
+
|
|
|
+ can = checkNearestNswe(geoX, geoY + 1, worldZ, Cell.NSWE_WEST) && checkNearestNswe(geoX - 1, geoY, worldZ, Cell.NSWE_SOUTH);
|
|
|
+ }
|
|
|
+
|
|
|
+ return can && checkNearestNswe(geoX, geoY, worldZ, nswe);
|
|
|
}
|
|
|
|
|
|
- @Override
|
|
|
- public boolean hasGeoPos(int geoX, int geoY)
|
|
|
+ public boolean checkNearestNsweAntiCornerCut(int geoX, int geoY, int worldZ, int nswe, int zDeltaLimit)
|
|
|
{
|
|
|
- return _driver.hasGeoPos(geoX, geoY);
|
|
|
+ boolean can = true;
|
|
|
+ if ((nswe & Cell.NSWE_NORTH_EAST) != 0)
|
|
|
+ {
|
|
|
+
|
|
|
+ can = checkNearestNswe(geoX, geoY - 1, worldZ, Cell.NSWE_EAST, zDeltaLimit) && checkNearestNswe(geoX + 1, geoY, worldZ, Cell.NSWE_NORTH, zDeltaLimit);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (can && ((nswe & Cell.NSWE_NORTH_WEST) != 0))
|
|
|
+ {
|
|
|
+
|
|
|
+ can = checkNearestNswe(geoX, geoY - 1, worldZ, Cell.NSWE_WEST, zDeltaLimit) && checkNearestNswe(geoX, geoY - 1, worldZ, Cell.NSWE_NORTH, zDeltaLimit);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (can && ((nswe & Cell.NSWE_SOUTH_EAST) != 0))
|
|
|
+ {
|
|
|
+
|
|
|
+ can = checkNearestNswe(geoX, geoY + 1, worldZ, Cell.NSWE_EAST, zDeltaLimit) && checkNearestNswe(geoX + 1, geoY, worldZ, Cell.NSWE_SOUTH, zDeltaLimit);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (can && ((nswe & Cell.NSWE_SOUTH_WEST) != 0))
|
|
|
+ {
|
|
|
+
|
|
|
+ can = checkNearestNswe(geoX, geoY + 1, worldZ, Cell.NSWE_WEST, zDeltaLimit) && checkNearestNswe(geoX - 1, geoY, worldZ, Cell.NSWE_SOUTH, zDeltaLimit);
|
|
|
+ }
|
|
|
+
|
|
|
+ return can && checkNearestNswe(geoX, geoY, worldZ, nswe, zDeltaLimit);
|
|
|
}
|
|
|
|
|
|
- @Override
|
|
|
public int getNearestZ(int geoX, int geoY, int worldZ)
|
|
|
{
|
|
|
return _driver.getNearestZ(geoX, geoY, worldZ);
|
|
|
}
|
|
|
|
|
|
- @Override
|
|
|
+ public int getNearestZ(int geoX, int geoY, int worldZ, int zDeltaLimit)
|
|
|
+ {
|
|
|
+ return _driver.getNearestZ(geoX, geoY, worldZ, zDeltaLimit);
|
|
|
+ }
|
|
|
+
|
|
|
public int getNextLowerZ(int geoX, int geoY, int worldZ)
|
|
|
{
|
|
|
return _driver.getNextLowerZ(geoX, geoY, worldZ);
|
|
|
}
|
|
|
|
|
|
- @Override
|
|
|
+ public int getNextLowerZ(int geoX, int geoY, int worldZ, int zDeltaLimit)
|
|
|
+ {
|
|
|
+ return _driver.getNextLowerZ(geoX, geoY, worldZ, zDeltaLimit);
|
|
|
+ }
|
|
|
+
|
|
|
public int getNextHigherZ(int geoX, int geoY, int worldZ)
|
|
|
{
|
|
|
return _driver.getNextHigherZ(geoX, geoY, worldZ);
|
|
|
}
|
|
|
|
|
|
- @Override
|
|
|
- public boolean canEnterNeighbors(int geoX, int geoY, int worldZ, Direction first, Direction... more)
|
|
|
+ public int getNextHigherZ(int geoX, int geoY, int worldZ, int zDeltaLimit)
|
|
|
+ {
|
|
|
+ return _driver.getNextHigherZ(geoX, geoY, worldZ, zDeltaLimit);
|
|
|
+ }
|
|
|
+
|
|
|
+ public int getGeoX(int worldX)
|
|
|
{
|
|
|
- return _driver.canEnterNeighbors(geoX, geoY, worldZ, first, more);
|
|
|
+ return _driver.getGeoX(worldX);
|
|
|
}
|
|
|
|
|
|
- @Override
|
|
|
- public boolean canEnterAllNeighbors(int geoX, int geoY, int worldZ)
|
|
|
+ public int getGeoY(int worldY)
|
|
|
{
|
|
|
- return _driver.canEnterAllNeighbors(geoX, geoY, worldZ);
|
|
|
+ return _driver.getGeoY(worldY);
|
|
|
}
|
|
|
|
|
|
-
|
|
|
-
|
|
|
- public boolean isNullDriver()
|
|
|
+ public int getWorldX(int geoX)
|
|
|
{
|
|
|
- return _driver instanceof NullDriver;
|
|
|
+ return _driver.getWorldX(geoX);
|
|
|
+ }
|
|
|
+
|
|
|
+ public int getWorldY(int geoY)
|
|
|
+ {
|
|
|
+ return _driver.getWorldY(geoY);
|
|
|
}
|
|
|
|
|
|
+
|
|
|
+
|
|
|
|
|
|
* Gets the height.
|
|
|
* @param x the x coordinate
|
|
@@ -170,8 +251,7 @@ public class GeoData implements IGeoDriver
|
|
|
*/
|
|
|
public int getSpawnHeight(int x, int y, int z)
|
|
|
{
|
|
|
-
|
|
|
- return getNextLowerZ(getGeoX(x), getGeoY(y), z + 30);
|
|
|
+ return getNearestZ(getGeoX(x), getGeoY(y), z, Z_DELTA_LIMIT);
|
|
|
}
|
|
|
|
|
|
|
|
@@ -253,31 +333,17 @@ public class GeoData implements IGeoDriver
|
|
|
return canSeeTarget(x, y, z, tx, ty, tz);
|
|
|
}
|
|
|
|
|
|
- private int getLosGeoZ(int prevX, int prevY, int prevGeoZ, int curX, int curY, Direction dir)
|
|
|
+ private int getLosGeoZ(int prevX, int prevY, int prevGeoZ, int curX, int curY, int nswe)
|
|
|
{
|
|
|
- boolean can = true;
|
|
|
-
|
|
|
- switch (dir)
|
|
|
+ if ((((nswe & Cell.NSWE_NORTH) != 0) && ((nswe & Cell.NSWE_SOUTH) != 0)) || (((nswe & Cell.NSWE_WEST) != 0) && ((nswe & Cell.NSWE_EAST) != 0)))
|
|
|
{
|
|
|
- case NORTH_EAST:
|
|
|
- can = canEnterNeighbors(prevX, prevY - 1, prevGeoZ, Direction.EAST) && canEnterNeighbors(prevX + 1, prevY, prevGeoZ, Direction.NORTH);
|
|
|
- break;
|
|
|
- case NORTH_WEST:
|
|
|
- can = canEnterNeighbors(prevX, prevY - 1, prevGeoZ, Direction.WEST) && canEnterNeighbors(prevX - 1, prevY, prevGeoZ, Direction.NORTH);
|
|
|
- break;
|
|
|
- case SOUTH_EAST:
|
|
|
- can = canEnterNeighbors(prevX, prevY + 1, prevGeoZ, Direction.EAST) && canEnterNeighbors(prevX + 1, prevY, prevGeoZ, Direction.SOUTH);
|
|
|
- break;
|
|
|
- case SOUTH_WEST:
|
|
|
- can = canEnterNeighbors(prevX, prevY + 1, prevGeoZ, Direction.WEST) && canEnterNeighbors(prevX - 1, prevY, prevGeoZ, Direction.SOUTH);
|
|
|
- break;
|
|
|
-
|
|
|
+ throw new RuntimeException("Multiple directions!");
|
|
|
}
|
|
|
- if (can && canEnterNeighbors(prevX, prevY, prevGeoZ, dir))
|
|
|
+
|
|
|
+ if (checkNearestNsweAntiCornerCut(prevX, prevY, prevGeoZ, nswe, Z_DELTA_LIMIT))
|
|
|
{
|
|
|
- return getNearestZ(curX, curY, prevGeoZ);
|
|
|
+ return getNearestZ(curX, curY, prevGeoZ, Z_DELTA_LIMIT);
|
|
|
}
|
|
|
-
|
|
|
return getNextHigherZ(curX, curY, prevGeoZ);
|
|
|
}
|
|
|
|
|
@@ -298,9 +364,10 @@ public class GeoData implements IGeoDriver
|
|
|
int tGeoX = getGeoX(tx);
|
|
|
int tGeoY = getGeoY(ty);
|
|
|
|
|
|
- z = getNearestZ(geoX, geoY, z);
|
|
|
- tz = getNearestZ(tGeoX, tGeoY, tz);
|
|
|
+ z = getNearestZ(geoX, geoY, z, Z_DELTA_LIMIT);
|
|
|
+ tz = getNearestZ(tGeoX, tGeoY, tz, Z_DELTA_LIMIT);
|
|
|
|
|
|
+
|
|
|
if ((geoX == tGeoX) && (geoY == tGeoY))
|
|
|
{
|
|
|
if (hasGeoPos(tGeoX, tGeoY))
|
|
@@ -356,12 +423,12 @@ public class GeoData implements IGeoDriver
|
|
|
int beeCurZ = pointIter.z();
|
|
|
int curGeoZ = prevGeoZ;
|
|
|
|
|
|
-
|
|
|
+
|
|
|
if (hasGeoPos(curX, curY))
|
|
|
{
|
|
|
int beeCurGeoZ = getNearestZ(curX, curY, beeCurZ);
|
|
|
- Direction dir = GeoUtils.computeDirection(prevX, prevY, curX, curY);
|
|
|
- curGeoZ = getLosGeoZ(prevX, prevY, prevGeoZ, curX, curY, dir);
|
|
|
+ int nswe = GeoUtils.computeNswe(prevX, prevY, curX, curY);
|
|
|
+ curGeoZ = getLosGeoZ(prevX, prevY, prevGeoZ, curX, curY, nswe);
|
|
|
int maxHeight;
|
|
|
if (ptIndex < ELEVATED_SEE_OVER_DISTANCE)
|
|
|
{
|
|
@@ -375,41 +442,33 @@ public class GeoData implements IGeoDriver
|
|
|
boolean canSeeThrough = false;
|
|
|
if ((curGeoZ <= maxHeight) && (curGeoZ <= beeCurGeoZ))
|
|
|
{
|
|
|
- switch (dir)
|
|
|
+ if ((nswe & Cell.NSWE_NORTH_EAST) != 0)
|
|
|
{
|
|
|
- case NORTH_EAST:
|
|
|
- {
|
|
|
- int northGeoZ = getLosGeoZ(prevX, prevY, prevGeoZ, prevX, prevY - 1, Direction.EAST);
|
|
|
- int eastGeoZ = getLosGeoZ(prevX, prevY, prevGeoZ, prevX + 1, prevY, Direction.NORTH);
|
|
|
- canSeeThrough = (northGeoZ <= maxHeight) && (eastGeoZ <= maxHeight) && (northGeoZ <= getNearestZ(prevX, prevY - 1, beeCurZ)) && (eastGeoZ <= getNearestZ(prevX + 1, prevY, beeCurZ));
|
|
|
- break;
|
|
|
- }
|
|
|
- case NORTH_WEST:
|
|
|
- {
|
|
|
- int northGeoZ = getLosGeoZ(prevX, prevY, prevGeoZ, prevX, prevY - 1, Direction.WEST);
|
|
|
- int westGeoZ = getLosGeoZ(prevX, prevY, prevGeoZ, prevX - 1, prevY, Direction.NORTH);
|
|
|
- canSeeThrough = (northGeoZ <= maxHeight) && (westGeoZ <= maxHeight) && (northGeoZ <= getNearestZ(prevX, prevY - 1, beeCurZ)) && (westGeoZ <= getNearestZ(prevX - 1, prevY, beeCurZ));
|
|
|
- break;
|
|
|
- }
|
|
|
- case SOUTH_EAST:
|
|
|
- {
|
|
|
- int southGeoZ = getLosGeoZ(prevX, prevY, prevGeoZ, prevX, prevY + 1, Direction.EAST);
|
|
|
- int eastGeoZ = getLosGeoZ(prevX, prevY, prevGeoZ, prevX + 1, prevY, Direction.SOUTH);
|
|
|
- canSeeThrough = (southGeoZ <= maxHeight) && (eastGeoZ <= maxHeight) && (southGeoZ <= getNearestZ(prevX, prevY + 1, beeCurZ)) && (eastGeoZ <= getNearestZ(prevX + 1, prevY, beeCurZ));
|
|
|
- break;
|
|
|
- }
|
|
|
- case SOUTH_WEST:
|
|
|
- {
|
|
|
- int southGeoZ = getLosGeoZ(prevX, prevY, prevGeoZ, prevX, prevY + 1, Direction.WEST);
|
|
|
- int westGeoZ = getLosGeoZ(prevX, prevY, prevGeoZ, prevX - 1, prevY, Direction.SOUTH);
|
|
|
- canSeeThrough = (southGeoZ <= maxHeight) && (westGeoZ <= maxHeight) && (southGeoZ <= getNearestZ(prevX, prevY + 1, beeCurZ)) && (westGeoZ <= getNearestZ(prevX - 1, prevY, beeCurZ));
|
|
|
- break;
|
|
|
- }
|
|
|
- default:
|
|
|
- {
|
|
|
- canSeeThrough = true;
|
|
|
- break;
|
|
|
- }
|
|
|
+ int northGeoZ = getLosGeoZ(prevX, prevY, prevGeoZ, prevX, prevY - 1, Cell.NSWE_EAST);
|
|
|
+ int eastGeoZ = getLosGeoZ(prevX, prevY, prevGeoZ, prevX + 1, prevY, Cell.NSWE_NORTH);
|
|
|
+ canSeeThrough = (northGeoZ <= maxHeight) && (eastGeoZ <= maxHeight) && (northGeoZ <= getNearestZ(prevX, prevY - 1, beeCurZ)) && (eastGeoZ <= getNearestZ(prevX + 1, prevY, beeCurZ));
|
|
|
+ }
|
|
|
+ else if ((nswe & Cell.NSWE_NORTH_WEST) != 0)
|
|
|
+ {
|
|
|
+ int northGeoZ = getLosGeoZ(prevX, prevY, prevGeoZ, prevX, prevY - 1, Cell.NSWE_WEST);
|
|
|
+ int westGeoZ = getLosGeoZ(prevX, prevY, prevGeoZ, prevX - 1, prevY, Cell.NSWE_NORTH);
|
|
|
+ canSeeThrough = (northGeoZ <= maxHeight) && (westGeoZ <= maxHeight) && (northGeoZ <= getNearestZ(prevX, prevY - 1, beeCurZ)) && (westGeoZ <= getNearestZ(prevX - 1, prevY, beeCurZ));
|
|
|
+ }
|
|
|
+ else if ((nswe & Cell.NSWE_SOUTH_EAST) != 0)
|
|
|
+ {
|
|
|
+ int southGeoZ = getLosGeoZ(prevX, prevY, prevGeoZ, prevX, prevY + 1, Cell.NSWE_EAST);
|
|
|
+ int eastGeoZ = getLosGeoZ(prevX, prevY, prevGeoZ, prevX + 1, prevY, Cell.NSWE_SOUTH);
|
|
|
+ canSeeThrough = (southGeoZ <= maxHeight) && (eastGeoZ <= maxHeight) && (southGeoZ <= getNearestZ(prevX, prevY + 1, beeCurZ)) && (eastGeoZ <= getNearestZ(prevX + 1, prevY, beeCurZ));
|
|
|
+ }
|
|
|
+ else if ((nswe & Cell.NSWE_SOUTH_WEST) != 0)
|
|
|
+ {
|
|
|
+ int southGeoZ = getLosGeoZ(prevX, prevY, prevGeoZ, prevX, prevY + 1, Cell.NSWE_WEST);
|
|
|
+ int westGeoZ = getLosGeoZ(prevX, prevY, prevGeoZ, prevX - 1, prevY, Cell.NSWE_SOUTH);
|
|
|
+ canSeeThrough = (southGeoZ <= maxHeight) && (westGeoZ <= maxHeight) && (southGeoZ <= getNearestZ(prevX, prevY + 1, beeCurZ)) && (westGeoZ <= getNearestZ(prevX - 1, prevY, beeCurZ));
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ canSeeThrough = true;
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -443,10 +502,10 @@ public class GeoData implements IGeoDriver
|
|
|
{
|
|
|
int geoX = getGeoX(x);
|
|
|
int geoY = getGeoY(y);
|
|
|
- z = getNearestZ(geoX, geoY, z);
|
|
|
+ z = getNearestZ(geoX, geoY, z, Z_DELTA_LIMIT);
|
|
|
int tGeoX = getGeoX(tx);
|
|
|
int tGeoY = getGeoY(ty);
|
|
|
- tz = getNearestZ(tGeoX, tGeoY, tz);
|
|
|
+ tz = getNearestZ(tGeoX, tGeoY, tz, Z_DELTA_LIMIT);
|
|
|
|
|
|
if (DoorTable.getInstance().checkIfDoorsBetween(x, y, z, tx, ty, tz, instanceId, false))
|
|
|
{
|
|
@@ -464,36 +523,12 @@ public class GeoData implements IGeoDriver
|
|
|
{
|
|
|
int curX = pointIter.x();
|
|
|
int curY = pointIter.y();
|
|
|
- int curZ = getNearestZ(curX, curY, prevZ);
|
|
|
+ int curZ = getNearestZ(curX, curY, prevZ, Z_DELTA_LIMIT);
|
|
|
|
|
|
if (hasGeoPos(prevX, prevY))
|
|
|
{
|
|
|
- Direction dir = GeoUtils.computeDirection(prevX, prevY, curX, curY);
|
|
|
- boolean canEnter = false;
|
|
|
- if (canEnterNeighbors(prevX, prevY, prevZ, dir))
|
|
|
- {
|
|
|
-
|
|
|
- switch (dir)
|
|
|
- {
|
|
|
- case NORTH_EAST:
|
|
|
- canEnter = canEnterNeighbors(prevX, prevY - 1, prevZ, Direction.EAST) && canEnterNeighbors(prevX + 1, prevY, prevZ, Direction.NORTH);
|
|
|
- break;
|
|
|
- case NORTH_WEST:
|
|
|
- canEnter = canEnterNeighbors(prevX, prevY - 1, prevZ, Direction.WEST) && canEnterNeighbors(prevX - 1, prevY, prevZ, Direction.NORTH);
|
|
|
- break;
|
|
|
- case SOUTH_EAST:
|
|
|
- canEnter = canEnterNeighbors(prevX, prevY + 1, prevZ, Direction.EAST) && canEnterNeighbors(prevX + 1, prevY, prevZ, Direction.SOUTH);
|
|
|
- break;
|
|
|
- case SOUTH_WEST:
|
|
|
- canEnter = canEnterNeighbors(prevX, prevY + 1, prevZ, Direction.WEST) && canEnterNeighbors(prevX - 1, prevY, prevZ, Direction.SOUTH);
|
|
|
- break;
|
|
|
- default:
|
|
|
- canEnter = true;
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- if (!canEnter)
|
|
|
+ int nswe = GeoUtils.computeNswe(prevX, prevY, curX, curY);
|
|
|
+ if (!checkNearestNsweAntiCornerCut(prevX, prevY, prevZ, nswe, Z_DELTA_LIMIT))
|
|
|
{
|
|
|
|
|
|
return new Location(getWorldX(prevX), getWorldY(prevY), prevZ);
|
|
@@ -529,10 +564,10 @@ public class GeoData implements IGeoDriver
|
|
|
{
|
|
|
int geoX = getGeoX(fromX);
|
|
|
int geoY = getGeoY(fromY);
|
|
|
- fromZ = getNearestZ(geoX, geoY, fromZ);
|
|
|
+ fromZ = getNearestZ(geoX, geoY, fromZ, Z_DELTA_LIMIT);
|
|
|
int tGeoX = getGeoX(toX);
|
|
|
int tGeoY = getGeoY(toY);
|
|
|
- toZ = getNearestZ(tGeoX, tGeoY, toZ);
|
|
|
+ toZ = getNearestZ(tGeoX, tGeoY, toZ, Z_DELTA_LIMIT);
|
|
|
|
|
|
if (DoorTable.getInstance().checkIfDoorsBetween(fromX, fromY, fromZ, toX, toY, toZ, instanceId, false))
|
|
|
{
|
|
@@ -550,36 +585,12 @@ public class GeoData implements IGeoDriver
|
|
|
{
|
|
|
int curX = pointIter.x();
|
|
|
int curY = pointIter.y();
|
|
|
- int curZ = getNearestZ(curX, curY, prevZ);
|
|
|
+ int curZ = getNearestZ(curX, curY, prevZ, Z_DELTA_LIMIT);
|
|
|
|
|
|
if (hasGeoPos(prevX, prevY))
|
|
|
{
|
|
|
- Direction dir = GeoUtils.computeDirection(prevX, prevY, curX, curY);
|
|
|
- boolean canEnter = false;
|
|
|
- if (canEnterNeighbors(prevX, prevY, prevZ, dir))
|
|
|
- {
|
|
|
-
|
|
|
- switch (dir)
|
|
|
- {
|
|
|
- case NORTH_EAST:
|
|
|
- canEnter = canEnterNeighbors(prevX, prevY - 1, prevZ, Direction.EAST) && canEnterNeighbors(prevX + 1, prevY, prevZ, Direction.NORTH);
|
|
|
- break;
|
|
|
- case NORTH_WEST:
|
|
|
- canEnter = canEnterNeighbors(prevX, prevY - 1, prevZ, Direction.WEST) && canEnterNeighbors(prevX - 1, prevY, prevZ, Direction.NORTH);
|
|
|
- break;
|
|
|
- case SOUTH_EAST:
|
|
|
- canEnter = canEnterNeighbors(prevX, prevY + 1, prevZ, Direction.EAST) && canEnterNeighbors(prevX + 1, prevY, prevZ, Direction.SOUTH);
|
|
|
- break;
|
|
|
- case SOUTH_WEST:
|
|
|
- canEnter = canEnterNeighbors(prevX, prevY + 1, prevZ, Direction.WEST) && canEnterNeighbors(prevX - 1, prevY, prevZ, Direction.SOUTH);
|
|
|
- break;
|
|
|
- default:
|
|
|
- canEnter = true;
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- if (!canEnter)
|
|
|
+ int nswe = GeoUtils.computeNswe(prevX, prevY, curX, curY);
|
|
|
+ if (!checkNearestNsweAntiCornerCut(prevX, prevY, prevZ, nswe, Z_DELTA_LIMIT))
|
|
|
{
|
|
|
return false;
|
|
|
}
|
|
@@ -603,7 +614,7 @@ public class GeoData implements IGeoDriver
|
|
|
{
|
|
|
int geoX = getGeoX(x);
|
|
|
int geoY = getGeoY(y);
|
|
|
- z = getNearestZ(geoX, geoY, z);
|
|
|
+ z = getNearestZ(geoX, geoY, z, Z_DELTA_LIMIT);
|
|
|
int tGeoX = getGeoX(tx);
|
|
|
int tGeoY = getGeoY(ty);
|
|
|
|
|
@@ -616,7 +627,7 @@ public class GeoData implements IGeoDriver
|
|
|
{
|
|
|
int curX = pointIter.x();
|
|
|
int curY = pointIter.y();
|
|
|
- int curZ = getNearestZ(curX, curY, prevZ);
|
|
|
+ int curZ = getNearestZ(curX, curY, prevZ, Z_DELTA_LIMIT);
|
|
|
|
|
|
prevZ = curZ;
|
|
|
}
|