From a8c77b8795d7957cefc2501948473c871c9b9399 Mon Sep 17 00:00:00 2001 From: MobiusDevelopment <8391001+MobiusDevelopment@users.noreply.github.com> Date: Sun, 14 Mar 2021 22:03:28 +0000 Subject: [PATCH] Store fence objects in regions. --- .../gameserver/data/xml/FenceData.java | 42 ++++++-------- .../gameserver/model/WorldObject.java | 9 +++ .../gameserver/model/WorldRegion.java | 37 ++++++++++++- .../model/actor/instance/FenceInstance.java | 6 ++ .../gameserver/data/xml/FenceData.java | 42 ++++++-------- .../gameserver/model/WorldObject.java | 9 +++ .../gameserver/model/WorldRegion.java | 37 ++++++++++++- .../model/actor/instance/FenceInstance.java | 6 ++ .../gameserver/data/xml/FenceData.java | 42 ++++++-------- .../gameserver/model/WorldObject.java | 9 +++ .../gameserver/model/WorldRegion.java | 37 ++++++++++++- .../model/actor/instance/FenceInstance.java | 6 ++ .../gameserver/data/xml/FenceData.java | 42 ++++++-------- .../gameserver/model/WorldObject.java | 9 +++ .../gameserver/model/WorldRegion.java | 37 ++++++++++++- .../model/actor/instance/FenceInstance.java | 6 ++ .../gameserver/data/xml/FenceData.java | 42 ++++++-------- .../gameserver/model/WorldObject.java | 9 +++ .../gameserver/model/WorldRegion.java | 37 ++++++++++++- .../model/actor/instance/FenceInstance.java | 6 ++ .../gameserver/data/xml/FenceData.java | 42 ++++++-------- .../gameserver/model/WorldObject.java | 9 +++ .../gameserver/model/WorldRegion.java | 37 ++++++++++++- .../model/actor/instance/FenceInstance.java | 6 ++ .../gameserver/data/xml/FenceData.java | 42 ++++++-------- .../gameserver/model/WorldObject.java | 9 +++ .../gameserver/model/WorldRegion.java | 37 ++++++++++++- .../model/actor/instance/FenceInstance.java | 6 ++ .../gameserver/data/xml/FenceData.java | 42 ++++++-------- .../gameserver/model/WorldObject.java | 9 +++ .../gameserver/model/WorldRegion.java | 37 ++++++++++++- .../model/actor/instance/FenceInstance.java | 6 ++ .../gameserver/data/xml/FenceData.java | 42 ++++++-------- .../gameserver/model/WorldObject.java | 9 +++ .../gameserver/model/WorldRegion.java | 37 ++++++++++++- .../model/actor/instance/FenceInstance.java | 6 ++ .../gameserver/data/xml/FenceData.java | 42 ++++++-------- .../gameserver/model/WorldObject.java | 9 +++ .../gameserver/model/WorldRegion.java | 37 ++++++++++++- .../model/actor/instance/FenceInstance.java | 6 ++ .../gameserver/data/xml/FenceData.java | 55 +++++++------------ .../gameserver/model/WorldObject.java | 5 ++ .../gameserver/model/WorldRegion.java | 45 ++++++++++++--- .../model/actor/instance/FenceInstance.java | 6 ++ .../gameserver/data/xml/FenceData.java | 55 +++++++------------ .../gameserver/model/WorldObject.java | 5 ++ .../gameserver/model/WorldRegion.java | 45 ++++++++++++--- .../model/actor/instance/FenceInstance.java | 6 ++ .../gameserver/data/xml/FenceData.java | 55 +++++++------------ .../gameserver/model/WorldObject.java | 9 +++ .../gameserver/model/WorldRegion.java | 37 ++++++++++++- .../model/actor/instance/FenceInstance.java | 6 ++ .../gameserver/data/xml/FenceData.java | 55 +++++++------------ .../gameserver/model/WorldObject.java | 9 +++ .../gameserver/model/WorldRegion.java | 37 ++++++++++++- .../model/actor/instance/FenceInstance.java | 6 ++ .../gameserver/data/xml/FenceData.java | 42 ++++++-------- .../gameserver/model/WorldObject.java | 9 +++ .../gameserver/model/WorldRegion.java | 37 ++++++++++++- .../model/actor/instance/FenceInstance.java | 6 ++ .../gameserver/data/xml/FenceData.java | 42 ++++++-------- .../gameserver/model/WorldObject.java | 9 +++ .../gameserver/model/WorldRegion.java | 37 ++++++++++++- .../model/actor/instance/FenceInstance.java | 6 ++ .../gameserver/data/xml/FenceData.java | 42 ++++++-------- .../gameserver/model/WorldObject.java | 9 +++ .../gameserver/model/WorldRegion.java | 37 ++++++++++++- .../model/actor/instance/FenceInstance.java | 6 ++ .../gameserver/data/xml/FenceData.java | 42 ++++++-------- .../gameserver/model/WorldObject.java | 9 +++ .../gameserver/model/WorldRegion.java | 37 ++++++++++++- .../model/actor/instance/FenceInstance.java | 6 ++ .../gameserver/data/xml/FenceData.java | 42 ++++++-------- .../gameserver/model/WorldObject.java | 9 +++ .../gameserver/model/WorldRegion.java | 37 ++++++++++++- .../model/actor/instance/FenceInstance.java | 6 ++ .../gameserver/data/xml/FenceData.java | 42 ++++++-------- .../gameserver/model/WorldObject.java | 9 +++ .../gameserver/model/WorldRegion.java | 37 ++++++++++++- .../model/actor/instance/FenceInstance.java | 6 ++ .../gameserver/data/xml/FenceData.java | 42 ++++++-------- .../gameserver/model/WorldObject.java | 9 +++ .../gameserver/model/WorldRegion.java | 37 ++++++++++++- .../model/actor/instance/FenceInstance.java | 6 ++ .../gameserver/data/xml/FenceData.java | 42 ++++++-------- .../gameserver/model/WorldObject.java | 9 +++ .../gameserver/model/WorldRegion.java | 37 ++++++++++++- .../model/actor/instance/FenceInstance.java | 6 ++ .../gameserver/data/xml/FenceData.java | 42 ++++++-------- .../gameserver/model/WorldObject.java | 9 +++ .../gameserver/model/WorldRegion.java | 37 ++++++++++++- .../model/actor/instance/FenceInstance.java | 6 ++ 92 files changed, 1570 insertions(+), 652 deletions(-) diff --git a/L2J_Mobius_1.0_Ertheia/java/org/l2jmobius/gameserver/data/xml/FenceData.java b/L2J_Mobius_1.0_Ertheia/java/org/l2jmobius/gameserver/data/xml/FenceData.java index 10b68e2f34..cc647ecea2 100644 --- a/L2J_Mobius_1.0_Ertheia/java/org/l2jmobius/gameserver/data/xml/FenceData.java +++ b/L2J_Mobius_1.0_Ertheia/java/org/l2jmobius/gameserver/data/xml/FenceData.java @@ -17,12 +17,9 @@ package org.l2jmobius.gameserver.data.xml; import java.io.File; -import java.util.ArrayList; -import java.util.Collections; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; -import java.util.function.Predicate; import java.util.logging.Logger; import org.w3c.dom.Document; @@ -45,7 +42,6 @@ public class FenceData implements IXmlReader private static final int MAX_Z_DIFF = 100; - private final Map> _regions = new ConcurrentHashMap<>(); private final Map _fences = new ConcurrentHashMap<>(); protected FenceData() @@ -104,18 +100,11 @@ public class FenceData implements IXmlReader private void addFence(FenceInstance fence) { _fences.put(fence.getObjectId(), fence); - _regions.computeIfAbsent(World.getInstance().getRegion(fence), key -> new ArrayList<>()).add(fence); } public void removeFence(FenceInstance fence) { _fences.remove(fence.getObjectId()); - - final List fencesInRegion = _regions.get(World.getInstance().getRegion(fence)); - if (fencesInRegion != null) - { - fencesInRegion.remove(fence); - } } public Map getFences() @@ -130,19 +119,26 @@ public class FenceData implements IXmlReader public boolean checkIfFenceBetween(int x, int y, int z, int tx, int ty, int tz, Instance instance) { - final Predicate filter = fence -> + final WorldRegion region = World.getInstance().getRegion(x, y); + final List fences = region != null ? region.getFences() : null; + if ((fences == null) || fences.isEmpty()) + { + return false; + } + + for (FenceInstance fence : fences) { // Check if fence is geodata enabled. if (!fence.getState().isGeodataEnabled()) { - return false; + continue; } // Check if fence is within the instance we search for. final int instanceId = (instance == null) ? 0 : instance.getId(); if (fence.getInstanceId() != instanceId) { - return false; + continue; } final int xMin = fence.getXMin(); @@ -151,34 +147,30 @@ public class FenceData implements IXmlReader final int yMax = fence.getYMax(); if ((x < xMin) && (tx < xMin)) { - return false; + continue; } if ((x > xMax) && (tx > xMax)) { - return false; + continue; } if ((y < yMin) && (ty < yMin)) { - return false; + continue; } if ((y > yMax) && (ty > yMax)) { - return false; + continue; } if ((x > xMin) && (tx > xMin) && (x < xMax) && (tx < xMax) && (y > yMin) && (ty > yMin) && (y < yMax) && (ty < yMax)) { - return false; + continue; } if ((crossLinePart(xMin, yMin, xMax, yMin, x, y, tx, ty, xMin, yMin, xMax, yMax) || crossLinePart(xMax, yMin, xMax, yMax, x, y, tx, ty, xMin, yMin, xMax, yMax) || crossLinePart(xMax, yMax, xMin, yMax, x, y, tx, ty, xMin, yMin, xMax, yMax) || crossLinePart(xMin, yMax, xMin, yMin, x, y, tx, ty, xMin, yMin, xMax, yMax)) && (z > (fence.getZ() - MAX_Z_DIFF)) && (z < (fence.getZ() + MAX_Z_DIFF))) { return true; } - - return false; - }; - - final WorldRegion region = World.getInstance().getRegion(x, y); // Should never be null. - return (region != null) && _regions.getOrDefault(region, Collections.emptyList()).stream().anyMatch(filter); + } + return false; } private boolean crossLinePart(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4, double xMin, double yMin, double xMax, double yMax) diff --git a/L2J_Mobius_1.0_Ertheia/java/org/l2jmobius/gameserver/model/WorldObject.java b/L2J_Mobius_1.0_Ertheia/java/org/l2jmobius/gameserver/model/WorldObject.java index b1292dd3d4..0e5536bbc0 100644 --- a/L2J_Mobius_1.0_Ertheia/java/org/l2jmobius/gameserver/model/WorldObject.java +++ b/L2J_Mobius_1.0_Ertheia/java/org/l2jmobius/gameserver/model/WorldObject.java @@ -412,6 +412,15 @@ public abstract class WorldObject extends ListenersContainer implements IIdentif return false; } + /** + * Verifies if this object is a fence. + * @return {@code true} if object is Fence, {@code false} otherwise + */ + public boolean isFence() + { + return false; + } + public void setTargetable(boolean targetable) { if (_isTargetable != targetable) diff --git a/L2J_Mobius_1.0_Ertheia/java/org/l2jmobius/gameserver/model/WorldRegion.java b/L2J_Mobius_1.0_Ertheia/java/org/l2jmobius/gameserver/model/WorldRegion.java index 8ad2649d3e..787947f2d7 100644 --- a/L2J_Mobius_1.0_Ertheia/java/org/l2jmobius/gameserver/model/WorldRegion.java +++ b/L2J_Mobius_1.0_Ertheia/java/org/l2jmobius/gameserver/model/WorldRegion.java @@ -25,6 +25,7 @@ import org.l2jmobius.commons.concurrent.ThreadPool; import org.l2jmobius.gameserver.model.actor.Attackable; import org.l2jmobius.gameserver.model.actor.Npc; import org.l2jmobius.gameserver.model.actor.instance.DoorInstance; +import org.l2jmobius.gameserver.model.actor.instance.FenceInstance; import org.l2jmobius.gameserver.taskmanager.RandomAnimationTaskManager; import org.l2jmobius.gameserver.util.UnboundArrayList; @@ -34,6 +35,8 @@ public class WorldRegion private final UnboundArrayList _visibleObjects = new UnboundArrayList<>(); /** List containing doors in this world region. */ private final List _doors = new ArrayList<>(1); + /** List containing fences in this world region. */ + private final List _fences = new ArrayList<>(1); /** Array containing nearby regions forming this world region's effective area. */ private WorldRegion[] _surroundingRegions; private final int _regionX; @@ -241,6 +244,13 @@ public class WorldRegion _surroundingRegions[i].addDoor((DoorInstance) object); } } + else if (object.isFence()) + { + for (int i = 0; i < _surroundingRegions.length; i++) + { + _surroundingRegions[i].addFence((FenceInstance) object); + } + } // If this is the first player to enter the region, activate self and neighbors. if (object.isPlayable() && !_active && !Config.GRIDS_ALWAYS_ON) @@ -271,7 +281,14 @@ public class WorldRegion { for (int i = 0; i < _surroundingRegions.length; i++) { - removeDoor((DoorInstance) object); + _surroundingRegions[i].removeDoor((DoorInstance) object); + } + } + else if (object.isFence()) + { + for (int i = 0; i < _surroundingRegions.length; i++) + { + _surroundingRegions[i].removeFence((FenceInstance) object); } } @@ -304,6 +321,24 @@ public class WorldRegion return _doors; } + public synchronized void addFence(FenceInstance fence) + { + if (!_fences.contains(fence)) + { + _fences.add(fence); + } + } + + private synchronized void removeFence(FenceInstance fence) + { + _fences.remove(fence); + } + + public List getFences() + { + return _fences; + } + public void setSurroundingRegions(WorldRegion[] regions) { _surroundingRegions = regions; diff --git a/L2J_Mobius_1.0_Ertheia/java/org/l2jmobius/gameserver/model/actor/instance/FenceInstance.java b/L2J_Mobius_1.0_Ertheia/java/org/l2jmobius/gameserver/model/actor/instance/FenceInstance.java index e933cff384..821a64b0f6 100644 --- a/L2J_Mobius_1.0_Ertheia/java/org/l2jmobius/gameserver/model/actor/instance/FenceInstance.java +++ b/L2J_Mobius_1.0_Ertheia/java/org/l2jmobius/gameserver/model/actor/instance/FenceInstance.java @@ -160,4 +160,10 @@ public class FenceInstance extends WorldObject { return _yMax; } + + @Override + public boolean isFence() + { + return true; + } } \ No newline at end of file diff --git a/L2J_Mobius_2.5_Underground/java/org/l2jmobius/gameserver/data/xml/FenceData.java b/L2J_Mobius_2.5_Underground/java/org/l2jmobius/gameserver/data/xml/FenceData.java index 10b68e2f34..cc647ecea2 100644 --- a/L2J_Mobius_2.5_Underground/java/org/l2jmobius/gameserver/data/xml/FenceData.java +++ b/L2J_Mobius_2.5_Underground/java/org/l2jmobius/gameserver/data/xml/FenceData.java @@ -17,12 +17,9 @@ package org.l2jmobius.gameserver.data.xml; import java.io.File; -import java.util.ArrayList; -import java.util.Collections; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; -import java.util.function.Predicate; import java.util.logging.Logger; import org.w3c.dom.Document; @@ -45,7 +42,6 @@ public class FenceData implements IXmlReader private static final int MAX_Z_DIFF = 100; - private final Map> _regions = new ConcurrentHashMap<>(); private final Map _fences = new ConcurrentHashMap<>(); protected FenceData() @@ -104,18 +100,11 @@ public class FenceData implements IXmlReader private void addFence(FenceInstance fence) { _fences.put(fence.getObjectId(), fence); - _regions.computeIfAbsent(World.getInstance().getRegion(fence), key -> new ArrayList<>()).add(fence); } public void removeFence(FenceInstance fence) { _fences.remove(fence.getObjectId()); - - final List fencesInRegion = _regions.get(World.getInstance().getRegion(fence)); - if (fencesInRegion != null) - { - fencesInRegion.remove(fence); - } } public Map getFences() @@ -130,19 +119,26 @@ public class FenceData implements IXmlReader public boolean checkIfFenceBetween(int x, int y, int z, int tx, int ty, int tz, Instance instance) { - final Predicate filter = fence -> + final WorldRegion region = World.getInstance().getRegion(x, y); + final List fences = region != null ? region.getFences() : null; + if ((fences == null) || fences.isEmpty()) + { + return false; + } + + for (FenceInstance fence : fences) { // Check if fence is geodata enabled. if (!fence.getState().isGeodataEnabled()) { - return false; + continue; } // Check if fence is within the instance we search for. final int instanceId = (instance == null) ? 0 : instance.getId(); if (fence.getInstanceId() != instanceId) { - return false; + continue; } final int xMin = fence.getXMin(); @@ -151,34 +147,30 @@ public class FenceData implements IXmlReader final int yMax = fence.getYMax(); if ((x < xMin) && (tx < xMin)) { - return false; + continue; } if ((x > xMax) && (tx > xMax)) { - return false; + continue; } if ((y < yMin) && (ty < yMin)) { - return false; + continue; } if ((y > yMax) && (ty > yMax)) { - return false; + continue; } if ((x > xMin) && (tx > xMin) && (x < xMax) && (tx < xMax) && (y > yMin) && (ty > yMin) && (y < yMax) && (ty < yMax)) { - return false; + continue; } if ((crossLinePart(xMin, yMin, xMax, yMin, x, y, tx, ty, xMin, yMin, xMax, yMax) || crossLinePart(xMax, yMin, xMax, yMax, x, y, tx, ty, xMin, yMin, xMax, yMax) || crossLinePart(xMax, yMax, xMin, yMax, x, y, tx, ty, xMin, yMin, xMax, yMax) || crossLinePart(xMin, yMax, xMin, yMin, x, y, tx, ty, xMin, yMin, xMax, yMax)) && (z > (fence.getZ() - MAX_Z_DIFF)) && (z < (fence.getZ() + MAX_Z_DIFF))) { return true; } - - return false; - }; - - final WorldRegion region = World.getInstance().getRegion(x, y); // Should never be null. - return (region != null) && _regions.getOrDefault(region, Collections.emptyList()).stream().anyMatch(filter); + } + return false; } private boolean crossLinePart(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4, double xMin, double yMin, double xMax, double yMax) diff --git a/L2J_Mobius_2.5_Underground/java/org/l2jmobius/gameserver/model/WorldObject.java b/L2J_Mobius_2.5_Underground/java/org/l2jmobius/gameserver/model/WorldObject.java index b1292dd3d4..0e5536bbc0 100644 --- a/L2J_Mobius_2.5_Underground/java/org/l2jmobius/gameserver/model/WorldObject.java +++ b/L2J_Mobius_2.5_Underground/java/org/l2jmobius/gameserver/model/WorldObject.java @@ -412,6 +412,15 @@ public abstract class WorldObject extends ListenersContainer implements IIdentif return false; } + /** + * Verifies if this object is a fence. + * @return {@code true} if object is Fence, {@code false} otherwise + */ + public boolean isFence() + { + return false; + } + public void setTargetable(boolean targetable) { if (_isTargetable != targetable) diff --git a/L2J_Mobius_2.5_Underground/java/org/l2jmobius/gameserver/model/WorldRegion.java b/L2J_Mobius_2.5_Underground/java/org/l2jmobius/gameserver/model/WorldRegion.java index 8ad2649d3e..787947f2d7 100644 --- a/L2J_Mobius_2.5_Underground/java/org/l2jmobius/gameserver/model/WorldRegion.java +++ b/L2J_Mobius_2.5_Underground/java/org/l2jmobius/gameserver/model/WorldRegion.java @@ -25,6 +25,7 @@ import org.l2jmobius.commons.concurrent.ThreadPool; import org.l2jmobius.gameserver.model.actor.Attackable; import org.l2jmobius.gameserver.model.actor.Npc; import org.l2jmobius.gameserver.model.actor.instance.DoorInstance; +import org.l2jmobius.gameserver.model.actor.instance.FenceInstance; import org.l2jmobius.gameserver.taskmanager.RandomAnimationTaskManager; import org.l2jmobius.gameserver.util.UnboundArrayList; @@ -34,6 +35,8 @@ public class WorldRegion private final UnboundArrayList _visibleObjects = new UnboundArrayList<>(); /** List containing doors in this world region. */ private final List _doors = new ArrayList<>(1); + /** List containing fences in this world region. */ + private final List _fences = new ArrayList<>(1); /** Array containing nearby regions forming this world region's effective area. */ private WorldRegion[] _surroundingRegions; private final int _regionX; @@ -241,6 +244,13 @@ public class WorldRegion _surroundingRegions[i].addDoor((DoorInstance) object); } } + else if (object.isFence()) + { + for (int i = 0; i < _surroundingRegions.length; i++) + { + _surroundingRegions[i].addFence((FenceInstance) object); + } + } // If this is the first player to enter the region, activate self and neighbors. if (object.isPlayable() && !_active && !Config.GRIDS_ALWAYS_ON) @@ -271,7 +281,14 @@ public class WorldRegion { for (int i = 0; i < _surroundingRegions.length; i++) { - removeDoor((DoorInstance) object); + _surroundingRegions[i].removeDoor((DoorInstance) object); + } + } + else if (object.isFence()) + { + for (int i = 0; i < _surroundingRegions.length; i++) + { + _surroundingRegions[i].removeFence((FenceInstance) object); } } @@ -304,6 +321,24 @@ public class WorldRegion return _doors; } + public synchronized void addFence(FenceInstance fence) + { + if (!_fences.contains(fence)) + { + _fences.add(fence); + } + } + + private synchronized void removeFence(FenceInstance fence) + { + _fences.remove(fence); + } + + public List getFences() + { + return _fences; + } + public void setSurroundingRegions(WorldRegion[] regions) { _surroundingRegions = regions; diff --git a/L2J_Mobius_2.5_Underground/java/org/l2jmobius/gameserver/model/actor/instance/FenceInstance.java b/L2J_Mobius_2.5_Underground/java/org/l2jmobius/gameserver/model/actor/instance/FenceInstance.java index e933cff384..821a64b0f6 100644 --- a/L2J_Mobius_2.5_Underground/java/org/l2jmobius/gameserver/model/actor/instance/FenceInstance.java +++ b/L2J_Mobius_2.5_Underground/java/org/l2jmobius/gameserver/model/actor/instance/FenceInstance.java @@ -160,4 +160,10 @@ public class FenceInstance extends WorldObject { return _yMax; } + + @Override + public boolean isFence() + { + return true; + } } \ No newline at end of file diff --git a/L2J_Mobius_3.0_Helios/java/org/l2jmobius/gameserver/data/xml/FenceData.java b/L2J_Mobius_3.0_Helios/java/org/l2jmobius/gameserver/data/xml/FenceData.java index 10b68e2f34..cc647ecea2 100644 --- a/L2J_Mobius_3.0_Helios/java/org/l2jmobius/gameserver/data/xml/FenceData.java +++ b/L2J_Mobius_3.0_Helios/java/org/l2jmobius/gameserver/data/xml/FenceData.java @@ -17,12 +17,9 @@ package org.l2jmobius.gameserver.data.xml; import java.io.File; -import java.util.ArrayList; -import java.util.Collections; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; -import java.util.function.Predicate; import java.util.logging.Logger; import org.w3c.dom.Document; @@ -45,7 +42,6 @@ public class FenceData implements IXmlReader private static final int MAX_Z_DIFF = 100; - private final Map> _regions = new ConcurrentHashMap<>(); private final Map _fences = new ConcurrentHashMap<>(); protected FenceData() @@ -104,18 +100,11 @@ public class FenceData implements IXmlReader private void addFence(FenceInstance fence) { _fences.put(fence.getObjectId(), fence); - _regions.computeIfAbsent(World.getInstance().getRegion(fence), key -> new ArrayList<>()).add(fence); } public void removeFence(FenceInstance fence) { _fences.remove(fence.getObjectId()); - - final List fencesInRegion = _regions.get(World.getInstance().getRegion(fence)); - if (fencesInRegion != null) - { - fencesInRegion.remove(fence); - } } public Map getFences() @@ -130,19 +119,26 @@ public class FenceData implements IXmlReader public boolean checkIfFenceBetween(int x, int y, int z, int tx, int ty, int tz, Instance instance) { - final Predicate filter = fence -> + final WorldRegion region = World.getInstance().getRegion(x, y); + final List fences = region != null ? region.getFences() : null; + if ((fences == null) || fences.isEmpty()) + { + return false; + } + + for (FenceInstance fence : fences) { // Check if fence is geodata enabled. if (!fence.getState().isGeodataEnabled()) { - return false; + continue; } // Check if fence is within the instance we search for. final int instanceId = (instance == null) ? 0 : instance.getId(); if (fence.getInstanceId() != instanceId) { - return false; + continue; } final int xMin = fence.getXMin(); @@ -151,34 +147,30 @@ public class FenceData implements IXmlReader final int yMax = fence.getYMax(); if ((x < xMin) && (tx < xMin)) { - return false; + continue; } if ((x > xMax) && (tx > xMax)) { - return false; + continue; } if ((y < yMin) && (ty < yMin)) { - return false; + continue; } if ((y > yMax) && (ty > yMax)) { - return false; + continue; } if ((x > xMin) && (tx > xMin) && (x < xMax) && (tx < xMax) && (y > yMin) && (ty > yMin) && (y < yMax) && (ty < yMax)) { - return false; + continue; } if ((crossLinePart(xMin, yMin, xMax, yMin, x, y, tx, ty, xMin, yMin, xMax, yMax) || crossLinePart(xMax, yMin, xMax, yMax, x, y, tx, ty, xMin, yMin, xMax, yMax) || crossLinePart(xMax, yMax, xMin, yMax, x, y, tx, ty, xMin, yMin, xMax, yMax) || crossLinePart(xMin, yMax, xMin, yMin, x, y, tx, ty, xMin, yMin, xMax, yMax)) && (z > (fence.getZ() - MAX_Z_DIFF)) && (z < (fence.getZ() + MAX_Z_DIFF))) { return true; } - - return false; - }; - - final WorldRegion region = World.getInstance().getRegion(x, y); // Should never be null. - return (region != null) && _regions.getOrDefault(region, Collections.emptyList()).stream().anyMatch(filter); + } + return false; } private boolean crossLinePart(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4, double xMin, double yMin, double xMax, double yMax) diff --git a/L2J_Mobius_3.0_Helios/java/org/l2jmobius/gameserver/model/WorldObject.java b/L2J_Mobius_3.0_Helios/java/org/l2jmobius/gameserver/model/WorldObject.java index b1292dd3d4..0e5536bbc0 100644 --- a/L2J_Mobius_3.0_Helios/java/org/l2jmobius/gameserver/model/WorldObject.java +++ b/L2J_Mobius_3.0_Helios/java/org/l2jmobius/gameserver/model/WorldObject.java @@ -412,6 +412,15 @@ public abstract class WorldObject extends ListenersContainer implements IIdentif return false; } + /** + * Verifies if this object is a fence. + * @return {@code true} if object is Fence, {@code false} otherwise + */ + public boolean isFence() + { + return false; + } + public void setTargetable(boolean targetable) { if (_isTargetable != targetable) diff --git a/L2J_Mobius_3.0_Helios/java/org/l2jmobius/gameserver/model/WorldRegion.java b/L2J_Mobius_3.0_Helios/java/org/l2jmobius/gameserver/model/WorldRegion.java index 8ad2649d3e..787947f2d7 100644 --- a/L2J_Mobius_3.0_Helios/java/org/l2jmobius/gameserver/model/WorldRegion.java +++ b/L2J_Mobius_3.0_Helios/java/org/l2jmobius/gameserver/model/WorldRegion.java @@ -25,6 +25,7 @@ import org.l2jmobius.commons.concurrent.ThreadPool; import org.l2jmobius.gameserver.model.actor.Attackable; import org.l2jmobius.gameserver.model.actor.Npc; import org.l2jmobius.gameserver.model.actor.instance.DoorInstance; +import org.l2jmobius.gameserver.model.actor.instance.FenceInstance; import org.l2jmobius.gameserver.taskmanager.RandomAnimationTaskManager; import org.l2jmobius.gameserver.util.UnboundArrayList; @@ -34,6 +35,8 @@ public class WorldRegion private final UnboundArrayList _visibleObjects = new UnboundArrayList<>(); /** List containing doors in this world region. */ private final List _doors = new ArrayList<>(1); + /** List containing fences in this world region. */ + private final List _fences = new ArrayList<>(1); /** Array containing nearby regions forming this world region's effective area. */ private WorldRegion[] _surroundingRegions; private final int _regionX; @@ -241,6 +244,13 @@ public class WorldRegion _surroundingRegions[i].addDoor((DoorInstance) object); } } + else if (object.isFence()) + { + for (int i = 0; i < _surroundingRegions.length; i++) + { + _surroundingRegions[i].addFence((FenceInstance) object); + } + } // If this is the first player to enter the region, activate self and neighbors. if (object.isPlayable() && !_active && !Config.GRIDS_ALWAYS_ON) @@ -271,7 +281,14 @@ public class WorldRegion { for (int i = 0; i < _surroundingRegions.length; i++) { - removeDoor((DoorInstance) object); + _surroundingRegions[i].removeDoor((DoorInstance) object); + } + } + else if (object.isFence()) + { + for (int i = 0; i < _surroundingRegions.length; i++) + { + _surroundingRegions[i].removeFence((FenceInstance) object); } } @@ -304,6 +321,24 @@ public class WorldRegion return _doors; } + public synchronized void addFence(FenceInstance fence) + { + if (!_fences.contains(fence)) + { + _fences.add(fence); + } + } + + private synchronized void removeFence(FenceInstance fence) + { + _fences.remove(fence); + } + + public List getFences() + { + return _fences; + } + public void setSurroundingRegions(WorldRegion[] regions) { _surroundingRegions = regions; diff --git a/L2J_Mobius_3.0_Helios/java/org/l2jmobius/gameserver/model/actor/instance/FenceInstance.java b/L2J_Mobius_3.0_Helios/java/org/l2jmobius/gameserver/model/actor/instance/FenceInstance.java index e933cff384..821a64b0f6 100644 --- a/L2J_Mobius_3.0_Helios/java/org/l2jmobius/gameserver/model/actor/instance/FenceInstance.java +++ b/L2J_Mobius_3.0_Helios/java/org/l2jmobius/gameserver/model/actor/instance/FenceInstance.java @@ -160,4 +160,10 @@ public class FenceInstance extends WorldObject { return _yMax; } + + @Override + public boolean isFence() + { + return true; + } } \ No newline at end of file diff --git a/L2J_Mobius_4.0_GrandCrusade/java/org/l2jmobius/gameserver/data/xml/FenceData.java b/L2J_Mobius_4.0_GrandCrusade/java/org/l2jmobius/gameserver/data/xml/FenceData.java index 10b68e2f34..cc647ecea2 100644 --- a/L2J_Mobius_4.0_GrandCrusade/java/org/l2jmobius/gameserver/data/xml/FenceData.java +++ b/L2J_Mobius_4.0_GrandCrusade/java/org/l2jmobius/gameserver/data/xml/FenceData.java @@ -17,12 +17,9 @@ package org.l2jmobius.gameserver.data.xml; import java.io.File; -import java.util.ArrayList; -import java.util.Collections; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; -import java.util.function.Predicate; import java.util.logging.Logger; import org.w3c.dom.Document; @@ -45,7 +42,6 @@ public class FenceData implements IXmlReader private static final int MAX_Z_DIFF = 100; - private final Map> _regions = new ConcurrentHashMap<>(); private final Map _fences = new ConcurrentHashMap<>(); protected FenceData() @@ -104,18 +100,11 @@ public class FenceData implements IXmlReader private void addFence(FenceInstance fence) { _fences.put(fence.getObjectId(), fence); - _regions.computeIfAbsent(World.getInstance().getRegion(fence), key -> new ArrayList<>()).add(fence); } public void removeFence(FenceInstance fence) { _fences.remove(fence.getObjectId()); - - final List fencesInRegion = _regions.get(World.getInstance().getRegion(fence)); - if (fencesInRegion != null) - { - fencesInRegion.remove(fence); - } } public Map getFences() @@ -130,19 +119,26 @@ public class FenceData implements IXmlReader public boolean checkIfFenceBetween(int x, int y, int z, int tx, int ty, int tz, Instance instance) { - final Predicate filter = fence -> + final WorldRegion region = World.getInstance().getRegion(x, y); + final List fences = region != null ? region.getFences() : null; + if ((fences == null) || fences.isEmpty()) + { + return false; + } + + for (FenceInstance fence : fences) { // Check if fence is geodata enabled. if (!fence.getState().isGeodataEnabled()) { - return false; + continue; } // Check if fence is within the instance we search for. final int instanceId = (instance == null) ? 0 : instance.getId(); if (fence.getInstanceId() != instanceId) { - return false; + continue; } final int xMin = fence.getXMin(); @@ -151,34 +147,30 @@ public class FenceData implements IXmlReader final int yMax = fence.getYMax(); if ((x < xMin) && (tx < xMin)) { - return false; + continue; } if ((x > xMax) && (tx > xMax)) { - return false; + continue; } if ((y < yMin) && (ty < yMin)) { - return false; + continue; } if ((y > yMax) && (ty > yMax)) { - return false; + continue; } if ((x > xMin) && (tx > xMin) && (x < xMax) && (tx < xMax) && (y > yMin) && (ty > yMin) && (y < yMax) && (ty < yMax)) { - return false; + continue; } if ((crossLinePart(xMin, yMin, xMax, yMin, x, y, tx, ty, xMin, yMin, xMax, yMax) || crossLinePart(xMax, yMin, xMax, yMax, x, y, tx, ty, xMin, yMin, xMax, yMax) || crossLinePart(xMax, yMax, xMin, yMax, x, y, tx, ty, xMin, yMin, xMax, yMax) || crossLinePart(xMin, yMax, xMin, yMin, x, y, tx, ty, xMin, yMin, xMax, yMax)) && (z > (fence.getZ() - MAX_Z_DIFF)) && (z < (fence.getZ() + MAX_Z_DIFF))) { return true; } - - return false; - }; - - final WorldRegion region = World.getInstance().getRegion(x, y); // Should never be null. - return (region != null) && _regions.getOrDefault(region, Collections.emptyList()).stream().anyMatch(filter); + } + return false; } private boolean crossLinePart(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4, double xMin, double yMin, double xMax, double yMax) diff --git a/L2J_Mobius_4.0_GrandCrusade/java/org/l2jmobius/gameserver/model/WorldObject.java b/L2J_Mobius_4.0_GrandCrusade/java/org/l2jmobius/gameserver/model/WorldObject.java index b1292dd3d4..0e5536bbc0 100644 --- a/L2J_Mobius_4.0_GrandCrusade/java/org/l2jmobius/gameserver/model/WorldObject.java +++ b/L2J_Mobius_4.0_GrandCrusade/java/org/l2jmobius/gameserver/model/WorldObject.java @@ -412,6 +412,15 @@ public abstract class WorldObject extends ListenersContainer implements IIdentif return false; } + /** + * Verifies if this object is a fence. + * @return {@code true} if object is Fence, {@code false} otherwise + */ + public boolean isFence() + { + return false; + } + public void setTargetable(boolean targetable) { if (_isTargetable != targetable) diff --git a/L2J_Mobius_4.0_GrandCrusade/java/org/l2jmobius/gameserver/model/WorldRegion.java b/L2J_Mobius_4.0_GrandCrusade/java/org/l2jmobius/gameserver/model/WorldRegion.java index 8ad2649d3e..787947f2d7 100644 --- a/L2J_Mobius_4.0_GrandCrusade/java/org/l2jmobius/gameserver/model/WorldRegion.java +++ b/L2J_Mobius_4.0_GrandCrusade/java/org/l2jmobius/gameserver/model/WorldRegion.java @@ -25,6 +25,7 @@ import org.l2jmobius.commons.concurrent.ThreadPool; import org.l2jmobius.gameserver.model.actor.Attackable; import org.l2jmobius.gameserver.model.actor.Npc; import org.l2jmobius.gameserver.model.actor.instance.DoorInstance; +import org.l2jmobius.gameserver.model.actor.instance.FenceInstance; import org.l2jmobius.gameserver.taskmanager.RandomAnimationTaskManager; import org.l2jmobius.gameserver.util.UnboundArrayList; @@ -34,6 +35,8 @@ public class WorldRegion private final UnboundArrayList _visibleObjects = new UnboundArrayList<>(); /** List containing doors in this world region. */ private final List _doors = new ArrayList<>(1); + /** List containing fences in this world region. */ + private final List _fences = new ArrayList<>(1); /** Array containing nearby regions forming this world region's effective area. */ private WorldRegion[] _surroundingRegions; private final int _regionX; @@ -241,6 +244,13 @@ public class WorldRegion _surroundingRegions[i].addDoor((DoorInstance) object); } } + else if (object.isFence()) + { + for (int i = 0; i < _surroundingRegions.length; i++) + { + _surroundingRegions[i].addFence((FenceInstance) object); + } + } // If this is the first player to enter the region, activate self and neighbors. if (object.isPlayable() && !_active && !Config.GRIDS_ALWAYS_ON) @@ -271,7 +281,14 @@ public class WorldRegion { for (int i = 0; i < _surroundingRegions.length; i++) { - removeDoor((DoorInstance) object); + _surroundingRegions[i].removeDoor((DoorInstance) object); + } + } + else if (object.isFence()) + { + for (int i = 0; i < _surroundingRegions.length; i++) + { + _surroundingRegions[i].removeFence((FenceInstance) object); } } @@ -304,6 +321,24 @@ public class WorldRegion return _doors; } + public synchronized void addFence(FenceInstance fence) + { + if (!_fences.contains(fence)) + { + _fences.add(fence); + } + } + + private synchronized void removeFence(FenceInstance fence) + { + _fences.remove(fence); + } + + public List getFences() + { + return _fences; + } + public void setSurroundingRegions(WorldRegion[] regions) { _surroundingRegions = regions; diff --git a/L2J_Mobius_4.0_GrandCrusade/java/org/l2jmobius/gameserver/model/actor/instance/FenceInstance.java b/L2J_Mobius_4.0_GrandCrusade/java/org/l2jmobius/gameserver/model/actor/instance/FenceInstance.java index e933cff384..821a64b0f6 100644 --- a/L2J_Mobius_4.0_GrandCrusade/java/org/l2jmobius/gameserver/model/actor/instance/FenceInstance.java +++ b/L2J_Mobius_4.0_GrandCrusade/java/org/l2jmobius/gameserver/model/actor/instance/FenceInstance.java @@ -160,4 +160,10 @@ public class FenceInstance extends WorldObject { return _yMax; } + + @Override + public boolean isFence() + { + return true; + } } \ No newline at end of file diff --git a/L2J_Mobius_5.0_Salvation/java/org/l2jmobius/gameserver/data/xml/FenceData.java b/L2J_Mobius_5.0_Salvation/java/org/l2jmobius/gameserver/data/xml/FenceData.java index 10b68e2f34..cc647ecea2 100644 --- a/L2J_Mobius_5.0_Salvation/java/org/l2jmobius/gameserver/data/xml/FenceData.java +++ b/L2J_Mobius_5.0_Salvation/java/org/l2jmobius/gameserver/data/xml/FenceData.java @@ -17,12 +17,9 @@ package org.l2jmobius.gameserver.data.xml; import java.io.File; -import java.util.ArrayList; -import java.util.Collections; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; -import java.util.function.Predicate; import java.util.logging.Logger; import org.w3c.dom.Document; @@ -45,7 +42,6 @@ public class FenceData implements IXmlReader private static final int MAX_Z_DIFF = 100; - private final Map> _regions = new ConcurrentHashMap<>(); private final Map _fences = new ConcurrentHashMap<>(); protected FenceData() @@ -104,18 +100,11 @@ public class FenceData implements IXmlReader private void addFence(FenceInstance fence) { _fences.put(fence.getObjectId(), fence); - _regions.computeIfAbsent(World.getInstance().getRegion(fence), key -> new ArrayList<>()).add(fence); } public void removeFence(FenceInstance fence) { _fences.remove(fence.getObjectId()); - - final List fencesInRegion = _regions.get(World.getInstance().getRegion(fence)); - if (fencesInRegion != null) - { - fencesInRegion.remove(fence); - } } public Map getFences() @@ -130,19 +119,26 @@ public class FenceData implements IXmlReader public boolean checkIfFenceBetween(int x, int y, int z, int tx, int ty, int tz, Instance instance) { - final Predicate filter = fence -> + final WorldRegion region = World.getInstance().getRegion(x, y); + final List fences = region != null ? region.getFences() : null; + if ((fences == null) || fences.isEmpty()) + { + return false; + } + + for (FenceInstance fence : fences) { // Check if fence is geodata enabled. if (!fence.getState().isGeodataEnabled()) { - return false; + continue; } // Check if fence is within the instance we search for. final int instanceId = (instance == null) ? 0 : instance.getId(); if (fence.getInstanceId() != instanceId) { - return false; + continue; } final int xMin = fence.getXMin(); @@ -151,34 +147,30 @@ public class FenceData implements IXmlReader final int yMax = fence.getYMax(); if ((x < xMin) && (tx < xMin)) { - return false; + continue; } if ((x > xMax) && (tx > xMax)) { - return false; + continue; } if ((y < yMin) && (ty < yMin)) { - return false; + continue; } if ((y > yMax) && (ty > yMax)) { - return false; + continue; } if ((x > xMin) && (tx > xMin) && (x < xMax) && (tx < xMax) && (y > yMin) && (ty > yMin) && (y < yMax) && (ty < yMax)) { - return false; + continue; } if ((crossLinePart(xMin, yMin, xMax, yMin, x, y, tx, ty, xMin, yMin, xMax, yMax) || crossLinePart(xMax, yMin, xMax, yMax, x, y, tx, ty, xMin, yMin, xMax, yMax) || crossLinePart(xMax, yMax, xMin, yMax, x, y, tx, ty, xMin, yMin, xMax, yMax) || crossLinePart(xMin, yMax, xMin, yMin, x, y, tx, ty, xMin, yMin, xMax, yMax)) && (z > (fence.getZ() - MAX_Z_DIFF)) && (z < (fence.getZ() + MAX_Z_DIFF))) { return true; } - - return false; - }; - - final WorldRegion region = World.getInstance().getRegion(x, y); // Should never be null. - return (region != null) && _regions.getOrDefault(region, Collections.emptyList()).stream().anyMatch(filter); + } + return false; } private boolean crossLinePart(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4, double xMin, double yMin, double xMax, double yMax) diff --git a/L2J_Mobius_5.0_Salvation/java/org/l2jmobius/gameserver/model/WorldObject.java b/L2J_Mobius_5.0_Salvation/java/org/l2jmobius/gameserver/model/WorldObject.java index b1292dd3d4..0e5536bbc0 100644 --- a/L2J_Mobius_5.0_Salvation/java/org/l2jmobius/gameserver/model/WorldObject.java +++ b/L2J_Mobius_5.0_Salvation/java/org/l2jmobius/gameserver/model/WorldObject.java @@ -412,6 +412,15 @@ public abstract class WorldObject extends ListenersContainer implements IIdentif return false; } + /** + * Verifies if this object is a fence. + * @return {@code true} if object is Fence, {@code false} otherwise + */ + public boolean isFence() + { + return false; + } + public void setTargetable(boolean targetable) { if (_isTargetable != targetable) diff --git a/L2J_Mobius_5.0_Salvation/java/org/l2jmobius/gameserver/model/WorldRegion.java b/L2J_Mobius_5.0_Salvation/java/org/l2jmobius/gameserver/model/WorldRegion.java index 8ad2649d3e..787947f2d7 100644 --- a/L2J_Mobius_5.0_Salvation/java/org/l2jmobius/gameserver/model/WorldRegion.java +++ b/L2J_Mobius_5.0_Salvation/java/org/l2jmobius/gameserver/model/WorldRegion.java @@ -25,6 +25,7 @@ import org.l2jmobius.commons.concurrent.ThreadPool; import org.l2jmobius.gameserver.model.actor.Attackable; import org.l2jmobius.gameserver.model.actor.Npc; import org.l2jmobius.gameserver.model.actor.instance.DoorInstance; +import org.l2jmobius.gameserver.model.actor.instance.FenceInstance; import org.l2jmobius.gameserver.taskmanager.RandomAnimationTaskManager; import org.l2jmobius.gameserver.util.UnboundArrayList; @@ -34,6 +35,8 @@ public class WorldRegion private final UnboundArrayList _visibleObjects = new UnboundArrayList<>(); /** List containing doors in this world region. */ private final List _doors = new ArrayList<>(1); + /** List containing fences in this world region. */ + private final List _fences = new ArrayList<>(1); /** Array containing nearby regions forming this world region's effective area. */ private WorldRegion[] _surroundingRegions; private final int _regionX; @@ -241,6 +244,13 @@ public class WorldRegion _surroundingRegions[i].addDoor((DoorInstance) object); } } + else if (object.isFence()) + { + for (int i = 0; i < _surroundingRegions.length; i++) + { + _surroundingRegions[i].addFence((FenceInstance) object); + } + } // If this is the first player to enter the region, activate self and neighbors. if (object.isPlayable() && !_active && !Config.GRIDS_ALWAYS_ON) @@ -271,7 +281,14 @@ public class WorldRegion { for (int i = 0; i < _surroundingRegions.length; i++) { - removeDoor((DoorInstance) object); + _surroundingRegions[i].removeDoor((DoorInstance) object); + } + } + else if (object.isFence()) + { + for (int i = 0; i < _surroundingRegions.length; i++) + { + _surroundingRegions[i].removeFence((FenceInstance) object); } } @@ -304,6 +321,24 @@ public class WorldRegion return _doors; } + public synchronized void addFence(FenceInstance fence) + { + if (!_fences.contains(fence)) + { + _fences.add(fence); + } + } + + private synchronized void removeFence(FenceInstance fence) + { + _fences.remove(fence); + } + + public List getFences() + { + return _fences; + } + public void setSurroundingRegions(WorldRegion[] regions) { _surroundingRegions = regions; diff --git a/L2J_Mobius_5.0_Salvation/java/org/l2jmobius/gameserver/model/actor/instance/FenceInstance.java b/L2J_Mobius_5.0_Salvation/java/org/l2jmobius/gameserver/model/actor/instance/FenceInstance.java index e933cff384..821a64b0f6 100644 --- a/L2J_Mobius_5.0_Salvation/java/org/l2jmobius/gameserver/model/actor/instance/FenceInstance.java +++ b/L2J_Mobius_5.0_Salvation/java/org/l2jmobius/gameserver/model/actor/instance/FenceInstance.java @@ -160,4 +160,10 @@ public class FenceInstance extends WorldObject { return _yMax; } + + @Override + public boolean isFence() + { + return true; + } } \ No newline at end of file diff --git a/L2J_Mobius_5.5_EtinasFate/java/org/l2jmobius/gameserver/data/xml/FenceData.java b/L2J_Mobius_5.5_EtinasFate/java/org/l2jmobius/gameserver/data/xml/FenceData.java index 10b68e2f34..cc647ecea2 100644 --- a/L2J_Mobius_5.5_EtinasFate/java/org/l2jmobius/gameserver/data/xml/FenceData.java +++ b/L2J_Mobius_5.5_EtinasFate/java/org/l2jmobius/gameserver/data/xml/FenceData.java @@ -17,12 +17,9 @@ package org.l2jmobius.gameserver.data.xml; import java.io.File; -import java.util.ArrayList; -import java.util.Collections; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; -import java.util.function.Predicate; import java.util.logging.Logger; import org.w3c.dom.Document; @@ -45,7 +42,6 @@ public class FenceData implements IXmlReader private static final int MAX_Z_DIFF = 100; - private final Map> _regions = new ConcurrentHashMap<>(); private final Map _fences = new ConcurrentHashMap<>(); protected FenceData() @@ -104,18 +100,11 @@ public class FenceData implements IXmlReader private void addFence(FenceInstance fence) { _fences.put(fence.getObjectId(), fence); - _regions.computeIfAbsent(World.getInstance().getRegion(fence), key -> new ArrayList<>()).add(fence); } public void removeFence(FenceInstance fence) { _fences.remove(fence.getObjectId()); - - final List fencesInRegion = _regions.get(World.getInstance().getRegion(fence)); - if (fencesInRegion != null) - { - fencesInRegion.remove(fence); - } } public Map getFences() @@ -130,19 +119,26 @@ public class FenceData implements IXmlReader public boolean checkIfFenceBetween(int x, int y, int z, int tx, int ty, int tz, Instance instance) { - final Predicate filter = fence -> + final WorldRegion region = World.getInstance().getRegion(x, y); + final List fences = region != null ? region.getFences() : null; + if ((fences == null) || fences.isEmpty()) + { + return false; + } + + for (FenceInstance fence : fences) { // Check if fence is geodata enabled. if (!fence.getState().isGeodataEnabled()) { - return false; + continue; } // Check if fence is within the instance we search for. final int instanceId = (instance == null) ? 0 : instance.getId(); if (fence.getInstanceId() != instanceId) { - return false; + continue; } final int xMin = fence.getXMin(); @@ -151,34 +147,30 @@ public class FenceData implements IXmlReader final int yMax = fence.getYMax(); if ((x < xMin) && (tx < xMin)) { - return false; + continue; } if ((x > xMax) && (tx > xMax)) { - return false; + continue; } if ((y < yMin) && (ty < yMin)) { - return false; + continue; } if ((y > yMax) && (ty > yMax)) { - return false; + continue; } if ((x > xMin) && (tx > xMin) && (x < xMax) && (tx < xMax) && (y > yMin) && (ty > yMin) && (y < yMax) && (ty < yMax)) { - return false; + continue; } if ((crossLinePart(xMin, yMin, xMax, yMin, x, y, tx, ty, xMin, yMin, xMax, yMax) || crossLinePart(xMax, yMin, xMax, yMax, x, y, tx, ty, xMin, yMin, xMax, yMax) || crossLinePart(xMax, yMax, xMin, yMax, x, y, tx, ty, xMin, yMin, xMax, yMax) || crossLinePart(xMin, yMax, xMin, yMin, x, y, tx, ty, xMin, yMin, xMax, yMax)) && (z > (fence.getZ() - MAX_Z_DIFF)) && (z < (fence.getZ() + MAX_Z_DIFF))) { return true; } - - return false; - }; - - final WorldRegion region = World.getInstance().getRegion(x, y); // Should never be null. - return (region != null) && _regions.getOrDefault(region, Collections.emptyList()).stream().anyMatch(filter); + } + return false; } private boolean crossLinePart(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4, double xMin, double yMin, double xMax, double yMax) diff --git a/L2J_Mobius_5.5_EtinasFate/java/org/l2jmobius/gameserver/model/WorldObject.java b/L2J_Mobius_5.5_EtinasFate/java/org/l2jmobius/gameserver/model/WorldObject.java index b1292dd3d4..0e5536bbc0 100644 --- a/L2J_Mobius_5.5_EtinasFate/java/org/l2jmobius/gameserver/model/WorldObject.java +++ b/L2J_Mobius_5.5_EtinasFate/java/org/l2jmobius/gameserver/model/WorldObject.java @@ -412,6 +412,15 @@ public abstract class WorldObject extends ListenersContainer implements IIdentif return false; } + /** + * Verifies if this object is a fence. + * @return {@code true} if object is Fence, {@code false} otherwise + */ + public boolean isFence() + { + return false; + } + public void setTargetable(boolean targetable) { if (_isTargetable != targetable) diff --git a/L2J_Mobius_5.5_EtinasFate/java/org/l2jmobius/gameserver/model/WorldRegion.java b/L2J_Mobius_5.5_EtinasFate/java/org/l2jmobius/gameserver/model/WorldRegion.java index 8ad2649d3e..787947f2d7 100644 --- a/L2J_Mobius_5.5_EtinasFate/java/org/l2jmobius/gameserver/model/WorldRegion.java +++ b/L2J_Mobius_5.5_EtinasFate/java/org/l2jmobius/gameserver/model/WorldRegion.java @@ -25,6 +25,7 @@ import org.l2jmobius.commons.concurrent.ThreadPool; import org.l2jmobius.gameserver.model.actor.Attackable; import org.l2jmobius.gameserver.model.actor.Npc; import org.l2jmobius.gameserver.model.actor.instance.DoorInstance; +import org.l2jmobius.gameserver.model.actor.instance.FenceInstance; import org.l2jmobius.gameserver.taskmanager.RandomAnimationTaskManager; import org.l2jmobius.gameserver.util.UnboundArrayList; @@ -34,6 +35,8 @@ public class WorldRegion private final UnboundArrayList _visibleObjects = new UnboundArrayList<>(); /** List containing doors in this world region. */ private final List _doors = new ArrayList<>(1); + /** List containing fences in this world region. */ + private final List _fences = new ArrayList<>(1); /** Array containing nearby regions forming this world region's effective area. */ private WorldRegion[] _surroundingRegions; private final int _regionX; @@ -241,6 +244,13 @@ public class WorldRegion _surroundingRegions[i].addDoor((DoorInstance) object); } } + else if (object.isFence()) + { + for (int i = 0; i < _surroundingRegions.length; i++) + { + _surroundingRegions[i].addFence((FenceInstance) object); + } + } // If this is the first player to enter the region, activate self and neighbors. if (object.isPlayable() && !_active && !Config.GRIDS_ALWAYS_ON) @@ -271,7 +281,14 @@ public class WorldRegion { for (int i = 0; i < _surroundingRegions.length; i++) { - removeDoor((DoorInstance) object); + _surroundingRegions[i].removeDoor((DoorInstance) object); + } + } + else if (object.isFence()) + { + for (int i = 0; i < _surroundingRegions.length; i++) + { + _surroundingRegions[i].removeFence((FenceInstance) object); } } @@ -304,6 +321,24 @@ public class WorldRegion return _doors; } + public synchronized void addFence(FenceInstance fence) + { + if (!_fences.contains(fence)) + { + _fences.add(fence); + } + } + + private synchronized void removeFence(FenceInstance fence) + { + _fences.remove(fence); + } + + public List getFences() + { + return _fences; + } + public void setSurroundingRegions(WorldRegion[] regions) { _surroundingRegions = regions; diff --git a/L2J_Mobius_5.5_EtinasFate/java/org/l2jmobius/gameserver/model/actor/instance/FenceInstance.java b/L2J_Mobius_5.5_EtinasFate/java/org/l2jmobius/gameserver/model/actor/instance/FenceInstance.java index e933cff384..821a64b0f6 100644 --- a/L2J_Mobius_5.5_EtinasFate/java/org/l2jmobius/gameserver/model/actor/instance/FenceInstance.java +++ b/L2J_Mobius_5.5_EtinasFate/java/org/l2jmobius/gameserver/model/actor/instance/FenceInstance.java @@ -160,4 +160,10 @@ public class FenceInstance extends WorldObject { return _yMax; } + + @Override + public boolean isFence() + { + return true; + } } \ No newline at end of file diff --git a/L2J_Mobius_6.0_Fafurion/java/org/l2jmobius/gameserver/data/xml/FenceData.java b/L2J_Mobius_6.0_Fafurion/java/org/l2jmobius/gameserver/data/xml/FenceData.java index 10b68e2f34..cc647ecea2 100644 --- a/L2J_Mobius_6.0_Fafurion/java/org/l2jmobius/gameserver/data/xml/FenceData.java +++ b/L2J_Mobius_6.0_Fafurion/java/org/l2jmobius/gameserver/data/xml/FenceData.java @@ -17,12 +17,9 @@ package org.l2jmobius.gameserver.data.xml; import java.io.File; -import java.util.ArrayList; -import java.util.Collections; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; -import java.util.function.Predicate; import java.util.logging.Logger; import org.w3c.dom.Document; @@ -45,7 +42,6 @@ public class FenceData implements IXmlReader private static final int MAX_Z_DIFF = 100; - private final Map> _regions = new ConcurrentHashMap<>(); private final Map _fences = new ConcurrentHashMap<>(); protected FenceData() @@ -104,18 +100,11 @@ public class FenceData implements IXmlReader private void addFence(FenceInstance fence) { _fences.put(fence.getObjectId(), fence); - _regions.computeIfAbsent(World.getInstance().getRegion(fence), key -> new ArrayList<>()).add(fence); } public void removeFence(FenceInstance fence) { _fences.remove(fence.getObjectId()); - - final List fencesInRegion = _regions.get(World.getInstance().getRegion(fence)); - if (fencesInRegion != null) - { - fencesInRegion.remove(fence); - } } public Map getFences() @@ -130,19 +119,26 @@ public class FenceData implements IXmlReader public boolean checkIfFenceBetween(int x, int y, int z, int tx, int ty, int tz, Instance instance) { - final Predicate filter = fence -> + final WorldRegion region = World.getInstance().getRegion(x, y); + final List fences = region != null ? region.getFences() : null; + if ((fences == null) || fences.isEmpty()) + { + return false; + } + + for (FenceInstance fence : fences) { // Check if fence is geodata enabled. if (!fence.getState().isGeodataEnabled()) { - return false; + continue; } // Check if fence is within the instance we search for. final int instanceId = (instance == null) ? 0 : instance.getId(); if (fence.getInstanceId() != instanceId) { - return false; + continue; } final int xMin = fence.getXMin(); @@ -151,34 +147,30 @@ public class FenceData implements IXmlReader final int yMax = fence.getYMax(); if ((x < xMin) && (tx < xMin)) { - return false; + continue; } if ((x > xMax) && (tx > xMax)) { - return false; + continue; } if ((y < yMin) && (ty < yMin)) { - return false; + continue; } if ((y > yMax) && (ty > yMax)) { - return false; + continue; } if ((x > xMin) && (tx > xMin) && (x < xMax) && (tx < xMax) && (y > yMin) && (ty > yMin) && (y < yMax) && (ty < yMax)) { - return false; + continue; } if ((crossLinePart(xMin, yMin, xMax, yMin, x, y, tx, ty, xMin, yMin, xMax, yMax) || crossLinePart(xMax, yMin, xMax, yMax, x, y, tx, ty, xMin, yMin, xMax, yMax) || crossLinePart(xMax, yMax, xMin, yMax, x, y, tx, ty, xMin, yMin, xMax, yMax) || crossLinePart(xMin, yMax, xMin, yMin, x, y, tx, ty, xMin, yMin, xMax, yMax)) && (z > (fence.getZ() - MAX_Z_DIFF)) && (z < (fence.getZ() + MAX_Z_DIFF))) { return true; } - - return false; - }; - - final WorldRegion region = World.getInstance().getRegion(x, y); // Should never be null. - return (region != null) && _regions.getOrDefault(region, Collections.emptyList()).stream().anyMatch(filter); + } + return false; } private boolean crossLinePart(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4, double xMin, double yMin, double xMax, double yMax) diff --git a/L2J_Mobius_6.0_Fafurion/java/org/l2jmobius/gameserver/model/WorldObject.java b/L2J_Mobius_6.0_Fafurion/java/org/l2jmobius/gameserver/model/WorldObject.java index b1292dd3d4..0e5536bbc0 100644 --- a/L2J_Mobius_6.0_Fafurion/java/org/l2jmobius/gameserver/model/WorldObject.java +++ b/L2J_Mobius_6.0_Fafurion/java/org/l2jmobius/gameserver/model/WorldObject.java @@ -412,6 +412,15 @@ public abstract class WorldObject extends ListenersContainer implements IIdentif return false; } + /** + * Verifies if this object is a fence. + * @return {@code true} if object is Fence, {@code false} otherwise + */ + public boolean isFence() + { + return false; + } + public void setTargetable(boolean targetable) { if (_isTargetable != targetable) diff --git a/L2J_Mobius_6.0_Fafurion/java/org/l2jmobius/gameserver/model/WorldRegion.java b/L2J_Mobius_6.0_Fafurion/java/org/l2jmobius/gameserver/model/WorldRegion.java index 8ad2649d3e..787947f2d7 100644 --- a/L2J_Mobius_6.0_Fafurion/java/org/l2jmobius/gameserver/model/WorldRegion.java +++ b/L2J_Mobius_6.0_Fafurion/java/org/l2jmobius/gameserver/model/WorldRegion.java @@ -25,6 +25,7 @@ import org.l2jmobius.commons.concurrent.ThreadPool; import org.l2jmobius.gameserver.model.actor.Attackable; import org.l2jmobius.gameserver.model.actor.Npc; import org.l2jmobius.gameserver.model.actor.instance.DoorInstance; +import org.l2jmobius.gameserver.model.actor.instance.FenceInstance; import org.l2jmobius.gameserver.taskmanager.RandomAnimationTaskManager; import org.l2jmobius.gameserver.util.UnboundArrayList; @@ -34,6 +35,8 @@ public class WorldRegion private final UnboundArrayList _visibleObjects = new UnboundArrayList<>(); /** List containing doors in this world region. */ private final List _doors = new ArrayList<>(1); + /** List containing fences in this world region. */ + private final List _fences = new ArrayList<>(1); /** Array containing nearby regions forming this world region's effective area. */ private WorldRegion[] _surroundingRegions; private final int _regionX; @@ -241,6 +244,13 @@ public class WorldRegion _surroundingRegions[i].addDoor((DoorInstance) object); } } + else if (object.isFence()) + { + for (int i = 0; i < _surroundingRegions.length; i++) + { + _surroundingRegions[i].addFence((FenceInstance) object); + } + } // If this is the first player to enter the region, activate self and neighbors. if (object.isPlayable() && !_active && !Config.GRIDS_ALWAYS_ON) @@ -271,7 +281,14 @@ public class WorldRegion { for (int i = 0; i < _surroundingRegions.length; i++) { - removeDoor((DoorInstance) object); + _surroundingRegions[i].removeDoor((DoorInstance) object); + } + } + else if (object.isFence()) + { + for (int i = 0; i < _surroundingRegions.length; i++) + { + _surroundingRegions[i].removeFence((FenceInstance) object); } } @@ -304,6 +321,24 @@ public class WorldRegion return _doors; } + public synchronized void addFence(FenceInstance fence) + { + if (!_fences.contains(fence)) + { + _fences.add(fence); + } + } + + private synchronized void removeFence(FenceInstance fence) + { + _fences.remove(fence); + } + + public List getFences() + { + return _fences; + } + public void setSurroundingRegions(WorldRegion[] regions) { _surroundingRegions = regions; diff --git a/L2J_Mobius_6.0_Fafurion/java/org/l2jmobius/gameserver/model/actor/instance/FenceInstance.java b/L2J_Mobius_6.0_Fafurion/java/org/l2jmobius/gameserver/model/actor/instance/FenceInstance.java index e933cff384..821a64b0f6 100644 --- a/L2J_Mobius_6.0_Fafurion/java/org/l2jmobius/gameserver/model/actor/instance/FenceInstance.java +++ b/L2J_Mobius_6.0_Fafurion/java/org/l2jmobius/gameserver/model/actor/instance/FenceInstance.java @@ -160,4 +160,10 @@ public class FenceInstance extends WorldObject { return _yMax; } + + @Override + public boolean isFence() + { + return true; + } } \ No newline at end of file diff --git a/L2J_Mobius_7.0_PreludeOfWar/java/org/l2jmobius/gameserver/data/xml/FenceData.java b/L2J_Mobius_7.0_PreludeOfWar/java/org/l2jmobius/gameserver/data/xml/FenceData.java index 10b68e2f34..cc647ecea2 100644 --- a/L2J_Mobius_7.0_PreludeOfWar/java/org/l2jmobius/gameserver/data/xml/FenceData.java +++ b/L2J_Mobius_7.0_PreludeOfWar/java/org/l2jmobius/gameserver/data/xml/FenceData.java @@ -17,12 +17,9 @@ package org.l2jmobius.gameserver.data.xml; import java.io.File; -import java.util.ArrayList; -import java.util.Collections; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; -import java.util.function.Predicate; import java.util.logging.Logger; import org.w3c.dom.Document; @@ -45,7 +42,6 @@ public class FenceData implements IXmlReader private static final int MAX_Z_DIFF = 100; - private final Map> _regions = new ConcurrentHashMap<>(); private final Map _fences = new ConcurrentHashMap<>(); protected FenceData() @@ -104,18 +100,11 @@ public class FenceData implements IXmlReader private void addFence(FenceInstance fence) { _fences.put(fence.getObjectId(), fence); - _regions.computeIfAbsent(World.getInstance().getRegion(fence), key -> new ArrayList<>()).add(fence); } public void removeFence(FenceInstance fence) { _fences.remove(fence.getObjectId()); - - final List fencesInRegion = _regions.get(World.getInstance().getRegion(fence)); - if (fencesInRegion != null) - { - fencesInRegion.remove(fence); - } } public Map getFences() @@ -130,19 +119,26 @@ public class FenceData implements IXmlReader public boolean checkIfFenceBetween(int x, int y, int z, int tx, int ty, int tz, Instance instance) { - final Predicate filter = fence -> + final WorldRegion region = World.getInstance().getRegion(x, y); + final List fences = region != null ? region.getFences() : null; + if ((fences == null) || fences.isEmpty()) + { + return false; + } + + for (FenceInstance fence : fences) { // Check if fence is geodata enabled. if (!fence.getState().isGeodataEnabled()) { - return false; + continue; } // Check if fence is within the instance we search for. final int instanceId = (instance == null) ? 0 : instance.getId(); if (fence.getInstanceId() != instanceId) { - return false; + continue; } final int xMin = fence.getXMin(); @@ -151,34 +147,30 @@ public class FenceData implements IXmlReader final int yMax = fence.getYMax(); if ((x < xMin) && (tx < xMin)) { - return false; + continue; } if ((x > xMax) && (tx > xMax)) { - return false; + continue; } if ((y < yMin) && (ty < yMin)) { - return false; + continue; } if ((y > yMax) && (ty > yMax)) { - return false; + continue; } if ((x > xMin) && (tx > xMin) && (x < xMax) && (tx < xMax) && (y > yMin) && (ty > yMin) && (y < yMax) && (ty < yMax)) { - return false; + continue; } if ((crossLinePart(xMin, yMin, xMax, yMin, x, y, tx, ty, xMin, yMin, xMax, yMax) || crossLinePart(xMax, yMin, xMax, yMax, x, y, tx, ty, xMin, yMin, xMax, yMax) || crossLinePart(xMax, yMax, xMin, yMax, x, y, tx, ty, xMin, yMin, xMax, yMax) || crossLinePart(xMin, yMax, xMin, yMin, x, y, tx, ty, xMin, yMin, xMax, yMax)) && (z > (fence.getZ() - MAX_Z_DIFF)) && (z < (fence.getZ() + MAX_Z_DIFF))) { return true; } - - return false; - }; - - final WorldRegion region = World.getInstance().getRegion(x, y); // Should never be null. - return (region != null) && _regions.getOrDefault(region, Collections.emptyList()).stream().anyMatch(filter); + } + return false; } private boolean crossLinePart(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4, double xMin, double yMin, double xMax, double yMax) diff --git a/L2J_Mobius_7.0_PreludeOfWar/java/org/l2jmobius/gameserver/model/WorldObject.java b/L2J_Mobius_7.0_PreludeOfWar/java/org/l2jmobius/gameserver/model/WorldObject.java index b1292dd3d4..0e5536bbc0 100644 --- a/L2J_Mobius_7.0_PreludeOfWar/java/org/l2jmobius/gameserver/model/WorldObject.java +++ b/L2J_Mobius_7.0_PreludeOfWar/java/org/l2jmobius/gameserver/model/WorldObject.java @@ -412,6 +412,15 @@ public abstract class WorldObject extends ListenersContainer implements IIdentif return false; } + /** + * Verifies if this object is a fence. + * @return {@code true} if object is Fence, {@code false} otherwise + */ + public boolean isFence() + { + return false; + } + public void setTargetable(boolean targetable) { if (_isTargetable != targetable) diff --git a/L2J_Mobius_7.0_PreludeOfWar/java/org/l2jmobius/gameserver/model/WorldRegion.java b/L2J_Mobius_7.0_PreludeOfWar/java/org/l2jmobius/gameserver/model/WorldRegion.java index 8ad2649d3e..787947f2d7 100644 --- a/L2J_Mobius_7.0_PreludeOfWar/java/org/l2jmobius/gameserver/model/WorldRegion.java +++ b/L2J_Mobius_7.0_PreludeOfWar/java/org/l2jmobius/gameserver/model/WorldRegion.java @@ -25,6 +25,7 @@ import org.l2jmobius.commons.concurrent.ThreadPool; import org.l2jmobius.gameserver.model.actor.Attackable; import org.l2jmobius.gameserver.model.actor.Npc; import org.l2jmobius.gameserver.model.actor.instance.DoorInstance; +import org.l2jmobius.gameserver.model.actor.instance.FenceInstance; import org.l2jmobius.gameserver.taskmanager.RandomAnimationTaskManager; import org.l2jmobius.gameserver.util.UnboundArrayList; @@ -34,6 +35,8 @@ public class WorldRegion private final UnboundArrayList _visibleObjects = new UnboundArrayList<>(); /** List containing doors in this world region. */ private final List _doors = new ArrayList<>(1); + /** List containing fences in this world region. */ + private final List _fences = new ArrayList<>(1); /** Array containing nearby regions forming this world region's effective area. */ private WorldRegion[] _surroundingRegions; private final int _regionX; @@ -241,6 +244,13 @@ public class WorldRegion _surroundingRegions[i].addDoor((DoorInstance) object); } } + else if (object.isFence()) + { + for (int i = 0; i < _surroundingRegions.length; i++) + { + _surroundingRegions[i].addFence((FenceInstance) object); + } + } // If this is the first player to enter the region, activate self and neighbors. if (object.isPlayable() && !_active && !Config.GRIDS_ALWAYS_ON) @@ -271,7 +281,14 @@ public class WorldRegion { for (int i = 0; i < _surroundingRegions.length; i++) { - removeDoor((DoorInstance) object); + _surroundingRegions[i].removeDoor((DoorInstance) object); + } + } + else if (object.isFence()) + { + for (int i = 0; i < _surroundingRegions.length; i++) + { + _surroundingRegions[i].removeFence((FenceInstance) object); } } @@ -304,6 +321,24 @@ public class WorldRegion return _doors; } + public synchronized void addFence(FenceInstance fence) + { + if (!_fences.contains(fence)) + { + _fences.add(fence); + } + } + + private synchronized void removeFence(FenceInstance fence) + { + _fences.remove(fence); + } + + public List getFences() + { + return _fences; + } + public void setSurroundingRegions(WorldRegion[] regions) { _surroundingRegions = regions; diff --git a/L2J_Mobius_7.0_PreludeOfWar/java/org/l2jmobius/gameserver/model/actor/instance/FenceInstance.java b/L2J_Mobius_7.0_PreludeOfWar/java/org/l2jmobius/gameserver/model/actor/instance/FenceInstance.java index e933cff384..821a64b0f6 100644 --- a/L2J_Mobius_7.0_PreludeOfWar/java/org/l2jmobius/gameserver/model/actor/instance/FenceInstance.java +++ b/L2J_Mobius_7.0_PreludeOfWar/java/org/l2jmobius/gameserver/model/actor/instance/FenceInstance.java @@ -160,4 +160,10 @@ public class FenceInstance extends WorldObject { return _yMax; } + + @Override + public boolean isFence() + { + return true; + } } \ No newline at end of file diff --git a/L2J_Mobius_8.0_Homunculus/java/org/l2jmobius/gameserver/data/xml/FenceData.java b/L2J_Mobius_8.0_Homunculus/java/org/l2jmobius/gameserver/data/xml/FenceData.java index 10b68e2f34..cc647ecea2 100644 --- a/L2J_Mobius_8.0_Homunculus/java/org/l2jmobius/gameserver/data/xml/FenceData.java +++ b/L2J_Mobius_8.0_Homunculus/java/org/l2jmobius/gameserver/data/xml/FenceData.java @@ -17,12 +17,9 @@ package org.l2jmobius.gameserver.data.xml; import java.io.File; -import java.util.ArrayList; -import java.util.Collections; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; -import java.util.function.Predicate; import java.util.logging.Logger; import org.w3c.dom.Document; @@ -45,7 +42,6 @@ public class FenceData implements IXmlReader private static final int MAX_Z_DIFF = 100; - private final Map> _regions = new ConcurrentHashMap<>(); private final Map _fences = new ConcurrentHashMap<>(); protected FenceData() @@ -104,18 +100,11 @@ public class FenceData implements IXmlReader private void addFence(FenceInstance fence) { _fences.put(fence.getObjectId(), fence); - _regions.computeIfAbsent(World.getInstance().getRegion(fence), key -> new ArrayList<>()).add(fence); } public void removeFence(FenceInstance fence) { _fences.remove(fence.getObjectId()); - - final List fencesInRegion = _regions.get(World.getInstance().getRegion(fence)); - if (fencesInRegion != null) - { - fencesInRegion.remove(fence); - } } public Map getFences() @@ -130,19 +119,26 @@ public class FenceData implements IXmlReader public boolean checkIfFenceBetween(int x, int y, int z, int tx, int ty, int tz, Instance instance) { - final Predicate filter = fence -> + final WorldRegion region = World.getInstance().getRegion(x, y); + final List fences = region != null ? region.getFences() : null; + if ((fences == null) || fences.isEmpty()) + { + return false; + } + + for (FenceInstance fence : fences) { // Check if fence is geodata enabled. if (!fence.getState().isGeodataEnabled()) { - return false; + continue; } // Check if fence is within the instance we search for. final int instanceId = (instance == null) ? 0 : instance.getId(); if (fence.getInstanceId() != instanceId) { - return false; + continue; } final int xMin = fence.getXMin(); @@ -151,34 +147,30 @@ public class FenceData implements IXmlReader final int yMax = fence.getYMax(); if ((x < xMin) && (tx < xMin)) { - return false; + continue; } if ((x > xMax) && (tx > xMax)) { - return false; + continue; } if ((y < yMin) && (ty < yMin)) { - return false; + continue; } if ((y > yMax) && (ty > yMax)) { - return false; + continue; } if ((x > xMin) && (tx > xMin) && (x < xMax) && (tx < xMax) && (y > yMin) && (ty > yMin) && (y < yMax) && (ty < yMax)) { - return false; + continue; } if ((crossLinePart(xMin, yMin, xMax, yMin, x, y, tx, ty, xMin, yMin, xMax, yMax) || crossLinePart(xMax, yMin, xMax, yMax, x, y, tx, ty, xMin, yMin, xMax, yMax) || crossLinePart(xMax, yMax, xMin, yMax, x, y, tx, ty, xMin, yMin, xMax, yMax) || crossLinePart(xMin, yMax, xMin, yMin, x, y, tx, ty, xMin, yMin, xMax, yMax)) && (z > (fence.getZ() - MAX_Z_DIFF)) && (z < (fence.getZ() + MAX_Z_DIFF))) { return true; } - - return false; - }; - - final WorldRegion region = World.getInstance().getRegion(x, y); // Should never be null. - return (region != null) && _regions.getOrDefault(region, Collections.emptyList()).stream().anyMatch(filter); + } + return false; } private boolean crossLinePart(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4, double xMin, double yMin, double xMax, double yMax) diff --git a/L2J_Mobius_8.0_Homunculus/java/org/l2jmobius/gameserver/model/WorldObject.java b/L2J_Mobius_8.0_Homunculus/java/org/l2jmobius/gameserver/model/WorldObject.java index b1292dd3d4..0e5536bbc0 100644 --- a/L2J_Mobius_8.0_Homunculus/java/org/l2jmobius/gameserver/model/WorldObject.java +++ b/L2J_Mobius_8.0_Homunculus/java/org/l2jmobius/gameserver/model/WorldObject.java @@ -412,6 +412,15 @@ public abstract class WorldObject extends ListenersContainer implements IIdentif return false; } + /** + * Verifies if this object is a fence. + * @return {@code true} if object is Fence, {@code false} otherwise + */ + public boolean isFence() + { + return false; + } + public void setTargetable(boolean targetable) { if (_isTargetable != targetable) diff --git a/L2J_Mobius_8.0_Homunculus/java/org/l2jmobius/gameserver/model/WorldRegion.java b/L2J_Mobius_8.0_Homunculus/java/org/l2jmobius/gameserver/model/WorldRegion.java index 8ad2649d3e..787947f2d7 100644 --- a/L2J_Mobius_8.0_Homunculus/java/org/l2jmobius/gameserver/model/WorldRegion.java +++ b/L2J_Mobius_8.0_Homunculus/java/org/l2jmobius/gameserver/model/WorldRegion.java @@ -25,6 +25,7 @@ import org.l2jmobius.commons.concurrent.ThreadPool; import org.l2jmobius.gameserver.model.actor.Attackable; import org.l2jmobius.gameserver.model.actor.Npc; import org.l2jmobius.gameserver.model.actor.instance.DoorInstance; +import org.l2jmobius.gameserver.model.actor.instance.FenceInstance; import org.l2jmobius.gameserver.taskmanager.RandomAnimationTaskManager; import org.l2jmobius.gameserver.util.UnboundArrayList; @@ -34,6 +35,8 @@ public class WorldRegion private final UnboundArrayList _visibleObjects = new UnboundArrayList<>(); /** List containing doors in this world region. */ private final List _doors = new ArrayList<>(1); + /** List containing fences in this world region. */ + private final List _fences = new ArrayList<>(1); /** Array containing nearby regions forming this world region's effective area. */ private WorldRegion[] _surroundingRegions; private final int _regionX; @@ -241,6 +244,13 @@ public class WorldRegion _surroundingRegions[i].addDoor((DoorInstance) object); } } + else if (object.isFence()) + { + for (int i = 0; i < _surroundingRegions.length; i++) + { + _surroundingRegions[i].addFence((FenceInstance) object); + } + } // If this is the first player to enter the region, activate self and neighbors. if (object.isPlayable() && !_active && !Config.GRIDS_ALWAYS_ON) @@ -271,7 +281,14 @@ public class WorldRegion { for (int i = 0; i < _surroundingRegions.length; i++) { - removeDoor((DoorInstance) object); + _surroundingRegions[i].removeDoor((DoorInstance) object); + } + } + else if (object.isFence()) + { + for (int i = 0; i < _surroundingRegions.length; i++) + { + _surroundingRegions[i].removeFence((FenceInstance) object); } } @@ -304,6 +321,24 @@ public class WorldRegion return _doors; } + public synchronized void addFence(FenceInstance fence) + { + if (!_fences.contains(fence)) + { + _fences.add(fence); + } + } + + private synchronized void removeFence(FenceInstance fence) + { + _fences.remove(fence); + } + + public List getFences() + { + return _fences; + } + public void setSurroundingRegions(WorldRegion[] regions) { _surroundingRegions = regions; diff --git a/L2J_Mobius_8.0_Homunculus/java/org/l2jmobius/gameserver/model/actor/instance/FenceInstance.java b/L2J_Mobius_8.0_Homunculus/java/org/l2jmobius/gameserver/model/actor/instance/FenceInstance.java index e933cff384..821a64b0f6 100644 --- a/L2J_Mobius_8.0_Homunculus/java/org/l2jmobius/gameserver/model/actor/instance/FenceInstance.java +++ b/L2J_Mobius_8.0_Homunculus/java/org/l2jmobius/gameserver/model/actor/instance/FenceInstance.java @@ -160,4 +160,10 @@ public class FenceInstance extends WorldObject { return _yMax; } + + @Override + public boolean isFence() + { + return true; + } } \ No newline at end of file diff --git a/L2J_Mobius_9.0_ReturnOfTheQueenAnt/java/org/l2jmobius/gameserver/data/xml/FenceData.java b/L2J_Mobius_9.0_ReturnOfTheQueenAnt/java/org/l2jmobius/gameserver/data/xml/FenceData.java index 10b68e2f34..cc647ecea2 100644 --- a/L2J_Mobius_9.0_ReturnOfTheQueenAnt/java/org/l2jmobius/gameserver/data/xml/FenceData.java +++ b/L2J_Mobius_9.0_ReturnOfTheQueenAnt/java/org/l2jmobius/gameserver/data/xml/FenceData.java @@ -17,12 +17,9 @@ package org.l2jmobius.gameserver.data.xml; import java.io.File; -import java.util.ArrayList; -import java.util.Collections; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; -import java.util.function.Predicate; import java.util.logging.Logger; import org.w3c.dom.Document; @@ -45,7 +42,6 @@ public class FenceData implements IXmlReader private static final int MAX_Z_DIFF = 100; - private final Map> _regions = new ConcurrentHashMap<>(); private final Map _fences = new ConcurrentHashMap<>(); protected FenceData() @@ -104,18 +100,11 @@ public class FenceData implements IXmlReader private void addFence(FenceInstance fence) { _fences.put(fence.getObjectId(), fence); - _regions.computeIfAbsent(World.getInstance().getRegion(fence), key -> new ArrayList<>()).add(fence); } public void removeFence(FenceInstance fence) { _fences.remove(fence.getObjectId()); - - final List fencesInRegion = _regions.get(World.getInstance().getRegion(fence)); - if (fencesInRegion != null) - { - fencesInRegion.remove(fence); - } } public Map getFences() @@ -130,19 +119,26 @@ public class FenceData implements IXmlReader public boolean checkIfFenceBetween(int x, int y, int z, int tx, int ty, int tz, Instance instance) { - final Predicate filter = fence -> + final WorldRegion region = World.getInstance().getRegion(x, y); + final List fences = region != null ? region.getFences() : null; + if ((fences == null) || fences.isEmpty()) + { + return false; + } + + for (FenceInstance fence : fences) { // Check if fence is geodata enabled. if (!fence.getState().isGeodataEnabled()) { - return false; + continue; } // Check if fence is within the instance we search for. final int instanceId = (instance == null) ? 0 : instance.getId(); if (fence.getInstanceId() != instanceId) { - return false; + continue; } final int xMin = fence.getXMin(); @@ -151,34 +147,30 @@ public class FenceData implements IXmlReader final int yMax = fence.getYMax(); if ((x < xMin) && (tx < xMin)) { - return false; + continue; } if ((x > xMax) && (tx > xMax)) { - return false; + continue; } if ((y < yMin) && (ty < yMin)) { - return false; + continue; } if ((y > yMax) && (ty > yMax)) { - return false; + continue; } if ((x > xMin) && (tx > xMin) && (x < xMax) && (tx < xMax) && (y > yMin) && (ty > yMin) && (y < yMax) && (ty < yMax)) { - return false; + continue; } if ((crossLinePart(xMin, yMin, xMax, yMin, x, y, tx, ty, xMin, yMin, xMax, yMax) || crossLinePart(xMax, yMin, xMax, yMax, x, y, tx, ty, xMin, yMin, xMax, yMax) || crossLinePart(xMax, yMax, xMin, yMax, x, y, tx, ty, xMin, yMin, xMax, yMax) || crossLinePart(xMin, yMax, xMin, yMin, x, y, tx, ty, xMin, yMin, xMax, yMax)) && (z > (fence.getZ() - MAX_Z_DIFF)) && (z < (fence.getZ() + MAX_Z_DIFF))) { return true; } - - return false; - }; - - final WorldRegion region = World.getInstance().getRegion(x, y); // Should never be null. - return (region != null) && _regions.getOrDefault(region, Collections.emptyList()).stream().anyMatch(filter); + } + return false; } private boolean crossLinePart(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4, double xMin, double yMin, double xMax, double yMax) diff --git a/L2J_Mobius_9.0_ReturnOfTheQueenAnt/java/org/l2jmobius/gameserver/model/WorldObject.java b/L2J_Mobius_9.0_ReturnOfTheQueenAnt/java/org/l2jmobius/gameserver/model/WorldObject.java index b1292dd3d4..0e5536bbc0 100644 --- a/L2J_Mobius_9.0_ReturnOfTheQueenAnt/java/org/l2jmobius/gameserver/model/WorldObject.java +++ b/L2J_Mobius_9.0_ReturnOfTheQueenAnt/java/org/l2jmobius/gameserver/model/WorldObject.java @@ -412,6 +412,15 @@ public abstract class WorldObject extends ListenersContainer implements IIdentif return false; } + /** + * Verifies if this object is a fence. + * @return {@code true} if object is Fence, {@code false} otherwise + */ + public boolean isFence() + { + return false; + } + public void setTargetable(boolean targetable) { if (_isTargetable != targetable) diff --git a/L2J_Mobius_9.0_ReturnOfTheQueenAnt/java/org/l2jmobius/gameserver/model/WorldRegion.java b/L2J_Mobius_9.0_ReturnOfTheQueenAnt/java/org/l2jmobius/gameserver/model/WorldRegion.java index 8ad2649d3e..787947f2d7 100644 --- a/L2J_Mobius_9.0_ReturnOfTheQueenAnt/java/org/l2jmobius/gameserver/model/WorldRegion.java +++ b/L2J_Mobius_9.0_ReturnOfTheQueenAnt/java/org/l2jmobius/gameserver/model/WorldRegion.java @@ -25,6 +25,7 @@ import org.l2jmobius.commons.concurrent.ThreadPool; import org.l2jmobius.gameserver.model.actor.Attackable; import org.l2jmobius.gameserver.model.actor.Npc; import org.l2jmobius.gameserver.model.actor.instance.DoorInstance; +import org.l2jmobius.gameserver.model.actor.instance.FenceInstance; import org.l2jmobius.gameserver.taskmanager.RandomAnimationTaskManager; import org.l2jmobius.gameserver.util.UnboundArrayList; @@ -34,6 +35,8 @@ public class WorldRegion private final UnboundArrayList _visibleObjects = new UnboundArrayList<>(); /** List containing doors in this world region. */ private final List _doors = new ArrayList<>(1); + /** List containing fences in this world region. */ + private final List _fences = new ArrayList<>(1); /** Array containing nearby regions forming this world region's effective area. */ private WorldRegion[] _surroundingRegions; private final int _regionX; @@ -241,6 +244,13 @@ public class WorldRegion _surroundingRegions[i].addDoor((DoorInstance) object); } } + else if (object.isFence()) + { + for (int i = 0; i < _surroundingRegions.length; i++) + { + _surroundingRegions[i].addFence((FenceInstance) object); + } + } // If this is the first player to enter the region, activate self and neighbors. if (object.isPlayable() && !_active && !Config.GRIDS_ALWAYS_ON) @@ -271,7 +281,14 @@ public class WorldRegion { for (int i = 0; i < _surroundingRegions.length; i++) { - removeDoor((DoorInstance) object); + _surroundingRegions[i].removeDoor((DoorInstance) object); + } + } + else if (object.isFence()) + { + for (int i = 0; i < _surroundingRegions.length; i++) + { + _surroundingRegions[i].removeFence((FenceInstance) object); } } @@ -304,6 +321,24 @@ public class WorldRegion return _doors; } + public synchronized void addFence(FenceInstance fence) + { + if (!_fences.contains(fence)) + { + _fences.add(fence); + } + } + + private synchronized void removeFence(FenceInstance fence) + { + _fences.remove(fence); + } + + public List getFences() + { + return _fences; + } + public void setSurroundingRegions(WorldRegion[] regions) { _surroundingRegions = regions; diff --git a/L2J_Mobius_9.0_ReturnOfTheQueenAnt/java/org/l2jmobius/gameserver/model/actor/instance/FenceInstance.java b/L2J_Mobius_9.0_ReturnOfTheQueenAnt/java/org/l2jmobius/gameserver/model/actor/instance/FenceInstance.java index e933cff384..821a64b0f6 100644 --- a/L2J_Mobius_9.0_ReturnOfTheQueenAnt/java/org/l2jmobius/gameserver/model/actor/instance/FenceInstance.java +++ b/L2J_Mobius_9.0_ReturnOfTheQueenAnt/java/org/l2jmobius/gameserver/model/actor/instance/FenceInstance.java @@ -160,4 +160,10 @@ public class FenceInstance extends WorldObject { return _yMax; } + + @Override + public boolean isFence() + { + return true; + } } \ No newline at end of file diff --git a/L2J_Mobius_C4_ScionsOfDestiny/java/org/l2jmobius/gameserver/data/xml/FenceData.java b/L2J_Mobius_C4_ScionsOfDestiny/java/org/l2jmobius/gameserver/data/xml/FenceData.java index a630e75512..924fca51ef 100644 --- a/L2J_Mobius_C4_ScionsOfDestiny/java/org/l2jmobius/gameserver/data/xml/FenceData.java +++ b/L2J_Mobius_C4_ScionsOfDestiny/java/org/l2jmobius/gameserver/data/xml/FenceData.java @@ -17,12 +17,9 @@ package org.l2jmobius.gameserver.data.xml; import java.io.File; -import java.util.ArrayList; -import java.util.Collections; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; -import java.util.function.Predicate; import java.util.logging.Logger; import javax.xml.parsers.DocumentBuilderFactory; @@ -33,7 +30,6 @@ import org.w3c.dom.Node; import org.l2jmobius.Config; import org.l2jmobius.gameserver.enums.FenceState; -import org.l2jmobius.gameserver.model.Location; import org.l2jmobius.gameserver.model.World; import org.l2jmobius.gameserver.model.WorldRegion; import org.l2jmobius.gameserver.model.actor.instance.FenceInstance; @@ -47,7 +43,6 @@ public class FenceData private static final int MAX_Z_DIFF = 100; - private final Map> _regions = new ConcurrentHashMap<>(); private final Map _fences = new ConcurrentHashMap<>(); protected FenceData() @@ -126,21 +121,12 @@ public class FenceData private void addFence(FenceInstance fence) { - final Location point = new Location(fence.getX(), fence.getY(), fence.getZ()); _fences.put(fence.getObjectId(), fence); - _regions.computeIfAbsent(World.getInstance().getRegion(point), key -> new ArrayList<>()).add(fence); } public void removeFence(FenceInstance fence) { _fences.remove(fence.getObjectId()); - - final Location point = new Location(fence.getX(), fence.getY(), fence.getZ()); - final List fencesInRegion = _regions.get(World.getInstance().getRegion(point)); - if (fencesInRegion != null) - { - fencesInRegion.remove(fence); - } } public Map getFences() @@ -155,12 +141,19 @@ public class FenceData public boolean checkIfFenceBetween(int x, int y, int z, int tx, int ty, int tz) { - final Predicate filter = fence -> + final WorldRegion region = World.getInstance().getRegion(x, y); + final List fences = region != null ? region.getFences() : null; + if ((fences == null) || fences.isEmpty()) + { + return false; + } + + for (FenceInstance fence : fences) { // Check if fence is geodata enabled. if (!fence.getState().isGeodataEnabled()) { - return false; + continue; } final int xMin = fence.getXMin(); @@ -169,40 +162,30 @@ public class FenceData final int yMax = fence.getYMax(); if ((x < xMin) && (tx < xMin)) { - return false; + continue; } if ((x > xMax) && (tx > xMax)) { - return false; + continue; } if ((y < yMin) && (ty < yMin)) { - return false; + continue; } if ((y > yMax) && (ty > yMax)) { - return false; + continue; } - if ((x > xMin) && (tx > xMin) && (x < xMax) && (tx < xMax)) + if ((x > xMin) && (tx > xMin) && (x < xMax) && (tx < xMax) && (y > yMin) && (ty > yMin) && (y < yMax) && (ty < yMax)) { - if ((y > yMin) && (ty > yMin) && (y < yMax) && (ty < yMax)) - { - return false; - } + continue; } - - if (crossLinePart(xMin, yMin, xMax, yMin, x, y, tx, ty, xMin, yMin, xMax, yMax) || crossLinePart(xMax, yMin, xMax, yMax, x, y, tx, ty, xMin, yMin, xMax, yMax) || crossLinePart(xMax, yMax, xMin, yMax, x, y, tx, ty, xMin, yMin, xMax, yMax) || crossLinePart(xMin, yMax, xMin, yMin, x, y, tx, ty, xMin, yMin, xMax, yMax)) + if ((crossLinePart(xMin, yMin, xMax, yMin, x, y, tx, ty, xMin, yMin, xMax, yMax) || crossLinePart(xMax, yMin, xMax, yMax, x, y, tx, ty, xMin, yMin, xMax, yMax) || crossLinePart(xMax, yMax, xMin, yMax, x, y, tx, ty, xMin, yMin, xMax, yMax) || crossLinePart(xMin, yMax, xMin, yMin, x, y, tx, ty, xMin, yMin, xMax, yMax)) && (z > (fence.getZ() - MAX_Z_DIFF)) && (z < (fence.getZ() + MAX_Z_DIFF))) { - if ((z > (fence.getZ() - MAX_Z_DIFF)) && (z < (fence.getZ() + MAX_Z_DIFF))) - { - return true; - } + return true; } - - return false; - }; - - return _regions.getOrDefault(World.getInstance().getRegion(new Location(x, y, z)), Collections.emptyList()).stream().anyMatch(filter); + } + return false; } private boolean crossLinePart(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4, double xMin, double yMin, double xMax, double yMax) diff --git a/L2J_Mobius_C4_ScionsOfDestiny/java/org/l2jmobius/gameserver/model/WorldObject.java b/L2J_Mobius_C4_ScionsOfDestiny/java/org/l2jmobius/gameserver/model/WorldObject.java index 13cc9642df..efa7d53b2e 100644 --- a/L2J_Mobius_C4_ScionsOfDestiny/java/org/l2jmobius/gameserver/model/WorldObject.java +++ b/L2J_Mobius_C4_ScionsOfDestiny/java/org/l2jmobius/gameserver/model/WorldObject.java @@ -460,6 +460,11 @@ public abstract class WorldObject return false; } + public boolean isFence() + { + return false; + } + public boolean isBoat() { return false; diff --git a/L2J_Mobius_C4_ScionsOfDestiny/java/org/l2jmobius/gameserver/model/WorldRegion.java b/L2J_Mobius_C4_ScionsOfDestiny/java/org/l2jmobius/gameserver/model/WorldRegion.java index e520ada2f5..f9f32ee7a7 100644 --- a/L2J_Mobius_C4_ScionsOfDestiny/java/org/l2jmobius/gameserver/model/WorldRegion.java +++ b/L2J_Mobius_C4_ScionsOfDestiny/java/org/l2jmobius/gameserver/model/WorldRegion.java @@ -31,6 +31,7 @@ import org.l2jmobius.gameserver.data.sql.SpawnTable; import org.l2jmobius.gameserver.model.actor.Attackable; import org.l2jmobius.gameserver.model.actor.Creature; import org.l2jmobius.gameserver.model.actor.instance.DoorInstance; +import org.l2jmobius.gameserver.model.actor.instance.FenceInstance; import org.l2jmobius.gameserver.model.actor.instance.NpcInstance; import org.l2jmobius.gameserver.model.spawn.Spawn; import org.l2jmobius.gameserver.model.zone.ZoneManager; @@ -45,6 +46,7 @@ public class WorldRegion private final UnboundArrayList _visibleObjects = new UnboundArrayList<>(); private final List _doors = new ArrayList<>(1); + private final List _fences = new ArrayList<>(1); private WorldRegion[] _surroundingRegions; private final int _regionX; private final int _regionY; @@ -241,7 +243,7 @@ public class WorldRegion _active = value; - // turn the AI on or off to match the region's activation. + // Turn the AI on or off to match the region's activation. switchAI(value); } @@ -305,8 +307,7 @@ public class WorldRegion /** * Add the WorldObject in the WorldObjectHashSet(WorldObject) _visibleObjects containing WorldObject visible in this WorldRegion
- * If WorldObject is a PlayerInstance, Add the PlayerInstance in the WorldObjectHashSet(PlayerInstance) _allPlayable containing PlayerInstance of all player in game in this WorldRegion
- * Assert : object.getCurrentWorldRegion() == this + * If WorldObject is a PlayerInstance, Add the PlayerInstance in the WorldObjectHashSet(PlayerInstance) _allPlayable containing PlayerInstance of all player in game in this WorldRegion * @param object */ public void addVisibleObject(WorldObject object) @@ -325,6 +326,13 @@ public class WorldRegion _surroundingRegions[i].addDoor((DoorInstance) object); } } + else if (object.isFence()) + { + for (int i = 0; i < _surroundingRegions.length; i++) + { + _surroundingRegions[i].addFence((FenceInstance) object); + } + } // If this is the first player to enter the region, activate self and neighbors. if (object.isPlayable() && !_active && !Config.GRIDS_ALWAYS_ON) @@ -334,9 +342,7 @@ public class WorldRegion } /** - * Remove the WorldObject from the WorldObjectHashSet(WorldObject) _visibleObjects in this WorldRegion
- * If WorldObject is a PlayerInstance, remove it from the WorldObjectHashSet(PlayerInstance) _allPlayable of this WorldRegion
- * Assert : object.getCurrentWorldRegion() == this || object.getCurrentWorldRegion() == null + * Remove the WorldObject from the WorldObjectHashSet(WorldObject) _visibleObjects in this WorldRegion. If WorldObject is a PlayerInstance, remove it from the WorldObjectHashSet(PlayerInstance) _allPlayable of this WorldRegion * @param object */ public void removeVisibleObject(WorldObject object) @@ -357,7 +363,14 @@ public class WorldRegion { for (int i = 0; i < _surroundingRegions.length; i++) { - removeDoor((DoorInstance) object); + _surroundingRegions[i].removeDoor((DoorInstance) object); + } + } + else if (object.isFence()) + { + for (int i = 0; i < _surroundingRegions.length; i++) + { + _surroundingRegions[i].removeFence((FenceInstance) object); } } @@ -414,6 +427,24 @@ public class WorldRegion return _doors; } + public synchronized void addFence(FenceInstance fence) + { + if (!_fences.contains(fence)) + { + _fences.add(fence); + } + } + + private synchronized void removeFence(FenceInstance fence) + { + _fences.remove(fence); + } + + public List getFences() + { + return _fences; + } + public String getName() { return "(" + _regionX + ", " + _regionY + ")"; diff --git a/L2J_Mobius_C4_ScionsOfDestiny/java/org/l2jmobius/gameserver/model/actor/instance/FenceInstance.java b/L2J_Mobius_C4_ScionsOfDestiny/java/org/l2jmobius/gameserver/model/actor/instance/FenceInstance.java index 9e0683b03d..925c1f794b 100644 --- a/L2J_Mobius_C4_ScionsOfDestiny/java/org/l2jmobius/gameserver/model/actor/instance/FenceInstance.java +++ b/L2J_Mobius_C4_ScionsOfDestiny/java/org/l2jmobius/gameserver/model/actor/instance/FenceInstance.java @@ -153,4 +153,10 @@ public class FenceInstance extends WorldObject { return _yMax; } + + @Override + public boolean isFence() + { + return true; + } } \ No newline at end of file diff --git a/L2J_Mobius_C6_Interlude/java/org/l2jmobius/gameserver/data/xml/FenceData.java b/L2J_Mobius_C6_Interlude/java/org/l2jmobius/gameserver/data/xml/FenceData.java index a630e75512..924fca51ef 100644 --- a/L2J_Mobius_C6_Interlude/java/org/l2jmobius/gameserver/data/xml/FenceData.java +++ b/L2J_Mobius_C6_Interlude/java/org/l2jmobius/gameserver/data/xml/FenceData.java @@ -17,12 +17,9 @@ package org.l2jmobius.gameserver.data.xml; import java.io.File; -import java.util.ArrayList; -import java.util.Collections; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; -import java.util.function.Predicate; import java.util.logging.Logger; import javax.xml.parsers.DocumentBuilderFactory; @@ -33,7 +30,6 @@ import org.w3c.dom.Node; import org.l2jmobius.Config; import org.l2jmobius.gameserver.enums.FenceState; -import org.l2jmobius.gameserver.model.Location; import org.l2jmobius.gameserver.model.World; import org.l2jmobius.gameserver.model.WorldRegion; import org.l2jmobius.gameserver.model.actor.instance.FenceInstance; @@ -47,7 +43,6 @@ public class FenceData private static final int MAX_Z_DIFF = 100; - private final Map> _regions = new ConcurrentHashMap<>(); private final Map _fences = new ConcurrentHashMap<>(); protected FenceData() @@ -126,21 +121,12 @@ public class FenceData private void addFence(FenceInstance fence) { - final Location point = new Location(fence.getX(), fence.getY(), fence.getZ()); _fences.put(fence.getObjectId(), fence); - _regions.computeIfAbsent(World.getInstance().getRegion(point), key -> new ArrayList<>()).add(fence); } public void removeFence(FenceInstance fence) { _fences.remove(fence.getObjectId()); - - final Location point = new Location(fence.getX(), fence.getY(), fence.getZ()); - final List fencesInRegion = _regions.get(World.getInstance().getRegion(point)); - if (fencesInRegion != null) - { - fencesInRegion.remove(fence); - } } public Map getFences() @@ -155,12 +141,19 @@ public class FenceData public boolean checkIfFenceBetween(int x, int y, int z, int tx, int ty, int tz) { - final Predicate filter = fence -> + final WorldRegion region = World.getInstance().getRegion(x, y); + final List fences = region != null ? region.getFences() : null; + if ((fences == null) || fences.isEmpty()) + { + return false; + } + + for (FenceInstance fence : fences) { // Check if fence is geodata enabled. if (!fence.getState().isGeodataEnabled()) { - return false; + continue; } final int xMin = fence.getXMin(); @@ -169,40 +162,30 @@ public class FenceData final int yMax = fence.getYMax(); if ((x < xMin) && (tx < xMin)) { - return false; + continue; } if ((x > xMax) && (tx > xMax)) { - return false; + continue; } if ((y < yMin) && (ty < yMin)) { - return false; + continue; } if ((y > yMax) && (ty > yMax)) { - return false; + continue; } - if ((x > xMin) && (tx > xMin) && (x < xMax) && (tx < xMax)) + if ((x > xMin) && (tx > xMin) && (x < xMax) && (tx < xMax) && (y > yMin) && (ty > yMin) && (y < yMax) && (ty < yMax)) { - if ((y > yMin) && (ty > yMin) && (y < yMax) && (ty < yMax)) - { - return false; - } + continue; } - - if (crossLinePart(xMin, yMin, xMax, yMin, x, y, tx, ty, xMin, yMin, xMax, yMax) || crossLinePart(xMax, yMin, xMax, yMax, x, y, tx, ty, xMin, yMin, xMax, yMax) || crossLinePart(xMax, yMax, xMin, yMax, x, y, tx, ty, xMin, yMin, xMax, yMax) || crossLinePart(xMin, yMax, xMin, yMin, x, y, tx, ty, xMin, yMin, xMax, yMax)) + if ((crossLinePart(xMin, yMin, xMax, yMin, x, y, tx, ty, xMin, yMin, xMax, yMax) || crossLinePart(xMax, yMin, xMax, yMax, x, y, tx, ty, xMin, yMin, xMax, yMax) || crossLinePart(xMax, yMax, xMin, yMax, x, y, tx, ty, xMin, yMin, xMax, yMax) || crossLinePart(xMin, yMax, xMin, yMin, x, y, tx, ty, xMin, yMin, xMax, yMax)) && (z > (fence.getZ() - MAX_Z_DIFF)) && (z < (fence.getZ() + MAX_Z_DIFF))) { - if ((z > (fence.getZ() - MAX_Z_DIFF)) && (z < (fence.getZ() + MAX_Z_DIFF))) - { - return true; - } + return true; } - - return false; - }; - - return _regions.getOrDefault(World.getInstance().getRegion(new Location(x, y, z)), Collections.emptyList()).stream().anyMatch(filter); + } + return false; } private boolean crossLinePart(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4, double xMin, double yMin, double xMax, double yMax) diff --git a/L2J_Mobius_C6_Interlude/java/org/l2jmobius/gameserver/model/WorldObject.java b/L2J_Mobius_C6_Interlude/java/org/l2jmobius/gameserver/model/WorldObject.java index 13cc9642df..efa7d53b2e 100644 --- a/L2J_Mobius_C6_Interlude/java/org/l2jmobius/gameserver/model/WorldObject.java +++ b/L2J_Mobius_C6_Interlude/java/org/l2jmobius/gameserver/model/WorldObject.java @@ -460,6 +460,11 @@ public abstract class WorldObject return false; } + public boolean isFence() + { + return false; + } + public boolean isBoat() { return false; diff --git a/L2J_Mobius_C6_Interlude/java/org/l2jmobius/gameserver/model/WorldRegion.java b/L2J_Mobius_C6_Interlude/java/org/l2jmobius/gameserver/model/WorldRegion.java index e520ada2f5..f9f32ee7a7 100644 --- a/L2J_Mobius_C6_Interlude/java/org/l2jmobius/gameserver/model/WorldRegion.java +++ b/L2J_Mobius_C6_Interlude/java/org/l2jmobius/gameserver/model/WorldRegion.java @@ -31,6 +31,7 @@ import org.l2jmobius.gameserver.data.sql.SpawnTable; import org.l2jmobius.gameserver.model.actor.Attackable; import org.l2jmobius.gameserver.model.actor.Creature; import org.l2jmobius.gameserver.model.actor.instance.DoorInstance; +import org.l2jmobius.gameserver.model.actor.instance.FenceInstance; import org.l2jmobius.gameserver.model.actor.instance.NpcInstance; import org.l2jmobius.gameserver.model.spawn.Spawn; import org.l2jmobius.gameserver.model.zone.ZoneManager; @@ -45,6 +46,7 @@ public class WorldRegion private final UnboundArrayList _visibleObjects = new UnboundArrayList<>(); private final List _doors = new ArrayList<>(1); + private final List _fences = new ArrayList<>(1); private WorldRegion[] _surroundingRegions; private final int _regionX; private final int _regionY; @@ -241,7 +243,7 @@ public class WorldRegion _active = value; - // turn the AI on or off to match the region's activation. + // Turn the AI on or off to match the region's activation. switchAI(value); } @@ -305,8 +307,7 @@ public class WorldRegion /** * Add the WorldObject in the WorldObjectHashSet(WorldObject) _visibleObjects containing WorldObject visible in this WorldRegion
- * If WorldObject is a PlayerInstance, Add the PlayerInstance in the WorldObjectHashSet(PlayerInstance) _allPlayable containing PlayerInstance of all player in game in this WorldRegion
- * Assert : object.getCurrentWorldRegion() == this + * If WorldObject is a PlayerInstance, Add the PlayerInstance in the WorldObjectHashSet(PlayerInstance) _allPlayable containing PlayerInstance of all player in game in this WorldRegion * @param object */ public void addVisibleObject(WorldObject object) @@ -325,6 +326,13 @@ public class WorldRegion _surroundingRegions[i].addDoor((DoorInstance) object); } } + else if (object.isFence()) + { + for (int i = 0; i < _surroundingRegions.length; i++) + { + _surroundingRegions[i].addFence((FenceInstance) object); + } + } // If this is the first player to enter the region, activate self and neighbors. if (object.isPlayable() && !_active && !Config.GRIDS_ALWAYS_ON) @@ -334,9 +342,7 @@ public class WorldRegion } /** - * Remove the WorldObject from the WorldObjectHashSet(WorldObject) _visibleObjects in this WorldRegion
- * If WorldObject is a PlayerInstance, remove it from the WorldObjectHashSet(PlayerInstance) _allPlayable of this WorldRegion
- * Assert : object.getCurrentWorldRegion() == this || object.getCurrentWorldRegion() == null + * Remove the WorldObject from the WorldObjectHashSet(WorldObject) _visibleObjects in this WorldRegion. If WorldObject is a PlayerInstance, remove it from the WorldObjectHashSet(PlayerInstance) _allPlayable of this WorldRegion * @param object */ public void removeVisibleObject(WorldObject object) @@ -357,7 +363,14 @@ public class WorldRegion { for (int i = 0; i < _surroundingRegions.length; i++) { - removeDoor((DoorInstance) object); + _surroundingRegions[i].removeDoor((DoorInstance) object); + } + } + else if (object.isFence()) + { + for (int i = 0; i < _surroundingRegions.length; i++) + { + _surroundingRegions[i].removeFence((FenceInstance) object); } } @@ -414,6 +427,24 @@ public class WorldRegion return _doors; } + public synchronized void addFence(FenceInstance fence) + { + if (!_fences.contains(fence)) + { + _fences.add(fence); + } + } + + private synchronized void removeFence(FenceInstance fence) + { + _fences.remove(fence); + } + + public List getFences() + { + return _fences; + } + public String getName() { return "(" + _regionX + ", " + _regionY + ")"; diff --git a/L2J_Mobius_C6_Interlude/java/org/l2jmobius/gameserver/model/actor/instance/FenceInstance.java b/L2J_Mobius_C6_Interlude/java/org/l2jmobius/gameserver/model/actor/instance/FenceInstance.java index 9e0683b03d..925c1f794b 100644 --- a/L2J_Mobius_C6_Interlude/java/org/l2jmobius/gameserver/model/actor/instance/FenceInstance.java +++ b/L2J_Mobius_C6_Interlude/java/org/l2jmobius/gameserver/model/actor/instance/FenceInstance.java @@ -153,4 +153,10 @@ public class FenceInstance extends WorldObject { return _yMax; } + + @Override + public boolean isFence() + { + return true; + } } \ No newline at end of file diff --git a/L2J_Mobius_CT_2.4_Epilogue/java/org/l2jmobius/gameserver/data/xml/FenceData.java b/L2J_Mobius_CT_2.4_Epilogue/java/org/l2jmobius/gameserver/data/xml/FenceData.java index c51ef11752..f4f7c7dde4 100644 --- a/L2J_Mobius_CT_2.4_Epilogue/java/org/l2jmobius/gameserver/data/xml/FenceData.java +++ b/L2J_Mobius_CT_2.4_Epilogue/java/org/l2jmobius/gameserver/data/xml/FenceData.java @@ -17,12 +17,9 @@ package org.l2jmobius.gameserver.data.xml; import java.io.File; -import java.util.ArrayList; -import java.util.Collections; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; -import java.util.function.Predicate; import java.util.logging.Logger; import org.w3c.dom.Document; @@ -44,7 +41,6 @@ public class FenceData implements IXmlReader private static final int MAX_Z_DIFF = 100; - private final Map> _regions = new ConcurrentHashMap<>(); private final Map _fences = new ConcurrentHashMap<>(); protected FenceData() @@ -103,18 +99,11 @@ public class FenceData implements IXmlReader private void addFence(FenceInstance fence) { _fences.put(fence.getObjectId(), fence); - _regions.computeIfAbsent(World.getInstance().getRegion(fence), key -> new ArrayList<>()).add(fence); } public void removeFence(FenceInstance fence) { _fences.remove(fence.getObjectId()); - - final List fencesInRegion = _regions.get(World.getInstance().getRegion(fence)); - if (fencesInRegion != null) - { - fencesInRegion.remove(fence); - } } public Map getFences() @@ -129,18 +118,25 @@ public class FenceData implements IXmlReader public boolean checkIfFenceBetween(int x, int y, int z, int tx, int ty, int tz, int instanceId) { - final Predicate filter = fence -> + final WorldRegion region = World.getInstance().getRegion(x, y); + final List fences = region != null ? region.getFences() : null; + if ((fences == null) || fences.isEmpty()) + { + return false; + } + + for (FenceInstance fence : fences) { // Check if fence is geodata enabled. if (!fence.getState().isGeodataEnabled()) { - return false; + continue; } // Check if fence is within the instance we search for. if (fence.getInstanceId() != instanceId) { - return false; + continue; } final int xMin = fence.getXMin(); @@ -149,41 +145,30 @@ public class FenceData implements IXmlReader final int yMax = fence.getYMax(); if ((x < xMin) && (tx < xMin)) { - return false; + continue; } if ((x > xMax) && (tx > xMax)) { - return false; + continue; } if ((y < yMin) && (ty < yMin)) { - return false; + continue; } if ((y > yMax) && (ty > yMax)) { - return false; + continue; } - if ((x > xMin) && (tx > xMin) && (x < xMax) && (tx < xMax)) + if ((x > xMin) && (tx > xMin) && (x < xMax) && (tx < xMax) && (y > yMin) && (ty > yMin) && (y < yMax) && (ty < yMax)) { - if ((y > yMin) && (ty > yMin) && (y < yMax) && (ty < yMax)) - { - return false; - } + continue; } - - if (crossLinePart(xMin, yMin, xMax, yMin, x, y, tx, ty, xMin, yMin, xMax, yMax) || crossLinePart(xMax, yMin, xMax, yMax, x, y, tx, ty, xMin, yMin, xMax, yMax) || crossLinePart(xMax, yMax, xMin, yMax, x, y, tx, ty, xMin, yMin, xMax, yMax) || crossLinePart(xMin, yMax, xMin, yMin, x, y, tx, ty, xMin, yMin, xMax, yMax)) + if ((crossLinePart(xMin, yMin, xMax, yMin, x, y, tx, ty, xMin, yMin, xMax, yMax) || crossLinePart(xMax, yMin, xMax, yMax, x, y, tx, ty, xMin, yMin, xMax, yMax) || crossLinePart(xMax, yMax, xMin, yMax, x, y, tx, ty, xMin, yMin, xMax, yMax) || crossLinePart(xMin, yMax, xMin, yMin, x, y, tx, ty, xMin, yMin, xMax, yMax)) && (z > (fence.getZ() - MAX_Z_DIFF)) && (z < (fence.getZ() + MAX_Z_DIFF))) { - if ((z > (fence.getZ() - MAX_Z_DIFF)) && (z < (fence.getZ() + MAX_Z_DIFF))) - { - return true; - } + return true; } - - return false; - }; - - final WorldRegion region = World.getInstance().getRegion(x, y); // Should never be null. - return region == null ? false : _regions.getOrDefault(region, Collections.emptyList()).stream().anyMatch(filter); + } + return false; } private boolean crossLinePart(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4, double xMin, double yMin, double xMax, double yMax) diff --git a/L2J_Mobius_CT_2.4_Epilogue/java/org/l2jmobius/gameserver/model/WorldObject.java b/L2J_Mobius_CT_2.4_Epilogue/java/org/l2jmobius/gameserver/model/WorldObject.java index 7706487f7b..f85f231ede 100644 --- a/L2J_Mobius_CT_2.4_Epilogue/java/org/l2jmobius/gameserver/model/WorldObject.java +++ b/L2J_Mobius_CT_2.4_Epilogue/java/org/l2jmobius/gameserver/model/WorldObject.java @@ -415,6 +415,15 @@ public abstract class WorldObject extends ListenersContainer implements IIdentif return false; } + /** + * Verifies if this object is a fence. + * @return {@code true} if object is Fence, {@code false} otherwise + */ + public boolean isFence() + { + return false; + } + /** * @return {@code true} if object Can be targeted */ diff --git a/L2J_Mobius_CT_2.4_Epilogue/java/org/l2jmobius/gameserver/model/WorldRegion.java b/L2J_Mobius_CT_2.4_Epilogue/java/org/l2jmobius/gameserver/model/WorldRegion.java index 8ad2649d3e..787947f2d7 100644 --- a/L2J_Mobius_CT_2.4_Epilogue/java/org/l2jmobius/gameserver/model/WorldRegion.java +++ b/L2J_Mobius_CT_2.4_Epilogue/java/org/l2jmobius/gameserver/model/WorldRegion.java @@ -25,6 +25,7 @@ import org.l2jmobius.commons.concurrent.ThreadPool; import org.l2jmobius.gameserver.model.actor.Attackable; import org.l2jmobius.gameserver.model.actor.Npc; import org.l2jmobius.gameserver.model.actor.instance.DoorInstance; +import org.l2jmobius.gameserver.model.actor.instance.FenceInstance; import org.l2jmobius.gameserver.taskmanager.RandomAnimationTaskManager; import org.l2jmobius.gameserver.util.UnboundArrayList; @@ -34,6 +35,8 @@ public class WorldRegion private final UnboundArrayList _visibleObjects = new UnboundArrayList<>(); /** List containing doors in this world region. */ private final List _doors = new ArrayList<>(1); + /** List containing fences in this world region. */ + private final List _fences = new ArrayList<>(1); /** Array containing nearby regions forming this world region's effective area. */ private WorldRegion[] _surroundingRegions; private final int _regionX; @@ -241,6 +244,13 @@ public class WorldRegion _surroundingRegions[i].addDoor((DoorInstance) object); } } + else if (object.isFence()) + { + for (int i = 0; i < _surroundingRegions.length; i++) + { + _surroundingRegions[i].addFence((FenceInstance) object); + } + } // If this is the first player to enter the region, activate self and neighbors. if (object.isPlayable() && !_active && !Config.GRIDS_ALWAYS_ON) @@ -271,7 +281,14 @@ public class WorldRegion { for (int i = 0; i < _surroundingRegions.length; i++) { - removeDoor((DoorInstance) object); + _surroundingRegions[i].removeDoor((DoorInstance) object); + } + } + else if (object.isFence()) + { + for (int i = 0; i < _surroundingRegions.length; i++) + { + _surroundingRegions[i].removeFence((FenceInstance) object); } } @@ -304,6 +321,24 @@ public class WorldRegion return _doors; } + public synchronized void addFence(FenceInstance fence) + { + if (!_fences.contains(fence)) + { + _fences.add(fence); + } + } + + private synchronized void removeFence(FenceInstance fence) + { + _fences.remove(fence); + } + + public List getFences() + { + return _fences; + } + public void setSurroundingRegions(WorldRegion[] regions) { _surroundingRegions = regions; diff --git a/L2J_Mobius_CT_2.4_Epilogue/java/org/l2jmobius/gameserver/model/actor/instance/FenceInstance.java b/L2J_Mobius_CT_2.4_Epilogue/java/org/l2jmobius/gameserver/model/actor/instance/FenceInstance.java index e933cff384..821a64b0f6 100644 --- a/L2J_Mobius_CT_2.4_Epilogue/java/org/l2jmobius/gameserver/model/actor/instance/FenceInstance.java +++ b/L2J_Mobius_CT_2.4_Epilogue/java/org/l2jmobius/gameserver/model/actor/instance/FenceInstance.java @@ -160,4 +160,10 @@ public class FenceInstance extends WorldObject { return _yMax; } + + @Override + public boolean isFence() + { + return true; + } } \ No newline at end of file diff --git a/L2J_Mobius_CT_2.6_HighFive/java/org/l2jmobius/gameserver/data/xml/FenceData.java b/L2J_Mobius_CT_2.6_HighFive/java/org/l2jmobius/gameserver/data/xml/FenceData.java index c51ef11752..f4f7c7dde4 100644 --- a/L2J_Mobius_CT_2.6_HighFive/java/org/l2jmobius/gameserver/data/xml/FenceData.java +++ b/L2J_Mobius_CT_2.6_HighFive/java/org/l2jmobius/gameserver/data/xml/FenceData.java @@ -17,12 +17,9 @@ package org.l2jmobius.gameserver.data.xml; import java.io.File; -import java.util.ArrayList; -import java.util.Collections; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; -import java.util.function.Predicate; import java.util.logging.Logger; import org.w3c.dom.Document; @@ -44,7 +41,6 @@ public class FenceData implements IXmlReader private static final int MAX_Z_DIFF = 100; - private final Map> _regions = new ConcurrentHashMap<>(); private final Map _fences = new ConcurrentHashMap<>(); protected FenceData() @@ -103,18 +99,11 @@ public class FenceData implements IXmlReader private void addFence(FenceInstance fence) { _fences.put(fence.getObjectId(), fence); - _regions.computeIfAbsent(World.getInstance().getRegion(fence), key -> new ArrayList<>()).add(fence); } public void removeFence(FenceInstance fence) { _fences.remove(fence.getObjectId()); - - final List fencesInRegion = _regions.get(World.getInstance().getRegion(fence)); - if (fencesInRegion != null) - { - fencesInRegion.remove(fence); - } } public Map getFences() @@ -129,18 +118,25 @@ public class FenceData implements IXmlReader public boolean checkIfFenceBetween(int x, int y, int z, int tx, int ty, int tz, int instanceId) { - final Predicate filter = fence -> + final WorldRegion region = World.getInstance().getRegion(x, y); + final List fences = region != null ? region.getFences() : null; + if ((fences == null) || fences.isEmpty()) + { + return false; + } + + for (FenceInstance fence : fences) { // Check if fence is geodata enabled. if (!fence.getState().isGeodataEnabled()) { - return false; + continue; } // Check if fence is within the instance we search for. if (fence.getInstanceId() != instanceId) { - return false; + continue; } final int xMin = fence.getXMin(); @@ -149,41 +145,30 @@ public class FenceData implements IXmlReader final int yMax = fence.getYMax(); if ((x < xMin) && (tx < xMin)) { - return false; + continue; } if ((x > xMax) && (tx > xMax)) { - return false; + continue; } if ((y < yMin) && (ty < yMin)) { - return false; + continue; } if ((y > yMax) && (ty > yMax)) { - return false; + continue; } - if ((x > xMin) && (tx > xMin) && (x < xMax) && (tx < xMax)) + if ((x > xMin) && (tx > xMin) && (x < xMax) && (tx < xMax) && (y > yMin) && (ty > yMin) && (y < yMax) && (ty < yMax)) { - if ((y > yMin) && (ty > yMin) && (y < yMax) && (ty < yMax)) - { - return false; - } + continue; } - - if (crossLinePart(xMin, yMin, xMax, yMin, x, y, tx, ty, xMin, yMin, xMax, yMax) || crossLinePart(xMax, yMin, xMax, yMax, x, y, tx, ty, xMin, yMin, xMax, yMax) || crossLinePart(xMax, yMax, xMin, yMax, x, y, tx, ty, xMin, yMin, xMax, yMax) || crossLinePart(xMin, yMax, xMin, yMin, x, y, tx, ty, xMin, yMin, xMax, yMax)) + if ((crossLinePart(xMin, yMin, xMax, yMin, x, y, tx, ty, xMin, yMin, xMax, yMax) || crossLinePart(xMax, yMin, xMax, yMax, x, y, tx, ty, xMin, yMin, xMax, yMax) || crossLinePart(xMax, yMax, xMin, yMax, x, y, tx, ty, xMin, yMin, xMax, yMax) || crossLinePart(xMin, yMax, xMin, yMin, x, y, tx, ty, xMin, yMin, xMax, yMax)) && (z > (fence.getZ() - MAX_Z_DIFF)) && (z < (fence.getZ() + MAX_Z_DIFF))) { - if ((z > (fence.getZ() - MAX_Z_DIFF)) && (z < (fence.getZ() + MAX_Z_DIFF))) - { - return true; - } + return true; } - - return false; - }; - - final WorldRegion region = World.getInstance().getRegion(x, y); // Should never be null. - return region == null ? false : _regions.getOrDefault(region, Collections.emptyList()).stream().anyMatch(filter); + } + return false; } private boolean crossLinePart(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4, double xMin, double yMin, double xMax, double yMax) diff --git a/L2J_Mobius_CT_2.6_HighFive/java/org/l2jmobius/gameserver/model/WorldObject.java b/L2J_Mobius_CT_2.6_HighFive/java/org/l2jmobius/gameserver/model/WorldObject.java index 7706487f7b..f85f231ede 100644 --- a/L2J_Mobius_CT_2.6_HighFive/java/org/l2jmobius/gameserver/model/WorldObject.java +++ b/L2J_Mobius_CT_2.6_HighFive/java/org/l2jmobius/gameserver/model/WorldObject.java @@ -415,6 +415,15 @@ public abstract class WorldObject extends ListenersContainer implements IIdentif return false; } + /** + * Verifies if this object is a fence. + * @return {@code true} if object is Fence, {@code false} otherwise + */ + public boolean isFence() + { + return false; + } + /** * @return {@code true} if object Can be targeted */ diff --git a/L2J_Mobius_CT_2.6_HighFive/java/org/l2jmobius/gameserver/model/WorldRegion.java b/L2J_Mobius_CT_2.6_HighFive/java/org/l2jmobius/gameserver/model/WorldRegion.java index 8ad2649d3e..787947f2d7 100644 --- a/L2J_Mobius_CT_2.6_HighFive/java/org/l2jmobius/gameserver/model/WorldRegion.java +++ b/L2J_Mobius_CT_2.6_HighFive/java/org/l2jmobius/gameserver/model/WorldRegion.java @@ -25,6 +25,7 @@ import org.l2jmobius.commons.concurrent.ThreadPool; import org.l2jmobius.gameserver.model.actor.Attackable; import org.l2jmobius.gameserver.model.actor.Npc; import org.l2jmobius.gameserver.model.actor.instance.DoorInstance; +import org.l2jmobius.gameserver.model.actor.instance.FenceInstance; import org.l2jmobius.gameserver.taskmanager.RandomAnimationTaskManager; import org.l2jmobius.gameserver.util.UnboundArrayList; @@ -34,6 +35,8 @@ public class WorldRegion private final UnboundArrayList _visibleObjects = new UnboundArrayList<>(); /** List containing doors in this world region. */ private final List _doors = new ArrayList<>(1); + /** List containing fences in this world region. */ + private final List _fences = new ArrayList<>(1); /** Array containing nearby regions forming this world region's effective area. */ private WorldRegion[] _surroundingRegions; private final int _regionX; @@ -241,6 +244,13 @@ public class WorldRegion _surroundingRegions[i].addDoor((DoorInstance) object); } } + else if (object.isFence()) + { + for (int i = 0; i < _surroundingRegions.length; i++) + { + _surroundingRegions[i].addFence((FenceInstance) object); + } + } // If this is the first player to enter the region, activate self and neighbors. if (object.isPlayable() && !_active && !Config.GRIDS_ALWAYS_ON) @@ -271,7 +281,14 @@ public class WorldRegion { for (int i = 0; i < _surroundingRegions.length; i++) { - removeDoor((DoorInstance) object); + _surroundingRegions[i].removeDoor((DoorInstance) object); + } + } + else if (object.isFence()) + { + for (int i = 0; i < _surroundingRegions.length; i++) + { + _surroundingRegions[i].removeFence((FenceInstance) object); } } @@ -304,6 +321,24 @@ public class WorldRegion return _doors; } + public synchronized void addFence(FenceInstance fence) + { + if (!_fences.contains(fence)) + { + _fences.add(fence); + } + } + + private synchronized void removeFence(FenceInstance fence) + { + _fences.remove(fence); + } + + public List getFences() + { + return _fences; + } + public void setSurroundingRegions(WorldRegion[] regions) { _surroundingRegions = regions; diff --git a/L2J_Mobius_CT_2.6_HighFive/java/org/l2jmobius/gameserver/model/actor/instance/FenceInstance.java b/L2J_Mobius_CT_2.6_HighFive/java/org/l2jmobius/gameserver/model/actor/instance/FenceInstance.java index e933cff384..821a64b0f6 100644 --- a/L2J_Mobius_CT_2.6_HighFive/java/org/l2jmobius/gameserver/model/actor/instance/FenceInstance.java +++ b/L2J_Mobius_CT_2.6_HighFive/java/org/l2jmobius/gameserver/model/actor/instance/FenceInstance.java @@ -160,4 +160,10 @@ public class FenceInstance extends WorldObject { return _yMax; } + + @Override + public boolean isFence() + { + return true; + } } \ No newline at end of file diff --git a/L2J_Mobius_Classic_2.0_Saviors/java/org/l2jmobius/gameserver/data/xml/FenceData.java b/L2J_Mobius_Classic_2.0_Saviors/java/org/l2jmobius/gameserver/data/xml/FenceData.java index 10b68e2f34..cc647ecea2 100644 --- a/L2J_Mobius_Classic_2.0_Saviors/java/org/l2jmobius/gameserver/data/xml/FenceData.java +++ b/L2J_Mobius_Classic_2.0_Saviors/java/org/l2jmobius/gameserver/data/xml/FenceData.java @@ -17,12 +17,9 @@ package org.l2jmobius.gameserver.data.xml; import java.io.File; -import java.util.ArrayList; -import java.util.Collections; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; -import java.util.function.Predicate; import java.util.logging.Logger; import org.w3c.dom.Document; @@ -45,7 +42,6 @@ public class FenceData implements IXmlReader private static final int MAX_Z_DIFF = 100; - private final Map> _regions = new ConcurrentHashMap<>(); private final Map _fences = new ConcurrentHashMap<>(); protected FenceData() @@ -104,18 +100,11 @@ public class FenceData implements IXmlReader private void addFence(FenceInstance fence) { _fences.put(fence.getObjectId(), fence); - _regions.computeIfAbsent(World.getInstance().getRegion(fence), key -> new ArrayList<>()).add(fence); } public void removeFence(FenceInstance fence) { _fences.remove(fence.getObjectId()); - - final List fencesInRegion = _regions.get(World.getInstance().getRegion(fence)); - if (fencesInRegion != null) - { - fencesInRegion.remove(fence); - } } public Map getFences() @@ -130,19 +119,26 @@ public class FenceData implements IXmlReader public boolean checkIfFenceBetween(int x, int y, int z, int tx, int ty, int tz, Instance instance) { - final Predicate filter = fence -> + final WorldRegion region = World.getInstance().getRegion(x, y); + final List fences = region != null ? region.getFences() : null; + if ((fences == null) || fences.isEmpty()) + { + return false; + } + + for (FenceInstance fence : fences) { // Check if fence is geodata enabled. if (!fence.getState().isGeodataEnabled()) { - return false; + continue; } // Check if fence is within the instance we search for. final int instanceId = (instance == null) ? 0 : instance.getId(); if (fence.getInstanceId() != instanceId) { - return false; + continue; } final int xMin = fence.getXMin(); @@ -151,34 +147,30 @@ public class FenceData implements IXmlReader final int yMax = fence.getYMax(); if ((x < xMin) && (tx < xMin)) { - return false; + continue; } if ((x > xMax) && (tx > xMax)) { - return false; + continue; } if ((y < yMin) && (ty < yMin)) { - return false; + continue; } if ((y > yMax) && (ty > yMax)) { - return false; + continue; } if ((x > xMin) && (tx > xMin) && (x < xMax) && (tx < xMax) && (y > yMin) && (ty > yMin) && (y < yMax) && (ty < yMax)) { - return false; + continue; } if ((crossLinePart(xMin, yMin, xMax, yMin, x, y, tx, ty, xMin, yMin, xMax, yMax) || crossLinePart(xMax, yMin, xMax, yMax, x, y, tx, ty, xMin, yMin, xMax, yMax) || crossLinePart(xMax, yMax, xMin, yMax, x, y, tx, ty, xMin, yMin, xMax, yMax) || crossLinePart(xMin, yMax, xMin, yMin, x, y, tx, ty, xMin, yMin, xMax, yMax)) && (z > (fence.getZ() - MAX_Z_DIFF)) && (z < (fence.getZ() + MAX_Z_DIFF))) { return true; } - - return false; - }; - - final WorldRegion region = World.getInstance().getRegion(x, y); // Should never be null. - return (region != null) && _regions.getOrDefault(region, Collections.emptyList()).stream().anyMatch(filter); + } + return false; } private boolean crossLinePart(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4, double xMin, double yMin, double xMax, double yMax) diff --git a/L2J_Mobius_Classic_2.0_Saviors/java/org/l2jmobius/gameserver/model/WorldObject.java b/L2J_Mobius_Classic_2.0_Saviors/java/org/l2jmobius/gameserver/model/WorldObject.java index b1292dd3d4..0e5536bbc0 100644 --- a/L2J_Mobius_Classic_2.0_Saviors/java/org/l2jmobius/gameserver/model/WorldObject.java +++ b/L2J_Mobius_Classic_2.0_Saviors/java/org/l2jmobius/gameserver/model/WorldObject.java @@ -412,6 +412,15 @@ public abstract class WorldObject extends ListenersContainer implements IIdentif return false; } + /** + * Verifies if this object is a fence. + * @return {@code true} if object is Fence, {@code false} otherwise + */ + public boolean isFence() + { + return false; + } + public void setTargetable(boolean targetable) { if (_isTargetable != targetable) diff --git a/L2J_Mobius_Classic_2.0_Saviors/java/org/l2jmobius/gameserver/model/WorldRegion.java b/L2J_Mobius_Classic_2.0_Saviors/java/org/l2jmobius/gameserver/model/WorldRegion.java index 8ad2649d3e..787947f2d7 100644 --- a/L2J_Mobius_Classic_2.0_Saviors/java/org/l2jmobius/gameserver/model/WorldRegion.java +++ b/L2J_Mobius_Classic_2.0_Saviors/java/org/l2jmobius/gameserver/model/WorldRegion.java @@ -25,6 +25,7 @@ import org.l2jmobius.commons.concurrent.ThreadPool; import org.l2jmobius.gameserver.model.actor.Attackable; import org.l2jmobius.gameserver.model.actor.Npc; import org.l2jmobius.gameserver.model.actor.instance.DoorInstance; +import org.l2jmobius.gameserver.model.actor.instance.FenceInstance; import org.l2jmobius.gameserver.taskmanager.RandomAnimationTaskManager; import org.l2jmobius.gameserver.util.UnboundArrayList; @@ -34,6 +35,8 @@ public class WorldRegion private final UnboundArrayList _visibleObjects = new UnboundArrayList<>(); /** List containing doors in this world region. */ private final List _doors = new ArrayList<>(1); + /** List containing fences in this world region. */ + private final List _fences = new ArrayList<>(1); /** Array containing nearby regions forming this world region's effective area. */ private WorldRegion[] _surroundingRegions; private final int _regionX; @@ -241,6 +244,13 @@ public class WorldRegion _surroundingRegions[i].addDoor((DoorInstance) object); } } + else if (object.isFence()) + { + for (int i = 0; i < _surroundingRegions.length; i++) + { + _surroundingRegions[i].addFence((FenceInstance) object); + } + } // If this is the first player to enter the region, activate self and neighbors. if (object.isPlayable() && !_active && !Config.GRIDS_ALWAYS_ON) @@ -271,7 +281,14 @@ public class WorldRegion { for (int i = 0; i < _surroundingRegions.length; i++) { - removeDoor((DoorInstance) object); + _surroundingRegions[i].removeDoor((DoorInstance) object); + } + } + else if (object.isFence()) + { + for (int i = 0; i < _surroundingRegions.length; i++) + { + _surroundingRegions[i].removeFence((FenceInstance) object); } } @@ -304,6 +321,24 @@ public class WorldRegion return _doors; } + public synchronized void addFence(FenceInstance fence) + { + if (!_fences.contains(fence)) + { + _fences.add(fence); + } + } + + private synchronized void removeFence(FenceInstance fence) + { + _fences.remove(fence); + } + + public List getFences() + { + return _fences; + } + public void setSurroundingRegions(WorldRegion[] regions) { _surroundingRegions = regions; diff --git a/L2J_Mobius_Classic_2.0_Saviors/java/org/l2jmobius/gameserver/model/actor/instance/FenceInstance.java b/L2J_Mobius_Classic_2.0_Saviors/java/org/l2jmobius/gameserver/model/actor/instance/FenceInstance.java index e933cff384..821a64b0f6 100644 --- a/L2J_Mobius_Classic_2.0_Saviors/java/org/l2jmobius/gameserver/model/actor/instance/FenceInstance.java +++ b/L2J_Mobius_Classic_2.0_Saviors/java/org/l2jmobius/gameserver/model/actor/instance/FenceInstance.java @@ -160,4 +160,10 @@ public class FenceInstance extends WorldObject { return _yMax; } + + @Override + public boolean isFence() + { + return true; + } } \ No newline at end of file diff --git a/L2J_Mobius_Classic_2.1_Zaken/java/org/l2jmobius/gameserver/data/xml/FenceData.java b/L2J_Mobius_Classic_2.1_Zaken/java/org/l2jmobius/gameserver/data/xml/FenceData.java index 10b68e2f34..cc647ecea2 100644 --- a/L2J_Mobius_Classic_2.1_Zaken/java/org/l2jmobius/gameserver/data/xml/FenceData.java +++ b/L2J_Mobius_Classic_2.1_Zaken/java/org/l2jmobius/gameserver/data/xml/FenceData.java @@ -17,12 +17,9 @@ package org.l2jmobius.gameserver.data.xml; import java.io.File; -import java.util.ArrayList; -import java.util.Collections; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; -import java.util.function.Predicate; import java.util.logging.Logger; import org.w3c.dom.Document; @@ -45,7 +42,6 @@ public class FenceData implements IXmlReader private static final int MAX_Z_DIFF = 100; - private final Map> _regions = new ConcurrentHashMap<>(); private final Map _fences = new ConcurrentHashMap<>(); protected FenceData() @@ -104,18 +100,11 @@ public class FenceData implements IXmlReader private void addFence(FenceInstance fence) { _fences.put(fence.getObjectId(), fence); - _regions.computeIfAbsent(World.getInstance().getRegion(fence), key -> new ArrayList<>()).add(fence); } public void removeFence(FenceInstance fence) { _fences.remove(fence.getObjectId()); - - final List fencesInRegion = _regions.get(World.getInstance().getRegion(fence)); - if (fencesInRegion != null) - { - fencesInRegion.remove(fence); - } } public Map getFences() @@ -130,19 +119,26 @@ public class FenceData implements IXmlReader public boolean checkIfFenceBetween(int x, int y, int z, int tx, int ty, int tz, Instance instance) { - final Predicate filter = fence -> + final WorldRegion region = World.getInstance().getRegion(x, y); + final List fences = region != null ? region.getFences() : null; + if ((fences == null) || fences.isEmpty()) + { + return false; + } + + for (FenceInstance fence : fences) { // Check if fence is geodata enabled. if (!fence.getState().isGeodataEnabled()) { - return false; + continue; } // Check if fence is within the instance we search for. final int instanceId = (instance == null) ? 0 : instance.getId(); if (fence.getInstanceId() != instanceId) { - return false; + continue; } final int xMin = fence.getXMin(); @@ -151,34 +147,30 @@ public class FenceData implements IXmlReader final int yMax = fence.getYMax(); if ((x < xMin) && (tx < xMin)) { - return false; + continue; } if ((x > xMax) && (tx > xMax)) { - return false; + continue; } if ((y < yMin) && (ty < yMin)) { - return false; + continue; } if ((y > yMax) && (ty > yMax)) { - return false; + continue; } if ((x > xMin) && (tx > xMin) && (x < xMax) && (tx < xMax) && (y > yMin) && (ty > yMin) && (y < yMax) && (ty < yMax)) { - return false; + continue; } if ((crossLinePart(xMin, yMin, xMax, yMin, x, y, tx, ty, xMin, yMin, xMax, yMax) || crossLinePart(xMax, yMin, xMax, yMax, x, y, tx, ty, xMin, yMin, xMax, yMax) || crossLinePart(xMax, yMax, xMin, yMax, x, y, tx, ty, xMin, yMin, xMax, yMax) || crossLinePart(xMin, yMax, xMin, yMin, x, y, tx, ty, xMin, yMin, xMax, yMax)) && (z > (fence.getZ() - MAX_Z_DIFF)) && (z < (fence.getZ() + MAX_Z_DIFF))) { return true; } - - return false; - }; - - final WorldRegion region = World.getInstance().getRegion(x, y); // Should never be null. - return (region != null) && _regions.getOrDefault(region, Collections.emptyList()).stream().anyMatch(filter); + } + return false; } private boolean crossLinePart(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4, double xMin, double yMin, double xMax, double yMax) diff --git a/L2J_Mobius_Classic_2.1_Zaken/java/org/l2jmobius/gameserver/model/WorldObject.java b/L2J_Mobius_Classic_2.1_Zaken/java/org/l2jmobius/gameserver/model/WorldObject.java index b1292dd3d4..0e5536bbc0 100644 --- a/L2J_Mobius_Classic_2.1_Zaken/java/org/l2jmobius/gameserver/model/WorldObject.java +++ b/L2J_Mobius_Classic_2.1_Zaken/java/org/l2jmobius/gameserver/model/WorldObject.java @@ -412,6 +412,15 @@ public abstract class WorldObject extends ListenersContainer implements IIdentif return false; } + /** + * Verifies if this object is a fence. + * @return {@code true} if object is Fence, {@code false} otherwise + */ + public boolean isFence() + { + return false; + } + public void setTargetable(boolean targetable) { if (_isTargetable != targetable) diff --git a/L2J_Mobius_Classic_2.1_Zaken/java/org/l2jmobius/gameserver/model/WorldRegion.java b/L2J_Mobius_Classic_2.1_Zaken/java/org/l2jmobius/gameserver/model/WorldRegion.java index 8ad2649d3e..787947f2d7 100644 --- a/L2J_Mobius_Classic_2.1_Zaken/java/org/l2jmobius/gameserver/model/WorldRegion.java +++ b/L2J_Mobius_Classic_2.1_Zaken/java/org/l2jmobius/gameserver/model/WorldRegion.java @@ -25,6 +25,7 @@ import org.l2jmobius.commons.concurrent.ThreadPool; import org.l2jmobius.gameserver.model.actor.Attackable; import org.l2jmobius.gameserver.model.actor.Npc; import org.l2jmobius.gameserver.model.actor.instance.DoorInstance; +import org.l2jmobius.gameserver.model.actor.instance.FenceInstance; import org.l2jmobius.gameserver.taskmanager.RandomAnimationTaskManager; import org.l2jmobius.gameserver.util.UnboundArrayList; @@ -34,6 +35,8 @@ public class WorldRegion private final UnboundArrayList _visibleObjects = new UnboundArrayList<>(); /** List containing doors in this world region. */ private final List _doors = new ArrayList<>(1); + /** List containing fences in this world region. */ + private final List _fences = new ArrayList<>(1); /** Array containing nearby regions forming this world region's effective area. */ private WorldRegion[] _surroundingRegions; private final int _regionX; @@ -241,6 +244,13 @@ public class WorldRegion _surroundingRegions[i].addDoor((DoorInstance) object); } } + else if (object.isFence()) + { + for (int i = 0; i < _surroundingRegions.length; i++) + { + _surroundingRegions[i].addFence((FenceInstance) object); + } + } // If this is the first player to enter the region, activate self and neighbors. if (object.isPlayable() && !_active && !Config.GRIDS_ALWAYS_ON) @@ -271,7 +281,14 @@ public class WorldRegion { for (int i = 0; i < _surroundingRegions.length; i++) { - removeDoor((DoorInstance) object); + _surroundingRegions[i].removeDoor((DoorInstance) object); + } + } + else if (object.isFence()) + { + for (int i = 0; i < _surroundingRegions.length; i++) + { + _surroundingRegions[i].removeFence((FenceInstance) object); } } @@ -304,6 +321,24 @@ public class WorldRegion return _doors; } + public synchronized void addFence(FenceInstance fence) + { + if (!_fences.contains(fence)) + { + _fences.add(fence); + } + } + + private synchronized void removeFence(FenceInstance fence) + { + _fences.remove(fence); + } + + public List getFences() + { + return _fences; + } + public void setSurroundingRegions(WorldRegion[] regions) { _surroundingRegions = regions; diff --git a/L2J_Mobius_Classic_2.1_Zaken/java/org/l2jmobius/gameserver/model/actor/instance/FenceInstance.java b/L2J_Mobius_Classic_2.1_Zaken/java/org/l2jmobius/gameserver/model/actor/instance/FenceInstance.java index e933cff384..821a64b0f6 100644 --- a/L2J_Mobius_Classic_2.1_Zaken/java/org/l2jmobius/gameserver/model/actor/instance/FenceInstance.java +++ b/L2J_Mobius_Classic_2.1_Zaken/java/org/l2jmobius/gameserver/model/actor/instance/FenceInstance.java @@ -160,4 +160,10 @@ public class FenceInstance extends WorldObject { return _yMax; } + + @Override + public boolean isFence() + { + return true; + } } \ No newline at end of file diff --git a/L2J_Mobius_Classic_2.2_Antharas/java/org/l2jmobius/gameserver/data/xml/FenceData.java b/L2J_Mobius_Classic_2.2_Antharas/java/org/l2jmobius/gameserver/data/xml/FenceData.java index 10b68e2f34..cc647ecea2 100644 --- a/L2J_Mobius_Classic_2.2_Antharas/java/org/l2jmobius/gameserver/data/xml/FenceData.java +++ b/L2J_Mobius_Classic_2.2_Antharas/java/org/l2jmobius/gameserver/data/xml/FenceData.java @@ -17,12 +17,9 @@ package org.l2jmobius.gameserver.data.xml; import java.io.File; -import java.util.ArrayList; -import java.util.Collections; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; -import java.util.function.Predicate; import java.util.logging.Logger; import org.w3c.dom.Document; @@ -45,7 +42,6 @@ public class FenceData implements IXmlReader private static final int MAX_Z_DIFF = 100; - private final Map> _regions = new ConcurrentHashMap<>(); private final Map _fences = new ConcurrentHashMap<>(); protected FenceData() @@ -104,18 +100,11 @@ public class FenceData implements IXmlReader private void addFence(FenceInstance fence) { _fences.put(fence.getObjectId(), fence); - _regions.computeIfAbsent(World.getInstance().getRegion(fence), key -> new ArrayList<>()).add(fence); } public void removeFence(FenceInstance fence) { _fences.remove(fence.getObjectId()); - - final List fencesInRegion = _regions.get(World.getInstance().getRegion(fence)); - if (fencesInRegion != null) - { - fencesInRegion.remove(fence); - } } public Map getFences() @@ -130,19 +119,26 @@ public class FenceData implements IXmlReader public boolean checkIfFenceBetween(int x, int y, int z, int tx, int ty, int tz, Instance instance) { - final Predicate filter = fence -> + final WorldRegion region = World.getInstance().getRegion(x, y); + final List fences = region != null ? region.getFences() : null; + if ((fences == null) || fences.isEmpty()) + { + return false; + } + + for (FenceInstance fence : fences) { // Check if fence is geodata enabled. if (!fence.getState().isGeodataEnabled()) { - return false; + continue; } // Check if fence is within the instance we search for. final int instanceId = (instance == null) ? 0 : instance.getId(); if (fence.getInstanceId() != instanceId) { - return false; + continue; } final int xMin = fence.getXMin(); @@ -151,34 +147,30 @@ public class FenceData implements IXmlReader final int yMax = fence.getYMax(); if ((x < xMin) && (tx < xMin)) { - return false; + continue; } if ((x > xMax) && (tx > xMax)) { - return false; + continue; } if ((y < yMin) && (ty < yMin)) { - return false; + continue; } if ((y > yMax) && (ty > yMax)) { - return false; + continue; } if ((x > xMin) && (tx > xMin) && (x < xMax) && (tx < xMax) && (y > yMin) && (ty > yMin) && (y < yMax) && (ty < yMax)) { - return false; + continue; } if ((crossLinePart(xMin, yMin, xMax, yMin, x, y, tx, ty, xMin, yMin, xMax, yMax) || crossLinePart(xMax, yMin, xMax, yMax, x, y, tx, ty, xMin, yMin, xMax, yMax) || crossLinePart(xMax, yMax, xMin, yMax, x, y, tx, ty, xMin, yMin, xMax, yMax) || crossLinePart(xMin, yMax, xMin, yMin, x, y, tx, ty, xMin, yMin, xMax, yMax)) && (z > (fence.getZ() - MAX_Z_DIFF)) && (z < (fence.getZ() + MAX_Z_DIFF))) { return true; } - - return false; - }; - - final WorldRegion region = World.getInstance().getRegion(x, y); // Should never be null. - return (region != null) && _regions.getOrDefault(region, Collections.emptyList()).stream().anyMatch(filter); + } + return false; } private boolean crossLinePart(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4, double xMin, double yMin, double xMax, double yMax) diff --git a/L2J_Mobius_Classic_2.2_Antharas/java/org/l2jmobius/gameserver/model/WorldObject.java b/L2J_Mobius_Classic_2.2_Antharas/java/org/l2jmobius/gameserver/model/WorldObject.java index b1292dd3d4..0e5536bbc0 100644 --- a/L2J_Mobius_Classic_2.2_Antharas/java/org/l2jmobius/gameserver/model/WorldObject.java +++ b/L2J_Mobius_Classic_2.2_Antharas/java/org/l2jmobius/gameserver/model/WorldObject.java @@ -412,6 +412,15 @@ public abstract class WorldObject extends ListenersContainer implements IIdentif return false; } + /** + * Verifies if this object is a fence. + * @return {@code true} if object is Fence, {@code false} otherwise + */ + public boolean isFence() + { + return false; + } + public void setTargetable(boolean targetable) { if (_isTargetable != targetable) diff --git a/L2J_Mobius_Classic_2.2_Antharas/java/org/l2jmobius/gameserver/model/WorldRegion.java b/L2J_Mobius_Classic_2.2_Antharas/java/org/l2jmobius/gameserver/model/WorldRegion.java index 8ad2649d3e..787947f2d7 100644 --- a/L2J_Mobius_Classic_2.2_Antharas/java/org/l2jmobius/gameserver/model/WorldRegion.java +++ b/L2J_Mobius_Classic_2.2_Antharas/java/org/l2jmobius/gameserver/model/WorldRegion.java @@ -25,6 +25,7 @@ import org.l2jmobius.commons.concurrent.ThreadPool; import org.l2jmobius.gameserver.model.actor.Attackable; import org.l2jmobius.gameserver.model.actor.Npc; import org.l2jmobius.gameserver.model.actor.instance.DoorInstance; +import org.l2jmobius.gameserver.model.actor.instance.FenceInstance; import org.l2jmobius.gameserver.taskmanager.RandomAnimationTaskManager; import org.l2jmobius.gameserver.util.UnboundArrayList; @@ -34,6 +35,8 @@ public class WorldRegion private final UnboundArrayList _visibleObjects = new UnboundArrayList<>(); /** List containing doors in this world region. */ private final List _doors = new ArrayList<>(1); + /** List containing fences in this world region. */ + private final List _fences = new ArrayList<>(1); /** Array containing nearby regions forming this world region's effective area. */ private WorldRegion[] _surroundingRegions; private final int _regionX; @@ -241,6 +244,13 @@ public class WorldRegion _surroundingRegions[i].addDoor((DoorInstance) object); } } + else if (object.isFence()) + { + for (int i = 0; i < _surroundingRegions.length; i++) + { + _surroundingRegions[i].addFence((FenceInstance) object); + } + } // If this is the first player to enter the region, activate self and neighbors. if (object.isPlayable() && !_active && !Config.GRIDS_ALWAYS_ON) @@ -271,7 +281,14 @@ public class WorldRegion { for (int i = 0; i < _surroundingRegions.length; i++) { - removeDoor((DoorInstance) object); + _surroundingRegions[i].removeDoor((DoorInstance) object); + } + } + else if (object.isFence()) + { + for (int i = 0; i < _surroundingRegions.length; i++) + { + _surroundingRegions[i].removeFence((FenceInstance) object); } } @@ -304,6 +321,24 @@ public class WorldRegion return _doors; } + public synchronized void addFence(FenceInstance fence) + { + if (!_fences.contains(fence)) + { + _fences.add(fence); + } + } + + private synchronized void removeFence(FenceInstance fence) + { + _fences.remove(fence); + } + + public List getFences() + { + return _fences; + } + public void setSurroundingRegions(WorldRegion[] regions) { _surroundingRegions = regions; diff --git a/L2J_Mobius_Classic_2.2_Antharas/java/org/l2jmobius/gameserver/model/actor/instance/FenceInstance.java b/L2J_Mobius_Classic_2.2_Antharas/java/org/l2jmobius/gameserver/model/actor/instance/FenceInstance.java index e933cff384..821a64b0f6 100644 --- a/L2J_Mobius_Classic_2.2_Antharas/java/org/l2jmobius/gameserver/model/actor/instance/FenceInstance.java +++ b/L2J_Mobius_Classic_2.2_Antharas/java/org/l2jmobius/gameserver/model/actor/instance/FenceInstance.java @@ -160,4 +160,10 @@ public class FenceInstance extends WorldObject { return _yMax; } + + @Override + public boolean isFence() + { + return true; + } } \ No newline at end of file diff --git a/L2J_Mobius_Classic_2.3_SevenSigns/java/org/l2jmobius/gameserver/data/xml/FenceData.java b/L2J_Mobius_Classic_2.3_SevenSigns/java/org/l2jmobius/gameserver/data/xml/FenceData.java index 10b68e2f34..cc647ecea2 100644 --- a/L2J_Mobius_Classic_2.3_SevenSigns/java/org/l2jmobius/gameserver/data/xml/FenceData.java +++ b/L2J_Mobius_Classic_2.3_SevenSigns/java/org/l2jmobius/gameserver/data/xml/FenceData.java @@ -17,12 +17,9 @@ package org.l2jmobius.gameserver.data.xml; import java.io.File; -import java.util.ArrayList; -import java.util.Collections; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; -import java.util.function.Predicate; import java.util.logging.Logger; import org.w3c.dom.Document; @@ -45,7 +42,6 @@ public class FenceData implements IXmlReader private static final int MAX_Z_DIFF = 100; - private final Map> _regions = new ConcurrentHashMap<>(); private final Map _fences = new ConcurrentHashMap<>(); protected FenceData() @@ -104,18 +100,11 @@ public class FenceData implements IXmlReader private void addFence(FenceInstance fence) { _fences.put(fence.getObjectId(), fence); - _regions.computeIfAbsent(World.getInstance().getRegion(fence), key -> new ArrayList<>()).add(fence); } public void removeFence(FenceInstance fence) { _fences.remove(fence.getObjectId()); - - final List fencesInRegion = _regions.get(World.getInstance().getRegion(fence)); - if (fencesInRegion != null) - { - fencesInRegion.remove(fence); - } } public Map getFences() @@ -130,19 +119,26 @@ public class FenceData implements IXmlReader public boolean checkIfFenceBetween(int x, int y, int z, int tx, int ty, int tz, Instance instance) { - final Predicate filter = fence -> + final WorldRegion region = World.getInstance().getRegion(x, y); + final List fences = region != null ? region.getFences() : null; + if ((fences == null) || fences.isEmpty()) + { + return false; + } + + for (FenceInstance fence : fences) { // Check if fence is geodata enabled. if (!fence.getState().isGeodataEnabled()) { - return false; + continue; } // Check if fence is within the instance we search for. final int instanceId = (instance == null) ? 0 : instance.getId(); if (fence.getInstanceId() != instanceId) { - return false; + continue; } final int xMin = fence.getXMin(); @@ -151,34 +147,30 @@ public class FenceData implements IXmlReader final int yMax = fence.getYMax(); if ((x < xMin) && (tx < xMin)) { - return false; + continue; } if ((x > xMax) && (tx > xMax)) { - return false; + continue; } if ((y < yMin) && (ty < yMin)) { - return false; + continue; } if ((y > yMax) && (ty > yMax)) { - return false; + continue; } if ((x > xMin) && (tx > xMin) && (x < xMax) && (tx < xMax) && (y > yMin) && (ty > yMin) && (y < yMax) && (ty < yMax)) { - return false; + continue; } if ((crossLinePart(xMin, yMin, xMax, yMin, x, y, tx, ty, xMin, yMin, xMax, yMax) || crossLinePart(xMax, yMin, xMax, yMax, x, y, tx, ty, xMin, yMin, xMax, yMax) || crossLinePart(xMax, yMax, xMin, yMax, x, y, tx, ty, xMin, yMin, xMax, yMax) || crossLinePart(xMin, yMax, xMin, yMin, x, y, tx, ty, xMin, yMin, xMax, yMax)) && (z > (fence.getZ() - MAX_Z_DIFF)) && (z < (fence.getZ() + MAX_Z_DIFF))) { return true; } - - return false; - }; - - final WorldRegion region = World.getInstance().getRegion(x, y); // Should never be null. - return (region != null) && _regions.getOrDefault(region, Collections.emptyList()).stream().anyMatch(filter); + } + return false; } private boolean crossLinePart(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4, double xMin, double yMin, double xMax, double yMax) diff --git a/L2J_Mobius_Classic_2.3_SevenSigns/java/org/l2jmobius/gameserver/model/WorldObject.java b/L2J_Mobius_Classic_2.3_SevenSigns/java/org/l2jmobius/gameserver/model/WorldObject.java index b1292dd3d4..0e5536bbc0 100644 --- a/L2J_Mobius_Classic_2.3_SevenSigns/java/org/l2jmobius/gameserver/model/WorldObject.java +++ b/L2J_Mobius_Classic_2.3_SevenSigns/java/org/l2jmobius/gameserver/model/WorldObject.java @@ -412,6 +412,15 @@ public abstract class WorldObject extends ListenersContainer implements IIdentif return false; } + /** + * Verifies if this object is a fence. + * @return {@code true} if object is Fence, {@code false} otherwise + */ + public boolean isFence() + { + return false; + } + public void setTargetable(boolean targetable) { if (_isTargetable != targetable) diff --git a/L2J_Mobius_Classic_2.3_SevenSigns/java/org/l2jmobius/gameserver/model/WorldRegion.java b/L2J_Mobius_Classic_2.3_SevenSigns/java/org/l2jmobius/gameserver/model/WorldRegion.java index 8ad2649d3e..787947f2d7 100644 --- a/L2J_Mobius_Classic_2.3_SevenSigns/java/org/l2jmobius/gameserver/model/WorldRegion.java +++ b/L2J_Mobius_Classic_2.3_SevenSigns/java/org/l2jmobius/gameserver/model/WorldRegion.java @@ -25,6 +25,7 @@ import org.l2jmobius.commons.concurrent.ThreadPool; import org.l2jmobius.gameserver.model.actor.Attackable; import org.l2jmobius.gameserver.model.actor.Npc; import org.l2jmobius.gameserver.model.actor.instance.DoorInstance; +import org.l2jmobius.gameserver.model.actor.instance.FenceInstance; import org.l2jmobius.gameserver.taskmanager.RandomAnimationTaskManager; import org.l2jmobius.gameserver.util.UnboundArrayList; @@ -34,6 +35,8 @@ public class WorldRegion private final UnboundArrayList _visibleObjects = new UnboundArrayList<>(); /** List containing doors in this world region. */ private final List _doors = new ArrayList<>(1); + /** List containing fences in this world region. */ + private final List _fences = new ArrayList<>(1); /** Array containing nearby regions forming this world region's effective area. */ private WorldRegion[] _surroundingRegions; private final int _regionX; @@ -241,6 +244,13 @@ public class WorldRegion _surroundingRegions[i].addDoor((DoorInstance) object); } } + else if (object.isFence()) + { + for (int i = 0; i < _surroundingRegions.length; i++) + { + _surroundingRegions[i].addFence((FenceInstance) object); + } + } // If this is the first player to enter the region, activate self and neighbors. if (object.isPlayable() && !_active && !Config.GRIDS_ALWAYS_ON) @@ -271,7 +281,14 @@ public class WorldRegion { for (int i = 0; i < _surroundingRegions.length; i++) { - removeDoor((DoorInstance) object); + _surroundingRegions[i].removeDoor((DoorInstance) object); + } + } + else if (object.isFence()) + { + for (int i = 0; i < _surroundingRegions.length; i++) + { + _surroundingRegions[i].removeFence((FenceInstance) object); } } @@ -304,6 +321,24 @@ public class WorldRegion return _doors; } + public synchronized void addFence(FenceInstance fence) + { + if (!_fences.contains(fence)) + { + _fences.add(fence); + } + } + + private synchronized void removeFence(FenceInstance fence) + { + _fences.remove(fence); + } + + public List getFences() + { + return _fences; + } + public void setSurroundingRegions(WorldRegion[] regions) { _surroundingRegions = regions; diff --git a/L2J_Mobius_Classic_2.3_SevenSigns/java/org/l2jmobius/gameserver/model/actor/instance/FenceInstance.java b/L2J_Mobius_Classic_2.3_SevenSigns/java/org/l2jmobius/gameserver/model/actor/instance/FenceInstance.java index e933cff384..821a64b0f6 100644 --- a/L2J_Mobius_Classic_2.3_SevenSigns/java/org/l2jmobius/gameserver/model/actor/instance/FenceInstance.java +++ b/L2J_Mobius_Classic_2.3_SevenSigns/java/org/l2jmobius/gameserver/model/actor/instance/FenceInstance.java @@ -160,4 +160,10 @@ public class FenceInstance extends WorldObject { return _yMax; } + + @Override + public boolean isFence() + { + return true; + } } \ No newline at end of file diff --git a/L2J_Mobius_Classic_2.4_SecretOfEmpire/java/org/l2jmobius/gameserver/data/xml/FenceData.java b/L2J_Mobius_Classic_2.4_SecretOfEmpire/java/org/l2jmobius/gameserver/data/xml/FenceData.java index 10b68e2f34..cc647ecea2 100644 --- a/L2J_Mobius_Classic_2.4_SecretOfEmpire/java/org/l2jmobius/gameserver/data/xml/FenceData.java +++ b/L2J_Mobius_Classic_2.4_SecretOfEmpire/java/org/l2jmobius/gameserver/data/xml/FenceData.java @@ -17,12 +17,9 @@ package org.l2jmobius.gameserver.data.xml; import java.io.File; -import java.util.ArrayList; -import java.util.Collections; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; -import java.util.function.Predicate; import java.util.logging.Logger; import org.w3c.dom.Document; @@ -45,7 +42,6 @@ public class FenceData implements IXmlReader private static final int MAX_Z_DIFF = 100; - private final Map> _regions = new ConcurrentHashMap<>(); private final Map _fences = new ConcurrentHashMap<>(); protected FenceData() @@ -104,18 +100,11 @@ public class FenceData implements IXmlReader private void addFence(FenceInstance fence) { _fences.put(fence.getObjectId(), fence); - _regions.computeIfAbsent(World.getInstance().getRegion(fence), key -> new ArrayList<>()).add(fence); } public void removeFence(FenceInstance fence) { _fences.remove(fence.getObjectId()); - - final List fencesInRegion = _regions.get(World.getInstance().getRegion(fence)); - if (fencesInRegion != null) - { - fencesInRegion.remove(fence); - } } public Map getFences() @@ -130,19 +119,26 @@ public class FenceData implements IXmlReader public boolean checkIfFenceBetween(int x, int y, int z, int tx, int ty, int tz, Instance instance) { - final Predicate filter = fence -> + final WorldRegion region = World.getInstance().getRegion(x, y); + final List fences = region != null ? region.getFences() : null; + if ((fences == null) || fences.isEmpty()) + { + return false; + } + + for (FenceInstance fence : fences) { // Check if fence is geodata enabled. if (!fence.getState().isGeodataEnabled()) { - return false; + continue; } // Check if fence is within the instance we search for. final int instanceId = (instance == null) ? 0 : instance.getId(); if (fence.getInstanceId() != instanceId) { - return false; + continue; } final int xMin = fence.getXMin(); @@ -151,34 +147,30 @@ public class FenceData implements IXmlReader final int yMax = fence.getYMax(); if ((x < xMin) && (tx < xMin)) { - return false; + continue; } if ((x > xMax) && (tx > xMax)) { - return false; + continue; } if ((y < yMin) && (ty < yMin)) { - return false; + continue; } if ((y > yMax) && (ty > yMax)) { - return false; + continue; } if ((x > xMin) && (tx > xMin) && (x < xMax) && (tx < xMax) && (y > yMin) && (ty > yMin) && (y < yMax) && (ty < yMax)) { - return false; + continue; } if ((crossLinePart(xMin, yMin, xMax, yMin, x, y, tx, ty, xMin, yMin, xMax, yMax) || crossLinePart(xMax, yMin, xMax, yMax, x, y, tx, ty, xMin, yMin, xMax, yMax) || crossLinePart(xMax, yMax, xMin, yMax, x, y, tx, ty, xMin, yMin, xMax, yMax) || crossLinePart(xMin, yMax, xMin, yMin, x, y, tx, ty, xMin, yMin, xMax, yMax)) && (z > (fence.getZ() - MAX_Z_DIFF)) && (z < (fence.getZ() + MAX_Z_DIFF))) { return true; } - - return false; - }; - - final WorldRegion region = World.getInstance().getRegion(x, y); // Should never be null. - return (region != null) && _regions.getOrDefault(region, Collections.emptyList()).stream().anyMatch(filter); + } + return false; } private boolean crossLinePart(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4, double xMin, double yMin, double xMax, double yMax) diff --git a/L2J_Mobius_Classic_2.4_SecretOfEmpire/java/org/l2jmobius/gameserver/model/WorldObject.java b/L2J_Mobius_Classic_2.4_SecretOfEmpire/java/org/l2jmobius/gameserver/model/WorldObject.java index b1292dd3d4..0e5536bbc0 100644 --- a/L2J_Mobius_Classic_2.4_SecretOfEmpire/java/org/l2jmobius/gameserver/model/WorldObject.java +++ b/L2J_Mobius_Classic_2.4_SecretOfEmpire/java/org/l2jmobius/gameserver/model/WorldObject.java @@ -412,6 +412,15 @@ public abstract class WorldObject extends ListenersContainer implements IIdentif return false; } + /** + * Verifies if this object is a fence. + * @return {@code true} if object is Fence, {@code false} otherwise + */ + public boolean isFence() + { + return false; + } + public void setTargetable(boolean targetable) { if (_isTargetable != targetable) diff --git a/L2J_Mobius_Classic_2.4_SecretOfEmpire/java/org/l2jmobius/gameserver/model/WorldRegion.java b/L2J_Mobius_Classic_2.4_SecretOfEmpire/java/org/l2jmobius/gameserver/model/WorldRegion.java index 8ad2649d3e..787947f2d7 100644 --- a/L2J_Mobius_Classic_2.4_SecretOfEmpire/java/org/l2jmobius/gameserver/model/WorldRegion.java +++ b/L2J_Mobius_Classic_2.4_SecretOfEmpire/java/org/l2jmobius/gameserver/model/WorldRegion.java @@ -25,6 +25,7 @@ import org.l2jmobius.commons.concurrent.ThreadPool; import org.l2jmobius.gameserver.model.actor.Attackable; import org.l2jmobius.gameserver.model.actor.Npc; import org.l2jmobius.gameserver.model.actor.instance.DoorInstance; +import org.l2jmobius.gameserver.model.actor.instance.FenceInstance; import org.l2jmobius.gameserver.taskmanager.RandomAnimationTaskManager; import org.l2jmobius.gameserver.util.UnboundArrayList; @@ -34,6 +35,8 @@ public class WorldRegion private final UnboundArrayList _visibleObjects = new UnboundArrayList<>(); /** List containing doors in this world region. */ private final List _doors = new ArrayList<>(1); + /** List containing fences in this world region. */ + private final List _fences = new ArrayList<>(1); /** Array containing nearby regions forming this world region's effective area. */ private WorldRegion[] _surroundingRegions; private final int _regionX; @@ -241,6 +244,13 @@ public class WorldRegion _surroundingRegions[i].addDoor((DoorInstance) object); } } + else if (object.isFence()) + { + for (int i = 0; i < _surroundingRegions.length; i++) + { + _surroundingRegions[i].addFence((FenceInstance) object); + } + } // If this is the first player to enter the region, activate self and neighbors. if (object.isPlayable() && !_active && !Config.GRIDS_ALWAYS_ON) @@ -271,7 +281,14 @@ public class WorldRegion { for (int i = 0; i < _surroundingRegions.length; i++) { - removeDoor((DoorInstance) object); + _surroundingRegions[i].removeDoor((DoorInstance) object); + } + } + else if (object.isFence()) + { + for (int i = 0; i < _surroundingRegions.length; i++) + { + _surroundingRegions[i].removeFence((FenceInstance) object); } } @@ -304,6 +321,24 @@ public class WorldRegion return _doors; } + public synchronized void addFence(FenceInstance fence) + { + if (!_fences.contains(fence)) + { + _fences.add(fence); + } + } + + private synchronized void removeFence(FenceInstance fence) + { + _fences.remove(fence); + } + + public List getFences() + { + return _fences; + } + public void setSurroundingRegions(WorldRegion[] regions) { _surroundingRegions = regions; diff --git a/L2J_Mobius_Classic_2.4_SecretOfEmpire/java/org/l2jmobius/gameserver/model/actor/instance/FenceInstance.java b/L2J_Mobius_Classic_2.4_SecretOfEmpire/java/org/l2jmobius/gameserver/model/actor/instance/FenceInstance.java index e933cff384..821a64b0f6 100644 --- a/L2J_Mobius_Classic_2.4_SecretOfEmpire/java/org/l2jmobius/gameserver/model/actor/instance/FenceInstance.java +++ b/L2J_Mobius_Classic_2.4_SecretOfEmpire/java/org/l2jmobius/gameserver/model/actor/instance/FenceInstance.java @@ -160,4 +160,10 @@ public class FenceInstance extends WorldObject { return _yMax; } + + @Override + public boolean isFence() + { + return true; + } } \ No newline at end of file diff --git a/L2J_Mobius_Classic_3.0_TheKamael/java/org/l2jmobius/gameserver/data/xml/FenceData.java b/L2J_Mobius_Classic_3.0_TheKamael/java/org/l2jmobius/gameserver/data/xml/FenceData.java index 10b68e2f34..cc647ecea2 100644 --- a/L2J_Mobius_Classic_3.0_TheKamael/java/org/l2jmobius/gameserver/data/xml/FenceData.java +++ b/L2J_Mobius_Classic_3.0_TheKamael/java/org/l2jmobius/gameserver/data/xml/FenceData.java @@ -17,12 +17,9 @@ package org.l2jmobius.gameserver.data.xml; import java.io.File; -import java.util.ArrayList; -import java.util.Collections; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; -import java.util.function.Predicate; import java.util.logging.Logger; import org.w3c.dom.Document; @@ -45,7 +42,6 @@ public class FenceData implements IXmlReader private static final int MAX_Z_DIFF = 100; - private final Map> _regions = new ConcurrentHashMap<>(); private final Map _fences = new ConcurrentHashMap<>(); protected FenceData() @@ -104,18 +100,11 @@ public class FenceData implements IXmlReader private void addFence(FenceInstance fence) { _fences.put(fence.getObjectId(), fence); - _regions.computeIfAbsent(World.getInstance().getRegion(fence), key -> new ArrayList<>()).add(fence); } public void removeFence(FenceInstance fence) { _fences.remove(fence.getObjectId()); - - final List fencesInRegion = _regions.get(World.getInstance().getRegion(fence)); - if (fencesInRegion != null) - { - fencesInRegion.remove(fence); - } } public Map getFences() @@ -130,19 +119,26 @@ public class FenceData implements IXmlReader public boolean checkIfFenceBetween(int x, int y, int z, int tx, int ty, int tz, Instance instance) { - final Predicate filter = fence -> + final WorldRegion region = World.getInstance().getRegion(x, y); + final List fences = region != null ? region.getFences() : null; + if ((fences == null) || fences.isEmpty()) + { + return false; + } + + for (FenceInstance fence : fences) { // Check if fence is geodata enabled. if (!fence.getState().isGeodataEnabled()) { - return false; + continue; } // Check if fence is within the instance we search for. final int instanceId = (instance == null) ? 0 : instance.getId(); if (fence.getInstanceId() != instanceId) { - return false; + continue; } final int xMin = fence.getXMin(); @@ -151,34 +147,30 @@ public class FenceData implements IXmlReader final int yMax = fence.getYMax(); if ((x < xMin) && (tx < xMin)) { - return false; + continue; } if ((x > xMax) && (tx > xMax)) { - return false; + continue; } if ((y < yMin) && (ty < yMin)) { - return false; + continue; } if ((y > yMax) && (ty > yMax)) { - return false; + continue; } if ((x > xMin) && (tx > xMin) && (x < xMax) && (tx < xMax) && (y > yMin) && (ty > yMin) && (y < yMax) && (ty < yMax)) { - return false; + continue; } if ((crossLinePart(xMin, yMin, xMax, yMin, x, y, tx, ty, xMin, yMin, xMax, yMax) || crossLinePart(xMax, yMin, xMax, yMax, x, y, tx, ty, xMin, yMin, xMax, yMax) || crossLinePart(xMax, yMax, xMin, yMax, x, y, tx, ty, xMin, yMin, xMax, yMax) || crossLinePart(xMin, yMax, xMin, yMin, x, y, tx, ty, xMin, yMin, xMax, yMax)) && (z > (fence.getZ() - MAX_Z_DIFF)) && (z < (fence.getZ() + MAX_Z_DIFF))) { return true; } - - return false; - }; - - final WorldRegion region = World.getInstance().getRegion(x, y); // Should never be null. - return (region != null) && _regions.getOrDefault(region, Collections.emptyList()).stream().anyMatch(filter); + } + return false; } private boolean crossLinePart(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4, double xMin, double yMin, double xMax, double yMax) diff --git a/L2J_Mobius_Classic_3.0_TheKamael/java/org/l2jmobius/gameserver/model/WorldObject.java b/L2J_Mobius_Classic_3.0_TheKamael/java/org/l2jmobius/gameserver/model/WorldObject.java index b1292dd3d4..0e5536bbc0 100644 --- a/L2J_Mobius_Classic_3.0_TheKamael/java/org/l2jmobius/gameserver/model/WorldObject.java +++ b/L2J_Mobius_Classic_3.0_TheKamael/java/org/l2jmobius/gameserver/model/WorldObject.java @@ -412,6 +412,15 @@ public abstract class WorldObject extends ListenersContainer implements IIdentif return false; } + /** + * Verifies if this object is a fence. + * @return {@code true} if object is Fence, {@code false} otherwise + */ + public boolean isFence() + { + return false; + } + public void setTargetable(boolean targetable) { if (_isTargetable != targetable) diff --git a/L2J_Mobius_Classic_3.0_TheKamael/java/org/l2jmobius/gameserver/model/WorldRegion.java b/L2J_Mobius_Classic_3.0_TheKamael/java/org/l2jmobius/gameserver/model/WorldRegion.java index 8ad2649d3e..787947f2d7 100644 --- a/L2J_Mobius_Classic_3.0_TheKamael/java/org/l2jmobius/gameserver/model/WorldRegion.java +++ b/L2J_Mobius_Classic_3.0_TheKamael/java/org/l2jmobius/gameserver/model/WorldRegion.java @@ -25,6 +25,7 @@ import org.l2jmobius.commons.concurrent.ThreadPool; import org.l2jmobius.gameserver.model.actor.Attackable; import org.l2jmobius.gameserver.model.actor.Npc; import org.l2jmobius.gameserver.model.actor.instance.DoorInstance; +import org.l2jmobius.gameserver.model.actor.instance.FenceInstance; import org.l2jmobius.gameserver.taskmanager.RandomAnimationTaskManager; import org.l2jmobius.gameserver.util.UnboundArrayList; @@ -34,6 +35,8 @@ public class WorldRegion private final UnboundArrayList _visibleObjects = new UnboundArrayList<>(); /** List containing doors in this world region. */ private final List _doors = new ArrayList<>(1); + /** List containing fences in this world region. */ + private final List _fences = new ArrayList<>(1); /** Array containing nearby regions forming this world region's effective area. */ private WorldRegion[] _surroundingRegions; private final int _regionX; @@ -241,6 +244,13 @@ public class WorldRegion _surroundingRegions[i].addDoor((DoorInstance) object); } } + else if (object.isFence()) + { + for (int i = 0; i < _surroundingRegions.length; i++) + { + _surroundingRegions[i].addFence((FenceInstance) object); + } + } // If this is the first player to enter the region, activate self and neighbors. if (object.isPlayable() && !_active && !Config.GRIDS_ALWAYS_ON) @@ -271,7 +281,14 @@ public class WorldRegion { for (int i = 0; i < _surroundingRegions.length; i++) { - removeDoor((DoorInstance) object); + _surroundingRegions[i].removeDoor((DoorInstance) object); + } + } + else if (object.isFence()) + { + for (int i = 0; i < _surroundingRegions.length; i++) + { + _surroundingRegions[i].removeFence((FenceInstance) object); } } @@ -304,6 +321,24 @@ public class WorldRegion return _doors; } + public synchronized void addFence(FenceInstance fence) + { + if (!_fences.contains(fence)) + { + _fences.add(fence); + } + } + + private synchronized void removeFence(FenceInstance fence) + { + _fences.remove(fence); + } + + public List getFences() + { + return _fences; + } + public void setSurroundingRegions(WorldRegion[] regions) { _surroundingRegions = regions; diff --git a/L2J_Mobius_Classic_3.0_TheKamael/java/org/l2jmobius/gameserver/model/actor/instance/FenceInstance.java b/L2J_Mobius_Classic_3.0_TheKamael/java/org/l2jmobius/gameserver/model/actor/instance/FenceInstance.java index e933cff384..821a64b0f6 100644 --- a/L2J_Mobius_Classic_3.0_TheKamael/java/org/l2jmobius/gameserver/model/actor/instance/FenceInstance.java +++ b/L2J_Mobius_Classic_3.0_TheKamael/java/org/l2jmobius/gameserver/model/actor/instance/FenceInstance.java @@ -160,4 +160,10 @@ public class FenceInstance extends WorldObject { return _yMax; } + + @Override + public boolean isFence() + { + return true; + } } \ No newline at end of file diff --git a/L2J_Mobius_Classic_Interlude/java/org/l2jmobius/gameserver/data/xml/FenceData.java b/L2J_Mobius_Classic_Interlude/java/org/l2jmobius/gameserver/data/xml/FenceData.java index 10b68e2f34..cc647ecea2 100644 --- a/L2J_Mobius_Classic_Interlude/java/org/l2jmobius/gameserver/data/xml/FenceData.java +++ b/L2J_Mobius_Classic_Interlude/java/org/l2jmobius/gameserver/data/xml/FenceData.java @@ -17,12 +17,9 @@ package org.l2jmobius.gameserver.data.xml; import java.io.File; -import java.util.ArrayList; -import java.util.Collections; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; -import java.util.function.Predicate; import java.util.logging.Logger; import org.w3c.dom.Document; @@ -45,7 +42,6 @@ public class FenceData implements IXmlReader private static final int MAX_Z_DIFF = 100; - private final Map> _regions = new ConcurrentHashMap<>(); private final Map _fences = new ConcurrentHashMap<>(); protected FenceData() @@ -104,18 +100,11 @@ public class FenceData implements IXmlReader private void addFence(FenceInstance fence) { _fences.put(fence.getObjectId(), fence); - _regions.computeIfAbsent(World.getInstance().getRegion(fence), key -> new ArrayList<>()).add(fence); } public void removeFence(FenceInstance fence) { _fences.remove(fence.getObjectId()); - - final List fencesInRegion = _regions.get(World.getInstance().getRegion(fence)); - if (fencesInRegion != null) - { - fencesInRegion.remove(fence); - } } public Map getFences() @@ -130,19 +119,26 @@ public class FenceData implements IXmlReader public boolean checkIfFenceBetween(int x, int y, int z, int tx, int ty, int tz, Instance instance) { - final Predicate filter = fence -> + final WorldRegion region = World.getInstance().getRegion(x, y); + final List fences = region != null ? region.getFences() : null; + if ((fences == null) || fences.isEmpty()) + { + return false; + } + + for (FenceInstance fence : fences) { // Check if fence is geodata enabled. if (!fence.getState().isGeodataEnabled()) { - return false; + continue; } // Check if fence is within the instance we search for. final int instanceId = (instance == null) ? 0 : instance.getId(); if (fence.getInstanceId() != instanceId) { - return false; + continue; } final int xMin = fence.getXMin(); @@ -151,34 +147,30 @@ public class FenceData implements IXmlReader final int yMax = fence.getYMax(); if ((x < xMin) && (tx < xMin)) { - return false; + continue; } if ((x > xMax) && (tx > xMax)) { - return false; + continue; } if ((y < yMin) && (ty < yMin)) { - return false; + continue; } if ((y > yMax) && (ty > yMax)) { - return false; + continue; } if ((x > xMin) && (tx > xMin) && (x < xMax) && (tx < xMax) && (y > yMin) && (ty > yMin) && (y < yMax) && (ty < yMax)) { - return false; + continue; } if ((crossLinePart(xMin, yMin, xMax, yMin, x, y, tx, ty, xMin, yMin, xMax, yMax) || crossLinePart(xMax, yMin, xMax, yMax, x, y, tx, ty, xMin, yMin, xMax, yMax) || crossLinePart(xMax, yMax, xMin, yMax, x, y, tx, ty, xMin, yMin, xMax, yMax) || crossLinePart(xMin, yMax, xMin, yMin, x, y, tx, ty, xMin, yMin, xMax, yMax)) && (z > (fence.getZ() - MAX_Z_DIFF)) && (z < (fence.getZ() + MAX_Z_DIFF))) { return true; } - - return false; - }; - - final WorldRegion region = World.getInstance().getRegion(x, y); // Should never be null. - return (region != null) && _regions.getOrDefault(region, Collections.emptyList()).stream().anyMatch(filter); + } + return false; } private boolean crossLinePart(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4, double xMin, double yMin, double xMax, double yMax) diff --git a/L2J_Mobius_Classic_Interlude/java/org/l2jmobius/gameserver/model/WorldObject.java b/L2J_Mobius_Classic_Interlude/java/org/l2jmobius/gameserver/model/WorldObject.java index b1292dd3d4..0e5536bbc0 100644 --- a/L2J_Mobius_Classic_Interlude/java/org/l2jmobius/gameserver/model/WorldObject.java +++ b/L2J_Mobius_Classic_Interlude/java/org/l2jmobius/gameserver/model/WorldObject.java @@ -412,6 +412,15 @@ public abstract class WorldObject extends ListenersContainer implements IIdentif return false; } + /** + * Verifies if this object is a fence. + * @return {@code true} if object is Fence, {@code false} otherwise + */ + public boolean isFence() + { + return false; + } + public void setTargetable(boolean targetable) { if (_isTargetable != targetable) diff --git a/L2J_Mobius_Classic_Interlude/java/org/l2jmobius/gameserver/model/WorldRegion.java b/L2J_Mobius_Classic_Interlude/java/org/l2jmobius/gameserver/model/WorldRegion.java index 8ad2649d3e..787947f2d7 100644 --- a/L2J_Mobius_Classic_Interlude/java/org/l2jmobius/gameserver/model/WorldRegion.java +++ b/L2J_Mobius_Classic_Interlude/java/org/l2jmobius/gameserver/model/WorldRegion.java @@ -25,6 +25,7 @@ import org.l2jmobius.commons.concurrent.ThreadPool; import org.l2jmobius.gameserver.model.actor.Attackable; import org.l2jmobius.gameserver.model.actor.Npc; import org.l2jmobius.gameserver.model.actor.instance.DoorInstance; +import org.l2jmobius.gameserver.model.actor.instance.FenceInstance; import org.l2jmobius.gameserver.taskmanager.RandomAnimationTaskManager; import org.l2jmobius.gameserver.util.UnboundArrayList; @@ -34,6 +35,8 @@ public class WorldRegion private final UnboundArrayList _visibleObjects = new UnboundArrayList<>(); /** List containing doors in this world region. */ private final List _doors = new ArrayList<>(1); + /** List containing fences in this world region. */ + private final List _fences = new ArrayList<>(1); /** Array containing nearby regions forming this world region's effective area. */ private WorldRegion[] _surroundingRegions; private final int _regionX; @@ -241,6 +244,13 @@ public class WorldRegion _surroundingRegions[i].addDoor((DoorInstance) object); } } + else if (object.isFence()) + { + for (int i = 0; i < _surroundingRegions.length; i++) + { + _surroundingRegions[i].addFence((FenceInstance) object); + } + } // If this is the first player to enter the region, activate self and neighbors. if (object.isPlayable() && !_active && !Config.GRIDS_ALWAYS_ON) @@ -271,7 +281,14 @@ public class WorldRegion { for (int i = 0; i < _surroundingRegions.length; i++) { - removeDoor((DoorInstance) object); + _surroundingRegions[i].removeDoor((DoorInstance) object); + } + } + else if (object.isFence()) + { + for (int i = 0; i < _surroundingRegions.length; i++) + { + _surroundingRegions[i].removeFence((FenceInstance) object); } } @@ -304,6 +321,24 @@ public class WorldRegion return _doors; } + public synchronized void addFence(FenceInstance fence) + { + if (!_fences.contains(fence)) + { + _fences.add(fence); + } + } + + private synchronized void removeFence(FenceInstance fence) + { + _fences.remove(fence); + } + + public List getFences() + { + return _fences; + } + public void setSurroundingRegions(WorldRegion[] regions) { _surroundingRegions = regions; diff --git a/L2J_Mobius_Classic_Interlude/java/org/l2jmobius/gameserver/model/actor/instance/FenceInstance.java b/L2J_Mobius_Classic_Interlude/java/org/l2jmobius/gameserver/model/actor/instance/FenceInstance.java index e933cff384..821a64b0f6 100644 --- a/L2J_Mobius_Classic_Interlude/java/org/l2jmobius/gameserver/model/actor/instance/FenceInstance.java +++ b/L2J_Mobius_Classic_Interlude/java/org/l2jmobius/gameserver/model/actor/instance/FenceInstance.java @@ -160,4 +160,10 @@ public class FenceInstance extends WorldObject { return _yMax; } + + @Override + public boolean isFence() + { + return true; + } } \ No newline at end of file diff --git a/L2J_Mobius_Essence_4.0_DwellingOfSpirits/java/org/l2jmobius/gameserver/data/xml/FenceData.java b/L2J_Mobius_Essence_4.0_DwellingOfSpirits/java/org/l2jmobius/gameserver/data/xml/FenceData.java index 10b68e2f34..cc647ecea2 100644 --- a/L2J_Mobius_Essence_4.0_DwellingOfSpirits/java/org/l2jmobius/gameserver/data/xml/FenceData.java +++ b/L2J_Mobius_Essence_4.0_DwellingOfSpirits/java/org/l2jmobius/gameserver/data/xml/FenceData.java @@ -17,12 +17,9 @@ package org.l2jmobius.gameserver.data.xml; import java.io.File; -import java.util.ArrayList; -import java.util.Collections; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; -import java.util.function.Predicate; import java.util.logging.Logger; import org.w3c.dom.Document; @@ -45,7 +42,6 @@ public class FenceData implements IXmlReader private static final int MAX_Z_DIFF = 100; - private final Map> _regions = new ConcurrentHashMap<>(); private final Map _fences = new ConcurrentHashMap<>(); protected FenceData() @@ -104,18 +100,11 @@ public class FenceData implements IXmlReader private void addFence(FenceInstance fence) { _fences.put(fence.getObjectId(), fence); - _regions.computeIfAbsent(World.getInstance().getRegion(fence), key -> new ArrayList<>()).add(fence); } public void removeFence(FenceInstance fence) { _fences.remove(fence.getObjectId()); - - final List fencesInRegion = _regions.get(World.getInstance().getRegion(fence)); - if (fencesInRegion != null) - { - fencesInRegion.remove(fence); - } } public Map getFences() @@ -130,19 +119,26 @@ public class FenceData implements IXmlReader public boolean checkIfFenceBetween(int x, int y, int z, int tx, int ty, int tz, Instance instance) { - final Predicate filter = fence -> + final WorldRegion region = World.getInstance().getRegion(x, y); + final List fences = region != null ? region.getFences() : null; + if ((fences == null) || fences.isEmpty()) + { + return false; + } + + for (FenceInstance fence : fences) { // Check if fence is geodata enabled. if (!fence.getState().isGeodataEnabled()) { - return false; + continue; } // Check if fence is within the instance we search for. final int instanceId = (instance == null) ? 0 : instance.getId(); if (fence.getInstanceId() != instanceId) { - return false; + continue; } final int xMin = fence.getXMin(); @@ -151,34 +147,30 @@ public class FenceData implements IXmlReader final int yMax = fence.getYMax(); if ((x < xMin) && (tx < xMin)) { - return false; + continue; } if ((x > xMax) && (tx > xMax)) { - return false; + continue; } if ((y < yMin) && (ty < yMin)) { - return false; + continue; } if ((y > yMax) && (ty > yMax)) { - return false; + continue; } if ((x > xMin) && (tx > xMin) && (x < xMax) && (tx < xMax) && (y > yMin) && (ty > yMin) && (y < yMax) && (ty < yMax)) { - return false; + continue; } if ((crossLinePart(xMin, yMin, xMax, yMin, x, y, tx, ty, xMin, yMin, xMax, yMax) || crossLinePart(xMax, yMin, xMax, yMax, x, y, tx, ty, xMin, yMin, xMax, yMax) || crossLinePart(xMax, yMax, xMin, yMax, x, y, tx, ty, xMin, yMin, xMax, yMax) || crossLinePart(xMin, yMax, xMin, yMin, x, y, tx, ty, xMin, yMin, xMax, yMax)) && (z > (fence.getZ() - MAX_Z_DIFF)) && (z < (fence.getZ() + MAX_Z_DIFF))) { return true; } - - return false; - }; - - final WorldRegion region = World.getInstance().getRegion(x, y); // Should never be null. - return (region != null) && _regions.getOrDefault(region, Collections.emptyList()).stream().anyMatch(filter); + } + return false; } private boolean crossLinePart(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4, double xMin, double yMin, double xMax, double yMax) diff --git a/L2J_Mobius_Essence_4.0_DwellingOfSpirits/java/org/l2jmobius/gameserver/model/WorldObject.java b/L2J_Mobius_Essence_4.0_DwellingOfSpirits/java/org/l2jmobius/gameserver/model/WorldObject.java index b1292dd3d4..0e5536bbc0 100644 --- a/L2J_Mobius_Essence_4.0_DwellingOfSpirits/java/org/l2jmobius/gameserver/model/WorldObject.java +++ b/L2J_Mobius_Essence_4.0_DwellingOfSpirits/java/org/l2jmobius/gameserver/model/WorldObject.java @@ -412,6 +412,15 @@ public abstract class WorldObject extends ListenersContainer implements IIdentif return false; } + /** + * Verifies if this object is a fence. + * @return {@code true} if object is Fence, {@code false} otherwise + */ + public boolean isFence() + { + return false; + } + public void setTargetable(boolean targetable) { if (_isTargetable != targetable) diff --git a/L2J_Mobius_Essence_4.0_DwellingOfSpirits/java/org/l2jmobius/gameserver/model/WorldRegion.java b/L2J_Mobius_Essence_4.0_DwellingOfSpirits/java/org/l2jmobius/gameserver/model/WorldRegion.java index 8ad2649d3e..787947f2d7 100644 --- a/L2J_Mobius_Essence_4.0_DwellingOfSpirits/java/org/l2jmobius/gameserver/model/WorldRegion.java +++ b/L2J_Mobius_Essence_4.0_DwellingOfSpirits/java/org/l2jmobius/gameserver/model/WorldRegion.java @@ -25,6 +25,7 @@ import org.l2jmobius.commons.concurrent.ThreadPool; import org.l2jmobius.gameserver.model.actor.Attackable; import org.l2jmobius.gameserver.model.actor.Npc; import org.l2jmobius.gameserver.model.actor.instance.DoorInstance; +import org.l2jmobius.gameserver.model.actor.instance.FenceInstance; import org.l2jmobius.gameserver.taskmanager.RandomAnimationTaskManager; import org.l2jmobius.gameserver.util.UnboundArrayList; @@ -34,6 +35,8 @@ public class WorldRegion private final UnboundArrayList _visibleObjects = new UnboundArrayList<>(); /** List containing doors in this world region. */ private final List _doors = new ArrayList<>(1); + /** List containing fences in this world region. */ + private final List _fences = new ArrayList<>(1); /** Array containing nearby regions forming this world region's effective area. */ private WorldRegion[] _surroundingRegions; private final int _regionX; @@ -241,6 +244,13 @@ public class WorldRegion _surroundingRegions[i].addDoor((DoorInstance) object); } } + else if (object.isFence()) + { + for (int i = 0; i < _surroundingRegions.length; i++) + { + _surroundingRegions[i].addFence((FenceInstance) object); + } + } // If this is the first player to enter the region, activate self and neighbors. if (object.isPlayable() && !_active && !Config.GRIDS_ALWAYS_ON) @@ -271,7 +281,14 @@ public class WorldRegion { for (int i = 0; i < _surroundingRegions.length; i++) { - removeDoor((DoorInstance) object); + _surroundingRegions[i].removeDoor((DoorInstance) object); + } + } + else if (object.isFence()) + { + for (int i = 0; i < _surroundingRegions.length; i++) + { + _surroundingRegions[i].removeFence((FenceInstance) object); } } @@ -304,6 +321,24 @@ public class WorldRegion return _doors; } + public synchronized void addFence(FenceInstance fence) + { + if (!_fences.contains(fence)) + { + _fences.add(fence); + } + } + + private synchronized void removeFence(FenceInstance fence) + { + _fences.remove(fence); + } + + public List getFences() + { + return _fences; + } + public void setSurroundingRegions(WorldRegion[] regions) { _surroundingRegions = regions; diff --git a/L2J_Mobius_Essence_4.0_DwellingOfSpirits/java/org/l2jmobius/gameserver/model/actor/instance/FenceInstance.java b/L2J_Mobius_Essence_4.0_DwellingOfSpirits/java/org/l2jmobius/gameserver/model/actor/instance/FenceInstance.java index e933cff384..821a64b0f6 100644 --- a/L2J_Mobius_Essence_4.0_DwellingOfSpirits/java/org/l2jmobius/gameserver/model/actor/instance/FenceInstance.java +++ b/L2J_Mobius_Essence_4.0_DwellingOfSpirits/java/org/l2jmobius/gameserver/model/actor/instance/FenceInstance.java @@ -160,4 +160,10 @@ public class FenceInstance extends WorldObject { return _yMax; } + + @Override + public boolean isFence() + { + return true; + } } \ No newline at end of file diff --git a/L2J_Mobius_Essence_5.0_Sylph/java/org/l2jmobius/gameserver/data/xml/FenceData.java b/L2J_Mobius_Essence_5.0_Sylph/java/org/l2jmobius/gameserver/data/xml/FenceData.java index 10b68e2f34..cc647ecea2 100644 --- a/L2J_Mobius_Essence_5.0_Sylph/java/org/l2jmobius/gameserver/data/xml/FenceData.java +++ b/L2J_Mobius_Essence_5.0_Sylph/java/org/l2jmobius/gameserver/data/xml/FenceData.java @@ -17,12 +17,9 @@ package org.l2jmobius.gameserver.data.xml; import java.io.File; -import java.util.ArrayList; -import java.util.Collections; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; -import java.util.function.Predicate; import java.util.logging.Logger; import org.w3c.dom.Document; @@ -45,7 +42,6 @@ public class FenceData implements IXmlReader private static final int MAX_Z_DIFF = 100; - private final Map> _regions = new ConcurrentHashMap<>(); private final Map _fences = new ConcurrentHashMap<>(); protected FenceData() @@ -104,18 +100,11 @@ public class FenceData implements IXmlReader private void addFence(FenceInstance fence) { _fences.put(fence.getObjectId(), fence); - _regions.computeIfAbsent(World.getInstance().getRegion(fence), key -> new ArrayList<>()).add(fence); } public void removeFence(FenceInstance fence) { _fences.remove(fence.getObjectId()); - - final List fencesInRegion = _regions.get(World.getInstance().getRegion(fence)); - if (fencesInRegion != null) - { - fencesInRegion.remove(fence); - } } public Map getFences() @@ -130,19 +119,26 @@ public class FenceData implements IXmlReader public boolean checkIfFenceBetween(int x, int y, int z, int tx, int ty, int tz, Instance instance) { - final Predicate filter = fence -> + final WorldRegion region = World.getInstance().getRegion(x, y); + final List fences = region != null ? region.getFences() : null; + if ((fences == null) || fences.isEmpty()) + { + return false; + } + + for (FenceInstance fence : fences) { // Check if fence is geodata enabled. if (!fence.getState().isGeodataEnabled()) { - return false; + continue; } // Check if fence is within the instance we search for. final int instanceId = (instance == null) ? 0 : instance.getId(); if (fence.getInstanceId() != instanceId) { - return false; + continue; } final int xMin = fence.getXMin(); @@ -151,34 +147,30 @@ public class FenceData implements IXmlReader final int yMax = fence.getYMax(); if ((x < xMin) && (tx < xMin)) { - return false; + continue; } if ((x > xMax) && (tx > xMax)) { - return false; + continue; } if ((y < yMin) && (ty < yMin)) { - return false; + continue; } if ((y > yMax) && (ty > yMax)) { - return false; + continue; } if ((x > xMin) && (tx > xMin) && (x < xMax) && (tx < xMax) && (y > yMin) && (ty > yMin) && (y < yMax) && (ty < yMax)) { - return false; + continue; } if ((crossLinePart(xMin, yMin, xMax, yMin, x, y, tx, ty, xMin, yMin, xMax, yMax) || crossLinePart(xMax, yMin, xMax, yMax, x, y, tx, ty, xMin, yMin, xMax, yMax) || crossLinePart(xMax, yMax, xMin, yMax, x, y, tx, ty, xMin, yMin, xMax, yMax) || crossLinePart(xMin, yMax, xMin, yMin, x, y, tx, ty, xMin, yMin, xMax, yMax)) && (z > (fence.getZ() - MAX_Z_DIFF)) && (z < (fence.getZ() + MAX_Z_DIFF))) { return true; } - - return false; - }; - - final WorldRegion region = World.getInstance().getRegion(x, y); // Should never be null. - return (region != null) && _regions.getOrDefault(region, Collections.emptyList()).stream().anyMatch(filter); + } + return false; } private boolean crossLinePart(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4, double xMin, double yMin, double xMax, double yMax) diff --git a/L2J_Mobius_Essence_5.0_Sylph/java/org/l2jmobius/gameserver/model/WorldObject.java b/L2J_Mobius_Essence_5.0_Sylph/java/org/l2jmobius/gameserver/model/WorldObject.java index b1292dd3d4..0e5536bbc0 100644 --- a/L2J_Mobius_Essence_5.0_Sylph/java/org/l2jmobius/gameserver/model/WorldObject.java +++ b/L2J_Mobius_Essence_5.0_Sylph/java/org/l2jmobius/gameserver/model/WorldObject.java @@ -412,6 +412,15 @@ public abstract class WorldObject extends ListenersContainer implements IIdentif return false; } + /** + * Verifies if this object is a fence. + * @return {@code true} if object is Fence, {@code false} otherwise + */ + public boolean isFence() + { + return false; + } + public void setTargetable(boolean targetable) { if (_isTargetable != targetable) diff --git a/L2J_Mobius_Essence_5.0_Sylph/java/org/l2jmobius/gameserver/model/WorldRegion.java b/L2J_Mobius_Essence_5.0_Sylph/java/org/l2jmobius/gameserver/model/WorldRegion.java index 8ad2649d3e..787947f2d7 100644 --- a/L2J_Mobius_Essence_5.0_Sylph/java/org/l2jmobius/gameserver/model/WorldRegion.java +++ b/L2J_Mobius_Essence_5.0_Sylph/java/org/l2jmobius/gameserver/model/WorldRegion.java @@ -25,6 +25,7 @@ import org.l2jmobius.commons.concurrent.ThreadPool; import org.l2jmobius.gameserver.model.actor.Attackable; import org.l2jmobius.gameserver.model.actor.Npc; import org.l2jmobius.gameserver.model.actor.instance.DoorInstance; +import org.l2jmobius.gameserver.model.actor.instance.FenceInstance; import org.l2jmobius.gameserver.taskmanager.RandomAnimationTaskManager; import org.l2jmobius.gameserver.util.UnboundArrayList; @@ -34,6 +35,8 @@ public class WorldRegion private final UnboundArrayList _visibleObjects = new UnboundArrayList<>(); /** List containing doors in this world region. */ private final List _doors = new ArrayList<>(1); + /** List containing fences in this world region. */ + private final List _fences = new ArrayList<>(1); /** Array containing nearby regions forming this world region's effective area. */ private WorldRegion[] _surroundingRegions; private final int _regionX; @@ -241,6 +244,13 @@ public class WorldRegion _surroundingRegions[i].addDoor((DoorInstance) object); } } + else if (object.isFence()) + { + for (int i = 0; i < _surroundingRegions.length; i++) + { + _surroundingRegions[i].addFence((FenceInstance) object); + } + } // If this is the first player to enter the region, activate self and neighbors. if (object.isPlayable() && !_active && !Config.GRIDS_ALWAYS_ON) @@ -271,7 +281,14 @@ public class WorldRegion { for (int i = 0; i < _surroundingRegions.length; i++) { - removeDoor((DoorInstance) object); + _surroundingRegions[i].removeDoor((DoorInstance) object); + } + } + else if (object.isFence()) + { + for (int i = 0; i < _surroundingRegions.length; i++) + { + _surroundingRegions[i].removeFence((FenceInstance) object); } } @@ -304,6 +321,24 @@ public class WorldRegion return _doors; } + public synchronized void addFence(FenceInstance fence) + { + if (!_fences.contains(fence)) + { + _fences.add(fence); + } + } + + private synchronized void removeFence(FenceInstance fence) + { + _fences.remove(fence); + } + + public List getFences() + { + return _fences; + } + public void setSurroundingRegions(WorldRegion[] regions) { _surroundingRegions = regions; diff --git a/L2J_Mobius_Essence_5.0_Sylph/java/org/l2jmobius/gameserver/model/actor/instance/FenceInstance.java b/L2J_Mobius_Essence_5.0_Sylph/java/org/l2jmobius/gameserver/model/actor/instance/FenceInstance.java index e933cff384..821a64b0f6 100644 --- a/L2J_Mobius_Essence_5.0_Sylph/java/org/l2jmobius/gameserver/model/actor/instance/FenceInstance.java +++ b/L2J_Mobius_Essence_5.0_Sylph/java/org/l2jmobius/gameserver/model/actor/instance/FenceInstance.java @@ -160,4 +160,10 @@ public class FenceInstance extends WorldObject { return _yMax; } + + @Override + public boolean isFence() + { + return true; + } } \ No newline at end of file