L2World related rework.

This commit is contained in:
MobiusDev
2018-09-04 19:27:09 +00:00
parent 70c624ed4a
commit 484ec7823d
79 changed files with 1137 additions and 2145 deletions

View File

@ -184,7 +184,7 @@ public final class FenceData implements IGameXmlReader
return false;
};
final L2WorldRegion region = L2World.getInstance().getRegion(x, y, z); // FIXME: Should not be null.
final L2WorldRegion region = L2World.getInstance().getRegion(x, y); // Should never be null.
return region == null ? false : _regions.getOrDefault(region, Collections.emptyList()).stream().anyMatch(filter);
}

View File

@ -115,7 +115,7 @@ public final class ItemsOnGroundManager implements Runnable
item.setEnchantLevel(rs.getInt(4));
}
item.setXYZ(rs.getInt(5), rs.getInt(6), rs.getInt(7));
item.setWorldRegion(L2World.getInstance().getRegion(item.getLocation()));
item.setWorldRegion(L2World.getInstance().getRegion(item));
item.getWorldRegion().addVisibleObject(item);
final long dropTime = rs.getLong(8);
item.setDropTime(dropTime);

View File

@ -169,7 +169,7 @@ public abstract class L2Object extends ListenersContainer implements IIdentifiab
{
// Set the x,y,z position of the L2Object spawn and update its _worldregion
_isSpawned = true;
setWorldRegion(L2World.getInstance().getRegion(getLocation()));
setWorldRegion(L2World.getInstance().getRegion(this));
// Add the L2Object spawn in the _allobjects of L2World
L2World.getInstance().addObject(this);
@ -207,14 +207,6 @@ public abstract class L2Object extends ListenersContainer implements IIdentifiab
{
y = L2World.MAP_MIN_Y + 5000;
}
if (z > L2World.MAP_MAX_Z)
{
z = L2World.MAP_MAX_Z - 1000;
}
if (z < L2World.MAP_MIN_Z)
{
z = L2World.MAP_MIN_Z + 1000;
}
// Set the x,y,z position of the WorldObject. If flagged with _isSpawned, setXYZ will automatically update world region, so avoid that.
setXYZ(x, y, z);

View File

@ -35,14 +35,13 @@ import com.l2jmobius.gameserver.data.sql.impl.CharNameTable;
import com.l2jmobius.gameserver.instancemanager.PlayerCountManager;
import com.l2jmobius.gameserver.model.actor.L2Character;
import com.l2jmobius.gameserver.model.actor.L2Npc;
import com.l2jmobius.gameserver.model.actor.L2Summon;
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
import com.l2jmobius.gameserver.model.actor.instance.L2PetInstance;
import com.l2jmobius.gameserver.model.events.EventDispatcher;
import com.l2jmobius.gameserver.model.events.impl.character.npc.OnNpcCreatureSee;
import com.l2jmobius.gameserver.model.interfaces.ILocational;
import com.l2jmobius.gameserver.network.Disconnection;
import com.l2jmobius.gameserver.network.serverpackets.DeleteObject;
import com.l2jmobius.gameserver.util.Util;
public final class L2World
{
@ -54,11 +53,10 @@ public final class L2World
/** Bit shift, defines number of regions note, shifting by 15 will result in regions corresponding to map tiles shifting by 11 divides one tile to 16x16 regions. */
public static final int SHIFT_BY = 11;
public static final int SHIFT_BY_Z = 10;
public static final int TILE_SIZE = 32768;
/** Map dimensions */
/** Map dimensions. */
public static final int TILE_X_MIN = 11;
public static final int TILE_Y_MIN = 10;
public static final int TILE_X_MAX = 28;
@ -67,23 +65,20 @@ public final class L2World
public static final int TILE_ZERO_COORD_Y = 18;
public static final int MAP_MIN_X = (TILE_X_MIN - TILE_ZERO_COORD_X) * TILE_SIZE;
public static final int MAP_MIN_Y = (TILE_Y_MIN - TILE_ZERO_COORD_Y) * TILE_SIZE;
public static final int MAP_MIN_Z = -TILE_SIZE / 2;
public static final int MAP_MAX_X = ((TILE_X_MAX - TILE_ZERO_COORD_X) + 1) * TILE_SIZE;
public static final int MAP_MAX_Y = ((TILE_Y_MAX - TILE_ZERO_COORD_Y) + 1) * TILE_SIZE;
public static final int MAP_MAX_Z = TILE_SIZE / 2;
/** calculated offset used so top left region is 0,0 */
/** Calculated offset used so top left region is 0,0 */
public static final int OFFSET_X = Math.abs(MAP_MIN_X >> SHIFT_BY);
public static final int OFFSET_Y = Math.abs(MAP_MIN_Y >> SHIFT_BY);
public static final int OFFSET_Z = Math.abs(MAP_MIN_Z >> SHIFT_BY_Z);
/** number of regions */
/** Number of regions. */
private static final int REGIONS_X = (MAP_MAX_X >> SHIFT_BY) + OFFSET_X;
private static final int REGIONS_Y = (MAP_MAX_Y >> SHIFT_BY) + OFFSET_Y;
private static final int REGIONS_Z = (MAP_MAX_Z >> SHIFT_BY_Z) + OFFSET_Z;
public static final int REGION_MIN_DIMENSION = Math.min(TILE_SIZE / (TILE_SIZE >> SHIFT_BY_Z), TILE_SIZE / (TILE_SIZE >> SHIFT_BY));
/** Max client visibility distance. **/
private static final int VISIBILITY_RANGE = 3000;
/** Map containing all the players in game. */
private final Map<Integer, L2PcInstance> _allPlayers = new ConcurrentHashMap<>();
@ -99,7 +94,7 @@ public final class L2World
private final AtomicInteger _partyNumber = new AtomicInteger();
private final AtomicInteger _memberInPartyNumber = new AtomicInteger();
private final L2WorldRegion[][][] _worldRegions = new L2WorldRegion[REGIONS_X + 1][REGIONS_Y + 1][REGIONS_Z + 1];
private final L2WorldRegion[][] _worldRegions = new L2WorldRegion[REGIONS_X + 1][REGIONS_Y + 1];
/** Constructor of L2World. */
protected L2World()
@ -108,14 +103,11 @@ public final class L2World
{
for (int y = 0; y <= REGIONS_Y; y++)
{
for (int z = 0; z <= REGIONS_Z; z++)
{
_worldRegions[x][y][z] = new L2WorldRegion(x, y, z);
}
_worldRegions[x][y] = new L2WorldRegion(x, y);
}
}
LOGGER.info(getClass().getSimpleName() + ": (" + REGIONS_X + " by " + REGIONS_Y + " by " + REGIONS_Z + ") World Region Grid set up.");
LOGGER.info(getClass().getSimpleName() + ": (" + REGIONS_X + " by " + REGIONS_Y + ") World Region Grid set up.");
}
/**
@ -139,7 +131,7 @@ public final class L2World
PlayerCountManager.getInstance().incConnectedCount();
final L2PcInstance newPlayer = (L2PcInstance) object;
if (newPlayer.isTeleporting()) // TODO: drop when we stop removing player from the world while teleporting.
if (newPlayer.isTeleporting()) // TODO: Drop when we stop removing player from the world while teleporting.
{
return;
}
@ -176,7 +168,7 @@ public final class L2World
PlayerCountManager.getInstance().decConnectedCount();
final L2PcInstance player = (L2PcInstance) object;
if (player.isTeleporting()) // TODO: drop when we stop removing player from the world while teleportingq.
if (player.isTeleporting()) // TODO: Drop when we stop removing player from the world while teleporting.
{
return;
}
@ -309,7 +301,7 @@ public final class L2World
return;
}
forEachVisibleObject(object, L2Object.class, 1, wo ->
forEachVisibleObject(object, L2Object.class, wo ->
{
if (object.isPlayer() && wo.isVisibleFor((L2PcInstance) object))
{
@ -584,47 +576,9 @@ public final class L2World
});
}
public <T extends L2Object> void forEachVisibleObject(L2Object object, Class<T> clazz, int depth, Consumer<T> c)
{
if (object == null)
{
return;
}
final L2WorldRegion centerWorldRegion = getRegion(object);
if (centerWorldRegion == null)
{
return;
}
for (int x = Math.max(centerWorldRegion.getRegionX() - depth, 0); x <= Math.min(centerWorldRegion.getRegionX() + depth, REGIONS_X); x++)
{
for (int y = Math.max(centerWorldRegion.getRegionY() - depth, 0); y <= Math.min(centerWorldRegion.getRegionY() + depth, REGIONS_Y); y++)
{
for (int z = Math.max(centerWorldRegion.getRegionZ() - depth, 0); z <= Math.min(centerWorldRegion.getRegionZ() + depth, REGIONS_Z); z++)
{
for (L2Object visibleObject : _worldRegions[x][y][z].getVisibleObjects().values())
{
if ((visibleObject == null) || (visibleObject == object) || !clazz.isInstance(visibleObject))
{
continue;
}
if (visibleObject.getInstanceWorld() != object.getInstanceWorld())
{
continue;
}
c.accept(clazz.cast(visibleObject));
}
}
}
}
}
public <T extends L2Object> void forEachVisibleObject(L2Object object, Class<T> clazz, Consumer<T> c)
{
forEachVisibleObject(object, clazz, 1, c);
forEachVisibleObjectInRange(object, clazz, VISIBILITY_RANGE, c);
}
public <T extends L2Object> void forEachVisibleObjectInRange(L2Object object, Class<T> clazz, int range, Consumer<T> c)
@ -640,62 +594,49 @@ public final class L2World
return;
}
final int depth = (range / REGION_MIN_DIMENSION) + 1;
for (int x = Math.max(centerWorldRegion.getRegionX() - depth, 0); x <= Math.min(centerWorldRegion.getRegionX() + depth, REGIONS_X); x++)
final int regionX = centerWorldRegion.getRegionX();
final int regionY = centerWorldRegion.getRegionY();
for (int x = regionX - 1; x <= (regionX + 1); x++)
{
for (int y = Math.max(centerWorldRegion.getRegionY() - depth, 0); y <= Math.min(centerWorldRegion.getRegionY() + depth, REGIONS_Y); y++)
for (int y = regionY - 1; y <= (regionY + 1); y++)
{
for (int z = Math.max(centerWorldRegion.getRegionZ() - depth, 0); z <= Math.min(centerWorldRegion.getRegionZ() + depth, REGIONS_Z); z++)
if (validRegion(x, y))
{
final int x1 = (x - OFFSET_X) << SHIFT_BY;
final int y1 = (y - OFFSET_Y) << SHIFT_BY;
final int z1 = (z - OFFSET_Z) << SHIFT_BY_Z;
final int x2 = ((x + 1) - OFFSET_X) << SHIFT_BY;
final int y2 = ((y + 1) - OFFSET_Y) << SHIFT_BY;
final int z2 = ((z + 1) - OFFSET_Z) << SHIFT_BY_Z;
if (Util.cubeIntersectsSphere(x1, y1, z1, x2, y2, z2, object.getX(), object.getY(), object.getZ(), range))
for (L2Object visibleObject : _worldRegions[x][y].getVisibleObjects().values())
{
for (L2Object visibleObject : _worldRegions[x][y][z].getVisibleObjects().values())
if ((visibleObject == null) || (visibleObject == object) || !clazz.isInstance(visibleObject))
{
if ((visibleObject == null) || (visibleObject == object) || !clazz.isInstance(visibleObject))
{
continue;
}
if (visibleObject.getInstanceWorld() != object.getInstanceWorld())
{
continue;
}
if (visibleObject.calculateDistance(object, true, false) <= range)
{
c.accept(clazz.cast(visibleObject));
}
continue;
}
if (visibleObject.getInstanceWorld() != object.getInstanceWorld())
{
continue;
}
if (visibleObject.calculateDistance(object, true, false) <= range)
{
c.accept(clazz.cast(visibleObject));
}
}
}
else if ((x == regionX) && (y == regionY)) // Precaution. Moved at invalid region?
{
disposeOutOfBoundsObject(object);
return;
}
}
}
}
public <T extends L2Object> List<T> getVisibleObjects(L2Object object, Class<T> clazz)
{
final List<T> result = new LinkedList<>();
forEachVisibleObject(object, clazz, result::add);
return result;
return getVisibleObjects(object, clazz, VISIBILITY_RANGE);
}
public <T extends L2Object> List<T> getVisibleObjects(L2Object object, Class<T> clazz, Predicate<T> predicate)
{
final List<T> result = new LinkedList<>();
forEachVisibleObject(object, clazz, o ->
{
if (predicate.test(o))
{
result.add(o);
}
});
return result;
return getVisibleObjects(object, clazz, VISIBILITY_RANGE, predicate);
}
public <T extends L2Object> List<T> getVisibleObjects(L2Object object, Class<T> clazz, int range)
@ -722,24 +663,31 @@ public final class L2World
* Calculate the current L2WorldRegions of the object according to its position (x,y). <B><U> Example of use </U> :</B>
* <li>Set position of a new L2Object (drop, spawn...)</li>
* <li>Update position of a L2Object after a movement</li><BR>
* @param point position of the object
* @param object the object
* @return
*/
public L2WorldRegion getRegion(ILocational point)
{
return getRegion(point.getX(), point.getY(), point.getZ());
}
public L2WorldRegion getRegion(int x, int y, int z)
public L2WorldRegion getRegion(L2Object object)
{
try
{
return _worldRegions[(x >> SHIFT_BY) + OFFSET_X][(y >> SHIFT_BY) + OFFSET_Y][(z >> SHIFT_BY_Z) + OFFSET_Z];
return _worldRegions[(object.getX() >> SHIFT_BY) + OFFSET_X][(object.getY() >> SHIFT_BY) + OFFSET_Y];
}
catch (ArrayIndexOutOfBoundsException e) // Precaution. Moved at invalid region?
{
disposeOutOfBoundsObject(object);
return null;
}
}
public L2WorldRegion getRegion(int x, int y)
{
try
{
return _worldRegions[(x >> SHIFT_BY) + OFFSET_X][(y >> SHIFT_BY) + OFFSET_Y];
}
catch (ArrayIndexOutOfBoundsException e)
{
// TODO: Find when this can be null. (Bad geodata? Check GeoEngine hasGeoPos method.)
// LOGGER.warning(getClass().getSimpleName() + ": Incorrect world region X: " + ((x >> SHIFT_BY) + OFFSET_X) + " Y: " + ((y >> SHIFT_BY) + OFFSET_Y) + " Z: " + ((z >> SHIFT_BY_Z) + OFFSET_Z) + " for coordinates x: " + x + " y: " + y + " z: " + z);
LOGGER.warning(getClass().getSimpleName() + ": Incorrect world region X: " + ((x >> SHIFT_BY) + OFFSET_X) + " Y: " + ((y >> SHIFT_BY) + OFFSET_Y));
return null;
}
}
@ -748,7 +696,7 @@ public final class L2World
* Returns the whole 3d array containing the world regions used by ZoneData.java to setup zones inside the world regions
* @return
*/
public L2WorldRegion[][][] getWorldRegions()
public L2WorldRegion[][] getWorldRegions()
{
return _worldRegions;
}
@ -758,31 +706,49 @@ public final class L2World
* <li>Init L2WorldRegions</li><BR>
* @param x X position of the object
* @param y Y position of the object
* @param z Z position of the object
* @return True if the L2WorldRegion is valid
*/
public static boolean validRegion(int x, int y, int z)
public static boolean validRegion(int x, int y)
{
return ((x >= 0) && (x <= REGIONS_X) && (y >= 0) && (y <= REGIONS_Y)) && (z >= 0) && (z <= REGIONS_Z);
return ((x >= 0) && (x <= REGIONS_X) && (y >= 0) && (y <= REGIONS_Y));
}
/**
* Deleted all spawns in the world.
*/
public void deleteVisibleNpcSpawns()
public synchronized void disposeOutOfBoundsObject(L2Object object)
{
LOGGER.info(getClass().getSimpleName() + ": Deleting all visible NPCs.");
for (int x = 0; x <= REGIONS_X; x++)
if (object.isPlayer())
{
for (int y = 0; y <= REGIONS_Y; y++)
((L2Character) object).stopMove(((L2PcInstance) object).getLastServerPosition());
}
else if (object.isSummon())
{
final L2Summon summon = (L2Summon) object;
summon.unSummon(summon.getOwner());
}
else if (_allObjects.remove(object.getObjectId()) != null)
{
if (object.isNpc())
{
for (int z = 0; z <= REGIONS_Z; z++)
final L2Npc npc = (L2Npc) object;
LOGGER.warning("Deleting npc " + object.getName() + " NPCID[" + npc.getId() + "] from invalid location X:" + object.getX() + " Y:" + object.getY() + " Z:" + object.getZ());
npc.deleteMe();
final L2Spawn spawn = npc.getSpawn();
if (spawn != null)
{
_worldRegions[x][y][z].deleteVisibleNpcSpawns();
LOGGER.warning("Spawn location X:" + spawn.getX() + " Y:" + spawn.getY() + " Z:" + spawn.getZ() + " Heading:" + spawn.getHeading());
}
}
else if (object.isCharacter())
{
LOGGER.warning("Deleting object " + object.getName() + " OID[" + object.getObjectId() + "] from invalid location X:" + object.getX() + " Y:" + object.getY() + " Z:" + object.getZ());
((L2Character) object).deleteMe();
}
if (object.getWorldRegion() != null)
{
object.getWorldRegion().removeVisibleObject(object);
}
}
LOGGER.info(getClass().getSimpleName() + ": All visible NPCs deleted.");
}
public void incrementParty()

View File

@ -25,7 +25,6 @@ import java.util.logging.Logger;
import com.l2jmobius.Config;
import com.l2jmobius.commons.concurrent.ThreadPool;
import com.l2jmobius.gameserver.datatables.SpawnTable;
import com.l2jmobius.gameserver.model.actor.L2Attackable;
import com.l2jmobius.gameserver.model.actor.L2Npc;
import com.l2jmobius.gameserver.model.actor.L2Vehicle;
@ -38,17 +37,15 @@ public final class L2WorldRegion
private volatile Map<Integer, L2Object> _visibleObjects;
private final int _regionX;
private final int _regionY;
private final int _regionZ;
private boolean _active = false;
private ScheduledFuture<?> _neighborsTask = null;
public L2WorldRegion(int regionX, int regionY, int regionZ)
public L2WorldRegion(int regionX, int regionY)
{
_regionX = regionX;
_regionY = regionY;
_regionZ = regionZ;
// default a newly initialized region to inactive, unless always on is specified
// Default a newly initialized region to inactive, unless always on is specified.
_active = Config.GRIDS_ALWAYS_ON;
}
@ -93,19 +90,19 @@ public final class L2WorldRegion
c++;
final L2Attackable mob = (L2Attackable) o;
// Set target to null and cancel Attack or Cast
// Set target to null and cancel attack or cast.
mob.setTarget(null);
// Stop movement
// Stop movement.
mob.stopMove(null);
// Stop all active skills effects in progress on the L2Character
// Stop all active skills effects in progress on the L2Character.
mob.stopAllEffects();
mob.clearAggroList();
mob.getAttackByList().clear();
// stop the ai tasks
// Stop the AI tasks.
if (mob.hasAI())
{
mob.getAI().setIntention(com.l2jmobius.gameserver.ai.CtrlIntention.AI_INTENTION_IDLE);
@ -126,7 +123,7 @@ public final class L2WorldRegion
if (o.isAttackable())
{
c++;
// Start HP/MP/CP Regeneration task
// Start HP/MP/CP regeneration task.
((L2Attackable) o).getStatus().startHpMpRegeneration();
}
else if (o instanceof L2Npc)
@ -161,7 +158,7 @@ public final class L2WorldRegion
_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);
LOGGER.finer((value ? "Starting" : "Stopping") + " Grid " + this);
@ -172,10 +169,10 @@ public final class L2WorldRegion
*/
private void startActivation()
{
// first set self to active and do self-tasks...
// First set self to active and do self-tasks...
setActive(true);
// if the timer to deactivate neighbors is running, cancel it.
// If the timer to deactivate neighbors is running, cancel it.
synchronized (this)
{
if (_neighborsTask != null)
@ -184,7 +181,7 @@ public final class L2WorldRegion
_neighborsTask = null;
}
// then, set a timer to activate the neighbors
// Then, set a timer to activate the neighbors.
_neighborsTask = ThreadPool.schedule(new NeighborsTask(true), 1000 * Config.GRID_NEIGHBOR_TURNON_TIME);
}
}
@ -194,7 +191,7 @@ public final class L2WorldRegion
*/
private void startDeactivation()
{
// if the timer to activate neighbors is running, cancel it.
// If the timer to activate neighbors is running, cancel it.
synchronized (this)
{
if (_neighborsTask != null)
@ -203,8 +200,8 @@ public final class L2WorldRegion
_neighborsTask = null;
}
// start a timer to "suggest" a deactivate to self and neighbors.
// suggest means: first check if a neighbor has L2PcInstances in it. If not, deactivate.
// Start a timer to "suggest" a deactivate to self and neighbors.
// Suggest means: first check if a neighbor has L2PcInstances in it. If not, deactivate.
_neighborsTask = ThreadPool.schedule(new NeighborsTask(false), 1000 * Config.GRID_NEIGHBOR_TURNOFF_TIME);
}
}
@ -235,7 +232,7 @@ public final class L2WorldRegion
if (object.isPlayable())
{
// if this is the first player to enter the region, activate self & neighbors
// If this is the first player to enter the region, activate self and neighbors.
if (!_active && (!Config.GRIDS_ALWAYS_ON))
{
startActivation();
@ -274,50 +271,18 @@ public final class L2WorldRegion
return _visibleObjects != null ? _visibleObjects : Collections.emptyMap();
}
/**
* Deleted all spawns in the world.
*/
public void deleteVisibleNpcSpawns()
{
if (_visibleObjects == null)
{
return;
}
LOGGER.info("Deleting all visible NPCs in Region: " + this);
for (L2Object obj : _visibleObjects.values())
{
if (obj instanceof L2Npc)
{
final L2Npc target = (L2Npc) obj;
target.deleteMe();
final L2Spawn spawn = target.getSpawn();
if (spawn != null)
{
spawn.stopRespawn();
SpawnTable.getInstance().deleteSpawn(spawn, false);
}
LOGGER.finest("Removed NPC " + target.getObjectId());
}
}
LOGGER.info("All visible NPCs deleted in Region: " + this);
}
public boolean forEachSurroundingRegion(Predicate<L2WorldRegion> p)
{
for (int x = _regionX - 1; x <= (_regionX + 1); x++)
{
for (int y = _regionY - 1; y <= (_regionY + 1); y++)
{
for (int z = _regionZ - 1; z <= (_regionZ + 1); z++)
if (L2World.validRegion(x, y))
{
if (L2World.validRegion(x, y, z))
final L2WorldRegion worldRegion = L2World.getInstance().getWorldRegions()[x][y];
if (!p.test(worldRegion))
{
final L2WorldRegion worldRegion = L2World.getInstance().getWorldRegions()[x][y][z];
if (!p.test(worldRegion))
{
return false;
}
return false;
}
}
}
@ -335,19 +300,14 @@ public final class L2WorldRegion
return _regionY;
}
public int getRegionZ()
{
return _regionZ;
}
public boolean isSurroundingRegion(L2WorldRegion region)
{
return (region != null) && (getRegionX() >= (region.getRegionX() - 1)) && (getRegionX() <= (region.getRegionX() + 1)) && (getRegionY() >= (region.getRegionY() - 1)) && (getRegionY() <= (region.getRegionY() + 1)) && (getRegionZ() >= (region.getRegionZ() - 1)) && (getRegionZ() <= (region.getRegionZ() + 1));
return (region != null) && (_regionX >= (region.getRegionX() - 1)) && (_regionX <= (region.getRegionX() + 1)) && (_regionY >= (region.getRegionY() - 1)) && (_regionY <= (region.getRegionY() + 1));
}
@Override
public String toString()
{
return "(" + _regionX + ", " + _regionY + ", " + _regionZ + ")";
return "(" + _regionX + ", " + _regionY + ")";
}
}

View File

@ -73,7 +73,6 @@ import com.l2jmobius.gameserver.model.L2AccessLevel;
import com.l2jmobius.gameserver.model.L2Clan;
import com.l2jmobius.gameserver.model.L2Object;
import com.l2jmobius.gameserver.model.L2Party;
import com.l2jmobius.gameserver.model.L2Spawn;
import com.l2jmobius.gameserver.model.L2World;
import com.l2jmobius.gameserver.model.L2WorldRegion;
import com.l2jmobius.gameserver.model.Location;
@ -83,7 +82,6 @@ import com.l2jmobius.gameserver.model.TimeStamp;
import com.l2jmobius.gameserver.model.actor.instance.FriendlyNpcInstance;
import com.l2jmobius.gameserver.model.actor.instance.L2MonsterInstance;
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
import com.l2jmobius.gameserver.model.actor.instance.L2ServitorInstance;
import com.l2jmobius.gameserver.model.actor.instance.L2TrapInstance;
import com.l2jmobius.gameserver.model.actor.stat.CharStat;
import com.l2jmobius.gameserver.model.actor.status.CharStatus;
@ -2981,31 +2979,7 @@ public abstract class L2Character extends L2Object implements ISkillsHolder, IDe
}
else // Precaution. Moved at invalid region?
{
if (isPlayer())
{
stopMove(((L2PcInstance) this).getLastServerPosition());
}
else if (isServitor())
{
final L2ServitorInstance servitor = (L2ServitorInstance) this;
servitor.unSummon(servitor.getOwner());
}
else if (isNpc())
{
final L2Npc npc = (L2Npc) this;
LOGGER.warning("Deleting npc " + getName() + " NPCID[" + npc.getId() + "] from invalid location X:" + getX() + " Y:" + getY() + " Z:" + getZ());
final L2Spawn spawn = npc.getSpawn();
if (spawn != null)
{
LOGGER.warning("Spawn location X:" + spawn.getX() + " Y:" + spawn.getY() + " Z:" + spawn.getZ() + " Heading:" + spawn.getHeading());
}
deleteMe();
}
else
{
LOGGER.warning("Deleting object " + getName() + " OID[" + getObjectId() + "] from invalid location X:" + getX() + " Y:" + getY() + " Z:" + getZ());
deleteMe();
}
L2World.getInstance().disposeOutOfBoundsObject(this);
}
}

