Geodata related classes are moved in gameserver geodata folder.
This commit is contained in:
@@ -19,10 +19,10 @@ package handlers.admincommandhandlers;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import com.l2jmobius.Config;
|
import com.l2jmobius.Config;
|
||||||
|
import com.l2jmobius.gameserver.geodata.pathfinding.AbstractNodeLoc;
|
||||||
|
import com.l2jmobius.gameserver.geodata.pathfinding.PathFinding;
|
||||||
import com.l2jmobius.gameserver.handler.IAdminCommandHandler;
|
import com.l2jmobius.gameserver.handler.IAdminCommandHandler;
|
||||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||||
import com.l2jmobius.gameserver.pathfinding.AbstractNodeLoc;
|
|
||||||
import com.l2jmobius.gameserver.pathfinding.PathFinding;
|
|
||||||
|
|
||||||
public class AdminPathNode implements IAdminCommandHandler
|
public class AdminPathNode implements IAdminCommandHandler
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -98,6 +98,7 @@ import com.l2jmobius.gameserver.datatables.BotReportTable;
|
|||||||
import com.l2jmobius.gameserver.datatables.EventDroplist;
|
import com.l2jmobius.gameserver.datatables.EventDroplist;
|
||||||
import com.l2jmobius.gameserver.datatables.ItemTable;
|
import com.l2jmobius.gameserver.datatables.ItemTable;
|
||||||
import com.l2jmobius.gameserver.datatables.MerchantPriceConfigTable;
|
import com.l2jmobius.gameserver.datatables.MerchantPriceConfigTable;
|
||||||
|
import com.l2jmobius.gameserver.geodata.pathfinding.PathFinding;
|
||||||
import com.l2jmobius.gameserver.handler.ConditionHandler;
|
import com.l2jmobius.gameserver.handler.ConditionHandler;
|
||||||
import com.l2jmobius.gameserver.handler.DailyMissionHandler;
|
import com.l2jmobius.gameserver.handler.DailyMissionHandler;
|
||||||
import com.l2jmobius.gameserver.handler.EffectHandler;
|
import com.l2jmobius.gameserver.handler.EffectHandler;
|
||||||
@@ -143,7 +144,6 @@ import com.l2jmobius.gameserver.model.votereward.VoteSystem;
|
|||||||
import com.l2jmobius.gameserver.network.ClientNetworkManager;
|
import com.l2jmobius.gameserver.network.ClientNetworkManager;
|
||||||
import com.l2jmobius.gameserver.network.loginserver.LoginServerNetworkManager;
|
import com.l2jmobius.gameserver.network.loginserver.LoginServerNetworkManager;
|
||||||
import com.l2jmobius.gameserver.network.telnet.TelnetServer;
|
import com.l2jmobius.gameserver.network.telnet.TelnetServer;
|
||||||
import com.l2jmobius.gameserver.pathfinding.PathFinding;
|
|
||||||
import com.l2jmobius.gameserver.scripting.ScriptEngineManager;
|
import com.l2jmobius.gameserver.scripting.ScriptEngineManager;
|
||||||
import com.l2jmobius.gameserver.taskmanager.TaskManager;
|
import com.l2jmobius.gameserver.taskmanager.TaskManager;
|
||||||
import com.l2jmobius.gameserver.util.Broadcast;
|
import com.l2jmobius.gameserver.util.Broadcast;
|
||||||
|
|||||||
@@ -22,9 +22,9 @@ import java.util.logging.Level;
|
|||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import com.l2jmobius.Config;
|
import com.l2jmobius.Config;
|
||||||
import com.l2jmobius.commons.geodriver.Cell;
|
|
||||||
import com.l2jmobius.commons.geodriver.GeoDriver;
|
|
||||||
import com.l2jmobius.gameserver.data.xml.impl.DoorData;
|
import com.l2jmobius.gameserver.data.xml.impl.DoorData;
|
||||||
|
import com.l2jmobius.gameserver.geodata.geodriver.Cell;
|
||||||
|
import com.l2jmobius.gameserver.geodata.geodriver.GeoDriver;
|
||||||
import com.l2jmobius.gameserver.instancemanager.WarpedSpaceManager;
|
import com.l2jmobius.gameserver.instancemanager.WarpedSpaceManager;
|
||||||
import com.l2jmobius.gameserver.model.L2Object;
|
import com.l2jmobius.gameserver.model.L2Object;
|
||||||
import com.l2jmobius.gameserver.model.L2World;
|
import com.l2jmobius.gameserver.model.L2World;
|
||||||
|
|||||||
@@ -34,12 +34,12 @@ import org.w3c.dom.Node;
|
|||||||
|
|
||||||
import com.l2jmobius.commons.util.IGameXmlReader;
|
import com.l2jmobius.commons.util.IGameXmlReader;
|
||||||
import com.l2jmobius.commons.util.IXmlReader;
|
import com.l2jmobius.commons.util.IXmlReader;
|
||||||
|
import com.l2jmobius.gameserver.geodata.pathfinding.AbstractNodeLoc;
|
||||||
import com.l2jmobius.gameserver.instancemanager.MapRegionManager;
|
import com.l2jmobius.gameserver.instancemanager.MapRegionManager;
|
||||||
import com.l2jmobius.gameserver.model.StatsSet;
|
import com.l2jmobius.gameserver.model.StatsSet;
|
||||||
import com.l2jmobius.gameserver.model.actor.instance.L2DoorInstance;
|
import com.l2jmobius.gameserver.model.actor.instance.L2DoorInstance;
|
||||||
import com.l2jmobius.gameserver.model.actor.templates.L2DoorTemplate;
|
import com.l2jmobius.gameserver.model.actor.templates.L2DoorTemplate;
|
||||||
import com.l2jmobius.gameserver.model.instancezone.Instance;
|
import com.l2jmobius.gameserver.model.instancezone.Instance;
|
||||||
import com.l2jmobius.gameserver.pathfinding.AbstractNodeLoc;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class loads and hold info about doors.
|
* This class loads and hold info about doors.
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package com.l2jmobius.commons.geodriver;
|
package com.l2jmobius.gameserver.geodata.geodriver;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author HorridoJoho
|
* @author HorridoJoho
|
||||||
@@ -1,189 +1,189 @@
|
|||||||
/*
|
/*
|
||||||
* This file is part of the L2J Mobius project.
|
* This file is part of the L2J Mobius project.
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
* General Public License for more details.
|
* General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package com.l2jmobius.commons.geodriver;
|
package com.l2jmobius.gameserver.geodata.geodriver;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.RandomAccessFile;
|
import java.io.RandomAccessFile;
|
||||||
import java.nio.ByteOrder;
|
import java.nio.ByteOrder;
|
||||||
import java.nio.channels.FileChannel.MapMode;
|
import java.nio.channels.FileChannel.MapMode;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.util.concurrent.atomic.AtomicReferenceArray;
|
import java.util.concurrent.atomic.AtomicReferenceArray;
|
||||||
|
|
||||||
import com.l2jmobius.commons.geodriver.regions.NullRegion;
|
import com.l2jmobius.gameserver.geodata.geodriver.regions.NullRegion;
|
||||||
import com.l2jmobius.commons.geodriver.regions.Region;
|
import com.l2jmobius.gameserver.geodata.geodriver.regions.Region;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author HorridoJoho
|
* @author HorridoJoho
|
||||||
*/
|
*/
|
||||||
public final class GeoDriver
|
public final class GeoDriver
|
||||||
{
|
{
|
||||||
// world dimensions: 1048576 * 1048576 = 1099511627776
|
// world dimensions: 1048576 * 1048576 = 1099511627776
|
||||||
private static final int WORLD_MIN_X = -655360;
|
private static final int WORLD_MIN_X = -655360;
|
||||||
private static final int WORLD_MAX_X = 393215;
|
private static final int WORLD_MAX_X = 393215;
|
||||||
private static final int WORLD_MIN_Y = -589824;
|
private static final int WORLD_MIN_Y = -589824;
|
||||||
private static final int WORLD_MAX_Y = 458751;
|
private static final int WORLD_MAX_Y = 458751;
|
||||||
private static final int WORLD_MIN_Z = -16384;
|
private static final int WORLD_MIN_Z = -16384;
|
||||||
private static final int WORLD_MAX_Z = 16384;
|
private static final int WORLD_MAX_Z = 16384;
|
||||||
|
|
||||||
/** Regions in the world on the x axis */
|
/** Regions in the world on the x axis */
|
||||||
public static final int GEO_REGIONS_X = 32;
|
public static final int GEO_REGIONS_X = 32;
|
||||||
/** Regions in the world on the y axis */
|
/** Regions in the world on the y axis */
|
||||||
public static final int GEO_REGIONS_Y = 32;
|
public static final int GEO_REGIONS_Y = 32;
|
||||||
/** Region in the world */
|
/** Region in the world */
|
||||||
public static final int GEO_REGIONS = GEO_REGIONS_X * GEO_REGIONS_Y;
|
public static final int GEO_REGIONS = GEO_REGIONS_X * GEO_REGIONS_Y;
|
||||||
|
|
||||||
/** Blocks in the world on the x axis */
|
/** Blocks in the world on the x axis */
|
||||||
public static final int GEO_BLOCKS_X = GEO_REGIONS_X * IRegion.REGION_BLOCKS_X;
|
public static final int GEO_BLOCKS_X = GEO_REGIONS_X * IRegion.REGION_BLOCKS_X;
|
||||||
/** Blocks in the world on the y axis */
|
/** Blocks in the world on the y axis */
|
||||||
public static final int GEO_BLOCKS_Y = GEO_REGIONS_Y * IRegion.REGION_BLOCKS_Y;
|
public static final int GEO_BLOCKS_Y = GEO_REGIONS_Y * IRegion.REGION_BLOCKS_Y;
|
||||||
/** Blocks in the world */
|
/** Blocks in the world */
|
||||||
public static final int GEO_BLOCKS = GEO_REGIONS * IRegion.REGION_BLOCKS;
|
public static final int GEO_BLOCKS = GEO_REGIONS * IRegion.REGION_BLOCKS;
|
||||||
|
|
||||||
/** Cells in the world on the x axis */
|
/** Cells in the world on the x axis */
|
||||||
public static final int GEO_CELLS_X = GEO_BLOCKS_X * IBlock.BLOCK_CELLS_X;
|
public static final int GEO_CELLS_X = GEO_BLOCKS_X * IBlock.BLOCK_CELLS_X;
|
||||||
/** Cells in the world in the y axis */
|
/** Cells in the world in the y axis */
|
||||||
public static final int GEO_CELLS_Y = GEO_BLOCKS_Y * IBlock.BLOCK_CELLS_Y;
|
public static final int GEO_CELLS_Y = GEO_BLOCKS_Y * IBlock.BLOCK_CELLS_Y;
|
||||||
/** Cells in the world in the z axis */
|
/** Cells in the world in the z axis */
|
||||||
public static final int GEO_CELLS_Z = (Math.abs(WORLD_MIN_Z) + Math.abs(WORLD_MAX_Z)) / 16;
|
public static final int GEO_CELLS_Z = (Math.abs(WORLD_MIN_Z) + Math.abs(WORLD_MAX_Z)) / 16;
|
||||||
|
|
||||||
/** The regions array */
|
/** The regions array */
|
||||||
private final AtomicReferenceArray<IRegion> _regions = new AtomicReferenceArray<>(GEO_REGIONS);
|
private final AtomicReferenceArray<IRegion> _regions = new AtomicReferenceArray<>(GEO_REGIONS);
|
||||||
|
|
||||||
public GeoDriver()
|
public GeoDriver()
|
||||||
{
|
{
|
||||||
for (int i = 0; i < _regions.length(); i++)
|
for (int i = 0; i < _regions.length(); i++)
|
||||||
{
|
{
|
||||||
_regions.set(i, NullRegion.INSTANCE);
|
_regions.set(i, NullRegion.INSTANCE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkGeoX(int geoX)
|
private void checkGeoX(int geoX)
|
||||||
{
|
{
|
||||||
if ((geoX < 0) || (geoX >= GEO_CELLS_X))
|
if ((geoX < 0) || (geoX >= GEO_CELLS_X))
|
||||||
{
|
{
|
||||||
throw new IllegalArgumentException();
|
throw new IllegalArgumentException();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkGeoY(int geoY)
|
private void checkGeoY(int geoY)
|
||||||
{
|
{
|
||||||
if ((geoY < 0) || (geoY >= GEO_CELLS_Y))
|
if ((geoY < 0) || (geoY >= GEO_CELLS_Y))
|
||||||
{
|
{
|
||||||
throw new IllegalArgumentException();
|
throw new IllegalArgumentException();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkGeoZ(int geoZ)
|
private void checkGeoZ(int geoZ)
|
||||||
{
|
{
|
||||||
if ((geoZ < 0) || (geoZ >= GEO_CELLS_Z))
|
if ((geoZ < 0) || (geoZ >= GEO_CELLS_Z))
|
||||||
{
|
{
|
||||||
throw new IllegalArgumentException();
|
throw new IllegalArgumentException();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private IRegion getRegion(int geoX, int geoY)
|
private IRegion getRegion(int geoX, int geoY)
|
||||||
{
|
{
|
||||||
checkGeoX(geoX);
|
checkGeoX(geoX);
|
||||||
checkGeoY(geoY);
|
checkGeoY(geoY);
|
||||||
return _regions.get(((geoX / IRegion.REGION_CELLS_X) * GEO_REGIONS_Y) + (geoY / IRegion.REGION_CELLS_Y));
|
return _regions.get(((geoX / IRegion.REGION_CELLS_X) * GEO_REGIONS_Y) + (geoY / IRegion.REGION_CELLS_Y));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void loadRegion(Path filePath, int regionX, int regionY) throws IOException
|
public void loadRegion(Path filePath, int regionX, int regionY) throws IOException
|
||||||
{
|
{
|
||||||
final int regionOffset = (regionX * GEO_REGIONS_Y) + regionY;
|
final int regionOffset = (regionX * GEO_REGIONS_Y) + regionY;
|
||||||
|
|
||||||
try (RandomAccessFile raf = new RandomAccessFile(filePath.toFile(), "r"))
|
try (RandomAccessFile raf = new RandomAccessFile(filePath.toFile(), "r"))
|
||||||
{
|
{
|
||||||
_regions.set(regionOffset, new Region(raf.getChannel().map(MapMode.READ_ONLY, 0, raf.length()).load().order(ByteOrder.LITTLE_ENDIAN)));
|
_regions.set(regionOffset, new Region(raf.getChannel().map(MapMode.READ_ONLY, 0, raf.length()).load().order(ByteOrder.LITTLE_ENDIAN)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void unloadRegion(int regionX, int regionY)
|
public void unloadRegion(int regionX, int regionY)
|
||||||
{
|
{
|
||||||
_regions.set((regionX * GEO_REGIONS_Y) + regionY, NullRegion.INSTANCE);
|
_regions.set((regionX * GEO_REGIONS_Y) + regionY, NullRegion.INSTANCE);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasGeoPos(int geoX, int geoY)
|
public boolean hasGeoPos(int geoX, int geoY)
|
||||||
{
|
{
|
||||||
return getRegion(geoX, geoY).hasGeo();
|
return getRegion(geoX, geoY).hasGeo();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean checkNearestNswe(int geoX, int geoY, int worldZ, int nswe)
|
public boolean checkNearestNswe(int geoX, int geoY, int worldZ, int nswe)
|
||||||
{
|
{
|
||||||
return getRegion(geoX, geoY).checkNearestNswe(geoX, geoY, worldZ, nswe);
|
return getRegion(geoX, geoY).checkNearestNswe(geoX, geoY, worldZ, nswe);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getNearestZ(int geoX, int geoY, int worldZ)
|
public int getNearestZ(int geoX, int geoY, int worldZ)
|
||||||
{
|
{
|
||||||
return getRegion(geoX, geoY).getNearestZ(geoX, geoY, worldZ);
|
return getRegion(geoX, geoY).getNearestZ(geoX, geoY, worldZ);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getNextLowerZ(int geoX, int geoY, int worldZ)
|
public int getNextLowerZ(int geoX, int geoY, int worldZ)
|
||||||
{
|
{
|
||||||
return getRegion(geoX, geoY).getNextLowerZ(geoX, geoY, worldZ);
|
return getRegion(geoX, geoY).getNextLowerZ(geoX, geoY, worldZ);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getNextHigherZ(int geoX, int geoY, int worldZ)
|
public int getNextHigherZ(int geoX, int geoY, int worldZ)
|
||||||
{
|
{
|
||||||
return getRegion(geoX, geoY).getNextHigherZ(geoX, geoY, worldZ);
|
return getRegion(geoX, geoY).getNextHigherZ(geoX, geoY, worldZ);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getGeoX(int worldX)
|
public int getGeoX(int worldX)
|
||||||
{
|
{
|
||||||
if ((worldX < WORLD_MIN_X) || (worldX > WORLD_MAX_X))
|
if ((worldX < WORLD_MIN_X) || (worldX > WORLD_MAX_X))
|
||||||
{
|
{
|
||||||
throw new IllegalArgumentException();
|
throw new IllegalArgumentException();
|
||||||
}
|
}
|
||||||
return (worldX - WORLD_MIN_X) / 16;
|
return (worldX - WORLD_MIN_X) / 16;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getGeoY(int worldY)
|
public int getGeoY(int worldY)
|
||||||
{
|
{
|
||||||
if ((worldY < WORLD_MIN_Y) || (worldY > WORLD_MAX_Y))
|
if ((worldY < WORLD_MIN_Y) || (worldY > WORLD_MAX_Y))
|
||||||
{
|
{
|
||||||
throw new IllegalArgumentException();
|
throw new IllegalArgumentException();
|
||||||
}
|
}
|
||||||
return (worldY - WORLD_MIN_Y) / 16;
|
return (worldY - WORLD_MIN_Y) / 16;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getGeoZ(int worldZ)
|
public int getGeoZ(int worldZ)
|
||||||
{
|
{
|
||||||
if ((worldZ < WORLD_MIN_Z) || (worldZ > WORLD_MAX_Z))
|
if ((worldZ < WORLD_MIN_Z) || (worldZ > WORLD_MAX_Z))
|
||||||
{
|
{
|
||||||
throw new IllegalArgumentException();
|
throw new IllegalArgumentException();
|
||||||
}
|
}
|
||||||
return (worldZ - WORLD_MIN_Z) / 16;
|
return (worldZ - WORLD_MIN_Z) / 16;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getWorldX(int geoX)
|
public int getWorldX(int geoX)
|
||||||
{
|
{
|
||||||
checkGeoX(geoX);
|
checkGeoX(geoX);
|
||||||
return (geoX * 16) + WORLD_MIN_X + 8;
|
return (geoX * 16) + WORLD_MIN_X + 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getWorldY(int geoY)
|
public int getWorldY(int geoY)
|
||||||
{
|
{
|
||||||
checkGeoY(geoY);
|
checkGeoY(geoY);
|
||||||
return (geoY * 16) + WORLD_MIN_Y + 8;
|
return (geoY * 16) + WORLD_MIN_Y + 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getWorldZ(int geoZ)
|
public int getWorldZ(int geoZ)
|
||||||
{
|
{
|
||||||
checkGeoZ(geoZ);
|
checkGeoZ(geoZ);
|
||||||
return (geoZ * 16) + WORLD_MIN_Z + 8;
|
return (geoZ * 16) + WORLD_MIN_Z + 8;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -14,7 +14,7 @@
|
|||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package com.l2jmobius.commons.geodriver;
|
package com.l2jmobius.gameserver.geodata.geodriver;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author HorridoJoho
|
* @author HorridoJoho
|
||||||
@@ -14,7 +14,7 @@
|
|||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package com.l2jmobius.commons.geodriver;
|
package com.l2jmobius.gameserver.geodata.geodriver;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author HorridoJoho
|
* @author HorridoJoho
|
||||||
@@ -14,11 +14,11 @@
|
|||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package com.l2jmobius.commons.geodriver.blocks;
|
package com.l2jmobius.gameserver.geodata.geodriver.blocks;
|
||||||
|
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
import com.l2jmobius.commons.geodriver.IBlock;
|
import com.l2jmobius.gameserver.geodata.geodriver.IBlock;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author HorridoJoho
|
* @author HorridoJoho
|
||||||
@@ -14,11 +14,11 @@
|
|||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package com.l2jmobius.commons.geodriver.blocks;
|
package com.l2jmobius.gameserver.geodata.geodriver.blocks;
|
||||||
|
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
import com.l2jmobius.commons.geodriver.IBlock;
|
import com.l2jmobius.gameserver.geodata.geodriver.IBlock;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author HorridoJoho
|
* @author HorridoJoho
|
||||||
@@ -14,11 +14,11 @@
|
|||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package com.l2jmobius.commons.geodriver.blocks;
|
package com.l2jmobius.gameserver.geodata.geodriver.blocks;
|
||||||
|
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
import com.l2jmobius.commons.geodriver.IBlock;
|
import com.l2jmobius.gameserver.geodata.geodriver.IBlock;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author HorridoJoho
|
* @author HorridoJoho
|
||||||
@@ -14,9 +14,9 @@
|
|||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package com.l2jmobius.commons.geodriver.regions;
|
package com.l2jmobius.gameserver.geodata.geodriver.regions;
|
||||||
|
|
||||||
import com.l2jmobius.commons.geodriver.IRegion;
|
import com.l2jmobius.gameserver.geodata.geodriver.IRegion;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author HorridoJoho
|
* @author HorridoJoho
|
||||||
@@ -14,15 +14,15 @@
|
|||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package com.l2jmobius.commons.geodriver.regions;
|
package com.l2jmobius.gameserver.geodata.geodriver.regions;
|
||||||
|
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
import com.l2jmobius.commons.geodriver.IBlock;
|
import com.l2jmobius.gameserver.geodata.geodriver.IBlock;
|
||||||
import com.l2jmobius.commons.geodriver.IRegion;
|
import com.l2jmobius.gameserver.geodata.geodriver.IRegion;
|
||||||
import com.l2jmobius.commons.geodriver.blocks.ComplexBlock;
|
import com.l2jmobius.gameserver.geodata.geodriver.blocks.ComplexBlock;
|
||||||
import com.l2jmobius.commons.geodriver.blocks.FlatBlock;
|
import com.l2jmobius.gameserver.geodata.geodriver.blocks.FlatBlock;
|
||||||
import com.l2jmobius.commons.geodriver.blocks.MultilayerBlock;
|
import com.l2jmobius.gameserver.geodata.geodriver.blocks.MultilayerBlock;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author HorridoJoho
|
* @author HorridoJoho
|
||||||
@@ -1,87 +1,87 @@
|
|||||||
/*
|
/*
|
||||||
* This file is part of the L2J Mobius project.
|
* This file is part of the L2J Mobius project.
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
* General Public License for more details.
|
* General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package com.l2jmobius.gameserver.pathfinding;
|
package com.l2jmobius.gameserver.geodata.pathfinding;
|
||||||
|
|
||||||
public abstract class AbstractNode<T extends AbstractNodeLoc>
|
public abstract class AbstractNode<T extends AbstractNodeLoc>
|
||||||
{
|
{
|
||||||
private T _loc;
|
private T _loc;
|
||||||
private AbstractNode<T> _parent;
|
private AbstractNode<T> _parent;
|
||||||
|
|
||||||
public AbstractNode(T loc)
|
public AbstractNode(T loc)
|
||||||
{
|
{
|
||||||
_loc = loc;
|
_loc = loc;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setParent(AbstractNode<T> p)
|
public void setParent(AbstractNode<T> p)
|
||||||
{
|
{
|
||||||
_parent = p;
|
_parent = p;
|
||||||
}
|
}
|
||||||
|
|
||||||
public AbstractNode<T> getParent()
|
public AbstractNode<T> getParent()
|
||||||
{
|
{
|
||||||
return _parent;
|
return _parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
public T getLoc()
|
public T getLoc()
|
||||||
{
|
{
|
||||||
return _loc;
|
return _loc;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setLoc(T l)
|
public void setLoc(T l)
|
||||||
{
|
{
|
||||||
_loc = l;
|
_loc = l;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode()
|
public int hashCode()
|
||||||
{
|
{
|
||||||
final int prime = 31;
|
final int prime = 31;
|
||||||
int result = 1;
|
int result = 1;
|
||||||
result = (prime * result) + ((_loc == null) ? 0 : _loc.hashCode());
|
result = (prime * result) + ((_loc == null) ? 0 : _loc.hashCode());
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object obj)
|
public boolean equals(Object obj)
|
||||||
{
|
{
|
||||||
if (this == obj)
|
if (this == obj)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (obj == null)
|
if (obj == null)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!(obj instanceof AbstractNode))
|
if (!(obj instanceof AbstractNode))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
final AbstractNode<?> other = (AbstractNode<?>) obj;
|
final AbstractNode<?> other = (AbstractNode<?>) obj;
|
||||||
if (_loc == null)
|
if (_loc == null)
|
||||||
{
|
{
|
||||||
if (other._loc != null)
|
if (other._loc != null)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (!_loc.equals(other._loc))
|
else if (!_loc.equals(other._loc))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,33 +1,33 @@
|
|||||||
/*
|
/*
|
||||||
* This file is part of the L2J Mobius project.
|
* This file is part of the L2J Mobius project.
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
* General Public License for more details.
|
* General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package com.l2jmobius.gameserver.pathfinding;
|
package com.l2jmobius.gameserver.geodata.pathfinding;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author -Nemesiss-
|
* @author -Nemesiss-
|
||||||
*/
|
*/
|
||||||
public abstract class AbstractNodeLoc
|
public abstract class AbstractNodeLoc
|
||||||
{
|
{
|
||||||
public abstract int getX();
|
public abstract int getX();
|
||||||
|
|
||||||
public abstract int getY();
|
public abstract int getY();
|
||||||
|
|
||||||
public abstract int getZ();
|
public abstract int getZ();
|
||||||
|
|
||||||
public abstract int getNodeX();
|
public abstract int getNodeX();
|
||||||
|
|
||||||
public abstract int getNodeY();
|
public abstract int getNodeY();
|
||||||
}
|
}
|
||||||
@@ -1,211 +1,211 @@
|
|||||||
/*
|
/*
|
||||||
* This file is part of the L2J Mobius project.
|
* This file is part of the L2J Mobius project.
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
* General Public License for more details.
|
* General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package com.l2jmobius.gameserver.pathfinding;
|
package com.l2jmobius.gameserver.geodata.pathfinding;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import com.l2jmobius.Config;
|
import com.l2jmobius.Config;
|
||||||
import com.l2jmobius.gameserver.model.L2World;
|
import com.l2jmobius.gameserver.geodata.pathfinding.cellnodes.CellPathFinding;
|
||||||
import com.l2jmobius.gameserver.model.instancezone.Instance;
|
import com.l2jmobius.gameserver.geodata.pathfinding.geonodes.GeoPathFinding;
|
||||||
import com.l2jmobius.gameserver.pathfinding.cellnodes.CellPathFinding;
|
import com.l2jmobius.gameserver.model.L2World;
|
||||||
import com.l2jmobius.gameserver.pathfinding.geonodes.GeoPathFinding;
|
import com.l2jmobius.gameserver.model.instancezone.Instance;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author -Nemesiss-
|
* @author -Nemesiss-
|
||||||
*/
|
*/
|
||||||
public abstract class PathFinding
|
public abstract class PathFinding
|
||||||
{
|
{
|
||||||
public static PathFinding getInstance()
|
public static PathFinding getInstance()
|
||||||
{
|
{
|
||||||
if (Config.PATHFINDING == 1)
|
if (Config.PATHFINDING == 1)
|
||||||
{
|
{
|
||||||
// Higher Memory Usage, Smaller Cpu Usage
|
// Higher Memory Usage, Smaller Cpu Usage
|
||||||
return GeoPathFinding.getInstance();
|
return GeoPathFinding.getInstance();
|
||||||
}
|
}
|
||||||
// Cell pathfinding, calculated directly from geodata files
|
// Cell pathfinding, calculated directly from geodata files
|
||||||
return CellPathFinding.getInstance();
|
return CellPathFinding.getInstance();
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract boolean pathNodesExist(short regionoffset);
|
public abstract boolean pathNodesExist(short regionoffset);
|
||||||
|
|
||||||
public abstract List<AbstractNodeLoc> findPath(int x, int y, int z, int tx, int ty, int tz, Instance instance, boolean playable);
|
public abstract List<AbstractNodeLoc> findPath(int x, int y, int z, int tx, int ty, int tz, Instance instance, boolean playable);
|
||||||
|
|
||||||
// @formatter:off
|
// @formatter:off
|
||||||
/*
|
/*
|
||||||
public List<AbstractNodeLoc> search(AbstractNode start, AbstractNode end, int instanceId)
|
public List<AbstractNodeLoc> search(AbstractNode start, AbstractNode end, int instanceId)
|
||||||
{
|
{
|
||||||
// The simplest grid-based pathfinding.
|
// The simplest grid-based pathfinding.
|
||||||
// Drawback is not having higher cost for diagonal movement (means funny routes)
|
// Drawback is not having higher cost for diagonal movement (means funny routes)
|
||||||
// Could be optimized e.g. not to calculate backwards as far as forwards.
|
// Could be optimized e.g. not to calculate backwards as far as forwards.
|
||||||
|
|
||||||
// List of Visited Nodes
|
// List of Visited Nodes
|
||||||
LinkedList<AbstractNode> visited = new LinkedList<AbstractNode>();
|
LinkedList<AbstractNode> visited = new LinkedList<AbstractNode>();
|
||||||
|
|
||||||
// List of Nodes to Visit
|
// List of Nodes to Visit
|
||||||
LinkedList<AbstractNode> to_visit = new LinkedList<AbstractNode>();
|
LinkedList<AbstractNode> to_visit = new LinkedList<AbstractNode>();
|
||||||
to_visit.add(start);
|
to_visit.add(start);
|
||||||
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
while (i < 800)
|
while (i < 800)
|
||||||
{
|
{
|
||||||
AbstractNode node;
|
AbstractNode node;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
node = to_visit.removeFirst();
|
node = to_visit.removeFirst();
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
// No Path found
|
// No Path found
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
if (node.equals(end)) //path found!
|
if (node.equals(end)) //path found!
|
||||||
return constructPath(node, instanceId);
|
return constructPath(node, instanceId);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
i++;
|
i++;
|
||||||
visited.add(node);
|
visited.add(node);
|
||||||
node.attachNeighbors();
|
node.attachNeighbors();
|
||||||
Node[] neighbors = node.getNeighbors();
|
Node[] neighbors = node.getNeighbors();
|
||||||
if (neighbors == null)
|
if (neighbors == null)
|
||||||
continue;
|
continue;
|
||||||
for (Node n : neighbors)
|
for (Node n : neighbors)
|
||||||
{
|
{
|
||||||
if (!visited.contains(n) && !to_visit.contains(n))
|
if (!visited.contains(n) && !to_visit.contains(n))
|
||||||
{
|
{
|
||||||
n.setParent(node);
|
n.setParent(node);
|
||||||
to_visit.add(n);
|
to_visit.add(n);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//No Path found
|
//No Path found
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
public List<AbstractNodeLoc> searchAStar(Node start, Node end, int instanceId)
|
public List<AbstractNodeLoc> searchAStar(Node start, Node end, int instanceId)
|
||||||
{
|
{
|
||||||
// Not operational yet?
|
// Not operational yet?
|
||||||
int start_x = start.getLoc().getX();
|
int start_x = start.getLoc().getX();
|
||||||
int start_y = start.getLoc().getY();
|
int start_y = start.getLoc().getY();
|
||||||
int end_x = end.getLoc().getX();
|
int end_x = end.getLoc().getX();
|
||||||
int end_y = end.getLoc().getY();
|
int end_y = end.getLoc().getY();
|
||||||
//List of Visited Nodes
|
//List of Visited Nodes
|
||||||
FastNodeList visited = new FastNodeList(800);//TODO! Add limit to cfg
|
FastNodeList visited = new FastNodeList(800);//TODO! Add limit to cfg
|
||||||
|
|
||||||
// List of Nodes to Visit
|
// List of Nodes to Visit
|
||||||
BinaryNodeHeap to_visit = new BinaryNodeHeap(800);
|
BinaryNodeHeap to_visit = new BinaryNodeHeap(800);
|
||||||
to_visit.add(start);
|
to_visit.add(start);
|
||||||
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
while (i < 800)//TODO! Add limit to cfg
|
while (i < 800)//TODO! Add limit to cfg
|
||||||
{
|
{
|
||||||
AbstractNode node;
|
AbstractNode node;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
node = to_visit.removeFirst();
|
node = to_visit.removeFirst();
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
// No Path found
|
// No Path found
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
if (node.equals(end)) //path found!
|
if (node.equals(end)) //path found!
|
||||||
return constructPath(node, instanceId);
|
return constructPath(node, instanceId);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
visited.add(node);
|
visited.add(node);
|
||||||
node.attachNeighbors();
|
node.attachNeighbors();
|
||||||
for (Node n : node.getNeighbors())
|
for (Node n : node.getNeighbors())
|
||||||
{
|
{
|
||||||
if (!visited.contains(n) && !to_visit.contains(n))
|
if (!visited.contains(n) && !to_visit.contains(n))
|
||||||
{
|
{
|
||||||
i++;
|
i++;
|
||||||
n.setParent(node);
|
n.setParent(node);
|
||||||
n.setCost(Math.abs(start_x - n.getLoc().getNodeX()) + Math.abs(start_y - n.getLoc().getNodeY())
|
n.setCost(Math.abs(start_x - n.getLoc().getNodeX()) + Math.abs(start_y - n.getLoc().getNodeY())
|
||||||
+ Math.abs(end_x - n.getLoc().getNodeX()) + Math.abs(end_y - n.getLoc().getNodeY()));
|
+ Math.abs(end_x - n.getLoc().getNodeX()) + Math.abs(end_y - n.getLoc().getNodeY()));
|
||||||
to_visit.add(n);
|
to_visit.add(n);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//No Path found
|
//No Path found
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
// @formatter:on
|
// @formatter:on
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert geodata position to pathnode position
|
* Convert geodata position to pathnode position
|
||||||
* @param geo_pos
|
* @param geo_pos
|
||||||
* @return pathnode position
|
* @return pathnode position
|
||||||
*/
|
*/
|
||||||
public short getNodePos(int geo_pos)
|
public short getNodePos(int geo_pos)
|
||||||
{
|
{
|
||||||
return (short) (geo_pos >> 3); // OK?
|
return (short) (geo_pos >> 3); // OK?
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert node position to pathnode block position
|
* Convert node position to pathnode block position
|
||||||
* @param node_pos
|
* @param node_pos
|
||||||
* @return pathnode block position (0...255)
|
* @return pathnode block position (0...255)
|
||||||
*/
|
*/
|
||||||
public short getNodeBlock(int node_pos)
|
public short getNodeBlock(int node_pos)
|
||||||
{
|
{
|
||||||
return (short) (node_pos % 256);
|
return (short) (node_pos % 256);
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte getRegionX(int node_pos)
|
public byte getRegionX(int node_pos)
|
||||||
{
|
{
|
||||||
return (byte) ((node_pos >> 8) + L2World.TILE_X_MIN);
|
return (byte) ((node_pos >> 8) + L2World.TILE_X_MIN);
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte getRegionY(int node_pos)
|
public byte getRegionY(int node_pos)
|
||||||
{
|
{
|
||||||
return (byte) ((node_pos >> 8) + L2World.TILE_Y_MIN);
|
return (byte) ((node_pos >> 8) + L2World.TILE_Y_MIN);
|
||||||
}
|
}
|
||||||
|
|
||||||
public short getRegionOffset(byte rx, byte ry)
|
public short getRegionOffset(byte rx, byte ry)
|
||||||
{
|
{
|
||||||
return (short) ((rx << 5) + ry);
|
return (short) ((rx << 5) + ry);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert pathnode x to World x position
|
* Convert pathnode x to World x position
|
||||||
* @param node_x rx
|
* @param node_x rx
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public int calculateWorldX(short node_x)
|
public int calculateWorldX(short node_x)
|
||||||
{
|
{
|
||||||
return L2World.MAP_MIN_X + (node_x * 128) + 48;
|
return L2World.MAP_MIN_X + (node_x * 128) + 48;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert pathnode y to World y position
|
* Convert pathnode y to World y position
|
||||||
* @param node_y
|
* @param node_y
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public int calculateWorldY(short node_y)
|
public int calculateWorldY(short node_y)
|
||||||
{
|
{
|
||||||
return L2World.MAP_MIN_Y + (node_y * 128) + 48;
|
return L2World.MAP_MIN_Y + (node_y * 128) + 48;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String[] getStat()
|
public String[] getStat()
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,69 +1,69 @@
|
|||||||
/*
|
/*
|
||||||
* This file is part of the L2J Mobius project.
|
* This file is part of the L2J Mobius project.
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
* General Public License for more details.
|
* General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package com.l2jmobius.gameserver.pathfinding.cellnodes;
|
package com.l2jmobius.gameserver.geodata.pathfinding.cellnodes;
|
||||||
|
|
||||||
import com.l2jmobius.gameserver.pathfinding.AbstractNode;
|
import com.l2jmobius.gameserver.geodata.pathfinding.AbstractNode;
|
||||||
|
|
||||||
public class CellNode extends AbstractNode<NodeLoc>
|
public class CellNode extends AbstractNode<NodeLoc>
|
||||||
{
|
{
|
||||||
private CellNode _next = null;
|
private CellNode _next = null;
|
||||||
private boolean _isInUse = true;
|
private boolean _isInUse = true;
|
||||||
private float _cost = -1000;
|
private float _cost = -1000;
|
||||||
|
|
||||||
public CellNode(NodeLoc loc)
|
public CellNode(NodeLoc loc)
|
||||||
{
|
{
|
||||||
super(loc);
|
super(loc);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isInUse()
|
public boolean isInUse()
|
||||||
{
|
{
|
||||||
return _isInUse;
|
return _isInUse;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setInUse()
|
public void setInUse()
|
||||||
{
|
{
|
||||||
_isInUse = true;
|
_isInUse = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public CellNode getNext()
|
public CellNode getNext()
|
||||||
{
|
{
|
||||||
return _next;
|
return _next;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setNext(CellNode next)
|
public void setNext(CellNode next)
|
||||||
{
|
{
|
||||||
_next = next;
|
_next = next;
|
||||||
}
|
}
|
||||||
|
|
||||||
public float getCost()
|
public float getCost()
|
||||||
{
|
{
|
||||||
return _cost;
|
return _cost;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setCost(double cost)
|
public void setCost(double cost)
|
||||||
{
|
{
|
||||||
_cost = (float) cost;
|
_cost = (float) cost;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void free()
|
public void free()
|
||||||
{
|
{
|
||||||
setParent(null);
|
setParent(null);
|
||||||
_cost = -1000;
|
_cost = -1000;
|
||||||
_isInUse = false;
|
_isInUse = false;
|
||||||
_next = null;
|
_next = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,361 +1,361 @@
|
|||||||
/*
|
/*
|
||||||
* This file is part of the L2J Mobius project.
|
* This file is part of the L2J Mobius project.
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
* General Public License for more details.
|
* General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package com.l2jmobius.gameserver.pathfinding.cellnodes;
|
package com.l2jmobius.gameserver.geodata.pathfinding.cellnodes;
|
||||||
|
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.locks.ReentrantLock;
|
import java.util.concurrent.locks.ReentrantLock;
|
||||||
|
|
||||||
import com.l2jmobius.Config;
|
import com.l2jmobius.Config;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author DS Credits to Diamond
|
* @author DS Credits to Diamond
|
||||||
*/
|
*/
|
||||||
public class CellNodeBuffer
|
public class CellNodeBuffer
|
||||||
{
|
{
|
||||||
private static final int MAX_ITERATIONS = 3500;
|
private static final int MAX_ITERATIONS = 3500;
|
||||||
|
|
||||||
private final ReentrantLock _lock = new ReentrantLock();
|
private final ReentrantLock _lock = new ReentrantLock();
|
||||||
private final int _mapSize;
|
private final int _mapSize;
|
||||||
private final CellNode[][] _buffer;
|
private final CellNode[][] _buffer;
|
||||||
|
|
||||||
private int _baseX = 0;
|
private int _baseX = 0;
|
||||||
private int _baseY = 0;
|
private int _baseY = 0;
|
||||||
|
|
||||||
private int _targetX = 0;
|
private int _targetX = 0;
|
||||||
private int _targetY = 0;
|
private int _targetY = 0;
|
||||||
private int _targetZ = 0;
|
private int _targetZ = 0;
|
||||||
|
|
||||||
private long _timeStamp = 0;
|
private long _timeStamp = 0;
|
||||||
private long _lastElapsedTime = 0;
|
private long _lastElapsedTime = 0;
|
||||||
|
|
||||||
private CellNode _current = null;
|
private CellNode _current = null;
|
||||||
|
|
||||||
public CellNodeBuffer(int size)
|
public CellNodeBuffer(int size)
|
||||||
{
|
{
|
||||||
_mapSize = size;
|
_mapSize = size;
|
||||||
_buffer = new CellNode[_mapSize][_mapSize];
|
_buffer = new CellNode[_mapSize][_mapSize];
|
||||||
}
|
}
|
||||||
|
|
||||||
public final boolean lock()
|
public final boolean lock()
|
||||||
{
|
{
|
||||||
return _lock.tryLock();
|
return _lock.tryLock();
|
||||||
}
|
}
|
||||||
|
|
||||||
public final CellNode findPath(int x, int y, int z, int tx, int ty, int tz)
|
public final CellNode findPath(int x, int y, int z, int tx, int ty, int tz)
|
||||||
{
|
{
|
||||||
_timeStamp = System.currentTimeMillis();
|
_timeStamp = System.currentTimeMillis();
|
||||||
_baseX = x + ((tx - x - _mapSize) / 2); // middle of the line (x,y) - (tx,ty)
|
_baseX = x + ((tx - x - _mapSize) / 2); // middle of the line (x,y) - (tx,ty)
|
||||||
_baseY = y + ((ty - y - _mapSize) / 2); // will be in the center of the buffer
|
_baseY = y + ((ty - y - _mapSize) / 2); // will be in the center of the buffer
|
||||||
_targetX = tx;
|
_targetX = tx;
|
||||||
_targetY = ty;
|
_targetY = ty;
|
||||||
_targetZ = tz;
|
_targetZ = tz;
|
||||||
_current = getNode(x, y, z);
|
_current = getNode(x, y, z);
|
||||||
_current.setCost(getCost(x, y, z, Config.HIGH_WEIGHT));
|
_current.setCost(getCost(x, y, z, Config.HIGH_WEIGHT));
|
||||||
|
|
||||||
for (int count = 0; count < MAX_ITERATIONS; count++)
|
for (int count = 0; count < MAX_ITERATIONS; count++)
|
||||||
{
|
{
|
||||||
if ((_current.getLoc().getNodeX() == _targetX) && (_current.getLoc().getNodeY() == _targetY) && (Math.abs(_current.getLoc().getZ() - _targetZ) < 64))
|
if ((_current.getLoc().getNodeX() == _targetX) && (_current.getLoc().getNodeY() == _targetY) && (Math.abs(_current.getLoc().getZ() - _targetZ) < 64))
|
||||||
{
|
{
|
||||||
return _current; // found
|
return _current; // found
|
||||||
}
|
}
|
||||||
|
|
||||||
getNeighbors();
|
getNeighbors();
|
||||||
if (_current.getNext() == null)
|
if (_current.getNext() == null)
|
||||||
{
|
{
|
||||||
return null; // no more ways
|
return null; // no more ways
|
||||||
}
|
}
|
||||||
|
|
||||||
_current = _current.getNext();
|
_current = _current.getNext();
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public final void free()
|
public final void free()
|
||||||
{
|
{
|
||||||
_current = null;
|
_current = null;
|
||||||
|
|
||||||
CellNode node;
|
CellNode node;
|
||||||
for (int i = 0; i < _mapSize; i++)
|
for (int i = 0; i < _mapSize; i++)
|
||||||
{
|
{
|
||||||
for (int j = 0; j < _mapSize; j++)
|
for (int j = 0; j < _mapSize; j++)
|
||||||
{
|
{
|
||||||
node = _buffer[i][j];
|
node = _buffer[i][j];
|
||||||
if (node != null)
|
if (node != null)
|
||||||
{
|
{
|
||||||
node.free();
|
node.free();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_lock.unlock();
|
_lock.unlock();
|
||||||
_lastElapsedTime = System.currentTimeMillis() - _timeStamp;
|
_lastElapsedTime = System.currentTimeMillis() - _timeStamp;
|
||||||
}
|
}
|
||||||
|
|
||||||
public final long getElapsedTime()
|
public final long getElapsedTime()
|
||||||
{
|
{
|
||||||
return _lastElapsedTime;
|
return _lastElapsedTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
public final List<CellNode> debugPath()
|
public final List<CellNode> debugPath()
|
||||||
{
|
{
|
||||||
final List<CellNode> result = new LinkedList<>();
|
final List<CellNode> result = new LinkedList<>();
|
||||||
|
|
||||||
for (CellNode n = _current; n.getParent() != null; n = (CellNode) n.getParent())
|
for (CellNode n = _current; n.getParent() != null; n = (CellNode) n.getParent())
|
||||||
{
|
{
|
||||||
result.add(n);
|
result.add(n);
|
||||||
n.setCost(-n.getCost());
|
n.setCost(-n.getCost());
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < _mapSize; i++)
|
for (int i = 0; i < _mapSize; i++)
|
||||||
{
|
{
|
||||||
for (int j = 0; j < _mapSize; j++)
|
for (int j = 0; j < _mapSize; j++)
|
||||||
{
|
{
|
||||||
final CellNode n = _buffer[i][j];
|
final CellNode n = _buffer[i][j];
|
||||||
if ((n == null) || !n.isInUse() || (n.getCost() <= 0))
|
if ((n == null) || !n.isInUse() || (n.getCost() <= 0))
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
result.add(n);
|
result.add(n);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void getNeighbors()
|
private void getNeighbors()
|
||||||
{
|
{
|
||||||
if (!_current.getLoc().canGoAll())
|
if (!_current.getLoc().canGoAll())
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
final int x = _current.getLoc().getNodeX();
|
final int x = _current.getLoc().getNodeX();
|
||||||
final int y = _current.getLoc().getNodeY();
|
final int y = _current.getLoc().getNodeY();
|
||||||
final int z = _current.getLoc().getZ();
|
final int z = _current.getLoc().getZ();
|
||||||
|
|
||||||
CellNode nodeE = null;
|
CellNode nodeE = null;
|
||||||
CellNode nodeS = null;
|
CellNode nodeS = null;
|
||||||
CellNode nodeW = null;
|
CellNode nodeW = null;
|
||||||
CellNode nodeN = null;
|
CellNode nodeN = null;
|
||||||
|
|
||||||
// East
|
// East
|
||||||
if (_current.getLoc().canGoEast())
|
if (_current.getLoc().canGoEast())
|
||||||
{
|
{
|
||||||
nodeE = addNode(x + 1, y, z, false);
|
nodeE = addNode(x + 1, y, z, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
// South
|
// South
|
||||||
if (_current.getLoc().canGoSouth())
|
if (_current.getLoc().canGoSouth())
|
||||||
{
|
{
|
||||||
nodeS = addNode(x, y + 1, z, false);
|
nodeS = addNode(x, y + 1, z, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
// West
|
// West
|
||||||
if (_current.getLoc().canGoWest())
|
if (_current.getLoc().canGoWest())
|
||||||
{
|
{
|
||||||
nodeW = addNode(x - 1, y, z, false);
|
nodeW = addNode(x - 1, y, z, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
// North
|
// North
|
||||||
if (_current.getLoc().canGoNorth())
|
if (_current.getLoc().canGoNorth())
|
||||||
{
|
{
|
||||||
nodeN = addNode(x, y - 1, z, false);
|
nodeN = addNode(x, y - 1, z, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Config.ADVANCED_DIAGONAL_STRATEGY)
|
if (Config.ADVANCED_DIAGONAL_STRATEGY)
|
||||||
{
|
{
|
||||||
// SouthEast
|
// SouthEast
|
||||||
if ((nodeE != null) && (nodeS != null))
|
if ((nodeE != null) && (nodeS != null))
|
||||||
{
|
{
|
||||||
if (nodeE.getLoc().canGoSouth() && nodeS.getLoc().canGoEast())
|
if (nodeE.getLoc().canGoSouth() && nodeS.getLoc().canGoEast())
|
||||||
{
|
{
|
||||||
addNode(x + 1, y + 1, z, true);
|
addNode(x + 1, y + 1, z, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// SouthWest
|
// SouthWest
|
||||||
if ((nodeS != null) && (nodeW != null))
|
if ((nodeS != null) && (nodeW != null))
|
||||||
{
|
{
|
||||||
if (nodeW.getLoc().canGoSouth() && nodeS.getLoc().canGoWest())
|
if (nodeW.getLoc().canGoSouth() && nodeS.getLoc().canGoWest())
|
||||||
{
|
{
|
||||||
addNode(x - 1, y + 1, z, true);
|
addNode(x - 1, y + 1, z, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// NorthEast
|
// NorthEast
|
||||||
if ((nodeN != null) && (nodeE != null))
|
if ((nodeN != null) && (nodeE != null))
|
||||||
{
|
{
|
||||||
if (nodeE.getLoc().canGoNorth() && nodeN.getLoc().canGoEast())
|
if (nodeE.getLoc().canGoNorth() && nodeN.getLoc().canGoEast())
|
||||||
{
|
{
|
||||||
addNode(x + 1, y - 1, z, true);
|
addNode(x + 1, y - 1, z, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// NorthWest
|
// NorthWest
|
||||||
if ((nodeN != null) && (nodeW != null))
|
if ((nodeN != null) && (nodeW != null))
|
||||||
{
|
{
|
||||||
if (nodeW.getLoc().canGoNorth() && nodeN.getLoc().canGoWest())
|
if (nodeW.getLoc().canGoNorth() && nodeN.getLoc().canGoWest())
|
||||||
{
|
{
|
||||||
addNode(x - 1, y - 1, z, true);
|
addNode(x - 1, y - 1, z, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private CellNode getNode(int x, int y, int z)
|
private CellNode getNode(int x, int y, int z)
|
||||||
{
|
{
|
||||||
final int aX = x - _baseX;
|
final int aX = x - _baseX;
|
||||||
if ((aX < 0) || (aX >= _mapSize))
|
if ((aX < 0) || (aX >= _mapSize))
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
final int aY = y - _baseY;
|
final int aY = y - _baseY;
|
||||||
if ((aY < 0) || (aY >= _mapSize))
|
if ((aY < 0) || (aY >= _mapSize))
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
CellNode result = _buffer[aX][aY];
|
CellNode result = _buffer[aX][aY];
|
||||||
if (result == null)
|
if (result == null)
|
||||||
{
|
{
|
||||||
result = new CellNode(new NodeLoc(x, y, z));
|
result = new CellNode(new NodeLoc(x, y, z));
|
||||||
_buffer[aX][aY] = result;
|
_buffer[aX][aY] = result;
|
||||||
}
|
}
|
||||||
else if (!result.isInUse())
|
else if (!result.isInUse())
|
||||||
{
|
{
|
||||||
result.setInUse();
|
result.setInUse();
|
||||||
// reinit node if needed
|
// reinit node if needed
|
||||||
if (result.getLoc() != null)
|
if (result.getLoc() != null)
|
||||||
{
|
{
|
||||||
result.getLoc().set(x, y, z);
|
result.getLoc().set(x, y, z);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
result.setLoc(new NodeLoc(x, y, z));
|
result.setLoc(new NodeLoc(x, y, z));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private CellNode addNode(int x, int y, int z, boolean diagonal)
|
private CellNode addNode(int x, int y, int z, boolean diagonal)
|
||||||
{
|
{
|
||||||
final CellNode newNode = getNode(x, y, z);
|
final CellNode newNode = getNode(x, y, z);
|
||||||
if (newNode == null)
|
if (newNode == null)
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
if (newNode.getCost() >= 0)
|
if (newNode.getCost() >= 0)
|
||||||
{
|
{
|
||||||
return newNode;
|
return newNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
final int geoZ = newNode.getLoc().getZ();
|
final int geoZ = newNode.getLoc().getZ();
|
||||||
|
|
||||||
final int stepZ = Math.abs(geoZ - _current.getLoc().getZ());
|
final int stepZ = Math.abs(geoZ - _current.getLoc().getZ());
|
||||||
float weight = diagonal ? Config.DIAGONAL_WEIGHT : Config.LOW_WEIGHT;
|
float weight = diagonal ? Config.DIAGONAL_WEIGHT : Config.LOW_WEIGHT;
|
||||||
|
|
||||||
if (!newNode.getLoc().canGoAll() || (stepZ > 16))
|
if (!newNode.getLoc().canGoAll() || (stepZ > 16))
|
||||||
{
|
{
|
||||||
weight = Config.HIGH_WEIGHT;
|
weight = Config.HIGH_WEIGHT;
|
||||||
}
|
}
|
||||||
else if (isHighWeight(x + 1, y, geoZ))
|
else if (isHighWeight(x + 1, y, geoZ))
|
||||||
{
|
{
|
||||||
weight = Config.MEDIUM_WEIGHT;
|
weight = Config.MEDIUM_WEIGHT;
|
||||||
}
|
}
|
||||||
else if (isHighWeight(x - 1, y, geoZ))
|
else if (isHighWeight(x - 1, y, geoZ))
|
||||||
{
|
{
|
||||||
weight = Config.MEDIUM_WEIGHT;
|
weight = Config.MEDIUM_WEIGHT;
|
||||||
}
|
}
|
||||||
else if (isHighWeight(x, y + 1, geoZ))
|
else if (isHighWeight(x, y + 1, geoZ))
|
||||||
{
|
{
|
||||||
weight = Config.MEDIUM_WEIGHT;
|
weight = Config.MEDIUM_WEIGHT;
|
||||||
}
|
}
|
||||||
else if (isHighWeight(x, y - 1, geoZ))
|
else if (isHighWeight(x, y - 1, geoZ))
|
||||||
{
|
{
|
||||||
weight = Config.MEDIUM_WEIGHT;
|
weight = Config.MEDIUM_WEIGHT;
|
||||||
}
|
}
|
||||||
|
|
||||||
newNode.setParent(_current);
|
newNode.setParent(_current);
|
||||||
newNode.setCost(getCost(x, y, geoZ, weight));
|
newNode.setCost(getCost(x, y, geoZ, weight));
|
||||||
|
|
||||||
CellNode node = _current;
|
CellNode node = _current;
|
||||||
int count = 0;
|
int count = 0;
|
||||||
while ((node.getNext() != null) && (count < (MAX_ITERATIONS * 4)))
|
while ((node.getNext() != null) && (count < (MAX_ITERATIONS * 4)))
|
||||||
{
|
{
|
||||||
count++;
|
count++;
|
||||||
if (node.getNext().getCost() > newNode.getCost())
|
if (node.getNext().getCost() > newNode.getCost())
|
||||||
{
|
{
|
||||||
// insert node into a chain
|
// insert node into a chain
|
||||||
newNode.setNext(node.getNext());
|
newNode.setNext(node.getNext());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
node = node.getNext();
|
node = node.getNext();
|
||||||
}
|
}
|
||||||
if (count == (MAX_ITERATIONS * 4))
|
if (count == (MAX_ITERATIONS * 4))
|
||||||
{
|
{
|
||||||
System.err.println("Pathfinding: too long loop detected, cost:" + newNode.getCost());
|
System.err.println("Pathfinding: too long loop detected, cost:" + newNode.getCost());
|
||||||
}
|
}
|
||||||
|
|
||||||
node.setNext(newNode); // add last
|
node.setNext(newNode); // add last
|
||||||
|
|
||||||
return newNode;
|
return newNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isHighWeight(int x, int y, int z)
|
private boolean isHighWeight(int x, int y, int z)
|
||||||
{
|
{
|
||||||
final CellNode result = getNode(x, y, z);
|
final CellNode result = getNode(x, y, z);
|
||||||
if (result == null)
|
if (result == null)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!result.getLoc().canGoAll())
|
if (!result.getLoc().canGoAll())
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (Math.abs(result.getLoc().getZ() - z) > 16)
|
if (Math.abs(result.getLoc().getZ() - z) > 16)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private double getCost(int x, int y, int z, float weight)
|
private double getCost(int x, int y, int z, float weight)
|
||||||
{
|
{
|
||||||
final int dX = x - _targetX;
|
final int dX = x - _targetX;
|
||||||
final int dY = y - _targetY;
|
final int dY = y - _targetY;
|
||||||
final int dZ = z - _targetZ;
|
final int dZ = z - _targetZ;
|
||||||
// Math.abs(dx) + Math.abs(dy) + Math.abs(dz) / 16
|
// Math.abs(dx) + Math.abs(dy) + Math.abs(dz) / 16
|
||||||
double result = Math.sqrt((dX * dX) + (dY * dY) + ((dZ * dZ) / 256.0));
|
double result = Math.sqrt((dX * dX) + (dY * dY) + ((dZ * dZ) / 256.0));
|
||||||
if (result > weight)
|
if (result > weight)
|
||||||
{
|
{
|
||||||
result += weight;
|
result += weight;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result > Float.MAX_VALUE)
|
if (result > Float.MAX_VALUE)
|
||||||
{
|
{
|
||||||
result = Float.MAX_VALUE;
|
result = Float.MAX_VALUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,440 +1,440 @@
|
|||||||
/*
|
/*
|
||||||
* This file is part of the L2J Mobius project.
|
* This file is part of the L2J Mobius project.
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
* General Public License for more details.
|
* General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package com.l2jmobius.gameserver.pathfinding.cellnodes;
|
package com.l2jmobius.gameserver.geodata.pathfinding.cellnodes;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.ListIterator;
|
import java.util.ListIterator;
|
||||||
import java.util.concurrent.CopyOnWriteArrayList;
|
import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import com.l2jmobius.Config;
|
import com.l2jmobius.Config;
|
||||||
import com.l2jmobius.gameserver.GeoData;
|
import com.l2jmobius.gameserver.GeoData;
|
||||||
import com.l2jmobius.gameserver.idfactory.IdFactory;
|
import com.l2jmobius.gameserver.geodata.pathfinding.AbstractNode;
|
||||||
import com.l2jmobius.gameserver.model.instancezone.Instance;
|
import com.l2jmobius.gameserver.geodata.pathfinding.AbstractNodeLoc;
|
||||||
import com.l2jmobius.gameserver.model.itemcontainer.Inventory;
|
import com.l2jmobius.gameserver.geodata.pathfinding.PathFinding;
|
||||||
import com.l2jmobius.gameserver.model.items.instance.L2ItemInstance;
|
import com.l2jmobius.gameserver.idfactory.IdFactory;
|
||||||
import com.l2jmobius.gameserver.pathfinding.AbstractNode;
|
import com.l2jmobius.gameserver.model.instancezone.Instance;
|
||||||
import com.l2jmobius.gameserver.pathfinding.AbstractNodeLoc;
|
import com.l2jmobius.gameserver.model.itemcontainer.Inventory;
|
||||||
import com.l2jmobius.gameserver.pathfinding.PathFinding;
|
import com.l2jmobius.gameserver.model.items.instance.L2ItemInstance;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Sami, DS Credits to Diamond
|
* @author Sami, DS Credits to Diamond
|
||||||
*/
|
*/
|
||||||
public class CellPathFinding extends PathFinding
|
public class CellPathFinding extends PathFinding
|
||||||
{
|
{
|
||||||
private static final Logger _log = Logger.getLogger(CellPathFinding.class.getName());
|
private static final Logger _log = Logger.getLogger(CellPathFinding.class.getName());
|
||||||
private BufferInfo[] _allBuffers;
|
private BufferInfo[] _allBuffers;
|
||||||
private int _findSuccess = 0;
|
private int _findSuccess = 0;
|
||||||
private int _findFails = 0;
|
private int _findFails = 0;
|
||||||
private int _postFilterUses = 0;
|
private int _postFilterUses = 0;
|
||||||
private int _postFilterPlayableUses = 0;
|
private int _postFilterPlayableUses = 0;
|
||||||
private int _postFilterPasses = 0;
|
private int _postFilterPasses = 0;
|
||||||
private long _postFilterElapsed = 0;
|
private long _postFilterElapsed = 0;
|
||||||
|
|
||||||
private List<L2ItemInstance> _debugItems = null;
|
private List<L2ItemInstance> _debugItems = null;
|
||||||
|
|
||||||
public static CellPathFinding getInstance()
|
public static CellPathFinding getInstance()
|
||||||
{
|
{
|
||||||
return SingletonHolder._instance;
|
return SingletonHolder._instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected CellPathFinding()
|
protected CellPathFinding()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
final String[] array = Config.PATHFIND_BUFFERS.split(";");
|
final String[] array = Config.PATHFIND_BUFFERS.split(";");
|
||||||
|
|
||||||
_allBuffers = new BufferInfo[array.length];
|
_allBuffers = new BufferInfo[array.length];
|
||||||
|
|
||||||
String buf;
|
String buf;
|
||||||
String[] args;
|
String[] args;
|
||||||
for (int i = 0; i < array.length; i++)
|
for (int i = 0; i < array.length; i++)
|
||||||
{
|
{
|
||||||
buf = array[i];
|
buf = array[i];
|
||||||
args = buf.split("x");
|
args = buf.split("x");
|
||||||
if (args.length != 2)
|
if (args.length != 2)
|
||||||
{
|
{
|
||||||
throw new Exception("Invalid buffer definition: " + buf);
|
throw new Exception("Invalid buffer definition: " + buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
_allBuffers[i] = new BufferInfo(Integer.parseInt(args[0]), Integer.parseInt(args[1]));
|
_allBuffers[i] = new BufferInfo(Integer.parseInt(args[0]), Integer.parseInt(args[1]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
_log.log(Level.WARNING, "CellPathFinding: Problem during buffer init: " + e.getMessage(), e);
|
_log.log(Level.WARNING, "CellPathFinding: Problem during buffer init: " + e.getMessage(), e);
|
||||||
throw new Error("CellPathFinding: load aborted");
|
throw new Error("CellPathFinding: load aborted");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean pathNodesExist(short regionoffset)
|
public boolean pathNodesExist(short regionoffset)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<AbstractNodeLoc> findPath(int x, int y, int z, int tx, int ty, int tz, Instance instance, boolean playable)
|
public List<AbstractNodeLoc> findPath(int x, int y, int z, int tx, int ty, int tz, Instance instance, boolean playable)
|
||||||
{
|
{
|
||||||
final int gx = GeoData.getInstance().getGeoX(x);
|
final int gx = GeoData.getInstance().getGeoX(x);
|
||||||
final int gy = GeoData.getInstance().getGeoY(y);
|
final int gy = GeoData.getInstance().getGeoY(y);
|
||||||
if (!GeoData.getInstance().hasGeo(x, y))
|
if (!GeoData.getInstance().hasGeo(x, y))
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
final int gz = GeoData.getInstance().getHeight(x, y, z);
|
final int gz = GeoData.getInstance().getHeight(x, y, z);
|
||||||
final int gtx = GeoData.getInstance().getGeoX(tx);
|
final int gtx = GeoData.getInstance().getGeoX(tx);
|
||||||
final int gty = GeoData.getInstance().getGeoY(ty);
|
final int gty = GeoData.getInstance().getGeoY(ty);
|
||||||
if (!GeoData.getInstance().hasGeo(tx, ty))
|
if (!GeoData.getInstance().hasGeo(tx, ty))
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
final int gtz = GeoData.getInstance().getHeight(tx, ty, tz);
|
final int gtz = GeoData.getInstance().getHeight(tx, ty, tz);
|
||||||
final CellNodeBuffer buffer = alloc(64 + (2 * Math.max(Math.abs(gx - gtx), Math.abs(gy - gty))), playable);
|
final CellNodeBuffer buffer = alloc(64 + (2 * Math.max(Math.abs(gx - gtx), Math.abs(gy - gty))), playable);
|
||||||
if (buffer == null)
|
if (buffer == null)
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
final boolean debug = playable && Config.DEBUG_PATH;
|
final boolean debug = playable && Config.DEBUG_PATH;
|
||||||
|
|
||||||
if (debug)
|
if (debug)
|
||||||
{
|
{
|
||||||
if (_debugItems == null)
|
if (_debugItems == null)
|
||||||
{
|
{
|
||||||
_debugItems = new CopyOnWriteArrayList<>();
|
_debugItems = new CopyOnWriteArrayList<>();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for (L2ItemInstance item : _debugItems)
|
for (L2ItemInstance item : _debugItems)
|
||||||
{
|
{
|
||||||
if (item == null)
|
if (item == null)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
item.decayMe();
|
item.decayMe();
|
||||||
}
|
}
|
||||||
|
|
||||||
_debugItems.clear();
|
_debugItems.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
List<AbstractNodeLoc> path = null;
|
List<AbstractNodeLoc> path = null;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
final CellNode result = buffer.findPath(gx, gy, gz, gtx, gty, gtz);
|
final CellNode result = buffer.findPath(gx, gy, gz, gtx, gty, gtz);
|
||||||
|
|
||||||
if (debug)
|
if (debug)
|
||||||
{
|
{
|
||||||
for (CellNode n : buffer.debugPath())
|
for (CellNode n : buffer.debugPath())
|
||||||
{
|
{
|
||||||
if (n.getCost() < 0)
|
if (n.getCost() < 0)
|
||||||
{
|
{
|
||||||
dropDebugItem(1831, (int) (-n.getCost() * 10), n.getLoc());
|
dropDebugItem(1831, (int) (-n.getCost() * 10), n.getLoc());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// known nodes
|
// known nodes
|
||||||
dropDebugItem(Inventory.ADENA_ID, (int) (n.getCost() * 10), n.getLoc());
|
dropDebugItem(Inventory.ADENA_ID, (int) (n.getCost() * 10), n.getLoc());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result == null)
|
if (result == null)
|
||||||
{
|
{
|
||||||
_findFails++;
|
_findFails++;
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
path = constructPath(result);
|
path = constructPath(result);
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
_log.log(Level.WARNING, "", e);
|
_log.log(Level.WARNING, "", e);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
buffer.free();
|
buffer.free();
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((path.size() < 3) || (Config.MAX_POSTFILTER_PASSES <= 0))
|
if ((path.size() < 3) || (Config.MAX_POSTFILTER_PASSES <= 0))
|
||||||
{
|
{
|
||||||
_findSuccess++;
|
_findSuccess++;
|
||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
final long timeStamp = System.currentTimeMillis();
|
final long timeStamp = System.currentTimeMillis();
|
||||||
_postFilterUses++;
|
_postFilterUses++;
|
||||||
if (playable)
|
if (playable)
|
||||||
{
|
{
|
||||||
_postFilterPlayableUses++;
|
_postFilterPlayableUses++;
|
||||||
}
|
}
|
||||||
|
|
||||||
int currentX, currentY, currentZ;
|
int currentX, currentY, currentZ;
|
||||||
ListIterator<AbstractNodeLoc> middlePoint;
|
ListIterator<AbstractNodeLoc> middlePoint;
|
||||||
boolean remove;
|
boolean remove;
|
||||||
int pass = 0;
|
int pass = 0;
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
pass++;
|
pass++;
|
||||||
_postFilterPasses++;
|
_postFilterPasses++;
|
||||||
|
|
||||||
remove = false;
|
remove = false;
|
||||||
middlePoint = path.listIterator();
|
middlePoint = path.listIterator();
|
||||||
currentX = x;
|
currentX = x;
|
||||||
currentY = y;
|
currentY = y;
|
||||||
currentZ = z;
|
currentZ = z;
|
||||||
|
|
||||||
while (middlePoint.hasNext())
|
while (middlePoint.hasNext())
|
||||||
{
|
{
|
||||||
final AbstractNodeLoc locMiddle = middlePoint.next();
|
final AbstractNodeLoc locMiddle = middlePoint.next();
|
||||||
if (!middlePoint.hasNext())
|
if (!middlePoint.hasNext())
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
final AbstractNodeLoc locEnd = path.get(middlePoint.nextIndex());
|
final AbstractNodeLoc locEnd = path.get(middlePoint.nextIndex());
|
||||||
if (GeoData.getInstance().canMove(currentX, currentY, currentZ, locEnd.getX(), locEnd.getY(), locEnd.getZ(), instance))
|
if (GeoData.getInstance().canMove(currentX, currentY, currentZ, locEnd.getX(), locEnd.getY(), locEnd.getZ(), instance))
|
||||||
{
|
{
|
||||||
middlePoint.remove();
|
middlePoint.remove();
|
||||||
remove = true;
|
remove = true;
|
||||||
if (debug)
|
if (debug)
|
||||||
{
|
{
|
||||||
dropDebugItem(735, 1, locMiddle);
|
dropDebugItem(735, 1, locMiddle);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
currentX = locMiddle.getX();
|
currentX = locMiddle.getX();
|
||||||
currentY = locMiddle.getY();
|
currentY = locMiddle.getY();
|
||||||
currentZ = locMiddle.getZ();
|
currentZ = locMiddle.getZ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// only one postfilter pass for AI
|
// only one postfilter pass for AI
|
||||||
while (playable && remove && (path.size() > 2) && (pass < Config.MAX_POSTFILTER_PASSES));
|
while (playable && remove && (path.size() > 2) && (pass < Config.MAX_POSTFILTER_PASSES));
|
||||||
|
|
||||||
if (debug)
|
if (debug)
|
||||||
{
|
{
|
||||||
path.forEach(n -> dropDebugItem(65, 1, n));
|
path.forEach(n -> dropDebugItem(65, 1, n));
|
||||||
}
|
}
|
||||||
|
|
||||||
_findSuccess++;
|
_findSuccess++;
|
||||||
_postFilterElapsed += System.currentTimeMillis() - timeStamp;
|
_postFilterElapsed += System.currentTimeMillis() - timeStamp;
|
||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<AbstractNodeLoc> constructPath(AbstractNode<NodeLoc> node)
|
private List<AbstractNodeLoc> constructPath(AbstractNode<NodeLoc> node)
|
||||||
{
|
{
|
||||||
final LinkedList<AbstractNodeLoc> path = new LinkedList<>();
|
final LinkedList<AbstractNodeLoc> path = new LinkedList<>();
|
||||||
int previousDirectionX = Integer.MIN_VALUE;
|
int previousDirectionX = Integer.MIN_VALUE;
|
||||||
int previousDirectionY = Integer.MIN_VALUE;
|
int previousDirectionY = Integer.MIN_VALUE;
|
||||||
int directionX, directionY;
|
int directionX, directionY;
|
||||||
|
|
||||||
while (node.getParent() != null)
|
while (node.getParent() != null)
|
||||||
{
|
{
|
||||||
if (!Config.ADVANCED_DIAGONAL_STRATEGY && (node.getParent().getParent() != null))
|
if (!Config.ADVANCED_DIAGONAL_STRATEGY && (node.getParent().getParent() != null))
|
||||||
{
|
{
|
||||||
final int tmpX = node.getLoc().getNodeX() - node.getParent().getParent().getLoc().getNodeX();
|
final int tmpX = node.getLoc().getNodeX() - node.getParent().getParent().getLoc().getNodeX();
|
||||||
final int tmpY = node.getLoc().getNodeY() - node.getParent().getParent().getLoc().getNodeY();
|
final int tmpY = node.getLoc().getNodeY() - node.getParent().getParent().getLoc().getNodeY();
|
||||||
if (Math.abs(tmpX) == Math.abs(tmpY))
|
if (Math.abs(tmpX) == Math.abs(tmpY))
|
||||||
{
|
{
|
||||||
directionX = tmpX;
|
directionX = tmpX;
|
||||||
directionY = tmpY;
|
directionY = tmpY;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
directionX = node.getLoc().getNodeX() - node.getParent().getLoc().getNodeX();
|
directionX = node.getLoc().getNodeX() - node.getParent().getLoc().getNodeX();
|
||||||
directionY = node.getLoc().getNodeY() - node.getParent().getLoc().getNodeY();
|
directionY = node.getLoc().getNodeY() - node.getParent().getLoc().getNodeY();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
directionX = node.getLoc().getNodeX() - node.getParent().getLoc().getNodeX();
|
directionX = node.getLoc().getNodeX() - node.getParent().getLoc().getNodeX();
|
||||||
directionY = node.getLoc().getNodeY() - node.getParent().getLoc().getNodeY();
|
directionY = node.getLoc().getNodeY() - node.getParent().getLoc().getNodeY();
|
||||||
}
|
}
|
||||||
|
|
||||||
// only add a new route point if moving direction changes
|
// only add a new route point if moving direction changes
|
||||||
if ((directionX != previousDirectionX) || (directionY != previousDirectionY))
|
if ((directionX != previousDirectionX) || (directionY != previousDirectionY))
|
||||||
{
|
{
|
||||||
previousDirectionX = directionX;
|
previousDirectionX = directionX;
|
||||||
previousDirectionY = directionY;
|
previousDirectionY = directionY;
|
||||||
|
|
||||||
path.addFirst(node.getLoc());
|
path.addFirst(node.getLoc());
|
||||||
node.setLoc(null);
|
node.setLoc(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
node = node.getParent();
|
node = node.getParent();
|
||||||
}
|
}
|
||||||
|
|
||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
private CellNodeBuffer alloc(int size, boolean playable)
|
private CellNodeBuffer alloc(int size, boolean playable)
|
||||||
{
|
{
|
||||||
CellNodeBuffer current = null;
|
CellNodeBuffer current = null;
|
||||||
for (BufferInfo i : _allBuffers)
|
for (BufferInfo i : _allBuffers)
|
||||||
{
|
{
|
||||||
if (i.mapSize >= size)
|
if (i.mapSize >= size)
|
||||||
{
|
{
|
||||||
for (CellNodeBuffer buf : i.bufs)
|
for (CellNodeBuffer buf : i.bufs)
|
||||||
{
|
{
|
||||||
if (buf.lock())
|
if (buf.lock())
|
||||||
{
|
{
|
||||||
i.uses++;
|
i.uses++;
|
||||||
if (playable)
|
if (playable)
|
||||||
{
|
{
|
||||||
i.playableUses++;
|
i.playableUses++;
|
||||||
}
|
}
|
||||||
i.elapsed += buf.getElapsedTime();
|
i.elapsed += buf.getElapsedTime();
|
||||||
current = buf;
|
current = buf;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (current != null)
|
if (current != null)
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// not found, allocate temporary buffer
|
// not found, allocate temporary buffer
|
||||||
current = new CellNodeBuffer(i.mapSize);
|
current = new CellNodeBuffer(i.mapSize);
|
||||||
current.lock();
|
current.lock();
|
||||||
if (i.bufs.size() < i.count)
|
if (i.bufs.size() < i.count)
|
||||||
{
|
{
|
||||||
i.bufs.add(current);
|
i.bufs.add(current);
|
||||||
i.uses++;
|
i.uses++;
|
||||||
if (playable)
|
if (playable)
|
||||||
{
|
{
|
||||||
i.playableUses++;
|
i.playableUses++;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
i.overflows++;
|
i.overflows++;
|
||||||
if (playable)
|
if (playable)
|
||||||
{
|
{
|
||||||
i.playableOverflows++;
|
i.playableOverflows++;
|
||||||
// System.err.println("Overflow, size requested: " + size + " playable:"+playable);
|
// System.err.println("Overflow, size requested: " + size + " playable:"+playable);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return current;
|
return current;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void dropDebugItem(int itemId, int num, AbstractNodeLoc loc)
|
private void dropDebugItem(int itemId, int num, AbstractNodeLoc loc)
|
||||||
{
|
{
|
||||||
final L2ItemInstance item = new L2ItemInstance(IdFactory.getInstance().getNextId(), itemId);
|
final L2ItemInstance item = new L2ItemInstance(IdFactory.getInstance().getNextId(), itemId);
|
||||||
item.setCount(num);
|
item.setCount(num);
|
||||||
item.spawnMe(loc.getX(), loc.getY(), loc.getZ());
|
item.spawnMe(loc.getX(), loc.getY(), loc.getZ());
|
||||||
_debugItems.add(item);
|
_debugItems.add(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final class BufferInfo
|
private static final class BufferInfo
|
||||||
{
|
{
|
||||||
final int mapSize;
|
final int mapSize;
|
||||||
final int count;
|
final int count;
|
||||||
ArrayList<CellNodeBuffer> bufs;
|
ArrayList<CellNodeBuffer> bufs;
|
||||||
int uses = 0;
|
int uses = 0;
|
||||||
int playableUses = 0;
|
int playableUses = 0;
|
||||||
int overflows = 0;
|
int overflows = 0;
|
||||||
int playableOverflows = 0;
|
int playableOverflows = 0;
|
||||||
long elapsed = 0;
|
long elapsed = 0;
|
||||||
|
|
||||||
public BufferInfo(int size, int cnt)
|
public BufferInfo(int size, int cnt)
|
||||||
{
|
{
|
||||||
mapSize = size;
|
mapSize = size;
|
||||||
count = cnt;
|
count = cnt;
|
||||||
bufs = new ArrayList<>(count);
|
bufs = new ArrayList<>(count);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString()
|
public String toString()
|
||||||
{
|
{
|
||||||
final StringBuilder sb = new StringBuilder(100);
|
final StringBuilder sb = new StringBuilder(100);
|
||||||
sb.append(mapSize);
|
sb.append(mapSize);
|
||||||
sb.append("x");
|
sb.append("x");
|
||||||
sb.append(mapSize);
|
sb.append(mapSize);
|
||||||
sb.append(" num:");
|
sb.append(" num:");
|
||||||
sb.append(bufs.size());
|
sb.append(bufs.size());
|
||||||
sb.append("/");
|
sb.append("/");
|
||||||
sb.append(count);
|
sb.append(count);
|
||||||
sb.append(" uses:");
|
sb.append(" uses:");
|
||||||
sb.append(uses);
|
sb.append(uses);
|
||||||
sb.append("/");
|
sb.append("/");
|
||||||
sb.append(playableUses);
|
sb.append(playableUses);
|
||||||
if (uses > 0)
|
if (uses > 0)
|
||||||
{
|
{
|
||||||
sb.append(" total/avg(ms):");
|
sb.append(" total/avg(ms):");
|
||||||
sb.append(elapsed);
|
sb.append(elapsed);
|
||||||
sb.append("/");
|
sb.append("/");
|
||||||
sb.append(String.format("%1.2f", (double) elapsed / uses));
|
sb.append(String.format("%1.2f", (double) elapsed / uses));
|
||||||
}
|
}
|
||||||
|
|
||||||
sb.append(" ovf:");
|
sb.append(" ovf:");
|
||||||
sb.append(overflows);
|
sb.append(overflows);
|
||||||
sb.append("/");
|
sb.append("/");
|
||||||
sb.append(playableOverflows);
|
sb.append(playableOverflows);
|
||||||
|
|
||||||
return sb.toString();
|
return sb.toString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String[] getStat()
|
public String[] getStat()
|
||||||
{
|
{
|
||||||
final String[] result = new String[_allBuffers.length + 1];
|
final String[] result = new String[_allBuffers.length + 1];
|
||||||
for (int i = 0; i < _allBuffers.length; i++)
|
for (int i = 0; i < _allBuffers.length; i++)
|
||||||
{
|
{
|
||||||
result[i] = _allBuffers[i].toString();
|
result[i] = _allBuffers[i].toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
final StringBuilder sb = new StringBuilder(128);
|
final StringBuilder sb = new StringBuilder(128);
|
||||||
sb.append("LOS postfilter uses:");
|
sb.append("LOS postfilter uses:");
|
||||||
sb.append(_postFilterUses);
|
sb.append(_postFilterUses);
|
||||||
sb.append("/");
|
sb.append("/");
|
||||||
sb.append(_postFilterPlayableUses);
|
sb.append(_postFilterPlayableUses);
|
||||||
if (_postFilterUses > 0)
|
if (_postFilterUses > 0)
|
||||||
{
|
{
|
||||||
sb.append(" total/avg(ms):");
|
sb.append(" total/avg(ms):");
|
||||||
sb.append(_postFilterElapsed);
|
sb.append(_postFilterElapsed);
|
||||||
sb.append("/");
|
sb.append("/");
|
||||||
sb.append(String.format("%1.2f", (double) _postFilterElapsed / _postFilterUses));
|
sb.append(String.format("%1.2f", (double) _postFilterElapsed / _postFilterUses));
|
||||||
sb.append(" passes total/avg:");
|
sb.append(" passes total/avg:");
|
||||||
sb.append(_postFilterPasses);
|
sb.append(_postFilterPasses);
|
||||||
sb.append("/");
|
sb.append("/");
|
||||||
sb.append(String.format("%1.1f", (double) _postFilterPasses / _postFilterUses));
|
sb.append(String.format("%1.1f", (double) _postFilterPasses / _postFilterUses));
|
||||||
sb.append(Config.EOL);
|
sb.append(Config.EOL);
|
||||||
}
|
}
|
||||||
sb.append("Pathfind success/fail:");
|
sb.append("Pathfind success/fail:");
|
||||||
sb.append(_findSuccess);
|
sb.append(_findSuccess);
|
||||||
sb.append("/");
|
sb.append("/");
|
||||||
sb.append(_findFails);
|
sb.append(_findFails);
|
||||||
result[result.length - 1] = sb.toString();
|
result[result.length - 1] = sb.toString();
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class SingletonHolder
|
private static class SingletonHolder
|
||||||
{
|
{
|
||||||
protected static final CellPathFinding _instance = new CellPathFinding();
|
protected static final CellPathFinding _instance = new CellPathFinding();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,184 +1,184 @@
|
|||||||
/*
|
/*
|
||||||
* This file is part of the L2J Mobius project.
|
* This file is part of the L2J Mobius project.
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
* General Public License for more details.
|
* General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package com.l2jmobius.gameserver.pathfinding.cellnodes;
|
package com.l2jmobius.gameserver.geodata.pathfinding.cellnodes;
|
||||||
|
|
||||||
import com.l2jmobius.commons.geodriver.Cell;
|
import com.l2jmobius.gameserver.GeoData;
|
||||||
import com.l2jmobius.gameserver.GeoData;
|
import com.l2jmobius.gameserver.geodata.geodriver.Cell;
|
||||||
import com.l2jmobius.gameserver.pathfinding.AbstractNodeLoc;
|
import com.l2jmobius.gameserver.geodata.pathfinding.AbstractNodeLoc;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author -Nemesiss-, HorridoJoho
|
* @author -Nemesiss-, HorridoJoho
|
||||||
*/
|
*/
|
||||||
public class NodeLoc extends AbstractNodeLoc
|
public class NodeLoc extends AbstractNodeLoc
|
||||||
{
|
{
|
||||||
private int _x;
|
private int _x;
|
||||||
private int _y;
|
private int _y;
|
||||||
private boolean _goNorth;
|
private boolean _goNorth;
|
||||||
private boolean _goEast;
|
private boolean _goEast;
|
||||||
private boolean _goSouth;
|
private boolean _goSouth;
|
||||||
private boolean _goWest;
|
private boolean _goWest;
|
||||||
private int _geoHeight;
|
private int _geoHeight;
|
||||||
|
|
||||||
public NodeLoc(int x, int y, int z)
|
public NodeLoc(int x, int y, int z)
|
||||||
{
|
{
|
||||||
set(x, y, z);
|
set(x, y, z);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void set(int x, int y, int z)
|
public void set(int x, int y, int z)
|
||||||
{
|
{
|
||||||
_x = x;
|
_x = x;
|
||||||
_y = y;
|
_y = y;
|
||||||
_goNorth = GeoData.getInstance().checkNearestNswe(x, y, z, Cell.NSWE_NORTH);
|
_goNorth = GeoData.getInstance().checkNearestNswe(x, y, z, Cell.NSWE_NORTH);
|
||||||
_goEast = GeoData.getInstance().checkNearestNswe(x, y, z, Cell.NSWE_EAST);
|
_goEast = GeoData.getInstance().checkNearestNswe(x, y, z, Cell.NSWE_EAST);
|
||||||
_goSouth = GeoData.getInstance().checkNearestNswe(x, y, z, Cell.NSWE_SOUTH);
|
_goSouth = GeoData.getInstance().checkNearestNswe(x, y, z, Cell.NSWE_SOUTH);
|
||||||
_goWest = GeoData.getInstance().checkNearestNswe(x, y, z, Cell.NSWE_WEST);
|
_goWest = GeoData.getInstance().checkNearestNswe(x, y, z, Cell.NSWE_WEST);
|
||||||
_geoHeight = GeoData.getInstance().getNearestZ(x, y, z);
|
_geoHeight = GeoData.getInstance().getNearestZ(x, y, z);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean canGoNorth()
|
public boolean canGoNorth()
|
||||||
{
|
{
|
||||||
return _goNorth;
|
return _goNorth;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean canGoEast()
|
public boolean canGoEast()
|
||||||
{
|
{
|
||||||
return _goEast;
|
return _goEast;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean canGoSouth()
|
public boolean canGoSouth()
|
||||||
{
|
{
|
||||||
return _goSouth;
|
return _goSouth;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean canGoWest()
|
public boolean canGoWest()
|
||||||
{
|
{
|
||||||
return _goWest;
|
return _goWest;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean canGoAll()
|
public boolean canGoAll()
|
||||||
{
|
{
|
||||||
return canGoNorth() && canGoEast() && canGoSouth() && canGoWest();
|
return canGoNorth() && canGoEast() && canGoSouth() && canGoWest();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getX()
|
public int getX()
|
||||||
{
|
{
|
||||||
return GeoData.getInstance().getWorldX(_x);
|
return GeoData.getInstance().getWorldX(_x);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getY()
|
public int getY()
|
||||||
{
|
{
|
||||||
return GeoData.getInstance().getWorldY(_y);
|
return GeoData.getInstance().getWorldY(_y);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getZ()
|
public int getZ()
|
||||||
{
|
{
|
||||||
return _geoHeight;
|
return _geoHeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getNodeX()
|
public int getNodeX()
|
||||||
{
|
{
|
||||||
return _x;
|
return _x;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getNodeY()
|
public int getNodeY()
|
||||||
{
|
{
|
||||||
return _y;
|
return _y;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode()
|
public int hashCode()
|
||||||
{
|
{
|
||||||
final int prime = 31;
|
final int prime = 31;
|
||||||
int result = 1;
|
int result = 1;
|
||||||
result = (prime * result) + _x;
|
result = (prime * result) + _x;
|
||||||
result = (prime * result) + _y;
|
result = (prime * result) + _y;
|
||||||
|
|
||||||
int nswe = 0;
|
int nswe = 0;
|
||||||
if (canGoNorth())
|
if (canGoNorth())
|
||||||
{
|
{
|
||||||
nswe |= Cell.NSWE_NORTH;
|
nswe |= Cell.NSWE_NORTH;
|
||||||
}
|
}
|
||||||
if (canGoEast())
|
if (canGoEast())
|
||||||
{
|
{
|
||||||
nswe |= Cell.NSWE_EAST;
|
nswe |= Cell.NSWE_EAST;
|
||||||
}
|
}
|
||||||
if (canGoSouth())
|
if (canGoSouth())
|
||||||
{
|
{
|
||||||
nswe |= Cell.NSWE_SOUTH;
|
nswe |= Cell.NSWE_SOUTH;
|
||||||
}
|
}
|
||||||
if (canGoWest())
|
if (canGoWest())
|
||||||
{
|
{
|
||||||
nswe |= Cell.NSWE_WEST;
|
nswe |= Cell.NSWE_WEST;
|
||||||
}
|
}
|
||||||
|
|
||||||
result = (prime * result) + (((_geoHeight & 0xFFFF) << 1) | nswe);
|
result = (prime * result) + (((_geoHeight & 0xFFFF) << 1) | nswe);
|
||||||
return result;
|
return result;
|
||||||
// return super.hashCode();
|
// return super.hashCode();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object obj)
|
public boolean equals(Object obj)
|
||||||
{
|
{
|
||||||
if (this == obj)
|
if (this == obj)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (obj == null)
|
if (obj == null)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!(obj instanceof NodeLoc))
|
if (!(obj instanceof NodeLoc))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
final NodeLoc other = (NodeLoc) obj;
|
final NodeLoc other = (NodeLoc) obj;
|
||||||
if (_x != other._x)
|
if (_x != other._x)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (_y != other._y)
|
if (_y != other._y)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (_goNorth != other._goNorth)
|
if (_goNorth != other._goNorth)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (_goEast != other._goEast)
|
if (_goEast != other._goEast)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (_goSouth != other._goSouth)
|
if (_goSouth != other._goSouth)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (_goWest != other._goWest)
|
if (_goWest != other._goWest)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (_geoHeight != other._geoHeight)
|
if (_geoHeight != other._geoHeight)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,62 +1,62 @@
|
|||||||
/*
|
/*
|
||||||
* This file is part of the L2J Mobius project.
|
* This file is part of the L2J Mobius project.
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
* General Public License for more details.
|
* General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package com.l2jmobius.gameserver.pathfinding.geonodes;
|
package com.l2jmobius.gameserver.geodata.pathfinding.geonodes;
|
||||||
|
|
||||||
import com.l2jmobius.gameserver.pathfinding.AbstractNode;
|
import com.l2jmobius.gameserver.geodata.pathfinding.AbstractNode;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author -Nemesiss-
|
* @author -Nemesiss-
|
||||||
*/
|
*/
|
||||||
public class GeoNode extends AbstractNode<GeoNodeLoc>
|
public class GeoNode extends AbstractNode<GeoNodeLoc>
|
||||||
{
|
{
|
||||||
private final int _neighborsIdx;
|
private final int _neighborsIdx;
|
||||||
private short _cost;
|
private short _cost;
|
||||||
private GeoNode[] _neighbors;
|
private GeoNode[] _neighbors;
|
||||||
|
|
||||||
public GeoNode(GeoNodeLoc Loc, int Neighbors_idx)
|
public GeoNode(GeoNodeLoc Loc, int Neighbors_idx)
|
||||||
{
|
{
|
||||||
super(Loc);
|
super(Loc);
|
||||||
_neighborsIdx = Neighbors_idx;
|
_neighborsIdx = Neighbors_idx;
|
||||||
}
|
}
|
||||||
|
|
||||||
public short getCost()
|
public short getCost()
|
||||||
{
|
{
|
||||||
return _cost;
|
return _cost;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setCost(int cost)
|
public void setCost(int cost)
|
||||||
{
|
{
|
||||||
_cost = (short) cost;
|
_cost = (short) cost;
|
||||||
}
|
}
|
||||||
|
|
||||||
public GeoNode[] getNeighbors()
|
public GeoNode[] getNeighbors()
|
||||||
{
|
{
|
||||||
return _neighbors;
|
return _neighbors;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void attachNeighbors()
|
public void attachNeighbors()
|
||||||
{
|
{
|
||||||
if (getLoc() == null)
|
if (getLoc() == null)
|
||||||
{
|
{
|
||||||
_neighbors = null;
|
_neighbors = null;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_neighbors = GeoPathFinding.getInstance().readNeighbors(this, _neighborsIdx);
|
_neighbors = GeoPathFinding.getInstance().readNeighbors(this, _neighborsIdx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,109 +1,109 @@
|
|||||||
/*
|
/*
|
||||||
* This file is part of the L2J Mobius project.
|
* This file is part of the L2J Mobius project.
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
* General Public License for more details.
|
* General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package com.l2jmobius.gameserver.pathfinding.geonodes;
|
package com.l2jmobius.gameserver.geodata.pathfinding.geonodes;
|
||||||
|
|
||||||
import com.l2jmobius.gameserver.model.L2World;
|
import com.l2jmobius.gameserver.geodata.pathfinding.AbstractNodeLoc;
|
||||||
import com.l2jmobius.gameserver.pathfinding.AbstractNodeLoc;
|
import com.l2jmobius.gameserver.model.L2World;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author -Nemesiss-
|
* @author -Nemesiss-
|
||||||
*/
|
*/
|
||||||
public class GeoNodeLoc extends AbstractNodeLoc
|
public class GeoNodeLoc extends AbstractNodeLoc
|
||||||
{
|
{
|
||||||
private final short _x;
|
private final short _x;
|
||||||
private final short _y;
|
private final short _y;
|
||||||
private final short _z;
|
private final short _z;
|
||||||
|
|
||||||
public GeoNodeLoc(short x, short y, short z)
|
public GeoNodeLoc(short x, short y, short z)
|
||||||
{
|
{
|
||||||
_x = x;
|
_x = x;
|
||||||
_y = y;
|
_y = y;
|
||||||
_z = z;
|
_z = z;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getX()
|
public int getX()
|
||||||
{
|
{
|
||||||
return L2World.MAP_MIN_X + (_x * 128) + 48;
|
return L2World.MAP_MIN_X + (_x * 128) + 48;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getY()
|
public int getY()
|
||||||
{
|
{
|
||||||
return L2World.MAP_MIN_Y + (_y * 128) + 48;
|
return L2World.MAP_MIN_Y + (_y * 128) + 48;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getZ()
|
public int getZ()
|
||||||
{
|
{
|
||||||
return _z;
|
return _z;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getNodeX()
|
public int getNodeX()
|
||||||
{
|
{
|
||||||
return _x;
|
return _x;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getNodeY()
|
public int getNodeY()
|
||||||
{
|
{
|
||||||
return _y;
|
return _y;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode()
|
public int hashCode()
|
||||||
{
|
{
|
||||||
final int prime = 31;
|
final int prime = 31;
|
||||||
int result = 1;
|
int result = 1;
|
||||||
result = (prime * result) + _x;
|
result = (prime * result) + _x;
|
||||||
result = (prime * result) + _y;
|
result = (prime * result) + _y;
|
||||||
result = (prime * result) + _z;
|
result = (prime * result) + _z;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object obj)
|
public boolean equals(Object obj)
|
||||||
{
|
{
|
||||||
if (this == obj)
|
if (this == obj)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (obj == null)
|
if (obj == null)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!(obj instanceof GeoNodeLoc))
|
if (!(obj instanceof GeoNodeLoc))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
final GeoNodeLoc other = (GeoNodeLoc) obj;
|
final GeoNodeLoc other = (GeoNodeLoc) obj;
|
||||||
if (_x != other._x)
|
if (_x != other._x)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (_y != other._y)
|
if (_y != other._y)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (_z != other._z)
|
if (_z != other._z)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,470 +1,470 @@
|
|||||||
/*
|
/*
|
||||||
* This file is part of the L2J Mobius project.
|
* This file is part of the L2J Mobius project.
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
* General Public License for more details.
|
* General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package com.l2jmobius.gameserver.pathfinding.geonodes;
|
package com.l2jmobius.gameserver.geodata.pathfinding.geonodes;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.RandomAccessFile;
|
import java.io.RandomAccessFile;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.nio.IntBuffer;
|
import java.nio.IntBuffer;
|
||||||
import java.nio.MappedByteBuffer;
|
import java.nio.MappedByteBuffer;
|
||||||
import java.nio.channels.FileChannel;
|
import java.nio.channels.FileChannel;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import com.l2jmobius.Config;
|
import com.l2jmobius.Config;
|
||||||
import com.l2jmobius.gameserver.GeoData;
|
import com.l2jmobius.gameserver.GeoData;
|
||||||
import com.l2jmobius.gameserver.model.L2World;
|
import com.l2jmobius.gameserver.geodata.pathfinding.AbstractNode;
|
||||||
import com.l2jmobius.gameserver.model.Location;
|
import com.l2jmobius.gameserver.geodata.pathfinding.AbstractNodeLoc;
|
||||||
import com.l2jmobius.gameserver.model.instancezone.Instance;
|
import com.l2jmobius.gameserver.geodata.pathfinding.PathFinding;
|
||||||
import com.l2jmobius.gameserver.pathfinding.AbstractNode;
|
import com.l2jmobius.gameserver.model.L2World;
|
||||||
import com.l2jmobius.gameserver.pathfinding.AbstractNodeLoc;
|
import com.l2jmobius.gameserver.model.Location;
|
||||||
import com.l2jmobius.gameserver.pathfinding.PathFinding;
|
import com.l2jmobius.gameserver.model.instancezone.Instance;
|
||||||
import com.l2jmobius.gameserver.util.Util;
|
import com.l2jmobius.gameserver.util.Util;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author -Nemesiss-
|
* @author -Nemesiss-
|
||||||
*/
|
*/
|
||||||
public class GeoPathFinding extends PathFinding
|
public class GeoPathFinding extends PathFinding
|
||||||
{
|
{
|
||||||
private static Logger _log = Logger.getLogger(GeoPathFinding.class.getName());
|
private static Logger _log = Logger.getLogger(GeoPathFinding.class.getName());
|
||||||
private static Map<Short, ByteBuffer> _pathNodes = new ConcurrentHashMap<>();
|
private static Map<Short, ByteBuffer> _pathNodes = new ConcurrentHashMap<>();
|
||||||
private static Map<Short, IntBuffer> _pathNodesIndex = new ConcurrentHashMap<>();
|
private static Map<Short, IntBuffer> _pathNodesIndex = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
public static GeoPathFinding getInstance()
|
public static GeoPathFinding getInstance()
|
||||||
{
|
{
|
||||||
return SingletonHolder._instance;
|
return SingletonHolder._instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean pathNodesExist(short regionoffset)
|
public boolean pathNodesExist(short regionoffset)
|
||||||
{
|
{
|
||||||
return _pathNodesIndex.containsKey(regionoffset);
|
return _pathNodesIndex.containsKey(regionoffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<AbstractNodeLoc> findPath(int x, int y, int z, int tx, int ty, int tz, Instance instance, boolean playable)
|
public List<AbstractNodeLoc> findPath(int x, int y, int z, int tx, int ty, int tz, Instance instance, boolean playable)
|
||||||
{
|
{
|
||||||
final int gx = (x - L2World.MAP_MIN_X) >> 4;
|
final int gx = (x - L2World.MAP_MIN_X) >> 4;
|
||||||
final int gy = (y - L2World.MAP_MIN_Y) >> 4;
|
final int gy = (y - L2World.MAP_MIN_Y) >> 4;
|
||||||
final short gz = (short) z;
|
final short gz = (short) z;
|
||||||
final int gtx = (tx - L2World.MAP_MIN_X) >> 4;
|
final int gtx = (tx - L2World.MAP_MIN_X) >> 4;
|
||||||
final int gty = (ty - L2World.MAP_MIN_Y) >> 4;
|
final int gty = (ty - L2World.MAP_MIN_Y) >> 4;
|
||||||
final short gtz = (short) tz;
|
final short gtz = (short) tz;
|
||||||
|
|
||||||
final GeoNode start = readNode(gx, gy, gz);
|
final GeoNode start = readNode(gx, gy, gz);
|
||||||
final GeoNode end = readNode(gtx, gty, gtz);
|
final GeoNode end = readNode(gtx, gty, gtz);
|
||||||
if ((start == null) || (end == null))
|
if ((start == null) || (end == null))
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
if (Math.abs(start.getLoc().getZ() - z) > 55)
|
if (Math.abs(start.getLoc().getZ() - z) > 55)
|
||||||
{
|
{
|
||||||
return null; // not correct layer
|
return null; // not correct layer
|
||||||
}
|
}
|
||||||
if (Math.abs(end.getLoc().getZ() - tz) > 55)
|
if (Math.abs(end.getLoc().getZ() - tz) > 55)
|
||||||
{
|
{
|
||||||
return null; // not correct layer
|
return null; // not correct layer
|
||||||
}
|
}
|
||||||
if (start == end)
|
if (start == end)
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Find closest path node we CAN access. Now only checks if we can not reach the closest
|
// TODO: Find closest path node we CAN access. Now only checks if we can not reach the closest
|
||||||
Location temp = GeoData.getInstance().moveCheck(x, y, z, start.getLoc().getX(), start.getLoc().getY(), start.getLoc().getZ(), instance);
|
Location temp = GeoData.getInstance().moveCheck(x, y, z, start.getLoc().getX(), start.getLoc().getY(), start.getLoc().getZ(), instance);
|
||||||
if ((temp.getX() != start.getLoc().getX()) || (temp.getY() != start.getLoc().getY()))
|
if ((temp.getX() != start.getLoc().getX()) || (temp.getY() != start.getLoc().getY()))
|
||||||
{
|
{
|
||||||
return null; // cannot reach closest...
|
return null; // cannot reach closest...
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Find closest path node around target, now only checks if final location can be reached
|
// TODO: Find closest path node around target, now only checks if final location can be reached
|
||||||
temp = GeoData.getInstance().moveCheck(tx, ty, tz, end.getLoc().getX(), end.getLoc().getY(), end.getLoc().getZ(), instance);
|
temp = GeoData.getInstance().moveCheck(tx, ty, tz, end.getLoc().getX(), end.getLoc().getY(), end.getLoc().getZ(), instance);
|
||||||
if ((temp.getX() != end.getLoc().getX()) || (temp.getY() != end.getLoc().getY()))
|
if ((temp.getX() != end.getLoc().getX()) || (temp.getY() != end.getLoc().getY()))
|
||||||
{
|
{
|
||||||
return null; // cannot reach closest...
|
return null; // cannot reach closest...
|
||||||
}
|
}
|
||||||
|
|
||||||
// return searchAStar(start, end);
|
// return searchAStar(start, end);
|
||||||
return searchByClosest2(start, end);
|
return searchByClosest2(start, end);
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<AbstractNodeLoc> searchByClosest2(GeoNode start, GeoNode end)
|
public List<AbstractNodeLoc> searchByClosest2(GeoNode start, GeoNode end)
|
||||||
{
|
{
|
||||||
// Always continues checking from the closest to target non-blocked
|
// Always continues checking from the closest to target non-blocked
|
||||||
// node from to_visit list. There's extra length in path if needed
|
// node from to_visit list. There's extra length in path if needed
|
||||||
// to go backwards/sideways but when moving generally forwards, this is extra fast
|
// to go backwards/sideways but when moving generally forwards, this is extra fast
|
||||||
// and accurate. And can reach insane distances (try it with 800 nodes..).
|
// and accurate. And can reach insane distances (try it with 800 nodes..).
|
||||||
// Minimum required node count would be around 300-400.
|
// Minimum required node count would be around 300-400.
|
||||||
// Generally returns a bit (only a bit) more intelligent looking routes than
|
// Generally returns a bit (only a bit) more intelligent looking routes than
|
||||||
// the basic version. Not a true distance image (which would increase CPU
|
// the basic version. Not a true distance image (which would increase CPU
|
||||||
// load) level of intelligence though.
|
// load) level of intelligence though.
|
||||||
|
|
||||||
// List of Visited Nodes
|
// List of Visited Nodes
|
||||||
final List<GeoNode> visited = new ArrayList<>(550);
|
final List<GeoNode> visited = new ArrayList<>(550);
|
||||||
|
|
||||||
// List of Nodes to Visit
|
// List of Nodes to Visit
|
||||||
final LinkedList<GeoNode> to_visit = new LinkedList<>();
|
final LinkedList<GeoNode> to_visit = new LinkedList<>();
|
||||||
to_visit.add(start);
|
to_visit.add(start);
|
||||||
final int targetX = end.getLoc().getNodeX();
|
final int targetX = end.getLoc().getNodeX();
|
||||||
final int targetY = end.getLoc().getNodeY();
|
final int targetY = end.getLoc().getNodeY();
|
||||||
|
|
||||||
int dx, dy;
|
int dx, dy;
|
||||||
boolean added;
|
boolean added;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
while (i < 550)
|
while (i < 550)
|
||||||
{
|
{
|
||||||
GeoNode node;
|
GeoNode node;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
node = to_visit.removeFirst();
|
node = to_visit.removeFirst();
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
// No Path found
|
// No Path found
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
if (node.equals(end))
|
if (node.equals(end))
|
||||||
{
|
{
|
||||||
return constructPath2(node);
|
return constructPath2(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
i++;
|
i++;
|
||||||
visited.add(node);
|
visited.add(node);
|
||||||
node.attachNeighbors();
|
node.attachNeighbors();
|
||||||
final GeoNode[] neighbors = node.getNeighbors();
|
final GeoNode[] neighbors = node.getNeighbors();
|
||||||
if (neighbors == null)
|
if (neighbors == null)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
for (GeoNode n : neighbors)
|
for (GeoNode n : neighbors)
|
||||||
{
|
{
|
||||||
if ((visited.lastIndexOf(n) == -1) && !to_visit.contains(n))
|
if ((visited.lastIndexOf(n) == -1) && !to_visit.contains(n))
|
||||||
{
|
{
|
||||||
added = false;
|
added = false;
|
||||||
n.setParent(node);
|
n.setParent(node);
|
||||||
dx = targetX - n.getLoc().getNodeX();
|
dx = targetX - n.getLoc().getNodeX();
|
||||||
dy = targetY - n.getLoc().getNodeY();
|
dy = targetY - n.getLoc().getNodeY();
|
||||||
n.setCost((dx * dx) + (dy * dy));
|
n.setCost((dx * dx) + (dy * dy));
|
||||||
for (int index = 0; index < to_visit.size(); index++)
|
for (int index = 0; index < to_visit.size(); index++)
|
||||||
{
|
{
|
||||||
// supposed to find it quite early..
|
// supposed to find it quite early..
|
||||||
if (to_visit.get(index).getCost() > n.getCost())
|
if (to_visit.get(index).getCost() > n.getCost())
|
||||||
{
|
{
|
||||||
to_visit.add(index, n);
|
to_visit.add(index, n);
|
||||||
added = true;
|
added = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!added)
|
if (!added)
|
||||||
{
|
{
|
||||||
to_visit.addLast(n);
|
to_visit.addLast(n);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// No Path found
|
// No Path found
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<AbstractNodeLoc> constructPath2(AbstractNode<GeoNodeLoc> node)
|
public List<AbstractNodeLoc> constructPath2(AbstractNode<GeoNodeLoc> node)
|
||||||
{
|
{
|
||||||
final LinkedList<AbstractNodeLoc> path = new LinkedList<>();
|
final LinkedList<AbstractNodeLoc> path = new LinkedList<>();
|
||||||
int previousDirectionX = -1000;
|
int previousDirectionX = -1000;
|
||||||
int previousDirectionY = -1000;
|
int previousDirectionY = -1000;
|
||||||
int directionX;
|
int directionX;
|
||||||
int directionY;
|
int directionY;
|
||||||
|
|
||||||
while (node.getParent() != null)
|
while (node.getParent() != null)
|
||||||
{
|
{
|
||||||
// only add a new route point if moving direction changes
|
// only add a new route point if moving direction changes
|
||||||
directionX = node.getLoc().getNodeX() - node.getParent().getLoc().getNodeX();
|
directionX = node.getLoc().getNodeX() - node.getParent().getLoc().getNodeX();
|
||||||
directionY = node.getLoc().getNodeY() - node.getParent().getLoc().getNodeY();
|
directionY = node.getLoc().getNodeY() - node.getParent().getLoc().getNodeY();
|
||||||
|
|
||||||
if ((directionX != previousDirectionX) || (directionY != previousDirectionY))
|
if ((directionX != previousDirectionX) || (directionY != previousDirectionY))
|
||||||
{
|
{
|
||||||
previousDirectionX = directionX;
|
previousDirectionX = directionX;
|
||||||
previousDirectionY = directionY;
|
previousDirectionY = directionY;
|
||||||
path.addFirst(node.getLoc());
|
path.addFirst(node.getLoc());
|
||||||
}
|
}
|
||||||
node = node.getParent();
|
node = node.getParent();
|
||||||
}
|
}
|
||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
public GeoNode[] readNeighbors(GeoNode n, int idx)
|
public GeoNode[] readNeighbors(GeoNode n, int idx)
|
||||||
{
|
{
|
||||||
final int node_x = n.getLoc().getNodeX();
|
final int node_x = n.getLoc().getNodeX();
|
||||||
final int node_y = n.getLoc().getNodeY();
|
final int node_y = n.getLoc().getNodeY();
|
||||||
// short node_z = n.getLoc().getZ();
|
// short node_z = n.getLoc().getZ();
|
||||||
|
|
||||||
final short regoffset = getRegionOffset(getRegionX(node_x), getRegionY(node_y));
|
final short regoffset = getRegionOffset(getRegionX(node_x), getRegionY(node_y));
|
||||||
final ByteBuffer pn = _pathNodes.get(regoffset);
|
final ByteBuffer pn = _pathNodes.get(regoffset);
|
||||||
|
|
||||||
final List<AbstractNode<GeoNodeLoc>> Neighbors = new ArrayList<>(8);
|
final List<AbstractNode<GeoNodeLoc>> Neighbors = new ArrayList<>(8);
|
||||||
GeoNode newNode;
|
GeoNode newNode;
|
||||||
short new_node_x, new_node_y;
|
short new_node_x, new_node_y;
|
||||||
|
|
||||||
// Region for sure will change, we must read from correct file
|
// Region for sure will change, we must read from correct file
|
||||||
byte neighbor = pn.get(idx++); // N
|
byte neighbor = pn.get(idx++); // N
|
||||||
if (neighbor > 0)
|
if (neighbor > 0)
|
||||||
{
|
{
|
||||||
neighbor--;
|
neighbor--;
|
||||||
new_node_x = (short) node_x;
|
new_node_x = (short) node_x;
|
||||||
new_node_y = (short) (node_y - 1);
|
new_node_y = (short) (node_y - 1);
|
||||||
newNode = readNode(new_node_x, new_node_y, neighbor);
|
newNode = readNode(new_node_x, new_node_y, neighbor);
|
||||||
if (newNode != null)
|
if (newNode != null)
|
||||||
{
|
{
|
||||||
Neighbors.add(newNode);
|
Neighbors.add(newNode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
neighbor = pn.get(idx++); // NE
|
neighbor = pn.get(idx++); // NE
|
||||||
if (neighbor > 0)
|
if (neighbor > 0)
|
||||||
{
|
{
|
||||||
neighbor--;
|
neighbor--;
|
||||||
new_node_x = (short) (node_x + 1);
|
new_node_x = (short) (node_x + 1);
|
||||||
new_node_y = (short) (node_y - 1);
|
new_node_y = (short) (node_y - 1);
|
||||||
newNode = readNode(new_node_x, new_node_y, neighbor);
|
newNode = readNode(new_node_x, new_node_y, neighbor);
|
||||||
if (newNode != null)
|
if (newNode != null)
|
||||||
{
|
{
|
||||||
Neighbors.add(newNode);
|
Neighbors.add(newNode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
neighbor = pn.get(idx++); // E
|
neighbor = pn.get(idx++); // E
|
||||||
if (neighbor > 0)
|
if (neighbor > 0)
|
||||||
{
|
{
|
||||||
neighbor--;
|
neighbor--;
|
||||||
new_node_x = (short) (node_x + 1);
|
new_node_x = (short) (node_x + 1);
|
||||||
new_node_y = (short) node_y;
|
new_node_y = (short) node_y;
|
||||||
newNode = readNode(new_node_x, new_node_y, neighbor);
|
newNode = readNode(new_node_x, new_node_y, neighbor);
|
||||||
if (newNode != null)
|
if (newNode != null)
|
||||||
{
|
{
|
||||||
Neighbors.add(newNode);
|
Neighbors.add(newNode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
neighbor = pn.get(idx++); // SE
|
neighbor = pn.get(idx++); // SE
|
||||||
if (neighbor > 0)
|
if (neighbor > 0)
|
||||||
{
|
{
|
||||||
neighbor--;
|
neighbor--;
|
||||||
new_node_x = (short) (node_x + 1);
|
new_node_x = (short) (node_x + 1);
|
||||||
new_node_y = (short) (node_y + 1);
|
new_node_y = (short) (node_y + 1);
|
||||||
newNode = readNode(new_node_x, new_node_y, neighbor);
|
newNode = readNode(new_node_x, new_node_y, neighbor);
|
||||||
if (newNode != null)
|
if (newNode != null)
|
||||||
{
|
{
|
||||||
Neighbors.add(newNode);
|
Neighbors.add(newNode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
neighbor = pn.get(idx++); // S
|
neighbor = pn.get(idx++); // S
|
||||||
if (neighbor > 0)
|
if (neighbor > 0)
|
||||||
{
|
{
|
||||||
neighbor--;
|
neighbor--;
|
||||||
new_node_x = (short) node_x;
|
new_node_x = (short) node_x;
|
||||||
new_node_y = (short) (node_y + 1);
|
new_node_y = (short) (node_y + 1);
|
||||||
newNode = readNode(new_node_x, new_node_y, neighbor);
|
newNode = readNode(new_node_x, new_node_y, neighbor);
|
||||||
if (newNode != null)
|
if (newNode != null)
|
||||||
{
|
{
|
||||||
Neighbors.add(newNode);
|
Neighbors.add(newNode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
neighbor = pn.get(idx++); // SW
|
neighbor = pn.get(idx++); // SW
|
||||||
if (neighbor > 0)
|
if (neighbor > 0)
|
||||||
{
|
{
|
||||||
neighbor--;
|
neighbor--;
|
||||||
new_node_x = (short) (node_x - 1);
|
new_node_x = (short) (node_x - 1);
|
||||||
new_node_y = (short) (node_y + 1);
|
new_node_y = (short) (node_y + 1);
|
||||||
newNode = readNode(new_node_x, new_node_y, neighbor);
|
newNode = readNode(new_node_x, new_node_y, neighbor);
|
||||||
if (newNode != null)
|
if (newNode != null)
|
||||||
{
|
{
|
||||||
Neighbors.add(newNode);
|
Neighbors.add(newNode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
neighbor = pn.get(idx++); // W
|
neighbor = pn.get(idx++); // W
|
||||||
if (neighbor > 0)
|
if (neighbor > 0)
|
||||||
{
|
{
|
||||||
neighbor--;
|
neighbor--;
|
||||||
new_node_x = (short) (node_x - 1);
|
new_node_x = (short) (node_x - 1);
|
||||||
new_node_y = (short) node_y;
|
new_node_y = (short) node_y;
|
||||||
newNode = readNode(new_node_x, new_node_y, neighbor);
|
newNode = readNode(new_node_x, new_node_y, neighbor);
|
||||||
if (newNode != null)
|
if (newNode != null)
|
||||||
{
|
{
|
||||||
Neighbors.add(newNode);
|
Neighbors.add(newNode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
neighbor = pn.get(idx++); // NW
|
neighbor = pn.get(idx++); // NW
|
||||||
if (neighbor > 0)
|
if (neighbor > 0)
|
||||||
{
|
{
|
||||||
neighbor--;
|
neighbor--;
|
||||||
new_node_x = (short) (node_x - 1);
|
new_node_x = (short) (node_x - 1);
|
||||||
new_node_y = (short) (node_y - 1);
|
new_node_y = (short) (node_y - 1);
|
||||||
newNode = readNode(new_node_x, new_node_y, neighbor);
|
newNode = readNode(new_node_x, new_node_y, neighbor);
|
||||||
if (newNode != null)
|
if (newNode != null)
|
||||||
{
|
{
|
||||||
Neighbors.add(newNode);
|
Neighbors.add(newNode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
final GeoNode[] result = new GeoNode[Neighbors.size()];
|
final GeoNode[] result = new GeoNode[Neighbors.size()];
|
||||||
return Neighbors.toArray(result);
|
return Neighbors.toArray(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Private
|
// Private
|
||||||
|
|
||||||
private GeoNode readNode(short node_x, short node_y, byte layer)
|
private GeoNode readNode(short node_x, short node_y, byte layer)
|
||||||
{
|
{
|
||||||
final short regoffset = getRegionOffset(getRegionX(node_x), getRegionY(node_y));
|
final short regoffset = getRegionOffset(getRegionX(node_x), getRegionY(node_y));
|
||||||
if (!pathNodesExist(regoffset))
|
if (!pathNodesExist(regoffset))
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
final short nbx = getNodeBlock(node_x);
|
final short nbx = getNodeBlock(node_x);
|
||||||
final short nby = getNodeBlock(node_y);
|
final short nby = getNodeBlock(node_y);
|
||||||
int idx = _pathNodesIndex.get(regoffset).get((nby << 8) + nbx);
|
int idx = _pathNodesIndex.get(regoffset).get((nby << 8) + nbx);
|
||||||
final ByteBuffer pn = _pathNodes.get(regoffset);
|
final ByteBuffer pn = _pathNodes.get(regoffset);
|
||||||
// reading
|
// reading
|
||||||
final byte nodes = pn.get(idx);
|
final byte nodes = pn.get(idx);
|
||||||
idx += (layer * 10) + 1; // byte + layer*10byte
|
idx += (layer * 10) + 1; // byte + layer*10byte
|
||||||
if (nodes < layer)
|
if (nodes < layer)
|
||||||
{
|
{
|
||||||
_log.warning("SmthWrong!");
|
_log.warning("SmthWrong!");
|
||||||
}
|
}
|
||||||
final short node_z = pn.getShort(idx);
|
final short node_z = pn.getShort(idx);
|
||||||
idx += 2;
|
idx += 2;
|
||||||
return new GeoNode(new GeoNodeLoc(node_x, node_y, node_z), idx);
|
return new GeoNode(new GeoNodeLoc(node_x, node_y, node_z), idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
private GeoNode readNode(int gx, int gy, short z)
|
private GeoNode readNode(int gx, int gy, short z)
|
||||||
{
|
{
|
||||||
final short node_x = getNodePos(gx);
|
final short node_x = getNodePos(gx);
|
||||||
final short node_y = getNodePos(gy);
|
final short node_y = getNodePos(gy);
|
||||||
final short regoffset = getRegionOffset(getRegionX(node_x), getRegionY(node_y));
|
final short regoffset = getRegionOffset(getRegionX(node_x), getRegionY(node_y));
|
||||||
if (!pathNodesExist(regoffset))
|
if (!pathNodesExist(regoffset))
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
final short nbx = getNodeBlock(node_x);
|
final short nbx = getNodeBlock(node_x);
|
||||||
final short nby = getNodeBlock(node_y);
|
final short nby = getNodeBlock(node_y);
|
||||||
int idx = _pathNodesIndex.get(regoffset).get((nby << 8) + nbx);
|
int idx = _pathNodesIndex.get(regoffset).get((nby << 8) + nbx);
|
||||||
final ByteBuffer pn = _pathNodes.get(regoffset);
|
final ByteBuffer pn = _pathNodes.get(regoffset);
|
||||||
// reading
|
// reading
|
||||||
byte nodes = pn.get(idx++);
|
byte nodes = pn.get(idx++);
|
||||||
int idx2 = 0; // create index to nearlest node by z
|
int idx2 = 0; // create index to nearlest node by z
|
||||||
short last_z = Short.MIN_VALUE;
|
short last_z = Short.MIN_VALUE;
|
||||||
while (nodes > 0)
|
while (nodes > 0)
|
||||||
{
|
{
|
||||||
final short node_z = pn.getShort(idx);
|
final short node_z = pn.getShort(idx);
|
||||||
if (Math.abs(last_z - z) > Math.abs(node_z - z))
|
if (Math.abs(last_z - z) > Math.abs(node_z - z))
|
||||||
{
|
{
|
||||||
last_z = node_z;
|
last_z = node_z;
|
||||||
idx2 = idx + 2;
|
idx2 = idx + 2;
|
||||||
}
|
}
|
||||||
idx += 10; // short + 8 byte
|
idx += 10; // short + 8 byte
|
||||||
nodes--;
|
nodes--;
|
||||||
}
|
}
|
||||||
return new GeoNode(new GeoNodeLoc(node_x, node_y, last_z), idx2);
|
return new GeoNode(new GeoNodeLoc(node_x, node_y, last_z), idx2);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected GeoPathFinding()
|
protected GeoPathFinding()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
_log.info("Path Engine: - Loading Path Nodes...");
|
_log.info("Path Engine: - Loading Path Nodes...");
|
||||||
//@formatter:off
|
//@formatter:off
|
||||||
Files.lines(Paths.get(Config.PATHNODE_DIR.getPath(), "pn_index.txt"), StandardCharsets.UTF_8)
|
Files.lines(Paths.get(Config.PATHNODE_DIR.getPath(), "pn_index.txt"), StandardCharsets.UTF_8)
|
||||||
.map(String::trim)
|
.map(String::trim)
|
||||||
.filter(l -> !l.isEmpty())
|
.filter(l -> !l.isEmpty())
|
||||||
.forEach(line -> {
|
.forEach(line -> {
|
||||||
final String[] parts = line.split("_");
|
final String[] parts = line.split("_");
|
||||||
|
|
||||||
if ((parts.length < 2)
|
if ((parts.length < 2)
|
||||||
|| !Util.isDigit(parts[0])
|
|| !Util.isDigit(parts[0])
|
||||||
|| !Util.isDigit(parts[1]))
|
|| !Util.isDigit(parts[1]))
|
||||||
{
|
{
|
||||||
_log.warning("Invalid pathnode entry: '" + line + "', must be in format 'XX_YY', where X and Y - integers");
|
_log.warning("Invalid pathnode entry: '" + line + "', must be in format 'XX_YY', where X and Y - integers");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
final byte rx = Byte.parseByte(parts[0]);
|
final byte rx = Byte.parseByte(parts[0]);
|
||||||
final byte ry = Byte.parseByte(parts[1]);
|
final byte ry = Byte.parseByte(parts[1]);
|
||||||
LoadPathNodeFile(rx, ry);
|
LoadPathNodeFile(rx, ry);
|
||||||
});
|
});
|
||||||
//@formatter:on
|
//@formatter:on
|
||||||
}
|
}
|
||||||
catch (IOException e)
|
catch (IOException e)
|
||||||
{
|
{
|
||||||
_log.log(Level.WARNING, "", e);
|
_log.log(Level.WARNING, "", e);
|
||||||
throw new Error("Failed to read pn_index file.");
|
throw new Error("Failed to read pn_index file.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void LoadPathNodeFile(byte rx, byte ry)
|
private void LoadPathNodeFile(byte rx, byte ry)
|
||||||
{
|
{
|
||||||
if ((rx < L2World.TILE_X_MIN) || (rx > L2World.TILE_X_MAX) || (ry < L2World.TILE_Y_MIN) || (ry > L2World.TILE_Y_MAX))
|
if ((rx < L2World.TILE_X_MIN) || (rx > L2World.TILE_X_MAX) || (ry < L2World.TILE_Y_MIN) || (ry > L2World.TILE_Y_MAX))
|
||||||
{
|
{
|
||||||
_log.warning("Failed to Load PathNode File: invalid region " + rx + "," + ry + Config.EOL);
|
_log.warning("Failed to Load PathNode File: invalid region " + rx + "," + ry + Config.EOL);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
final short regionoffset = getRegionOffset(rx, ry);
|
final short regionoffset = getRegionOffset(rx, ry);
|
||||||
final File file = new File(Config.PATHNODE_DIR, rx + "_" + ry + ".pn");
|
final File file = new File(Config.PATHNODE_DIR, rx + "_" + ry + ".pn");
|
||||||
_log.info("Path Engine: - Loading: " + file.getName() + " -> region offset: " + regionoffset + " X: " + rx + " Y: " + ry);
|
_log.info("Path Engine: - Loading: " + file.getName() + " -> region offset: " + regionoffset + " X: " + rx + " Y: " + ry);
|
||||||
int node = 0, size, index = 0;
|
int node = 0, size, index = 0;
|
||||||
|
|
||||||
// Create a read-only memory-mapped file
|
// Create a read-only memory-mapped file
|
||||||
try (RandomAccessFile raf = new RandomAccessFile(file, "r");
|
try (RandomAccessFile raf = new RandomAccessFile(file, "r");
|
||||||
FileChannel roChannel = raf.getChannel())
|
FileChannel roChannel = raf.getChannel())
|
||||||
{
|
{
|
||||||
size = (int) roChannel.size();
|
size = (int) roChannel.size();
|
||||||
MappedByteBuffer nodes;
|
MappedByteBuffer nodes;
|
||||||
if (Config.FORCE_GEODATA)
|
if (Config.FORCE_GEODATA)
|
||||||
{
|
{
|
||||||
// it is not guarantee, because the underlying operating system may have paged out some of the buffer's data
|
// it is not guarantee, because the underlying operating system may have paged out some of the buffer's data
|
||||||
nodes = roChannel.map(FileChannel.MapMode.READ_ONLY, 0, size).load();
|
nodes = roChannel.map(FileChannel.MapMode.READ_ONLY, 0, size).load();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
nodes = roChannel.map(FileChannel.MapMode.READ_ONLY, 0, size);
|
nodes = roChannel.map(FileChannel.MapMode.READ_ONLY, 0, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Indexing pathnode files, so we will know where each block starts
|
// Indexing pathnode files, so we will know where each block starts
|
||||||
final IntBuffer indexs = IntBuffer.allocate(65536);
|
final IntBuffer indexs = IntBuffer.allocate(65536);
|
||||||
|
|
||||||
while (node < 65536)
|
while (node < 65536)
|
||||||
{
|
{
|
||||||
final byte layer = nodes.get(index);
|
final byte layer = nodes.get(index);
|
||||||
indexs.put(node++, index);
|
indexs.put(node++, index);
|
||||||
index += (layer * 10) + 1;
|
index += (layer * 10) + 1;
|
||||||
}
|
}
|
||||||
_pathNodesIndex.put(regionoffset, indexs);
|
_pathNodesIndex.put(regionoffset, indexs);
|
||||||
_pathNodes.put(regionoffset, nodes);
|
_pathNodes.put(regionoffset, nodes);
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
_log.log(Level.WARNING, "Failed to Load PathNode File: " + file.getAbsolutePath() + " : " + e.getMessage(), e);
|
_log.log(Level.WARNING, "Failed to Load PathNode File: " + file.getAbsolutePath() + " : " + e.getMessage(), e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class SingletonHolder
|
private static class SingletonHolder
|
||||||
{
|
{
|
||||||
protected static final GeoPathFinding _instance = new GeoPathFinding();
|
protected static final GeoPathFinding _instance = new GeoPathFinding();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,124 +1,124 @@
|
|||||||
/*
|
/*
|
||||||
* This file is part of the L2J Mobius project.
|
* This file is part of the L2J Mobius project.
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
* General Public License for more details.
|
* General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package com.l2jmobius.gameserver.pathfinding.utils;
|
package com.l2jmobius.gameserver.geodata.pathfinding.utils;
|
||||||
|
|
||||||
import com.l2jmobius.gameserver.pathfinding.geonodes.GeoNode;
|
import com.l2jmobius.gameserver.geodata.pathfinding.geonodes.GeoNode;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author -Nemesiss-
|
* @author -Nemesiss-
|
||||||
*/
|
*/
|
||||||
public class BinaryNodeHeap
|
public class BinaryNodeHeap
|
||||||
{
|
{
|
||||||
private final GeoNode[] _list;
|
private final GeoNode[] _list;
|
||||||
private int _size;
|
private int _size;
|
||||||
|
|
||||||
public BinaryNodeHeap(int size)
|
public BinaryNodeHeap(int size)
|
||||||
{
|
{
|
||||||
_list = new GeoNode[size + 1];
|
_list = new GeoNode[size + 1];
|
||||||
_size = 0;
|
_size = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void add(GeoNode n)
|
public void add(GeoNode n)
|
||||||
{
|
{
|
||||||
_size++;
|
_size++;
|
||||||
int pos = _size;
|
int pos = _size;
|
||||||
_list[pos] = n;
|
_list[pos] = n;
|
||||||
while (pos != 1)
|
while (pos != 1)
|
||||||
{
|
{
|
||||||
final int p2 = pos / 2;
|
final int p2 = pos / 2;
|
||||||
if (_list[pos].getCost() <= _list[p2].getCost())
|
if (_list[pos].getCost() <= _list[p2].getCost())
|
||||||
{
|
{
|
||||||
final GeoNode temp = _list[p2];
|
final GeoNode temp = _list[p2];
|
||||||
_list[p2] = _list[pos];
|
_list[p2] = _list[pos];
|
||||||
_list[pos] = temp;
|
_list[pos] = temp;
|
||||||
pos = p2;
|
pos = p2;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public GeoNode removeFirst()
|
public GeoNode removeFirst()
|
||||||
{
|
{
|
||||||
final GeoNode first = _list[1];
|
final GeoNode first = _list[1];
|
||||||
_list[1] = _list[_size];
|
_list[1] = _list[_size];
|
||||||
_list[_size] = null;
|
_list[_size] = null;
|
||||||
_size--;
|
_size--;
|
||||||
int pos = 1;
|
int pos = 1;
|
||||||
int cpos;
|
int cpos;
|
||||||
int dblcpos;
|
int dblcpos;
|
||||||
GeoNode temp;
|
GeoNode temp;
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
cpos = pos;
|
cpos = pos;
|
||||||
dblcpos = cpos * 2;
|
dblcpos = cpos * 2;
|
||||||
if ((dblcpos + 1) <= _size)
|
if ((dblcpos + 1) <= _size)
|
||||||
{
|
{
|
||||||
if (_list[cpos].getCost() >= _list[dblcpos].getCost())
|
if (_list[cpos].getCost() >= _list[dblcpos].getCost())
|
||||||
{
|
{
|
||||||
pos = dblcpos;
|
pos = dblcpos;
|
||||||
}
|
}
|
||||||
if (_list[pos].getCost() >= _list[dblcpos + 1].getCost())
|
if (_list[pos].getCost() >= _list[dblcpos + 1].getCost())
|
||||||
{
|
{
|
||||||
pos = dblcpos + 1;
|
pos = dblcpos + 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (dblcpos <= _size)
|
else if (dblcpos <= _size)
|
||||||
{
|
{
|
||||||
if (_list[cpos].getCost() >= _list[dblcpos].getCost())
|
if (_list[cpos].getCost() >= _list[dblcpos].getCost())
|
||||||
{
|
{
|
||||||
pos = dblcpos;
|
pos = dblcpos;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cpos != pos)
|
if (cpos != pos)
|
||||||
{
|
{
|
||||||
temp = _list[cpos];
|
temp = _list[cpos];
|
||||||
_list[cpos] = _list[pos];
|
_list[cpos] = _list[pos];
|
||||||
_list[pos] = temp;
|
_list[pos] = temp;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return first;
|
return first;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean contains(GeoNode n)
|
public boolean contains(GeoNode n)
|
||||||
{
|
{
|
||||||
if (_size == 0)
|
if (_size == 0)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
for (int i = 1; i <= _size; i++)
|
for (int i = 1; i <= _size; i++)
|
||||||
{
|
{
|
||||||
if (_list[i].equals(n))
|
if (_list[i].equals(n))
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isEmpty()
|
public boolean isEmpty()
|
||||||
{
|
{
|
||||||
return _size == 0;
|
return _size == 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -18,11 +18,11 @@ package com.l2jmobius.gameserver.instancemanager;
|
|||||||
|
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
|
import com.l2jmobius.gameserver.geodata.pathfinding.AbstractNodeLoc;
|
||||||
import com.l2jmobius.gameserver.model.Location;
|
import com.l2jmobius.gameserver.model.Location;
|
||||||
import com.l2jmobius.gameserver.model.actor.L2Character;
|
import com.l2jmobius.gameserver.model.actor.L2Character;
|
||||||
import com.l2jmobius.gameserver.model.holders.WarpedSpaceHolder;
|
import com.l2jmobius.gameserver.model.holders.WarpedSpaceHolder;
|
||||||
import com.l2jmobius.gameserver.model.instancezone.Instance;
|
import com.l2jmobius.gameserver.model.instancezone.Instance;
|
||||||
import com.l2jmobius.gameserver.pathfinding.AbstractNodeLoc;
|
|
||||||
import com.l2jmobius.gameserver.util.Util;
|
import com.l2jmobius.gameserver.util.Util;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -63,6 +63,8 @@ import com.l2jmobius.gameserver.enums.ShotType;
|
|||||||
import com.l2jmobius.gameserver.enums.StatusUpdateType;
|
import com.l2jmobius.gameserver.enums.StatusUpdateType;
|
||||||
import com.l2jmobius.gameserver.enums.Team;
|
import com.l2jmobius.gameserver.enums.Team;
|
||||||
import com.l2jmobius.gameserver.enums.UserInfoType;
|
import com.l2jmobius.gameserver.enums.UserInfoType;
|
||||||
|
import com.l2jmobius.gameserver.geodata.pathfinding.AbstractNodeLoc;
|
||||||
|
import com.l2jmobius.gameserver.geodata.pathfinding.PathFinding;
|
||||||
import com.l2jmobius.gameserver.idfactory.IdFactory;
|
import com.l2jmobius.gameserver.idfactory.IdFactory;
|
||||||
import com.l2jmobius.gameserver.instancemanager.MapRegionManager;
|
import com.l2jmobius.gameserver.instancemanager.MapRegionManager;
|
||||||
import com.l2jmobius.gameserver.instancemanager.TimersManager;
|
import com.l2jmobius.gameserver.instancemanager.TimersManager;
|
||||||
@@ -153,8 +155,6 @@ import com.l2jmobius.gameserver.network.serverpackets.StopMove;
|
|||||||
import com.l2jmobius.gameserver.network.serverpackets.StopRotation;
|
import com.l2jmobius.gameserver.network.serverpackets.StopRotation;
|
||||||
import com.l2jmobius.gameserver.network.serverpackets.TeleportToLocation;
|
import com.l2jmobius.gameserver.network.serverpackets.TeleportToLocation;
|
||||||
import com.l2jmobius.gameserver.network.serverpackets.UserInfo;
|
import com.l2jmobius.gameserver.network.serverpackets.UserInfo;
|
||||||
import com.l2jmobius.gameserver.pathfinding.AbstractNodeLoc;
|
|
||||||
import com.l2jmobius.gameserver.pathfinding.PathFinding;
|
|
||||||
import com.l2jmobius.gameserver.taskmanager.AttackStanceTaskManager;
|
import com.l2jmobius.gameserver.taskmanager.AttackStanceTaskManager;
|
||||||
import com.l2jmobius.gameserver.util.Util;
|
import com.l2jmobius.gameserver.util.Util;
|
||||||
|
|
||||||
|
|||||||
@@ -18,8 +18,8 @@ package com.l2jmobius.gameserver.util;
|
|||||||
|
|
||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
|
|
||||||
import com.l2jmobius.commons.geodriver.Cell;
|
|
||||||
import com.l2jmobius.gameserver.GeoData;
|
import com.l2jmobius.gameserver.GeoData;
|
||||||
|
import com.l2jmobius.gameserver.geodata.geodriver.Cell;
|
||||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||||
import com.l2jmobius.gameserver.network.serverpackets.ExServerPrimitive;
|
import com.l2jmobius.gameserver.network.serverpackets.ExServerPrimitive;
|
||||||
|
|
||||||
|
|||||||
@@ -19,10 +19,10 @@ package handlers.admincommandhandlers;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import com.l2jmobius.Config;
|
import com.l2jmobius.Config;
|
||||||
|
import com.l2jmobius.gameserver.geodata.pathfinding.AbstractNodeLoc;
|
||||||
|
import com.l2jmobius.gameserver.geodata.pathfinding.PathFinding;
|
||||||
import com.l2jmobius.gameserver.handler.IAdminCommandHandler;
|
import com.l2jmobius.gameserver.handler.IAdminCommandHandler;
|
||||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||||
import com.l2jmobius.gameserver.pathfinding.AbstractNodeLoc;
|
|
||||||
import com.l2jmobius.gameserver.pathfinding.PathFinding;
|
|
||||||
|
|
||||||
public class AdminPathNode implements IAdminCommandHandler
|
public class AdminPathNode implements IAdminCommandHandler
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -98,6 +98,7 @@ import com.l2jmobius.gameserver.datatables.BotReportTable;
|
|||||||
import com.l2jmobius.gameserver.datatables.EventDroplist;
|
import com.l2jmobius.gameserver.datatables.EventDroplist;
|
||||||
import com.l2jmobius.gameserver.datatables.ItemTable;
|
import com.l2jmobius.gameserver.datatables.ItemTable;
|
||||||
import com.l2jmobius.gameserver.datatables.MerchantPriceConfigTable;
|
import com.l2jmobius.gameserver.datatables.MerchantPriceConfigTable;
|
||||||
|
import com.l2jmobius.gameserver.geodata.pathfinding.PathFinding;
|
||||||
import com.l2jmobius.gameserver.handler.ConditionHandler;
|
import com.l2jmobius.gameserver.handler.ConditionHandler;
|
||||||
import com.l2jmobius.gameserver.handler.DailyMissionHandler;
|
import com.l2jmobius.gameserver.handler.DailyMissionHandler;
|
||||||
import com.l2jmobius.gameserver.handler.EffectHandler;
|
import com.l2jmobius.gameserver.handler.EffectHandler;
|
||||||
@@ -145,7 +146,6 @@ import com.l2jmobius.gameserver.model.votereward.VoteSystem;
|
|||||||
import com.l2jmobius.gameserver.network.ClientNetworkManager;
|
import com.l2jmobius.gameserver.network.ClientNetworkManager;
|
||||||
import com.l2jmobius.gameserver.network.loginserver.LoginServerNetworkManager;
|
import com.l2jmobius.gameserver.network.loginserver.LoginServerNetworkManager;
|
||||||
import com.l2jmobius.gameserver.network.telnet.TelnetServer;
|
import com.l2jmobius.gameserver.network.telnet.TelnetServer;
|
||||||
import com.l2jmobius.gameserver.pathfinding.PathFinding;
|
|
||||||
import com.l2jmobius.gameserver.scripting.ScriptEngineManager;
|
import com.l2jmobius.gameserver.scripting.ScriptEngineManager;
|
||||||
import com.l2jmobius.gameserver.taskmanager.TaskManager;
|
import com.l2jmobius.gameserver.taskmanager.TaskManager;
|
||||||
import com.l2jmobius.gameserver.util.Broadcast;
|
import com.l2jmobius.gameserver.util.Broadcast;
|
||||||
|
|||||||
@@ -22,9 +22,9 @@ import java.util.logging.Level;
|
|||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import com.l2jmobius.Config;
|
import com.l2jmobius.Config;
|
||||||
import com.l2jmobius.commons.geodriver.Cell;
|
|
||||||
import com.l2jmobius.commons.geodriver.GeoDriver;
|
|
||||||
import com.l2jmobius.gameserver.data.xml.impl.DoorData;
|
import com.l2jmobius.gameserver.data.xml.impl.DoorData;
|
||||||
|
import com.l2jmobius.gameserver.geodata.geodriver.Cell;
|
||||||
|
import com.l2jmobius.gameserver.geodata.geodriver.GeoDriver;
|
||||||
import com.l2jmobius.gameserver.instancemanager.WarpedSpaceManager;
|
import com.l2jmobius.gameserver.instancemanager.WarpedSpaceManager;
|
||||||
import com.l2jmobius.gameserver.model.L2Object;
|
import com.l2jmobius.gameserver.model.L2Object;
|
||||||
import com.l2jmobius.gameserver.model.L2World;
|
import com.l2jmobius.gameserver.model.L2World;
|
||||||
|
|||||||
@@ -34,12 +34,12 @@ import org.w3c.dom.Node;
|
|||||||
|
|
||||||
import com.l2jmobius.commons.util.IGameXmlReader;
|
import com.l2jmobius.commons.util.IGameXmlReader;
|
||||||
import com.l2jmobius.commons.util.IXmlReader;
|
import com.l2jmobius.commons.util.IXmlReader;
|
||||||
|
import com.l2jmobius.gameserver.geodata.pathfinding.AbstractNodeLoc;
|
||||||
import com.l2jmobius.gameserver.instancemanager.MapRegionManager;
|
import com.l2jmobius.gameserver.instancemanager.MapRegionManager;
|
||||||
import com.l2jmobius.gameserver.model.StatsSet;
|
import com.l2jmobius.gameserver.model.StatsSet;
|
||||||
import com.l2jmobius.gameserver.model.actor.instance.L2DoorInstance;
|
import com.l2jmobius.gameserver.model.actor.instance.L2DoorInstance;
|
||||||
import com.l2jmobius.gameserver.model.actor.templates.L2DoorTemplate;
|
import com.l2jmobius.gameserver.model.actor.templates.L2DoorTemplate;
|
||||||
import com.l2jmobius.gameserver.model.instancezone.Instance;
|
import com.l2jmobius.gameserver.model.instancezone.Instance;
|
||||||
import com.l2jmobius.gameserver.pathfinding.AbstractNodeLoc;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class loads and hold info about doors.
|
* This class loads and hold info about doors.
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package com.l2jmobius.commons.geodriver;
|
package com.l2jmobius.gameserver.geodata.geodriver;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author HorridoJoho
|
* @author HorridoJoho
|
||||||
@@ -1,189 +1,189 @@
|
|||||||
/*
|
/*
|
||||||
* This file is part of the L2J Mobius project.
|
* This file is part of the L2J Mobius project.
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
* General Public License for more details.
|
* General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package com.l2jmobius.commons.geodriver;
|
package com.l2jmobius.gameserver.geodata.geodriver;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.RandomAccessFile;
|
import java.io.RandomAccessFile;
|
||||||
import java.nio.ByteOrder;
|
import java.nio.ByteOrder;
|
||||||
import java.nio.channels.FileChannel.MapMode;
|
import java.nio.channels.FileChannel.MapMode;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.util.concurrent.atomic.AtomicReferenceArray;
|
import java.util.concurrent.atomic.AtomicReferenceArray;
|
||||||
|
|
||||||
import com.l2jmobius.commons.geodriver.regions.NullRegion;
|
import com.l2jmobius.gameserver.geodata.geodriver.regions.NullRegion;
|
||||||
import com.l2jmobius.commons.geodriver.regions.Region;
|
import com.l2jmobius.gameserver.geodata.geodriver.regions.Region;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author HorridoJoho
|
* @author HorridoJoho
|
||||||
*/
|
*/
|
||||||
public final class GeoDriver
|
public final class GeoDriver
|
||||||
{
|
{
|
||||||
// world dimensions: 1048576 * 1048576 = 1099511627776
|
// world dimensions: 1048576 * 1048576 = 1099511627776
|
||||||
private static final int WORLD_MIN_X = -655360;
|
private static final int WORLD_MIN_X = -655360;
|
||||||
private static final int WORLD_MAX_X = 393215;
|
private static final int WORLD_MAX_X = 393215;
|
||||||
private static final int WORLD_MIN_Y = -589824;
|
private static final int WORLD_MIN_Y = -589824;
|
||||||
private static final int WORLD_MAX_Y = 458751;
|
private static final int WORLD_MAX_Y = 458751;
|
||||||
private static final int WORLD_MIN_Z = -16384;
|
private static final int WORLD_MIN_Z = -16384;
|
||||||
private static final int WORLD_MAX_Z = 16384;
|
private static final int WORLD_MAX_Z = 16384;
|
||||||
|
|
||||||
/** Regions in the world on the x axis */
|
/** Regions in the world on the x axis */
|
||||||
public static final int GEO_REGIONS_X = 32;
|
public static final int GEO_REGIONS_X = 32;
|
||||||
/** Regions in the world on the y axis */
|
/** Regions in the world on the y axis */
|
||||||
public static final int GEO_REGIONS_Y = 32;
|
public static final int GEO_REGIONS_Y = 32;
|
||||||
/** Region in the world */
|
/** Region in the world */
|
||||||
public static final int GEO_REGIONS = GEO_REGIONS_X * GEO_REGIONS_Y;
|
public static final int GEO_REGIONS = GEO_REGIONS_X * GEO_REGIONS_Y;
|
||||||
|
|
||||||
/** Blocks in the world on the x axis */
|
/** Blocks in the world on the x axis */
|
||||||
public static final int GEO_BLOCKS_X = GEO_REGIONS_X * IRegion.REGION_BLOCKS_X;
|
public static final int GEO_BLOCKS_X = GEO_REGIONS_X * IRegion.REGION_BLOCKS_X;
|
||||||
/** Blocks in the world on the y axis */
|
/** Blocks in the world on the y axis */
|
||||||
public static final int GEO_BLOCKS_Y = GEO_REGIONS_Y * IRegion.REGION_BLOCKS_Y;
|
public static final int GEO_BLOCKS_Y = GEO_REGIONS_Y * IRegion.REGION_BLOCKS_Y;
|
||||||
/** Blocks in the world */
|
/** Blocks in the world */
|
||||||
public static final int GEO_BLOCKS = GEO_REGIONS * IRegion.REGION_BLOCKS;
|
public static final int GEO_BLOCKS = GEO_REGIONS * IRegion.REGION_BLOCKS;
|
||||||
|
|
||||||
/** Cells in the world on the x axis */
|
/** Cells in the world on the x axis */
|
||||||
public static final int GEO_CELLS_X = GEO_BLOCKS_X * IBlock.BLOCK_CELLS_X;
|
public static final int GEO_CELLS_X = GEO_BLOCKS_X * IBlock.BLOCK_CELLS_X;
|
||||||
/** Cells in the world in the y axis */
|
/** Cells in the world in the y axis */
|
||||||
public static final int GEO_CELLS_Y = GEO_BLOCKS_Y * IBlock.BLOCK_CELLS_Y;
|
public static final int GEO_CELLS_Y = GEO_BLOCKS_Y * IBlock.BLOCK_CELLS_Y;
|
||||||
/** Cells in the world in the z axis */
|
/** Cells in the world in the z axis */
|
||||||
public static final int GEO_CELLS_Z = (Math.abs(WORLD_MIN_Z) + Math.abs(WORLD_MAX_Z)) / 16;
|
public static final int GEO_CELLS_Z = (Math.abs(WORLD_MIN_Z) + Math.abs(WORLD_MAX_Z)) / 16;
|
||||||
|
|
||||||
/** The regions array */
|
/** The regions array */
|
||||||
private final AtomicReferenceArray<IRegion> _regions = new AtomicReferenceArray<>(GEO_REGIONS);
|
private final AtomicReferenceArray<IRegion> _regions = new AtomicReferenceArray<>(GEO_REGIONS);
|
||||||
|
|
||||||
public GeoDriver()
|
public GeoDriver()
|
||||||
{
|
{
|
||||||
for (int i = 0; i < _regions.length(); i++)
|
for (int i = 0; i < _regions.length(); i++)
|
||||||
{
|
{
|
||||||
_regions.set(i, NullRegion.INSTANCE);
|
_regions.set(i, NullRegion.INSTANCE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkGeoX(int geoX)
|
private void checkGeoX(int geoX)
|
||||||
{
|
{
|
||||||
if ((geoX < 0) || (geoX >= GEO_CELLS_X))
|
if ((geoX < 0) || (geoX >= GEO_CELLS_X))
|
||||||
{
|
{
|
||||||
throw new IllegalArgumentException();
|
throw new IllegalArgumentException();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkGeoY(int geoY)
|
private void checkGeoY(int geoY)
|
||||||
{
|
{
|
||||||
if ((geoY < 0) || (geoY >= GEO_CELLS_Y))
|
if ((geoY < 0) || (geoY >= GEO_CELLS_Y))
|
||||||
{
|
{
|
||||||
throw new IllegalArgumentException();
|
throw new IllegalArgumentException();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkGeoZ(int geoZ)
|
private void checkGeoZ(int geoZ)
|
||||||
{
|
{
|
||||||
if ((geoZ < 0) || (geoZ >= GEO_CELLS_Z))
|
if ((geoZ < 0) || (geoZ >= GEO_CELLS_Z))
|
||||||
{
|
{
|
||||||
throw new IllegalArgumentException();
|
throw new IllegalArgumentException();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private IRegion getRegion(int geoX, int geoY)
|
private IRegion getRegion(int geoX, int geoY)
|
||||||
{
|
{
|
||||||
checkGeoX(geoX);
|
checkGeoX(geoX);
|
||||||
checkGeoY(geoY);
|
checkGeoY(geoY);
|
||||||
return _regions.get(((geoX / IRegion.REGION_CELLS_X) * GEO_REGIONS_Y) + (geoY / IRegion.REGION_CELLS_Y));
|
return _regions.get(((geoX / IRegion.REGION_CELLS_X) * GEO_REGIONS_Y) + (geoY / IRegion.REGION_CELLS_Y));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void loadRegion(Path filePath, int regionX, int regionY) throws IOException
|
public void loadRegion(Path filePath, int regionX, int regionY) throws IOException
|
||||||
{
|
{
|
||||||
final int regionOffset = (regionX * GEO_REGIONS_Y) + regionY;
|
final int regionOffset = (regionX * GEO_REGIONS_Y) + regionY;
|
||||||
|
|
||||||
try (RandomAccessFile raf = new RandomAccessFile(filePath.toFile(), "r"))
|
try (RandomAccessFile raf = new RandomAccessFile(filePath.toFile(), "r"))
|
||||||
{
|
{
|
||||||
_regions.set(regionOffset, new Region(raf.getChannel().map(MapMode.READ_ONLY, 0, raf.length()).load().order(ByteOrder.LITTLE_ENDIAN)));
|
_regions.set(regionOffset, new Region(raf.getChannel().map(MapMode.READ_ONLY, 0, raf.length()).load().order(ByteOrder.LITTLE_ENDIAN)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void unloadRegion(int regionX, int regionY)
|
public void unloadRegion(int regionX, int regionY)
|
||||||
{
|
{
|
||||||
_regions.set((regionX * GEO_REGIONS_Y) + regionY, NullRegion.INSTANCE);
|
_regions.set((regionX * GEO_REGIONS_Y) + regionY, NullRegion.INSTANCE);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasGeoPos(int geoX, int geoY)
|
public boolean hasGeoPos(int geoX, int geoY)
|
||||||
{
|
{
|
||||||
return getRegion(geoX, geoY).hasGeo();
|
return getRegion(geoX, geoY).hasGeo();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean checkNearestNswe(int geoX, int geoY, int worldZ, int nswe)
|
public boolean checkNearestNswe(int geoX, int geoY, int worldZ, int nswe)
|
||||||
{
|
{
|
||||||
return getRegion(geoX, geoY).checkNearestNswe(geoX, geoY, worldZ, nswe);
|
return getRegion(geoX, geoY).checkNearestNswe(geoX, geoY, worldZ, nswe);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getNearestZ(int geoX, int geoY, int worldZ)
|
public int getNearestZ(int geoX, int geoY, int worldZ)
|
||||||
{
|
{
|
||||||
return getRegion(geoX, geoY).getNearestZ(geoX, geoY, worldZ);
|
return getRegion(geoX, geoY).getNearestZ(geoX, geoY, worldZ);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getNextLowerZ(int geoX, int geoY, int worldZ)
|
public int getNextLowerZ(int geoX, int geoY, int worldZ)
|
||||||
{
|
{
|
||||||
return getRegion(geoX, geoY).getNextLowerZ(geoX, geoY, worldZ);
|
return getRegion(geoX, geoY).getNextLowerZ(geoX, geoY, worldZ);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getNextHigherZ(int geoX, int geoY, int worldZ)
|
public int getNextHigherZ(int geoX, int geoY, int worldZ)
|
||||||
{
|
{
|
||||||
return getRegion(geoX, geoY).getNextHigherZ(geoX, geoY, worldZ);
|
return getRegion(geoX, geoY).getNextHigherZ(geoX, geoY, worldZ);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getGeoX(int worldX)
|
public int getGeoX(int worldX)
|
||||||
{
|
{
|
||||||
if ((worldX < WORLD_MIN_X) || (worldX > WORLD_MAX_X))
|
if ((worldX < WORLD_MIN_X) || (worldX > WORLD_MAX_X))
|
||||||
{
|
{
|
||||||
throw new IllegalArgumentException();
|
throw new IllegalArgumentException();
|
||||||
}
|
}
|
||||||
return (worldX - WORLD_MIN_X) / 16;
|
return (worldX - WORLD_MIN_X) / 16;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getGeoY(int worldY)
|
public int getGeoY(int worldY)
|
||||||
{
|
{
|
||||||
if ((worldY < WORLD_MIN_Y) || (worldY > WORLD_MAX_Y))
|
if ((worldY < WORLD_MIN_Y) || (worldY > WORLD_MAX_Y))
|
||||||
{
|
{
|
||||||
throw new IllegalArgumentException();
|
throw new IllegalArgumentException();
|
||||||
}
|
}
|
||||||
return (worldY - WORLD_MIN_Y) / 16;
|
return (worldY - WORLD_MIN_Y) / 16;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getGeoZ(int worldZ)
|
public int getGeoZ(int worldZ)
|
||||||
{
|
{
|
||||||
if ((worldZ < WORLD_MIN_Z) || (worldZ > WORLD_MAX_Z))
|
if ((worldZ < WORLD_MIN_Z) || (worldZ > WORLD_MAX_Z))
|
||||||
{
|
{
|
||||||
throw new IllegalArgumentException();
|
throw new IllegalArgumentException();
|
||||||
}
|
}
|
||||||
return (worldZ - WORLD_MIN_Z) / 16;
|
return (worldZ - WORLD_MIN_Z) / 16;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getWorldX(int geoX)
|
public int getWorldX(int geoX)
|
||||||
{
|
{
|
||||||
checkGeoX(geoX);
|
checkGeoX(geoX);
|
||||||
return (geoX * 16) + WORLD_MIN_X + 8;
|
return (geoX * 16) + WORLD_MIN_X + 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getWorldY(int geoY)
|
public int getWorldY(int geoY)
|
||||||
{
|
{
|
||||||
checkGeoY(geoY);
|
checkGeoY(geoY);
|
||||||
return (geoY * 16) + WORLD_MIN_Y + 8;
|
return (geoY * 16) + WORLD_MIN_Y + 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getWorldZ(int geoZ)
|
public int getWorldZ(int geoZ)
|
||||||
{
|
{
|
||||||
checkGeoZ(geoZ);
|
checkGeoZ(geoZ);
|
||||||
return (geoZ * 16) + WORLD_MIN_Z + 8;
|
return (geoZ * 16) + WORLD_MIN_Z + 8;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -14,7 +14,7 @@
|
|||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package com.l2jmobius.commons.geodriver;
|
package com.l2jmobius.gameserver.geodata.geodriver;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author HorridoJoho
|
* @author HorridoJoho
|
||||||
@@ -14,7 +14,7 @@
|
|||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package com.l2jmobius.commons.geodriver;
|
package com.l2jmobius.gameserver.geodata.geodriver;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author HorridoJoho
|
* @author HorridoJoho
|
||||||
@@ -14,11 +14,11 @@
|
|||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package com.l2jmobius.commons.geodriver.blocks;
|
package com.l2jmobius.gameserver.geodata.geodriver.blocks;
|
||||||
|
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
import com.l2jmobius.commons.geodriver.IBlock;
|
import com.l2jmobius.gameserver.geodata.geodriver.IBlock;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author HorridoJoho
|
* @author HorridoJoho
|
||||||
@@ -14,11 +14,11 @@
|
|||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package com.l2jmobius.commons.geodriver.blocks;
|
package com.l2jmobius.gameserver.geodata.geodriver.blocks;
|
||||||
|
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
import com.l2jmobius.commons.geodriver.IBlock;
|
import com.l2jmobius.gameserver.geodata.geodriver.IBlock;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author HorridoJoho
|
* @author HorridoJoho
|
||||||
@@ -14,11 +14,11 @@
|
|||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package com.l2jmobius.commons.geodriver.blocks;
|
package com.l2jmobius.gameserver.geodata.geodriver.blocks;
|
||||||
|
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
import com.l2jmobius.commons.geodriver.IBlock;
|
import com.l2jmobius.gameserver.geodata.geodriver.IBlock;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author HorridoJoho
|
* @author HorridoJoho
|
||||||
@@ -14,9 +14,9 @@
|
|||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package com.l2jmobius.commons.geodriver.regions;
|
package com.l2jmobius.gameserver.geodata.geodriver.regions;
|
||||||
|
|
||||||
import com.l2jmobius.commons.geodriver.IRegion;
|
import com.l2jmobius.gameserver.geodata.geodriver.IRegion;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author HorridoJoho
|
* @author HorridoJoho
|
||||||
@@ -14,15 +14,15 @@
|
|||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package com.l2jmobius.commons.geodriver.regions;
|
package com.l2jmobius.gameserver.geodata.geodriver.regions;
|
||||||
|
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
import com.l2jmobius.commons.geodriver.IBlock;
|
import com.l2jmobius.gameserver.geodata.geodriver.IBlock;
|
||||||
import com.l2jmobius.commons.geodriver.IRegion;
|
import com.l2jmobius.gameserver.geodata.geodriver.IRegion;
|
||||||
import com.l2jmobius.commons.geodriver.blocks.ComplexBlock;
|
import com.l2jmobius.gameserver.geodata.geodriver.blocks.ComplexBlock;
|
||||||
import com.l2jmobius.commons.geodriver.blocks.FlatBlock;
|
import com.l2jmobius.gameserver.geodata.geodriver.blocks.FlatBlock;
|
||||||
import com.l2jmobius.commons.geodriver.blocks.MultilayerBlock;
|
import com.l2jmobius.gameserver.geodata.geodriver.blocks.MultilayerBlock;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author HorridoJoho
|
* @author HorridoJoho
|
||||||
@@ -1,87 +1,87 @@
|
|||||||
/*
|
/*
|
||||||
* This file is part of the L2J Mobius project.
|
* This file is part of the L2J Mobius project.
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
* General Public License for more details.
|
* General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package com.l2jmobius.gameserver.pathfinding;
|
package com.l2jmobius.gameserver.geodata.pathfinding;
|
||||||
|
|
||||||
public abstract class AbstractNode<T extends AbstractNodeLoc>
|
public abstract class AbstractNode<T extends AbstractNodeLoc>
|
||||||
{
|
{
|
||||||
private T _loc;
|
private T _loc;
|
||||||
private AbstractNode<T> _parent;
|
private AbstractNode<T> _parent;
|
||||||
|
|
||||||
public AbstractNode(T loc)
|
public AbstractNode(T loc)
|
||||||
{
|
{
|
||||||
_loc = loc;
|
_loc = loc;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setParent(AbstractNode<T> p)
|
public void setParent(AbstractNode<T> p)
|
||||||
{
|
{
|
||||||
_parent = p;
|
_parent = p;
|
||||||
}
|
}
|
||||||
|
|
||||||
public AbstractNode<T> getParent()
|
public AbstractNode<T> getParent()
|
||||||
{
|
{
|
||||||
return _parent;
|
return _parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
public T getLoc()
|
public T getLoc()
|
||||||
{
|
{
|
||||||
return _loc;
|
return _loc;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setLoc(T l)
|
public void setLoc(T l)
|
||||||
{
|
{
|
||||||
_loc = l;
|
_loc = l;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode()
|
public int hashCode()
|
||||||
{
|
{
|
||||||
final int prime = 31;
|
final int prime = 31;
|
||||||
int result = 1;
|
int result = 1;
|
||||||
result = (prime * result) + ((_loc == null) ? 0 : _loc.hashCode());
|
result = (prime * result) + ((_loc == null) ? 0 : _loc.hashCode());
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object obj)
|
public boolean equals(Object obj)
|
||||||
{
|
{
|
||||||
if (this == obj)
|
if (this == obj)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (obj == null)
|
if (obj == null)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!(obj instanceof AbstractNode))
|
if (!(obj instanceof AbstractNode))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
final AbstractNode<?> other = (AbstractNode<?>) obj;
|
final AbstractNode<?> other = (AbstractNode<?>) obj;
|
||||||
if (_loc == null)
|
if (_loc == null)
|
||||||
{
|
{
|
||||||
if (other._loc != null)
|
if (other._loc != null)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (!_loc.equals(other._loc))
|
else if (!_loc.equals(other._loc))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,33 +1,33 @@
|
|||||||
/*
|
/*
|
||||||
* This file is part of the L2J Mobius project.
|
* This file is part of the L2J Mobius project.
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
* General Public License for more details.
|
* General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package com.l2jmobius.gameserver.pathfinding;
|
package com.l2jmobius.gameserver.geodata.pathfinding;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author -Nemesiss-
|
* @author -Nemesiss-
|
||||||
*/
|
*/
|
||||||
public abstract class AbstractNodeLoc
|
public abstract class AbstractNodeLoc
|
||||||
{
|
{
|
||||||
public abstract int getX();
|
public abstract int getX();
|
||||||
|
|
||||||
public abstract int getY();
|
public abstract int getY();
|
||||||
|
|
||||||
public abstract int getZ();
|
public abstract int getZ();
|
||||||
|
|
||||||
public abstract int getNodeX();
|
public abstract int getNodeX();
|
||||||
|
|
||||||
public abstract int getNodeY();
|
public abstract int getNodeY();
|
||||||
}
|
}
|
||||||
@@ -1,211 +1,211 @@
|
|||||||
/*
|
/*
|
||||||
* This file is part of the L2J Mobius project.
|
* This file is part of the L2J Mobius project.
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
* General Public License for more details.
|
* General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package com.l2jmobius.gameserver.pathfinding;
|
package com.l2jmobius.gameserver.geodata.pathfinding;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import com.l2jmobius.Config;
|
import com.l2jmobius.Config;
|
||||||
import com.l2jmobius.gameserver.model.L2World;
|
import com.l2jmobius.gameserver.geodata.pathfinding.cellnodes.CellPathFinding;
|
||||||
import com.l2jmobius.gameserver.model.instancezone.Instance;
|
import com.l2jmobius.gameserver.geodata.pathfinding.geonodes.GeoPathFinding;
|
||||||
import com.l2jmobius.gameserver.pathfinding.cellnodes.CellPathFinding;
|
import com.l2jmobius.gameserver.model.L2World;
|
||||||
import com.l2jmobius.gameserver.pathfinding.geonodes.GeoPathFinding;
|
import com.l2jmobius.gameserver.model.instancezone.Instance;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author -Nemesiss-
|
* @author -Nemesiss-
|
||||||
*/
|
*/
|
||||||
public abstract class PathFinding
|
public abstract class PathFinding
|
||||||
{
|
{
|
||||||
public static PathFinding getInstance()
|
public static PathFinding getInstance()
|
||||||
{
|
{
|
||||||
if (Config.PATHFINDING == 1)
|
if (Config.PATHFINDING == 1)
|
||||||
{
|
{
|
||||||
// Higher Memory Usage, Smaller Cpu Usage
|
// Higher Memory Usage, Smaller Cpu Usage
|
||||||
return GeoPathFinding.getInstance();
|
return GeoPathFinding.getInstance();
|
||||||
}
|
}
|
||||||
// Cell pathfinding, calculated directly from geodata files
|
// Cell pathfinding, calculated directly from geodata files
|
||||||
return CellPathFinding.getInstance();
|
return CellPathFinding.getInstance();
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract boolean pathNodesExist(short regionoffset);
|
public abstract boolean pathNodesExist(short regionoffset);
|
||||||
|
|
||||||
public abstract List<AbstractNodeLoc> findPath(int x, int y, int z, int tx, int ty, int tz, Instance instance, boolean playable);
|
public abstract List<AbstractNodeLoc> findPath(int x, int y, int z, int tx, int ty, int tz, Instance instance, boolean playable);
|
||||||
|
|
||||||
// @formatter:off
|
// @formatter:off
|
||||||
/*
|
/*
|
||||||
public List<AbstractNodeLoc> search(AbstractNode start, AbstractNode end, int instanceId)
|
public List<AbstractNodeLoc> search(AbstractNode start, AbstractNode end, int instanceId)
|
||||||
{
|
{
|
||||||
// The simplest grid-based pathfinding.
|
// The simplest grid-based pathfinding.
|
||||||
// Drawback is not having higher cost for diagonal movement (means funny routes)
|
// Drawback is not having higher cost for diagonal movement (means funny routes)
|
||||||
// Could be optimized e.g. not to calculate backwards as far as forwards.
|
// Could be optimized e.g. not to calculate backwards as far as forwards.
|
||||||
|
|
||||||
// List of Visited Nodes
|
// List of Visited Nodes
|
||||||
LinkedList<AbstractNode> visited = new LinkedList<AbstractNode>();
|
LinkedList<AbstractNode> visited = new LinkedList<AbstractNode>();
|
||||||
|
|
||||||
// List of Nodes to Visit
|
// List of Nodes to Visit
|
||||||
LinkedList<AbstractNode> to_visit = new LinkedList<AbstractNode>();
|
LinkedList<AbstractNode> to_visit = new LinkedList<AbstractNode>();
|
||||||
to_visit.add(start);
|
to_visit.add(start);
|
||||||
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
while (i < 800)
|
while (i < 800)
|
||||||
{
|
{
|
||||||
AbstractNode node;
|
AbstractNode node;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
node = to_visit.removeFirst();
|
node = to_visit.removeFirst();
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
// No Path found
|
// No Path found
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
if (node.equals(end)) //path found!
|
if (node.equals(end)) //path found!
|
||||||
return constructPath(node, instanceId);
|
return constructPath(node, instanceId);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
i++;
|
i++;
|
||||||
visited.add(node);
|
visited.add(node);
|
||||||
node.attachNeighbors();
|
node.attachNeighbors();
|
||||||
Node[] neighbors = node.getNeighbors();
|
Node[] neighbors = node.getNeighbors();
|
||||||
if (neighbors == null)
|
if (neighbors == null)
|
||||||
continue;
|
continue;
|
||||||
for (Node n : neighbors)
|
for (Node n : neighbors)
|
||||||
{
|
{
|
||||||
if (!visited.contains(n) && !to_visit.contains(n))
|
if (!visited.contains(n) && !to_visit.contains(n))
|
||||||
{
|
{
|
||||||
n.setParent(node);
|
n.setParent(node);
|
||||||
to_visit.add(n);
|
to_visit.add(n);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//No Path found
|
//No Path found
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
public List<AbstractNodeLoc> searchAStar(Node start, Node end, int instanceId)
|
public List<AbstractNodeLoc> searchAStar(Node start, Node end, int instanceId)
|
||||||
{
|
{
|
||||||
// Not operational yet?
|
// Not operational yet?
|
||||||
int start_x = start.getLoc().getX();
|
int start_x = start.getLoc().getX();
|
||||||
int start_y = start.getLoc().getY();
|
int start_y = start.getLoc().getY();
|
||||||
int end_x = end.getLoc().getX();
|
int end_x = end.getLoc().getX();
|
||||||
int end_y = end.getLoc().getY();
|
int end_y = end.getLoc().getY();
|
||||||
//List of Visited Nodes
|
//List of Visited Nodes
|
||||||
FastNodeList visited = new FastNodeList(800);//TODO! Add limit to cfg
|
FastNodeList visited = new FastNodeList(800);//TODO! Add limit to cfg
|
||||||
|
|
||||||
// List of Nodes to Visit
|
// List of Nodes to Visit
|
||||||
BinaryNodeHeap to_visit = new BinaryNodeHeap(800);
|
BinaryNodeHeap to_visit = new BinaryNodeHeap(800);
|
||||||
to_visit.add(start);
|
to_visit.add(start);
|
||||||
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
while (i < 800)//TODO! Add limit to cfg
|
while (i < 800)//TODO! Add limit to cfg
|
||||||
{
|
{
|
||||||
AbstractNode node;
|
AbstractNode node;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
node = to_visit.removeFirst();
|
node = to_visit.removeFirst();
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
// No Path found
|
// No Path found
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
if (node.equals(end)) //path found!
|
if (node.equals(end)) //path found!
|
||||||
return constructPath(node, instanceId);
|
return constructPath(node, instanceId);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
visited.add(node);
|
visited.add(node);
|
||||||
node.attachNeighbors();
|
node.attachNeighbors();
|
||||||
for (Node n : node.getNeighbors())
|
for (Node n : node.getNeighbors())
|
||||||
{
|
{
|
||||||
if (!visited.contains(n) && !to_visit.contains(n))
|
if (!visited.contains(n) && !to_visit.contains(n))
|
||||||
{
|
{
|
||||||
i++;
|
i++;
|
||||||
n.setParent(node);
|
n.setParent(node);
|
||||||
n.setCost(Math.abs(start_x - n.getLoc().getNodeX()) + Math.abs(start_y - n.getLoc().getNodeY())
|
n.setCost(Math.abs(start_x - n.getLoc().getNodeX()) + Math.abs(start_y - n.getLoc().getNodeY())
|
||||||
+ Math.abs(end_x - n.getLoc().getNodeX()) + Math.abs(end_y - n.getLoc().getNodeY()));
|
+ Math.abs(end_x - n.getLoc().getNodeX()) + Math.abs(end_y - n.getLoc().getNodeY()));
|
||||||
to_visit.add(n);
|
to_visit.add(n);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//No Path found
|
//No Path found
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
// @formatter:on
|
// @formatter:on
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert geodata position to pathnode position
|
* Convert geodata position to pathnode position
|
||||||
* @param geo_pos
|
* @param geo_pos
|
||||||
* @return pathnode position
|
* @return pathnode position
|
||||||
*/
|
*/
|
||||||
public short getNodePos(int geo_pos)
|
public short getNodePos(int geo_pos)
|
||||||
{
|
{
|
||||||
return (short) (geo_pos >> 3); // OK?
|
return (short) (geo_pos >> 3); // OK?
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert node position to pathnode block position
|
* Convert node position to pathnode block position
|
||||||
* @param node_pos
|
* @param node_pos
|
||||||
* @return pathnode block position (0...255)
|
* @return pathnode block position (0...255)
|
||||||
*/
|
*/
|
||||||
public short getNodeBlock(int node_pos)
|
public short getNodeBlock(int node_pos)
|
||||||
{
|
{
|
||||||
return (short) (node_pos % 256);
|
return (short) (node_pos % 256);
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte getRegionX(int node_pos)
|
public byte getRegionX(int node_pos)
|
||||||
{
|
{
|
||||||
return (byte) ((node_pos >> 8) + L2World.TILE_X_MIN);
|
return (byte) ((node_pos >> 8) + L2World.TILE_X_MIN);
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte getRegionY(int node_pos)
|
public byte getRegionY(int node_pos)
|
||||||
{
|
{
|
||||||
return (byte) ((node_pos >> 8) + L2World.TILE_Y_MIN);
|
return (byte) ((node_pos >> 8) + L2World.TILE_Y_MIN);
|
||||||
}
|
}
|
||||||
|
|
||||||
public short getRegionOffset(byte rx, byte ry)
|
public short getRegionOffset(byte rx, byte ry)
|
||||||
{
|
{
|
||||||
return (short) ((rx << 5) + ry);
|
return (short) ((rx << 5) + ry);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert pathnode x to World x position
|
* Convert pathnode x to World x position
|
||||||
* @param node_x rx
|
* @param node_x rx
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public int calculateWorldX(short node_x)
|
public int calculateWorldX(short node_x)
|
||||||
{
|
{
|
||||||
return L2World.MAP_MIN_X + (node_x * 128) + 48;
|
return L2World.MAP_MIN_X + (node_x * 128) + 48;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert pathnode y to World y position
|
* Convert pathnode y to World y position
|
||||||
* @param node_y
|
* @param node_y
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public int calculateWorldY(short node_y)
|
public int calculateWorldY(short node_y)
|
||||||
{
|
{
|
||||||
return L2World.MAP_MIN_Y + (node_y * 128) + 48;
|
return L2World.MAP_MIN_Y + (node_y * 128) + 48;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String[] getStat()
|
public String[] getStat()
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,69 +1,69 @@
|
|||||||
/*
|
/*
|
||||||
* This file is part of the L2J Mobius project.
|
* This file is part of the L2J Mobius project.
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
* General Public License for more details.
|
* General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package com.l2jmobius.gameserver.pathfinding.cellnodes;
|
package com.l2jmobius.gameserver.geodata.pathfinding.cellnodes;
|
||||||
|
|
||||||
import com.l2jmobius.gameserver.pathfinding.AbstractNode;
|
import com.l2jmobius.gameserver.geodata.pathfinding.AbstractNode;
|
||||||
|
|
||||||
public class CellNode extends AbstractNode<NodeLoc>
|
public class CellNode extends AbstractNode<NodeLoc>
|
||||||
{
|
{
|
||||||
private CellNode _next = null;
|
private CellNode _next = null;
|
||||||
private boolean _isInUse = true;
|
private boolean _isInUse = true;
|
||||||
private float _cost = -1000;
|
private float _cost = -1000;
|
||||||
|
|
||||||
public CellNode(NodeLoc loc)
|
public CellNode(NodeLoc loc)
|
||||||
{
|
{
|
||||||
super(loc);
|
super(loc);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isInUse()
|
public boolean isInUse()
|
||||||
{
|
{
|
||||||
return _isInUse;
|
return _isInUse;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setInUse()
|
public void setInUse()
|
||||||
{
|
{
|
||||||
_isInUse = true;
|
_isInUse = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public CellNode getNext()
|
public CellNode getNext()
|
||||||
{
|
{
|
||||||
return _next;
|
return _next;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setNext(CellNode next)
|
public void setNext(CellNode next)
|
||||||
{
|
{
|
||||||
_next = next;
|
_next = next;
|
||||||
}
|
}
|
||||||
|
|
||||||
public float getCost()
|
public float getCost()
|
||||||
{
|
{
|
||||||
return _cost;
|
return _cost;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setCost(double cost)
|
public void setCost(double cost)
|
||||||
{
|
{
|
||||||
_cost = (float) cost;
|
_cost = (float) cost;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void free()
|
public void free()
|
||||||
{
|
{
|
||||||
setParent(null);
|
setParent(null);
|
||||||
_cost = -1000;
|
_cost = -1000;
|
||||||
_isInUse = false;
|
_isInUse = false;
|
||||||
_next = null;
|
_next = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,361 +1,361 @@
|
|||||||
/*
|
/*
|
||||||
* This file is part of the L2J Mobius project.
|
* This file is part of the L2J Mobius project.
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
* General Public License for more details.
|
* General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package com.l2jmobius.gameserver.pathfinding.cellnodes;
|
package com.l2jmobius.gameserver.geodata.pathfinding.cellnodes;
|
||||||
|
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.locks.ReentrantLock;
|
import java.util.concurrent.locks.ReentrantLock;
|
||||||
|
|
||||||
import com.l2jmobius.Config;
|
import com.l2jmobius.Config;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author DS Credits to Diamond
|
* @author DS Credits to Diamond
|
||||||
*/
|
*/
|
||||||
public class CellNodeBuffer
|
public class CellNodeBuffer
|
||||||
{
|
{
|
||||||
private static final int MAX_ITERATIONS = 3500;
|
private static final int MAX_ITERATIONS = 3500;
|
||||||
|
|
||||||
private final ReentrantLock _lock = new ReentrantLock();
|
private final ReentrantLock _lock = new ReentrantLock();
|
||||||
private final int _mapSize;
|
private final int _mapSize;
|
||||||
private final CellNode[][] _buffer;
|
private final CellNode[][] _buffer;
|
||||||
|
|
||||||
private int _baseX = 0;
|
private int _baseX = 0;
|
||||||
private int _baseY = 0;
|
private int _baseY = 0;
|
||||||
|
|
||||||
private int _targetX = 0;
|
private int _targetX = 0;
|
||||||
private int _targetY = 0;
|
private int _targetY = 0;
|
||||||
private int _targetZ = 0;
|
private int _targetZ = 0;
|
||||||
|
|
||||||
private long _timeStamp = 0;
|
private long _timeStamp = 0;
|
||||||
private long _lastElapsedTime = 0;
|
private long _lastElapsedTime = 0;
|
||||||
|
|
||||||
private CellNode _current = null;
|
private CellNode _current = null;
|
||||||
|
|
||||||
public CellNodeBuffer(int size)
|
public CellNodeBuffer(int size)
|
||||||
{
|
{
|
||||||
_mapSize = size;
|
_mapSize = size;
|
||||||
_buffer = new CellNode[_mapSize][_mapSize];
|
_buffer = new CellNode[_mapSize][_mapSize];
|
||||||
}
|
}
|
||||||
|
|
||||||
public final boolean lock()
|
public final boolean lock()
|
||||||
{
|
{
|
||||||
return _lock.tryLock();
|
return _lock.tryLock();
|
||||||
}
|
}
|
||||||
|
|
||||||
public final CellNode findPath(int x, int y, int z, int tx, int ty, int tz)
|
public final CellNode findPath(int x, int y, int z, int tx, int ty, int tz)
|
||||||
{
|
{
|
||||||
_timeStamp = System.currentTimeMillis();
|
_timeStamp = System.currentTimeMillis();
|
||||||
_baseX = x + ((tx - x - _mapSize) / 2); // middle of the line (x,y) - (tx,ty)
|
_baseX = x + ((tx - x - _mapSize) / 2); // middle of the line (x,y) - (tx,ty)
|
||||||
_baseY = y + ((ty - y - _mapSize) / 2); // will be in the center of the buffer
|
_baseY = y + ((ty - y - _mapSize) / 2); // will be in the center of the buffer
|
||||||
_targetX = tx;
|
_targetX = tx;
|
||||||
_targetY = ty;
|
_targetY = ty;
|
||||||
_targetZ = tz;
|
_targetZ = tz;
|
||||||
_current = getNode(x, y, z);
|
_current = getNode(x, y, z);
|
||||||
_current.setCost(getCost(x, y, z, Config.HIGH_WEIGHT));
|
_current.setCost(getCost(x, y, z, Config.HIGH_WEIGHT));
|
||||||
|
|
||||||
for (int count = 0; count < MAX_ITERATIONS; count++)
|
for (int count = 0; count < MAX_ITERATIONS; count++)
|
||||||
{
|
{
|
||||||
if ((_current.getLoc().getNodeX() == _targetX) && (_current.getLoc().getNodeY() == _targetY) && (Math.abs(_current.getLoc().getZ() - _targetZ) < 64))
|
if ((_current.getLoc().getNodeX() == _targetX) && (_current.getLoc().getNodeY() == _targetY) && (Math.abs(_current.getLoc().getZ() - _targetZ) < 64))
|
||||||
{
|
{
|
||||||
return _current; // found
|
return _current; // found
|
||||||
}
|
}
|
||||||
|
|
||||||
getNeighbors();
|
getNeighbors();
|
||||||
if (_current.getNext() == null)
|
if (_current.getNext() == null)
|
||||||
{
|
{
|
||||||
return null; // no more ways
|
return null; // no more ways
|
||||||
}
|
}
|
||||||
|
|
||||||
_current = _current.getNext();
|
_current = _current.getNext();
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public final void free()
|
public final void free()
|
||||||
{
|
{
|
||||||
_current = null;
|
_current = null;
|
||||||
|
|
||||||
CellNode node;
|
CellNode node;
|
||||||
for (int i = 0; i < _mapSize; i++)
|
for (int i = 0; i < _mapSize; i++)
|
||||||
{
|
{
|
||||||
for (int j = 0; j < _mapSize; j++)
|
for (int j = 0; j < _mapSize; j++)
|
||||||
{
|
{
|
||||||
node = _buffer[i][j];
|
node = _buffer[i][j];
|
||||||
if (node != null)
|
if (node != null)
|
||||||
{
|
{
|
||||||
node.free();
|
node.free();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_lock.unlock();
|
_lock.unlock();
|
||||||
_lastElapsedTime = System.currentTimeMillis() - _timeStamp;
|
_lastElapsedTime = System.currentTimeMillis() - _timeStamp;
|
||||||
}
|
}
|
||||||
|
|
||||||
public final long getElapsedTime()
|
public final long getElapsedTime()
|
||||||
{
|
{
|
||||||
return _lastElapsedTime;
|
return _lastElapsedTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
public final List<CellNode> debugPath()
|
public final List<CellNode> debugPath()
|
||||||
{
|
{
|
||||||
final List<CellNode> result = new LinkedList<>();
|
final List<CellNode> result = new LinkedList<>();
|
||||||
|
|
||||||
for (CellNode n = _current; n.getParent() != null; n = (CellNode) n.getParent())
|
for (CellNode n = _current; n.getParent() != null; n = (CellNode) n.getParent())
|
||||||
{
|
{
|
||||||
result.add(n);
|
result.add(n);
|
||||||
n.setCost(-n.getCost());
|
n.setCost(-n.getCost());
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < _mapSize; i++)
|
for (int i = 0; i < _mapSize; i++)
|
||||||
{
|
{
|
||||||
for (int j = 0; j < _mapSize; j++)
|
for (int j = 0; j < _mapSize; j++)
|
||||||
{
|
{
|
||||||
final CellNode n = _buffer[i][j];
|
final CellNode n = _buffer[i][j];
|
||||||
if ((n == null) || !n.isInUse() || (n.getCost() <= 0))
|
if ((n == null) || !n.isInUse() || (n.getCost() <= 0))
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
result.add(n);
|
result.add(n);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void getNeighbors()
|
private void getNeighbors()
|
||||||
{
|
{
|
||||||
if (!_current.getLoc().canGoAll())
|
if (!_current.getLoc().canGoAll())
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
final int x = _current.getLoc().getNodeX();
|
final int x = _current.getLoc().getNodeX();
|
||||||
final int y = _current.getLoc().getNodeY();
|
final int y = _current.getLoc().getNodeY();
|
||||||
final int z = _current.getLoc().getZ();
|
final int z = _current.getLoc().getZ();
|
||||||
|
|
||||||
CellNode nodeE = null;
|
CellNode nodeE = null;
|
||||||
CellNode nodeS = null;
|
CellNode nodeS = null;
|
||||||
CellNode nodeW = null;
|
CellNode nodeW = null;
|
||||||
CellNode nodeN = null;
|
CellNode nodeN = null;
|
||||||
|
|
||||||
// East
|
// East
|
||||||
if (_current.getLoc().canGoEast())
|
if (_current.getLoc().canGoEast())
|
||||||
{
|
{
|
||||||
nodeE = addNode(x + 1, y, z, false);
|
nodeE = addNode(x + 1, y, z, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
// South
|
// South
|
||||||
if (_current.getLoc().canGoSouth())
|
if (_current.getLoc().canGoSouth())
|
||||||
{
|
{
|
||||||
nodeS = addNode(x, y + 1, z, false);
|
nodeS = addNode(x, y + 1, z, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
// West
|
// West
|
||||||
if (_current.getLoc().canGoWest())
|
if (_current.getLoc().canGoWest())
|
||||||
{
|
{
|
||||||
nodeW = addNode(x - 1, y, z, false);
|
nodeW = addNode(x - 1, y, z, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
// North
|
// North
|
||||||
if (_current.getLoc().canGoNorth())
|
if (_current.getLoc().canGoNorth())
|
||||||
{
|
{
|
||||||
nodeN = addNode(x, y - 1, z, false);
|
nodeN = addNode(x, y - 1, z, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Config.ADVANCED_DIAGONAL_STRATEGY)
|
if (Config.ADVANCED_DIAGONAL_STRATEGY)
|
||||||
{
|
{
|
||||||
// SouthEast
|
// SouthEast
|
||||||
if ((nodeE != null) && (nodeS != null))
|
if ((nodeE != null) && (nodeS != null))
|
||||||
{
|
{
|
||||||
if (nodeE.getLoc().canGoSouth() && nodeS.getLoc().canGoEast())
|
if (nodeE.getLoc().canGoSouth() && nodeS.getLoc().canGoEast())
|
||||||
{
|
{
|
||||||
addNode(x + 1, y + 1, z, true);
|
addNode(x + 1, y + 1, z, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// SouthWest
|
// SouthWest
|
||||||
if ((nodeS != null) && (nodeW != null))
|
if ((nodeS != null) && (nodeW != null))
|
||||||
{
|
{
|
||||||
if (nodeW.getLoc().canGoSouth() && nodeS.getLoc().canGoWest())
|
if (nodeW.getLoc().canGoSouth() && nodeS.getLoc().canGoWest())
|
||||||
{
|
{
|
||||||
addNode(x - 1, y + 1, z, true);
|
addNode(x - 1, y + 1, z, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// NorthEast
|
// NorthEast
|
||||||
if ((nodeN != null) && (nodeE != null))
|
if ((nodeN != null) && (nodeE != null))
|
||||||
{
|
{
|
||||||
if (nodeE.getLoc().canGoNorth() && nodeN.getLoc().canGoEast())
|
if (nodeE.getLoc().canGoNorth() && nodeN.getLoc().canGoEast())
|
||||||
{
|
{
|
||||||
addNode(x + 1, y - 1, z, true);
|
addNode(x + 1, y - 1, z, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// NorthWest
|
// NorthWest
|
||||||
if ((nodeN != null) && (nodeW != null))
|
if ((nodeN != null) && (nodeW != null))
|
||||||
{
|
{
|
||||||
if (nodeW.getLoc().canGoNorth() && nodeN.getLoc().canGoWest())
|
if (nodeW.getLoc().canGoNorth() && nodeN.getLoc().canGoWest())
|
||||||
{
|
{
|
||||||
addNode(x - 1, y - 1, z, true);
|
addNode(x - 1, y - 1, z, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private CellNode getNode(int x, int y, int z)
|
private CellNode getNode(int x, int y, int z)
|
||||||
{
|
{
|
||||||
final int aX = x - _baseX;
|
final int aX = x - _baseX;
|
||||||
if ((aX < 0) || (aX >= _mapSize))
|
if ((aX < 0) || (aX >= _mapSize))
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
final int aY = y - _baseY;
|
final int aY = y - _baseY;
|
||||||
if ((aY < 0) || (aY >= _mapSize))
|
if ((aY < 0) || (aY >= _mapSize))
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
CellNode result = _buffer[aX][aY];
|
CellNode result = _buffer[aX][aY];
|
||||||
if (result == null)
|
if (result == null)
|
||||||
{
|
{
|
||||||
result = new CellNode(new NodeLoc(x, y, z));
|
result = new CellNode(new NodeLoc(x, y, z));
|
||||||
_buffer[aX][aY] = result;
|
_buffer[aX][aY] = result;
|
||||||
}
|
}
|
||||||
else if (!result.isInUse())
|
else if (!result.isInUse())
|
||||||
{
|
{
|
||||||
result.setInUse();
|
result.setInUse();
|
||||||
// reinit node if needed
|
// reinit node if needed
|
||||||
if (result.getLoc() != null)
|
if (result.getLoc() != null)
|
||||||
{
|
{
|
||||||
result.getLoc().set(x, y, z);
|
result.getLoc().set(x, y, z);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
result.setLoc(new NodeLoc(x, y, z));
|
result.setLoc(new NodeLoc(x, y, z));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private CellNode addNode(int x, int y, int z, boolean diagonal)
|
private CellNode addNode(int x, int y, int z, boolean diagonal)
|
||||||
{
|
{
|
||||||
final CellNode newNode = getNode(x, y, z);
|
final CellNode newNode = getNode(x, y, z);
|
||||||
if (newNode == null)
|
if (newNode == null)
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
if (newNode.getCost() >= 0)
|
if (newNode.getCost() >= 0)
|
||||||
{
|
{
|
||||||
return newNode;
|
return newNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
final int geoZ = newNode.getLoc().getZ();
|
final int geoZ = newNode.getLoc().getZ();
|
||||||
|
|
||||||
final int stepZ = Math.abs(geoZ - _current.getLoc().getZ());
|
final int stepZ = Math.abs(geoZ - _current.getLoc().getZ());
|
||||||
float weight = diagonal ? Config.DIAGONAL_WEIGHT : Config.LOW_WEIGHT;
|
float weight = diagonal ? Config.DIAGONAL_WEIGHT : Config.LOW_WEIGHT;
|
||||||
|
|
||||||
if (!newNode.getLoc().canGoAll() || (stepZ > 16))
|
if (!newNode.getLoc().canGoAll() || (stepZ > 16))
|
||||||
{
|
{
|
||||||
weight = Config.HIGH_WEIGHT;
|
weight = Config.HIGH_WEIGHT;
|
||||||
}
|
}
|
||||||
else if (isHighWeight(x + 1, y, geoZ))
|
else if (isHighWeight(x + 1, y, geoZ))
|
||||||
{
|
{
|
||||||
weight = Config.MEDIUM_WEIGHT;
|
weight = Config.MEDIUM_WEIGHT;
|
||||||
}
|
}
|
||||||
else if (isHighWeight(x - 1, y, geoZ))
|
else if (isHighWeight(x - 1, y, geoZ))
|
||||||
{
|
{
|
||||||
weight = Config.MEDIUM_WEIGHT;
|
weight = Config.MEDIUM_WEIGHT;
|
||||||
}
|
}
|
||||||
else if (isHighWeight(x, y + 1, geoZ))
|
else if (isHighWeight(x, y + 1, geoZ))
|
||||||
{
|
{
|
||||||
weight = Config.MEDIUM_WEIGHT;
|
weight = Config.MEDIUM_WEIGHT;
|
||||||
}
|
}
|
||||||
else if (isHighWeight(x, y - 1, geoZ))
|
else if (isHighWeight(x, y - 1, geoZ))
|
||||||
{
|
{
|
||||||
weight = Config.MEDIUM_WEIGHT;
|
weight = Config.MEDIUM_WEIGHT;
|
||||||
}
|
}
|
||||||
|
|
||||||
newNode.setParent(_current);
|
newNode.setParent(_current);
|
||||||
newNode.setCost(getCost(x, y, geoZ, weight));
|
newNode.setCost(getCost(x, y, geoZ, weight));
|
||||||
|
|
||||||
CellNode node = _current;
|
CellNode node = _current;
|
||||||
int count = 0;
|
int count = 0;
|
||||||
while ((node.getNext() != null) && (count < (MAX_ITERATIONS * 4)))
|
while ((node.getNext() != null) && (count < (MAX_ITERATIONS * 4)))
|
||||||
{
|
{
|
||||||
count++;
|
count++;
|
||||||
if (node.getNext().getCost() > newNode.getCost())
|
if (node.getNext().getCost() > newNode.getCost())
|
||||||
{
|
{
|
||||||
// insert node into a chain
|
// insert node into a chain
|
||||||
newNode.setNext(node.getNext());
|
newNode.setNext(node.getNext());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
node = node.getNext();
|
node = node.getNext();
|
||||||
}
|
}
|
||||||
if (count == (MAX_ITERATIONS * 4))
|
if (count == (MAX_ITERATIONS * 4))
|
||||||
{
|
{
|
||||||
System.err.println("Pathfinding: too long loop detected, cost:" + newNode.getCost());
|
System.err.println("Pathfinding: too long loop detected, cost:" + newNode.getCost());
|
||||||
}
|
}
|
||||||
|
|
||||||
node.setNext(newNode); // add last
|
node.setNext(newNode); // add last
|
||||||
|
|
||||||
return newNode;
|
return newNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isHighWeight(int x, int y, int z)
|
private boolean isHighWeight(int x, int y, int z)
|
||||||
{
|
{
|
||||||
final CellNode result = getNode(x, y, z);
|
final CellNode result = getNode(x, y, z);
|
||||||
if (result == null)
|
if (result == null)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!result.getLoc().canGoAll())
|
if (!result.getLoc().canGoAll())
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (Math.abs(result.getLoc().getZ() - z) > 16)
|
if (Math.abs(result.getLoc().getZ() - z) > 16)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private double getCost(int x, int y, int z, float weight)
|
private double getCost(int x, int y, int z, float weight)
|
||||||
{
|
{
|
||||||
final int dX = x - _targetX;
|
final int dX = x - _targetX;
|
||||||
final int dY = y - _targetY;
|
final int dY = y - _targetY;
|
||||||
final int dZ = z - _targetZ;
|
final int dZ = z - _targetZ;
|
||||||
// Math.abs(dx) + Math.abs(dy) + Math.abs(dz) / 16
|
// Math.abs(dx) + Math.abs(dy) + Math.abs(dz) / 16
|
||||||
double result = Math.sqrt((dX * dX) + (dY * dY) + ((dZ * dZ) / 256.0));
|
double result = Math.sqrt((dX * dX) + (dY * dY) + ((dZ * dZ) / 256.0));
|
||||||
if (result > weight)
|
if (result > weight)
|
||||||
{
|
{
|
||||||
result += weight;
|
result += weight;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result > Float.MAX_VALUE)
|
if (result > Float.MAX_VALUE)
|
||||||
{
|
{
|
||||||
result = Float.MAX_VALUE;
|
result = Float.MAX_VALUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,440 +1,440 @@
|
|||||||
/*
|
/*
|
||||||
* This file is part of the L2J Mobius project.
|
* This file is part of the L2J Mobius project.
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
* General Public License for more details.
|
* General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package com.l2jmobius.gameserver.pathfinding.cellnodes;
|
package com.l2jmobius.gameserver.geodata.pathfinding.cellnodes;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.ListIterator;
|
import java.util.ListIterator;
|
||||||
import java.util.concurrent.CopyOnWriteArrayList;
|
import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import com.l2jmobius.Config;
|
import com.l2jmobius.Config;
|
||||||
import com.l2jmobius.gameserver.GeoData;
|
import com.l2jmobius.gameserver.GeoData;
|
||||||
import com.l2jmobius.gameserver.idfactory.IdFactory;
|
import com.l2jmobius.gameserver.geodata.pathfinding.AbstractNode;
|
||||||
import com.l2jmobius.gameserver.model.instancezone.Instance;
|
import com.l2jmobius.gameserver.geodata.pathfinding.AbstractNodeLoc;
|
||||||
import com.l2jmobius.gameserver.model.itemcontainer.Inventory;
|
import com.l2jmobius.gameserver.geodata.pathfinding.PathFinding;
|
||||||
import com.l2jmobius.gameserver.model.items.instance.L2ItemInstance;
|
import com.l2jmobius.gameserver.idfactory.IdFactory;
|
||||||
import com.l2jmobius.gameserver.pathfinding.AbstractNode;
|
import com.l2jmobius.gameserver.model.instancezone.Instance;
|
||||||
import com.l2jmobius.gameserver.pathfinding.AbstractNodeLoc;
|
import com.l2jmobius.gameserver.model.itemcontainer.Inventory;
|
||||||
import com.l2jmobius.gameserver.pathfinding.PathFinding;
|
import com.l2jmobius.gameserver.model.items.instance.L2ItemInstance;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Sami, DS Credits to Diamond
|
* @author Sami, DS Credits to Diamond
|
||||||
*/
|
*/
|
||||||
public class CellPathFinding extends PathFinding
|
public class CellPathFinding extends PathFinding
|
||||||
{
|
{
|
||||||
private static final Logger _log = Logger.getLogger(CellPathFinding.class.getName());
|
private static final Logger _log = Logger.getLogger(CellPathFinding.class.getName());
|
||||||
private BufferInfo[] _allBuffers;
|
private BufferInfo[] _allBuffers;
|
||||||
private int _findSuccess = 0;
|
private int _findSuccess = 0;
|
||||||
private int _findFails = 0;
|
private int _findFails = 0;
|
||||||
private int _postFilterUses = 0;
|
private int _postFilterUses = 0;
|
||||||
private int _postFilterPlayableUses = 0;
|
private int _postFilterPlayableUses = 0;
|
||||||
private int _postFilterPasses = 0;
|
private int _postFilterPasses = 0;
|
||||||
private long _postFilterElapsed = 0;
|
private long _postFilterElapsed = 0;
|
||||||
|
|
||||||
private List<L2ItemInstance> _debugItems = null;
|
private List<L2ItemInstance> _debugItems = null;
|
||||||
|
|
||||||
public static CellPathFinding getInstance()
|
public static CellPathFinding getInstance()
|
||||||
{
|
{
|
||||||
return SingletonHolder._instance;
|
return SingletonHolder._instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected CellPathFinding()
|
protected CellPathFinding()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
final String[] array = Config.PATHFIND_BUFFERS.split(";");
|
final String[] array = Config.PATHFIND_BUFFERS.split(";");
|
||||||
|
|
||||||
_allBuffers = new BufferInfo[array.length];
|
_allBuffers = new BufferInfo[array.length];
|
||||||
|
|
||||||
String buf;
|
String buf;
|
||||||
String[] args;
|
String[] args;
|
||||||
for (int i = 0; i < array.length; i++)
|
for (int i = 0; i < array.length; i++)
|
||||||
{
|
{
|
||||||
buf = array[i];
|
buf = array[i];
|
||||||
args = buf.split("x");
|
args = buf.split("x");
|
||||||
if (args.length != 2)
|
if (args.length != 2)
|
||||||
{
|
{
|
||||||
throw new Exception("Invalid buffer definition: " + buf);
|
throw new Exception("Invalid buffer definition: " + buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
_allBuffers[i] = new BufferInfo(Integer.parseInt(args[0]), Integer.parseInt(args[1]));
|
_allBuffers[i] = new BufferInfo(Integer.parseInt(args[0]), Integer.parseInt(args[1]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
_log.log(Level.WARNING, "CellPathFinding: Problem during buffer init: " + e.getMessage(), e);
|
_log.log(Level.WARNING, "CellPathFinding: Problem during buffer init: " + e.getMessage(), e);
|
||||||
throw new Error("CellPathFinding: load aborted");
|
throw new Error("CellPathFinding: load aborted");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean pathNodesExist(short regionoffset)
|
public boolean pathNodesExist(short regionoffset)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<AbstractNodeLoc> findPath(int x, int y, int z, int tx, int ty, int tz, Instance instance, boolean playable)
|
public List<AbstractNodeLoc> findPath(int x, int y, int z, int tx, int ty, int tz, Instance instance, boolean playable)
|
||||||
{
|
{
|
||||||
final int gx = GeoData.getInstance().getGeoX(x);
|
final int gx = GeoData.getInstance().getGeoX(x);
|
||||||
final int gy = GeoData.getInstance().getGeoY(y);
|
final int gy = GeoData.getInstance().getGeoY(y);
|
||||||
if (!GeoData.getInstance().hasGeo(x, y))
|
if (!GeoData.getInstance().hasGeo(x, y))
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
final int gz = GeoData.getInstance().getHeight(x, y, z);
|
final int gz = GeoData.getInstance().getHeight(x, y, z);
|
||||||
final int gtx = GeoData.getInstance().getGeoX(tx);
|
final int gtx = GeoData.getInstance().getGeoX(tx);
|
||||||
final int gty = GeoData.getInstance().getGeoY(ty);
|
final int gty = GeoData.getInstance().getGeoY(ty);
|
||||||
if (!GeoData.getInstance().hasGeo(tx, ty))
|
if (!GeoData.getInstance().hasGeo(tx, ty))
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
final int gtz = GeoData.getInstance().getHeight(tx, ty, tz);
|
final int gtz = GeoData.getInstance().getHeight(tx, ty, tz);
|
||||||
final CellNodeBuffer buffer = alloc(64 + (2 * Math.max(Math.abs(gx - gtx), Math.abs(gy - gty))), playable);
|
final CellNodeBuffer buffer = alloc(64 + (2 * Math.max(Math.abs(gx - gtx), Math.abs(gy - gty))), playable);
|
||||||
if (buffer == null)
|
if (buffer == null)
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
final boolean debug = playable && Config.DEBUG_PATH;
|
final boolean debug = playable && Config.DEBUG_PATH;
|
||||||
|
|
||||||
if (debug)
|
if (debug)
|
||||||
{
|
{
|
||||||
if (_debugItems == null)
|
if (_debugItems == null)
|
||||||
{
|
{
|
||||||
_debugItems = new CopyOnWriteArrayList<>();
|
_debugItems = new CopyOnWriteArrayList<>();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for (L2ItemInstance item : _debugItems)
|
for (L2ItemInstance item : _debugItems)
|
||||||
{
|
{
|
||||||
if (item == null)
|
if (item == null)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
item.decayMe();
|
item.decayMe();
|
||||||
}
|
}
|
||||||
|
|
||||||
_debugItems.clear();
|
_debugItems.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
List<AbstractNodeLoc> path = null;
|
List<AbstractNodeLoc> path = null;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
final CellNode result = buffer.findPath(gx, gy, gz, gtx, gty, gtz);
|
final CellNode result = buffer.findPath(gx, gy, gz, gtx, gty, gtz);
|
||||||
|
|
||||||
if (debug)
|
if (debug)
|
||||||
{
|
{
|
||||||
for (CellNode n : buffer.debugPath())
|
for (CellNode n : buffer.debugPath())
|
||||||
{
|
{
|
||||||
if (n.getCost() < 0)
|
if (n.getCost() < 0)
|
||||||
{
|
{
|
||||||
dropDebugItem(1831, (int) (-n.getCost() * 10), n.getLoc());
|
dropDebugItem(1831, (int) (-n.getCost() * 10), n.getLoc());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// known nodes
|
// known nodes
|
||||||
dropDebugItem(Inventory.ADENA_ID, (int) (n.getCost() * 10), n.getLoc());
|
dropDebugItem(Inventory.ADENA_ID, (int) (n.getCost() * 10), n.getLoc());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result == null)
|
if (result == null)
|
||||||
{
|
{
|
||||||
_findFails++;
|
_findFails++;
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
path = constructPath(result);
|
path = constructPath(result);
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
_log.log(Level.WARNING, "", e);
|
_log.log(Level.WARNING, "", e);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
buffer.free();
|
buffer.free();
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((path.size() < 3) || (Config.MAX_POSTFILTER_PASSES <= 0))
|
if ((path.size() < 3) || (Config.MAX_POSTFILTER_PASSES <= 0))
|
||||||
{
|
{
|
||||||
_findSuccess++;
|
_findSuccess++;
|
||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
final long timeStamp = System.currentTimeMillis();
|
final long timeStamp = System.currentTimeMillis();
|
||||||
_postFilterUses++;
|
_postFilterUses++;
|
||||||
if (playable)
|
if (playable)
|
||||||
{
|
{
|
||||||
_postFilterPlayableUses++;
|
_postFilterPlayableUses++;
|
||||||
}
|
}
|
||||||
|
|
||||||
int currentX, currentY, currentZ;
|
int currentX, currentY, currentZ;
|
||||||
ListIterator<AbstractNodeLoc> middlePoint;
|
ListIterator<AbstractNodeLoc> middlePoint;
|
||||||
boolean remove;
|
boolean remove;
|
||||||
int pass = 0;
|
int pass = 0;
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
pass++;
|
pass++;
|
||||||
_postFilterPasses++;
|
_postFilterPasses++;
|
||||||
|
|
||||||
remove = false;
|
remove = false;
|
||||||
middlePoint = path.listIterator();
|
middlePoint = path.listIterator();
|
||||||
currentX = x;
|
currentX = x;
|
||||||
currentY = y;
|
currentY = y;
|
||||||
currentZ = z;
|
currentZ = z;
|
||||||
|
|
||||||
while (middlePoint.hasNext())
|
while (middlePoint.hasNext())
|
||||||
{
|
{
|
||||||
final AbstractNodeLoc locMiddle = middlePoint.next();
|
final AbstractNodeLoc locMiddle = middlePoint.next();
|
||||||
if (!middlePoint.hasNext())
|
if (!middlePoint.hasNext())
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
final AbstractNodeLoc locEnd = path.get(middlePoint.nextIndex());
|
final AbstractNodeLoc locEnd = path.get(middlePoint.nextIndex());
|
||||||
if (GeoData.getInstance().canMove(currentX, currentY, currentZ, locEnd.getX(), locEnd.getY(), locEnd.getZ(), instance))
|
if (GeoData.getInstance().canMove(currentX, currentY, currentZ, locEnd.getX(), locEnd.getY(), locEnd.getZ(), instance))
|
||||||
{
|
{
|
||||||
middlePoint.remove();
|
middlePoint.remove();
|
||||||
remove = true;
|
remove = true;
|
||||||
if (debug)
|
if (debug)
|
||||||
{
|
{
|
||||||
dropDebugItem(735, 1, locMiddle);
|
dropDebugItem(735, 1, locMiddle);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
currentX = locMiddle.getX();
|
currentX = locMiddle.getX();
|
||||||
currentY = locMiddle.getY();
|
currentY = locMiddle.getY();
|
||||||
currentZ = locMiddle.getZ();
|
currentZ = locMiddle.getZ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// only one postfilter pass for AI
|
// only one postfilter pass for AI
|
||||||
while (playable && remove && (path.size() > 2) && (pass < Config.MAX_POSTFILTER_PASSES));
|
while (playable && remove && (path.size() > 2) && (pass < Config.MAX_POSTFILTER_PASSES));
|
||||||
|
|
||||||
if (debug)
|
if (debug)
|
||||||
{
|
{
|
||||||
path.forEach(n -> dropDebugItem(65, 1, n));
|
path.forEach(n -> dropDebugItem(65, 1, n));
|
||||||
}
|
}
|
||||||
|
|
||||||
_findSuccess++;
|
_findSuccess++;
|
||||||
_postFilterElapsed += System.currentTimeMillis() - timeStamp;
|
_postFilterElapsed += System.currentTimeMillis() - timeStamp;
|
||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<AbstractNodeLoc> constructPath(AbstractNode<NodeLoc> node)
|
private List<AbstractNodeLoc> constructPath(AbstractNode<NodeLoc> node)
|
||||||
{
|
{
|
||||||
final LinkedList<AbstractNodeLoc> path = new LinkedList<>();
|
final LinkedList<AbstractNodeLoc> path = new LinkedList<>();
|
||||||
int previousDirectionX = Integer.MIN_VALUE;
|
int previousDirectionX = Integer.MIN_VALUE;
|
||||||
int previousDirectionY = Integer.MIN_VALUE;
|
int previousDirectionY = Integer.MIN_VALUE;
|
||||||
int directionX, directionY;
|
int directionX, directionY;
|
||||||
|
|
||||||
while (node.getParent() != null)
|
while (node.getParent() != null)
|
||||||
{
|
{
|
||||||
if (!Config.ADVANCED_DIAGONAL_STRATEGY && (node.getParent().getParent() != null))
|
if (!Config.ADVANCED_DIAGONAL_STRATEGY && (node.getParent().getParent() != null))
|
||||||
{
|
{
|
||||||
final int tmpX = node.getLoc().getNodeX() - node.getParent().getParent().getLoc().getNodeX();
|
final int tmpX = node.getLoc().getNodeX() - node.getParent().getParent().getLoc().getNodeX();
|
||||||
final int tmpY = node.getLoc().getNodeY() - node.getParent().getParent().getLoc().getNodeY();
|
final int tmpY = node.getLoc().getNodeY() - node.getParent().getParent().getLoc().getNodeY();
|
||||||
if (Math.abs(tmpX) == Math.abs(tmpY))
|
if (Math.abs(tmpX) == Math.abs(tmpY))
|
||||||
{
|
{
|
||||||
directionX = tmpX;
|
directionX = tmpX;
|
||||||
directionY = tmpY;
|
directionY = tmpY;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
directionX = node.getLoc().getNodeX() - node.getParent().getLoc().getNodeX();
|
directionX = node.getLoc().getNodeX() - node.getParent().getLoc().getNodeX();
|
||||||
directionY = node.getLoc().getNodeY() - node.getParent().getLoc().getNodeY();
|
directionY = node.getLoc().getNodeY() - node.getParent().getLoc().getNodeY();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
directionX = node.getLoc().getNodeX() - node.getParent().getLoc().getNodeX();
|
directionX = node.getLoc().getNodeX() - node.getParent().getLoc().getNodeX();
|
||||||
directionY = node.getLoc().getNodeY() - node.getParent().getLoc().getNodeY();
|
directionY = node.getLoc().getNodeY() - node.getParent().getLoc().getNodeY();
|
||||||
}
|
}
|
||||||
|
|
||||||
// only add a new route point if moving direction changes
|
// only add a new route point if moving direction changes
|
||||||
if ((directionX != previousDirectionX) || (directionY != previousDirectionY))
|
if ((directionX != previousDirectionX) || (directionY != previousDirectionY))
|
||||||
{
|
{
|
||||||
previousDirectionX = directionX;
|
previousDirectionX = directionX;
|
||||||
previousDirectionY = directionY;
|
previousDirectionY = directionY;
|
||||||
|
|
||||||
path.addFirst(node.getLoc());
|
path.addFirst(node.getLoc());
|
||||||
node.setLoc(null);
|
node.setLoc(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
node = node.getParent();
|
node = node.getParent();
|
||||||
}
|
}
|
||||||
|
|
||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
private CellNodeBuffer alloc(int size, boolean playable)
|
private CellNodeBuffer alloc(int size, boolean playable)
|
||||||
{
|
{
|
||||||
CellNodeBuffer current = null;
|
CellNodeBuffer current = null;
|
||||||
for (BufferInfo i : _allBuffers)
|
for (BufferInfo i : _allBuffers)
|
||||||
{
|
{
|
||||||
if (i.mapSize >= size)
|
if (i.mapSize >= size)
|
||||||
{
|
{
|
||||||
for (CellNodeBuffer buf : i.bufs)
|
for (CellNodeBuffer buf : i.bufs)
|
||||||
{
|
{
|
||||||
if (buf.lock())
|
if (buf.lock())
|
||||||
{
|
{
|
||||||
i.uses++;
|
i.uses++;
|
||||||
if (playable)
|
if (playable)
|
||||||
{
|
{
|
||||||
i.playableUses++;
|
i.playableUses++;
|
||||||
}
|
}
|
||||||
i.elapsed += buf.getElapsedTime();
|
i.elapsed += buf.getElapsedTime();
|
||||||
current = buf;
|
current = buf;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (current != null)
|
if (current != null)
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// not found, allocate temporary buffer
|
// not found, allocate temporary buffer
|
||||||
current = new CellNodeBuffer(i.mapSize);
|
current = new CellNodeBuffer(i.mapSize);
|
||||||
current.lock();
|
current.lock();
|
||||||
if (i.bufs.size() < i.count)
|
if (i.bufs.size() < i.count)
|
||||||
{
|
{
|
||||||
i.bufs.add(current);
|
i.bufs.add(current);
|
||||||
i.uses++;
|
i.uses++;
|
||||||
if (playable)
|
if (playable)
|
||||||
{
|
{
|
||||||
i.playableUses++;
|
i.playableUses++;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
i.overflows++;
|
i.overflows++;
|
||||||
if (playable)
|
if (playable)
|
||||||
{
|
{
|
||||||
i.playableOverflows++;
|
i.playableOverflows++;
|
||||||
// System.err.println("Overflow, size requested: " + size + " playable:"+playable);
|
// System.err.println("Overflow, size requested: " + size + " playable:"+playable);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return current;
|
return current;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void dropDebugItem(int itemId, int num, AbstractNodeLoc loc)
|
private void dropDebugItem(int itemId, int num, AbstractNodeLoc loc)
|
||||||
{
|
{
|
||||||
final L2ItemInstance item = new L2ItemInstance(IdFactory.getInstance().getNextId(), itemId);
|
final L2ItemInstance item = new L2ItemInstance(IdFactory.getInstance().getNextId(), itemId);
|
||||||
item.setCount(num);
|
item.setCount(num);
|
||||||
item.spawnMe(loc.getX(), loc.getY(), loc.getZ());
|
item.spawnMe(loc.getX(), loc.getY(), loc.getZ());
|
||||||
_debugItems.add(item);
|
_debugItems.add(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final class BufferInfo
|
private static final class BufferInfo
|
||||||
{
|
{
|
||||||
final int mapSize;
|
final int mapSize;
|
||||||
final int count;
|
final int count;
|
||||||
ArrayList<CellNodeBuffer> bufs;
|
ArrayList<CellNodeBuffer> bufs;
|
||||||
int uses = 0;
|
int uses = 0;
|
||||||
int playableUses = 0;
|
int playableUses = 0;
|
||||||
int overflows = 0;
|
int overflows = 0;
|
||||||
int playableOverflows = 0;
|
int playableOverflows = 0;
|
||||||
long elapsed = 0;
|
long elapsed = 0;
|
||||||
|
|
||||||
public BufferInfo(int size, int cnt)
|
public BufferInfo(int size, int cnt)
|
||||||
{
|
{
|
||||||
mapSize = size;
|
mapSize = size;
|
||||||
count = cnt;
|
count = cnt;
|
||||||
bufs = new ArrayList<>(count);
|
bufs = new ArrayList<>(count);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString()
|
public String toString()
|
||||||
{
|
{
|
||||||
final StringBuilder sb = new StringBuilder(100);
|
final StringBuilder sb = new StringBuilder(100);
|
||||||
sb.append(mapSize);
|
sb.append(mapSize);
|
||||||
sb.append("x");
|
sb.append("x");
|
||||||
sb.append(mapSize);
|
sb.append(mapSize);
|
||||||
sb.append(" num:");
|
sb.append(" num:");
|
||||||
sb.append(bufs.size());
|
sb.append(bufs.size());
|
||||||
sb.append("/");
|
sb.append("/");
|
||||||
sb.append(count);
|
sb.append(count);
|
||||||
sb.append(" uses:");
|
sb.append(" uses:");
|
||||||
sb.append(uses);
|
sb.append(uses);
|
||||||
sb.append("/");
|
sb.append("/");
|
||||||
sb.append(playableUses);
|
sb.append(playableUses);
|
||||||
if (uses > 0)
|
if (uses > 0)
|
||||||
{
|
{
|
||||||
sb.append(" total/avg(ms):");
|
sb.append(" total/avg(ms):");
|
||||||
sb.append(elapsed);
|
sb.append(elapsed);
|
||||||
sb.append("/");
|
sb.append("/");
|
||||||
sb.append(String.format("%1.2f", (double) elapsed / uses));
|
sb.append(String.format("%1.2f", (double) elapsed / uses));
|
||||||
}
|
}
|
||||||
|
|
||||||
sb.append(" ovf:");
|
sb.append(" ovf:");
|
||||||
sb.append(overflows);
|
sb.append(overflows);
|
||||||
sb.append("/");
|
sb.append("/");
|
||||||
sb.append(playableOverflows);
|
sb.append(playableOverflows);
|
||||||
|
|
||||||
return sb.toString();
|
return sb.toString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String[] getStat()
|
public String[] getStat()
|
||||||
{
|
{
|
||||||
final String[] result = new String[_allBuffers.length + 1];
|
final String[] result = new String[_allBuffers.length + 1];
|
||||||
for (int i = 0; i < _allBuffers.length; i++)
|
for (int i = 0; i < _allBuffers.length; i++)
|
||||||
{
|
{
|
||||||
result[i] = _allBuffers[i].toString();
|
result[i] = _allBuffers[i].toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
final StringBuilder sb = new StringBuilder(128);
|
final StringBuilder sb = new StringBuilder(128);
|
||||||
sb.append("LOS postfilter uses:");
|
sb.append("LOS postfilter uses:");
|
||||||
sb.append(_postFilterUses);
|
sb.append(_postFilterUses);
|
||||||
sb.append("/");
|
sb.append("/");
|
||||||
sb.append(_postFilterPlayableUses);
|
sb.append(_postFilterPlayableUses);
|
||||||
if (_postFilterUses > 0)
|
if (_postFilterUses > 0)
|
||||||
{
|
{
|
||||||
sb.append(" total/avg(ms):");
|
sb.append(" total/avg(ms):");
|
||||||
sb.append(_postFilterElapsed);
|
sb.append(_postFilterElapsed);
|
||||||
sb.append("/");
|
sb.append("/");
|
||||||
sb.append(String.format("%1.2f", (double) _postFilterElapsed / _postFilterUses));
|
sb.append(String.format("%1.2f", (double) _postFilterElapsed / _postFilterUses));
|
||||||
sb.append(" passes total/avg:");
|
sb.append(" passes total/avg:");
|
||||||
sb.append(_postFilterPasses);
|
sb.append(_postFilterPasses);
|
||||||
sb.append("/");
|
sb.append("/");
|
||||||
sb.append(String.format("%1.1f", (double) _postFilterPasses / _postFilterUses));
|
sb.append(String.format("%1.1f", (double) _postFilterPasses / _postFilterUses));
|
||||||
sb.append(Config.EOL);
|
sb.append(Config.EOL);
|
||||||
}
|
}
|
||||||
sb.append("Pathfind success/fail:");
|
sb.append("Pathfind success/fail:");
|
||||||
sb.append(_findSuccess);
|
sb.append(_findSuccess);
|
||||||
sb.append("/");
|
sb.append("/");
|
||||||
sb.append(_findFails);
|
sb.append(_findFails);
|
||||||
result[result.length - 1] = sb.toString();
|
result[result.length - 1] = sb.toString();
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class SingletonHolder
|
private static class SingletonHolder
|
||||||
{
|
{
|
||||||
protected static final CellPathFinding _instance = new CellPathFinding();
|
protected static final CellPathFinding _instance = new CellPathFinding();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,184 +1,184 @@
|
|||||||
/*
|
/*
|
||||||
* This file is part of the L2J Mobius project.
|
* This file is part of the L2J Mobius project.
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
* General Public License for more details.
|
* General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package com.l2jmobius.gameserver.pathfinding.cellnodes;
|
package com.l2jmobius.gameserver.geodata.pathfinding.cellnodes;
|
||||||
|
|
||||||
import com.l2jmobius.commons.geodriver.Cell;
|
import com.l2jmobius.gameserver.GeoData;
|
||||||
import com.l2jmobius.gameserver.GeoData;
|
import com.l2jmobius.gameserver.geodata.geodriver.Cell;
|
||||||
import com.l2jmobius.gameserver.pathfinding.AbstractNodeLoc;
|
import com.l2jmobius.gameserver.geodata.pathfinding.AbstractNodeLoc;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author -Nemesiss-, HorridoJoho
|
* @author -Nemesiss-, HorridoJoho
|
||||||
*/
|
*/
|
||||||
public class NodeLoc extends AbstractNodeLoc
|
public class NodeLoc extends AbstractNodeLoc
|
||||||
{
|
{
|
||||||
private int _x;
|
private int _x;
|
||||||
private int _y;
|
private int _y;
|
||||||
private boolean _goNorth;
|
private boolean _goNorth;
|
||||||
private boolean _goEast;
|
private boolean _goEast;
|
||||||
private boolean _goSouth;
|
private boolean _goSouth;
|
||||||
private boolean _goWest;
|
private boolean _goWest;
|
||||||
private int _geoHeight;
|
private int _geoHeight;
|
||||||
|
|
||||||
public NodeLoc(int x, int y, int z)
|
public NodeLoc(int x, int y, int z)
|
||||||
{
|
{
|
||||||
set(x, y, z);
|
set(x, y, z);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void set(int x, int y, int z)
|
public void set(int x, int y, int z)
|
||||||
{
|
{
|
||||||
_x = x;
|
_x = x;
|
||||||
_y = y;
|
_y = y;
|
||||||
_goNorth = GeoData.getInstance().checkNearestNswe(x, y, z, Cell.NSWE_NORTH);
|
_goNorth = GeoData.getInstance().checkNearestNswe(x, y, z, Cell.NSWE_NORTH);
|
||||||
_goEast = GeoData.getInstance().checkNearestNswe(x, y, z, Cell.NSWE_EAST);
|
_goEast = GeoData.getInstance().checkNearestNswe(x, y, z, Cell.NSWE_EAST);
|
||||||
_goSouth = GeoData.getInstance().checkNearestNswe(x, y, z, Cell.NSWE_SOUTH);
|
_goSouth = GeoData.getInstance().checkNearestNswe(x, y, z, Cell.NSWE_SOUTH);
|
||||||
_goWest = GeoData.getInstance().checkNearestNswe(x, y, z, Cell.NSWE_WEST);
|
_goWest = GeoData.getInstance().checkNearestNswe(x, y, z, Cell.NSWE_WEST);
|
||||||
_geoHeight = GeoData.getInstance().getNearestZ(x, y, z);
|
_geoHeight = GeoData.getInstance().getNearestZ(x, y, z);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean canGoNorth()
|
public boolean canGoNorth()
|
||||||
{
|
{
|
||||||
return _goNorth;
|
return _goNorth;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean canGoEast()
|
public boolean canGoEast()
|
||||||
{
|
{
|
||||||
return _goEast;
|
return _goEast;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean canGoSouth()
|
public boolean canGoSouth()
|
||||||
{
|
{
|
||||||
return _goSouth;
|
return _goSouth;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean canGoWest()
|
public boolean canGoWest()
|
||||||
{
|
{
|
||||||
return _goWest;
|
return _goWest;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean canGoAll()
|
public boolean canGoAll()
|
||||||
{
|
{
|
||||||
return canGoNorth() && canGoEast() && canGoSouth() && canGoWest();
|
return canGoNorth() && canGoEast() && canGoSouth() && canGoWest();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getX()
|
public int getX()
|
||||||
{
|
{
|
||||||
return GeoData.getInstance().getWorldX(_x);
|
return GeoData.getInstance().getWorldX(_x);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getY()
|
public int getY()
|
||||||
{
|
{
|
||||||
return GeoData.getInstance().getWorldY(_y);
|
return GeoData.getInstance().getWorldY(_y);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getZ()
|
public int getZ()
|
||||||
{
|
{
|
||||||
return _geoHeight;
|
return _geoHeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getNodeX()
|
public int getNodeX()
|
||||||
{
|
{
|
||||||
return _x;
|
return _x;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getNodeY()
|
public int getNodeY()
|
||||||
{
|
{
|
||||||
return _y;
|
return _y;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode()
|
public int hashCode()
|
||||||
{
|
{
|
||||||
final int prime = 31;
|
final int prime = 31;
|
||||||
int result = 1;
|
int result = 1;
|
||||||
result = (prime * result) + _x;
|
result = (prime * result) + _x;
|
||||||
result = (prime * result) + _y;
|
result = (prime * result) + _y;
|
||||||
|
|
||||||
int nswe = 0;
|
int nswe = 0;
|
||||||
if (canGoNorth())
|
if (canGoNorth())
|
||||||
{
|
{
|
||||||
nswe |= Cell.NSWE_NORTH;
|
nswe |= Cell.NSWE_NORTH;
|
||||||
}
|
}
|
||||||
if (canGoEast())
|
if (canGoEast())
|
||||||
{
|
{
|
||||||
nswe |= Cell.NSWE_EAST;
|
nswe |= Cell.NSWE_EAST;
|
||||||
}
|
}
|
||||||
if (canGoSouth())
|
if (canGoSouth())
|
||||||
{
|
{
|
||||||
nswe |= Cell.NSWE_SOUTH;
|
nswe |= Cell.NSWE_SOUTH;
|
||||||
}
|
}
|
||||||
if (canGoWest())
|
if (canGoWest())
|
||||||
{
|
{
|
||||||
nswe |= Cell.NSWE_WEST;
|
nswe |= Cell.NSWE_WEST;
|
||||||
}
|
}
|
||||||
|
|
||||||
result = (prime * result) + (((_geoHeight & 0xFFFF) << 1) | nswe);
|
result = (prime * result) + (((_geoHeight & 0xFFFF) << 1) | nswe);
|
||||||
return result;
|
return result;
|
||||||
// return super.hashCode();
|
// return super.hashCode();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object obj)
|
public boolean equals(Object obj)
|
||||||
{
|
{
|
||||||
if (this == obj)
|
if (this == obj)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (obj == null)
|
if (obj == null)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!(obj instanceof NodeLoc))
|
if (!(obj instanceof NodeLoc))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
final NodeLoc other = (NodeLoc) obj;
|
final NodeLoc other = (NodeLoc) obj;
|
||||||
if (_x != other._x)
|
if (_x != other._x)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (_y != other._y)
|
if (_y != other._y)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (_goNorth != other._goNorth)
|
if (_goNorth != other._goNorth)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (_goEast != other._goEast)
|
if (_goEast != other._goEast)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (_goSouth != other._goSouth)
|
if (_goSouth != other._goSouth)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (_goWest != other._goWest)
|
if (_goWest != other._goWest)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (_geoHeight != other._geoHeight)
|
if (_geoHeight != other._geoHeight)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,62 +1,62 @@
|
|||||||
/*
|
/*
|
||||||
* This file is part of the L2J Mobius project.
|
* This file is part of the L2J Mobius project.
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
* General Public License for more details.
|
* General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package com.l2jmobius.gameserver.pathfinding.geonodes;
|
package com.l2jmobius.gameserver.geodata.pathfinding.geonodes;
|
||||||
|
|
||||||
import com.l2jmobius.gameserver.pathfinding.AbstractNode;
|
import com.l2jmobius.gameserver.geodata.pathfinding.AbstractNode;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author -Nemesiss-
|
* @author -Nemesiss-
|
||||||
*/
|
*/
|
||||||
public class GeoNode extends AbstractNode<GeoNodeLoc>
|
public class GeoNode extends AbstractNode<GeoNodeLoc>
|
||||||
{
|
{
|
||||||
private final int _neighborsIdx;
|
private final int _neighborsIdx;
|
||||||
private short _cost;
|
private short _cost;
|
||||||
private GeoNode[] _neighbors;
|
private GeoNode[] _neighbors;
|
||||||
|
|
||||||
public GeoNode(GeoNodeLoc Loc, int Neighbors_idx)
|
public GeoNode(GeoNodeLoc Loc, int Neighbors_idx)
|
||||||
{
|
{
|
||||||
super(Loc);
|
super(Loc);
|
||||||
_neighborsIdx = Neighbors_idx;
|
_neighborsIdx = Neighbors_idx;
|
||||||
}
|
}
|
||||||
|
|
||||||
public short getCost()
|
public short getCost()
|
||||||
{
|
{
|
||||||
return _cost;
|
return _cost;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setCost(int cost)
|
public void setCost(int cost)
|
||||||
{
|
{
|
||||||
_cost = (short) cost;
|
_cost = (short) cost;
|
||||||
}
|
}
|
||||||
|
|
||||||
public GeoNode[] getNeighbors()
|
public GeoNode[] getNeighbors()
|
||||||
{
|
{
|
||||||
return _neighbors;
|
return _neighbors;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void attachNeighbors()
|
public void attachNeighbors()
|
||||||
{
|
{
|
||||||
if (getLoc() == null)
|
if (getLoc() == null)
|
||||||
{
|
{
|
||||||
_neighbors = null;
|
_neighbors = null;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_neighbors = GeoPathFinding.getInstance().readNeighbors(this, _neighborsIdx);
|
_neighbors = GeoPathFinding.getInstance().readNeighbors(this, _neighborsIdx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,109 +1,109 @@
|
|||||||
/*
|
/*
|
||||||
* This file is part of the L2J Mobius project.
|
* This file is part of the L2J Mobius project.
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
* General Public License for more details.
|
* General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package com.l2jmobius.gameserver.pathfinding.geonodes;
|
package com.l2jmobius.gameserver.geodata.pathfinding.geonodes;
|
||||||
|
|
||||||
import com.l2jmobius.gameserver.model.L2World;
|
import com.l2jmobius.gameserver.geodata.pathfinding.AbstractNodeLoc;
|
||||||
import com.l2jmobius.gameserver.pathfinding.AbstractNodeLoc;
|
import com.l2jmobius.gameserver.model.L2World;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author -Nemesiss-
|
* @author -Nemesiss-
|
||||||
*/
|
*/
|
||||||
public class GeoNodeLoc extends AbstractNodeLoc
|
public class GeoNodeLoc extends AbstractNodeLoc
|
||||||
{
|
{
|
||||||
private final short _x;
|
private final short _x;
|
||||||
private final short _y;
|
private final short _y;
|
||||||
private final short _z;
|
private final short _z;
|
||||||
|
|
||||||
public GeoNodeLoc(short x, short y, short z)
|
public GeoNodeLoc(short x, short y, short z)
|
||||||
{
|
{
|
||||||
_x = x;
|
_x = x;
|
||||||
_y = y;
|
_y = y;
|
||||||
_z = z;
|
_z = z;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getX()
|
public int getX()
|
||||||
{
|
{
|
||||||
return L2World.MAP_MIN_X + (_x * 128) + 48;
|
return L2World.MAP_MIN_X + (_x * 128) + 48;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getY()
|
public int getY()
|
||||||
{
|
{
|
||||||
return L2World.MAP_MIN_Y + (_y * 128) + 48;
|
return L2World.MAP_MIN_Y + (_y * 128) + 48;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getZ()
|
public int getZ()
|
||||||
{
|
{
|
||||||
return _z;
|
return _z;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getNodeX()
|
public int getNodeX()
|
||||||
{
|
{
|
||||||
return _x;
|
return _x;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getNodeY()
|
public int getNodeY()
|
||||||
{
|
{
|
||||||
return _y;
|
return _y;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode()
|
public int hashCode()
|
||||||
{
|
{
|
||||||
final int prime = 31;
|
final int prime = 31;
|
||||||
int result = 1;
|
int result = 1;
|
||||||
result = (prime * result) + _x;
|
result = (prime * result) + _x;
|
||||||
result = (prime * result) + _y;
|
result = (prime * result) + _y;
|
||||||
result = (prime * result) + _z;
|
result = (prime * result) + _z;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object obj)
|
public boolean equals(Object obj)
|
||||||
{
|
{
|
||||||
if (this == obj)
|
if (this == obj)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (obj == null)
|
if (obj == null)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!(obj instanceof GeoNodeLoc))
|
if (!(obj instanceof GeoNodeLoc))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
final GeoNodeLoc other = (GeoNodeLoc) obj;
|
final GeoNodeLoc other = (GeoNodeLoc) obj;
|
||||||
if (_x != other._x)
|
if (_x != other._x)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (_y != other._y)
|
if (_y != other._y)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (_z != other._z)
|
if (_z != other._z)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,470 +1,470 @@
|
|||||||
/*
|
/*
|
||||||
* This file is part of the L2J Mobius project.
|
* This file is part of the L2J Mobius project.
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
* General Public License for more details.
|
* General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package com.l2jmobius.gameserver.pathfinding.geonodes;
|
package com.l2jmobius.gameserver.geodata.pathfinding.geonodes;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.RandomAccessFile;
|
import java.io.RandomAccessFile;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.nio.IntBuffer;
|
import java.nio.IntBuffer;
|
||||||
import java.nio.MappedByteBuffer;
|
import java.nio.MappedByteBuffer;
|
||||||
import java.nio.channels.FileChannel;
|
import java.nio.channels.FileChannel;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import com.l2jmobius.Config;
|
import com.l2jmobius.Config;
|
||||||
import com.l2jmobius.gameserver.GeoData;
|
import com.l2jmobius.gameserver.GeoData;
|
||||||
import com.l2jmobius.gameserver.model.L2World;
|
import com.l2jmobius.gameserver.geodata.pathfinding.AbstractNode;
|
||||||
import com.l2jmobius.gameserver.model.Location;
|
import com.l2jmobius.gameserver.geodata.pathfinding.AbstractNodeLoc;
|
||||||
import com.l2jmobius.gameserver.model.instancezone.Instance;
|
import com.l2jmobius.gameserver.geodata.pathfinding.PathFinding;
|
||||||
import com.l2jmobius.gameserver.pathfinding.AbstractNode;
|
import com.l2jmobius.gameserver.model.L2World;
|
||||||
import com.l2jmobius.gameserver.pathfinding.AbstractNodeLoc;
|
import com.l2jmobius.gameserver.model.Location;
|
||||||
import com.l2jmobius.gameserver.pathfinding.PathFinding;
|
import com.l2jmobius.gameserver.model.instancezone.Instance;
|
||||||
import com.l2jmobius.gameserver.util.Util;
|
import com.l2jmobius.gameserver.util.Util;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author -Nemesiss-
|
* @author -Nemesiss-
|
||||||
*/
|
*/
|
||||||
public class GeoPathFinding extends PathFinding
|
public class GeoPathFinding extends PathFinding
|
||||||
{
|
{
|
||||||
private static Logger _log = Logger.getLogger(GeoPathFinding.class.getName());
|
private static Logger _log = Logger.getLogger(GeoPathFinding.class.getName());
|
||||||
private static Map<Short, ByteBuffer> _pathNodes = new ConcurrentHashMap<>();
|
private static Map<Short, ByteBuffer> _pathNodes = new ConcurrentHashMap<>();
|
||||||
private static Map<Short, IntBuffer> _pathNodesIndex = new ConcurrentHashMap<>();
|
private static Map<Short, IntBuffer> _pathNodesIndex = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
public static GeoPathFinding getInstance()
|
public static GeoPathFinding getInstance()
|
||||||
{
|
{
|
||||||
return SingletonHolder._instance;
|
return SingletonHolder._instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean pathNodesExist(short regionoffset)
|
public boolean pathNodesExist(short regionoffset)
|
||||||
{
|
{
|
||||||
return _pathNodesIndex.containsKey(regionoffset);
|
return _pathNodesIndex.containsKey(regionoffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<AbstractNodeLoc> findPath(int x, int y, int z, int tx, int ty, int tz, Instance instance, boolean playable)
|
public List<AbstractNodeLoc> findPath(int x, int y, int z, int tx, int ty, int tz, Instance instance, boolean playable)
|
||||||
{
|
{
|
||||||
final int gx = (x - L2World.MAP_MIN_X) >> 4;
|
final int gx = (x - L2World.MAP_MIN_X) >> 4;
|
||||||
final int gy = (y - L2World.MAP_MIN_Y) >> 4;
|
final int gy = (y - L2World.MAP_MIN_Y) >> 4;
|
||||||
final short gz = (short) z;
|
final short gz = (short) z;
|
||||||
final int gtx = (tx - L2World.MAP_MIN_X) >> 4;
|
final int gtx = (tx - L2World.MAP_MIN_X) >> 4;
|
||||||
final int gty = (ty - L2World.MAP_MIN_Y) >> 4;
|
final int gty = (ty - L2World.MAP_MIN_Y) >> 4;
|
||||||
final short gtz = (short) tz;
|
final short gtz = (short) tz;
|
||||||
|
|
||||||
final GeoNode start = readNode(gx, gy, gz);
|
final GeoNode start = readNode(gx, gy, gz);
|
||||||
final GeoNode end = readNode(gtx, gty, gtz);
|
final GeoNode end = readNode(gtx, gty, gtz);
|
||||||
if ((start == null) || (end == null))
|
if ((start == null) || (end == null))
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
if (Math.abs(start.getLoc().getZ() - z) > 55)
|
if (Math.abs(start.getLoc().getZ() - z) > 55)
|
||||||
{
|
{
|
||||||
return null; // not correct layer
|
return null; // not correct layer
|
||||||
}
|
}
|
||||||
if (Math.abs(end.getLoc().getZ() - tz) > 55)
|
if (Math.abs(end.getLoc().getZ() - tz) > 55)
|
||||||
{
|
{
|
||||||
return null; // not correct layer
|
return null; // not correct layer
|
||||||
}
|
}
|
||||||
if (start == end)
|
if (start == end)
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Find closest path node we CAN access. Now only checks if we can not reach the closest
|
// TODO: Find closest path node we CAN access. Now only checks if we can not reach the closest
|
||||||
Location temp = GeoData.getInstance().moveCheck(x, y, z, start.getLoc().getX(), start.getLoc().getY(), start.getLoc().getZ(), instance);
|
Location temp = GeoData.getInstance().moveCheck(x, y, z, start.getLoc().getX(), start.getLoc().getY(), start.getLoc().getZ(), instance);
|
||||||
if ((temp.getX() != start.getLoc().getX()) || (temp.getY() != start.getLoc().getY()))
|
if ((temp.getX() != start.getLoc().getX()) || (temp.getY() != start.getLoc().getY()))
|
||||||
{
|
{
|
||||||
return null; // cannot reach closest...
|
return null; // cannot reach closest...
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Find closest path node around target, now only checks if final location can be reached
|
// TODO: Find closest path node around target, now only checks if final location can be reached
|
||||||
temp = GeoData.getInstance().moveCheck(tx, ty, tz, end.getLoc().getX(), end.getLoc().getY(), end.getLoc().getZ(), instance);
|
temp = GeoData.getInstance().moveCheck(tx, ty, tz, end.getLoc().getX(), end.getLoc().getY(), end.getLoc().getZ(), instance);
|
||||||
if ((temp.getX() != end.getLoc().getX()) || (temp.getY() != end.getLoc().getY()))
|
if ((temp.getX() != end.getLoc().getX()) || (temp.getY() != end.getLoc().getY()))
|
||||||
{
|
{
|
||||||
return null; // cannot reach closest...
|
return null; // cannot reach closest...
|
||||||
}
|
}
|
||||||
|
|
||||||
// return searchAStar(start, end);
|
// return searchAStar(start, end);
|
||||||
return searchByClosest2(start, end);
|
return searchByClosest2(start, end);
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<AbstractNodeLoc> searchByClosest2(GeoNode start, GeoNode end)
|
public List<AbstractNodeLoc> searchByClosest2(GeoNode start, GeoNode end)
|
||||||
{
|
{
|
||||||
// Always continues checking from the closest to target non-blocked
|
// Always continues checking from the closest to target non-blocked
|
||||||
// node from to_visit list. There's extra length in path if needed
|
// node from to_visit list. There's extra length in path if needed
|
||||||
// to go backwards/sideways but when moving generally forwards, this is extra fast
|
// to go backwards/sideways but when moving generally forwards, this is extra fast
|
||||||
// and accurate. And can reach insane distances (try it with 800 nodes..).
|
// and accurate. And can reach insane distances (try it with 800 nodes..).
|
||||||
// Minimum required node count would be around 300-400.
|
// Minimum required node count would be around 300-400.
|
||||||
// Generally returns a bit (only a bit) more intelligent looking routes than
|
// Generally returns a bit (only a bit) more intelligent looking routes than
|
||||||
// the basic version. Not a true distance image (which would increase CPU
|
// the basic version. Not a true distance image (which would increase CPU
|
||||||
// load) level of intelligence though.
|
// load) level of intelligence though.
|
||||||
|
|
||||||
// List of Visited Nodes
|
// List of Visited Nodes
|
||||||
final List<GeoNode> visited = new ArrayList<>(550);
|
final List<GeoNode> visited = new ArrayList<>(550);
|
||||||
|
|
||||||
// List of Nodes to Visit
|
// List of Nodes to Visit
|
||||||
final LinkedList<GeoNode> to_visit = new LinkedList<>();
|
final LinkedList<GeoNode> to_visit = new LinkedList<>();
|
||||||
to_visit.add(start);
|
to_visit.add(start);
|
||||||
final int targetX = end.getLoc().getNodeX();
|
final int targetX = end.getLoc().getNodeX();
|
||||||
final int targetY = end.getLoc().getNodeY();
|
final int targetY = end.getLoc().getNodeY();
|
||||||
|
|
||||||
int dx, dy;
|
int dx, dy;
|
||||||
boolean added;
|
boolean added;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
while (i < 550)
|
while (i < 550)
|
||||||
{
|
{
|
||||||
GeoNode node;
|
GeoNode node;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
node = to_visit.removeFirst();
|
node = to_visit.removeFirst();
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
// No Path found
|
// No Path found
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
if (node.equals(end))
|
if (node.equals(end))
|
||||||
{
|
{
|
||||||
return constructPath2(node);
|
return constructPath2(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
i++;
|
i++;
|
||||||
visited.add(node);
|
visited.add(node);
|
||||||
node.attachNeighbors();
|
node.attachNeighbors();
|
||||||
final GeoNode[] neighbors = node.getNeighbors();
|
final GeoNode[] neighbors = node.getNeighbors();
|
||||||
if (neighbors == null)
|
if (neighbors == null)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
for (GeoNode n : neighbors)
|
for (GeoNode n : neighbors)
|
||||||
{
|
{
|
||||||
if ((visited.lastIndexOf(n) == -1) && !to_visit.contains(n))
|
if ((visited.lastIndexOf(n) == -1) && !to_visit.contains(n))
|
||||||
{
|
{
|
||||||
added = false;
|
added = false;
|
||||||
n.setParent(node);
|
n.setParent(node);
|
||||||
dx = targetX - n.getLoc().getNodeX();
|
dx = targetX - n.getLoc().getNodeX();
|
||||||
dy = targetY - n.getLoc().getNodeY();
|
dy = targetY - n.getLoc().getNodeY();
|
||||||
n.setCost((dx * dx) + (dy * dy));
|
n.setCost((dx * dx) + (dy * dy));
|
||||||
for (int index = 0; index < to_visit.size(); index++)
|
for (int index = 0; index < to_visit.size(); index++)
|
||||||
{
|
{
|
||||||
// supposed to find it quite early..
|
// supposed to find it quite early..
|
||||||
if (to_visit.get(index).getCost() > n.getCost())
|
if (to_visit.get(index).getCost() > n.getCost())
|
||||||
{
|
{
|
||||||
to_visit.add(index, n);
|
to_visit.add(index, n);
|
||||||
added = true;
|
added = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!added)
|
if (!added)
|
||||||
{
|
{
|
||||||
to_visit.addLast(n);
|
to_visit.addLast(n);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// No Path found
|
// No Path found
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<AbstractNodeLoc> constructPath2(AbstractNode<GeoNodeLoc> node)
|
public List<AbstractNodeLoc> constructPath2(AbstractNode<GeoNodeLoc> node)
|
||||||
{
|
{
|
||||||
final LinkedList<AbstractNodeLoc> path = new LinkedList<>();
|
final LinkedList<AbstractNodeLoc> path = new LinkedList<>();
|
||||||
int previousDirectionX = -1000;
|
int previousDirectionX = -1000;
|
||||||
int previousDirectionY = -1000;
|
int previousDirectionY = -1000;
|
||||||
int directionX;
|
int directionX;
|
||||||
int directionY;
|
int directionY;
|
||||||
|
|
||||||
while (node.getParent() != null)
|
while (node.getParent() != null)
|
||||||
{
|
{
|
||||||
// only add a new route point if moving direction changes
|
// only add a new route point if moving direction changes
|
||||||
directionX = node.getLoc().getNodeX() - node.getParent().getLoc().getNodeX();
|
directionX = node.getLoc().getNodeX() - node.getParent().getLoc().getNodeX();
|
||||||
directionY = node.getLoc().getNodeY() - node.getParent().getLoc().getNodeY();
|
directionY = node.getLoc().getNodeY() - node.getParent().getLoc().getNodeY();
|
||||||
|
|
||||||
if ((directionX != previousDirectionX) || (directionY != previousDirectionY))
|
if ((directionX != previousDirectionX) || (directionY != previousDirectionY))
|
||||||
{
|
{
|
||||||
previousDirectionX = directionX;
|
previousDirectionX = directionX;
|
||||||
previousDirectionY = directionY;
|
previousDirectionY = directionY;
|
||||||
path.addFirst(node.getLoc());
|
path.addFirst(node.getLoc());
|
||||||
}
|
}
|
||||||
node = node.getParent();
|
node = node.getParent();
|
||||||
}
|
}
|
||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
public GeoNode[] readNeighbors(GeoNode n, int idx)
|
public GeoNode[] readNeighbors(GeoNode n, int idx)
|
||||||
{
|
{
|
||||||
final int node_x = n.getLoc().getNodeX();
|
final int node_x = n.getLoc().getNodeX();
|
||||||
final int node_y = n.getLoc().getNodeY();
|
final int node_y = n.getLoc().getNodeY();
|
||||||
// short node_z = n.getLoc().getZ();
|
// short node_z = n.getLoc().getZ();
|
||||||
|
|
||||||
final short regoffset = getRegionOffset(getRegionX(node_x), getRegionY(node_y));
|
final short regoffset = getRegionOffset(getRegionX(node_x), getRegionY(node_y));
|
||||||
final ByteBuffer pn = _pathNodes.get(regoffset);
|
final ByteBuffer pn = _pathNodes.get(regoffset);
|
||||||
|
|
||||||
final List<AbstractNode<GeoNodeLoc>> Neighbors = new ArrayList<>(8);
|
final List<AbstractNode<GeoNodeLoc>> Neighbors = new ArrayList<>(8);
|
||||||
GeoNode newNode;
|
GeoNode newNode;
|
||||||
short new_node_x, new_node_y;
|
short new_node_x, new_node_y;
|
||||||
|
|
||||||
// Region for sure will change, we must read from correct file
|
// Region for sure will change, we must read from correct file
|
||||||
byte neighbor = pn.get(idx++); // N
|
byte neighbor = pn.get(idx++); // N
|
||||||
if (neighbor > 0)
|
if (neighbor > 0)
|
||||||
{
|
{
|
||||||
neighbor--;
|
neighbor--;
|
||||||
new_node_x = (short) node_x;
|
new_node_x = (short) node_x;
|
||||||
new_node_y = (short) (node_y - 1);
|
new_node_y = (short) (node_y - 1);
|
||||||
newNode = readNode(new_node_x, new_node_y, neighbor);
|
newNode = readNode(new_node_x, new_node_y, neighbor);
|
||||||
if (newNode != null)
|
if (newNode != null)
|
||||||
{
|
{
|
||||||
Neighbors.add(newNode);
|
Neighbors.add(newNode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
neighbor = pn.get(idx++); // NE
|
neighbor = pn.get(idx++); // NE
|
||||||
if (neighbor > 0)
|
if (neighbor > 0)
|
||||||
{
|
{
|
||||||
neighbor--;
|
neighbor--;
|
||||||
new_node_x = (short) (node_x + 1);
|
new_node_x = (short) (node_x + 1);
|
||||||
new_node_y = (short) (node_y - 1);
|
new_node_y = (short) (node_y - 1);
|
||||||
newNode = readNode(new_node_x, new_node_y, neighbor);
|
newNode = readNode(new_node_x, new_node_y, neighbor);
|
||||||
if (newNode != null)
|
if (newNode != null)
|
||||||
{
|
{
|
||||||
Neighbors.add(newNode);
|
Neighbors.add(newNode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
neighbor = pn.get(idx++); // E
|
neighbor = pn.get(idx++); // E
|
||||||
if (neighbor > 0)
|
if (neighbor > 0)
|
||||||
{
|
{
|
||||||
neighbor--;
|
neighbor--;
|
||||||
new_node_x = (short) (node_x + 1);
|
new_node_x = (short) (node_x + 1);
|
||||||
new_node_y = (short) node_y;
|
new_node_y = (short) node_y;
|
||||||
newNode = readNode(new_node_x, new_node_y, neighbor);
|
newNode = readNode(new_node_x, new_node_y, neighbor);
|
||||||
if (newNode != null)
|
if (newNode != null)
|
||||||
{
|
{
|
||||||
Neighbors.add(newNode);
|
Neighbors.add(newNode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
neighbor = pn.get(idx++); // SE
|
neighbor = pn.get(idx++); // SE
|
||||||
if (neighbor > 0)
|
if (neighbor > 0)
|
||||||
{
|
{
|
||||||
neighbor--;
|
neighbor--;
|
||||||
new_node_x = (short) (node_x + 1);
|
new_node_x = (short) (node_x + 1);
|
||||||
new_node_y = (short) (node_y + 1);
|
new_node_y = (short) (node_y + 1);
|
||||||
newNode = readNode(new_node_x, new_node_y, neighbor);
|
newNode = readNode(new_node_x, new_node_y, neighbor);
|
||||||
if (newNode != null)
|
if (newNode != null)
|
||||||
{
|
{
|
||||||
Neighbors.add(newNode);
|
Neighbors.add(newNode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
neighbor = pn.get(idx++); // S
|
neighbor = pn.get(idx++); // S
|
||||||
if (neighbor > 0)
|
if (neighbor > 0)
|
||||||
{
|
{
|
||||||
neighbor--;
|
neighbor--;
|
||||||
new_node_x = (short) node_x;
|
new_node_x = (short) node_x;
|
||||||
new_node_y = (short) (node_y + 1);
|
new_node_y = (short) (node_y + 1);
|
||||||
newNode = readNode(new_node_x, new_node_y, neighbor);
|
newNode = readNode(new_node_x, new_node_y, neighbor);
|
||||||
if (newNode != null)
|
if (newNode != null)
|
||||||
{
|
{
|
||||||
Neighbors.add(newNode);
|
Neighbors.add(newNode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
neighbor = pn.get(idx++); // SW
|
neighbor = pn.get(idx++); // SW
|
||||||
if (neighbor > 0)
|
if (neighbor > 0)
|
||||||
{
|
{
|
||||||
neighbor--;
|
neighbor--;
|
||||||
new_node_x = (short) (node_x - 1);
|
new_node_x = (short) (node_x - 1);
|
||||||
new_node_y = (short) (node_y + 1);
|
new_node_y = (short) (node_y + 1);
|
||||||
newNode = readNode(new_node_x, new_node_y, neighbor);
|
newNode = readNode(new_node_x, new_node_y, neighbor);
|
||||||
if (newNode != null)
|
if (newNode != null)
|
||||||
{
|
{
|
||||||
Neighbors.add(newNode);
|
Neighbors.add(newNode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
neighbor = pn.get(idx++); // W
|
neighbor = pn.get(idx++); // W
|
||||||
if (neighbor > 0)
|
if (neighbor > 0)
|
||||||
{
|
{
|
||||||
neighbor--;
|
neighbor--;
|
||||||
new_node_x = (short) (node_x - 1);
|
new_node_x = (short) (node_x - 1);
|
||||||
new_node_y = (short) node_y;
|
new_node_y = (short) node_y;
|
||||||
newNode = readNode(new_node_x, new_node_y, neighbor);
|
newNode = readNode(new_node_x, new_node_y, neighbor);
|
||||||
if (newNode != null)
|
if (newNode != null)
|
||||||
{
|
{
|
||||||
Neighbors.add(newNode);
|
Neighbors.add(newNode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
neighbor = pn.get(idx++); // NW
|
neighbor = pn.get(idx++); // NW
|
||||||
if (neighbor > 0)
|
if (neighbor > 0)
|
||||||
{
|
{
|
||||||
neighbor--;
|
neighbor--;
|
||||||
new_node_x = (short) (node_x - 1);
|
new_node_x = (short) (node_x - 1);
|
||||||
new_node_y = (short) (node_y - 1);
|
new_node_y = (short) (node_y - 1);
|
||||||
newNode = readNode(new_node_x, new_node_y, neighbor);
|
newNode = readNode(new_node_x, new_node_y, neighbor);
|
||||||
if (newNode != null)
|
if (newNode != null)
|
||||||
{
|
{
|
||||||
Neighbors.add(newNode);
|
Neighbors.add(newNode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
final GeoNode[] result = new GeoNode[Neighbors.size()];
|
final GeoNode[] result = new GeoNode[Neighbors.size()];
|
||||||
return Neighbors.toArray(result);
|
return Neighbors.toArray(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Private
|
// Private
|
||||||
|
|
||||||
private GeoNode readNode(short node_x, short node_y, byte layer)
|
private GeoNode readNode(short node_x, short node_y, byte layer)
|
||||||
{
|
{
|
||||||
final short regoffset = getRegionOffset(getRegionX(node_x), getRegionY(node_y));
|
final short regoffset = getRegionOffset(getRegionX(node_x), getRegionY(node_y));
|
||||||
if (!pathNodesExist(regoffset))
|
if (!pathNodesExist(regoffset))
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
final short nbx = getNodeBlock(node_x);
|
final short nbx = getNodeBlock(node_x);
|
||||||
final short nby = getNodeBlock(node_y);
|
final short nby = getNodeBlock(node_y);
|
||||||
int idx = _pathNodesIndex.get(regoffset).get((nby << 8) + nbx);
|
int idx = _pathNodesIndex.get(regoffset).get((nby << 8) + nbx);
|
||||||
final ByteBuffer pn = _pathNodes.get(regoffset);
|
final ByteBuffer pn = _pathNodes.get(regoffset);
|
||||||
// reading
|
// reading
|
||||||
final byte nodes = pn.get(idx);
|
final byte nodes = pn.get(idx);
|
||||||
idx += (layer * 10) + 1; // byte + layer*10byte
|
idx += (layer * 10) + 1; // byte + layer*10byte
|
||||||
if (nodes < layer)
|
if (nodes < layer)
|
||||||
{
|
{
|
||||||
_log.warning("SmthWrong!");
|
_log.warning("SmthWrong!");
|
||||||
}
|
}
|
||||||
final short node_z = pn.getShort(idx);
|
final short node_z = pn.getShort(idx);
|
||||||
idx += 2;
|
idx += 2;
|
||||||
return new GeoNode(new GeoNodeLoc(node_x, node_y, node_z), idx);
|
return new GeoNode(new GeoNodeLoc(node_x, node_y, node_z), idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
private GeoNode readNode(int gx, int gy, short z)
|
private GeoNode readNode(int gx, int gy, short z)
|
||||||
{
|
{
|
||||||
final short node_x = getNodePos(gx);
|
final short node_x = getNodePos(gx);
|
||||||
final short node_y = getNodePos(gy);
|
final short node_y = getNodePos(gy);
|
||||||
final short regoffset = getRegionOffset(getRegionX(node_x), getRegionY(node_y));
|
final short regoffset = getRegionOffset(getRegionX(node_x), getRegionY(node_y));
|
||||||
if (!pathNodesExist(regoffset))
|
if (!pathNodesExist(regoffset))
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
final short nbx = getNodeBlock(node_x);
|
final short nbx = getNodeBlock(node_x);
|
||||||
final short nby = getNodeBlock(node_y);
|
final short nby = getNodeBlock(node_y);
|
||||||
int idx = _pathNodesIndex.get(regoffset).get((nby << 8) + nbx);
|
int idx = _pathNodesIndex.get(regoffset).get((nby << 8) + nbx);
|
||||||
final ByteBuffer pn = _pathNodes.get(regoffset);
|
final ByteBuffer pn = _pathNodes.get(regoffset);
|
||||||
// reading
|
// reading
|
||||||
byte nodes = pn.get(idx++);
|
byte nodes = pn.get(idx++);
|
||||||
int idx2 = 0; // create index to nearlest node by z
|
int idx2 = 0; // create index to nearlest node by z
|
||||||
short last_z = Short.MIN_VALUE;
|
short last_z = Short.MIN_VALUE;
|
||||||
while (nodes > 0)
|
while (nodes > 0)
|
||||||
{
|
{
|
||||||
final short node_z = pn.getShort(idx);
|
final short node_z = pn.getShort(idx);
|
||||||
if (Math.abs(last_z - z) > Math.abs(node_z - z))
|
if (Math.abs(last_z - z) > Math.abs(node_z - z))
|
||||||
{
|
{
|
||||||
last_z = node_z;
|
last_z = node_z;
|
||||||
idx2 = idx + 2;
|
idx2 = idx + 2;
|
||||||
}
|
}
|
||||||
idx += 10; // short + 8 byte
|
idx += 10; // short + 8 byte
|
||||||
nodes--;
|
nodes--;
|
||||||
}
|
}
|
||||||
return new GeoNode(new GeoNodeLoc(node_x, node_y, last_z), idx2);
|
return new GeoNode(new GeoNodeLoc(node_x, node_y, last_z), idx2);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected GeoPathFinding()
|
protected GeoPathFinding()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
_log.info("Path Engine: - Loading Path Nodes...");
|
_log.info("Path Engine: - Loading Path Nodes...");
|
||||||
//@formatter:off
|
//@formatter:off
|
||||||
Files.lines(Paths.get(Config.PATHNODE_DIR.getPath(), "pn_index.txt"), StandardCharsets.UTF_8)
|
Files.lines(Paths.get(Config.PATHNODE_DIR.getPath(), "pn_index.txt"), StandardCharsets.UTF_8)
|
||||||
.map(String::trim)
|
.map(String::trim)
|
||||||
.filter(l -> !l.isEmpty())
|
.filter(l -> !l.isEmpty())
|
||||||
.forEach(line -> {
|
.forEach(line -> {
|
||||||
final String[] parts = line.split("_");
|
final String[] parts = line.split("_");
|
||||||
|
|
||||||
if ((parts.length < 2)
|
if ((parts.length < 2)
|
||||||
|| !Util.isDigit(parts[0])
|
|| !Util.isDigit(parts[0])
|
||||||
|| !Util.isDigit(parts[1]))
|
|| !Util.isDigit(parts[1]))
|
||||||
{
|
{
|
||||||
_log.warning("Invalid pathnode entry: '" + line + "', must be in format 'XX_YY', where X and Y - integers");
|
_log.warning("Invalid pathnode entry: '" + line + "', must be in format 'XX_YY', where X and Y - integers");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
final byte rx = Byte.parseByte(parts[0]);
|
final byte rx = Byte.parseByte(parts[0]);
|
||||||
final byte ry = Byte.parseByte(parts[1]);
|
final byte ry = Byte.parseByte(parts[1]);
|
||||||
LoadPathNodeFile(rx, ry);
|
LoadPathNodeFile(rx, ry);
|
||||||
});
|
});
|
||||||
//@formatter:on
|
//@formatter:on
|
||||||
}
|
}
|
||||||
catch (IOException e)
|
catch (IOException e)
|
||||||
{
|
{
|
||||||
_log.log(Level.WARNING, "", e);
|
_log.log(Level.WARNING, "", e);
|
||||||
throw new Error("Failed to read pn_index file.");
|
throw new Error("Failed to read pn_index file.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void LoadPathNodeFile(byte rx, byte ry)
|
private void LoadPathNodeFile(byte rx, byte ry)
|
||||||
{
|
{
|
||||||
if ((rx < L2World.TILE_X_MIN) || (rx > L2World.TILE_X_MAX) || (ry < L2World.TILE_Y_MIN) || (ry > L2World.TILE_Y_MAX))
|
if ((rx < L2World.TILE_X_MIN) || (rx > L2World.TILE_X_MAX) || (ry < L2World.TILE_Y_MIN) || (ry > L2World.TILE_Y_MAX))
|
||||||
{
|
{
|
||||||
_log.warning("Failed to Load PathNode File: invalid region " + rx + "," + ry + Config.EOL);
|
_log.warning("Failed to Load PathNode File: invalid region " + rx + "," + ry + Config.EOL);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
final short regionoffset = getRegionOffset(rx, ry);
|
final short regionoffset = getRegionOffset(rx, ry);
|
||||||
final File file = new File(Config.PATHNODE_DIR, rx + "_" + ry + ".pn");
|
final File file = new File(Config.PATHNODE_DIR, rx + "_" + ry + ".pn");
|
||||||
_log.info("Path Engine: - Loading: " + file.getName() + " -> region offset: " + regionoffset + " X: " + rx + " Y: " + ry);
|
_log.info("Path Engine: - Loading: " + file.getName() + " -> region offset: " + regionoffset + " X: " + rx + " Y: " + ry);
|
||||||
int node = 0, size, index = 0;
|
int node = 0, size, index = 0;
|
||||||
|
|
||||||
// Create a read-only memory-mapped file
|
// Create a read-only memory-mapped file
|
||||||
try (RandomAccessFile raf = new RandomAccessFile(file, "r");
|
try (RandomAccessFile raf = new RandomAccessFile(file, "r");
|
||||||
FileChannel roChannel = raf.getChannel())
|
FileChannel roChannel = raf.getChannel())
|
||||||
{
|
{
|
||||||
size = (int) roChannel.size();
|
size = (int) roChannel.size();
|
||||||
MappedByteBuffer nodes;
|
MappedByteBuffer nodes;
|
||||||
if (Config.FORCE_GEODATA)
|
if (Config.FORCE_GEODATA)
|
||||||
{
|
{
|
||||||
// it is not guarantee, because the underlying operating system may have paged out some of the buffer's data
|
// it is not guarantee, because the underlying operating system may have paged out some of the buffer's data
|
||||||
nodes = roChannel.map(FileChannel.MapMode.READ_ONLY, 0, size).load();
|
nodes = roChannel.map(FileChannel.MapMode.READ_ONLY, 0, size).load();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
nodes = roChannel.map(FileChannel.MapMode.READ_ONLY, 0, size);
|
nodes = roChannel.map(FileChannel.MapMode.READ_ONLY, 0, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Indexing pathnode files, so we will know where each block starts
|
// Indexing pathnode files, so we will know where each block starts
|
||||||
final IntBuffer indexs = IntBuffer.allocate(65536);
|
final IntBuffer indexs = IntBuffer.allocate(65536);
|
||||||
|
|
||||||
while (node < 65536)
|
while (node < 65536)
|
||||||
{
|
{
|
||||||
final byte layer = nodes.get(index);
|
final byte layer = nodes.get(index);
|
||||||
indexs.put(node++, index);
|
indexs.put(node++, index);
|
||||||
index += (layer * 10) + 1;
|
index += (layer * 10) + 1;
|
||||||
}
|
}
|
||||||
_pathNodesIndex.put(regionoffset, indexs);
|
_pathNodesIndex.put(regionoffset, indexs);
|
||||||
_pathNodes.put(regionoffset, nodes);
|
_pathNodes.put(regionoffset, nodes);
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
_log.log(Level.WARNING, "Failed to Load PathNode File: " + file.getAbsolutePath() + " : " + e.getMessage(), e);
|
_log.log(Level.WARNING, "Failed to Load PathNode File: " + file.getAbsolutePath() + " : " + e.getMessage(), e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class SingletonHolder
|
private static class SingletonHolder
|
||||||
{
|
{
|
||||||
protected static final GeoPathFinding _instance = new GeoPathFinding();
|
protected static final GeoPathFinding _instance = new GeoPathFinding();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,124 +1,124 @@
|
|||||||
/*
|
/*
|
||||||
* This file is part of the L2J Mobius project.
|
* This file is part of the L2J Mobius project.
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
* General Public License for more details.
|
* General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package com.l2jmobius.gameserver.pathfinding.utils;
|
package com.l2jmobius.gameserver.geodata.pathfinding.utils;
|
||||||
|
|
||||||
import com.l2jmobius.gameserver.pathfinding.geonodes.GeoNode;
|
import com.l2jmobius.gameserver.geodata.pathfinding.geonodes.GeoNode;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author -Nemesiss-
|
* @author -Nemesiss-
|
||||||
*/
|
*/
|
||||||
public class BinaryNodeHeap
|
public class BinaryNodeHeap
|
||||||
{
|
{
|
||||||
private final GeoNode[] _list;
|
private final GeoNode[] _list;
|
||||||
private int _size;
|
private int _size;
|
||||||
|
|
||||||
public BinaryNodeHeap(int size)
|
public BinaryNodeHeap(int size)
|
||||||
{
|
{
|
||||||
_list = new GeoNode[size + 1];
|
_list = new GeoNode[size + 1];
|
||||||
_size = 0;
|
_size = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void add(GeoNode n)
|
public void add(GeoNode n)
|
||||||
{
|
{
|
||||||
_size++;
|
_size++;
|
||||||
int pos = _size;
|
int pos = _size;
|
||||||
_list[pos] = n;
|
_list[pos] = n;
|
||||||
while (pos != 1)
|
while (pos != 1)
|
||||||
{
|
{
|
||||||
final int p2 = pos / 2;
|
final int p2 = pos / 2;
|
||||||
if (_list[pos].getCost() <= _list[p2].getCost())
|
if (_list[pos].getCost() <= _list[p2].getCost())
|
||||||
{
|
{
|
||||||
final GeoNode temp = _list[p2];
|
final GeoNode temp = _list[p2];
|
||||||
_list[p2] = _list[pos];
|
_list[p2] = _list[pos];
|
||||||
_list[pos] = temp;
|
_list[pos] = temp;
|
||||||
pos = p2;
|
pos = p2;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public GeoNode removeFirst()
|
public GeoNode removeFirst()
|
||||||
{
|
{
|
||||||
final GeoNode first = _list[1];
|
final GeoNode first = _list[1];
|
||||||
_list[1] = _list[_size];
|
_list[1] = _list[_size];
|
||||||
_list[_size] = null;
|
_list[_size] = null;
|
||||||
_size--;
|
_size--;
|
||||||
int pos = 1;
|
int pos = 1;
|
||||||
int cpos;
|
int cpos;
|
||||||
int dblcpos;
|
int dblcpos;
|
||||||
GeoNode temp;
|
GeoNode temp;
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
cpos = pos;
|
cpos = pos;
|
||||||
dblcpos = cpos * 2;
|
dblcpos = cpos * 2;
|
||||||
if ((dblcpos + 1) <= _size)
|
if ((dblcpos + 1) <= _size)
|
||||||
{
|
{
|
||||||
if (_list[cpos].getCost() >= _list[dblcpos].getCost())
|
if (_list[cpos].getCost() >= _list[dblcpos].getCost())
|
||||||
{
|
{
|
||||||
pos = dblcpos;
|
pos = dblcpos;
|
||||||
}
|
}
|
||||||
if (_list[pos].getCost() >= _list[dblcpos + 1].getCost())
|
if (_list[pos].getCost() >= _list[dblcpos + 1].getCost())
|
||||||
{
|
{
|
||||||
pos = dblcpos + 1;
|
pos = dblcpos + 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (dblcpos <= _size)
|
else if (dblcpos <= _size)
|
||||||
{
|
{
|
||||||
if (_list[cpos].getCost() >= _list[dblcpos].getCost())
|
if (_list[cpos].getCost() >= _list[dblcpos].getCost())
|
||||||
{
|
{
|
||||||
pos = dblcpos;
|
pos = dblcpos;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cpos != pos)
|
if (cpos != pos)
|
||||||
{
|
{
|
||||||
temp = _list[cpos];
|
temp = _list[cpos];
|
||||||
_list[cpos] = _list[pos];
|
_list[cpos] = _list[pos];
|
||||||
_list[pos] = temp;
|
_list[pos] = temp;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return first;
|
return first;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean contains(GeoNode n)
|
public boolean contains(GeoNode n)
|
||||||
{
|
{
|
||||||
if (_size == 0)
|
if (_size == 0)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
for (int i = 1; i <= _size; i++)
|
for (int i = 1; i <= _size; i++)
|
||||||
{
|
{
|
||||||
if (_list[i].equals(n))
|
if (_list[i].equals(n))
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isEmpty()
|
public boolean isEmpty()
|
||||||
{
|
{
|
||||||
return _size == 0;
|
return _size == 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -18,11 +18,11 @@ package com.l2jmobius.gameserver.instancemanager;
|
|||||||
|
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
|
import com.l2jmobius.gameserver.geodata.pathfinding.AbstractNodeLoc;
|
||||||
import com.l2jmobius.gameserver.model.Location;
|
import com.l2jmobius.gameserver.model.Location;
|
||||||
import com.l2jmobius.gameserver.model.actor.L2Character;
|
import com.l2jmobius.gameserver.model.actor.L2Character;
|
||||||
import com.l2jmobius.gameserver.model.holders.WarpedSpaceHolder;
|
import com.l2jmobius.gameserver.model.holders.WarpedSpaceHolder;
|
||||||
import com.l2jmobius.gameserver.model.instancezone.Instance;
|
import com.l2jmobius.gameserver.model.instancezone.Instance;
|
||||||
import com.l2jmobius.gameserver.pathfinding.AbstractNodeLoc;
|
|
||||||
import com.l2jmobius.gameserver.util.Util;
|
import com.l2jmobius.gameserver.util.Util;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -63,6 +63,8 @@ import com.l2jmobius.gameserver.enums.ShotType;
|
|||||||
import com.l2jmobius.gameserver.enums.StatusUpdateType;
|
import com.l2jmobius.gameserver.enums.StatusUpdateType;
|
||||||
import com.l2jmobius.gameserver.enums.Team;
|
import com.l2jmobius.gameserver.enums.Team;
|
||||||
import com.l2jmobius.gameserver.enums.UserInfoType;
|
import com.l2jmobius.gameserver.enums.UserInfoType;
|
||||||
|
import com.l2jmobius.gameserver.geodata.pathfinding.AbstractNodeLoc;
|
||||||
|
import com.l2jmobius.gameserver.geodata.pathfinding.PathFinding;
|
||||||
import com.l2jmobius.gameserver.idfactory.IdFactory;
|
import com.l2jmobius.gameserver.idfactory.IdFactory;
|
||||||
import com.l2jmobius.gameserver.instancemanager.MapRegionManager;
|
import com.l2jmobius.gameserver.instancemanager.MapRegionManager;
|
||||||
import com.l2jmobius.gameserver.instancemanager.TimersManager;
|
import com.l2jmobius.gameserver.instancemanager.TimersManager;
|
||||||
@@ -153,8 +155,6 @@ import com.l2jmobius.gameserver.network.serverpackets.StopMove;
|
|||||||
import com.l2jmobius.gameserver.network.serverpackets.StopRotation;
|
import com.l2jmobius.gameserver.network.serverpackets.StopRotation;
|
||||||
import com.l2jmobius.gameserver.network.serverpackets.TeleportToLocation;
|
import com.l2jmobius.gameserver.network.serverpackets.TeleportToLocation;
|
||||||
import com.l2jmobius.gameserver.network.serverpackets.UserInfo;
|
import com.l2jmobius.gameserver.network.serverpackets.UserInfo;
|
||||||
import com.l2jmobius.gameserver.pathfinding.AbstractNodeLoc;
|
|
||||||
import com.l2jmobius.gameserver.pathfinding.PathFinding;
|
|
||||||
import com.l2jmobius.gameserver.taskmanager.AttackStanceTaskManager;
|
import com.l2jmobius.gameserver.taskmanager.AttackStanceTaskManager;
|
||||||
import com.l2jmobius.gameserver.util.Util;
|
import com.l2jmobius.gameserver.util.Util;
|
||||||
|
|
||||||
|
|||||||
@@ -18,8 +18,8 @@ package com.l2jmobius.gameserver.util;
|
|||||||
|
|
||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
|
|
||||||
import com.l2jmobius.commons.geodriver.Cell;
|
|
||||||
import com.l2jmobius.gameserver.GeoData;
|
import com.l2jmobius.gameserver.GeoData;
|
||||||
|
import com.l2jmobius.gameserver.geodata.geodriver.Cell;
|
||||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||||
import com.l2jmobius.gameserver.network.serverpackets.ExServerPrimitive;
|
import com.l2jmobius.gameserver.network.serverpackets.ExServerPrimitive;
|
||||||
|
|
||||||
|
|||||||
@@ -19,10 +19,10 @@ package handlers.admincommandhandlers;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import com.l2jmobius.Config;
|
import com.l2jmobius.Config;
|
||||||
|
import com.l2jmobius.gameserver.geodata.pathfinding.AbstractNodeLoc;
|
||||||
|
import com.l2jmobius.gameserver.geodata.pathfinding.PathFinding;
|
||||||
import com.l2jmobius.gameserver.handler.IAdminCommandHandler;
|
import com.l2jmobius.gameserver.handler.IAdminCommandHandler;
|
||||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||||
import com.l2jmobius.gameserver.pathfinding.AbstractNodeLoc;
|
|
||||||
import com.l2jmobius.gameserver.pathfinding.PathFinding;
|
|
||||||
|
|
||||||
public class AdminPathNode implements IAdminCommandHandler
|
public class AdminPathNode implements IAdminCommandHandler
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -98,6 +98,7 @@ import com.l2jmobius.gameserver.datatables.BotReportTable;
|
|||||||
import com.l2jmobius.gameserver.datatables.EventDroplist;
|
import com.l2jmobius.gameserver.datatables.EventDroplist;
|
||||||
import com.l2jmobius.gameserver.datatables.ItemTable;
|
import com.l2jmobius.gameserver.datatables.ItemTable;
|
||||||
import com.l2jmobius.gameserver.datatables.MerchantPriceConfigTable;
|
import com.l2jmobius.gameserver.datatables.MerchantPriceConfigTable;
|
||||||
|
import com.l2jmobius.gameserver.geodata.pathfinding.PathFinding;
|
||||||
import com.l2jmobius.gameserver.handler.ConditionHandler;
|
import com.l2jmobius.gameserver.handler.ConditionHandler;
|
||||||
import com.l2jmobius.gameserver.handler.DailyMissionHandler;
|
import com.l2jmobius.gameserver.handler.DailyMissionHandler;
|
||||||
import com.l2jmobius.gameserver.handler.EffectHandler;
|
import com.l2jmobius.gameserver.handler.EffectHandler;
|
||||||
@@ -145,7 +146,6 @@ import com.l2jmobius.gameserver.model.votereward.VoteSystem;
|
|||||||
import com.l2jmobius.gameserver.network.ClientNetworkManager;
|
import com.l2jmobius.gameserver.network.ClientNetworkManager;
|
||||||
import com.l2jmobius.gameserver.network.loginserver.LoginServerNetworkManager;
|
import com.l2jmobius.gameserver.network.loginserver.LoginServerNetworkManager;
|
||||||
import com.l2jmobius.gameserver.network.telnet.TelnetServer;
|
import com.l2jmobius.gameserver.network.telnet.TelnetServer;
|
||||||
import com.l2jmobius.gameserver.pathfinding.PathFinding;
|
|
||||||
import com.l2jmobius.gameserver.scripting.ScriptEngineManager;
|
import com.l2jmobius.gameserver.scripting.ScriptEngineManager;
|
||||||
import com.l2jmobius.gameserver.taskmanager.TaskManager;
|
import com.l2jmobius.gameserver.taskmanager.TaskManager;
|
||||||
import com.l2jmobius.gameserver.util.Broadcast;
|
import com.l2jmobius.gameserver.util.Broadcast;
|
||||||
|
|||||||
@@ -22,9 +22,9 @@ import java.util.logging.Level;
|
|||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import com.l2jmobius.Config;
|
import com.l2jmobius.Config;
|
||||||
import com.l2jmobius.commons.geodriver.Cell;
|
|
||||||
import com.l2jmobius.commons.geodriver.GeoDriver;
|
|
||||||
import com.l2jmobius.gameserver.data.xml.impl.DoorData;
|
import com.l2jmobius.gameserver.data.xml.impl.DoorData;
|
||||||
|
import com.l2jmobius.gameserver.geodata.geodriver.Cell;
|
||||||
|
import com.l2jmobius.gameserver.geodata.geodriver.GeoDriver;
|
||||||
import com.l2jmobius.gameserver.instancemanager.WarpedSpaceManager;
|
import com.l2jmobius.gameserver.instancemanager.WarpedSpaceManager;
|
||||||
import com.l2jmobius.gameserver.model.L2Object;
|
import com.l2jmobius.gameserver.model.L2Object;
|
||||||
import com.l2jmobius.gameserver.model.L2World;
|
import com.l2jmobius.gameserver.model.L2World;
|
||||||
|
|||||||
@@ -34,12 +34,12 @@ import org.w3c.dom.Node;
|
|||||||
|
|
||||||
import com.l2jmobius.commons.util.IGameXmlReader;
|
import com.l2jmobius.commons.util.IGameXmlReader;
|
||||||
import com.l2jmobius.commons.util.IXmlReader;
|
import com.l2jmobius.commons.util.IXmlReader;
|
||||||
|
import com.l2jmobius.gameserver.geodata.pathfinding.AbstractNodeLoc;
|
||||||
import com.l2jmobius.gameserver.instancemanager.MapRegionManager;
|
import com.l2jmobius.gameserver.instancemanager.MapRegionManager;
|
||||||
import com.l2jmobius.gameserver.model.StatsSet;
|
import com.l2jmobius.gameserver.model.StatsSet;
|
||||||
import com.l2jmobius.gameserver.model.actor.instance.L2DoorInstance;
|
import com.l2jmobius.gameserver.model.actor.instance.L2DoorInstance;
|
||||||
import com.l2jmobius.gameserver.model.actor.templates.L2DoorTemplate;
|
import com.l2jmobius.gameserver.model.actor.templates.L2DoorTemplate;
|
||||||
import com.l2jmobius.gameserver.model.instancezone.Instance;
|
import com.l2jmobius.gameserver.model.instancezone.Instance;
|
||||||
import com.l2jmobius.gameserver.pathfinding.AbstractNodeLoc;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class loads and hold info about doors.
|
* This class loads and hold info about doors.
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package com.l2jmobius.commons.geodriver;
|
package com.l2jmobius.gameserver.geodata.geodriver;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author HorridoJoho
|
* @author HorridoJoho
|
||||||
@@ -14,7 +14,7 @@
|
|||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package com.l2jmobius.commons.geodriver;
|
package com.l2jmobius.gameserver.geodata.geodriver;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.RandomAccessFile;
|
import java.io.RandomAccessFile;
|
||||||
@@ -23,8 +23,8 @@ import java.nio.channels.FileChannel.MapMode;
|
|||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.util.concurrent.atomic.AtomicReferenceArray;
|
import java.util.concurrent.atomic.AtomicReferenceArray;
|
||||||
|
|
||||||
import com.l2jmobius.commons.geodriver.regions.NullRegion;
|
import com.l2jmobius.gameserver.geodata.geodriver.regions.NullRegion;
|
||||||
import com.l2jmobius.commons.geodriver.regions.Region;
|
import com.l2jmobius.gameserver.geodata.geodriver.regions.Region;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author HorridoJoho
|
* @author HorridoJoho
|
||||||
@@ -14,7 +14,7 @@
|
|||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package com.l2jmobius.commons.geodriver;
|
package com.l2jmobius.gameserver.geodata.geodriver;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author HorridoJoho
|
* @author HorridoJoho
|
||||||
@@ -14,7 +14,7 @@
|
|||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package com.l2jmobius.commons.geodriver;
|
package com.l2jmobius.gameserver.geodata.geodriver;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author HorridoJoho
|
* @author HorridoJoho
|
||||||
@@ -14,11 +14,11 @@
|
|||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package com.l2jmobius.commons.geodriver.blocks;
|
package com.l2jmobius.gameserver.geodata.geodriver.blocks;
|
||||||
|
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
import com.l2jmobius.commons.geodriver.IBlock;
|
import com.l2jmobius.gameserver.geodata.geodriver.IBlock;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author HorridoJoho
|
* @author HorridoJoho
|
||||||
@@ -14,11 +14,11 @@
|
|||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package com.l2jmobius.commons.geodriver.blocks;
|
package com.l2jmobius.gameserver.geodata.geodriver.blocks;
|
||||||
|
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
import com.l2jmobius.commons.geodriver.IBlock;
|
import com.l2jmobius.gameserver.geodata.geodriver.IBlock;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author HorridoJoho
|
* @author HorridoJoho
|
||||||
@@ -14,11 +14,11 @@
|
|||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package com.l2jmobius.commons.geodriver.blocks;
|
package com.l2jmobius.gameserver.geodata.geodriver.blocks;
|
||||||
|
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
import com.l2jmobius.commons.geodriver.IBlock;
|
import com.l2jmobius.gameserver.geodata.geodriver.IBlock;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author HorridoJoho
|
* @author HorridoJoho
|
||||||
@@ -14,9 +14,9 @@
|
|||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package com.l2jmobius.commons.geodriver.regions;
|
package com.l2jmobius.gameserver.geodata.geodriver.regions;
|
||||||
|
|
||||||
import com.l2jmobius.commons.geodriver.IRegion;
|
import com.l2jmobius.gameserver.geodata.geodriver.IRegion;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author HorridoJoho
|
* @author HorridoJoho
|
||||||
@@ -14,15 +14,15 @@
|
|||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package com.l2jmobius.commons.geodriver.regions;
|
package com.l2jmobius.gameserver.geodata.geodriver.regions;
|
||||||
|
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
import com.l2jmobius.commons.geodriver.IBlock;
|
import com.l2jmobius.gameserver.geodata.geodriver.IBlock;
|
||||||
import com.l2jmobius.commons.geodriver.IRegion;
|
import com.l2jmobius.gameserver.geodata.geodriver.IRegion;
|
||||||
import com.l2jmobius.commons.geodriver.blocks.ComplexBlock;
|
import com.l2jmobius.gameserver.geodata.geodriver.blocks.ComplexBlock;
|
||||||
import com.l2jmobius.commons.geodriver.blocks.FlatBlock;
|
import com.l2jmobius.gameserver.geodata.geodriver.blocks.FlatBlock;
|
||||||
import com.l2jmobius.commons.geodriver.blocks.MultilayerBlock;
|
import com.l2jmobius.gameserver.geodata.geodriver.blocks.MultilayerBlock;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author HorridoJoho
|
* @author HorridoJoho
|
||||||
@@ -14,7 +14,7 @@
|
|||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package com.l2jmobius.gameserver.pathfinding;
|
package com.l2jmobius.gameserver.geodata.pathfinding;
|
||||||
|
|
||||||
public abstract class AbstractNode<T extends AbstractNodeLoc>
|
public abstract class AbstractNode<T extends AbstractNodeLoc>
|
||||||
{
|
{
|
||||||
@@ -14,7 +14,7 @@
|
|||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package com.l2jmobius.gameserver.pathfinding;
|
package com.l2jmobius.gameserver.geodata.pathfinding;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author -Nemesiss-
|
* @author -Nemesiss-
|
||||||
@@ -14,15 +14,15 @@
|
|||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package com.l2jmobius.gameserver.pathfinding;
|
package com.l2jmobius.gameserver.geodata.pathfinding;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import com.l2jmobius.Config;
|
import com.l2jmobius.Config;
|
||||||
|
import com.l2jmobius.gameserver.geodata.pathfinding.cellnodes.CellPathFinding;
|
||||||
|
import com.l2jmobius.gameserver.geodata.pathfinding.geonodes.GeoPathFinding;
|
||||||
import com.l2jmobius.gameserver.model.L2World;
|
import com.l2jmobius.gameserver.model.L2World;
|
||||||
import com.l2jmobius.gameserver.model.instancezone.Instance;
|
import com.l2jmobius.gameserver.model.instancezone.Instance;
|
||||||
import com.l2jmobius.gameserver.pathfinding.cellnodes.CellPathFinding;
|
|
||||||
import com.l2jmobius.gameserver.pathfinding.geonodes.GeoPathFinding;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author -Nemesiss-
|
* @author -Nemesiss-
|
||||||
@@ -14,9 +14,9 @@
|
|||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package com.l2jmobius.gameserver.pathfinding.cellnodes;
|
package com.l2jmobius.gameserver.geodata.pathfinding.cellnodes;
|
||||||
|
|
||||||
import com.l2jmobius.gameserver.pathfinding.AbstractNode;
|
import com.l2jmobius.gameserver.geodata.pathfinding.AbstractNode;
|
||||||
|
|
||||||
public class CellNode extends AbstractNode<NodeLoc>
|
public class CellNode extends AbstractNode<NodeLoc>
|
||||||
{
|
{
|
||||||
@@ -14,7 +14,7 @@
|
|||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package com.l2jmobius.gameserver.pathfinding.cellnodes;
|
package com.l2jmobius.gameserver.geodata.pathfinding.cellnodes;
|
||||||
|
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -14,7 +14,7 @@
|
|||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package com.l2jmobius.gameserver.pathfinding.cellnodes;
|
package com.l2jmobius.gameserver.geodata.pathfinding.cellnodes;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
@@ -26,13 +26,13 @@ import java.util.logging.Logger;
|
|||||||
|
|
||||||
import com.l2jmobius.Config;
|
import com.l2jmobius.Config;
|
||||||
import com.l2jmobius.gameserver.GeoData;
|
import com.l2jmobius.gameserver.GeoData;
|
||||||
|
import com.l2jmobius.gameserver.geodata.pathfinding.AbstractNode;
|
||||||
|
import com.l2jmobius.gameserver.geodata.pathfinding.AbstractNodeLoc;
|
||||||
|
import com.l2jmobius.gameserver.geodata.pathfinding.PathFinding;
|
||||||
import com.l2jmobius.gameserver.idfactory.IdFactory;
|
import com.l2jmobius.gameserver.idfactory.IdFactory;
|
||||||
import com.l2jmobius.gameserver.model.instancezone.Instance;
|
import com.l2jmobius.gameserver.model.instancezone.Instance;
|
||||||
import com.l2jmobius.gameserver.model.itemcontainer.Inventory;
|
import com.l2jmobius.gameserver.model.itemcontainer.Inventory;
|
||||||
import com.l2jmobius.gameserver.model.items.instance.L2ItemInstance;
|
import com.l2jmobius.gameserver.model.items.instance.L2ItemInstance;
|
||||||
import com.l2jmobius.gameserver.pathfinding.AbstractNode;
|
|
||||||
import com.l2jmobius.gameserver.pathfinding.AbstractNodeLoc;
|
|
||||||
import com.l2jmobius.gameserver.pathfinding.PathFinding;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Sami, DS Credits to Diamond
|
* @author Sami, DS Credits to Diamond
|
||||||
@@ -14,11 +14,11 @@
|
|||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package com.l2jmobius.gameserver.pathfinding.cellnodes;
|
package com.l2jmobius.gameserver.geodata.pathfinding.cellnodes;
|
||||||
|
|
||||||
import com.l2jmobius.commons.geodriver.Cell;
|
|
||||||
import com.l2jmobius.gameserver.GeoData;
|
import com.l2jmobius.gameserver.GeoData;
|
||||||
import com.l2jmobius.gameserver.pathfinding.AbstractNodeLoc;
|
import com.l2jmobius.gameserver.geodata.geodriver.Cell;
|
||||||
|
import com.l2jmobius.gameserver.geodata.pathfinding.AbstractNodeLoc;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author -Nemesiss-, HorridoJoho
|
* @author -Nemesiss-, HorridoJoho
|
||||||
@@ -14,9 +14,9 @@
|
|||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package com.l2jmobius.gameserver.pathfinding.geonodes;
|
package com.l2jmobius.gameserver.geodata.pathfinding.geonodes;
|
||||||
|
|
||||||
import com.l2jmobius.gameserver.pathfinding.AbstractNode;
|
import com.l2jmobius.gameserver.geodata.pathfinding.AbstractNode;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author -Nemesiss-
|
* @author -Nemesiss-
|
||||||
@@ -14,10 +14,10 @@
|
|||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package com.l2jmobius.gameserver.pathfinding.geonodes;
|
package com.l2jmobius.gameserver.geodata.pathfinding.geonodes;
|
||||||
|
|
||||||
|
import com.l2jmobius.gameserver.geodata.pathfinding.AbstractNodeLoc;
|
||||||
import com.l2jmobius.gameserver.model.L2World;
|
import com.l2jmobius.gameserver.model.L2World;
|
||||||
import com.l2jmobius.gameserver.pathfinding.AbstractNodeLoc;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author -Nemesiss-
|
* @author -Nemesiss-
|
||||||
@@ -14,7 +14,7 @@
|
|||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package com.l2jmobius.gameserver.pathfinding.geonodes;
|
package com.l2jmobius.gameserver.geodata.pathfinding.geonodes;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@@ -36,12 +36,12 @@ import java.util.logging.Logger;
|
|||||||
|
|
||||||
import com.l2jmobius.Config;
|
import com.l2jmobius.Config;
|
||||||
import com.l2jmobius.gameserver.GeoData;
|
import com.l2jmobius.gameserver.GeoData;
|
||||||
|
import com.l2jmobius.gameserver.geodata.pathfinding.AbstractNode;
|
||||||
|
import com.l2jmobius.gameserver.geodata.pathfinding.AbstractNodeLoc;
|
||||||
|
import com.l2jmobius.gameserver.geodata.pathfinding.PathFinding;
|
||||||
import com.l2jmobius.gameserver.model.L2World;
|
import com.l2jmobius.gameserver.model.L2World;
|
||||||
import com.l2jmobius.gameserver.model.Location;
|
import com.l2jmobius.gameserver.model.Location;
|
||||||
import com.l2jmobius.gameserver.model.instancezone.Instance;
|
import com.l2jmobius.gameserver.model.instancezone.Instance;
|
||||||
import com.l2jmobius.gameserver.pathfinding.AbstractNode;
|
|
||||||
import com.l2jmobius.gameserver.pathfinding.AbstractNodeLoc;
|
|
||||||
import com.l2jmobius.gameserver.pathfinding.PathFinding;
|
|
||||||
import com.l2jmobius.gameserver.util.Util;
|
import com.l2jmobius.gameserver.util.Util;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -14,9 +14,9 @@
|
|||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package com.l2jmobius.gameserver.pathfinding.utils;
|
package com.l2jmobius.gameserver.geodata.pathfinding.utils;
|
||||||
|
|
||||||
import com.l2jmobius.gameserver.pathfinding.geonodes.GeoNode;
|
import com.l2jmobius.gameserver.geodata.pathfinding.geonodes.GeoNode;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author -Nemesiss-
|
* @author -Nemesiss-
|
||||||
@@ -18,11 +18,11 @@ package com.l2jmobius.gameserver.instancemanager;
|
|||||||
|
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
|
import com.l2jmobius.gameserver.geodata.pathfinding.AbstractNodeLoc;
|
||||||
import com.l2jmobius.gameserver.model.Location;
|
import com.l2jmobius.gameserver.model.Location;
|
||||||
import com.l2jmobius.gameserver.model.actor.L2Character;
|
import com.l2jmobius.gameserver.model.actor.L2Character;
|
||||||
import com.l2jmobius.gameserver.model.holders.WarpedSpaceHolder;
|
import com.l2jmobius.gameserver.model.holders.WarpedSpaceHolder;
|
||||||
import com.l2jmobius.gameserver.model.instancezone.Instance;
|
import com.l2jmobius.gameserver.model.instancezone.Instance;
|
||||||
import com.l2jmobius.gameserver.pathfinding.AbstractNodeLoc;
|
|
||||||
import com.l2jmobius.gameserver.util.Util;
|
import com.l2jmobius.gameserver.util.Util;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -63,6 +63,8 @@ import com.l2jmobius.gameserver.enums.ShotType;
|
|||||||
import com.l2jmobius.gameserver.enums.StatusUpdateType;
|
import com.l2jmobius.gameserver.enums.StatusUpdateType;
|
||||||
import com.l2jmobius.gameserver.enums.Team;
|
import com.l2jmobius.gameserver.enums.Team;
|
||||||
import com.l2jmobius.gameserver.enums.UserInfoType;
|
import com.l2jmobius.gameserver.enums.UserInfoType;
|
||||||
|
import com.l2jmobius.gameserver.geodata.pathfinding.AbstractNodeLoc;
|
||||||
|
import com.l2jmobius.gameserver.geodata.pathfinding.PathFinding;
|
||||||
import com.l2jmobius.gameserver.idfactory.IdFactory;
|
import com.l2jmobius.gameserver.idfactory.IdFactory;
|
||||||
import com.l2jmobius.gameserver.instancemanager.MapRegionManager;
|
import com.l2jmobius.gameserver.instancemanager.MapRegionManager;
|
||||||
import com.l2jmobius.gameserver.instancemanager.TimersManager;
|
import com.l2jmobius.gameserver.instancemanager.TimersManager;
|
||||||
@@ -153,8 +155,6 @@ import com.l2jmobius.gameserver.network.serverpackets.StopMove;
|
|||||||
import com.l2jmobius.gameserver.network.serverpackets.StopRotation;
|
import com.l2jmobius.gameserver.network.serverpackets.StopRotation;
|
||||||
import com.l2jmobius.gameserver.network.serverpackets.TeleportToLocation;
|
import com.l2jmobius.gameserver.network.serverpackets.TeleportToLocation;
|
||||||
import com.l2jmobius.gameserver.network.serverpackets.UserInfo;
|
import com.l2jmobius.gameserver.network.serverpackets.UserInfo;
|
||||||
import com.l2jmobius.gameserver.pathfinding.AbstractNodeLoc;
|
|
||||||
import com.l2jmobius.gameserver.pathfinding.PathFinding;
|
|
||||||
import com.l2jmobius.gameserver.taskmanager.AttackStanceTaskManager;
|
import com.l2jmobius.gameserver.taskmanager.AttackStanceTaskManager;
|
||||||
import com.l2jmobius.gameserver.util.Util;
|
import com.l2jmobius.gameserver.util.Util;
|
||||||
|
|
||||||
|
|||||||
@@ -18,8 +18,8 @@ package com.l2jmobius.gameserver.util;
|
|||||||
|
|
||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
|
|
||||||
import com.l2jmobius.commons.geodriver.Cell;
|
|
||||||
import com.l2jmobius.gameserver.GeoData;
|
import com.l2jmobius.gameserver.GeoData;
|
||||||
|
import com.l2jmobius.gameserver.geodata.geodriver.Cell;
|
||||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||||
import com.l2jmobius.gameserver.network.serverpackets.ExServerPrimitive;
|
import com.l2jmobius.gameserver.network.serverpackets.ExServerPrimitive;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user