Перейти к содержанию
Авторизация  
sedrik

getNext и getPrevious

Рекомендуемые сообщения

Всем привет! Решил я избавиться от Javolution в сборке. Всё благополучно вычистил кроме одного момента. После удаления FastMap из класса не могу подобрать альтернативный рабочий вариант для замены targetRecorder.head().getNext().getKey(); и targetRecorder.tail().getPrevious().getKey();

 

С листами там просто и понятно, через IteratorList всё без проблем получается. Но мне нужно через  Map+HashMap, Map+LinkedHashMap или ваш вариант. Заранее благодарю.

 

package l2f.gameserver.geodata;



import l2f.commons.config.Config;
import l2f.gameserver.model.L2CharPosition;
import l2f.gameserver.model.L2Character;
import l2f.gameserver.model.L2Player;
import l2f.gameserver.model.Location;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Map;
import java.util.HashMap;

public class GeoMove
{
private final static Logger _log = LoggerFactory.getLogger(GeoMove.class);
public Map targetRecorder;
public int currentTargetId;
public int currentMoveCounter;
private L2Character _actor;
private int _queueSize;
private static int GEODATAMODE = 1;
private static int PATHNODEMODE = 2;
private static boolean debug;

public GeoMove(L2Character actor)
{
targetRecorder = new HashMap<>();
_actor = actor;
if(_actor instanceof L2Player)
if(((L2Player) _actor).getAccessLevel() >= 100 && Config.GEODATA_DEBUG)
debug = true;
}

public int getQueueSize()
{
return _queueSize;
}

public synchronized Location checkMovement(L2Character target)
{
Location tCoord = null;
int mode = PATHNODEMODE;
PathFindNode n = null;
try
{
// Now check Line of sight
if(!GeoData.getInstance().canSeeTarget(_actor, target))
{
if(currentTargetId != target.getObjectId())
{
targetRecorder = null;
currentTargetId = target.getObjectId();
}
if(targetRecorder == null)
targetRecorder = new HashMap<>();
if(targetRecorder.size() > 1)
{
// try to get best movement path
tCoord = targetRecorder.tail().getPrevious().getValue();
if(Math.abs(tCoord.x - target.getX() + tCoord.y - target.getY()) < 1800)
mode = GEODATAMODE;
else
mode = PATHNODEMODE;
n = new PathFindNode(tCoord.x, tCoord.y, tCoord.z, target.getX(), target.getY(), target.getZ(), mode);
if(mode == 1 && n.path == null)
n = new PathFindNode(tCoord.x, tCoord.y, tCoord.z, target.getX(), target.getY(), target.getZ(), 2);
if(n.path == null)
return GeoData.getInstance().moveCheck(_actor.getX(), _actor.getY(), _actor.getZ(), target.getX(), target.getY(), target.getZ());
else if(!n.path.getNodes().isEmpty())
{
_queueSize = n.path.nodes.size();
for(Node p : n.path.getNodes())
{
// target moved, record
currentMoveCounter++;
targetRecorder.put(currentMoveCounter, p.location);
}
}
}
else
{
currentMoveCounter = 0;
if(Math.abs(_actor.getX() - target.getX() + _actor.getY() - target.getY()) < 1800)
mode = GEODATAMODE;
else
mode = PATHNODEMODE;
n = new PathFindNode(_actor.getX(), _actor.getY(), _actor.getZ(), target.getX(), target.getY(), target.getZ(), mode);
if(mode == GEODATAMODE && n.path == null)
n = new PathFindNode(_actor.getX(), _actor.getY(), _actor.getZ(), target.getX(), target.getY(), target.getZ(), PATHNODEMODE);
if(n.path == null)
return GeoData.getInstance().moveCheck(_actor.getX(), _actor.getY(), _actor.getZ(), target.getX(), target.getY(), target.getZ());
else if(!n.path.getNodes().isEmpty())
{
_queueSize = n.path.nodes.size();
for(Node p : n.path.getNodes())
{
// target moved, record
currentMoveCounter++;
targetRecorder.put(currentMoveCounter, p.location);
}
}
}
return checkmap();
}
_queueSize = 0;
return null;
}
catch (Exception e)
{
return null;
}
}

public synchronized Location checkMovement(L2CharPosition target)
{
int mode = PATHNODEMODE;
PathFindNode n = null;
long ti = System.currentTimeMillis();

// Now check Line of sight
try
{
if(debug)
{
_actor.sendMessage("--------------------------------");
_actor.sendMessage("Начало движения, цель - x:" + target.x + " y:" + target.y + " z:" + target.z);
}
if(!GeoData.getInstance().canSeeCoord(_actor.getX(), _actor.getY(), _actor.getZ(), target.x, target.y, target.z))
{
if(debug)
_actor.sendMessage("Цель не видна, ищем путь");
if(currentTargetId != target.getObjectId())
{
targetRecorder = null;
currentTargetId = target.getObjectId();
}
if(targetRecorder == null)
{
targetRecorder = new HashMap<>();
if(debug)
_actor.sendMessage("Цель изменилась, новый targetRecorder");
}
if(targetRecorder.size() < 1)
{
currentMoveCounter = 0;
if(Math.abs(_actor.getX() - target.x + _actor.getY() - target.y) < 1800)
{
if(debug)
_actor.sendMessage("Выбран режим GEODATAMODE");
mode = GEODATAMODE;
}
else
{
if(debug)
_actor.sendMessage("Выбран режим PATHNODEMODE");
mode = PATHNODEMODE;
}
n = new PathFindNode(_actor.getX(), _actor.getY(), (short) _actor.getZ(), target.x, target.y, (short) target.z, mode);
if(n.path == null)
{
Location loc = GeoData.getInstance().moveCheck(_actor.getX(), _actor.getY(), _actor.getZ(), target.x, target.y, target.z);
_queueSize = 1;
if(debug)
{
_actor.sendMessage("Путь не найден, FP= x:" + loc.x + " y:" + loc.y + " z:" + loc.z);
_actor.sendMessage("Время поиска: " + (System.currentTimeMillis() - ti) + "ms");
_actor.sendMessage("--------------------------------");
}
return loc;
}
if(!n.path.getNodes().isEmpty())
{
_queueSize = n.path.getNodes().size();
for(Node p : n.path.getNodes())
{
// target moved, record
currentMoveCounter++;
if(debug)
_actor.sendMessage("path = x:" + p.location.x + " y:" + p.location.y + " z:" + p.location.z);
targetRecorder.put(currentMoveCounter, p.location);
}
if(debug)
_actor.sendMessage("Время поиска: " + (System.currentTimeMillis() - ti) + "ms, Точек: " + n.path.getNodes().size());
}
}
Location coord = checkmap();
if(coord == null)
{
if(debug)
_actor.sendMessage("checkmap == null, идем в FP");

}
else
return coord;
}
_queueSize = 0;
return null;
}
catch (Exception e)
{
if(debug)
{
_actor.sendMessage("CheckMovement excep: " + e.getMessage());
_log.error(e.getMessage());
}
return null;
}
}

private synchronized Location checkmap()
{
Location tCoord = null;
Location prevtCoord = null;
//int failSafeCounter = 0;
try
{
if(targetRecorder == null)
{
_queueSize = 0;
return null;
}
int mapSize = targetRecorder.size();
if(mapSize == 0)
{
_queueSize = 0;
return null;
}
int startMapPos = targetRecorder.head().getNext().getKey();
int lastMapPos = targetRecorder.tail().getPrevious().getKey();
int mapPos = startMapPos;
prevtCoord = targetRecorder.get(mapPos);
tCoord = prevtCoord;
while(mapPos < lastMapPos && GeoData.getInstance().canSeeCoord(_actor.getX(), _actor.getY(), _actor.getZ(), tCoord.x, tCoord.y, tCoord.z))
{
prevtCoord = tCoord;
mapPos++;
tCoord = targetRecorder.get(mapPos);
}

for(int i = startMapPos; i < mapPos - 1; i++)
targetRecorder.remove(i);
_queueSize = targetRecorder.size();
if(debug)
_actor.sendMessage("moving to x:" + prevtCoord.x + " y:" + prevtCoord.y + " z:" + prevtCoord.z + " Qsize:" + _queueSize);
return prevtCoord;
}
catch (Exception e)
{
_queueSize = 0;
if(debug)
_actor.sendMessage("CheckMap excep : " + e.getMessage());
return null;
}
}
}

