L2World related rework.
This commit is contained in:
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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()
|
||||
|
@ -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 + ")";
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
Reference in New Issue
Block a user