Reduced move task delay and addition of proper targeted NPC support.

This commit is contained in:
MobiusDevelopment
2019-12-14 15:06:40 +00:00
parent f8a5bad1cc
commit 8f335f289e
65 changed files with 1326 additions and 1043 deletions

View File

@@ -67,6 +67,7 @@ public class WalkingManager implements IXmlReader
public static final byte REPEAT_TELE_FIRST = 2;
public static final byte REPEAT_RANDOM = 3;
private final List<Integer> _targetedNpcIds = new ArrayList<>();
private final Map<String, WalkRoute> _routes = new HashMap<>(); // all available routes
private final Map<Integer, WalkInfo> _activeRoutes = new HashMap<>(); // each record represents NPC, moving by predefined route from _routes, and moving progress
private final Map<Integer, NpcRoutesHolder> _routesToAttach = new HashMap<>(); // each record represents NPC and all available routes for it
@@ -89,8 +90,7 @@ public class WalkingManager implements IXmlReader
@Override
public void parseDocument(Document doc, File f)
{
final Node n = doc.getFirstChild();
for (Node d = n.getFirstChild(); d != null; d = d.getNextSibling())
for (Node d = doc.getFirstChild().getFirstChild(); d != null; d = d.getNextSibling())
{
if (d.getNodeName().equals("route"))
{
@@ -191,6 +191,11 @@ public class WalkingManager implements IXmlReader
final NpcRoutesHolder holder = _routesToAttach.containsKey(npcId) ? _routesToAttach.get(npcId) : new NpcRoutesHolder();
holder.addRoute(routeName, new Location(x, y, z));
_routesToAttach.put(npcId, holder);
if (!_targetedNpcIds.contains(npcId))
{
_targetedNpcIds.add(npcId);
}
}
else
{
@@ -214,31 +219,14 @@ public class WalkingManager implements IXmlReader
*/
public boolean isOnWalk(Npc npc)
{
MonsterInstance monster = null;
if (npc.isMonster())
{
if (((MonsterInstance) npc).getLeader() == null)
{
monster = (MonsterInstance) npc;
}
else
{
monster = ((MonsterInstance) npc).getLeader();
}
}
final MonsterInstance monster = npc.isMonster() ? ((MonsterInstance) npc).getLeader() == null ? (MonsterInstance) npc : ((MonsterInstance) npc).getLeader() : null;
if (((monster != null) && !isRegistered(monster)) || !isRegistered(npc))
{
return false;
}
final WalkInfo walk = monster != null ? _activeRoutes.get(monster.getObjectId()) : _activeRoutes.get(npc.getObjectId());
if (walk.isStoppedByAttack() || walk.isSuspended())
{
return false;
}
return true;
return !walk.isStoppedByAttack() && !walk.isSuspended();
}
public WalkRoute getRoute(String route)
@@ -246,6 +234,15 @@ public class WalkingManager implements IXmlReader
return _routes.get(route);
}
/**
* @param npc NPC to check
* @return {@code true} if given NPC id is registered as a route target.
*/
public boolean isTargeted(Npc npc)
{
return _targetedNpcIds.contains(npc.getId());
}
/**
* @param npc NPC to check
* @return {@code true} if given NPC controlled by Walking Manager.
@@ -290,7 +287,7 @@ public class WalkingManager implements IXmlReader
if (!npc.isInsideRadius3D(node, 3000))
{
LOGGER.warning("Route '" + routeName + "': NPC (id=" + npc.getId() + ", x=" + npc.getX() + ", y=" + npc.getY() + ", z=" + npc.getZ() + ") is too far from starting point (node x=" + node.getX() + ", y=" + node.getY() + ", z=" + node.getZ() + ", range=" + npc.calculateDistance3D(node) + "). Teleporting to proper location.");
LOGGER.warning(getClass().getSimpleName() + ": " + "Route '" + routeName + "': NPC (id=" + npc.getId() + ", x=" + npc.getX() + ", y=" + npc.getY() + ", z=" + npc.getZ() + ") is too far from starting point (node x=" + node.getX() + ", y=" + node.getY() + ", z=" + node.getZ() + ", range=" + npc.calculateDistance3D(node) + "). Teleporting to proper location.");
npc.teleToLocation(node);
}
@@ -307,7 +304,7 @@ public class WalkingManager implements IXmlReader
final ScheduledFuture<?> task = _repeatMoveTasks.get(npc);
if ((task == null) || task.isCancelled() || task.isDone())
{
final ScheduledFuture<?> newTask = ThreadPool.scheduleAtFixedRate(new StartMovingTask(npc, routeName), 60000, 60000);
final ScheduledFuture<?> newTask = ThreadPool.scheduleAtFixedRate(new StartMovingTask(npc, routeName), 10000, 10000);
_repeatMoveTasks.put(npc, newTask);
walk.setWalkCheckTask(newTask); // start walk check task, for resuming walk after fight
}
@@ -319,7 +316,7 @@ public class WalkingManager implements IXmlReader
final ScheduledFuture<?> task = _startMoveTasks.get(npc);
if ((task == null) || task.isCancelled() || task.isDone())
{
_startMoveTasks.put(npc, ThreadPool.schedule(new StartMovingTask(npc, routeName), 60000));
_startMoveTasks.put(npc, ThreadPool.schedule(new StartMovingTask(npc, routeName), 10000));
}
}
}
@@ -393,19 +390,7 @@ public class WalkingManager implements IXmlReader
*/
public void stopMoving(Npc npc, boolean suspend, boolean stoppedByAttack)
{
MonsterInstance monster = null;
if (npc.isMonster())
{
if (((MonsterInstance) npc).getLeader() == null)
{
monster = (MonsterInstance) npc;
}
else
{
monster = ((MonsterInstance) npc).getLeader();
}
}
final MonsterInstance monster = npc.isMonster() ? ((MonsterInstance) npc).getLeader() == null ? (MonsterInstance) npc : ((MonsterInstance) npc).getLeader() : null;
if (((monster != null) && !isRegistered(monster)) || !isRegistered(npc))
{
@@ -435,38 +420,43 @@ public class WalkingManager implements IXmlReader
*/
public void onArrived(Npc npc)
{
if (_activeRoutes.containsKey(npc.getObjectId()))
if (!_activeRoutes.containsKey(npc.getObjectId()))
{
// Notify quest
EventDispatcher.getInstance().notifyEventAsync(new OnNpcMoveNodeArrived(npc), npc);
final WalkInfo walk = _activeRoutes.get(npc.getObjectId());
// Opposite should not happen... but happens sometime
if ((walk.getCurrentNodeId() >= 0) && (walk.getCurrentNodeId() < walk.getRoute().getNodesCount()))
{
final NpcWalkerNode node = walk.getRoute().getNodeList().get(walk.getCurrentNodeId());
if (npc.isInsideRadius2D(node, 10))
{
walk.calculateNextNode(npc);
walk.setBlocked(true); // prevents to be ran from walk check task, if there is delay in this node.
if (node.getNpcString() != null)
{
npc.broadcastSay(ChatType.NPC_GENERAL, node.getNpcString());
}
else if (!node.getChatText().isEmpty())
{
npc.broadcastSay(ChatType.NPC_GENERAL, node.getChatText());
}
final ScheduledFuture<?> task = _arriveTasks.get(npc);
if ((task == null) || task.isCancelled() || task.isDone())
{
_arriveTasks.put(npc, ThreadPool.schedule(new ArrivedTask(npc, walk), 100 + (node.getDelay() * 1000)));
}
}
}
return;
}
// Notify quest
EventDispatcher.getInstance().notifyEventAsync(new OnNpcMoveNodeArrived(npc), npc);
final WalkInfo walk = _activeRoutes.get(npc.getObjectId());
// Opposite should not happen... but happens sometime
if ((walk.getCurrentNodeId() < 0) || (walk.getCurrentNodeId() >= walk.getRoute().getNodesCount()))
{
return;
}
final NpcWalkerNode node = walk.getRoute().getNodeList().get(walk.getCurrentNodeId());
if (!npc.isInsideRadius2D(node, 10))
{
return;
}
walk.calculateNextNode(npc);
walk.setBlocked(true); // prevents to be ran from walk check task, if there is delay in this node.
if (node.getNpcString() != null)
{
npc.broadcastSay(ChatType.NPC_GENERAL, node.getNpcString());
}
else if (!node.getChatText().isEmpty())
{
npc.broadcastSay(ChatType.NPC_GENERAL, node.getChatText());
}
final ScheduledFuture<?> task = _arriveTasks.get(npc);
if ((task == null) || task.isCancelled() || task.isDone())
{
_arriveTasks.put(npc, ThreadPool.schedule(new ArrivedTask(npc, walk), 100 + (node.getDelay() * 1000)));
}
}

View File

@@ -27,6 +27,7 @@ import org.l2jmobius.Config;
import org.l2jmobius.commons.util.Rnd;
import org.l2jmobius.gameserver.data.xml.impl.NpcData;
import org.l2jmobius.gameserver.geoengine.GeoEngine;
import org.l2jmobius.gameserver.instancemanager.WalkingManager;
import org.l2jmobius.gameserver.model.actor.Npc;
import org.l2jmobius.gameserver.model.actor.instance.MonsterInstance;
import org.l2jmobius.gameserver.model.actor.templates.NpcTemplate;
@@ -392,7 +393,7 @@ public class Spawn extends Location implements IIdentifiable, INamable
final int randX = newlocx + Rnd.get(Config.MOB_MIN_SPAWN_RANGE, Config.MOB_MAX_SPAWN_RANGE);
final int randY = newlocy + Rnd.get(Config.MOB_MIN_SPAWN_RANGE, Config.MOB_MAX_SPAWN_RANGE);
if (npc.isMonster() && !npc.isQuestMonster() && !npc.isWalker() && !npc.isInsideZone(ZoneId.NO_BOOKMARK) && (getInstanceId() == 0) && GeoEngine.getInstance().canMoveToTarget(newlocx, newlocy, newlocz, randX, randY, newlocz, npc.getInstanceWorld()) && !getTemplate().isUndying() && !npc.isRaid() && !npc.isRaidMinion() && !Config.MOBS_LIST_NOT_RANDOM.contains(npc.getId()))
if (npc.isMonster() && !npc.isQuestMonster() && !WalkingManager.getInstance().isTargeted(npc) && !npc.isInsideZone(ZoneId.NO_BOOKMARK) && (getInstanceId() == 0) && GeoEngine.getInstance().canMoveToTarget(newlocx, newlocy, newlocz, randX, randY, newlocz, npc.getInstanceWorld()) && !getTemplate().isUndying() && !npc.isRaid() && !npc.isRaidMinion() && !Config.MOBS_LIST_NOT_RANDOM.contains(npc.getId()))
{
newlocx = randX;
newlocy = randY;

View File

@@ -1030,7 +1030,7 @@ public class Npc extends Creature
_spiritshotamount = getTemplate().getSpiritShot();
_killingBlowWeaponId = 0;
_isRandomAnimationEnabled = getTemplate().isRandomAnimationEnabled();
_isRandomWalkingEnabled = getTemplate().isRandomWalkEnabled();
_isRandomWalkingEnabled = !WalkingManager.getInstance().isTargeted(this) && getTemplate().isRandomWalkEnabled();
if (isTeleporting())
{