View File

@ -226,50 +226,6 @@ public final class Util
return calculateDistance(obj1, obj2, includeZAxis, false) <= range;
}
/**
* Checks if the cube intersects the sphere.
* @param x1 the cube's first point x
* @param y1 the cube's first point y
* @param z1 the cube's first point z
* @param x2 the cube's second point x
* @param y2 the cube's second point y
* @param z2 the cube's second point z
* @param sX the sphere's middle x
* @param sY the sphere's middle y
* @param sZ the sphere's middle z
* @param radius the sphere's radius
* @return {@code true} if cube intersects sphere, {@code false} otherwise
*/
public static boolean cubeIntersectsSphere(int x1, int y1, int z1, int x2, int y2, int z2, int sX, int sY, int sZ, int radius)
{
double d = radius * radius;
if (sX < x1)
{
d -= Math.pow(sX - x1, 2);
}
else if (sX > x2)
{
d -= Math.pow(sX - x2, 2);
}
if (sY < y1)
{
d -= Math.pow(sY - y1, 2);
}
else if (sY > y2)
{
d -= Math.pow(sY - y2, 2);
}
if (sZ < z1)
{
d -= Math.pow(sZ - z1, 2);
}
else if (sZ > z2)
{
d -= Math.pow(sZ - z2, 2);
}
return d > 0;
}
/**
* @param text - the text to check
* @return {@code true} if {@code text} contains only numbers, {@code false} otherwise