/*
* Copyright (C) 2004-2014 L2J Server
*
* This file is part of L2J Server.
*
* L2J Server is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* L2J Server is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
package com.l2jserver.gameserver.pathfinding;
import java.util.List;
import com.l2jserver.Config;
import com.l2jserver.gameserver.model.L2World;
import com.l2jserver.gameserver.pathfinding.cellnodes.CellPathFinding;
import com.l2jserver.gameserver.pathfinding.geonodes.GeoPathFinding;
/**
* @author -Nemesiss-
*/
public abstract class PathFinding
{
public static PathFinding getInstance()
{
if (!Config.GEODATA_CELLFINDING)
{
// Higher Memory Usage, Smaller Cpu Usage
return GeoPathFinding.getInstance();
}
// Cell pathfinding, calculated directly from geodata files
return CellPathFinding.getInstance();
}
public abstract boolean pathNodesExist(short regionoffset);
public abstract List findPath(int x, int y, int z, int tx, int ty, int tz, int instanceId, boolean playable);
// @formatter:off
/*
public List search(AbstractNode start, AbstractNode end, int instanceId)
{
// The simplest grid-based pathfinding.
// 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.
// List of Visited Nodes
LinkedList visited = new LinkedList();
// List of Nodes to Visit
LinkedList to_visit = new LinkedList();
to_visit.add(start);
int i = 0;
while (i < 800)
{
AbstractNode node;
try
{
node = to_visit.removeFirst();
}
catch (Exception e)
{
// No Path found
return null;
}
if (node.equals(end)) //path found!
return constructPath(node, instanceId);
else
{
i++;
visited.add(node);
node.attachNeighbors();
Node[] neighbors = node.getNeighbors();
if (neighbors == null)
continue;
for (Node n : neighbors)
{
if (!visited.contains(n) && !to_visit.contains(n))
{
n.setParent(node);
to_visit.add(n);
}
}
}
}
//No Path found
return null;
}
*/
/*
public List searchAStar(Node start, Node end, int instanceId)
{
// Not operational yet?
int start_x = start.getLoc().getX();
int start_y = start.getLoc().getY();
int end_x = end.getLoc().getX();
int end_y = end.getLoc().getY();
//List of Visited Nodes
FastNodeList visited = new FastNodeList(800);//TODO! Add limit to cfg
// List of Nodes to Visit
BinaryNodeHeap to_visit = new BinaryNodeHeap(800);
to_visit.add(start);
int i = 0;
while (i < 800)//TODO! Add limit to cfg
{
AbstractNode node;
try
{
node = to_visit.removeFirst();
}
catch (Exception e)
{
// No Path found
return null;
}
if (node.equals(end)) //path found!
return constructPath(node, instanceId);
else
{
visited.add(node);
node.attachNeighbors();
for (Node n : node.getNeighbors())
{
if (!visited.contains(n) && !to_visit.contains(n))
{
i++;
n.setParent(node);
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()));
to_visit.add(n);
}
}
}
}
//No Path found
return null;
}
*/
// @formatter:on
/**
* Convert geodata position to pathnode position
* @param geo_pos
* @return pathnode position
*/
public short getNodePos(int geo_pos)
{
return (short) (geo_pos >> 3); // OK?
}
/**
* Convert node position to pathnode block position
* @param node_pos
* @return pathnode block position (0...255)
*/
public short getNodeBlock(int node_pos)
{
return (short) (node_pos % 256);
}
public byte getRegionX(int node_pos)
{
return (byte) ((node_pos >> 8) + L2World.TILE_X_MIN);
}
public byte getRegionY(int node_pos)
{
return (byte) ((node_pos >> 8) + L2World.TILE_Y_MIN);
}
public short getRegionOffset(byte rx, byte ry)
{
return (short) ((rx << 5) + ry);
}
/**
* Convert pathnode x to World x position
* @param node_x rx
* @return
*/
public int calculateWorldX(short node_x)
{
return L2World.MAP_MIN_X + (node_x * 128) + 48;
}
/**
* Convert pathnode y to World y position
* @param node_y
* @return
*/
public int calculateWorldY(short node_y)
{
return L2World.MAP_MIN_Y + (node_y * 128) + 48;
}
public String[] getStat()
{
return null;
}
}