,>

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Самым простым решением будет использовать LinkedHashMap

 

Объявить как:

public Map<Integer, Location> targetRecorder;

Инициализировать:

targetRecorder = new LinkedHashMap<>();

И вместо:

int startMapPos = targetRecorder.head().getNext().getKey();
int lastMapPos = targetRecorder.tail().getPrevious().getKey();

Делать так:

int startMapPos = targetRecorder.keySet().iterator().next();
int lastMapPos = startMapPos;
for(int key : targetRecorder.keySet()) {
        lastMapPos = key;
}

Однако получается не самый лучший вариант по производительности, нам приходится пробегать по циклу каждый раз чтобы достать последний элемент коллекции.

Есть вариант, при каждом добавлении элемента в targetRecorder сохранять "ключ" в какой-либо список, а при удалении элемента, соответственно, удалять, в таком случае не

придется бегать по циклу каждый раз, для того чтобы достать последний элемент, необходимо будет просто обратится к последнему элементу списка для получения последнего ключа

Изменено пользователем Nha
  • Upvote 1

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Спасибо огромное! По приезду домой попробую этот вариант. Мои попытки были с использованием Map.Entry, но успешного результата я так и не получил. Вот что значит прогуливать занятия :( Так как в дальнейшем я заменю полностью геодвижок на другой, как временное решение пойдет, производительность пока не в приоритете.

 

Нужно будет поднять доки от Oracle по Map, Entry и Iterator. Освежить память так сказать))

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

tCoord = targetRecorder.tail().getPrevious().getValue();

 

Тут я не стал ничего делать, просто закоментировал. Всё скомпилилось :)

 

Теперь осталось подобрать достойный геодвиг, который работает с l2j и pts форматами гео. Может, кто посоветует какой получше? Я пока присмотрелся к геодвижку из L2Region.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Для публикации сообщений создайте учётную запись или авторизуйтесь

Вы должны быть пользователем, чтобы оставить комментарий

Создать учетную запись

Зарегистрируйте новую учётную запись в нашем сообществе. Это очень просто!

Регистрация нового пользователя

Войти

Уже есть аккаунт? Войти в систему.

Войти
Авторизация  

  • Последние посетители   0 пользователей онлайн

    Ни одного зарегистрированного пользователя не просматривает данную страницу

×
×
  • Создать...