From a5ab4d03d4a833a2b552f2f4407856bbe61de5af Mon Sep 17 00:00:00 2001 From: MobiusDev <8391001+MobiusDevelopment@users.noreply.github.com> Date: Sun, 27 Aug 2017 14:58:10 +0000 Subject: [PATCH] Several GeoEngine improvements/fixes. --- .../geoengine/GeoEnginePathfinding.java | 44 +------ .../gameserver/model/actor/L2Character.java | 117 ++++++------------ .../actor/instance/L2AirShipInstance.java | 1 + .../geoengine/GeoEnginePathfinding.java | 44 +------ .../gameserver/model/actor/L2Character.java | 117 ++++++------------ .../actor/instance/L2AirShipInstance.java | 1 + .../geoengine/GeoEnginePathfinding.java | 44 +------ .../gameserver/model/actor/L2Character.java | 117 ++++++------------ .../actor/instance/L2AirShipInstance.java | 1 + .../geoengine/GeoEnginePathfinding.java | 44 +------ .../gameserver/model/actor/L2Character.java | 102 ++++++--------- .../actor/instance/L2AirShipInstance.java | 1 + .../geoengine/GeoEnginePathfinding.java | 44 +------ .../gameserver/model/actor/L2Character.java | 117 ++++++------------ .../actor/instance/L2AirShipInstance.java | 1 + 15 files changed, 220 insertions(+), 575 deletions(-) diff --git a/L2J_Mobius_Classic/java/com/l2jmobius/gameserver/geoengine/GeoEnginePathfinding.java b/L2J_Mobius_Classic/java/com/l2jmobius/gameserver/geoengine/GeoEnginePathfinding.java index b9def83228..5447dcc767 100644 --- a/L2J_Mobius_Classic/java/com/l2jmobius/gameserver/geoengine/GeoEnginePathfinding.java +++ b/L2J_Mobius_Classic/java/com/l2jmobius/gameserver/geoengine/GeoEnginePathfinding.java @@ -22,7 +22,6 @@ import java.util.List; import java.util.ListIterator; import com.l2jmobius.Config; -import com.l2jmobius.commons.util.StringUtil; import com.l2jmobius.gameserver.geoengine.geodata.GeoLocation; import com.l2jmobius.gameserver.geoengine.pathfinding.Node; import com.l2jmobius.gameserver.geoengine.pathfinding.NodeBuffer; @@ -212,7 +211,7 @@ final class GeoEnginePathfinding extends GeoEngine } /** - * Provides optimize selection of the buffer. When all pre-initialized buffer are locked, creates new buffer and log this situation. + * Provides optimize selection of the buffer. When all pre-initialized buffer are locked, creates new buffer. * @param size : pre-calculated minimal required size * @param playable : moving object is playable? * @return NodeBuffer : buffer @@ -236,25 +235,12 @@ final class GeoEnginePathfinding extends GeoEngine continue; } - holder._uses++; - if (playable) - { - holder._playableUses++; - } - - holder._elapsed += buffer.getElapsedTime(); return buffer; } // NodeBuffer not found, allocate temporary buffer current = new NodeBuffer(holder._size); current.isLocked(); - - holder._overflows++; - if (playable) - { - holder._playableOverflows++; - } } return current; @@ -266,20 +252,11 @@ final class GeoEnginePathfinding extends GeoEngine private static final class BufferHolder { final int _size; - final int _count; - ArrayList _buffer; - - // statistics - int _playableUses = 0; - int _uses = 0; - int _playableOverflows = 0; - int _overflows = 0; - long _elapsed = 0; + List _buffer; public BufferHolder(int size, int count) { _size = size; - _count = count; _buffer = new ArrayList<>(count); for (int i = 0; i < count; i++) @@ -287,22 +264,5 @@ final class GeoEnginePathfinding extends GeoEngine _buffer.add(new NodeBuffer(size)); } } - - @Override - public String toString() - { - final StringBuilder sb = new StringBuilder(100); - - StringUtil.append(sb, "Buffer ", String.valueOf(_size), "x", String.valueOf(_size), ": count=", String.valueOf(_count), " uses=", String.valueOf(_playableUses), "/", String.valueOf(_uses)); - - if (_uses > 0) - { - StringUtil.append(sb, " total/avg(ms)=", String.valueOf(_elapsed), "/", String.format("%1.2f", (double) _elapsed / _uses)); - } - - StringUtil.append(sb, " ovf=", String.valueOf(_playableOverflows), "/", String.valueOf(_overflows)); - - return sb.toString(); - } } } \ No newline at end of file diff --git a/L2J_Mobius_Classic/java/com/l2jmobius/gameserver/model/actor/L2Character.java b/L2J_Mobius_Classic/java/com/l2jmobius/gameserver/model/actor/L2Character.java index 8d4e253ccc..1ea1c674fb 100644 --- a/L2J_Mobius_Classic/java/com/l2jmobius/gameserver/model/actor/L2Character.java +++ b/L2J_Mobius_Classic/java/com/l2jmobius/gameserver/model/actor/L2Character.java @@ -51,7 +51,6 @@ import com.l2jmobius.gameserver.ai.CtrlIntention; import com.l2jmobius.gameserver.ai.L2AttackableAI; import com.l2jmobius.gameserver.ai.L2CharacterAI; import com.l2jmobius.gameserver.data.xml.impl.CategoryData; -import com.l2jmobius.gameserver.data.xml.impl.DoorData; import com.l2jmobius.gameserver.data.xml.impl.TransformData; import com.l2jmobius.gameserver.enums.AttributeType; import com.l2jmobius.gameserver.enums.BasicProperty; @@ -67,7 +66,6 @@ import com.l2jmobius.gameserver.geoengine.GeoEngine; import com.l2jmobius.gameserver.idfactory.IdFactory; import com.l2jmobius.gameserver.instancemanager.MapRegionManager; import com.l2jmobius.gameserver.instancemanager.TimersManager; -import com.l2jmobius.gameserver.instancemanager.WarpedSpaceManager; import com.l2jmobius.gameserver.instancemanager.ZoneManager; import com.l2jmobius.gameserver.model.CharEffectList; import com.l2jmobius.gameserver.model.CreatureContainer; @@ -3579,7 +3577,7 @@ public abstract class L2Character extends L2Object implements ISkillsHolder, IDe m.onGeodataPathIndex = -1; // Initialize not on geodata path m.disregardingGeodata = false; - if (!isFlying() && !isInsideZone(ZoneId.WATER) && !isWalker()) + if (!isFlying() && !isInsideZone(ZoneId.WATER) && !isWalker() && !isVehicle()) { final boolean isInVehicle = isPlayer() && (getActingPlayer().getVehicle() != null); if (isInVehicle) @@ -3598,7 +3596,7 @@ public abstract class L2Character extends L2Object implements ISkillsHolder, IDe // when geodata == 2, for all characters except mobs returning home (could be changed later to teleport if pathfinding fails) // when geodata == 1, for l2playableinstance // assuming intention_follow only when following owner - if ((Config.PATHFINDING && !(isAttackable() && ((L2Attackable) this).isReturningToSpawnPoint())) || (isPlayer() && !(isInVehicle && (distance > 1500))) || (isSummon() && !(getAI().getIntention() == CtrlIntention.AI_INTENTION_FOLLOW))) + if (Config.PATHFINDING && (!(isAttackable() && ((L2Attackable) this).isReturningToSpawnPoint()) || (isSummon() && !(getAI().getIntention() == CtrlIntention.AI_INTENTION_FOLLOW)))) { if (isOnGeodataPath()) { @@ -3636,7 +3634,7 @@ public abstract class L2Character extends L2Object implements ISkillsHolder, IDe return; } // location different if destination wasn't reached (or just z coord is different) - Location destiny = GeoEngine.getInstance().canMoveToTargetLoc(curX, curY, curZ, x, y, z, getInstanceWorld()); + final Location destiny = GeoEngine.getInstance().canMoveToTargetLoc(curX, curY, curZ, x, y, z, getInstanceWorld()); x = destiny.getX(); y = destiny.getY(); z = destiny.getZ(); @@ -3647,84 +3645,51 @@ public abstract class L2Character extends L2Object implements ISkillsHolder, IDe } // Pathfinding checks. Only when geodata setting is 2, the LoS check gives shorter result than the original movement was and the LoS gives a shorter distance than 2000 // This way of detecting need for pathfinding could be changed. - if (Config.PATHFINDING && ((originalDistance - distance) > 30) && (distance < 2000) && !isControlBlocked() && !isInVehicle) + if (Config.PATHFINDING && ((originalDistance - distance) > 30) && !isControlBlocked() && !isInVehicle) { // Path calculation -- overrides previous movement check - if (isPlayable() || isMinion() || isInCombat()) + m.geoPath = GeoEngine.getInstance().findPath(curX, curY, curZ, originalX, originalY, originalZ, getInstanceWorld(), isPlayable()); + if ((m.geoPath == null) || (m.geoPath.size() < 2)) { - m.geoPath = GeoEngine.getInstance().findPath(curX, curY, curZ, originalX, originalY, originalZ, getInstanceWorld(), isPlayable()); - if ((m.geoPath == null) || (m.geoPath.size() < 2)) + // No path found + // Even though there's no path found (remember geonodes aren't perfect), the mob is attacking and right now we set it so that the mob will go after target anyway, is dz is small enough. + // With cellpathfinding this approach could be changed but would require taking off the geonodes and some more checks. + // Summons will follow their masters no matter what. + // Currently minions also must move freely since L2AttackableAI commands them to move along with their leader + if (isPlayer() || (!isPlayable() && !isMinion() && (Math.abs(z - curZ) > 140)) || (isSummon() && !((L2Summon) this).getFollowStatus())) { - // No path found - // Even though there's no path found (remember geonodes aren't perfect), the mob is attacking and right now we set it so that the mob will go after target anyway, is dz is small enough. - // With cellpathfinding this approach could be changed but would require taking off the geonodes and some more checks. - // Summons will follow their masters no matter what. - // Currently minions also must move freely since L2AttackableAI commands them to move along with their leader - if (isPlayer() || (!isPlayable() && !isMinion() && (Math.abs(z - curZ) > 140)) || (isSummon() && !((L2Summon) this).getFollowStatus())) - { - getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE); - return; - } - - m.disregardingGeodata = true; - x = originalX; - y = originalY; - z = originalZ; - distance = originalDistance; - } - else - { - m.onGeodataPathIndex = 0; // on first segment - m.geoPathGtx = gtx; - m.geoPathGty = gty; - m.geoPathAccurateTx = originalX; - m.geoPathAccurateTy = originalY; - - x = m.geoPath.get(m.onGeodataPathIndex).getX(); - y = m.geoPath.get(m.onGeodataPathIndex).getY(); - z = m.geoPath.get(m.onGeodataPathIndex).getZ(); - - // check for doors in the route - if (DoorData.getInstance().checkIfDoorsBetween(curX, curY, curZ, x, y, z, getInstanceWorld())) - { - m.geoPath = null; - getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE); - return; - } - if (WarpedSpaceManager.getInstance().checkForWarpedSpace(new Location(curX, curY, curZ), new Location(x, y, z), getInstanceWorld())) - { - m.geoPath = null; - getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE); - return; - } - for (int i = 0; i < (m.geoPath.size() - 1); i++) - { - if (DoorData.getInstance().checkIfDoorsBetween(m.geoPath.get(i), m.geoPath.get(i + 1), getInstanceWorld())) - { - m.geoPath = null; - getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE); - return; - } - if (WarpedSpaceManager.getInstance().checkForWarpedSpace(m.geoPath.get(i), m.geoPath.get(i + 1), getInstanceWorld())) - { - m.geoPath = null; - getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE); - return; - } - } - - dx = x - curX; - dy = y - curY; - dz = z - curZ; - distance = verticalMovementOnly ? Math.pow(dz, 2) : Math.hypot(dx, dy); - sin = dy / distance; - cos = dx / distance; + getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE); + return; } + + m.disregardingGeodata = true; + x = originalX; + y = originalY; + z = originalZ; + distance = originalDistance; + } + else + { + m.onGeodataPathIndex = 0; // on first segment + m.geoPathGtx = gtx; + m.geoPathGty = gty; + m.geoPathAccurateTx = originalX; + m.geoPathAccurateTy = originalY; + + x = m.geoPath.get(m.onGeodataPathIndex).getX(); + y = m.geoPath.get(m.onGeodataPathIndex).getY(); + z = m.geoPath.get(m.onGeodataPathIndex).getZ(); + + dx = x - curX; + dy = y - curY; + dz = z - curZ; + distance = verticalMovementOnly ? Math.pow(dz, 2) : Math.hypot(dx, dy); + sin = dy / distance; + cos = dx / distance; } } - // If no distance to go through, the movement is canceled - if ((distance < 1) && (Config.PATHFINDING || isPlayable() || isControlBlocked())) + if ((distance < 1) && (Config.PATHFINDING || isPlayable())) { if (isSummon()) { @@ -3746,7 +3711,7 @@ public abstract class L2Character extends L2Object implements ISkillsHolder, IDe final int ticksToMove = 1 + (int) ((GameTimeController.TICKS_PER_SECOND * distance) / speed); m._xDestination = x; m._yDestination = y; - m._zDestination = z; + m._zDestination = z; // this is what was requested from client // Calculate and set the heading of the L2Character m._heading = 0; // initial value for coordinate sync diff --git a/L2J_Mobius_Classic/java/com/l2jmobius/gameserver/model/actor/instance/L2AirShipInstance.java b/L2J_Mobius_Classic/java/com/l2jmobius/gameserver/model/actor/instance/L2AirShipInstance.java index b4d574c40c..b253f13a62 100644 --- a/L2J_Mobius_Classic/java/com/l2jmobius/gameserver/model/actor/instance/L2AirShipInstance.java +++ b/L2J_Mobius_Classic/java/com/l2jmobius/gameserver/model/actor/instance/L2AirShipInstance.java @@ -133,6 +133,7 @@ public class L2AirShipInstance extends L2Vehicle player.broadcastPacket(new ExGetOnAirShip(player, this)); player.setXYZ(getX(), getY(), getZ()); player.revalidateZone(true); + player.stopMove(null); return true; } diff --git a/L2J_Mobius_Ertheia/java/com/l2jmobius/gameserver/geoengine/GeoEnginePathfinding.java b/L2J_Mobius_Ertheia/java/com/l2jmobius/gameserver/geoengine/GeoEnginePathfinding.java index b9def83228..5447dcc767 100644 --- a/L2J_Mobius_Ertheia/java/com/l2jmobius/gameserver/geoengine/GeoEnginePathfinding.java +++ b/L2J_Mobius_Ertheia/java/com/l2jmobius/gameserver/geoengine/GeoEnginePathfinding.java @@ -22,7 +22,6 @@ import java.util.List; import java.util.ListIterator; import com.l2jmobius.Config; -import com.l2jmobius.commons.util.StringUtil; import com.l2jmobius.gameserver.geoengine.geodata.GeoLocation; import com.l2jmobius.gameserver.geoengine.pathfinding.Node; import com.l2jmobius.gameserver.geoengine.pathfinding.NodeBuffer; @@ -212,7 +211,7 @@ final class GeoEnginePathfinding extends GeoEngine } /** - * Provides optimize selection of the buffer. When all pre-initialized buffer are locked, creates new buffer and log this situation. + * Provides optimize selection of the buffer. When all pre-initialized buffer are locked, creates new buffer. * @param size : pre-calculated minimal required size * @param playable : moving object is playable? * @return NodeBuffer : buffer @@ -236,25 +235,12 @@ final class GeoEnginePathfinding extends GeoEngine continue; } - holder._uses++; - if (playable) - { - holder._playableUses++; - } - - holder._elapsed += buffer.getElapsedTime(); return buffer; } // NodeBuffer not found, allocate temporary buffer current = new NodeBuffer(holder._size); current.isLocked(); - - holder._overflows++; - if (playable) - { - holder._playableOverflows++; - } } return current; @@ -266,20 +252,11 @@ final class GeoEnginePathfinding extends GeoEngine private static final class BufferHolder { final int _size; - final int _count; - ArrayList _buffer; - - // statistics - int _playableUses = 0; - int _uses = 0; - int _playableOverflows = 0; - int _overflows = 0; - long _elapsed = 0; + List _buffer; public BufferHolder(int size, int count) { _size = size; - _count = count; _buffer = new ArrayList<>(count); for (int i = 0; i < count; i++) @@ -287,22 +264,5 @@ final class GeoEnginePathfinding extends GeoEngine _buffer.add(new NodeBuffer(size)); } } - - @Override - public String toString() - { - final StringBuilder sb = new StringBuilder(100); - - StringUtil.append(sb, "Buffer ", String.valueOf(_size), "x", String.valueOf(_size), ": count=", String.valueOf(_count), " uses=", String.valueOf(_playableUses), "/", String.valueOf(_uses)); - - if (_uses > 0) - { - StringUtil.append(sb, " total/avg(ms)=", String.valueOf(_elapsed), "/", String.format("%1.2f", (double) _elapsed / _uses)); - } - - StringUtil.append(sb, " ovf=", String.valueOf(_playableOverflows), "/", String.valueOf(_overflows)); - - return sb.toString(); - } } } \ No newline at end of file diff --git a/L2J_Mobius_Ertheia/java/com/l2jmobius/gameserver/model/actor/L2Character.java b/L2J_Mobius_Ertheia/java/com/l2jmobius/gameserver/model/actor/L2Character.java index 8d4e253ccc..1ea1c674fb 100644 --- a/L2J_Mobius_Ertheia/java/com/l2jmobius/gameserver/model/actor/L2Character.java +++ b/L2J_Mobius_Ertheia/java/com/l2jmobius/gameserver/model/actor/L2Character.java @@ -51,7 +51,6 @@ import com.l2jmobius.gameserver.ai.CtrlIntention; import com.l2jmobius.gameserver.ai.L2AttackableAI; import com.l2jmobius.gameserver.ai.L2CharacterAI; import com.l2jmobius.gameserver.data.xml.impl.CategoryData; -import com.l2jmobius.gameserver.data.xml.impl.DoorData; import com.l2jmobius.gameserver.data.xml.impl.TransformData; import com.l2jmobius.gameserver.enums.AttributeType; import com.l2jmobius.gameserver.enums.BasicProperty; @@ -67,7 +66,6 @@ import com.l2jmobius.gameserver.geoengine.GeoEngine; import com.l2jmobius.gameserver.idfactory.IdFactory; import com.l2jmobius.gameserver.instancemanager.MapRegionManager; import com.l2jmobius.gameserver.instancemanager.TimersManager; -import com.l2jmobius.gameserver.instancemanager.WarpedSpaceManager; import com.l2jmobius.gameserver.instancemanager.ZoneManager; import com.l2jmobius.gameserver.model.CharEffectList; import com.l2jmobius.gameserver.model.CreatureContainer; @@ -3579,7 +3577,7 @@ public abstract class L2Character extends L2Object implements ISkillsHolder, IDe m.onGeodataPathIndex = -1; // Initialize not on geodata path m.disregardingGeodata = false; - if (!isFlying() && !isInsideZone(ZoneId.WATER) && !isWalker()) + if (!isFlying() && !isInsideZone(ZoneId.WATER) && !isWalker() && !isVehicle()) { final boolean isInVehicle = isPlayer() && (getActingPlayer().getVehicle() != null); if (isInVehicle) @@ -3598,7 +3596,7 @@ public abstract class L2Character extends L2Object implements ISkillsHolder, IDe // when geodata == 2, for all characters except mobs returning home (could be changed later to teleport if pathfinding fails) // when geodata == 1, for l2playableinstance // assuming intention_follow only when following owner - if ((Config.PATHFINDING && !(isAttackable() && ((L2Attackable) this).isReturningToSpawnPoint())) || (isPlayer() && !(isInVehicle && (distance > 1500))) || (isSummon() && !(getAI().getIntention() == CtrlIntention.AI_INTENTION_FOLLOW))) + if (Config.PATHFINDING && (!(isAttackable() && ((L2Attackable) this).isReturningToSpawnPoint()) || (isSummon() && !(getAI().getIntention() == CtrlIntention.AI_INTENTION_FOLLOW)))) { if (isOnGeodataPath()) { @@ -3636,7 +3634,7 @@ public abstract class L2Character extends L2Object implements ISkillsHolder, IDe return; } // location different if destination wasn't reached (or just z coord is different) - Location destiny = GeoEngine.getInstance().canMoveToTargetLoc(curX, curY, curZ, x, y, z, getInstanceWorld()); + final Location destiny = GeoEngine.getInstance().canMoveToTargetLoc(curX, curY, curZ, x, y, z, getInstanceWorld()); x = destiny.getX(); y = destiny.getY(); z = destiny.getZ(); @@ -3647,84 +3645,51 @@ public abstract class L2Character extends L2Object implements ISkillsHolder, IDe } // Pathfinding checks. Only when geodata setting is 2, the LoS check gives shorter result than the original movement was and the LoS gives a shorter distance than 2000 // This way of detecting need for pathfinding could be changed. - if (Config.PATHFINDING && ((originalDistance - distance) > 30) && (distance < 2000) && !isControlBlocked() && !isInVehicle) + if (Config.PATHFINDING && ((originalDistance - distance) > 30) && !isControlBlocked() && !isInVehicle) { // Path calculation -- overrides previous movement check - if (isPlayable() || isMinion() || isInCombat()) + m.geoPath = GeoEngine.getInstance().findPath(curX, curY, curZ, originalX, originalY, originalZ, getInstanceWorld(), isPlayable()); + if ((m.geoPath == null) || (m.geoPath.size() < 2)) { - m.geoPath = GeoEngine.getInstance().findPath(curX, curY, curZ, originalX, originalY, originalZ, getInstanceWorld(), isPlayable()); - if ((m.geoPath == null) || (m.geoPath.size() < 2)) + // No path found + // Even though there's no path found (remember geonodes aren't perfect), the mob is attacking and right now we set it so that the mob will go after target anyway, is dz is small enough. + // With cellpathfinding this approach could be changed but would require taking off the geonodes and some more checks. + // Summons will follow their masters no matter what. + // Currently minions also must move freely since L2AttackableAI commands them to move along with their leader + if (isPlayer() || (!isPlayable() && !isMinion() && (Math.abs(z - curZ) > 140)) || (isSummon() && !((L2Summon) this).getFollowStatus())) { - // No path found - // Even though there's no path found (remember geonodes aren't perfect), the mob is attacking and right now we set it so that the mob will go after target anyway, is dz is small enough. - // With cellpathfinding this approach could be changed but would require taking off the geonodes and some more checks. - // Summons will follow their masters no matter what. - // Currently minions also must move freely since L2AttackableAI commands them to move along with their leader - if (isPlayer() || (!isPlayable() && !isMinion() && (Math.abs(z - curZ) > 140)) || (isSummon() && !((L2Summon) this).getFollowStatus())) - { - getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE); - return; - } - - m.disregardingGeodata = true; - x = originalX; - y = originalY; - z = originalZ; - distance = originalDistance; - } - else - { - m.onGeodataPathIndex = 0; // on first segment - m.geoPathGtx = gtx; - m.geoPathGty = gty; - m.geoPathAccurateTx = originalX; - m.geoPathAccurateTy = originalY; - - x = m.geoPath.get(m.onGeodataPathIndex).getX(); - y = m.geoPath.get(m.onGeodataPathIndex).getY(); - z = m.geoPath.get(m.onGeodataPathIndex).getZ(); - - // check for doors in the route - if (DoorData.getInstance().checkIfDoorsBetween(curX, curY, curZ, x, y, z, getInstanceWorld())) - { - m.geoPath = null; - getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE); - return; - } - if (WarpedSpaceManager.getInstance().checkForWarpedSpace(new Location(curX, curY, curZ), new Location(x, y, z), getInstanceWorld())) - { - m.geoPath = null; - getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE); - return; - } - for (int i = 0; i < (m.geoPath.size() - 1); i++) - { - if (DoorData.getInstance().checkIfDoorsBetween(m.geoPath.get(i), m.geoPath.get(i + 1), getInstanceWorld())) - { - m.geoPath = null; - getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE); - return; - } - if (WarpedSpaceManager.getInstance().checkForWarpedSpace(m.geoPath.get(i), m.geoPath.get(i + 1), getInstanceWorld())) - { - m.geoPath = null; - getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE); - return; - } - } - - dx = x - curX; - dy = y - curY; - dz = z - curZ; - distance = verticalMovementOnly ? Math.pow(dz, 2) : Math.hypot(dx, dy); - sin = dy / distance; - cos = dx / distance; + getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE); + return; } + + m.disregardingGeodata = true; + x = originalX; + y = originalY; + z = originalZ; + distance = originalDistance; + } + else + { + m.onGeodataPathIndex = 0; // on first segment + m.geoPathGtx = gtx; + m.geoPathGty = gty; + m.geoPathAccurateTx = originalX; + m.geoPathAccurateTy = originalY; + + x = m.geoPath.get(m.onGeodataPathIndex).getX(); + y = m.geoPath.get(m.onGeodataPathIndex).getY(); + z = m.geoPath.get(m.onGeodataPathIndex).getZ(); + + dx = x - curX; + dy = y - curY; + dz = z - curZ; + distance = verticalMovementOnly ? Math.pow(dz, 2) : Math.hypot(dx, dy); + sin = dy / distance; + cos = dx / distance; } } - // If no distance to go through, the movement is canceled - if ((distance < 1) && (Config.PATHFINDING || isPlayable() || isControlBlocked())) + if ((distance < 1) && (Config.PATHFINDING || isPlayable())) { if (isSummon()) { @@ -3746,7 +3711,7 @@ public abstract class L2Character extends L2Object implements ISkillsHolder, IDe final int ticksToMove = 1 + (int) ((GameTimeController.TICKS_PER_SECOND * distance) / speed); m._xDestination = x; m._yDestination = y; - m._zDestination = z; + m._zDestination = z; // this is what was requested from client // Calculate and set the heading of the L2Character m._heading = 0; // initial value for coordinate sync diff --git a/L2J_Mobius_Ertheia/java/com/l2jmobius/gameserver/model/actor/instance/L2AirShipInstance.java b/L2J_Mobius_Ertheia/java/com/l2jmobius/gameserver/model/actor/instance/L2AirShipInstance.java index b4d574c40c..b253f13a62 100644 --- a/L2J_Mobius_Ertheia/java/com/l2jmobius/gameserver/model/actor/instance/L2AirShipInstance.java +++ b/L2J_Mobius_Ertheia/java/com/l2jmobius/gameserver/model/actor/instance/L2AirShipInstance.java @@ -133,6 +133,7 @@ public class L2AirShipInstance extends L2Vehicle player.broadcastPacket(new ExGetOnAirShip(player, this)); player.setXYZ(getX(), getY(), getZ()); player.revalidateZone(true); + player.stopMove(null); return true; } diff --git a/L2J_Mobius_Helios/java/com/l2jmobius/gameserver/geoengine/GeoEnginePathfinding.java b/L2J_Mobius_Helios/java/com/l2jmobius/gameserver/geoengine/GeoEnginePathfinding.java index b9def83228..5447dcc767 100644 --- a/L2J_Mobius_Helios/java/com/l2jmobius/gameserver/geoengine/GeoEnginePathfinding.java +++ b/L2J_Mobius_Helios/java/com/l2jmobius/gameserver/geoengine/GeoEnginePathfinding.java @@ -22,7 +22,6 @@ import java.util.List; import java.util.ListIterator; import com.l2jmobius.Config; -import com.l2jmobius.commons.util.StringUtil; import com.l2jmobius.gameserver.geoengine.geodata.GeoLocation; import com.l2jmobius.gameserver.geoengine.pathfinding.Node; import com.l2jmobius.gameserver.geoengine.pathfinding.NodeBuffer; @@ -212,7 +211,7 @@ final class GeoEnginePathfinding extends GeoEngine } /** - * Provides optimize selection of the buffer. When all pre-initialized buffer are locked, creates new buffer and log this situation. + * Provides optimize selection of the buffer. When all pre-initialized buffer are locked, creates new buffer. * @param size : pre-calculated minimal required size * @param playable : moving object is playable? * @return NodeBuffer : buffer @@ -236,25 +235,12 @@ final class GeoEnginePathfinding extends GeoEngine continue; } - holder._uses++; - if (playable) - { - holder._playableUses++; - } - - holder._elapsed += buffer.getElapsedTime(); return buffer; } // NodeBuffer not found, allocate temporary buffer current = new NodeBuffer(holder._size); current.isLocked(); - - holder._overflows++; - if (playable) - { - holder._playableOverflows++; - } } return current; @@ -266,20 +252,11 @@ final class GeoEnginePathfinding extends GeoEngine private static final class BufferHolder { final int _size; - final int _count; - ArrayList _buffer; - - // statistics - int _playableUses = 0; - int _uses = 0; - int _playableOverflows = 0; - int _overflows = 0; - long _elapsed = 0; + List _buffer; public BufferHolder(int size, int count) { _size = size; - _count = count; _buffer = new ArrayList<>(count); for (int i = 0; i < count; i++) @@ -287,22 +264,5 @@ final class GeoEnginePathfinding extends GeoEngine _buffer.add(new NodeBuffer(size)); } } - - @Override - public String toString() - { - final StringBuilder sb = new StringBuilder(100); - - StringUtil.append(sb, "Buffer ", String.valueOf(_size), "x", String.valueOf(_size), ": count=", String.valueOf(_count), " uses=", String.valueOf(_playableUses), "/", String.valueOf(_uses)); - - if (_uses > 0) - { - StringUtil.append(sb, " total/avg(ms)=", String.valueOf(_elapsed), "/", String.format("%1.2f", (double) _elapsed / _uses)); - } - - StringUtil.append(sb, " ovf=", String.valueOf(_playableOverflows), "/", String.valueOf(_overflows)); - - return sb.toString(); - } } } \ No newline at end of file diff --git a/L2J_Mobius_Helios/java/com/l2jmobius/gameserver/model/actor/L2Character.java b/L2J_Mobius_Helios/java/com/l2jmobius/gameserver/model/actor/L2Character.java index 8d4e253ccc..1ea1c674fb 100644 --- a/L2J_Mobius_Helios/java/com/l2jmobius/gameserver/model/actor/L2Character.java +++ b/L2J_Mobius_Helios/java/com/l2jmobius/gameserver/model/actor/L2Character.java @@ -51,7 +51,6 @@ import com.l2jmobius.gameserver.ai.CtrlIntention; import com.l2jmobius.gameserver.ai.L2AttackableAI; import com.l2jmobius.gameserver.ai.L2CharacterAI; import com.l2jmobius.gameserver.data.xml.impl.CategoryData; -import com.l2jmobius.gameserver.data.xml.impl.DoorData; import com.l2jmobius.gameserver.data.xml.impl.TransformData; import com.l2jmobius.gameserver.enums.AttributeType; import com.l2jmobius.gameserver.enums.BasicProperty; @@ -67,7 +66,6 @@ import com.l2jmobius.gameserver.geoengine.GeoEngine; import com.l2jmobius.gameserver.idfactory.IdFactory; import com.l2jmobius.gameserver.instancemanager.MapRegionManager; import com.l2jmobius.gameserver.instancemanager.TimersManager; -import com.l2jmobius.gameserver.instancemanager.WarpedSpaceManager; import com.l2jmobius.gameserver.instancemanager.ZoneManager; import com.l2jmobius.gameserver.model.CharEffectList; import com.l2jmobius.gameserver.model.CreatureContainer; @@ -3579,7 +3577,7 @@ public abstract class L2Character extends L2Object implements ISkillsHolder, IDe m.onGeodataPathIndex = -1; // Initialize not on geodata path m.disregardingGeodata = false; - if (!isFlying() && !isInsideZone(ZoneId.WATER) && !isWalker()) + if (!isFlying() && !isInsideZone(ZoneId.WATER) && !isWalker() && !isVehicle()) { final boolean isInVehicle = isPlayer() && (getActingPlayer().getVehicle() != null); if (isInVehicle) @@ -3598,7 +3596,7 @@ public abstract class L2Character extends L2Object implements ISkillsHolder, IDe // when geodata == 2, for all characters except mobs returning home (could be changed later to teleport if pathfinding fails) // when geodata == 1, for l2playableinstance // assuming intention_follow only when following owner - if ((Config.PATHFINDING && !(isAttackable() && ((L2Attackable) this).isReturningToSpawnPoint())) || (isPlayer() && !(isInVehicle && (distance > 1500))) || (isSummon() && !(getAI().getIntention() == CtrlIntention.AI_INTENTION_FOLLOW))) + if (Config.PATHFINDING && (!(isAttackable() && ((L2Attackable) this).isReturningToSpawnPoint()) || (isSummon() && !(getAI().getIntention() == CtrlIntention.AI_INTENTION_FOLLOW)))) { if (isOnGeodataPath()) { @@ -3636,7 +3634,7 @@ public abstract class L2Character extends L2Object implements ISkillsHolder, IDe return; } // location different if destination wasn't reached (or just z coord is different) - Location destiny = GeoEngine.getInstance().canMoveToTargetLoc(curX, curY, curZ, x, y, z, getInstanceWorld()); + final Location destiny = GeoEngine.getInstance().canMoveToTargetLoc(curX, curY, curZ, x, y, z, getInstanceWorld()); x = destiny.getX(); y = destiny.getY(); z = destiny.getZ(); @@ -3647,84 +3645,51 @@ public abstract class L2Character extends L2Object implements ISkillsHolder, IDe } // Pathfinding checks. Only when geodata setting is 2, the LoS check gives shorter result than the original movement was and the LoS gives a shorter distance than 2000 // This way of detecting need for pathfinding could be changed. - if (Config.PATHFINDING && ((originalDistance - distance) > 30) && (distance < 2000) && !isControlBlocked() && !isInVehicle) + if (Config.PATHFINDING && ((originalDistance - distance) > 30) && !isControlBlocked() && !isInVehicle) { // Path calculation -- overrides previous movement check - if (isPlayable() || isMinion() || isInCombat()) + m.geoPath = GeoEngine.getInstance().findPath(curX, curY, curZ, originalX, originalY, originalZ, getInstanceWorld(), isPlayable()); + if ((m.geoPath == null) || (m.geoPath.size() < 2)) { - m.geoPath = GeoEngine.getInstance().findPath(curX, curY, curZ, originalX, originalY, originalZ, getInstanceWorld(), isPlayable()); - if ((m.geoPath == null) || (m.geoPath.size() < 2)) + // No path found + // Even though there's no path found (remember geonodes aren't perfect), the mob is attacking and right now we set it so that the mob will go after target anyway, is dz is small enough. + // With cellpathfinding this approach could be changed but would require taking off the geonodes and some more checks. + // Summons will follow their masters no matter what. + // Currently minions also must move freely since L2AttackableAI commands them to move along with their leader + if (isPlayer() || (!isPlayable() && !isMinion() && (Math.abs(z - curZ) > 140)) || (isSummon() && !((L2Summon) this).getFollowStatus())) { - // No path found - // Even though there's no path found (remember geonodes aren't perfect), the mob is attacking and right now we set it so that the mob will go after target anyway, is dz is small enough. - // With cellpathfinding this approach could be changed but would require taking off the geonodes and some more checks. - // Summons will follow their masters no matter what. - // Currently minions also must move freely since L2AttackableAI commands them to move along with their leader - if (isPlayer() || (!isPlayable() && !isMinion() && (Math.abs(z - curZ) > 140)) || (isSummon() && !((L2Summon) this).getFollowStatus())) - { - getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE); - return; - } - - m.disregardingGeodata = true; - x = originalX; - y = originalY; - z = originalZ; - distance = originalDistance; - } - else - { - m.onGeodataPathIndex = 0; // on first segment - m.geoPathGtx = gtx; - m.geoPathGty = gty; - m.geoPathAccurateTx = originalX; - m.geoPathAccurateTy = originalY; - - x = m.geoPath.get(m.onGeodataPathIndex).getX(); - y = m.geoPath.get(m.onGeodataPathIndex).getY(); - z = m.geoPath.get(m.onGeodataPathIndex).getZ(); - - // check for doors in the route - if (DoorData.getInstance().checkIfDoorsBetween(curX, curY, curZ, x, y, z, getInstanceWorld())) - { - m.geoPath = null; - getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE); - return; - } - if (WarpedSpaceManager.getInstance().checkForWarpedSpace(new Location(curX, curY, curZ), new Location(x, y, z), getInstanceWorld())) - { - m.geoPath = null; - getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE); - return; - } - for (int i = 0; i < (m.geoPath.size() - 1); i++) - { - if (DoorData.getInstance().checkIfDoorsBetween(m.geoPath.get(i), m.geoPath.get(i + 1), getInstanceWorld())) - { - m.geoPath = null; - getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE); - return; - } - if (WarpedSpaceManager.getInstance().checkForWarpedSpace(m.geoPath.get(i), m.geoPath.get(i + 1), getInstanceWorld())) - { - m.geoPath = null; - getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE); - return; - } - } - - dx = x - curX; - dy = y - curY; - dz = z - curZ; - distance = verticalMovementOnly ? Math.pow(dz, 2) : Math.hypot(dx, dy); - sin = dy / distance; - cos = dx / distance; + getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE); + return; } + + m.disregardingGeodata = true; + x = originalX; + y = originalY; + z = originalZ; + distance = originalDistance; + } + else + { + m.onGeodataPathIndex = 0; // on first segment + m.geoPathGtx = gtx; + m.geoPathGty = gty; + m.geoPathAccurateTx = originalX; + m.geoPathAccurateTy = originalY; + + x = m.geoPath.get(m.onGeodataPathIndex).getX(); + y = m.geoPath.get(m.onGeodataPathIndex).getY(); + z = m.geoPath.get(m.onGeodataPathIndex).getZ(); + + dx = x - curX; + dy = y - curY; + dz = z - curZ; + distance = verticalMovementOnly ? Math.pow(dz, 2) : Math.hypot(dx, dy); + sin = dy / distance; + cos = dx / distance; } } - // If no distance to go through, the movement is canceled - if ((distance < 1) && (Config.PATHFINDING || isPlayable() || isControlBlocked())) + if ((distance < 1) && (Config.PATHFINDING || isPlayable())) { if (isSummon()) { @@ -3746,7 +3711,7 @@ public abstract class L2Character extends L2Object implements ISkillsHolder, IDe final int ticksToMove = 1 + (int) ((GameTimeController.TICKS_PER_SECOND * distance) / speed); m._xDestination = x; m._yDestination = y; - m._zDestination = z; + m._zDestination = z; // this is what was requested from client // Calculate and set the heading of the L2Character m._heading = 0; // initial value for coordinate sync diff --git a/L2J_Mobius_Helios/java/com/l2jmobius/gameserver/model/actor/instance/L2AirShipInstance.java b/L2J_Mobius_Helios/java/com/l2jmobius/gameserver/model/actor/instance/L2AirShipInstance.java index b4d574c40c..b253f13a62 100644 --- a/L2J_Mobius_Helios/java/com/l2jmobius/gameserver/model/actor/instance/L2AirShipInstance.java +++ b/L2J_Mobius_Helios/java/com/l2jmobius/gameserver/model/actor/instance/L2AirShipInstance.java @@ -133,6 +133,7 @@ public class L2AirShipInstance extends L2Vehicle player.broadcastPacket(new ExGetOnAirShip(player, this)); player.setXYZ(getX(), getY(), getZ()); player.revalidateZone(true); + player.stopMove(null); return true; } diff --git a/L2J_Mobius_HighFive/java/com/l2jmobius/gameserver/geoengine/GeoEnginePathfinding.java b/L2J_Mobius_HighFive/java/com/l2jmobius/gameserver/geoengine/GeoEnginePathfinding.java index 298401d71a..14c00be2a4 100644 --- a/L2J_Mobius_HighFive/java/com/l2jmobius/gameserver/geoengine/GeoEnginePathfinding.java +++ b/L2J_Mobius_HighFive/java/com/l2jmobius/gameserver/geoengine/GeoEnginePathfinding.java @@ -26,7 +26,6 @@ import com.l2jmobius.gameserver.geoengine.geodata.GeoLocation; import com.l2jmobius.gameserver.geoengine.pathfinding.Node; import com.l2jmobius.gameserver.geoengine.pathfinding.NodeBuffer; import com.l2jmobius.gameserver.model.Location; -import com.l2jmobius.gameserver.util.StringUtil; /** * @author Hasha @@ -211,7 +210,7 @@ final class GeoEnginePathfinding extends GeoEngine } /** - * Provides optimize selection of the buffer. When all pre-initialized buffer are locked, creates new buffer and log this situation. + * Provides optimize selection of the buffer. When all pre-initialized buffer are locked, creates new buffer. * @param size : pre-calculated minimal required size * @param playable : moving object is playable? * @return NodeBuffer : buffer @@ -235,25 +234,12 @@ final class GeoEnginePathfinding extends GeoEngine continue; } - holder._uses++; - if (playable) - { - holder._playableUses++; - } - - holder._elapsed += buffer.getElapsedTime(); return buffer; } // NodeBuffer not found, allocate temporary buffer current = new NodeBuffer(holder._size); current.isLocked(); - - holder._overflows++; - if (playable) - { - holder._playableOverflows++; - } } return current; @@ -265,20 +251,11 @@ final class GeoEnginePathfinding extends GeoEngine private static final class BufferHolder { final int _size; - final int _count; - ArrayList _buffer; - - // statistics - int _playableUses = 0; - int _uses = 0; - int _playableOverflows = 0; - int _overflows = 0; - long _elapsed = 0; + List _buffer; public BufferHolder(int size, int count) { _size = size; - _count = count; _buffer = new ArrayList<>(count); for (int i = 0; i < count; i++) @@ -286,22 +263,5 @@ final class GeoEnginePathfinding extends GeoEngine _buffer.add(new NodeBuffer(size)); } } - - @Override - public String toString() - { - final StringBuilder sb = new StringBuilder(100); - - StringUtil.append(sb, "Buffer ", String.valueOf(_size), "x", String.valueOf(_size), ": count=", String.valueOf(_count), " uses=", String.valueOf(_playableUses), "/", String.valueOf(_uses)); - - if (_uses > 0) - { - StringUtil.append(sb, " total/avg(ms)=", String.valueOf(_elapsed), "/", String.format("%1.2f", (double) _elapsed / _uses)); - } - - StringUtil.append(sb, " ovf=", String.valueOf(_playableOverflows), "/", String.valueOf(_overflows)); - - return sb.toString(); - } } } \ No newline at end of file diff --git a/L2J_Mobius_HighFive/java/com/l2jmobius/gameserver/model/actor/L2Character.java b/L2J_Mobius_HighFive/java/com/l2jmobius/gameserver/model/actor/L2Character.java index 966ddb04a2..d66dd8ccad 100644 --- a/L2J_Mobius_HighFive/java/com/l2jmobius/gameserver/model/actor/L2Character.java +++ b/L2J_Mobius_HighFive/java/com/l2jmobius/gameserver/model/actor/L2Character.java @@ -42,7 +42,6 @@ import com.l2jmobius.gameserver.ai.CtrlIntention; import com.l2jmobius.gameserver.ai.L2AttackableAI; import com.l2jmobius.gameserver.ai.L2CharacterAI; import com.l2jmobius.gameserver.data.xml.impl.CategoryData; -import com.l2jmobius.gameserver.data.xml.impl.DoorData; import com.l2jmobius.gameserver.datatables.ItemTable; import com.l2jmobius.gameserver.enums.CategoryType; import com.l2jmobius.gameserver.enums.InstanceType; @@ -4373,7 +4372,8 @@ public abstract class L2Character extends L2Object implements ISkillsHolder, IDe m.disregardingGeodata = false; if (!isFlying() // flying chars not checked - even canSeeTarget doesn't work yet - && (!isInsideZone(ZoneId.WATER) || isInsideZone(ZoneId.SIEGE))) // swimming also not checked unless in siege zone - but distance is limited + && (!isInsideZone(ZoneId.WATER) || isInsideZone(ZoneId.SIEGE)) // swimming also not checked unless in siege zone - but distance is limited + && !isWalker() && !isVehicle()) { final boolean isInVehicle = isPlayer() && (getActingPlayer().getVehicle() != null); if (isInVehicle) @@ -4429,8 +4429,8 @@ public abstract class L2Character extends L2Object implements ISkillsHolder, IDe } return; } - final Location destiny = GeoEngine.getInstance().canMoveToTargetLoc(curX, curY, curZ, x, y, z, getInstanceId()); // location different if destination wasn't reached (or just z coord is different) + final Location destiny = GeoEngine.getInstance().canMoveToTargetLoc(curX, curY, curZ, x, y, z, getInstanceId()); x = destiny.getX(); y = destiny.getY(); z = destiny.getZ(); @@ -4442,70 +4442,50 @@ public abstract class L2Character extends L2Object implements ISkillsHolder, IDe // Pathfinding checks. Only when geodata setting is 2, the LoS check gives shorter result // than the original movement was and the LoS gives a shorter distance than 2000 // This way of detecting need for pathfinding could be changed. - if (Config.PATHFINDING && ((originalDistance - distance) > 30) && (distance < 2000)) + if (Config.PATHFINDING && ((originalDistance - distance) > 30)) { // Path calculation // Overrides previous movement check - if ((isPlayable() && !isInVehicle) || isMinion() || isInCombat()) + m.geoPath = GeoEngine.getInstance().findPath(curX, curY, curZ, originalX, originalY, originalZ, getInstanceId(), isPlayable()); + if ((m.geoPath == null) || (m.geoPath.size() < 2)) // No path found { - m.geoPath = GeoEngine.getInstance().findPath(curX, curY, curZ, originalX, originalY, originalZ, getInstanceId(), isPlayable()); - if ((m.geoPath == null) || (m.geoPath.size() < 2)) // No path found + // Even though there's no path found (remember geonodes aren't perfect), + // the mob is attacking and right now we set it so that the mob will go + // after target anyway, is dz is small enough. + // With cellpathfinding this approach could be changed but would require taking + // off the geonodes and some more checks. + // Summons will follow their masters no matter what. + // Currently minions also must move freely since L2AttackableAI commands them to move along with their leader + if (isPlayer() || (!isPlayable() && !isMinion() && (Math.abs(z - curZ) > 140)) || (isSummon() && !((L2Summon) this).getFollowStatus())) { - // Even though there's no path found (remember geonodes aren't perfect), - // the mob is attacking and right now we set it so that the mob will go - // after target anyway, is dz is small enough. - // With cellpathfinding this approach could be changed but would require taking - // off the geonodes and some more checks. - // Summons will follow their masters no matter what. - // Currently minions also must move freely since L2AttackableAI commands them to move along with their leader - if (isPlayer() || (!isPlayable() && !isMinion() && (Math.abs(z - curZ) > 140)) || (isSummon() && !((L2Summon) this).getFollowStatus())) - { - getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE); - return; - } - - m.disregardingGeodata = true; - x = originalX; - y = originalY; - z = originalZ; - distance = originalDistance; - } - else - { - m.onGeodataPathIndex = 0; // on first segment - m.geoPathGtx = gtx; - m.geoPathGty = gty; - m.geoPathAccurateTx = originalX; - m.geoPathAccurateTy = originalY; - - x = m.geoPath.get(m.onGeodataPathIndex).getX(); - y = m.geoPath.get(m.onGeodataPathIndex).getY(); - z = m.geoPath.get(m.onGeodataPathIndex).getZ(); - - // check for doors in the route - if (DoorData.getInstance().checkIfDoorsBetween(curX, curY, curZ, x, y, z, getInstanceId())) - { - m.geoPath = null; - getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE); - return; - } - for (int i = 0; i < (m.geoPath.size() - 1); i++) - { - if (DoorData.getInstance().checkIfDoorsBetween(m.geoPath.get(i), m.geoPath.get(i + 1), getInstanceId())) - { - m.geoPath = null; - getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE); - return; - } - } - - dx = x - curX; - dy = y - curY; - dz = z - curZ; - distance = verticalMovementOnly ? Math.pow(dz, 2) : Math.hypot(dx, dy); - sin = dy / distance; - cos = dx / distance; + getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE); + return; } + + m.disregardingGeodata = true; + x = originalX; + y = originalY; + z = originalZ; + distance = originalDistance; + } + else + { + m.onGeodataPathIndex = 0; // on first segment + m.geoPathGtx = gtx; + m.geoPathGty = gty; + m.geoPathAccurateTx = originalX; + m.geoPathAccurateTy = originalY; + + x = m.geoPath.get(m.onGeodataPathIndex).getX(); + y = m.geoPath.get(m.onGeodataPathIndex).getY(); + z = m.geoPath.get(m.onGeodataPathIndex).getZ(); + + dx = x - curX; + dy = y - curY; + dz = z - curZ; + distance = verticalMovementOnly ? Math.pow(dz, 2) : Math.hypot(dx, dy); + sin = dy / distance; + cos = dx / distance; } } // If no distance to go through, the movement is canceled diff --git a/L2J_Mobius_HighFive/java/com/l2jmobius/gameserver/model/actor/instance/L2AirShipInstance.java b/L2J_Mobius_HighFive/java/com/l2jmobius/gameserver/model/actor/instance/L2AirShipInstance.java index 54ba6b6d90..051e1f9e82 100644 --- a/L2J_Mobius_HighFive/java/com/l2jmobius/gameserver/model/actor/instance/L2AirShipInstance.java +++ b/L2J_Mobius_HighFive/java/com/l2jmobius/gameserver/model/actor/instance/L2AirShipInstance.java @@ -134,6 +134,7 @@ public class L2AirShipInstance extends L2Vehicle player.getKnownList().removeAllKnownObjects(); player.setXYZ(getX(), getY(), getZ()); player.revalidateZone(true); + player.stopMove(null); return true; } diff --git a/L2J_Mobius_Underground/java/com/l2jmobius/gameserver/geoengine/GeoEnginePathfinding.java b/L2J_Mobius_Underground/java/com/l2jmobius/gameserver/geoengine/GeoEnginePathfinding.java index b9def83228..5447dcc767 100644 --- a/L2J_Mobius_Underground/java/com/l2jmobius/gameserver/geoengine/GeoEnginePathfinding.java +++ b/L2J_Mobius_Underground/java/com/l2jmobius/gameserver/geoengine/GeoEnginePathfinding.java @@ -22,7 +22,6 @@ import java.util.List; import java.util.ListIterator; import com.l2jmobius.Config; -import com.l2jmobius.commons.util.StringUtil; import com.l2jmobius.gameserver.geoengine.geodata.GeoLocation; import com.l2jmobius.gameserver.geoengine.pathfinding.Node; import com.l2jmobius.gameserver.geoengine.pathfinding.NodeBuffer; @@ -212,7 +211,7 @@ final class GeoEnginePathfinding extends GeoEngine } /** - * Provides optimize selection of the buffer. When all pre-initialized buffer are locked, creates new buffer and log this situation. + * Provides optimize selection of the buffer. When all pre-initialized buffer are locked, creates new buffer. * @param size : pre-calculated minimal required size * @param playable : moving object is playable? * @return NodeBuffer : buffer @@ -236,25 +235,12 @@ final class GeoEnginePathfinding extends GeoEngine continue; } - holder._uses++; - if (playable) - { - holder._playableUses++; - } - - holder._elapsed += buffer.getElapsedTime(); return buffer; } // NodeBuffer not found, allocate temporary buffer current = new NodeBuffer(holder._size); current.isLocked(); - - holder._overflows++; - if (playable) - { - holder._playableOverflows++; - } } return current; @@ -266,20 +252,11 @@ final class GeoEnginePathfinding extends GeoEngine private static final class BufferHolder { final int _size; - final int _count; - ArrayList _buffer; - - // statistics - int _playableUses = 0; - int _uses = 0; - int _playableOverflows = 0; - int _overflows = 0; - long _elapsed = 0; + List _buffer; public BufferHolder(int size, int count) { _size = size; - _count = count; _buffer = new ArrayList<>(count); for (int i = 0; i < count; i++) @@ -287,22 +264,5 @@ final class GeoEnginePathfinding extends GeoEngine _buffer.add(new NodeBuffer(size)); } } - - @Override - public String toString() - { - final StringBuilder sb = new StringBuilder(100); - - StringUtil.append(sb, "Buffer ", String.valueOf(_size), "x", String.valueOf(_size), ": count=", String.valueOf(_count), " uses=", String.valueOf(_playableUses), "/", String.valueOf(_uses)); - - if (_uses > 0) - { - StringUtil.append(sb, " total/avg(ms)=", String.valueOf(_elapsed), "/", String.format("%1.2f", (double) _elapsed / _uses)); - } - - StringUtil.append(sb, " ovf=", String.valueOf(_playableOverflows), "/", String.valueOf(_overflows)); - - return sb.toString(); - } } } \ No newline at end of file diff --git a/L2J_Mobius_Underground/java/com/l2jmobius/gameserver/model/actor/L2Character.java b/L2J_Mobius_Underground/java/com/l2jmobius/gameserver/model/actor/L2Character.java index 8d4e253ccc..1ea1c674fb 100644 --- a/L2J_Mobius_Underground/java/com/l2jmobius/gameserver/model/actor/L2Character.java +++ b/L2J_Mobius_Underground/java/com/l2jmobius/gameserver/model/actor/L2Character.java @@ -51,7 +51,6 @@ import com.l2jmobius.gameserver.ai.CtrlIntention; import com.l2jmobius.gameserver.ai.L2AttackableAI; import com.l2jmobius.gameserver.ai.L2CharacterAI; import com.l2jmobius.gameserver.data.xml.impl.CategoryData; -import com.l2jmobius.gameserver.data.xml.impl.DoorData; import com.l2jmobius.gameserver.data.xml.impl.TransformData; import com.l2jmobius.gameserver.enums.AttributeType; import com.l2jmobius.gameserver.enums.BasicProperty; @@ -67,7 +66,6 @@ import com.l2jmobius.gameserver.geoengine.GeoEngine; import com.l2jmobius.gameserver.idfactory.IdFactory; import com.l2jmobius.gameserver.instancemanager.MapRegionManager; import com.l2jmobius.gameserver.instancemanager.TimersManager; -import com.l2jmobius.gameserver.instancemanager.WarpedSpaceManager; import com.l2jmobius.gameserver.instancemanager.ZoneManager; import com.l2jmobius.gameserver.model.CharEffectList; import com.l2jmobius.gameserver.model.CreatureContainer; @@ -3579,7 +3577,7 @@ public abstract class L2Character extends L2Object implements ISkillsHolder, IDe m.onGeodataPathIndex = -1; // Initialize not on geodata path m.disregardingGeodata = false; - if (!isFlying() && !isInsideZone(ZoneId.WATER) && !isWalker()) + if (!isFlying() && !isInsideZone(ZoneId.WATER) && !isWalker() && !isVehicle()) { final boolean isInVehicle = isPlayer() && (getActingPlayer().getVehicle() != null); if (isInVehicle) @@ -3598,7 +3596,7 @@ public abstract class L2Character extends L2Object implements ISkillsHolder, IDe // when geodata == 2, for all characters except mobs returning home (could be changed later to teleport if pathfinding fails) // when geodata == 1, for l2playableinstance // assuming intention_follow only when following owner - if ((Config.PATHFINDING && !(isAttackable() && ((L2Attackable) this).isReturningToSpawnPoint())) || (isPlayer() && !(isInVehicle && (distance > 1500))) || (isSummon() && !(getAI().getIntention() == CtrlIntention.AI_INTENTION_FOLLOW))) + if (Config.PATHFINDING && (!(isAttackable() && ((L2Attackable) this).isReturningToSpawnPoint()) || (isSummon() && !(getAI().getIntention() == CtrlIntention.AI_INTENTION_FOLLOW)))) { if (isOnGeodataPath()) { @@ -3636,7 +3634,7 @@ public abstract class L2Character extends L2Object implements ISkillsHolder, IDe return; } // location different if destination wasn't reached (or just z coord is different) - Location destiny = GeoEngine.getInstance().canMoveToTargetLoc(curX, curY, curZ, x, y, z, getInstanceWorld()); + final Location destiny = GeoEngine.getInstance().canMoveToTargetLoc(curX, curY, curZ, x, y, z, getInstanceWorld()); x = destiny.getX(); y = destiny.getY(); z = destiny.getZ(); @@ -3647,84 +3645,51 @@ public abstract class L2Character extends L2Object implements ISkillsHolder, IDe } // Pathfinding checks. Only when geodata setting is 2, the LoS check gives shorter result than the original movement was and the LoS gives a shorter distance than 2000 // This way of detecting need for pathfinding could be changed. - if (Config.PATHFINDING && ((originalDistance - distance) > 30) && (distance < 2000) && !isControlBlocked() && !isInVehicle) + if (Config.PATHFINDING && ((originalDistance - distance) > 30) && !isControlBlocked() && !isInVehicle) { // Path calculation -- overrides previous movement check - if (isPlayable() || isMinion() || isInCombat()) + m.geoPath = GeoEngine.getInstance().findPath(curX, curY, curZ, originalX, originalY, originalZ, getInstanceWorld(), isPlayable()); + if ((m.geoPath == null) || (m.geoPath.size() < 2)) { - m.geoPath = GeoEngine.getInstance().findPath(curX, curY, curZ, originalX, originalY, originalZ, getInstanceWorld(), isPlayable()); - if ((m.geoPath == null) || (m.geoPath.size() < 2)) + // No path found + // Even though there's no path found (remember geonodes aren't perfect), the mob is attacking and right now we set it so that the mob will go after target anyway, is dz is small enough. + // With cellpathfinding this approach could be changed but would require taking off the geonodes and some more checks. + // Summons will follow their masters no matter what. + // Currently minions also must move freely since L2AttackableAI commands them to move along with their leader + if (isPlayer() || (!isPlayable() && !isMinion() && (Math.abs(z - curZ) > 140)) || (isSummon() && !((L2Summon) this).getFollowStatus())) { - // No path found - // Even though there's no path found (remember geonodes aren't perfect), the mob is attacking and right now we set it so that the mob will go after target anyway, is dz is small enough. - // With cellpathfinding this approach could be changed but would require taking off the geonodes and some more checks. - // Summons will follow their masters no matter what. - // Currently minions also must move freely since L2AttackableAI commands them to move along with their leader - if (isPlayer() || (!isPlayable() && !isMinion() && (Math.abs(z - curZ) > 140)) || (isSummon() && !((L2Summon) this).getFollowStatus())) - { - getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE); - return; - } - - m.disregardingGeodata = true; - x = originalX; - y = originalY; - z = originalZ; - distance = originalDistance; - } - else - { - m.onGeodataPathIndex = 0; // on first segment - m.geoPathGtx = gtx; - m.geoPathGty = gty; - m.geoPathAccurateTx = originalX; - m.geoPathAccurateTy = originalY; - - x = m.geoPath.get(m.onGeodataPathIndex).getX(); - y = m.geoPath.get(m.onGeodataPathIndex).getY(); - z = m.geoPath.get(m.onGeodataPathIndex).getZ(); - - // check for doors in the route - if (DoorData.getInstance().checkIfDoorsBetween(curX, curY, curZ, x, y, z, getInstanceWorld())) - { - m.geoPath = null; - getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE); - return; - } - if (WarpedSpaceManager.getInstance().checkForWarpedSpace(new Location(curX, curY, curZ), new Location(x, y, z), getInstanceWorld())) - { - m.geoPath = null; - getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE); - return; - } - for (int i = 0; i < (m.geoPath.size() - 1); i++) - { - if (DoorData.getInstance().checkIfDoorsBetween(m.geoPath.get(i), m.geoPath.get(i + 1), getInstanceWorld())) - { - m.geoPath = null; - getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE); - return; - } - if (WarpedSpaceManager.getInstance().checkForWarpedSpace(m.geoPath.get(i), m.geoPath.get(i + 1), getInstanceWorld())) - { - m.geoPath = null; - getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE); - return; - } - } - - dx = x - curX; - dy = y - curY; - dz = z - curZ; - distance = verticalMovementOnly ? Math.pow(dz, 2) : Math.hypot(dx, dy); - sin = dy / distance; - cos = dx / distance; + getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE); + return; } + + m.disregardingGeodata = true; + x = originalX; + y = originalY; + z = originalZ; + distance = originalDistance; + } + else + { + m.onGeodataPathIndex = 0; // on first segment + m.geoPathGtx = gtx; + m.geoPathGty = gty; + m.geoPathAccurateTx = originalX; + m.geoPathAccurateTy = originalY; + + x = m.geoPath.get(m.onGeodataPathIndex).getX(); + y = m.geoPath.get(m.onGeodataPathIndex).getY(); + z = m.geoPath.get(m.onGeodataPathIndex).getZ(); + + dx = x - curX; + dy = y - curY; + dz = z - curZ; + distance = verticalMovementOnly ? Math.pow(dz, 2) : Math.hypot(dx, dy); + sin = dy / distance; + cos = dx / distance; } } - // If no distance to go through, the movement is canceled - if ((distance < 1) && (Config.PATHFINDING || isPlayable() || isControlBlocked())) + if ((distance < 1) && (Config.PATHFINDING || isPlayable())) { if (isSummon()) { @@ -3746,7 +3711,7 @@ public abstract class L2Character extends L2Object implements ISkillsHolder, IDe final int ticksToMove = 1 + (int) ((GameTimeController.TICKS_PER_SECOND * distance) / speed); m._xDestination = x; m._yDestination = y; - m._zDestination = z; + m._zDestination = z; // this is what was requested from client // Calculate and set the heading of the L2Character m._heading = 0; // initial value for coordinate sync diff --git a/L2J_Mobius_Underground/java/com/l2jmobius/gameserver/model/actor/instance/L2AirShipInstance.java b/L2J_Mobius_Underground/java/com/l2jmobius/gameserver/model/actor/instance/L2AirShipInstance.java index b4d574c40c..b253f13a62 100644 --- a/L2J_Mobius_Underground/java/com/l2jmobius/gameserver/model/actor/instance/L2AirShipInstance.java +++ b/L2J_Mobius_Underground/java/com/l2jmobius/gameserver/model/actor/instance/L2AirShipInstance.java @@ -133,6 +133,7 @@ public class L2AirShipInstance extends L2Vehicle player.broadcastPacket(new ExGetOnAirShip(player, this)); player.setXYZ(getX(), getY(), getZ()); player.revalidateZone(true); + player.stopMove(null); return true; }