sedrik 6 Опубликовано 9 апреля, 2016 Всем привет! Решил я избавиться от 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 sightif(!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 pathtCoord = targetRecorder.tail().getPrevious().getValue();if(Math.abs(tCoord.x - target.getX() + tCoord.y - target.getY()) < 1800)mode = GEODATAMODE;elsemode = 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, recordcurrentMoveCounter++;targetRecorder.put(currentMoveCounter, p.location);}}}else{currentMoveCounter = 0;if(Math.abs(_actor.getX() - target.getX() + _actor.getY() - target.getY()) < 1800)mode = GEODATAMODE;elsemode = 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, recordcurrentMoveCounter++;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 sighttry{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, recordcurrentMoveCounter++;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");}elsereturn 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;}}},> Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты
Nha 22 Опубликовано 10 апреля, 2016 (изменено) Самым простым решением будет использовать 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 сохранять "ключ" в какой-либо список, а при удалении элемента, соответственно, удалять, в таком случае не придется бегать по циклу каждый раз, для того чтобы достать последний элемент, необходимо будет просто обратится к последнему элементу списка для получения последнего ключа Изменено 10 апреля, 2016 пользователем Nha 1 Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты
sedrik 6 Опубликовано 10 апреля, 2016 Спасибо огромное! По приезду домой попробую этот вариант. Мои попытки были с использованием Map.Entry, но успешного результата я так и не получил. Вот что значит прогуливать занятия Так как в дальнейшем я заменю полностью геодвижок на другой, как временное решение пойдет, производительность пока не в приоритете. Нужно будет поднять доки от Oracle по Map, Entry и Iterator. Освежить память так сказать)) Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты
sedrik 6 Опубликовано 10 апреля, 2016 tCoord = targetRecorder.tail().getPrevious().getValue(); Тут я не стал ничего делать, просто закоментировал. Всё скомпилилось Теперь осталось подобрать достойный геодвиг, который работает с l2j и pts форматами гео. Может, кто посоветует какой получше? Я пока присмотрелся к геодвижку из L2Region. Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты