L2World related rework.
This commit is contained in:
+1
-1
@@ -61,7 +61,7 @@ public final class HillsOfGold extends AbstractNpcAI
|
|||||||
{
|
{
|
||||||
if ((npc != null) && !npc.isDead())
|
if ((npc != null) && !npc.isDead())
|
||||||
{
|
{
|
||||||
L2World.getInstance().forEachVisibleObject(npc, L2MonsterInstance.class, npc.getAggroRange(), nearby ->
|
L2World.getInstance().forEachVisibleObjectInRange(npc, L2MonsterInstance.class, npc.getAggroRange(), nearby ->
|
||||||
{
|
{
|
||||||
if (npc.isInCombat())
|
if (npc.isInCombat())
|
||||||
{
|
{
|
||||||
|
|||||||
Vendored
+1
-1
@@ -344,7 +344,7 @@ public final class SeedOfAnnihilation extends AbstractNpcAI
|
|||||||
{
|
{
|
||||||
final Location teleLoc = TELEPORT_ZONES.get(zone.getId());
|
final Location teleLoc = TELEPORT_ZONES.get(zone.getId());
|
||||||
// Conditions for Quest 454
|
// Conditions for Quest 454
|
||||||
L2World.getInstance().forEachVisibleObject(character, L2Npc.class, 500, npc ->
|
L2World.getInstance().forEachVisibleObjectInRange(character, L2Npc.class, 500, npc ->
|
||||||
{
|
{
|
||||||
if ((npc.getId() == 32738) && (npc.getTarget() != null))
|
if ((npc.getId() == 32738) && (npc.getTarget() != null))
|
||||||
{
|
{
|
||||||
|
|||||||
Vendored
+28
-2
@@ -213,14 +213,40 @@ public class AdminSpawn implements IAdminCommandHandler
|
|||||||
{
|
{
|
||||||
Broadcast.toAllOnlinePlayers(SystemMessage.getSystemMessage(SystemMessageId.THE_NPC_SERVER_IS_NOT_OPERATING_AT_THIS_TIME));
|
Broadcast.toAllOnlinePlayers(SystemMessage.getSystemMessage(SystemMessageId.THE_NPC_SERVER_IS_NOT_OPERATING_AT_THIS_TIME));
|
||||||
DBSpawnManager.getInstance().cleanUp();
|
DBSpawnManager.getInstance().cleanUp();
|
||||||
L2World.getInstance().deleteVisibleNpcSpawns();
|
for (L2Object obj : L2World.getInstance().getVisibleObjects())
|
||||||
|
{
|
||||||
|
if ((obj != null) && obj.isNpc())
|
||||||
|
{
|
||||||
|
final L2Npc target = (L2Npc) obj;
|
||||||
|
target.deleteMe();
|
||||||
|
final L2Spawn spawn = target.getSpawn();
|
||||||
|
if (spawn != null)
|
||||||
|
{
|
||||||
|
spawn.stopRespawn();
|
||||||
|
SpawnTable.getInstance().deleteSpawn(spawn, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
AdminData.getInstance().broadcastMessageToGMs("NPC Unspawn completed!");
|
AdminData.getInstance().broadcastMessageToGMs("NPC Unspawn completed!");
|
||||||
}
|
}
|
||||||
else if (command.startsWith("admin_respawnall") || command.startsWith("admin_spawn_reload"))
|
else if (command.startsWith("admin_respawnall") || command.startsWith("admin_spawn_reload"))
|
||||||
{
|
{
|
||||||
// make sure all spawns are deleted
|
// make sure all spawns are deleted
|
||||||
DBSpawnManager.getInstance().cleanUp();
|
DBSpawnManager.getInstance().cleanUp();
|
||||||
L2World.getInstance().deleteVisibleNpcSpawns();
|
for (L2Object obj : L2World.getInstance().getVisibleObjects())
|
||||||
|
{
|
||||||
|
if ((obj != null) && obj.isNpc())
|
||||||
|
{
|
||||||
|
final L2Npc target = (L2Npc) obj;
|
||||||
|
target.deleteMe();
|
||||||
|
final L2Spawn spawn = target.getSpawn();
|
||||||
|
if (spawn != null)
|
||||||
|
{
|
||||||
|
spawn.stopRespawn();
|
||||||
|
SpawnTable.getInstance().deleteSpawn(spawn, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
// now respawn all
|
// now respawn all
|
||||||
NpcData.getInstance().load();
|
NpcData.getInstance().load();
|
||||||
DBSpawnManager.getInstance().load();
|
DBSpawnManager.getInstance().load();
|
||||||
|
|||||||
Vendored
+1
-1
@@ -190,7 +190,7 @@ public class AdminTeleport implements IAdminCommandHandler
|
|||||||
st.nextToken();
|
st.nextToken();
|
||||||
final int x = (int) Float.parseFloat(st.nextToken());
|
final int x = (int) Float.parseFloat(st.nextToken());
|
||||||
final int y = (int) Float.parseFloat(st.nextToken());
|
final int y = (int) Float.parseFloat(st.nextToken());
|
||||||
final int z = st.hasMoreTokens() ? ((int) Float.parseFloat(st.nextToken())) : GeoEngine.getInstance().getHeight(x, y, L2World.MAP_MAX_Z);
|
final int z = st.hasMoreTokens() ? ((int) Float.parseFloat(st.nextToken())) : GeoEngine.getInstance().getHeight(x, y, 10000);
|
||||||
|
|
||||||
activeChar.teleToLocation(x, y, z);
|
activeChar.teleToLocation(x, y, z);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -184,7 +184,7 @@ public final class FenceData implements IGameXmlReader
|
|||||||
return false;
|
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);
|
return region == null ? false : _regions.getOrDefault(region, Collections.emptyList()).stream().anyMatch(filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -115,7 +115,7 @@ public final class ItemsOnGroundManager implements Runnable
|
|||||||
item.setEnchantLevel(rs.getInt(4));
|
item.setEnchantLevel(rs.getInt(4));
|
||||||
}
|
}
|
||||||
item.setXYZ(rs.getInt(5), rs.getInt(6), rs.getInt(7));
|
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);
|
item.getWorldRegion().addVisibleObject(item);
|
||||||
final long dropTime = rs.getLong(8);
|
final long dropTime = rs.getLong(8);
|
||||||
item.setDropTime(dropTime);
|
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
|
// Set the x,y,z position of the L2Object spawn and update its _worldregion
|
||||||
_isSpawned = true;
|
_isSpawned = true;
|
||||||
setWorldRegion(L2World.getInstance().getRegion(getLocation()));
|
setWorldRegion(L2World.getInstance().getRegion(this));
|
||||||
|
|
||||||
// Add the L2Object spawn in the _allobjects of L2World
|
// Add the L2Object spawn in the _allobjects of L2World
|
||||||
L2World.getInstance().addObject(this);
|
L2World.getInstance().addObject(this);
|
||||||
@@ -207,14 +207,6 @@ public abstract class L2Object extends ListenersContainer implements IIdentifiab
|
|||||||
{
|
{
|
||||||
y = L2World.MAP_MIN_Y + 5000;
|
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.
|
// 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);
|
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.instancemanager.PlayerCountManager;
|
||||||
import com.l2jmobius.gameserver.model.actor.L2Character;
|
import com.l2jmobius.gameserver.model.actor.L2Character;
|
||||||
import com.l2jmobius.gameserver.model.actor.L2Npc;
|
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.L2PcInstance;
|
||||||
import com.l2jmobius.gameserver.model.actor.instance.L2PetInstance;
|
import com.l2jmobius.gameserver.model.actor.instance.L2PetInstance;
|
||||||
import com.l2jmobius.gameserver.model.events.EventDispatcher;
|
import com.l2jmobius.gameserver.model.events.EventDispatcher;
|
||||||
import com.l2jmobius.gameserver.model.events.impl.character.npc.OnNpcCreatureSee;
|
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.Disconnection;
|
||||||
import com.l2jmobius.gameserver.network.serverpackets.DeleteObject;
|
import com.l2jmobius.gameserver.network.serverpackets.DeleteObject;
|
||||||
import com.l2jmobius.gameserver.util.Util;
|
|
||||||
|
|
||||||
public final class L2World
|
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. */
|
/** 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 = 11;
|
||||||
public static final int SHIFT_BY_Z = 10;
|
|
||||||
|
|
||||||
public static final int TILE_SIZE = 32768;
|
public static final int TILE_SIZE = 32768;
|
||||||
|
|
||||||
/** Map dimensions */
|
/** Map dimensions. */
|
||||||
public static final int TILE_X_MIN = 11;
|
public static final int TILE_X_MIN = 11;
|
||||||
public static final int TILE_Y_MIN = 10;
|
public static final int TILE_Y_MIN = 10;
|
||||||
public static final int TILE_X_MAX = 28;
|
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 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_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_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_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_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_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_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_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_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. */
|
/** Map containing all the players in game. */
|
||||||
private final Map<Integer, L2PcInstance> _allPlayers = new ConcurrentHashMap<>();
|
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 _partyNumber = new AtomicInteger();
|
||||||
private final AtomicInteger _memberInPartyNumber = 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. */
|
/** Constructor of L2World. */
|
||||||
protected L2World()
|
protected L2World()
|
||||||
@@ -108,14 +103,11 @@ public final class L2World
|
|||||||
{
|
{
|
||||||
for (int y = 0; y <= REGIONS_Y; y++)
|
for (int y = 0; y <= REGIONS_Y; y++)
|
||||||
{
|
{
|
||||||
for (int z = 0; z <= REGIONS_Z; z++)
|
_worldRegions[x][y] = new L2WorldRegion(x, y);
|
||||||
{
|
|
||||||
_worldRegions[x][y][z] = new L2WorldRegion(x, y, z);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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();
|
PlayerCountManager.getInstance().incConnectedCount();
|
||||||
|
|
||||||
final L2PcInstance newPlayer = (L2PcInstance) object;
|
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;
|
return;
|
||||||
}
|
}
|
||||||
@@ -176,7 +168,7 @@ public final class L2World
|
|||||||
PlayerCountManager.getInstance().decConnectedCount();
|
PlayerCountManager.getInstance().decConnectedCount();
|
||||||
|
|
||||||
final L2PcInstance player = (L2PcInstance) object;
|
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;
|
return;
|
||||||
}
|
}
|
||||||
@@ -309,7 +301,7 @@ public final class L2World
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
forEachVisibleObject(object, L2Object.class, 1, wo ->
|
forEachVisibleObject(object, L2Object.class, wo ->
|
||||||
{
|
{
|
||||||
if (object.isPlayer() && wo.isVisibleFor((L2PcInstance) object))
|
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)
|
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)
|
public <T extends L2Object> void forEachVisibleObjectInRange(L2Object object, Class<T> clazz, int range, Consumer<T> c)
|
||||||
@@ -640,22 +594,15 @@ public final class L2World
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
final int depth = (range / REGION_MIN_DIMENSION) + 1;
|
final int regionX = centerWorldRegion.getRegionX();
|
||||||
for (int x = Math.max(centerWorldRegion.getRegionX() - depth, 0); x <= Math.min(centerWorldRegion.getRegionX() + depth, REGIONS_X); x++)
|
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;
|
for (L2Object visibleObject : _worldRegions[x][y].getVisibleObjects().values())
|
||||||
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][z].getVisibleObjects().values())
|
|
||||||
{
|
{
|
||||||
if ((visibleObject == null) || (visibleObject == object) || !clazz.isInstance(visibleObject))
|
if ((visibleObject == null) || (visibleObject == object) || !clazz.isInstance(visibleObject))
|
||||||
{
|
{
|
||||||
@@ -673,6 +620,10 @@ public final class L2World
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if ((x == regionX) && (y == regionY)) // Precaution. Moved at invalid region?
|
||||||
|
{
|
||||||
|
disposeOutOfBoundsObject(object);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -680,22 +631,12 @@ public final class L2World
|
|||||||
|
|
||||||
public <T extends L2Object> List<T> getVisibleObjects(L2Object object, Class<T> clazz)
|
public <T extends L2Object> List<T> getVisibleObjects(L2Object object, Class<T> clazz)
|
||||||
{
|
{
|
||||||
final List<T> result = new LinkedList<>();
|
return getVisibleObjects(object, clazz, VISIBILITY_RANGE);
|
||||||
forEachVisibleObject(object, clazz, result::add);
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public <T extends L2Object> List<T> getVisibleObjects(L2Object object, Class<T> clazz, Predicate<T> predicate)
|
public <T extends L2Object> List<T> getVisibleObjects(L2Object object, Class<T> clazz, Predicate<T> predicate)
|
||||||
{
|
{
|
||||||
final List<T> result = new LinkedList<>();
|
return getVisibleObjects(object, clazz, VISIBILITY_RANGE, predicate);
|
||||||
forEachVisibleObject(object, clazz, o ->
|
|
||||||
{
|
|
||||||
if (predicate.test(o))
|
|
||||||
{
|
|
||||||
result.add(o);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public <T extends L2Object> List<T> getVisibleObjects(L2Object object, Class<T> clazz, int range)
|
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>
|
* 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>Set position of a new L2Object (drop, spawn...)</li>
|
||||||
* <li>Update position of a L2Object after a movement</li><BR>
|
* <li>Update position of a L2Object after a movement</li><BR>
|
||||||
* @param point position of the object
|
* @param object the object
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public L2WorldRegion getRegion(ILocational point)
|
public L2WorldRegion getRegion(L2Object object)
|
||||||
{
|
|
||||||
return getRegion(point.getX(), point.getY(), point.getZ());
|
|
||||||
}
|
|
||||||
|
|
||||||
public L2WorldRegion getRegion(int x, int y, int z)
|
|
||||||
{
|
{
|
||||||
try
|
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)
|
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));
|
||||||
// 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);
|
|
||||||
return null;
|
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
|
* Returns the whole 3d array containing the world regions used by ZoneData.java to setup zones inside the world regions
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public L2WorldRegion[][][] getWorldRegions()
|
public L2WorldRegion[][] getWorldRegions()
|
||||||
{
|
{
|
||||||
return _worldRegions;
|
return _worldRegions;
|
||||||
}
|
}
|
||||||
@@ -758,31 +706,49 @@ public final class L2World
|
|||||||
* <li>Init L2WorldRegions</li><BR>
|
* <li>Init L2WorldRegions</li><BR>
|
||||||
* @param x X position of the object
|
* @param x X position of the object
|
||||||
* @param y Y 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
|
* @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));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public synchronized void disposeOutOfBoundsObject(L2Object object)
|
||||||
* Deleted all spawns in the world.
|
|
||||||
*/
|
|
||||||
public void deleteVisibleNpcSpawns()
|
|
||||||
{
|
{
|
||||||
LOGGER.info(getClass().getSimpleName() + ": Deleting all visible NPCs.");
|
if (object.isPlayer())
|
||||||
for (int x = 0; x <= REGIONS_X; x++)
|
|
||||||
{
|
{
|
||||||
for (int y = 0; y <= REGIONS_Y; y++)
|
((L2Character) object).stopMove(((L2PcInstance) object).getLastServerPosition());
|
||||||
|
}
|
||||||
|
else if (object.isSummon())
|
||||||
{
|
{
|
||||||
for (int z = 0; z <= REGIONS_Z; z++)
|
final L2Summon summon = (L2Summon) object;
|
||||||
|
summon.unSummon(summon.getOwner());
|
||||||
|
}
|
||||||
|
else if (_allObjects.remove(object.getObjectId()) != null)
|
||||||
{
|
{
|
||||||
_worldRegions[x][y][z].deleteVisibleNpcSpawns();
|
if (object.isNpc())
|
||||||
|
{
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
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()
|
public void incrementParty()
|
||||||
|
|||||||
@@ -25,7 +25,6 @@ import java.util.logging.Logger;
|
|||||||
|
|
||||||
import com.l2jmobius.Config;
|
import com.l2jmobius.Config;
|
||||||
import com.l2jmobius.commons.concurrent.ThreadPool;
|
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.L2Attackable;
|
||||||
import com.l2jmobius.gameserver.model.actor.L2Npc;
|
import com.l2jmobius.gameserver.model.actor.L2Npc;
|
||||||
import com.l2jmobius.gameserver.model.actor.L2Vehicle;
|
import com.l2jmobius.gameserver.model.actor.L2Vehicle;
|
||||||
@@ -38,17 +37,15 @@ public final class L2WorldRegion
|
|||||||
private volatile Map<Integer, L2Object> _visibleObjects;
|
private volatile Map<Integer, L2Object> _visibleObjects;
|
||||||
private final int _regionX;
|
private final int _regionX;
|
||||||
private final int _regionY;
|
private final int _regionY;
|
||||||
private final int _regionZ;
|
|
||||||
private boolean _active = false;
|
private boolean _active = false;
|
||||||
private ScheduledFuture<?> _neighborsTask = null;
|
private ScheduledFuture<?> _neighborsTask = null;
|
||||||
|
|
||||||
public L2WorldRegion(int regionX, int regionY, int regionZ)
|
public L2WorldRegion(int regionX, int regionY)
|
||||||
{
|
{
|
||||||
_regionX = regionX;
|
_regionX = regionX;
|
||||||
_regionY = regionY;
|
_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;
|
_active = Config.GRIDS_ALWAYS_ON;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -93,19 +90,19 @@ public final class L2WorldRegion
|
|||||||
c++;
|
c++;
|
||||||
final L2Attackable mob = (L2Attackable) o;
|
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);
|
mob.setTarget(null);
|
||||||
|
|
||||||
// Stop movement
|
// Stop movement.
|
||||||
mob.stopMove(null);
|
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.stopAllEffects();
|
||||||
|
|
||||||
mob.clearAggroList();
|
mob.clearAggroList();
|
||||||
mob.getAttackByList().clear();
|
mob.getAttackByList().clear();
|
||||||
|
|
||||||
// stop the ai tasks
|
// Stop the AI tasks.
|
||||||
if (mob.hasAI())
|
if (mob.hasAI())
|
||||||
{
|
{
|
||||||
mob.getAI().setIntention(com.l2jmobius.gameserver.ai.CtrlIntention.AI_INTENTION_IDLE);
|
mob.getAI().setIntention(com.l2jmobius.gameserver.ai.CtrlIntention.AI_INTENTION_IDLE);
|
||||||
@@ -126,7 +123,7 @@ public final class L2WorldRegion
|
|||||||
if (o.isAttackable())
|
if (o.isAttackable())
|
||||||
{
|
{
|
||||||
c++;
|
c++;
|
||||||
// Start HP/MP/CP Regeneration task
|
// Start HP/MP/CP regeneration task.
|
||||||
((L2Attackable) o).getStatus().startHpMpRegeneration();
|
((L2Attackable) o).getStatus().startHpMpRegeneration();
|
||||||
}
|
}
|
||||||
else if (o instanceof L2Npc)
|
else if (o instanceof L2Npc)
|
||||||
@@ -161,7 +158,7 @@ public final class L2WorldRegion
|
|||||||
|
|
||||||
_active = value;
|
_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);
|
switchAI(value);
|
||||||
|
|
||||||
LOGGER.finer((value ? "Starting" : "Stopping") + " Grid " + this);
|
LOGGER.finer((value ? "Starting" : "Stopping") + " Grid " + this);
|
||||||
@@ -172,10 +169,10 @@ public final class L2WorldRegion
|
|||||||
*/
|
*/
|
||||||
private void startActivation()
|
private void startActivation()
|
||||||
{
|
{
|
||||||
// first set self to active and do self-tasks...
|
// First set self to active and do self-tasks...
|
||||||
setActive(true);
|
setActive(true);
|
||||||
|
|
||||||
// if the timer to deactivate neighbors is running, cancel it.
|
// If the timer to deactivate neighbors is running, cancel it.
|
||||||
synchronized (this)
|
synchronized (this)
|
||||||
{
|
{
|
||||||
if (_neighborsTask != null)
|
if (_neighborsTask != null)
|
||||||
@@ -184,7 +181,7 @@ public final class L2WorldRegion
|
|||||||
_neighborsTask = null;
|
_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);
|
_neighborsTask = ThreadPool.schedule(new NeighborsTask(true), 1000 * Config.GRID_NEIGHBOR_TURNON_TIME);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -194,7 +191,7 @@ public final class L2WorldRegion
|
|||||||
*/
|
*/
|
||||||
private void startDeactivation()
|
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)
|
synchronized (this)
|
||||||
{
|
{
|
||||||
if (_neighborsTask != null)
|
if (_neighborsTask != null)
|
||||||
@@ -203,8 +200,8 @@ public final class L2WorldRegion
|
|||||||
_neighborsTask = null;
|
_neighborsTask = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// start a timer to "suggest" a deactivate to self and neighbors.
|
// 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.
|
// 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);
|
_neighborsTask = ThreadPool.schedule(new NeighborsTask(false), 1000 * Config.GRID_NEIGHBOR_TURNOFF_TIME);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -235,7 +232,7 @@ public final class L2WorldRegion
|
|||||||
|
|
||||||
if (object.isPlayable())
|
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))
|
if (!_active && (!Config.GRIDS_ALWAYS_ON))
|
||||||
{
|
{
|
||||||
startActivation();
|
startActivation();
|
||||||
@@ -274,46 +271,15 @@ public final class L2WorldRegion
|
|||||||
return _visibleObjects != null ? _visibleObjects : Collections.emptyMap();
|
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)
|
public boolean forEachSurroundingRegion(Predicate<L2WorldRegion> p)
|
||||||
{
|
{
|
||||||
for (int x = _regionX - 1; x <= (_regionX + 1); x++)
|
for (int x = _regionX - 1; x <= (_regionX + 1); x++)
|
||||||
{
|
{
|
||||||
for (int y = _regionY - 1; y <= (_regionY + 1); y++)
|
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];
|
||||||
{
|
|
||||||
final L2WorldRegion worldRegion = L2World.getInstance().getWorldRegions()[x][y][z];
|
|
||||||
if (!p.test(worldRegion))
|
if (!p.test(worldRegion))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
@@ -321,7 +287,6 @@ public final class L2WorldRegion
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -335,19 +300,14 @@ public final class L2WorldRegion
|
|||||||
return _regionY;
|
return _regionY;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getRegionZ()
|
|
||||||
{
|
|
||||||
return _regionZ;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isSurroundingRegion(L2WorldRegion region)
|
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
|
@Override
|
||||||
public String toString()
|
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.L2Clan;
|
||||||
import com.l2jmobius.gameserver.model.L2Object;
|
import com.l2jmobius.gameserver.model.L2Object;
|
||||||
import com.l2jmobius.gameserver.model.L2Party;
|
import com.l2jmobius.gameserver.model.L2Party;
|
||||||
import com.l2jmobius.gameserver.model.L2Spawn;
|
|
||||||
import com.l2jmobius.gameserver.model.L2World;
|
import com.l2jmobius.gameserver.model.L2World;
|
||||||
import com.l2jmobius.gameserver.model.L2WorldRegion;
|
import com.l2jmobius.gameserver.model.L2WorldRegion;
|
||||||
import com.l2jmobius.gameserver.model.Location;
|
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.FriendlyNpcInstance;
|
||||||
import com.l2jmobius.gameserver.model.actor.instance.L2MonsterInstance;
|
import com.l2jmobius.gameserver.model.actor.instance.L2MonsterInstance;
|
||||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
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.instance.L2TrapInstance;
|
||||||
import com.l2jmobius.gameserver.model.actor.stat.CharStat;
|
import com.l2jmobius.gameserver.model.actor.stat.CharStat;
|
||||||
import com.l2jmobius.gameserver.model.actor.status.CharStatus;
|
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?
|
else // Precaution. Moved at invalid region?
|
||||||
{
|
{
|
||||||
if (isPlayer())
|
L2World.getInstance().disposeOutOfBoundsObject(this);
|
||||||
{
|
|
||||||
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();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -226,50 +226,6 @@ public final class Util
|
|||||||
return calculateDistance(obj1, obj2, includeZAxis, false) <= range;
|
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
|
* @param text - the text to check
|
||||||
* @return {@code true} if {@code text} contains only numbers, {@code false} otherwise
|
* @return {@code true} if {@code text} contains only numbers, {@code false} otherwise
|
||||||
|
|||||||
+1
-1
@@ -61,7 +61,7 @@ public final class HillsOfGold extends AbstractNpcAI
|
|||||||
{
|
{
|
||||||
if ((npc != null) && !npc.isDead())
|
if ((npc != null) && !npc.isDead())
|
||||||
{
|
{
|
||||||
L2World.getInstance().forEachVisibleObject(npc, L2MonsterInstance.class, npc.getAggroRange(), nearby ->
|
L2World.getInstance().forEachVisibleObjectInRange(npc, L2MonsterInstance.class, npc.getAggroRange(), nearby ->
|
||||||
{
|
{
|
||||||
if (npc.isInCombat())
|
if (npc.isInCombat())
|
||||||
{
|
{
|
||||||
|
|||||||
+1
-1
@@ -344,7 +344,7 @@ public final class SeedOfAnnihilation extends AbstractNpcAI
|
|||||||
{
|
{
|
||||||
final Location teleLoc = TELEPORT_ZONES.get(zone.getId());
|
final Location teleLoc = TELEPORT_ZONES.get(zone.getId());
|
||||||
// Conditions for Quest 454
|
// Conditions for Quest 454
|
||||||
L2World.getInstance().forEachVisibleObject(character, L2Npc.class, 500, npc ->
|
L2World.getInstance().forEachVisibleObjectInRange(character, L2Npc.class, 500, npc ->
|
||||||
{
|
{
|
||||||
if ((npc.getId() == 32738) && (npc.getTarget() != null))
|
if ((npc.getId() == 32738) && (npc.getTarget() != null))
|
||||||
{
|
{
|
||||||
|
|||||||
Vendored
+28
-2
@@ -213,14 +213,40 @@ public class AdminSpawn implements IAdminCommandHandler
|
|||||||
{
|
{
|
||||||
Broadcast.toAllOnlinePlayers(SystemMessage.getSystemMessage(SystemMessageId.THE_NPC_SERVER_IS_NOT_OPERATING_AT_THIS_TIME));
|
Broadcast.toAllOnlinePlayers(SystemMessage.getSystemMessage(SystemMessageId.THE_NPC_SERVER_IS_NOT_OPERATING_AT_THIS_TIME));
|
||||||
DBSpawnManager.getInstance().cleanUp();
|
DBSpawnManager.getInstance().cleanUp();
|
||||||
L2World.getInstance().deleteVisibleNpcSpawns();
|
for (L2Object obj : L2World.getInstance().getVisibleObjects())
|
||||||
|
{
|
||||||
|
if ((obj != null) && obj.isNpc())
|
||||||
|
{
|
||||||
|
final L2Npc target = (L2Npc) obj;
|
||||||
|
target.deleteMe();
|
||||||
|
final L2Spawn spawn = target.getSpawn();
|
||||||
|
if (spawn != null)
|
||||||
|
{
|
||||||
|
spawn.stopRespawn();
|
||||||
|
SpawnTable.getInstance().deleteSpawn(spawn, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
AdminData.getInstance().broadcastMessageToGMs("NPC Unspawn completed!");
|
AdminData.getInstance().broadcastMessageToGMs("NPC Unspawn completed!");
|
||||||
}
|
}
|
||||||
else if (command.startsWith("admin_respawnall") || command.startsWith("admin_spawn_reload"))
|
else if (command.startsWith("admin_respawnall") || command.startsWith("admin_spawn_reload"))
|
||||||
{
|
{
|
||||||
// make sure all spawns are deleted
|
// make sure all spawns are deleted
|
||||||
DBSpawnManager.getInstance().cleanUp();
|
DBSpawnManager.getInstance().cleanUp();
|
||||||
L2World.getInstance().deleteVisibleNpcSpawns();
|
for (L2Object obj : L2World.getInstance().getVisibleObjects())
|
||||||
|
{
|
||||||
|
if ((obj != null) && obj.isNpc())
|
||||||
|
{
|
||||||
|
final L2Npc target = (L2Npc) obj;
|
||||||
|
target.deleteMe();
|
||||||
|
final L2Spawn spawn = target.getSpawn();
|
||||||
|
if (spawn != null)
|
||||||
|
{
|
||||||
|
spawn.stopRespawn();
|
||||||
|
SpawnTable.getInstance().deleteSpawn(spawn, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
// now respawn all
|
// now respawn all
|
||||||
NpcData.getInstance().load();
|
NpcData.getInstance().load();
|
||||||
DBSpawnManager.getInstance().load();
|
DBSpawnManager.getInstance().load();
|
||||||
|
|||||||
Vendored
+1
-1
@@ -190,7 +190,7 @@ public class AdminTeleport implements IAdminCommandHandler
|
|||||||
st.nextToken();
|
st.nextToken();
|
||||||
final int x = (int) Float.parseFloat(st.nextToken());
|
final int x = (int) Float.parseFloat(st.nextToken());
|
||||||
final int y = (int) Float.parseFloat(st.nextToken());
|
final int y = (int) Float.parseFloat(st.nextToken());
|
||||||
final int z = st.hasMoreTokens() ? ((int) Float.parseFloat(st.nextToken())) : GeoEngine.getInstance().getHeight(x, y, L2World.MAP_MAX_Z);
|
final int z = st.hasMoreTokens() ? ((int) Float.parseFloat(st.nextToken())) : GeoEngine.getInstance().getHeight(x, y, 10000);
|
||||||
|
|
||||||
activeChar.teleToLocation(x, y, z);
|
activeChar.teleToLocation(x, y, z);
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -184,7 +184,7 @@ public final class FenceData implements IGameXmlReader
|
|||||||
return false;
|
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);
|
return region == null ? false : _regions.getOrDefault(region, Collections.emptyList()).stream().anyMatch(filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -115,7 +115,7 @@ public final class ItemsOnGroundManager implements Runnable
|
|||||||
item.setEnchantLevel(rs.getInt(4));
|
item.setEnchantLevel(rs.getInt(4));
|
||||||
}
|
}
|
||||||
item.setXYZ(rs.getInt(5), rs.getInt(6), rs.getInt(7));
|
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);
|
item.getWorldRegion().addVisibleObject(item);
|
||||||
final long dropTime = rs.getLong(8);
|
final long dropTime = rs.getLong(8);
|
||||||
item.setDropTime(dropTime);
|
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
|
// Set the x,y,z position of the L2Object spawn and update its _worldregion
|
||||||
_isSpawned = true;
|
_isSpawned = true;
|
||||||
setWorldRegion(L2World.getInstance().getRegion(getLocation()));
|
setWorldRegion(L2World.getInstance().getRegion(this));
|
||||||
|
|
||||||
// Add the L2Object spawn in the _allobjects of L2World
|
// Add the L2Object spawn in the _allobjects of L2World
|
||||||
L2World.getInstance().addObject(this);
|
L2World.getInstance().addObject(this);
|
||||||
@@ -207,14 +207,6 @@ public abstract class L2Object extends ListenersContainer implements IIdentifiab
|
|||||||
{
|
{
|
||||||
y = L2World.MAP_MIN_Y + 5000;
|
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.
|
// 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);
|
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.instancemanager.PlayerCountManager;
|
||||||
import com.l2jmobius.gameserver.model.actor.L2Character;
|
import com.l2jmobius.gameserver.model.actor.L2Character;
|
||||||
import com.l2jmobius.gameserver.model.actor.L2Npc;
|
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.L2PcInstance;
|
||||||
import com.l2jmobius.gameserver.model.actor.instance.L2PetInstance;
|
import com.l2jmobius.gameserver.model.actor.instance.L2PetInstance;
|
||||||
import com.l2jmobius.gameserver.model.events.EventDispatcher;
|
import com.l2jmobius.gameserver.model.events.EventDispatcher;
|
||||||
import com.l2jmobius.gameserver.model.events.impl.character.npc.OnNpcCreatureSee;
|
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.Disconnection;
|
||||||
import com.l2jmobius.gameserver.network.serverpackets.DeleteObject;
|
import com.l2jmobius.gameserver.network.serverpackets.DeleteObject;
|
||||||
import com.l2jmobius.gameserver.util.Util;
|
|
||||||
|
|
||||||
public final class L2World
|
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. */
|
/** 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 = 11;
|
||||||
public static final int SHIFT_BY_Z = 10;
|
|
||||||
|
|
||||||
public static final int TILE_SIZE = 32768;
|
public static final int TILE_SIZE = 32768;
|
||||||
|
|
||||||
/** Map dimensions */
|
/** Map dimensions. */
|
||||||
public static final int TILE_X_MIN = 11;
|
public static final int TILE_X_MIN = 11;
|
||||||
public static final int TILE_Y_MIN = 10;
|
public static final int TILE_Y_MIN = 10;
|
||||||
public static final int TILE_X_MAX = 28;
|
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 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_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_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_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_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_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_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_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_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. */
|
/** Map containing all the players in game. */
|
||||||
private final Map<Integer, L2PcInstance> _allPlayers = new ConcurrentHashMap<>();
|
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 _partyNumber = new AtomicInteger();
|
||||||
private final AtomicInteger _memberInPartyNumber = 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. */
|
/** Constructor of L2World. */
|
||||||
protected L2World()
|
protected L2World()
|
||||||
@@ -108,14 +103,11 @@ public final class L2World
|
|||||||
{
|
{
|
||||||
for (int y = 0; y <= REGIONS_Y; y++)
|
for (int y = 0; y <= REGIONS_Y; y++)
|
||||||
{
|
{
|
||||||
for (int z = 0; z <= REGIONS_Z; z++)
|
_worldRegions[x][y] = new L2WorldRegion(x, y);
|
||||||
{
|
|
||||||
_worldRegions[x][y][z] = new L2WorldRegion(x, y, z);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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();
|
PlayerCountManager.getInstance().incConnectedCount();
|
||||||
|
|
||||||
final L2PcInstance newPlayer = (L2PcInstance) object;
|
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;
|
return;
|
||||||
}
|
}
|
||||||
@@ -176,7 +168,7 @@ public final class L2World
|
|||||||
PlayerCountManager.getInstance().decConnectedCount();
|
PlayerCountManager.getInstance().decConnectedCount();
|
||||||
|
|
||||||
final L2PcInstance player = (L2PcInstance) object;
|
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;
|
return;
|
||||||
}
|
}
|
||||||
@@ -309,7 +301,7 @@ public final class L2World
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
forEachVisibleObject(object, L2Object.class, 1, wo ->
|
forEachVisibleObject(object, L2Object.class, wo ->
|
||||||
{
|
{
|
||||||
if (object.isPlayer() && wo.isVisibleFor((L2PcInstance) object))
|
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)
|
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)
|
public <T extends L2Object> void forEachVisibleObjectInRange(L2Object object, Class<T> clazz, int range, Consumer<T> c)
|
||||||
@@ -640,22 +594,15 @@ public final class L2World
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
final int depth = (range / REGION_MIN_DIMENSION) + 1;
|
final int regionX = centerWorldRegion.getRegionX();
|
||||||
for (int x = Math.max(centerWorldRegion.getRegionX() - depth, 0); x <= Math.min(centerWorldRegion.getRegionX() + depth, REGIONS_X); x++)
|
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;
|
for (L2Object visibleObject : _worldRegions[x][y].getVisibleObjects().values())
|
||||||
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][z].getVisibleObjects().values())
|
|
||||||
{
|
{
|
||||||
if ((visibleObject == null) || (visibleObject == object) || !clazz.isInstance(visibleObject))
|
if ((visibleObject == null) || (visibleObject == object) || !clazz.isInstance(visibleObject))
|
||||||
{
|
{
|
||||||
@@ -673,6 +620,10 @@ public final class L2World
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if ((x == regionX) && (y == regionY)) // Precaution. Moved at invalid region?
|
||||||
|
{
|
||||||
|
disposeOutOfBoundsObject(object);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -680,22 +631,12 @@ public final class L2World
|
|||||||
|
|
||||||
public <T extends L2Object> List<T> getVisibleObjects(L2Object object, Class<T> clazz)
|
public <T extends L2Object> List<T> getVisibleObjects(L2Object object, Class<T> clazz)
|
||||||
{
|
{
|
||||||
final List<T> result = new LinkedList<>();
|
return getVisibleObjects(object, clazz, VISIBILITY_RANGE);
|
||||||
forEachVisibleObject(object, clazz, result::add);
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public <T extends L2Object> List<T> getVisibleObjects(L2Object object, Class<T> clazz, Predicate<T> predicate)
|
public <T extends L2Object> List<T> getVisibleObjects(L2Object object, Class<T> clazz, Predicate<T> predicate)
|
||||||
{
|
{
|
||||||
final List<T> result = new LinkedList<>();
|
return getVisibleObjects(object, clazz, VISIBILITY_RANGE, predicate);
|
||||||
forEachVisibleObject(object, clazz, o ->
|
|
||||||
{
|
|
||||||
if (predicate.test(o))
|
|
||||||
{
|
|
||||||
result.add(o);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public <T extends L2Object> List<T> getVisibleObjects(L2Object object, Class<T> clazz, int range)
|
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>
|
* 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>Set position of a new L2Object (drop, spawn...)</li>
|
||||||
* <li>Update position of a L2Object after a movement</li><BR>
|
* <li>Update position of a L2Object after a movement</li><BR>
|
||||||
* @param point position of the object
|
* @param object the object
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public L2WorldRegion getRegion(ILocational point)
|
public L2WorldRegion getRegion(L2Object object)
|
||||||
{
|
|
||||||
return getRegion(point.getX(), point.getY(), point.getZ());
|
|
||||||
}
|
|
||||||
|
|
||||||
public L2WorldRegion getRegion(int x, int y, int z)
|
|
||||||
{
|
{
|
||||||
try
|
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)
|
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));
|
||||||
// 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);
|
|
||||||
return null;
|
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
|
* Returns the whole 3d array containing the world regions used by ZoneData.java to setup zones inside the world regions
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public L2WorldRegion[][][] getWorldRegions()
|
public L2WorldRegion[][] getWorldRegions()
|
||||||
{
|
{
|
||||||
return _worldRegions;
|
return _worldRegions;
|
||||||
}
|
}
|
||||||
@@ -758,31 +706,49 @@ public final class L2World
|
|||||||
* <li>Init L2WorldRegions</li><BR>
|
* <li>Init L2WorldRegions</li><BR>
|
||||||
* @param x X position of the object
|
* @param x X position of the object
|
||||||
* @param y Y 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
|
* @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));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public synchronized void disposeOutOfBoundsObject(L2Object object)
|
||||||
* Deleted all spawns in the world.
|
|
||||||
*/
|
|
||||||
public void deleteVisibleNpcSpawns()
|
|
||||||
{
|
{
|
||||||
LOGGER.info(getClass().getSimpleName() + ": Deleting all visible NPCs.");
|
if (object.isPlayer())
|
||||||
for (int x = 0; x <= REGIONS_X; x++)
|
|
||||||
{
|
{
|
||||||
for (int y = 0; y <= REGIONS_Y; y++)
|
((L2Character) object).stopMove(((L2PcInstance) object).getLastServerPosition());
|
||||||
|
}
|
||||||
|
else if (object.isSummon())
|
||||||
{
|
{
|
||||||
for (int z = 0; z <= REGIONS_Z; z++)
|
final L2Summon summon = (L2Summon) object;
|
||||||
|
summon.unSummon(summon.getOwner());
|
||||||
|
}
|
||||||
|
else if (_allObjects.remove(object.getObjectId()) != null)
|
||||||
{
|
{
|
||||||
_worldRegions[x][y][z].deleteVisibleNpcSpawns();
|
if (object.isNpc())
|
||||||
|
{
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
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()
|
public void incrementParty()
|
||||||
|
|||||||
@@ -25,7 +25,6 @@ import java.util.logging.Logger;
|
|||||||
|
|
||||||
import com.l2jmobius.Config;
|
import com.l2jmobius.Config;
|
||||||
import com.l2jmobius.commons.concurrent.ThreadPool;
|
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.L2Attackable;
|
||||||
import com.l2jmobius.gameserver.model.actor.L2Npc;
|
import com.l2jmobius.gameserver.model.actor.L2Npc;
|
||||||
import com.l2jmobius.gameserver.model.actor.L2Vehicle;
|
import com.l2jmobius.gameserver.model.actor.L2Vehicle;
|
||||||
@@ -38,17 +37,15 @@ public final class L2WorldRegion
|
|||||||
private volatile Map<Integer, L2Object> _visibleObjects;
|
private volatile Map<Integer, L2Object> _visibleObjects;
|
||||||
private final int _regionX;
|
private final int _regionX;
|
||||||
private final int _regionY;
|
private final int _regionY;
|
||||||
private final int _regionZ;
|
|
||||||
private boolean _active = false;
|
private boolean _active = false;
|
||||||
private ScheduledFuture<?> _neighborsTask = null;
|
private ScheduledFuture<?> _neighborsTask = null;
|
||||||
|
|
||||||
public L2WorldRegion(int regionX, int regionY, int regionZ)
|
public L2WorldRegion(int regionX, int regionY)
|
||||||
{
|
{
|
||||||
_regionX = regionX;
|
_regionX = regionX;
|
||||||
_regionY = regionY;
|
_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;
|
_active = Config.GRIDS_ALWAYS_ON;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -93,19 +90,19 @@ public final class L2WorldRegion
|
|||||||
c++;
|
c++;
|
||||||
final L2Attackable mob = (L2Attackable) o;
|
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);
|
mob.setTarget(null);
|
||||||
|
|
||||||
// Stop movement
|
// Stop movement.
|
||||||
mob.stopMove(null);
|
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.stopAllEffects();
|
||||||
|
|
||||||
mob.clearAggroList();
|
mob.clearAggroList();
|
||||||
mob.getAttackByList().clear();
|
mob.getAttackByList().clear();
|
||||||
|
|
||||||
// stop the ai tasks
|
// Stop the AI tasks.
|
||||||
if (mob.hasAI())
|
if (mob.hasAI())
|
||||||
{
|
{
|
||||||
mob.getAI().setIntention(com.l2jmobius.gameserver.ai.CtrlIntention.AI_INTENTION_IDLE);
|
mob.getAI().setIntention(com.l2jmobius.gameserver.ai.CtrlIntention.AI_INTENTION_IDLE);
|
||||||
@@ -126,7 +123,7 @@ public final class L2WorldRegion
|
|||||||
if (o.isAttackable())
|
if (o.isAttackable())
|
||||||
{
|
{
|
||||||
c++;
|
c++;
|
||||||
// Start HP/MP/CP Regeneration task
|
// Start HP/MP/CP regeneration task.
|
||||||
((L2Attackable) o).getStatus().startHpMpRegeneration();
|
((L2Attackable) o).getStatus().startHpMpRegeneration();
|
||||||
}
|
}
|
||||||
else if (o instanceof L2Npc)
|
else if (o instanceof L2Npc)
|
||||||
@@ -161,7 +158,7 @@ public final class L2WorldRegion
|
|||||||
|
|
||||||
_active = value;
|
_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);
|
switchAI(value);
|
||||||
|
|
||||||
LOGGER.finer((value ? "Starting" : "Stopping") + " Grid " + this);
|
LOGGER.finer((value ? "Starting" : "Stopping") + " Grid " + this);
|
||||||
@@ -172,10 +169,10 @@ public final class L2WorldRegion
|
|||||||
*/
|
*/
|
||||||
private void startActivation()
|
private void startActivation()
|
||||||
{
|
{
|
||||||
// first set self to active and do self-tasks...
|
// First set self to active and do self-tasks...
|
||||||
setActive(true);
|
setActive(true);
|
||||||
|
|
||||||
// if the timer to deactivate neighbors is running, cancel it.
|
// If the timer to deactivate neighbors is running, cancel it.
|
||||||
synchronized (this)
|
synchronized (this)
|
||||||
{
|
{
|
||||||
if (_neighborsTask != null)
|
if (_neighborsTask != null)
|
||||||
@@ -184,7 +181,7 @@ public final class L2WorldRegion
|
|||||||
_neighborsTask = null;
|
_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);
|
_neighborsTask = ThreadPool.schedule(new NeighborsTask(true), 1000 * Config.GRID_NEIGHBOR_TURNON_TIME);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -194,7 +191,7 @@ public final class L2WorldRegion
|
|||||||
*/
|
*/
|
||||||
private void startDeactivation()
|
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)
|
synchronized (this)
|
||||||
{
|
{
|
||||||
if (_neighborsTask != null)
|
if (_neighborsTask != null)
|
||||||
@@ -203,8 +200,8 @@ public final class L2WorldRegion
|
|||||||
_neighborsTask = null;
|
_neighborsTask = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// start a timer to "suggest" a deactivate to self and neighbors.
|
// 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.
|
// 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);
|
_neighborsTask = ThreadPool.schedule(new NeighborsTask(false), 1000 * Config.GRID_NEIGHBOR_TURNOFF_TIME);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -235,7 +232,7 @@ public final class L2WorldRegion
|
|||||||
|
|
||||||
if (object.isPlayable())
|
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))
|
if (!_active && (!Config.GRIDS_ALWAYS_ON))
|
||||||
{
|
{
|
||||||
startActivation();
|
startActivation();
|
||||||
@@ -274,46 +271,15 @@ public final class L2WorldRegion
|
|||||||
return _visibleObjects != null ? _visibleObjects : Collections.emptyMap();
|
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)
|
public boolean forEachSurroundingRegion(Predicate<L2WorldRegion> p)
|
||||||
{
|
{
|
||||||
for (int x = _regionX - 1; x <= (_regionX + 1); x++)
|
for (int x = _regionX - 1; x <= (_regionX + 1); x++)
|
||||||
{
|
{
|
||||||
for (int y = _regionY - 1; y <= (_regionY + 1); y++)
|
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];
|
||||||
{
|
|
||||||
final L2WorldRegion worldRegion = L2World.getInstance().getWorldRegions()[x][y][z];
|
|
||||||
if (!p.test(worldRegion))
|
if (!p.test(worldRegion))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
@@ -321,7 +287,6 @@ public final class L2WorldRegion
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -335,19 +300,14 @@ public final class L2WorldRegion
|
|||||||
return _regionY;
|
return _regionY;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getRegionZ()
|
|
||||||
{
|
|
||||||
return _regionZ;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isSurroundingRegion(L2WorldRegion region)
|
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
|
@Override
|
||||||
public String toString()
|
public String toString()
|
||||||
{
|
{
|
||||||
return "(" + _regionX + ", " + _regionY + ", " + _regionZ + ")";
|
return "(" + _regionX + ", " + _regionY + ")";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-27
@@ -73,7 +73,6 @@ import com.l2jmobius.gameserver.model.L2AccessLevel;
|
|||||||
import com.l2jmobius.gameserver.model.L2Clan;
|
import com.l2jmobius.gameserver.model.L2Clan;
|
||||||
import com.l2jmobius.gameserver.model.L2Object;
|
import com.l2jmobius.gameserver.model.L2Object;
|
||||||
import com.l2jmobius.gameserver.model.L2Party;
|
import com.l2jmobius.gameserver.model.L2Party;
|
||||||
import com.l2jmobius.gameserver.model.L2Spawn;
|
|
||||||
import com.l2jmobius.gameserver.model.L2World;
|
import com.l2jmobius.gameserver.model.L2World;
|
||||||
import com.l2jmobius.gameserver.model.L2WorldRegion;
|
import com.l2jmobius.gameserver.model.L2WorldRegion;
|
||||||
import com.l2jmobius.gameserver.model.Location;
|
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.FriendlyNpcInstance;
|
||||||
import com.l2jmobius.gameserver.model.actor.instance.L2MonsterInstance;
|
import com.l2jmobius.gameserver.model.actor.instance.L2MonsterInstance;
|
||||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
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.instance.L2TrapInstance;
|
||||||
import com.l2jmobius.gameserver.model.actor.stat.CharStat;
|
import com.l2jmobius.gameserver.model.actor.stat.CharStat;
|
||||||
import com.l2jmobius.gameserver.model.actor.status.CharStatus;
|
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?
|
else // Precaution. Moved at invalid region?
|
||||||
{
|
{
|
||||||
if (isPlayer())
|
L2World.getInstance().disposeOutOfBoundsObject(this);
|
||||||
{
|
|
||||||
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();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -226,50 +226,6 @@ public final class Util
|
|||||||
return calculateDistance(obj1, obj2, includeZAxis, false) <= range;
|
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
|
* @param text - the text to check
|
||||||
* @return {@code true} if {@code text} contains only numbers, {@code false} otherwise
|
* @return {@code true} if {@code text} contains only numbers, {@code false} otherwise
|
||||||
|
|||||||
+1
-1
@@ -61,7 +61,7 @@ public final class HillsOfGold extends AbstractNpcAI
|
|||||||
{
|
{
|
||||||
if ((npc != null) && !npc.isDead())
|
if ((npc != null) && !npc.isDead())
|
||||||
{
|
{
|
||||||
L2World.getInstance().forEachVisibleObject(npc, L2MonsterInstance.class, npc.getAggroRange(), nearby ->
|
L2World.getInstance().forEachVisibleObjectInRange(npc, L2MonsterInstance.class, npc.getAggroRange(), nearby ->
|
||||||
{
|
{
|
||||||
if (npc.isInCombat())
|
if (npc.isInCombat())
|
||||||
{
|
{
|
||||||
|
|||||||
Vendored
+1
-1
@@ -344,7 +344,7 @@ public final class SeedOfAnnihilation extends AbstractNpcAI
|
|||||||
{
|
{
|
||||||
final Location teleLoc = TELEPORT_ZONES.get(zone.getId());
|
final Location teleLoc = TELEPORT_ZONES.get(zone.getId());
|
||||||
// Conditions for Quest 454
|
// Conditions for Quest 454
|
||||||
L2World.getInstance().forEachVisibleObject(character, L2Npc.class, 500, npc ->
|
L2World.getInstance().forEachVisibleObjectInRange(character, L2Npc.class, 500, npc ->
|
||||||
{
|
{
|
||||||
if ((npc.getId() == 32738) && (npc.getTarget() != null))
|
if ((npc.getId() == 32738) && (npc.getTarget() != null))
|
||||||
{
|
{
|
||||||
|
|||||||
+28
-2
@@ -213,14 +213,40 @@ public class AdminSpawn implements IAdminCommandHandler
|
|||||||
{
|
{
|
||||||
Broadcast.toAllOnlinePlayers(SystemMessage.getSystemMessage(SystemMessageId.THE_NPC_SERVER_IS_NOT_OPERATING_AT_THIS_TIME));
|
Broadcast.toAllOnlinePlayers(SystemMessage.getSystemMessage(SystemMessageId.THE_NPC_SERVER_IS_NOT_OPERATING_AT_THIS_TIME));
|
||||||
DBSpawnManager.getInstance().cleanUp();
|
DBSpawnManager.getInstance().cleanUp();
|
||||||
L2World.getInstance().deleteVisibleNpcSpawns();
|
for (L2Object obj : L2World.getInstance().getVisibleObjects())
|
||||||
|
{
|
||||||
|
if ((obj != null) && obj.isNpc())
|
||||||
|
{
|
||||||
|
final L2Npc target = (L2Npc) obj;
|
||||||
|
target.deleteMe();
|
||||||
|
final L2Spawn spawn = target.getSpawn();
|
||||||
|
if (spawn != null)
|
||||||
|
{
|
||||||
|
spawn.stopRespawn();
|
||||||
|
SpawnTable.getInstance().deleteSpawn(spawn, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
AdminData.getInstance().broadcastMessageToGMs("NPC Unspawn completed!");
|
AdminData.getInstance().broadcastMessageToGMs("NPC Unspawn completed!");
|
||||||
}
|
}
|
||||||
else if (command.startsWith("admin_respawnall") || command.startsWith("admin_spawn_reload"))
|
else if (command.startsWith("admin_respawnall") || command.startsWith("admin_spawn_reload"))
|
||||||
{
|
{
|
||||||
// make sure all spawns are deleted
|
// make sure all spawns are deleted
|
||||||
DBSpawnManager.getInstance().cleanUp();
|
DBSpawnManager.getInstance().cleanUp();
|
||||||
L2World.getInstance().deleteVisibleNpcSpawns();
|
for (L2Object obj : L2World.getInstance().getVisibleObjects())
|
||||||
|
{
|
||||||
|
if ((obj != null) && obj.isNpc())
|
||||||
|
{
|
||||||
|
final L2Npc target = (L2Npc) obj;
|
||||||
|
target.deleteMe();
|
||||||
|
final L2Spawn spawn = target.getSpawn();
|
||||||
|
if (spawn != null)
|
||||||
|
{
|
||||||
|
spawn.stopRespawn();
|
||||||
|
SpawnTable.getInstance().deleteSpawn(spawn, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
// now respawn all
|
// now respawn all
|
||||||
NpcData.getInstance().load();
|
NpcData.getInstance().load();
|
||||||
DBSpawnManager.getInstance().load();
|
DBSpawnManager.getInstance().load();
|
||||||
|
|||||||
Vendored
+1
-1
@@ -190,7 +190,7 @@ public class AdminTeleport implements IAdminCommandHandler
|
|||||||
st.nextToken();
|
st.nextToken();
|
||||||
final int x = (int) Float.parseFloat(st.nextToken());
|
final int x = (int) Float.parseFloat(st.nextToken());
|
||||||
final int y = (int) Float.parseFloat(st.nextToken());
|
final int y = (int) Float.parseFloat(st.nextToken());
|
||||||
final int z = st.hasMoreTokens() ? ((int) Float.parseFloat(st.nextToken())) : GeoEngine.getInstance().getHeight(x, y, L2World.MAP_MAX_Z);
|
final int z = st.hasMoreTokens() ? ((int) Float.parseFloat(st.nextToken())) : GeoEngine.getInstance().getHeight(x, y, 10000);
|
||||||
|
|
||||||
activeChar.teleToLocation(x, y, z);
|
activeChar.teleToLocation(x, y, z);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -184,7 +184,7 @@ public final class FenceData implements IGameXmlReader
|
|||||||
return false;
|
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);
|
return region == null ? false : _regions.getOrDefault(region, Collections.emptyList()).stream().anyMatch(filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -115,7 +115,7 @@ public final class ItemsOnGroundManager implements Runnable
|
|||||||
item.setEnchantLevel(rs.getInt(4));
|
item.setEnchantLevel(rs.getInt(4));
|
||||||
}
|
}
|
||||||
item.setXYZ(rs.getInt(5), rs.getInt(6), rs.getInt(7));
|
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);
|
item.getWorldRegion().addVisibleObject(item);
|
||||||
final long dropTime = rs.getLong(8);
|
final long dropTime = rs.getLong(8);
|
||||||
item.setDropTime(dropTime);
|
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
|
// Set the x,y,z position of the L2Object spawn and update its _worldregion
|
||||||
_isSpawned = true;
|
_isSpawned = true;
|
||||||
setWorldRegion(L2World.getInstance().getRegion(getLocation()));
|
setWorldRegion(L2World.getInstance().getRegion(this));
|
||||||
|
|
||||||
// Add the L2Object spawn in the _allobjects of L2World
|
// Add the L2Object spawn in the _allobjects of L2World
|
||||||
L2World.getInstance().addObject(this);
|
L2World.getInstance().addObject(this);
|
||||||
@@ -207,14 +207,6 @@ public abstract class L2Object extends ListenersContainer implements IIdentifiab
|
|||||||
{
|
{
|
||||||
y = L2World.MAP_MIN_Y + 5000;
|
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.
|
// 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);
|
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.instancemanager.PlayerCountManager;
|
||||||
import com.l2jmobius.gameserver.model.actor.L2Character;
|
import com.l2jmobius.gameserver.model.actor.L2Character;
|
||||||
import com.l2jmobius.gameserver.model.actor.L2Npc;
|
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.L2PcInstance;
|
||||||
import com.l2jmobius.gameserver.model.actor.instance.L2PetInstance;
|
import com.l2jmobius.gameserver.model.actor.instance.L2PetInstance;
|
||||||
import com.l2jmobius.gameserver.model.events.EventDispatcher;
|
import com.l2jmobius.gameserver.model.events.EventDispatcher;
|
||||||
import com.l2jmobius.gameserver.model.events.impl.character.npc.OnNpcCreatureSee;
|
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.Disconnection;
|
||||||
import com.l2jmobius.gameserver.network.serverpackets.DeleteObject;
|
import com.l2jmobius.gameserver.network.serverpackets.DeleteObject;
|
||||||
import com.l2jmobius.gameserver.util.Util;
|
|
||||||
|
|
||||||
public final class L2World
|
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. */
|
/** 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 = 11;
|
||||||
public static final int SHIFT_BY_Z = 10;
|
|
||||||
|
|
||||||
public static final int TILE_SIZE = 32768;
|
public static final int TILE_SIZE = 32768;
|
||||||
|
|
||||||
/** Map dimensions */
|
/** Map dimensions. */
|
||||||
public static final int TILE_X_MIN = 11;
|
public static final int TILE_X_MIN = 11;
|
||||||
public static final int TILE_Y_MIN = 10;
|
public static final int TILE_Y_MIN = 10;
|
||||||
public static final int TILE_X_MAX = 28;
|
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 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_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_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_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_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_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_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_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_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. */
|
/** Map containing all the players in game. */
|
||||||
private final Map<Integer, L2PcInstance> _allPlayers = new ConcurrentHashMap<>();
|
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 _partyNumber = new AtomicInteger();
|
||||||
private final AtomicInteger _memberInPartyNumber = 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. */
|
/** Constructor of L2World. */
|
||||||
protected L2World()
|
protected L2World()
|
||||||
@@ -108,14 +103,11 @@ public final class L2World
|
|||||||
{
|
{
|
||||||
for (int y = 0; y <= REGIONS_Y; y++)
|
for (int y = 0; y <= REGIONS_Y; y++)
|
||||||
{
|
{
|
||||||
for (int z = 0; z <= REGIONS_Z; z++)
|
_worldRegions[x][y] = new L2WorldRegion(x, y);
|
||||||
{
|
|
||||||
_worldRegions[x][y][z] = new L2WorldRegion(x, y, z);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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();
|
PlayerCountManager.getInstance().incConnectedCount();
|
||||||
|
|
||||||
final L2PcInstance newPlayer = (L2PcInstance) object;
|
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;
|
return;
|
||||||
}
|
}
|
||||||
@@ -176,7 +168,7 @@ public final class L2World
|
|||||||
PlayerCountManager.getInstance().decConnectedCount();
|
PlayerCountManager.getInstance().decConnectedCount();
|
||||||
|
|
||||||
final L2PcInstance player = (L2PcInstance) object;
|
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;
|
return;
|
||||||
}
|
}
|
||||||
@@ -309,7 +301,7 @@ public final class L2World
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
forEachVisibleObject(object, L2Object.class, 1, wo ->
|
forEachVisibleObject(object, L2Object.class, wo ->
|
||||||
{
|
{
|
||||||
if (object.isPlayer() && wo.isVisibleFor((L2PcInstance) object))
|
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)
|
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)
|
public <T extends L2Object> void forEachVisibleObjectInRange(L2Object object, Class<T> clazz, int range, Consumer<T> c)
|
||||||
@@ -640,22 +594,15 @@ public final class L2World
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
final int depth = (range / REGION_MIN_DIMENSION) + 1;
|
final int regionX = centerWorldRegion.getRegionX();
|
||||||
for (int x = Math.max(centerWorldRegion.getRegionX() - depth, 0); x <= Math.min(centerWorldRegion.getRegionX() + depth, REGIONS_X); x++)
|
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;
|
for (L2Object visibleObject : _worldRegions[x][y].getVisibleObjects().values())
|
||||||
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][z].getVisibleObjects().values())
|
|
||||||
{
|
{
|
||||||
if ((visibleObject == null) || (visibleObject == object) || !clazz.isInstance(visibleObject))
|
if ((visibleObject == null) || (visibleObject == object) || !clazz.isInstance(visibleObject))
|
||||||
{
|
{
|
||||||
@@ -673,6 +620,10 @@ public final class L2World
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if ((x == regionX) && (y == regionY)) // Precaution. Moved at invalid region?
|
||||||
|
{
|
||||||
|
disposeOutOfBoundsObject(object);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -680,22 +631,12 @@ public final class L2World
|
|||||||
|
|
||||||
public <T extends L2Object> List<T> getVisibleObjects(L2Object object, Class<T> clazz)
|
public <T extends L2Object> List<T> getVisibleObjects(L2Object object, Class<T> clazz)
|
||||||
{
|
{
|
||||||
final List<T> result = new LinkedList<>();
|
return getVisibleObjects(object, clazz, VISIBILITY_RANGE);
|
||||||
forEachVisibleObject(object, clazz, result::add);
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public <T extends L2Object> List<T> getVisibleObjects(L2Object object, Class<T> clazz, Predicate<T> predicate)
|
public <T extends L2Object> List<T> getVisibleObjects(L2Object object, Class<T> clazz, Predicate<T> predicate)
|
||||||
{
|
{
|
||||||
final List<T> result = new LinkedList<>();
|
return getVisibleObjects(object, clazz, VISIBILITY_RANGE, predicate);
|
||||||
forEachVisibleObject(object, clazz, o ->
|
|
||||||
{
|
|
||||||
if (predicate.test(o))
|
|
||||||
{
|
|
||||||
result.add(o);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public <T extends L2Object> List<T> getVisibleObjects(L2Object object, Class<T> clazz, int range)
|
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>
|
* 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>Set position of a new L2Object (drop, spawn...)</li>
|
||||||
* <li>Update position of a L2Object after a movement</li><BR>
|
* <li>Update position of a L2Object after a movement</li><BR>
|
||||||
* @param point position of the object
|
* @param object the object
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public L2WorldRegion getRegion(ILocational point)
|
public L2WorldRegion getRegion(L2Object object)
|
||||||
{
|
|
||||||
return getRegion(point.getX(), point.getY(), point.getZ());
|
|
||||||
}
|
|
||||||
|
|
||||||
public L2WorldRegion getRegion(int x, int y, int z)
|
|
||||||
{
|
{
|
||||||
try
|
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)
|
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));
|
||||||
// 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);
|
|
||||||
return null;
|
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
|
* Returns the whole 3d array containing the world regions used by ZoneData.java to setup zones inside the world regions
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public L2WorldRegion[][][] getWorldRegions()
|
public L2WorldRegion[][] getWorldRegions()
|
||||||
{
|
{
|
||||||
return _worldRegions;
|
return _worldRegions;
|
||||||
}
|
}
|
||||||
@@ -758,31 +706,49 @@ public final class L2World
|
|||||||
* <li>Init L2WorldRegions</li><BR>
|
* <li>Init L2WorldRegions</li><BR>
|
||||||
* @param x X position of the object
|
* @param x X position of the object
|
||||||
* @param y Y 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
|
* @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));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public synchronized void disposeOutOfBoundsObject(L2Object object)
|
||||||
* Deleted all spawns in the world.
|
|
||||||
*/
|
|
||||||
public void deleteVisibleNpcSpawns()
|
|
||||||
{
|
{
|
||||||
LOGGER.info(getClass().getSimpleName() + ": Deleting all visible NPCs.");
|
if (object.isPlayer())
|
||||||
for (int x = 0; x <= REGIONS_X; x++)
|
|
||||||
{
|
{
|
||||||
for (int y = 0; y <= REGIONS_Y; y++)
|
((L2Character) object).stopMove(((L2PcInstance) object).getLastServerPosition());
|
||||||
|
}
|
||||||
|
else if (object.isSummon())
|
||||||
{
|
{
|
||||||
for (int z = 0; z <= REGIONS_Z; z++)
|
final L2Summon summon = (L2Summon) object;
|
||||||
|
summon.unSummon(summon.getOwner());
|
||||||
|
}
|
||||||
|
else if (_allObjects.remove(object.getObjectId()) != null)
|
||||||
{
|
{
|
||||||
_worldRegions[x][y][z].deleteVisibleNpcSpawns();
|
if (object.isNpc())
|
||||||
|
{
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
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()
|
public void incrementParty()
|
||||||
|
|||||||
@@ -25,7 +25,6 @@ import java.util.logging.Logger;
|
|||||||
|
|
||||||
import com.l2jmobius.Config;
|
import com.l2jmobius.Config;
|
||||||
import com.l2jmobius.commons.concurrent.ThreadPool;
|
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.L2Attackable;
|
||||||
import com.l2jmobius.gameserver.model.actor.L2Npc;
|
import com.l2jmobius.gameserver.model.actor.L2Npc;
|
||||||
import com.l2jmobius.gameserver.model.actor.L2Vehicle;
|
import com.l2jmobius.gameserver.model.actor.L2Vehicle;
|
||||||
@@ -38,17 +37,15 @@ public final class L2WorldRegion
|
|||||||
private volatile Map<Integer, L2Object> _visibleObjects;
|
private volatile Map<Integer, L2Object> _visibleObjects;
|
||||||
private final int _regionX;
|
private final int _regionX;
|
||||||
private final int _regionY;
|
private final int _regionY;
|
||||||
private final int _regionZ;
|
|
||||||
private boolean _active = false;
|
private boolean _active = false;
|
||||||
private ScheduledFuture<?> _neighborsTask = null;
|
private ScheduledFuture<?> _neighborsTask = null;
|
||||||
|
|
||||||
public L2WorldRegion(int regionX, int regionY, int regionZ)
|
public L2WorldRegion(int regionX, int regionY)
|
||||||
{
|
{
|
||||||
_regionX = regionX;
|
_regionX = regionX;
|
||||||
_regionY = regionY;
|
_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;
|
_active = Config.GRIDS_ALWAYS_ON;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -93,19 +90,19 @@ public final class L2WorldRegion
|
|||||||
c++;
|
c++;
|
||||||
final L2Attackable mob = (L2Attackable) o;
|
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);
|
mob.setTarget(null);
|
||||||
|
|
||||||
// Stop movement
|
// Stop movement.
|
||||||
mob.stopMove(null);
|
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.stopAllEffects();
|
||||||
|
|
||||||
mob.clearAggroList();
|
mob.clearAggroList();
|
||||||
mob.getAttackByList().clear();
|
mob.getAttackByList().clear();
|
||||||
|
|
||||||
// stop the ai tasks
|
// Stop the AI tasks.
|
||||||
if (mob.hasAI())
|
if (mob.hasAI())
|
||||||
{
|
{
|
||||||
mob.getAI().setIntention(com.l2jmobius.gameserver.ai.CtrlIntention.AI_INTENTION_IDLE);
|
mob.getAI().setIntention(com.l2jmobius.gameserver.ai.CtrlIntention.AI_INTENTION_IDLE);
|
||||||
@@ -126,7 +123,7 @@ public final class L2WorldRegion
|
|||||||
if (o.isAttackable())
|
if (o.isAttackable())
|
||||||
{
|
{
|
||||||
c++;
|
c++;
|
||||||
// Start HP/MP/CP Regeneration task
|
// Start HP/MP/CP regeneration task.
|
||||||
((L2Attackable) o).getStatus().startHpMpRegeneration();
|
((L2Attackable) o).getStatus().startHpMpRegeneration();
|
||||||
}
|
}
|
||||||
else if (o instanceof L2Npc)
|
else if (o instanceof L2Npc)
|
||||||
@@ -161,7 +158,7 @@ public final class L2WorldRegion
|
|||||||
|
|
||||||
_active = value;
|
_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);
|
switchAI(value);
|
||||||
|
|
||||||
LOGGER.finer((value ? "Starting" : "Stopping") + " Grid " + this);
|
LOGGER.finer((value ? "Starting" : "Stopping") + " Grid " + this);
|
||||||
@@ -172,10 +169,10 @@ public final class L2WorldRegion
|
|||||||
*/
|
*/
|
||||||
private void startActivation()
|
private void startActivation()
|
||||||
{
|
{
|
||||||
// first set self to active and do self-tasks...
|
// First set self to active and do self-tasks...
|
||||||
setActive(true);
|
setActive(true);
|
||||||
|
|
||||||
// if the timer to deactivate neighbors is running, cancel it.
|
// If the timer to deactivate neighbors is running, cancel it.
|
||||||
synchronized (this)
|
synchronized (this)
|
||||||
{
|
{
|
||||||
if (_neighborsTask != null)
|
if (_neighborsTask != null)
|
||||||
@@ -184,7 +181,7 @@ public final class L2WorldRegion
|
|||||||
_neighborsTask = null;
|
_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);
|
_neighborsTask = ThreadPool.schedule(new NeighborsTask(true), 1000 * Config.GRID_NEIGHBOR_TURNON_TIME);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -194,7 +191,7 @@ public final class L2WorldRegion
|
|||||||
*/
|
*/
|
||||||
private void startDeactivation()
|
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)
|
synchronized (this)
|
||||||
{
|
{
|
||||||
if (_neighborsTask != null)
|
if (_neighborsTask != null)
|
||||||
@@ -203,8 +200,8 @@ public final class L2WorldRegion
|
|||||||
_neighborsTask = null;
|
_neighborsTask = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// start a timer to "suggest" a deactivate to self and neighbors.
|
// 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.
|
// 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);
|
_neighborsTask = ThreadPool.schedule(new NeighborsTask(false), 1000 * Config.GRID_NEIGHBOR_TURNOFF_TIME);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -235,7 +232,7 @@ public final class L2WorldRegion
|
|||||||
|
|
||||||
if (object.isPlayable())
|
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))
|
if (!_active && (!Config.GRIDS_ALWAYS_ON))
|
||||||
{
|
{
|
||||||
startActivation();
|
startActivation();
|
||||||
@@ -274,46 +271,15 @@ public final class L2WorldRegion
|
|||||||
return _visibleObjects != null ? _visibleObjects : Collections.emptyMap();
|
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)
|
public boolean forEachSurroundingRegion(Predicate<L2WorldRegion> p)
|
||||||
{
|
{
|
||||||
for (int x = _regionX - 1; x <= (_regionX + 1); x++)
|
for (int x = _regionX - 1; x <= (_regionX + 1); x++)
|
||||||
{
|
{
|
||||||
for (int y = _regionY - 1; y <= (_regionY + 1); y++)
|
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];
|
||||||
{
|
|
||||||
final L2WorldRegion worldRegion = L2World.getInstance().getWorldRegions()[x][y][z];
|
|
||||||
if (!p.test(worldRegion))
|
if (!p.test(worldRegion))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
@@ -321,7 +287,6 @@ public final class L2WorldRegion
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -335,19 +300,14 @@ public final class L2WorldRegion
|
|||||||
return _regionY;
|
return _regionY;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getRegionZ()
|
|
||||||
{
|
|
||||||
return _regionZ;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isSurroundingRegion(L2WorldRegion region)
|
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
|
@Override
|
||||||
public String toString()
|
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.L2Clan;
|
||||||
import com.l2jmobius.gameserver.model.L2Object;
|
import com.l2jmobius.gameserver.model.L2Object;
|
||||||
import com.l2jmobius.gameserver.model.L2Party;
|
import com.l2jmobius.gameserver.model.L2Party;
|
||||||
import com.l2jmobius.gameserver.model.L2Spawn;
|
|
||||||
import com.l2jmobius.gameserver.model.L2World;
|
import com.l2jmobius.gameserver.model.L2World;
|
||||||
import com.l2jmobius.gameserver.model.L2WorldRegion;
|
import com.l2jmobius.gameserver.model.L2WorldRegion;
|
||||||
import com.l2jmobius.gameserver.model.Location;
|
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.FriendlyNpcInstance;
|
||||||
import com.l2jmobius.gameserver.model.actor.instance.L2MonsterInstance;
|
import com.l2jmobius.gameserver.model.actor.instance.L2MonsterInstance;
|
||||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
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.instance.L2TrapInstance;
|
||||||
import com.l2jmobius.gameserver.model.actor.stat.CharStat;
|
import com.l2jmobius.gameserver.model.actor.stat.CharStat;
|
||||||
import com.l2jmobius.gameserver.model.actor.status.CharStatus;
|
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?
|
else // Precaution. Moved at invalid region?
|
||||||
{
|
{
|
||||||
if (isPlayer())
|
L2World.getInstance().disposeOutOfBoundsObject(this);
|
||||||
{
|
|
||||||
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();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -226,50 +226,6 @@ public final class Util
|
|||||||
return calculateDistance(obj1, obj2, includeZAxis, false) <= range;
|
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
|
* @param text - the text to check
|
||||||
* @return {@code true} if {@code text} contains only numbers, {@code false} otherwise
|
* @return {@code true} if {@code text} contains only numbers, {@code false} otherwise
|
||||||
|
|||||||
+1
-1
@@ -61,7 +61,7 @@ public final class HillsOfGold extends AbstractNpcAI
|
|||||||
{
|
{
|
||||||
if ((npc != null) && !npc.isDead())
|
if ((npc != null) && !npc.isDead())
|
||||||
{
|
{
|
||||||
L2World.getInstance().forEachVisibleObject(npc, L2MonsterInstance.class, npc.getAggroRange(), nearby ->
|
L2World.getInstance().forEachVisibleObjectInRange(npc, L2MonsterInstance.class, npc.getAggroRange(), nearby ->
|
||||||
{
|
{
|
||||||
if (npc.isInCombat())
|
if (npc.isInCombat())
|
||||||
{
|
{
|
||||||
|
|||||||
+1
-1
@@ -344,7 +344,7 @@ public final class SeedOfAnnihilation extends AbstractNpcAI
|
|||||||
{
|
{
|
||||||
final Location teleLoc = TELEPORT_ZONES.get(zone.getId());
|
final Location teleLoc = TELEPORT_ZONES.get(zone.getId());
|
||||||
// Conditions for Quest 454
|
// Conditions for Quest 454
|
||||||
L2World.getInstance().forEachVisibleObject(character, L2Npc.class, 500, npc ->
|
L2World.getInstance().forEachVisibleObjectInRange(character, L2Npc.class, 500, npc ->
|
||||||
{
|
{
|
||||||
if ((npc.getId() == 32738) && (npc.getTarget() != null))
|
if ((npc.getId() == 32738) && (npc.getTarget() != null))
|
||||||
{
|
{
|
||||||
|
|||||||
Vendored
+28
-2
@@ -213,14 +213,40 @@ public class AdminSpawn implements IAdminCommandHandler
|
|||||||
{
|
{
|
||||||
Broadcast.toAllOnlinePlayers(SystemMessage.getSystemMessage(SystemMessageId.THE_NPC_SERVER_IS_NOT_OPERATING_AT_THIS_TIME));
|
Broadcast.toAllOnlinePlayers(SystemMessage.getSystemMessage(SystemMessageId.THE_NPC_SERVER_IS_NOT_OPERATING_AT_THIS_TIME));
|
||||||
DBSpawnManager.getInstance().cleanUp();
|
DBSpawnManager.getInstance().cleanUp();
|
||||||
L2World.getInstance().deleteVisibleNpcSpawns();
|
for (L2Object obj : L2World.getInstance().getVisibleObjects())
|
||||||
|
{
|
||||||
|
if ((obj != null) && obj.isNpc())
|
||||||
|
{
|
||||||
|
final L2Npc target = (L2Npc) obj;
|
||||||
|
target.deleteMe();
|
||||||
|
final L2Spawn spawn = target.getSpawn();
|
||||||
|
if (spawn != null)
|
||||||
|
{
|
||||||
|
spawn.stopRespawn();
|
||||||
|
SpawnTable.getInstance().deleteSpawn(spawn, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
AdminData.getInstance().broadcastMessageToGMs("NPC Unspawn completed!");
|
AdminData.getInstance().broadcastMessageToGMs("NPC Unspawn completed!");
|
||||||
}
|
}
|
||||||
else if (command.startsWith("admin_respawnall") || command.startsWith("admin_spawn_reload"))
|
else if (command.startsWith("admin_respawnall") || command.startsWith("admin_spawn_reload"))
|
||||||
{
|
{
|
||||||
// make sure all spawns are deleted
|
// make sure all spawns are deleted
|
||||||
DBSpawnManager.getInstance().cleanUp();
|
DBSpawnManager.getInstance().cleanUp();
|
||||||
L2World.getInstance().deleteVisibleNpcSpawns();
|
for (L2Object obj : L2World.getInstance().getVisibleObjects())
|
||||||
|
{
|
||||||
|
if ((obj != null) && obj.isNpc())
|
||||||
|
{
|
||||||
|
final L2Npc target = (L2Npc) obj;
|
||||||
|
target.deleteMe();
|
||||||
|
final L2Spawn spawn = target.getSpawn();
|
||||||
|
if (spawn != null)
|
||||||
|
{
|
||||||
|
spawn.stopRespawn();
|
||||||
|
SpawnTable.getInstance().deleteSpawn(spawn, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
// now respawn all
|
// now respawn all
|
||||||
NpcData.getInstance().load();
|
NpcData.getInstance().load();
|
||||||
DBSpawnManager.getInstance().load();
|
DBSpawnManager.getInstance().load();
|
||||||
|
|||||||
Vendored
+1
-1
@@ -190,7 +190,7 @@ public class AdminTeleport implements IAdminCommandHandler
|
|||||||
st.nextToken();
|
st.nextToken();
|
||||||
final int x = (int) Float.parseFloat(st.nextToken());
|
final int x = (int) Float.parseFloat(st.nextToken());
|
||||||
final int y = (int) Float.parseFloat(st.nextToken());
|
final int y = (int) Float.parseFloat(st.nextToken());
|
||||||
final int z = st.hasMoreTokens() ? ((int) Float.parseFloat(st.nextToken())) : GeoEngine.getInstance().getHeight(x, y, L2World.MAP_MAX_Z);
|
final int z = st.hasMoreTokens() ? ((int) Float.parseFloat(st.nextToken())) : GeoEngine.getInstance().getHeight(x, y, 10000);
|
||||||
|
|
||||||
activeChar.teleToLocation(x, y, z);
|
activeChar.teleToLocation(x, y, z);
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -184,7 +184,7 @@ public final class FenceData implements IGameXmlReader
|
|||||||
return false;
|
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);
|
return region == null ? false : _regions.getOrDefault(region, Collections.emptyList()).stream().anyMatch(filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -115,7 +115,7 @@ public final class ItemsOnGroundManager implements Runnable
|
|||||||
item.setEnchantLevel(rs.getInt(4));
|
item.setEnchantLevel(rs.getInt(4));
|
||||||
}
|
}
|
||||||
item.setXYZ(rs.getInt(5), rs.getInt(6), rs.getInt(7));
|
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);
|
item.getWorldRegion().addVisibleObject(item);
|
||||||
final long dropTime = rs.getLong(8);
|
final long dropTime = rs.getLong(8);
|
||||||
item.setDropTime(dropTime);
|
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
|
// Set the x,y,z position of the L2Object spawn and update its _worldregion
|
||||||
_isSpawned = true;
|
_isSpawned = true;
|
||||||
setWorldRegion(L2World.getInstance().getRegion(getLocation()));
|
setWorldRegion(L2World.getInstance().getRegion(this));
|
||||||
|
|
||||||
// Add the L2Object spawn in the _allobjects of L2World
|
// Add the L2Object spawn in the _allobjects of L2World
|
||||||
L2World.getInstance().addObject(this);
|
L2World.getInstance().addObject(this);
|
||||||
@@ -207,14 +207,6 @@ public abstract class L2Object extends ListenersContainer implements IIdentifiab
|
|||||||
{
|
{
|
||||||
y = L2World.MAP_MIN_Y + 5000;
|
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.
|
// 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);
|
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.instancemanager.PlayerCountManager;
|
||||||
import com.l2jmobius.gameserver.model.actor.L2Character;
|
import com.l2jmobius.gameserver.model.actor.L2Character;
|
||||||
import com.l2jmobius.gameserver.model.actor.L2Npc;
|
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.L2PcInstance;
|
||||||
import com.l2jmobius.gameserver.model.actor.instance.L2PetInstance;
|
import com.l2jmobius.gameserver.model.actor.instance.L2PetInstance;
|
||||||
import com.l2jmobius.gameserver.model.events.EventDispatcher;
|
import com.l2jmobius.gameserver.model.events.EventDispatcher;
|
||||||
import com.l2jmobius.gameserver.model.events.impl.character.npc.OnNpcCreatureSee;
|
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.Disconnection;
|
||||||
import com.l2jmobius.gameserver.network.serverpackets.DeleteObject;
|
import com.l2jmobius.gameserver.network.serverpackets.DeleteObject;
|
||||||
import com.l2jmobius.gameserver.util.Util;
|
|
||||||
|
|
||||||
public final class L2World
|
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. */
|
/** 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 = 11;
|
||||||
public static final int SHIFT_BY_Z = 10;
|
|
||||||
|
|
||||||
public static final int TILE_SIZE = 32768;
|
public static final int TILE_SIZE = 32768;
|
||||||
|
|
||||||
/** Map dimensions */
|
/** Map dimensions. */
|
||||||
public static final int TILE_X_MIN = 11;
|
public static final int TILE_X_MIN = 11;
|
||||||
public static final int TILE_Y_MIN = 10;
|
public static final int TILE_Y_MIN = 10;
|
||||||
public static final int TILE_X_MAX = 28;
|
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 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_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_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_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_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_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_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_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_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. */
|
/** Map containing all the players in game. */
|
||||||
private final Map<Integer, L2PcInstance> _allPlayers = new ConcurrentHashMap<>();
|
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 _partyNumber = new AtomicInteger();
|
||||||
private final AtomicInteger _memberInPartyNumber = 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. */
|
/** Constructor of L2World. */
|
||||||
protected L2World()
|
protected L2World()
|
||||||
@@ -108,14 +103,11 @@ public final class L2World
|
|||||||
{
|
{
|
||||||
for (int y = 0; y <= REGIONS_Y; y++)
|
for (int y = 0; y <= REGIONS_Y; y++)
|
||||||
{
|
{
|
||||||
for (int z = 0; z <= REGIONS_Z; z++)
|
_worldRegions[x][y] = new L2WorldRegion(x, y);
|
||||||
{
|
|
||||||
_worldRegions[x][y][z] = new L2WorldRegion(x, y, z);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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();
|
PlayerCountManager.getInstance().incConnectedCount();
|
||||||
|
|
||||||
final L2PcInstance newPlayer = (L2PcInstance) object;
|
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;
|
return;
|
||||||
}
|
}
|
||||||
@@ -176,7 +168,7 @@ public final class L2World
|
|||||||
PlayerCountManager.getInstance().decConnectedCount();
|
PlayerCountManager.getInstance().decConnectedCount();
|
||||||
|
|
||||||
final L2PcInstance player = (L2PcInstance) object;
|
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;
|
return;
|
||||||
}
|
}
|
||||||
@@ -309,7 +301,7 @@ public final class L2World
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
forEachVisibleObject(object, L2Object.class, 1, wo ->
|
forEachVisibleObject(object, L2Object.class, wo ->
|
||||||
{
|
{
|
||||||
if (object.isPlayer() && wo.isVisibleFor((L2PcInstance) object))
|
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)
|
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)
|
public <T extends L2Object> void forEachVisibleObjectInRange(L2Object object, Class<T> clazz, int range, Consumer<T> c)
|
||||||
@@ -640,22 +594,15 @@ public final class L2World
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
final int depth = (range / REGION_MIN_DIMENSION) + 1;
|
final int regionX = centerWorldRegion.getRegionX();
|
||||||
for (int x = Math.max(centerWorldRegion.getRegionX() - depth, 0); x <= Math.min(centerWorldRegion.getRegionX() + depth, REGIONS_X); x++)
|
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;
|
for (L2Object visibleObject : _worldRegions[x][y].getVisibleObjects().values())
|
||||||
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][z].getVisibleObjects().values())
|
|
||||||
{
|
{
|
||||||
if ((visibleObject == null) || (visibleObject == object) || !clazz.isInstance(visibleObject))
|
if ((visibleObject == null) || (visibleObject == object) || !clazz.isInstance(visibleObject))
|
||||||
{
|
{
|
||||||
@@ -673,6 +620,10 @@ public final class L2World
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if ((x == regionX) && (y == regionY)) // Precaution. Moved at invalid region?
|
||||||
|
{
|
||||||
|
disposeOutOfBoundsObject(object);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -680,22 +631,12 @@ public final class L2World
|
|||||||
|
|
||||||
public <T extends L2Object> List<T> getVisibleObjects(L2Object object, Class<T> clazz)
|
public <T extends L2Object> List<T> getVisibleObjects(L2Object object, Class<T> clazz)
|
||||||
{
|
{
|
||||||
final List<T> result = new LinkedList<>();
|
return getVisibleObjects(object, clazz, VISIBILITY_RANGE);
|
||||||
forEachVisibleObject(object, clazz, result::add);
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public <T extends L2Object> List<T> getVisibleObjects(L2Object object, Class<T> clazz, Predicate<T> predicate)
|
public <T extends L2Object> List<T> getVisibleObjects(L2Object object, Class<T> clazz, Predicate<T> predicate)
|
||||||
{
|
{
|
||||||
final List<T> result = new LinkedList<>();
|
return getVisibleObjects(object, clazz, VISIBILITY_RANGE, predicate);
|
||||||
forEachVisibleObject(object, clazz, o ->
|
|
||||||
{
|
|
||||||
if (predicate.test(o))
|
|
||||||
{
|
|
||||||
result.add(o);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public <T extends L2Object> List<T> getVisibleObjects(L2Object object, Class<T> clazz, int range)
|
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>
|
* 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>Set position of a new L2Object (drop, spawn...)</li>
|
||||||
* <li>Update position of a L2Object after a movement</li><BR>
|
* <li>Update position of a L2Object after a movement</li><BR>
|
||||||
* @param point position of the object
|
* @param object the object
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public L2WorldRegion getRegion(ILocational point)
|
public L2WorldRegion getRegion(L2Object object)
|
||||||
{
|
|
||||||
return getRegion(point.getX(), point.getY(), point.getZ());
|
|
||||||
}
|
|
||||||
|
|
||||||
public L2WorldRegion getRegion(int x, int y, int z)
|
|
||||||
{
|
{
|
||||||
try
|
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)
|
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));
|
||||||
// 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);
|
|
||||||
return null;
|
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
|
* Returns the whole 3d array containing the world regions used by ZoneData.java to setup zones inside the world regions
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public L2WorldRegion[][][] getWorldRegions()
|
public L2WorldRegion[][] getWorldRegions()
|
||||||
{
|
{
|
||||||
return _worldRegions;
|
return _worldRegions;
|
||||||
}
|
}
|
||||||
@@ -758,31 +706,49 @@ public final class L2World
|
|||||||
* <li>Init L2WorldRegions</li><BR>
|
* <li>Init L2WorldRegions</li><BR>
|
||||||
* @param x X position of the object
|
* @param x X position of the object
|
||||||
* @param y Y 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
|
* @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));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public synchronized void disposeOutOfBoundsObject(L2Object object)
|
||||||
* Deleted all spawns in the world.
|
|
||||||
*/
|
|
||||||
public void deleteVisibleNpcSpawns()
|
|
||||||
{
|
{
|
||||||
LOGGER.info(getClass().getSimpleName() + ": Deleting all visible NPCs.");
|
if (object.isPlayer())
|
||||||
for (int x = 0; x <= REGIONS_X; x++)
|
|
||||||
{
|
{
|
||||||
for (int y = 0; y <= REGIONS_Y; y++)
|
((L2Character) object).stopMove(((L2PcInstance) object).getLastServerPosition());
|
||||||
|
}
|
||||||
|
else if (object.isSummon())
|
||||||
{
|
{
|
||||||
for (int z = 0; z <= REGIONS_Z; z++)
|
final L2Summon summon = (L2Summon) object;
|
||||||
|
summon.unSummon(summon.getOwner());
|
||||||
|
}
|
||||||
|
else if (_allObjects.remove(object.getObjectId()) != null)
|
||||||
{
|
{
|
||||||
_worldRegions[x][y][z].deleteVisibleNpcSpawns();
|
if (object.isNpc())
|
||||||
|
{
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
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()
|
public void incrementParty()
|
||||||
|
|||||||
+19
-59
@@ -25,7 +25,6 @@ import java.util.logging.Logger;
|
|||||||
|
|
||||||
import com.l2jmobius.Config;
|
import com.l2jmobius.Config;
|
||||||
import com.l2jmobius.commons.concurrent.ThreadPool;
|
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.L2Attackable;
|
||||||
import com.l2jmobius.gameserver.model.actor.L2Npc;
|
import com.l2jmobius.gameserver.model.actor.L2Npc;
|
||||||
import com.l2jmobius.gameserver.model.actor.L2Vehicle;
|
import com.l2jmobius.gameserver.model.actor.L2Vehicle;
|
||||||
@@ -38,17 +37,15 @@ public final class L2WorldRegion
|
|||||||
private volatile Map<Integer, L2Object> _visibleObjects;
|
private volatile Map<Integer, L2Object> _visibleObjects;
|
||||||
private final int _regionX;
|
private final int _regionX;
|
||||||
private final int _regionY;
|
private final int _regionY;
|
||||||
private final int _regionZ;
|
|
||||||
private boolean _active = false;
|
private boolean _active = false;
|
||||||
private ScheduledFuture<?> _neighborsTask = null;
|
private ScheduledFuture<?> _neighborsTask = null;
|
||||||
|
|
||||||
public L2WorldRegion(int regionX, int regionY, int regionZ)
|
public L2WorldRegion(int regionX, int regionY)
|
||||||
{
|
{
|
||||||
_regionX = regionX;
|
_regionX = regionX;
|
||||||
_regionY = regionY;
|
_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;
|
_active = Config.GRIDS_ALWAYS_ON;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -93,19 +90,19 @@ public final class L2WorldRegion
|
|||||||
c++;
|
c++;
|
||||||
final L2Attackable mob = (L2Attackable) o;
|
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);
|
mob.setTarget(null);
|
||||||
|
|
||||||
// Stop movement
|
// Stop movement.
|
||||||
mob.stopMove(null);
|
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.stopAllEffects();
|
||||||
|
|
||||||
mob.clearAggroList();
|
mob.clearAggroList();
|
||||||
mob.getAttackByList().clear();
|
mob.getAttackByList().clear();
|
||||||
|
|
||||||
// stop the ai tasks
|
// Stop the AI tasks.
|
||||||
if (mob.hasAI())
|
if (mob.hasAI())
|
||||||
{
|
{
|
||||||
mob.getAI().setIntention(com.l2jmobius.gameserver.ai.CtrlIntention.AI_INTENTION_IDLE);
|
mob.getAI().setIntention(com.l2jmobius.gameserver.ai.CtrlIntention.AI_INTENTION_IDLE);
|
||||||
@@ -126,7 +123,7 @@ public final class L2WorldRegion
|
|||||||
if (o.isAttackable())
|
if (o.isAttackable())
|
||||||
{
|
{
|
||||||
c++;
|
c++;
|
||||||
// Start HP/MP/CP Regeneration task
|
// Start HP/MP/CP regeneration task.
|
||||||
((L2Attackable) o).getStatus().startHpMpRegeneration();
|
((L2Attackable) o).getStatus().startHpMpRegeneration();
|
||||||
}
|
}
|
||||||
else if (o instanceof L2Npc)
|
else if (o instanceof L2Npc)
|
||||||
@@ -161,7 +158,7 @@ public final class L2WorldRegion
|
|||||||
|
|
||||||
_active = value;
|
_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);
|
switchAI(value);
|
||||||
|
|
||||||
LOGGER.finer((value ? "Starting" : "Stopping") + " Grid " + this);
|
LOGGER.finer((value ? "Starting" : "Stopping") + " Grid " + this);
|
||||||
@@ -172,10 +169,10 @@ public final class L2WorldRegion
|
|||||||
*/
|
*/
|
||||||
private void startActivation()
|
private void startActivation()
|
||||||
{
|
{
|
||||||
// first set self to active and do self-tasks...
|
// First set self to active and do self-tasks...
|
||||||
setActive(true);
|
setActive(true);
|
||||||
|
|
||||||
// if the timer to deactivate neighbors is running, cancel it.
|
// If the timer to deactivate neighbors is running, cancel it.
|
||||||
synchronized (this)
|
synchronized (this)
|
||||||
{
|
{
|
||||||
if (_neighborsTask != null)
|
if (_neighborsTask != null)
|
||||||
@@ -184,7 +181,7 @@ public final class L2WorldRegion
|
|||||||
_neighborsTask = null;
|
_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);
|
_neighborsTask = ThreadPool.schedule(new NeighborsTask(true), 1000 * Config.GRID_NEIGHBOR_TURNON_TIME);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -194,7 +191,7 @@ public final class L2WorldRegion
|
|||||||
*/
|
*/
|
||||||
private void startDeactivation()
|
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)
|
synchronized (this)
|
||||||
{
|
{
|
||||||
if (_neighborsTask != null)
|
if (_neighborsTask != null)
|
||||||
@@ -203,8 +200,8 @@ public final class L2WorldRegion
|
|||||||
_neighborsTask = null;
|
_neighborsTask = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// start a timer to "suggest" a deactivate to self and neighbors.
|
// 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.
|
// 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);
|
_neighborsTask = ThreadPool.schedule(new NeighborsTask(false), 1000 * Config.GRID_NEIGHBOR_TURNOFF_TIME);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -235,7 +232,7 @@ public final class L2WorldRegion
|
|||||||
|
|
||||||
if (object.isPlayable())
|
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))
|
if (!_active && (!Config.GRIDS_ALWAYS_ON))
|
||||||
{
|
{
|
||||||
startActivation();
|
startActivation();
|
||||||
@@ -274,46 +271,15 @@ public final class L2WorldRegion
|
|||||||
return _visibleObjects != null ? _visibleObjects : Collections.emptyMap();
|
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)
|
public boolean forEachSurroundingRegion(Predicate<L2WorldRegion> p)
|
||||||
{
|
{
|
||||||
for (int x = _regionX - 1; x <= (_regionX + 1); x++)
|
for (int x = _regionX - 1; x <= (_regionX + 1); x++)
|
||||||
{
|
{
|
||||||
for (int y = _regionY - 1; y <= (_regionY + 1); y++)
|
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];
|
||||||
{
|
|
||||||
final L2WorldRegion worldRegion = L2World.getInstance().getWorldRegions()[x][y][z];
|
|
||||||
if (!p.test(worldRegion))
|
if (!p.test(worldRegion))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
@@ -321,7 +287,6 @@ public final class L2WorldRegion
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -335,19 +300,14 @@ public final class L2WorldRegion
|
|||||||
return _regionY;
|
return _regionY;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getRegionZ()
|
|
||||||
{
|
|
||||||
return _regionZ;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isSurroundingRegion(L2WorldRegion region)
|
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
|
@Override
|
||||||
public String toString()
|
public String toString()
|
||||||
{
|
{
|
||||||
return "(" + _regionX + ", " + _regionY + ", " + _regionZ + ")";
|
return "(" + _regionX + ", " + _regionY + ")";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-27
@@ -73,7 +73,6 @@ import com.l2jmobius.gameserver.model.L2AccessLevel;
|
|||||||
import com.l2jmobius.gameserver.model.L2Clan;
|
import com.l2jmobius.gameserver.model.L2Clan;
|
||||||
import com.l2jmobius.gameserver.model.L2Object;
|
import com.l2jmobius.gameserver.model.L2Object;
|
||||||
import com.l2jmobius.gameserver.model.L2Party;
|
import com.l2jmobius.gameserver.model.L2Party;
|
||||||
import com.l2jmobius.gameserver.model.L2Spawn;
|
|
||||||
import com.l2jmobius.gameserver.model.L2World;
|
import com.l2jmobius.gameserver.model.L2World;
|
||||||
import com.l2jmobius.gameserver.model.L2WorldRegion;
|
import com.l2jmobius.gameserver.model.L2WorldRegion;
|
||||||
import com.l2jmobius.gameserver.model.Location;
|
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.FriendlyNpcInstance;
|
||||||
import com.l2jmobius.gameserver.model.actor.instance.L2MonsterInstance;
|
import com.l2jmobius.gameserver.model.actor.instance.L2MonsterInstance;
|
||||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
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.instance.L2TrapInstance;
|
||||||
import com.l2jmobius.gameserver.model.actor.stat.CharStat;
|
import com.l2jmobius.gameserver.model.actor.stat.CharStat;
|
||||||
import com.l2jmobius.gameserver.model.actor.status.CharStatus;
|
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?
|
else // Precaution. Moved at invalid region?
|
||||||
{
|
{
|
||||||
if (isPlayer())
|
L2World.getInstance().disposeOutOfBoundsObject(this);
|
||||||
{
|
|
||||||
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();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -226,50 +226,6 @@ public final class Util
|
|||||||
return calculateDistance(obj1, obj2, includeZAxis, false) <= range;
|
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
|
* @param text - the text to check
|
||||||
* @return {@code true} if {@code text} contains only numbers, {@code false} otherwise
|
* @return {@code true} if {@code text} contains only numbers, {@code false} otherwise
|
||||||
|
|||||||
Vendored
+30
-4
@@ -218,8 +218,21 @@ public class AdminSpawn implements IAdminCommandHandler
|
|||||||
Broadcast.toAllOnlinePlayers(SystemMessage.getSystemMessage(SystemMessageId.THE_NPC_SERVER_IS_NOT_OPERATING_AT_THIS_TIME));
|
Broadcast.toAllOnlinePlayers(SystemMessage.getSystemMessage(SystemMessageId.THE_NPC_SERVER_IS_NOT_OPERATING_AT_THIS_TIME));
|
||||||
RaidBossSpawnManager.getInstance().cleanUp();
|
RaidBossSpawnManager.getInstance().cleanUp();
|
||||||
DayNightSpawnManager.getInstance().cleanUp();
|
DayNightSpawnManager.getInstance().cleanUp();
|
||||||
L2World.getInstance().deleteVisibleNpcSpawns();
|
for (L2Object obj : L2World.getInstance().getVisibleObjects())
|
||||||
AdminData.getInstance().broadcastMessageToGMs("NPC Unspawn completed!");
|
{
|
||||||
|
if ((obj != null) && obj.isNpc())
|
||||||
|
{
|
||||||
|
final L2Npc target = (L2Npc) obj;
|
||||||
|
target.deleteMe();
|
||||||
|
final L2Spawn spawn = target.getSpawn();
|
||||||
|
if (spawn != null)
|
||||||
|
{
|
||||||
|
spawn.stopRespawn();
|
||||||
|
SpawnTable.getInstance().deleteSpawn(spawn, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
AdminData.getInstance().broadcastMessageToGMs("NPC unspawn completed!");
|
||||||
}
|
}
|
||||||
else if (command.startsWith("admin_spawnday"))
|
else if (command.startsWith("admin_spawnday"))
|
||||||
{
|
{
|
||||||
@@ -234,7 +247,20 @@ public class AdminSpawn implements IAdminCommandHandler
|
|||||||
// make sure all spawns are deleted
|
// make sure all spawns are deleted
|
||||||
RaidBossSpawnManager.getInstance().cleanUp();
|
RaidBossSpawnManager.getInstance().cleanUp();
|
||||||
DayNightSpawnManager.getInstance().cleanUp();
|
DayNightSpawnManager.getInstance().cleanUp();
|
||||||
L2World.getInstance().deleteVisibleNpcSpawns();
|
for (L2Object obj : L2World.getInstance().getVisibleObjects())
|
||||||
|
{
|
||||||
|
if ((obj != null) && obj.isNpc())
|
||||||
|
{
|
||||||
|
final L2Npc target = (L2Npc) obj;
|
||||||
|
target.deleteMe();
|
||||||
|
final L2Spawn spawn = target.getSpawn();
|
||||||
|
if (spawn != null)
|
||||||
|
{
|
||||||
|
spawn.stopRespawn();
|
||||||
|
SpawnTable.getInstance().deleteSpawn(spawn, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
// now respawn all
|
// now respawn all
|
||||||
NpcData.getInstance().load();
|
NpcData.getInstance().load();
|
||||||
SpawnTable.getInstance().load();
|
SpawnTable.getInstance().load();
|
||||||
@@ -242,7 +268,7 @@ public class AdminSpawn implements IAdminCommandHandler
|
|||||||
AutoSpawnHandler.getInstance().reload();
|
AutoSpawnHandler.getInstance().reload();
|
||||||
SevenSigns.getInstance().spawnSevenSignsNPC();
|
SevenSigns.getInstance().spawnSevenSignsNPC();
|
||||||
QuestManager.getInstance().reloadAllScripts();
|
QuestManager.getInstance().reloadAllScripts();
|
||||||
AdminData.getInstance().broadcastMessageToGMs("NPC Respawn completed!");
|
AdminData.getInstance().broadcastMessageToGMs("NPC respawn completed!");
|
||||||
}
|
}
|
||||||
else if (command.startsWith("admin_spawn_monster") || command.startsWith("admin_spawn"))
|
else if (command.startsWith("admin_spawn_monster") || command.startsWith("admin_spawn"))
|
||||||
{
|
{
|
||||||
|
|||||||
+1
-1
@@ -182,7 +182,7 @@ public final class FenceData implements IGameXmlReader
|
|||||||
return false;
|
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);
|
return region == null ? false : _regions.getOrDefault(region, Collections.emptyList()).stream().anyMatch(filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -115,7 +115,7 @@ public final class ItemsOnGroundManager implements Runnable
|
|||||||
item.setEnchantLevel(rs.getInt(4));
|
item.setEnchantLevel(rs.getInt(4));
|
||||||
}
|
}
|
||||||
item.setXYZ(rs.getInt(5), rs.getInt(6), rs.getInt(7));
|
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);
|
item.getWorldRegion().addVisibleObject(item);
|
||||||
final long dropTime = rs.getLong(8);
|
final long dropTime = rs.getLong(8);
|
||||||
item.setDropTime(dropTime);
|
item.setDropTime(dropTime);
|
||||||
|
|||||||
@@ -171,7 +171,7 @@ public abstract class L2Object extends ListenersContainer implements IIdentifiab
|
|||||||
{
|
{
|
||||||
// Set the x,y,z position of the L2Object spawn and update its _worldregion
|
// Set the x,y,z position of the L2Object spawn and update its _worldregion
|
||||||
_isSpawned = true;
|
_isSpawned = true;
|
||||||
setWorldRegion(L2World.getInstance().getRegion(getLocation()));
|
setWorldRegion(L2World.getInstance().getRegion(this));
|
||||||
|
|
||||||
// Add the L2Object spawn in the _allobjects of L2World
|
// Add the L2Object spawn in the _allobjects of L2World
|
||||||
L2World.getInstance().addObject(this);
|
L2World.getInstance().addObject(this);
|
||||||
@@ -209,14 +209,6 @@ public abstract class L2Object extends ListenersContainer implements IIdentifiab
|
|||||||
{
|
{
|
||||||
y = L2World.MAP_MIN_Y + 5000;
|
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.
|
// 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);
|
setXYZ(x, y, z);
|
||||||
|
|||||||
@@ -34,14 +34,13 @@ import com.l2jmobius.gameserver.data.sql.impl.CharNameTable;
|
|||||||
import com.l2jmobius.gameserver.instancemanager.PlayerCountManager;
|
import com.l2jmobius.gameserver.instancemanager.PlayerCountManager;
|
||||||
import com.l2jmobius.gameserver.model.actor.L2Character;
|
import com.l2jmobius.gameserver.model.actor.L2Character;
|
||||||
import com.l2jmobius.gameserver.model.actor.L2Npc;
|
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.L2PcInstance;
|
||||||
import com.l2jmobius.gameserver.model.actor.instance.L2PetInstance;
|
import com.l2jmobius.gameserver.model.actor.instance.L2PetInstance;
|
||||||
import com.l2jmobius.gameserver.model.events.EventDispatcher;
|
import com.l2jmobius.gameserver.model.events.EventDispatcher;
|
||||||
import com.l2jmobius.gameserver.model.events.impl.character.npc.OnNpcCreatureSee;
|
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.Disconnection;
|
||||||
import com.l2jmobius.gameserver.network.serverpackets.DeleteObject;
|
import com.l2jmobius.gameserver.network.serverpackets.DeleteObject;
|
||||||
import com.l2jmobius.gameserver.util.Util;
|
|
||||||
|
|
||||||
public final class L2World
|
public final class L2World
|
||||||
{
|
{
|
||||||
@@ -53,11 +52,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. */
|
/** 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 = 11;
|
||||||
public static final int SHIFT_BY_Z = 10;
|
|
||||||
|
|
||||||
public static final int TILE_SIZE = 32768;
|
public static final int TILE_SIZE = 32768;
|
||||||
|
|
||||||
/** Map dimensions */
|
/** Map dimensions. */
|
||||||
public static final int TILE_X_MIN = 11;
|
public static final int TILE_X_MIN = 11;
|
||||||
public static final int TILE_Y_MIN = 10;
|
public static final int TILE_Y_MIN = 10;
|
||||||
public static final int TILE_X_MAX = 26;
|
public static final int TILE_X_MAX = 26;
|
||||||
@@ -66,23 +64,20 @@ public final class L2World
|
|||||||
public static final int TILE_ZERO_COORD_Y = 18;
|
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_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_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_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_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_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_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_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_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. */
|
/** Map containing all the players in game. */
|
||||||
private final Map<Integer, L2PcInstance> _allPlayers = new ConcurrentHashMap<>();
|
private final Map<Integer, L2PcInstance> _allPlayers = new ConcurrentHashMap<>();
|
||||||
@@ -95,7 +90,7 @@ public final class L2World
|
|||||||
/** Map with the pets instances and their owner ID. */
|
/** Map with the pets instances and their owner ID. */
|
||||||
private final Map<Integer, L2PetInstance> _petsInstance = new ConcurrentHashMap<>();
|
private final Map<Integer, L2PetInstance> _petsInstance = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
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. */
|
/** Constructor of L2World. */
|
||||||
protected L2World()
|
protected L2World()
|
||||||
@@ -104,14 +99,11 @@ public final class L2World
|
|||||||
{
|
{
|
||||||
for (int y = 0; y <= REGIONS_Y; y++)
|
for (int y = 0; y <= REGIONS_Y; y++)
|
||||||
{
|
{
|
||||||
for (int z = 0; z <= REGIONS_Z; z++)
|
_worldRegions[x][y] = new L2WorldRegion(x, y);
|
||||||
{
|
|
||||||
_worldRegions[x][y][z] = new L2WorldRegion(x, y, z);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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.");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -135,7 +127,7 @@ public final class L2World
|
|||||||
PlayerCountManager.getInstance().incConnectedCount();
|
PlayerCountManager.getInstance().incConnectedCount();
|
||||||
|
|
||||||
final L2PcInstance newPlayer = (L2PcInstance) object;
|
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;
|
return;
|
||||||
}
|
}
|
||||||
@@ -172,7 +164,7 @@ public final class L2World
|
|||||||
PlayerCountManager.getInstance().decConnectedCount();
|
PlayerCountManager.getInstance().decConnectedCount();
|
||||||
|
|
||||||
final L2PcInstance player = (L2PcInstance) object;
|
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;
|
return;
|
||||||
}
|
}
|
||||||
@@ -305,7 +297,7 @@ public final class L2World
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
forEachVisibleObject(object, L2Object.class, 1, wo ->
|
forEachVisibleObject(object, L2Object.class, wo ->
|
||||||
{
|
{
|
||||||
if (object.isPlayer() && wo.isVisibleFor((L2PcInstance) object))
|
if (object.isPlayer() && wo.isVisibleFor((L2PcInstance) object))
|
||||||
{
|
{
|
||||||
@@ -580,47 +572,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.getInstanceId() != object.getInstanceId())
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
c.accept(clazz.cast(visibleObject));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public <T extends L2Object> void forEachVisibleObject(L2Object object, Class<T> clazz, Consumer<T> c)
|
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)
|
public <T extends L2Object> void forEachVisibleObjectInRange(L2Object object, Class<T> clazz, int range, Consumer<T> c)
|
||||||
@@ -636,22 +590,15 @@ public final class L2World
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
final int depth = (range / REGION_MIN_DIMENSION) + 1;
|
final int regionX = centerWorldRegion.getRegionX();
|
||||||
for (int x = Math.max(centerWorldRegion.getRegionX() - depth, 0); x <= Math.min(centerWorldRegion.getRegionX() + depth, REGIONS_X); x++)
|
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;
|
for (L2Object visibleObject : _worldRegions[x][y].getVisibleObjects().values())
|
||||||
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][z].getVisibleObjects().values())
|
|
||||||
{
|
{
|
||||||
if ((visibleObject == null) || (visibleObject == object) || !clazz.isInstance(visibleObject))
|
if ((visibleObject == null) || (visibleObject == object) || !clazz.isInstance(visibleObject))
|
||||||
{
|
{
|
||||||
@@ -669,6 +616,10 @@ public final class L2World
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if ((x == regionX) && (y == regionY)) // Precaution. Moved at invalid region?
|
||||||
|
{
|
||||||
|
disposeOutOfBoundsObject(object);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -676,22 +627,12 @@ public final class L2World
|
|||||||
|
|
||||||
public <T extends L2Object> List<T> getVisibleObjects(L2Object object, Class<T> clazz)
|
public <T extends L2Object> List<T> getVisibleObjects(L2Object object, Class<T> clazz)
|
||||||
{
|
{
|
||||||
final List<T> result = new LinkedList<>();
|
return getVisibleObjects(object, clazz, VISIBILITY_RANGE);
|
||||||
forEachVisibleObject(object, clazz, result::add);
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public <T extends L2Object> List<T> getVisibleObjects(L2Object object, Class<T> clazz, Predicate<T> predicate)
|
public <T extends L2Object> List<T> getVisibleObjects(L2Object object, Class<T> clazz, Predicate<T> predicate)
|
||||||
{
|
{
|
||||||
final List<T> result = new LinkedList<>();
|
return getVisibleObjects(object, clazz, VISIBILITY_RANGE, predicate);
|
||||||
forEachVisibleObject(object, clazz, o ->
|
|
||||||
{
|
|
||||||
if (predicate.test(o))
|
|
||||||
{
|
|
||||||
result.add(o);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public <T extends L2Object> List<T> getVisibleObjects(L2Object object, Class<T> clazz, int range)
|
public <T extends L2Object> List<T> getVisibleObjects(L2Object object, Class<T> clazz, int range)
|
||||||
@@ -718,24 +659,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>
|
* 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>Set position of a new L2Object (drop, spawn...)</li>
|
||||||
* <li>Update position of a L2Object after a movement</li><BR>
|
* <li>Update position of a L2Object after a movement</li><BR>
|
||||||
* @param point position of the object
|
* @param object the object
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public L2WorldRegion getRegion(ILocational point)
|
public L2WorldRegion getRegion(L2Object object)
|
||||||
{
|
|
||||||
return getRegion(point.getX(), point.getY(), point.getZ());
|
|
||||||
}
|
|
||||||
|
|
||||||
public L2WorldRegion getRegion(int x, int y, int z)
|
|
||||||
{
|
{
|
||||||
try
|
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)
|
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));
|
||||||
// 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);
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -744,7 +692,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
|
* Returns the whole 3d array containing the world regions used by ZoneData.java to setup zones inside the world regions
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public L2WorldRegion[][][] getWorldRegions()
|
public L2WorldRegion[][] getWorldRegions()
|
||||||
{
|
{
|
||||||
return _worldRegions;
|
return _worldRegions;
|
||||||
}
|
}
|
||||||
@@ -754,31 +702,49 @@ public final class L2World
|
|||||||
* <li>Init L2WorldRegions</li><BR>
|
* <li>Init L2WorldRegions</li><BR>
|
||||||
* @param x X position of the object
|
* @param x X position of the object
|
||||||
* @param y Y 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
|
* @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));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public synchronized void disposeOutOfBoundsObject(L2Object object)
|
||||||
* Deleted all spawns in the world.
|
|
||||||
*/
|
|
||||||
public void deleteVisibleNpcSpawns()
|
|
||||||
{
|
{
|
||||||
LOGGER.info(getClass().getSimpleName() + ": Deleting all visible NPCs.");
|
if (object.isPlayer())
|
||||||
for (int x = 0; x <= REGIONS_X; x++)
|
|
||||||
{
|
{
|
||||||
for (int y = 0; y <= REGIONS_Y; y++)
|
((L2Character) object).stopMove(((L2PcInstance) object).getLastServerPosition());
|
||||||
|
}
|
||||||
|
else if (object.isSummon())
|
||||||
{
|
{
|
||||||
for (int z = 0; z <= REGIONS_Z; z++)
|
final L2Summon summon = (L2Summon) object;
|
||||||
|
summon.unSummon(summon.getOwner());
|
||||||
|
}
|
||||||
|
else if (_allObjects.remove(object.getObjectId()) != null)
|
||||||
{
|
{
|
||||||
_worldRegions[x][y][z].deleteVisibleNpcSpawns();
|
if (object.isNpc())
|
||||||
|
{
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
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.");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -25,7 +25,6 @@ import java.util.logging.Logger;
|
|||||||
|
|
||||||
import com.l2jmobius.Config;
|
import com.l2jmobius.Config;
|
||||||
import com.l2jmobius.commons.concurrent.ThreadPool;
|
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.L2Attackable;
|
||||||
import com.l2jmobius.gameserver.model.actor.L2Npc;
|
import com.l2jmobius.gameserver.model.actor.L2Npc;
|
||||||
import com.l2jmobius.gameserver.model.actor.L2Vehicle;
|
import com.l2jmobius.gameserver.model.actor.L2Vehicle;
|
||||||
@@ -38,17 +37,15 @@ public final class L2WorldRegion
|
|||||||
private volatile Map<Integer, L2Object> _visibleObjects;
|
private volatile Map<Integer, L2Object> _visibleObjects;
|
||||||
private final int _regionX;
|
private final int _regionX;
|
||||||
private final int _regionY;
|
private final int _regionY;
|
||||||
private final int _regionZ;
|
|
||||||
private boolean _active = false;
|
private boolean _active = false;
|
||||||
private ScheduledFuture<?> _neighborsTask = null;
|
private ScheduledFuture<?> _neighborsTask = null;
|
||||||
|
|
||||||
public L2WorldRegion(int regionX, int regionY, int regionZ)
|
public L2WorldRegion(int regionX, int regionY)
|
||||||
{
|
{
|
||||||
_regionX = regionX;
|
_regionX = regionX;
|
||||||
_regionY = regionY;
|
_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;
|
_active = Config.GRIDS_ALWAYS_ON;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -93,19 +90,19 @@ public final class L2WorldRegion
|
|||||||
c++;
|
c++;
|
||||||
final L2Attackable mob = (L2Attackable) o;
|
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);
|
mob.setTarget(null);
|
||||||
|
|
||||||
// Stop movement
|
// Stop movement.
|
||||||
mob.stopMove(null);
|
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.stopAllEffects();
|
||||||
|
|
||||||
mob.clearAggroList();
|
mob.clearAggroList();
|
||||||
mob.getAttackByList().clear();
|
mob.getAttackByList().clear();
|
||||||
|
|
||||||
// stop the ai tasks
|
// Stop the AI tasks.
|
||||||
if (mob.hasAI())
|
if (mob.hasAI())
|
||||||
{
|
{
|
||||||
mob.getAI().setIntention(com.l2jmobius.gameserver.ai.CtrlIntention.AI_INTENTION_IDLE);
|
mob.getAI().setIntention(com.l2jmobius.gameserver.ai.CtrlIntention.AI_INTENTION_IDLE);
|
||||||
@@ -126,7 +123,7 @@ public final class L2WorldRegion
|
|||||||
if (o.isAttackable())
|
if (o.isAttackable())
|
||||||
{
|
{
|
||||||
c++;
|
c++;
|
||||||
// Start HP/MP/CP Regeneration task
|
// Start HP/MP/CP regeneration task.
|
||||||
((L2Attackable) o).getStatus().startHpMpRegeneration();
|
((L2Attackable) o).getStatus().startHpMpRegeneration();
|
||||||
}
|
}
|
||||||
else if (o instanceof L2Npc)
|
else if (o instanceof L2Npc)
|
||||||
@@ -161,7 +158,7 @@ public final class L2WorldRegion
|
|||||||
|
|
||||||
_active = value;
|
_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);
|
switchAI(value);
|
||||||
|
|
||||||
LOGGER.finer((value ? "Starting" : "Stopping") + " Grid " + this);
|
LOGGER.finer((value ? "Starting" : "Stopping") + " Grid " + this);
|
||||||
@@ -172,10 +169,10 @@ public final class L2WorldRegion
|
|||||||
*/
|
*/
|
||||||
private void startActivation()
|
private void startActivation()
|
||||||
{
|
{
|
||||||
// first set self to active and do self-tasks...
|
// First set self to active and do self-tasks...
|
||||||
setActive(true);
|
setActive(true);
|
||||||
|
|
||||||
// if the timer to deactivate neighbors is running, cancel it.
|
// If the timer to deactivate neighbors is running, cancel it.
|
||||||
synchronized (this)
|
synchronized (this)
|
||||||
{
|
{
|
||||||
if (_neighborsTask != null)
|
if (_neighborsTask != null)
|
||||||
@@ -184,7 +181,7 @@ public final class L2WorldRegion
|
|||||||
_neighborsTask = null;
|
_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);
|
_neighborsTask = ThreadPool.schedule(new NeighborsTask(true), 1000 * Config.GRID_NEIGHBOR_TURNON_TIME);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -194,7 +191,7 @@ public final class L2WorldRegion
|
|||||||
*/
|
*/
|
||||||
private void startDeactivation()
|
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)
|
synchronized (this)
|
||||||
{
|
{
|
||||||
if (_neighborsTask != null)
|
if (_neighborsTask != null)
|
||||||
@@ -203,8 +200,8 @@ public final class L2WorldRegion
|
|||||||
_neighborsTask = null;
|
_neighborsTask = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// start a timer to "suggest" a deactivate to self and neighbors.
|
// 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.
|
// 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);
|
_neighborsTask = ThreadPool.schedule(new NeighborsTask(false), 1000 * Config.GRID_NEIGHBOR_TURNOFF_TIME);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -235,7 +232,7 @@ public final class L2WorldRegion
|
|||||||
|
|
||||||
if (object.isPlayable())
|
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))
|
if (!_active && (!Config.GRIDS_ALWAYS_ON))
|
||||||
{
|
{
|
||||||
startActivation();
|
startActivation();
|
||||||
@@ -274,46 +271,15 @@ public final class L2WorldRegion
|
|||||||
return _visibleObjects != null ? _visibleObjects : Collections.emptyMap();
|
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)
|
public boolean forEachSurroundingRegion(Predicate<L2WorldRegion> p)
|
||||||
{
|
{
|
||||||
for (int x = _regionX - 1; x <= (_regionX + 1); x++)
|
for (int x = _regionX - 1; x <= (_regionX + 1); x++)
|
||||||
{
|
{
|
||||||
for (int y = _regionY - 1; y <= (_regionY + 1); y++)
|
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];
|
||||||
{
|
|
||||||
final L2WorldRegion worldRegion = L2World.getInstance().getWorldRegions()[x][y][z];
|
|
||||||
if (!p.test(worldRegion))
|
if (!p.test(worldRegion))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
@@ -321,7 +287,6 @@ public final class L2WorldRegion
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -335,19 +300,14 @@ public final class L2WorldRegion
|
|||||||
return _regionY;
|
return _regionY;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getRegionZ()
|
|
||||||
{
|
|
||||||
return _regionZ;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isSurroundingRegion(L2WorldRegion region)
|
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
|
@Override
|
||||||
public String toString()
|
public String toString()
|
||||||
{
|
{
|
||||||
return "(" + _regionX + ", " + _regionY + ", " + _regionZ + ")";
|
return "(" + _regionX + ", " + _regionY + ")";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-27
@@ -62,7 +62,6 @@ import com.l2jmobius.gameserver.model.L2AccessLevel;
|
|||||||
import com.l2jmobius.gameserver.model.L2Clan;
|
import com.l2jmobius.gameserver.model.L2Clan;
|
||||||
import com.l2jmobius.gameserver.model.L2Object;
|
import com.l2jmobius.gameserver.model.L2Object;
|
||||||
import com.l2jmobius.gameserver.model.L2Party;
|
import com.l2jmobius.gameserver.model.L2Party;
|
||||||
import com.l2jmobius.gameserver.model.L2Spawn;
|
|
||||||
import com.l2jmobius.gameserver.model.L2World;
|
import com.l2jmobius.gameserver.model.L2World;
|
||||||
import com.l2jmobius.gameserver.model.L2WorldRegion;
|
import com.l2jmobius.gameserver.model.L2WorldRegion;
|
||||||
import com.l2jmobius.gameserver.model.Location;
|
import com.l2jmobius.gameserver.model.Location;
|
||||||
@@ -72,7 +71,6 @@ import com.l2jmobius.gameserver.model.TimeStamp;
|
|||||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||||
import com.l2jmobius.gameserver.model.actor.instance.L2PetInstance;
|
import com.l2jmobius.gameserver.model.actor.instance.L2PetInstance;
|
||||||
import com.l2jmobius.gameserver.model.actor.instance.L2QuestGuardInstance;
|
import com.l2jmobius.gameserver.model.actor.instance.L2QuestGuardInstance;
|
||||||
import com.l2jmobius.gameserver.model.actor.instance.L2ServitorInstance;
|
|
||||||
import com.l2jmobius.gameserver.model.actor.stat.CharStat;
|
import com.l2jmobius.gameserver.model.actor.stat.CharStat;
|
||||||
import com.l2jmobius.gameserver.model.actor.status.CharStatus;
|
import com.l2jmobius.gameserver.model.actor.status.CharStatus;
|
||||||
import com.l2jmobius.gameserver.model.actor.tasks.character.FlyToLocationTask;
|
import com.l2jmobius.gameserver.model.actor.tasks.character.FlyToLocationTask;
|
||||||
@@ -3983,31 +3981,7 @@ public abstract class L2Character extends L2Object implements ISkillsHolder, IDe
|
|||||||
}
|
}
|
||||||
else // Precaution. Moved at invalid region?
|
else // Precaution. Moved at invalid region?
|
||||||
{
|
{
|
||||||
if (isPlayer())
|
L2World.getInstance().disposeOutOfBoundsObject(this);
|
||||||
{
|
|
||||||
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();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -235,50 +235,6 @@ public final class Util
|
|||||||
return calculateDistance(obj1, obj2, includeZAxis, false) <= range;
|
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 str - the String to count
|
* @param str - the String to count
|
||||||
* @return the number of "words" in a given string.
|
* @return the number of "words" in a given string.
|
||||||
|
|||||||
Vendored
+28
-2
@@ -213,14 +213,40 @@ public class AdminSpawn implements IAdminCommandHandler
|
|||||||
{
|
{
|
||||||
Broadcast.toAllOnlinePlayers(SystemMessage.getSystemMessage(SystemMessageId.THE_NPC_SERVER_IS_NOT_OPERATING_AT_THIS_TIME));
|
Broadcast.toAllOnlinePlayers(SystemMessage.getSystemMessage(SystemMessageId.THE_NPC_SERVER_IS_NOT_OPERATING_AT_THIS_TIME));
|
||||||
DBSpawnManager.getInstance().cleanUp();
|
DBSpawnManager.getInstance().cleanUp();
|
||||||
L2World.getInstance().deleteVisibleNpcSpawns();
|
for (L2Object obj : L2World.getInstance().getVisibleObjects())
|
||||||
|
{
|
||||||
|
if ((obj != null) && obj.isNpc())
|
||||||
|
{
|
||||||
|
final L2Npc target = (L2Npc) obj;
|
||||||
|
target.deleteMe();
|
||||||
|
final L2Spawn spawn = target.getSpawn();
|
||||||
|
if (spawn != null)
|
||||||
|
{
|
||||||
|
spawn.stopRespawn();
|
||||||
|
SpawnTable.getInstance().deleteSpawn(spawn, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
AdminData.getInstance().broadcastMessageToGMs("NPC Unspawn completed!");
|
AdminData.getInstance().broadcastMessageToGMs("NPC Unspawn completed!");
|
||||||
}
|
}
|
||||||
else if (command.startsWith("admin_respawnall") || command.startsWith("admin_spawn_reload"))
|
else if (command.startsWith("admin_respawnall") || command.startsWith("admin_spawn_reload"))
|
||||||
{
|
{
|
||||||
// make sure all spawns are deleted
|
// make sure all spawns are deleted
|
||||||
DBSpawnManager.getInstance().cleanUp();
|
DBSpawnManager.getInstance().cleanUp();
|
||||||
L2World.getInstance().deleteVisibleNpcSpawns();
|
for (L2Object obj : L2World.getInstance().getVisibleObjects())
|
||||||
|
{
|
||||||
|
if ((obj != null) && obj.isNpc())
|
||||||
|
{
|
||||||
|
final L2Npc target = (L2Npc) obj;
|
||||||
|
target.deleteMe();
|
||||||
|
final L2Spawn spawn = target.getSpawn();
|
||||||
|
if (spawn != null)
|
||||||
|
{
|
||||||
|
spawn.stopRespawn();
|
||||||
|
SpawnTable.getInstance().deleteSpawn(spawn, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
// now respawn all
|
// now respawn all
|
||||||
NpcData.getInstance().load();
|
NpcData.getInstance().load();
|
||||||
DBSpawnManager.getInstance().load();
|
DBSpawnManager.getInstance().load();
|
||||||
|
|||||||
+1
-1
@@ -190,7 +190,7 @@ public class AdminTeleport implements IAdminCommandHandler
|
|||||||
st.nextToken();
|
st.nextToken();
|
||||||
final int x = (int) Float.parseFloat(st.nextToken());
|
final int x = (int) Float.parseFloat(st.nextToken());
|
||||||
final int y = (int) Float.parseFloat(st.nextToken());
|
final int y = (int) Float.parseFloat(st.nextToken());
|
||||||
final int z = st.hasMoreTokens() ? ((int) Float.parseFloat(st.nextToken())) : GeoEngine.getInstance().getHeight(x, y, L2World.MAP_MAX_Z);
|
final int z = st.hasMoreTokens() ? ((int) Float.parseFloat(st.nextToken())) : GeoEngine.getInstance().getHeight(x, y, 10000);
|
||||||
|
|
||||||
activeChar.teleToLocation(x, y, z);
|
activeChar.teleToLocation(x, y, z);
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -184,7 +184,7 @@ public final class FenceData implements IGameXmlReader
|
|||||||
return false;
|
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);
|
return region == null ? false : _regions.getOrDefault(region, Collections.emptyList()).stream().anyMatch(filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -115,7 +115,7 @@ public final class ItemsOnGroundManager implements Runnable
|
|||||||
item.setEnchantLevel(rs.getInt(4));
|
item.setEnchantLevel(rs.getInt(4));
|
||||||
}
|
}
|
||||||
item.setXYZ(rs.getInt(5), rs.getInt(6), rs.getInt(7));
|
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);
|
item.getWorldRegion().addVisibleObject(item);
|
||||||
final long dropTime = rs.getLong(8);
|
final long dropTime = rs.getLong(8);
|
||||||
item.setDropTime(dropTime);
|
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
|
// Set the x,y,z position of the L2Object spawn and update its _worldregion
|
||||||
_isSpawned = true;
|
_isSpawned = true;
|
||||||
setWorldRegion(L2World.getInstance().getRegion(getLocation()));
|
setWorldRegion(L2World.getInstance().getRegion(this));
|
||||||
|
|
||||||
// Add the L2Object spawn in the _allobjects of L2World
|
// Add the L2Object spawn in the _allobjects of L2World
|
||||||
L2World.getInstance().addObject(this);
|
L2World.getInstance().addObject(this);
|
||||||
@@ -207,14 +207,6 @@ public abstract class L2Object extends ListenersContainer implements IIdentifiab
|
|||||||
{
|
{
|
||||||
y = L2World.MAP_MIN_Y + 5000;
|
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.
|
// 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);
|
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.instancemanager.PlayerCountManager;
|
||||||
import com.l2jmobius.gameserver.model.actor.L2Character;
|
import com.l2jmobius.gameserver.model.actor.L2Character;
|
||||||
import com.l2jmobius.gameserver.model.actor.L2Npc;
|
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.L2PcInstance;
|
||||||
import com.l2jmobius.gameserver.model.actor.instance.L2PetInstance;
|
import com.l2jmobius.gameserver.model.actor.instance.L2PetInstance;
|
||||||
import com.l2jmobius.gameserver.model.events.EventDispatcher;
|
import com.l2jmobius.gameserver.model.events.EventDispatcher;
|
||||||
import com.l2jmobius.gameserver.model.events.impl.character.npc.OnNpcCreatureSee;
|
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.Disconnection;
|
||||||
import com.l2jmobius.gameserver.network.serverpackets.DeleteObject;
|
import com.l2jmobius.gameserver.network.serverpackets.DeleteObject;
|
||||||
import com.l2jmobius.gameserver.util.Util;
|
|
||||||
|
|
||||||
public final class L2World
|
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. */
|
/** 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 = 11;
|
||||||
public static final int SHIFT_BY_Z = 10;
|
|
||||||
|
|
||||||
public static final int TILE_SIZE = 32768;
|
public static final int TILE_SIZE = 32768;
|
||||||
|
|
||||||
/** Map dimensions */
|
/** Map dimensions. */
|
||||||
public static final int TILE_X_MIN = 11;
|
public static final int TILE_X_MIN = 11;
|
||||||
public static final int TILE_Y_MIN = 10;
|
public static final int TILE_Y_MIN = 10;
|
||||||
public static final int TILE_X_MAX = 28;
|
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 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_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_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_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_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_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_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_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_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. */
|
/** Map containing all the players in game. */
|
||||||
private final Map<Integer, L2PcInstance> _allPlayers = new ConcurrentHashMap<>();
|
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 _partyNumber = new AtomicInteger();
|
||||||
private final AtomicInteger _memberInPartyNumber = 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. */
|
/** Constructor of L2World. */
|
||||||
protected L2World()
|
protected L2World()
|
||||||
@@ -108,14 +103,11 @@ public final class L2World
|
|||||||
{
|
{
|
||||||
for (int y = 0; y <= REGIONS_Y; y++)
|
for (int y = 0; y <= REGIONS_Y; y++)
|
||||||
{
|
{
|
||||||
for (int z = 0; z <= REGIONS_Z; z++)
|
_worldRegions[x][y] = new L2WorldRegion(x, y);
|
||||||
{
|
|
||||||
_worldRegions[x][y][z] = new L2WorldRegion(x, y, z);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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();
|
PlayerCountManager.getInstance().incConnectedCount();
|
||||||
|
|
||||||
final L2PcInstance newPlayer = (L2PcInstance) object;
|
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;
|
return;
|
||||||
}
|
}
|
||||||
@@ -176,7 +168,7 @@ public final class L2World
|
|||||||
PlayerCountManager.getInstance().decConnectedCount();
|
PlayerCountManager.getInstance().decConnectedCount();
|
||||||
|
|
||||||
final L2PcInstance player = (L2PcInstance) object;
|
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;
|
return;
|
||||||
}
|
}
|
||||||
@@ -309,7 +301,7 @@ public final class L2World
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
forEachVisibleObject(object, L2Object.class, 1, wo ->
|
forEachVisibleObject(object, L2Object.class, wo ->
|
||||||
{
|
{
|
||||||
if (object.isPlayer() && wo.isVisibleFor((L2PcInstance) object))
|
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)
|
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)
|
public <T extends L2Object> void forEachVisibleObjectInRange(L2Object object, Class<T> clazz, int range, Consumer<T> c)
|
||||||
@@ -640,22 +594,15 @@ public final class L2World
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
final int depth = (range / REGION_MIN_DIMENSION) + 1;
|
final int regionX = centerWorldRegion.getRegionX();
|
||||||
for (int x = Math.max(centerWorldRegion.getRegionX() - depth, 0); x <= Math.min(centerWorldRegion.getRegionX() + depth, REGIONS_X); x++)
|
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;
|
for (L2Object visibleObject : _worldRegions[x][y].getVisibleObjects().values())
|
||||||
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][z].getVisibleObjects().values())
|
|
||||||
{
|
{
|
||||||
if ((visibleObject == null) || (visibleObject == object) || !clazz.isInstance(visibleObject))
|
if ((visibleObject == null) || (visibleObject == object) || !clazz.isInstance(visibleObject))
|
||||||
{
|
{
|
||||||
@@ -673,6 +620,10 @@ public final class L2World
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if ((x == regionX) && (y == regionY)) // Precaution. Moved at invalid region?
|
||||||
|
{
|
||||||
|
disposeOutOfBoundsObject(object);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -680,22 +631,12 @@ public final class L2World
|
|||||||
|
|
||||||
public <T extends L2Object> List<T> getVisibleObjects(L2Object object, Class<T> clazz)
|
public <T extends L2Object> List<T> getVisibleObjects(L2Object object, Class<T> clazz)
|
||||||
{
|
{
|
||||||
final List<T> result = new LinkedList<>();
|
return getVisibleObjects(object, clazz, VISIBILITY_RANGE);
|
||||||
forEachVisibleObject(object, clazz, result::add);
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public <T extends L2Object> List<T> getVisibleObjects(L2Object object, Class<T> clazz, Predicate<T> predicate)
|
public <T extends L2Object> List<T> getVisibleObjects(L2Object object, Class<T> clazz, Predicate<T> predicate)
|
||||||
{
|
{
|
||||||
final List<T> result = new LinkedList<>();
|
return getVisibleObjects(object, clazz, VISIBILITY_RANGE, predicate);
|
||||||
forEachVisibleObject(object, clazz, o ->
|
|
||||||
{
|
|
||||||
if (predicate.test(o))
|
|
||||||
{
|
|
||||||
result.add(o);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public <T extends L2Object> List<T> getVisibleObjects(L2Object object, Class<T> clazz, int range)
|
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>
|
* 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>Set position of a new L2Object (drop, spawn...)</li>
|
||||||
* <li>Update position of a L2Object after a movement</li><BR>
|
* <li>Update position of a L2Object after a movement</li><BR>
|
||||||
* @param point position of the object
|
* @param object the object
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public L2WorldRegion getRegion(ILocational point)
|
public L2WorldRegion getRegion(L2Object object)
|
||||||
{
|
|
||||||
return getRegion(point.getX(), point.getY(), point.getZ());
|
|
||||||
}
|
|
||||||
|
|
||||||
public L2WorldRegion getRegion(int x, int y, int z)
|
|
||||||
{
|
{
|
||||||
try
|
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)
|
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));
|
||||||
// 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);
|
|
||||||
return null;
|
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
|
* Returns the whole 3d array containing the world regions used by ZoneData.java to setup zones inside the world regions
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public L2WorldRegion[][][] getWorldRegions()
|
public L2WorldRegion[][] getWorldRegions()
|
||||||
{
|
{
|
||||||
return _worldRegions;
|
return _worldRegions;
|
||||||
}
|
}
|
||||||
@@ -758,31 +706,49 @@ public final class L2World
|
|||||||
* <li>Init L2WorldRegions</li><BR>
|
* <li>Init L2WorldRegions</li><BR>
|
||||||
* @param x X position of the object
|
* @param x X position of the object
|
||||||
* @param y Y 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
|
* @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));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public synchronized void disposeOutOfBoundsObject(L2Object object)
|
||||||
* Deleted all spawns in the world.
|
|
||||||
*/
|
|
||||||
public void deleteVisibleNpcSpawns()
|
|
||||||
{
|
{
|
||||||
LOGGER.info(getClass().getSimpleName() + ": Deleting all visible NPCs.");
|
if (object.isPlayer())
|
||||||
for (int x = 0; x <= REGIONS_X; x++)
|
|
||||||
{
|
{
|
||||||
for (int y = 0; y <= REGIONS_Y; y++)
|
((L2Character) object).stopMove(((L2PcInstance) object).getLastServerPosition());
|
||||||
|
}
|
||||||
|
else if (object.isSummon())
|
||||||
{
|
{
|
||||||
for (int z = 0; z <= REGIONS_Z; z++)
|
final L2Summon summon = (L2Summon) object;
|
||||||
|
summon.unSummon(summon.getOwner());
|
||||||
|
}
|
||||||
|
else if (_allObjects.remove(object.getObjectId()) != null)
|
||||||
{
|
{
|
||||||
_worldRegions[x][y][z].deleteVisibleNpcSpawns();
|
if (object.isNpc())
|
||||||
|
{
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
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()
|
public void incrementParty()
|
||||||
|
|||||||
+19
-59
@@ -25,7 +25,6 @@ import java.util.logging.Logger;
|
|||||||
|
|
||||||
import com.l2jmobius.Config;
|
import com.l2jmobius.Config;
|
||||||
import com.l2jmobius.commons.concurrent.ThreadPool;
|
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.L2Attackable;
|
||||||
import com.l2jmobius.gameserver.model.actor.L2Npc;
|
import com.l2jmobius.gameserver.model.actor.L2Npc;
|
||||||
import com.l2jmobius.gameserver.model.actor.L2Vehicle;
|
import com.l2jmobius.gameserver.model.actor.L2Vehicle;
|
||||||
@@ -38,17 +37,15 @@ public final class L2WorldRegion
|
|||||||
private volatile Map<Integer, L2Object> _visibleObjects;
|
private volatile Map<Integer, L2Object> _visibleObjects;
|
||||||
private final int _regionX;
|
private final int _regionX;
|
||||||
private final int _regionY;
|
private final int _regionY;
|
||||||
private final int _regionZ;
|
|
||||||
private boolean _active = false;
|
private boolean _active = false;
|
||||||
private ScheduledFuture<?> _neighborsTask = null;
|
private ScheduledFuture<?> _neighborsTask = null;
|
||||||
|
|
||||||
public L2WorldRegion(int regionX, int regionY, int regionZ)
|
public L2WorldRegion(int regionX, int regionY)
|
||||||
{
|
{
|
||||||
_regionX = regionX;
|
_regionX = regionX;
|
||||||
_regionY = regionY;
|
_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;
|
_active = Config.GRIDS_ALWAYS_ON;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -93,19 +90,19 @@ public final class L2WorldRegion
|
|||||||
c++;
|
c++;
|
||||||
final L2Attackable mob = (L2Attackable) o;
|
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);
|
mob.setTarget(null);
|
||||||
|
|
||||||
// Stop movement
|
// Stop movement.
|
||||||
mob.stopMove(null);
|
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.stopAllEffects();
|
||||||
|
|
||||||
mob.clearAggroList();
|
mob.clearAggroList();
|
||||||
mob.getAttackByList().clear();
|
mob.getAttackByList().clear();
|
||||||
|
|
||||||
// stop the ai tasks
|
// Stop the AI tasks.
|
||||||
if (mob.hasAI())
|
if (mob.hasAI())
|
||||||
{
|
{
|
||||||
mob.getAI().setIntention(com.l2jmobius.gameserver.ai.CtrlIntention.AI_INTENTION_IDLE);
|
mob.getAI().setIntention(com.l2jmobius.gameserver.ai.CtrlIntention.AI_INTENTION_IDLE);
|
||||||
@@ -126,7 +123,7 @@ public final class L2WorldRegion
|
|||||||
if (o.isAttackable())
|
if (o.isAttackable())
|
||||||
{
|
{
|
||||||
c++;
|
c++;
|
||||||
// Start HP/MP/CP Regeneration task
|
// Start HP/MP/CP regeneration task.
|
||||||
((L2Attackable) o).getStatus().startHpMpRegeneration();
|
((L2Attackable) o).getStatus().startHpMpRegeneration();
|
||||||
}
|
}
|
||||||
else if (o instanceof L2Npc)
|
else if (o instanceof L2Npc)
|
||||||
@@ -161,7 +158,7 @@ public final class L2WorldRegion
|
|||||||
|
|
||||||
_active = value;
|
_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);
|
switchAI(value);
|
||||||
|
|
||||||
LOGGER.finer((value ? "Starting" : "Stopping") + " Grid " + this);
|
LOGGER.finer((value ? "Starting" : "Stopping") + " Grid " + this);
|
||||||
@@ -172,10 +169,10 @@ public final class L2WorldRegion
|
|||||||
*/
|
*/
|
||||||
private void startActivation()
|
private void startActivation()
|
||||||
{
|
{
|
||||||
// first set self to active and do self-tasks...
|
// First set self to active and do self-tasks...
|
||||||
setActive(true);
|
setActive(true);
|
||||||
|
|
||||||
// if the timer to deactivate neighbors is running, cancel it.
|
// If the timer to deactivate neighbors is running, cancel it.
|
||||||
synchronized (this)
|
synchronized (this)
|
||||||
{
|
{
|
||||||
if (_neighborsTask != null)
|
if (_neighborsTask != null)
|
||||||
@@ -184,7 +181,7 @@ public final class L2WorldRegion
|
|||||||
_neighborsTask = null;
|
_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);
|
_neighborsTask = ThreadPool.schedule(new NeighborsTask(true), 1000 * Config.GRID_NEIGHBOR_TURNON_TIME);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -194,7 +191,7 @@ public final class L2WorldRegion
|
|||||||
*/
|
*/
|
||||||
private void startDeactivation()
|
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)
|
synchronized (this)
|
||||||
{
|
{
|
||||||
if (_neighborsTask != null)
|
if (_neighborsTask != null)
|
||||||
@@ -203,8 +200,8 @@ public final class L2WorldRegion
|
|||||||
_neighborsTask = null;
|
_neighborsTask = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// start a timer to "suggest" a deactivate to self and neighbors.
|
// 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.
|
// 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);
|
_neighborsTask = ThreadPool.schedule(new NeighborsTask(false), 1000 * Config.GRID_NEIGHBOR_TURNOFF_TIME);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -235,7 +232,7 @@ public final class L2WorldRegion
|
|||||||
|
|
||||||
if (object.isPlayable())
|
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))
|
if (!_active && (!Config.GRIDS_ALWAYS_ON))
|
||||||
{
|
{
|
||||||
startActivation();
|
startActivation();
|
||||||
@@ -274,46 +271,15 @@ public final class L2WorldRegion
|
|||||||
return _visibleObjects != null ? _visibleObjects : Collections.emptyMap();
|
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)
|
public boolean forEachSurroundingRegion(Predicate<L2WorldRegion> p)
|
||||||
{
|
{
|
||||||
for (int x = _regionX - 1; x <= (_regionX + 1); x++)
|
for (int x = _regionX - 1; x <= (_regionX + 1); x++)
|
||||||
{
|
{
|
||||||
for (int y = _regionY - 1; y <= (_regionY + 1); y++)
|
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];
|
||||||
{
|
|
||||||
final L2WorldRegion worldRegion = L2World.getInstance().getWorldRegions()[x][y][z];
|
|
||||||
if (!p.test(worldRegion))
|
if (!p.test(worldRegion))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
@@ -321,7 +287,6 @@ public final class L2WorldRegion
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -335,19 +300,14 @@ public final class L2WorldRegion
|
|||||||
return _regionY;
|
return _regionY;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getRegionZ()
|
|
||||||
{
|
|
||||||
return _regionZ;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isSurroundingRegion(L2WorldRegion region)
|
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
|
@Override
|
||||||
public String toString()
|
public String toString()
|
||||||
{
|
{
|
||||||
return "(" + _regionX + ", " + _regionY + ", " + _regionZ + ")";
|
return "(" + _regionX + ", " + _regionY + ")";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-27
@@ -73,7 +73,6 @@ import com.l2jmobius.gameserver.model.L2AccessLevel;
|
|||||||
import com.l2jmobius.gameserver.model.L2Clan;
|
import com.l2jmobius.gameserver.model.L2Clan;
|
||||||
import com.l2jmobius.gameserver.model.L2Object;
|
import com.l2jmobius.gameserver.model.L2Object;
|
||||||
import com.l2jmobius.gameserver.model.L2Party;
|
import com.l2jmobius.gameserver.model.L2Party;
|
||||||
import com.l2jmobius.gameserver.model.L2Spawn;
|
|
||||||
import com.l2jmobius.gameserver.model.L2World;
|
import com.l2jmobius.gameserver.model.L2World;
|
||||||
import com.l2jmobius.gameserver.model.L2WorldRegion;
|
import com.l2jmobius.gameserver.model.L2WorldRegion;
|
||||||
import com.l2jmobius.gameserver.model.Location;
|
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.FriendlyNpcInstance;
|
||||||
import com.l2jmobius.gameserver.model.actor.instance.L2MonsterInstance;
|
import com.l2jmobius.gameserver.model.actor.instance.L2MonsterInstance;
|
||||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
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.instance.L2TrapInstance;
|
||||||
import com.l2jmobius.gameserver.model.actor.stat.CharStat;
|
import com.l2jmobius.gameserver.model.actor.stat.CharStat;
|
||||||
import com.l2jmobius.gameserver.model.actor.status.CharStatus;
|
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?
|
else // Precaution. Moved at invalid region?
|
||||||
{
|
{
|
||||||
if (isPlayer())
|
L2World.getInstance().disposeOutOfBoundsObject(this);
|
||||||
{
|
|
||||||
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();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -226,50 +226,6 @@ public final class Util
|
|||||||
return calculateDistance(obj1, obj2, includeZAxis, false) <= range;
|
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
|
* @param text - the text to check
|
||||||
* @return {@code true} if {@code text} contains only numbers, {@code false} otherwise
|
* @return {@code true} if {@code text} contains only numbers, {@code false} otherwise
|
||||||
|
|||||||
Vendored
+28
-2
@@ -213,14 +213,40 @@ public class AdminSpawn implements IAdminCommandHandler
|
|||||||
{
|
{
|
||||||
Broadcast.toAllOnlinePlayers(SystemMessage.getSystemMessage(SystemMessageId.THE_NPC_SERVER_IS_NOT_OPERATING_AT_THIS_TIME));
|
Broadcast.toAllOnlinePlayers(SystemMessage.getSystemMessage(SystemMessageId.THE_NPC_SERVER_IS_NOT_OPERATING_AT_THIS_TIME));
|
||||||
DBSpawnManager.getInstance().cleanUp();
|
DBSpawnManager.getInstance().cleanUp();
|
||||||
L2World.getInstance().deleteVisibleNpcSpawns();
|
for (L2Object obj : L2World.getInstance().getVisibleObjects())
|
||||||
|
{
|
||||||
|
if ((obj != null) && obj.isNpc())
|
||||||
|
{
|
||||||
|
final L2Npc target = (L2Npc) obj;
|
||||||
|
target.deleteMe();
|
||||||
|
final L2Spawn spawn = target.getSpawn();
|
||||||
|
if (spawn != null)
|
||||||
|
{
|
||||||
|
spawn.stopRespawn();
|
||||||
|
SpawnTable.getInstance().deleteSpawn(spawn, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
AdminData.getInstance().broadcastMessageToGMs("NPC Unspawn completed!");
|
AdminData.getInstance().broadcastMessageToGMs("NPC Unspawn completed!");
|
||||||
}
|
}
|
||||||
else if (command.startsWith("admin_respawnall") || command.startsWith("admin_spawn_reload"))
|
else if (command.startsWith("admin_respawnall") || command.startsWith("admin_spawn_reload"))
|
||||||
{
|
{
|
||||||
// make sure all spawns are deleted
|
// make sure all spawns are deleted
|
||||||
DBSpawnManager.getInstance().cleanUp();
|
DBSpawnManager.getInstance().cleanUp();
|
||||||
L2World.getInstance().deleteVisibleNpcSpawns();
|
for (L2Object obj : L2World.getInstance().getVisibleObjects())
|
||||||
|
{
|
||||||
|
if ((obj != null) && obj.isNpc())
|
||||||
|
{
|
||||||
|
final L2Npc target = (L2Npc) obj;
|
||||||
|
target.deleteMe();
|
||||||
|
final L2Spawn spawn = target.getSpawn();
|
||||||
|
if (spawn != null)
|
||||||
|
{
|
||||||
|
spawn.stopRespawn();
|
||||||
|
SpawnTable.getInstance().deleteSpawn(spawn, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
// now respawn all
|
// now respawn all
|
||||||
NpcData.getInstance().load();
|
NpcData.getInstance().load();
|
||||||
DBSpawnManager.getInstance().load();
|
DBSpawnManager.getInstance().load();
|
||||||
|
|||||||
L2J_Mobius_Classic_2.1_Zaken/dist/game/data/scripts/handlers/admincommandhandlers/AdminTeleport.java
Vendored
+1
-1
@@ -190,7 +190,7 @@ public class AdminTeleport implements IAdminCommandHandler
|
|||||||
st.nextToken();
|
st.nextToken();
|
||||||
final int x = (int) Float.parseFloat(st.nextToken());
|
final int x = (int) Float.parseFloat(st.nextToken());
|
||||||
final int y = (int) Float.parseFloat(st.nextToken());
|
final int y = (int) Float.parseFloat(st.nextToken());
|
||||||
final int z = st.hasMoreTokens() ? ((int) Float.parseFloat(st.nextToken())) : GeoEngine.getInstance().getHeight(x, y, L2World.MAP_MAX_Z);
|
final int z = st.hasMoreTokens() ? ((int) Float.parseFloat(st.nextToken())) : GeoEngine.getInstance().getHeight(x, y, 10000);
|
||||||
|
|
||||||
activeChar.teleToLocation(x, y, z);
|
activeChar.teleToLocation(x, y, z);
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -184,7 +184,7 @@ public final class FenceData implements IGameXmlReader
|
|||||||
return false;
|
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);
|
return region == null ? false : _regions.getOrDefault(region, Collections.emptyList()).stream().anyMatch(filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -115,7 +115,7 @@ public final class ItemsOnGroundManager implements Runnable
|
|||||||
item.setEnchantLevel(rs.getInt(4));
|
item.setEnchantLevel(rs.getInt(4));
|
||||||
}
|
}
|
||||||
item.setXYZ(rs.getInt(5), rs.getInt(6), rs.getInt(7));
|
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);
|
item.getWorldRegion().addVisibleObject(item);
|
||||||
final long dropTime = rs.getLong(8);
|
final long dropTime = rs.getLong(8);
|
||||||
item.setDropTime(dropTime);
|
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
|
// Set the x,y,z position of the L2Object spawn and update its _worldregion
|
||||||
_isSpawned = true;
|
_isSpawned = true;
|
||||||
setWorldRegion(L2World.getInstance().getRegion(getLocation()));
|
setWorldRegion(L2World.getInstance().getRegion(this));
|
||||||
|
|
||||||
// Add the L2Object spawn in the _allobjects of L2World
|
// Add the L2Object spawn in the _allobjects of L2World
|
||||||
L2World.getInstance().addObject(this);
|
L2World.getInstance().addObject(this);
|
||||||
@@ -207,14 +207,6 @@ public abstract class L2Object extends ListenersContainer implements IIdentifiab
|
|||||||
{
|
{
|
||||||
y = L2World.MAP_MIN_Y + 5000;
|
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.
|
// 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);
|
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.instancemanager.PlayerCountManager;
|
||||||
import com.l2jmobius.gameserver.model.actor.L2Character;
|
import com.l2jmobius.gameserver.model.actor.L2Character;
|
||||||
import com.l2jmobius.gameserver.model.actor.L2Npc;
|
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.L2PcInstance;
|
||||||
import com.l2jmobius.gameserver.model.actor.instance.L2PetInstance;
|
import com.l2jmobius.gameserver.model.actor.instance.L2PetInstance;
|
||||||
import com.l2jmobius.gameserver.model.events.EventDispatcher;
|
import com.l2jmobius.gameserver.model.events.EventDispatcher;
|
||||||
import com.l2jmobius.gameserver.model.events.impl.character.npc.OnNpcCreatureSee;
|
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.Disconnection;
|
||||||
import com.l2jmobius.gameserver.network.serverpackets.DeleteObject;
|
import com.l2jmobius.gameserver.network.serverpackets.DeleteObject;
|
||||||
import com.l2jmobius.gameserver.util.Util;
|
|
||||||
|
|
||||||
public final class L2World
|
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. */
|
/** 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 = 11;
|
||||||
public static final int SHIFT_BY_Z = 10;
|
|
||||||
|
|
||||||
public static final int TILE_SIZE = 32768;
|
public static final int TILE_SIZE = 32768;
|
||||||
|
|
||||||
/** Map dimensions */
|
/** Map dimensions. */
|
||||||
public static final int TILE_X_MIN = 11;
|
public static final int TILE_X_MIN = 11;
|
||||||
public static final int TILE_Y_MIN = 10;
|
public static final int TILE_Y_MIN = 10;
|
||||||
public static final int TILE_X_MAX = 28;
|
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 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_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_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_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_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_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_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_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_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. */
|
/** Map containing all the players in game. */
|
||||||
private final Map<Integer, L2PcInstance> _allPlayers = new ConcurrentHashMap<>();
|
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 _partyNumber = new AtomicInteger();
|
||||||
private final AtomicInteger _memberInPartyNumber = 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. */
|
/** Constructor of L2World. */
|
||||||
protected L2World()
|
protected L2World()
|
||||||
@@ -108,14 +103,11 @@ public final class L2World
|
|||||||
{
|
{
|
||||||
for (int y = 0; y <= REGIONS_Y; y++)
|
for (int y = 0; y <= REGIONS_Y; y++)
|
||||||
{
|
{
|
||||||
for (int z = 0; z <= REGIONS_Z; z++)
|
_worldRegions[x][y] = new L2WorldRegion(x, y);
|
||||||
{
|
|
||||||
_worldRegions[x][y][z] = new L2WorldRegion(x, y, z);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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();
|
PlayerCountManager.getInstance().incConnectedCount();
|
||||||
|
|
||||||
final L2PcInstance newPlayer = (L2PcInstance) object;
|
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;
|
return;
|
||||||
}
|
}
|
||||||
@@ -176,7 +168,7 @@ public final class L2World
|
|||||||
PlayerCountManager.getInstance().decConnectedCount();
|
PlayerCountManager.getInstance().decConnectedCount();
|
||||||
|
|
||||||
final L2PcInstance player = (L2PcInstance) object;
|
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;
|
return;
|
||||||
}
|
}
|
||||||
@@ -309,7 +301,7 @@ public final class L2World
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
forEachVisibleObject(object, L2Object.class, 1, wo ->
|
forEachVisibleObject(object, L2Object.class, wo ->
|
||||||
{
|
{
|
||||||
if (object.isPlayer() && wo.isVisibleFor((L2PcInstance) object))
|
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)
|
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)
|
public <T extends L2Object> void forEachVisibleObjectInRange(L2Object object, Class<T> clazz, int range, Consumer<T> c)
|
||||||
@@ -640,22 +594,15 @@ public final class L2World
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
final int depth = (range / REGION_MIN_DIMENSION) + 1;
|
final int regionX = centerWorldRegion.getRegionX();
|
||||||
for (int x = Math.max(centerWorldRegion.getRegionX() - depth, 0); x <= Math.min(centerWorldRegion.getRegionX() + depth, REGIONS_X); x++)
|
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;
|
for (L2Object visibleObject : _worldRegions[x][y].getVisibleObjects().values())
|
||||||
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][z].getVisibleObjects().values())
|
|
||||||
{
|
{
|
||||||
if ((visibleObject == null) || (visibleObject == object) || !clazz.isInstance(visibleObject))
|
if ((visibleObject == null) || (visibleObject == object) || !clazz.isInstance(visibleObject))
|
||||||
{
|
{
|
||||||
@@ -673,6 +620,10 @@ public final class L2World
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if ((x == regionX) && (y == regionY)) // Precaution. Moved at invalid region?
|
||||||
|
{
|
||||||
|
disposeOutOfBoundsObject(object);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -680,22 +631,12 @@ public final class L2World
|
|||||||
|
|
||||||
public <T extends L2Object> List<T> getVisibleObjects(L2Object object, Class<T> clazz)
|
public <T extends L2Object> List<T> getVisibleObjects(L2Object object, Class<T> clazz)
|
||||||
{
|
{
|
||||||
final List<T> result = new LinkedList<>();
|
return getVisibleObjects(object, clazz, VISIBILITY_RANGE);
|
||||||
forEachVisibleObject(object, clazz, result::add);
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public <T extends L2Object> List<T> getVisibleObjects(L2Object object, Class<T> clazz, Predicate<T> predicate)
|
public <T extends L2Object> List<T> getVisibleObjects(L2Object object, Class<T> clazz, Predicate<T> predicate)
|
||||||
{
|
{
|
||||||
final List<T> result = new LinkedList<>();
|
return getVisibleObjects(object, clazz, VISIBILITY_RANGE, predicate);
|
||||||
forEachVisibleObject(object, clazz, o ->
|
|
||||||
{
|
|
||||||
if (predicate.test(o))
|
|
||||||
{
|
|
||||||
result.add(o);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public <T extends L2Object> List<T> getVisibleObjects(L2Object object, Class<T> clazz, int range)
|
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>
|
* 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>Set position of a new L2Object (drop, spawn...)</li>
|
||||||
* <li>Update position of a L2Object after a movement</li><BR>
|
* <li>Update position of a L2Object after a movement</li><BR>
|
||||||
* @param point position of the object
|
* @param object the object
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public L2WorldRegion getRegion(ILocational point)
|
public L2WorldRegion getRegion(L2Object object)
|
||||||
{
|
|
||||||
return getRegion(point.getX(), point.getY(), point.getZ());
|
|
||||||
}
|
|
||||||
|
|
||||||
public L2WorldRegion getRegion(int x, int y, int z)
|
|
||||||
{
|
{
|
||||||
try
|
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)
|
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));
|
||||||
// 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);
|
|
||||||
return null;
|
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
|
* Returns the whole 3d array containing the world regions used by ZoneData.java to setup zones inside the world regions
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public L2WorldRegion[][][] getWorldRegions()
|
public L2WorldRegion[][] getWorldRegions()
|
||||||
{
|
{
|
||||||
return _worldRegions;
|
return _worldRegions;
|
||||||
}
|
}
|
||||||
@@ -758,31 +706,49 @@ public final class L2World
|
|||||||
* <li>Init L2WorldRegions</li><BR>
|
* <li>Init L2WorldRegions</li><BR>
|
||||||
* @param x X position of the object
|
* @param x X position of the object
|
||||||
* @param y Y 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
|
* @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));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public synchronized void disposeOutOfBoundsObject(L2Object object)
|
||||||
* Deleted all spawns in the world.
|
|
||||||
*/
|
|
||||||
public void deleteVisibleNpcSpawns()
|
|
||||||
{
|
{
|
||||||
LOGGER.info(getClass().getSimpleName() + ": Deleting all visible NPCs.");
|
if (object.isPlayer())
|
||||||
for (int x = 0; x <= REGIONS_X; x++)
|
|
||||||
{
|
{
|
||||||
for (int y = 0; y <= REGIONS_Y; y++)
|
((L2Character) object).stopMove(((L2PcInstance) object).getLastServerPosition());
|
||||||
|
}
|
||||||
|
else if (object.isSummon())
|
||||||
{
|
{
|
||||||
for (int z = 0; z <= REGIONS_Z; z++)
|
final L2Summon summon = (L2Summon) object;
|
||||||
|
summon.unSummon(summon.getOwner());
|
||||||
|
}
|
||||||
|
else if (_allObjects.remove(object.getObjectId()) != null)
|
||||||
{
|
{
|
||||||
_worldRegions[x][y][z].deleteVisibleNpcSpawns();
|
if (object.isNpc())
|
||||||
|
{
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
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()
|
public void incrementParty()
|
||||||
|
|||||||
+19
-59
@@ -25,7 +25,6 @@ import java.util.logging.Logger;
|
|||||||
|
|
||||||
import com.l2jmobius.Config;
|
import com.l2jmobius.Config;
|
||||||
import com.l2jmobius.commons.concurrent.ThreadPool;
|
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.L2Attackable;
|
||||||
import com.l2jmobius.gameserver.model.actor.L2Npc;
|
import com.l2jmobius.gameserver.model.actor.L2Npc;
|
||||||
import com.l2jmobius.gameserver.model.actor.L2Vehicle;
|
import com.l2jmobius.gameserver.model.actor.L2Vehicle;
|
||||||
@@ -38,17 +37,15 @@ public final class L2WorldRegion
|
|||||||
private volatile Map<Integer, L2Object> _visibleObjects;
|
private volatile Map<Integer, L2Object> _visibleObjects;
|
||||||
private final int _regionX;
|
private final int _regionX;
|
||||||
private final int _regionY;
|
private final int _regionY;
|
||||||
private final int _regionZ;
|
|
||||||
private boolean _active = false;
|
private boolean _active = false;
|
||||||
private ScheduledFuture<?> _neighborsTask = null;
|
private ScheduledFuture<?> _neighborsTask = null;
|
||||||
|
|
||||||
public L2WorldRegion(int regionX, int regionY, int regionZ)
|
public L2WorldRegion(int regionX, int regionY)
|
||||||
{
|
{
|
||||||
_regionX = regionX;
|
_regionX = regionX;
|
||||||
_regionY = regionY;
|
_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;
|
_active = Config.GRIDS_ALWAYS_ON;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -93,19 +90,19 @@ public final class L2WorldRegion
|
|||||||
c++;
|
c++;
|
||||||
final L2Attackable mob = (L2Attackable) o;
|
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);
|
mob.setTarget(null);
|
||||||
|
|
||||||
// Stop movement
|
// Stop movement.
|
||||||
mob.stopMove(null);
|
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.stopAllEffects();
|
||||||
|
|
||||||
mob.clearAggroList();
|
mob.clearAggroList();
|
||||||
mob.getAttackByList().clear();
|
mob.getAttackByList().clear();
|
||||||
|
|
||||||
// stop the ai tasks
|
// Stop the AI tasks.
|
||||||
if (mob.hasAI())
|
if (mob.hasAI())
|
||||||
{
|
{
|
||||||
mob.getAI().setIntention(com.l2jmobius.gameserver.ai.CtrlIntention.AI_INTENTION_IDLE);
|
mob.getAI().setIntention(com.l2jmobius.gameserver.ai.CtrlIntention.AI_INTENTION_IDLE);
|
||||||
@@ -126,7 +123,7 @@ public final class L2WorldRegion
|
|||||||
if (o.isAttackable())
|
if (o.isAttackable())
|
||||||
{
|
{
|
||||||
c++;
|
c++;
|
||||||
// Start HP/MP/CP Regeneration task
|
// Start HP/MP/CP regeneration task.
|
||||||
((L2Attackable) o).getStatus().startHpMpRegeneration();
|
((L2Attackable) o).getStatus().startHpMpRegeneration();
|
||||||
}
|
}
|
||||||
else if (o instanceof L2Npc)
|
else if (o instanceof L2Npc)
|
||||||
@@ -161,7 +158,7 @@ public final class L2WorldRegion
|
|||||||
|
|
||||||
_active = value;
|
_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);
|
switchAI(value);
|
||||||
|
|
||||||
LOGGER.finer((value ? "Starting" : "Stopping") + " Grid " + this);
|
LOGGER.finer((value ? "Starting" : "Stopping") + " Grid " + this);
|
||||||
@@ -172,10 +169,10 @@ public final class L2WorldRegion
|
|||||||
*/
|
*/
|
||||||
private void startActivation()
|
private void startActivation()
|
||||||
{
|
{
|
||||||
// first set self to active and do self-tasks...
|
// First set self to active and do self-tasks...
|
||||||
setActive(true);
|
setActive(true);
|
||||||
|
|
||||||
// if the timer to deactivate neighbors is running, cancel it.
|
// If the timer to deactivate neighbors is running, cancel it.
|
||||||
synchronized (this)
|
synchronized (this)
|
||||||
{
|
{
|
||||||
if (_neighborsTask != null)
|
if (_neighborsTask != null)
|
||||||
@@ -184,7 +181,7 @@ public final class L2WorldRegion
|
|||||||
_neighborsTask = null;
|
_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);
|
_neighborsTask = ThreadPool.schedule(new NeighborsTask(true), 1000 * Config.GRID_NEIGHBOR_TURNON_TIME);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -194,7 +191,7 @@ public final class L2WorldRegion
|
|||||||
*/
|
*/
|
||||||
private void startDeactivation()
|
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)
|
synchronized (this)
|
||||||
{
|
{
|
||||||
if (_neighborsTask != null)
|
if (_neighborsTask != null)
|
||||||
@@ -203,8 +200,8 @@ public final class L2WorldRegion
|
|||||||
_neighborsTask = null;
|
_neighborsTask = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// start a timer to "suggest" a deactivate to self and neighbors.
|
// 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.
|
// 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);
|
_neighborsTask = ThreadPool.schedule(new NeighborsTask(false), 1000 * Config.GRID_NEIGHBOR_TURNOFF_TIME);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -235,7 +232,7 @@ public final class L2WorldRegion
|
|||||||
|
|
||||||
if (object.isPlayable())
|
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))
|
if (!_active && (!Config.GRIDS_ALWAYS_ON))
|
||||||
{
|
{
|
||||||
startActivation();
|
startActivation();
|
||||||
@@ -274,46 +271,15 @@ public final class L2WorldRegion
|
|||||||
return _visibleObjects != null ? _visibleObjects : Collections.emptyMap();
|
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)
|
public boolean forEachSurroundingRegion(Predicate<L2WorldRegion> p)
|
||||||
{
|
{
|
||||||
for (int x = _regionX - 1; x <= (_regionX + 1); x++)
|
for (int x = _regionX - 1; x <= (_regionX + 1); x++)
|
||||||
{
|
{
|
||||||
for (int y = _regionY - 1; y <= (_regionY + 1); y++)
|
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];
|
||||||
{
|
|
||||||
final L2WorldRegion worldRegion = L2World.getInstance().getWorldRegions()[x][y][z];
|
|
||||||
if (!p.test(worldRegion))
|
if (!p.test(worldRegion))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
@@ -321,7 +287,6 @@ public final class L2WorldRegion
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -335,19 +300,14 @@ public final class L2WorldRegion
|
|||||||
return _regionY;
|
return _regionY;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getRegionZ()
|
|
||||||
{
|
|
||||||
return _regionZ;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isSurroundingRegion(L2WorldRegion region)
|
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
|
@Override
|
||||||
public String toString()
|
public String toString()
|
||||||
{
|
{
|
||||||
return "(" + _regionX + ", " + _regionY + ", " + _regionZ + ")";
|
return "(" + _regionX + ", " + _regionY + ")";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-27
@@ -73,7 +73,6 @@ import com.l2jmobius.gameserver.model.L2AccessLevel;
|
|||||||
import com.l2jmobius.gameserver.model.L2Clan;
|
import com.l2jmobius.gameserver.model.L2Clan;
|
||||||
import com.l2jmobius.gameserver.model.L2Object;
|
import com.l2jmobius.gameserver.model.L2Object;
|
||||||
import com.l2jmobius.gameserver.model.L2Party;
|
import com.l2jmobius.gameserver.model.L2Party;
|
||||||
import com.l2jmobius.gameserver.model.L2Spawn;
|
|
||||||
import com.l2jmobius.gameserver.model.L2World;
|
import com.l2jmobius.gameserver.model.L2World;
|
||||||
import com.l2jmobius.gameserver.model.L2WorldRegion;
|
import com.l2jmobius.gameserver.model.L2WorldRegion;
|
||||||
import com.l2jmobius.gameserver.model.Location;
|
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.FriendlyNpcInstance;
|
||||||
import com.l2jmobius.gameserver.model.actor.instance.L2MonsterInstance;
|
import com.l2jmobius.gameserver.model.actor.instance.L2MonsterInstance;
|
||||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
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.instance.L2TrapInstance;
|
||||||
import com.l2jmobius.gameserver.model.actor.stat.CharStat;
|
import com.l2jmobius.gameserver.model.actor.stat.CharStat;
|
||||||
import com.l2jmobius.gameserver.model.actor.status.CharStatus;
|
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?
|
else // Precaution. Moved at invalid region?
|
||||||
{
|
{
|
||||||
if (isPlayer())
|
L2World.getInstance().disposeOutOfBoundsObject(this);
|
||||||
{
|
|
||||||
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();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -226,50 +226,6 @@ public final class Util
|
|||||||
return calculateDistance(obj1, obj2, includeZAxis, false) <= range;
|
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
|
* @param text - the text to check
|
||||||
* @return {@code true} if {@code text} contains only numbers, {@code false} otherwise
|
* @return {@code true} if {@code text} contains only numbers, {@code false} otherwise
|
||||||
|
|||||||
L2J_Mobius_Classic_2.2_Antharas/dist/game/data/scripts/handlers/admincommandhandlers/AdminSpawn.java
Vendored
+28
-2
@@ -213,14 +213,40 @@ public class AdminSpawn implements IAdminCommandHandler
|
|||||||
{
|
{
|
||||||
Broadcast.toAllOnlinePlayers(SystemMessage.getSystemMessage(SystemMessageId.THE_NPC_SERVER_IS_NOT_OPERATING_AT_THIS_TIME));
|
Broadcast.toAllOnlinePlayers(SystemMessage.getSystemMessage(SystemMessageId.THE_NPC_SERVER_IS_NOT_OPERATING_AT_THIS_TIME));
|
||||||
DBSpawnManager.getInstance().cleanUp();
|
DBSpawnManager.getInstance().cleanUp();
|
||||||
L2World.getInstance().deleteVisibleNpcSpawns();
|
for (L2Object obj : L2World.getInstance().getVisibleObjects())
|
||||||
|
{
|
||||||
|
if ((obj != null) && obj.isNpc())
|
||||||
|
{
|
||||||
|
final L2Npc target = (L2Npc) obj;
|
||||||
|
target.deleteMe();
|
||||||
|
final L2Spawn spawn = target.getSpawn();
|
||||||
|
if (spawn != null)
|
||||||
|
{
|
||||||
|
spawn.stopRespawn();
|
||||||
|
SpawnTable.getInstance().deleteSpawn(spawn, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
AdminData.getInstance().broadcastMessageToGMs("NPC Unspawn completed!");
|
AdminData.getInstance().broadcastMessageToGMs("NPC Unspawn completed!");
|
||||||
}
|
}
|
||||||
else if (command.startsWith("admin_respawnall") || command.startsWith("admin_spawn_reload"))
|
else if (command.startsWith("admin_respawnall") || command.startsWith("admin_spawn_reload"))
|
||||||
{
|
{
|
||||||
// make sure all spawns are deleted
|
// make sure all spawns are deleted
|
||||||
DBSpawnManager.getInstance().cleanUp();
|
DBSpawnManager.getInstance().cleanUp();
|
||||||
L2World.getInstance().deleteVisibleNpcSpawns();
|
for (L2Object obj : L2World.getInstance().getVisibleObjects())
|
||||||
|
{
|
||||||
|
if ((obj != null) && obj.isNpc())
|
||||||
|
{
|
||||||
|
final L2Npc target = (L2Npc) obj;
|
||||||
|
target.deleteMe();
|
||||||
|
final L2Spawn spawn = target.getSpawn();
|
||||||
|
if (spawn != null)
|
||||||
|
{
|
||||||
|
spawn.stopRespawn();
|
||||||
|
SpawnTable.getInstance().deleteSpawn(spawn, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
// now respawn all
|
// now respawn all
|
||||||
NpcData.getInstance().load();
|
NpcData.getInstance().load();
|
||||||
DBSpawnManager.getInstance().load();
|
DBSpawnManager.getInstance().load();
|
||||||
|
|||||||
+1
-1
@@ -190,7 +190,7 @@ public class AdminTeleport implements IAdminCommandHandler
|
|||||||
st.nextToken();
|
st.nextToken();
|
||||||
final int x = (int) Float.parseFloat(st.nextToken());
|
final int x = (int) Float.parseFloat(st.nextToken());
|
||||||
final int y = (int) Float.parseFloat(st.nextToken());
|
final int y = (int) Float.parseFloat(st.nextToken());
|
||||||
final int z = st.hasMoreTokens() ? ((int) Float.parseFloat(st.nextToken())) : GeoEngine.getInstance().getHeight(x, y, L2World.MAP_MAX_Z);
|
final int z = st.hasMoreTokens() ? ((int) Float.parseFloat(st.nextToken())) : GeoEngine.getInstance().getHeight(x, y, 10000);
|
||||||
|
|
||||||
activeChar.teleToLocation(x, y, z);
|
activeChar.teleToLocation(x, y, z);
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -184,7 +184,7 @@ public final class FenceData implements IGameXmlReader
|
|||||||
return false;
|
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);
|
return region == null ? false : _regions.getOrDefault(region, Collections.emptyList()).stream().anyMatch(filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -115,7 +115,7 @@ public final class ItemsOnGroundManager implements Runnable
|
|||||||
item.setEnchantLevel(rs.getInt(4));
|
item.setEnchantLevel(rs.getInt(4));
|
||||||
}
|
}
|
||||||
item.setXYZ(rs.getInt(5), rs.getInt(6), rs.getInt(7));
|
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);
|
item.getWorldRegion().addVisibleObject(item);
|
||||||
final long dropTime = rs.getLong(8);
|
final long dropTime = rs.getLong(8);
|
||||||
item.setDropTime(dropTime);
|
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
|
// Set the x,y,z position of the L2Object spawn and update its _worldregion
|
||||||
_isSpawned = true;
|
_isSpawned = true;
|
||||||
setWorldRegion(L2World.getInstance().getRegion(getLocation()));
|
setWorldRegion(L2World.getInstance().getRegion(this));
|
||||||
|
|
||||||
// Add the L2Object spawn in the _allobjects of L2World
|
// Add the L2Object spawn in the _allobjects of L2World
|
||||||
L2World.getInstance().addObject(this);
|
L2World.getInstance().addObject(this);
|
||||||
@@ -207,14 +207,6 @@ public abstract class L2Object extends ListenersContainer implements IIdentifiab
|
|||||||
{
|
{
|
||||||
y = L2World.MAP_MIN_Y + 5000;
|
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.
|
// 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);
|
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.instancemanager.PlayerCountManager;
|
||||||
import com.l2jmobius.gameserver.model.actor.L2Character;
|
import com.l2jmobius.gameserver.model.actor.L2Character;
|
||||||
import com.l2jmobius.gameserver.model.actor.L2Npc;
|
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.L2PcInstance;
|
||||||
import com.l2jmobius.gameserver.model.actor.instance.L2PetInstance;
|
import com.l2jmobius.gameserver.model.actor.instance.L2PetInstance;
|
||||||
import com.l2jmobius.gameserver.model.events.EventDispatcher;
|
import com.l2jmobius.gameserver.model.events.EventDispatcher;
|
||||||
import com.l2jmobius.gameserver.model.events.impl.character.npc.OnNpcCreatureSee;
|
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.Disconnection;
|
||||||
import com.l2jmobius.gameserver.network.serverpackets.DeleteObject;
|
import com.l2jmobius.gameserver.network.serverpackets.DeleteObject;
|
||||||
import com.l2jmobius.gameserver.util.Util;
|
|
||||||
|
|
||||||
public final class L2World
|
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. */
|
/** 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 = 11;
|
||||||
public static final int SHIFT_BY_Z = 10;
|
|
||||||
|
|
||||||
public static final int TILE_SIZE = 32768;
|
public static final int TILE_SIZE = 32768;
|
||||||
|
|
||||||
/** Map dimensions */
|
/** Map dimensions. */
|
||||||
public static final int TILE_X_MIN = 11;
|
public static final int TILE_X_MIN = 11;
|
||||||
public static final int TILE_Y_MIN = 10;
|
public static final int TILE_Y_MIN = 10;
|
||||||
public static final int TILE_X_MAX = 28;
|
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 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_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_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_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_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_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_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_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_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. */
|
/** Map containing all the players in game. */
|
||||||
private final Map<Integer, L2PcInstance> _allPlayers = new ConcurrentHashMap<>();
|
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 _partyNumber = new AtomicInteger();
|
||||||
private final AtomicInteger _memberInPartyNumber = 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. */
|
/** Constructor of L2World. */
|
||||||
protected L2World()
|
protected L2World()
|
||||||
@@ -108,14 +103,11 @@ public final class L2World
|
|||||||
{
|
{
|
||||||
for (int y = 0; y <= REGIONS_Y; y++)
|
for (int y = 0; y <= REGIONS_Y; y++)
|
||||||
{
|
{
|
||||||
for (int z = 0; z <= REGIONS_Z; z++)
|
_worldRegions[x][y] = new L2WorldRegion(x, y);
|
||||||
{
|
|
||||||
_worldRegions[x][y][z] = new L2WorldRegion(x, y, z);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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();
|
PlayerCountManager.getInstance().incConnectedCount();
|
||||||
|
|
||||||
final L2PcInstance newPlayer = (L2PcInstance) object;
|
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;
|
return;
|
||||||
}
|
}
|
||||||
@@ -176,7 +168,7 @@ public final class L2World
|
|||||||
PlayerCountManager.getInstance().decConnectedCount();
|
PlayerCountManager.getInstance().decConnectedCount();
|
||||||
|
|
||||||
final L2PcInstance player = (L2PcInstance) object;
|
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;
|
return;
|
||||||
}
|
}
|
||||||
@@ -309,7 +301,7 @@ public final class L2World
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
forEachVisibleObject(object, L2Object.class, 1, wo ->
|
forEachVisibleObject(object, L2Object.class, wo ->
|
||||||
{
|
{
|
||||||
if (object.isPlayer() && wo.isVisibleFor((L2PcInstance) object))
|
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)
|
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)
|
public <T extends L2Object> void forEachVisibleObjectInRange(L2Object object, Class<T> clazz, int range, Consumer<T> c)
|
||||||
@@ -640,22 +594,15 @@ public final class L2World
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
final int depth = (range / REGION_MIN_DIMENSION) + 1;
|
final int regionX = centerWorldRegion.getRegionX();
|
||||||
for (int x = Math.max(centerWorldRegion.getRegionX() - depth, 0); x <= Math.min(centerWorldRegion.getRegionX() + depth, REGIONS_X); x++)
|
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;
|
for (L2Object visibleObject : _worldRegions[x][y].getVisibleObjects().values())
|
||||||
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][z].getVisibleObjects().values())
|
|
||||||
{
|
{
|
||||||
if ((visibleObject == null) || (visibleObject == object) || !clazz.isInstance(visibleObject))
|
if ((visibleObject == null) || (visibleObject == object) || !clazz.isInstance(visibleObject))
|
||||||
{
|
{
|
||||||
@@ -673,6 +620,10 @@ public final class L2World
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if ((x == regionX) && (y == regionY)) // Precaution. Moved at invalid region?
|
||||||
|
{
|
||||||
|
disposeOutOfBoundsObject(object);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -680,22 +631,12 @@ public final class L2World
|
|||||||
|
|
||||||
public <T extends L2Object> List<T> getVisibleObjects(L2Object object, Class<T> clazz)
|
public <T extends L2Object> List<T> getVisibleObjects(L2Object object, Class<T> clazz)
|
||||||
{
|
{
|
||||||
final List<T> result = new LinkedList<>();
|
return getVisibleObjects(object, clazz, VISIBILITY_RANGE);
|
||||||
forEachVisibleObject(object, clazz, result::add);
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public <T extends L2Object> List<T> getVisibleObjects(L2Object object, Class<T> clazz, Predicate<T> predicate)
|
public <T extends L2Object> List<T> getVisibleObjects(L2Object object, Class<T> clazz, Predicate<T> predicate)
|
||||||
{
|
{
|
||||||
final List<T> result = new LinkedList<>();
|
return getVisibleObjects(object, clazz, VISIBILITY_RANGE, predicate);
|
||||||
forEachVisibleObject(object, clazz, o ->
|
|
||||||
{
|
|
||||||
if (predicate.test(o))
|
|
||||||
{
|
|
||||||
result.add(o);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public <T extends L2Object> List<T> getVisibleObjects(L2Object object, Class<T> clazz, int range)
|
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>
|
* 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>Set position of a new L2Object (drop, spawn...)</li>
|
||||||
* <li>Update position of a L2Object after a movement</li><BR>
|
* <li>Update position of a L2Object after a movement</li><BR>
|
||||||
* @param point position of the object
|
* @param object the object
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public L2WorldRegion getRegion(ILocational point)
|
public L2WorldRegion getRegion(L2Object object)
|
||||||
{
|
|
||||||
return getRegion(point.getX(), point.getY(), point.getZ());
|
|
||||||
}
|
|
||||||
|
|
||||||
public L2WorldRegion getRegion(int x, int y, int z)
|
|
||||||
{
|
{
|
||||||
try
|
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)
|
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));
|
||||||
// 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);
|
|
||||||
return null;
|
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
|
* Returns the whole 3d array containing the world regions used by ZoneData.java to setup zones inside the world regions
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public L2WorldRegion[][][] getWorldRegions()
|
public L2WorldRegion[][] getWorldRegions()
|
||||||
{
|
{
|
||||||
return _worldRegions;
|
return _worldRegions;
|
||||||
}
|
}
|
||||||
@@ -758,31 +706,49 @@ public final class L2World
|
|||||||
* <li>Init L2WorldRegions</li><BR>
|
* <li>Init L2WorldRegions</li><BR>
|
||||||
* @param x X position of the object
|
* @param x X position of the object
|
||||||
* @param y Y 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
|
* @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));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public synchronized void disposeOutOfBoundsObject(L2Object object)
|
||||||
* Deleted all spawns in the world.
|
|
||||||
*/
|
|
||||||
public void deleteVisibleNpcSpawns()
|
|
||||||
{
|
{
|
||||||
LOGGER.info(getClass().getSimpleName() + ": Deleting all visible NPCs.");
|
if (object.isPlayer())
|
||||||
for (int x = 0; x <= REGIONS_X; x++)
|
|
||||||
{
|
{
|
||||||
for (int y = 0; y <= REGIONS_Y; y++)
|
((L2Character) object).stopMove(((L2PcInstance) object).getLastServerPosition());
|
||||||
|
}
|
||||||
|
else if (object.isSummon())
|
||||||
{
|
{
|
||||||
for (int z = 0; z <= REGIONS_Z; z++)
|
final L2Summon summon = (L2Summon) object;
|
||||||
|
summon.unSummon(summon.getOwner());
|
||||||
|
}
|
||||||
|
else if (_allObjects.remove(object.getObjectId()) != null)
|
||||||
{
|
{
|
||||||
_worldRegions[x][y][z].deleteVisibleNpcSpawns();
|
if (object.isNpc())
|
||||||
|
{
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
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()
|
public void incrementParty()
|
||||||
|
|||||||
+19
-59
@@ -25,7 +25,6 @@ import java.util.logging.Logger;
|
|||||||
|
|
||||||
import com.l2jmobius.Config;
|
import com.l2jmobius.Config;
|
||||||
import com.l2jmobius.commons.concurrent.ThreadPool;
|
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.L2Attackable;
|
||||||
import com.l2jmobius.gameserver.model.actor.L2Npc;
|
import com.l2jmobius.gameserver.model.actor.L2Npc;
|
||||||
import com.l2jmobius.gameserver.model.actor.L2Vehicle;
|
import com.l2jmobius.gameserver.model.actor.L2Vehicle;
|
||||||
@@ -38,17 +37,15 @@ public final class L2WorldRegion
|
|||||||
private volatile Map<Integer, L2Object> _visibleObjects;
|
private volatile Map<Integer, L2Object> _visibleObjects;
|
||||||
private final int _regionX;
|
private final int _regionX;
|
||||||
private final int _regionY;
|
private final int _regionY;
|
||||||
private final int _regionZ;
|
|
||||||
private boolean _active = false;
|
private boolean _active = false;
|
||||||
private ScheduledFuture<?> _neighborsTask = null;
|
private ScheduledFuture<?> _neighborsTask = null;
|
||||||
|
|
||||||
public L2WorldRegion(int regionX, int regionY, int regionZ)
|
public L2WorldRegion(int regionX, int regionY)
|
||||||
{
|
{
|
||||||
_regionX = regionX;
|
_regionX = regionX;
|
||||||
_regionY = regionY;
|
_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;
|
_active = Config.GRIDS_ALWAYS_ON;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -93,19 +90,19 @@ public final class L2WorldRegion
|
|||||||
c++;
|
c++;
|
||||||
final L2Attackable mob = (L2Attackable) o;
|
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);
|
mob.setTarget(null);
|
||||||
|
|
||||||
// Stop movement
|
// Stop movement.
|
||||||
mob.stopMove(null);
|
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.stopAllEffects();
|
||||||
|
|
||||||
mob.clearAggroList();
|
mob.clearAggroList();
|
||||||
mob.getAttackByList().clear();
|
mob.getAttackByList().clear();
|
||||||
|
|
||||||
// stop the ai tasks
|
// Stop the AI tasks.
|
||||||
if (mob.hasAI())
|
if (mob.hasAI())
|
||||||
{
|
{
|
||||||
mob.getAI().setIntention(com.l2jmobius.gameserver.ai.CtrlIntention.AI_INTENTION_IDLE);
|
mob.getAI().setIntention(com.l2jmobius.gameserver.ai.CtrlIntention.AI_INTENTION_IDLE);
|
||||||
@@ -126,7 +123,7 @@ public final class L2WorldRegion
|
|||||||
if (o.isAttackable())
|
if (o.isAttackable())
|
||||||
{
|
{
|
||||||
c++;
|
c++;
|
||||||
// Start HP/MP/CP Regeneration task
|
// Start HP/MP/CP regeneration task.
|
||||||
((L2Attackable) o).getStatus().startHpMpRegeneration();
|
((L2Attackable) o).getStatus().startHpMpRegeneration();
|
||||||
}
|
}
|
||||||
else if (o instanceof L2Npc)
|
else if (o instanceof L2Npc)
|
||||||
@@ -161,7 +158,7 @@ public final class L2WorldRegion
|
|||||||
|
|
||||||
_active = value;
|
_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);
|
switchAI(value);
|
||||||
|
|
||||||
LOGGER.finer((value ? "Starting" : "Stopping") + " Grid " + this);
|
LOGGER.finer((value ? "Starting" : "Stopping") + " Grid " + this);
|
||||||
@@ -172,10 +169,10 @@ public final class L2WorldRegion
|
|||||||
*/
|
*/
|
||||||
private void startActivation()
|
private void startActivation()
|
||||||
{
|
{
|
||||||
// first set self to active and do self-tasks...
|
// First set self to active and do self-tasks...
|
||||||
setActive(true);
|
setActive(true);
|
||||||
|
|
||||||
// if the timer to deactivate neighbors is running, cancel it.
|
// If the timer to deactivate neighbors is running, cancel it.
|
||||||
synchronized (this)
|
synchronized (this)
|
||||||
{
|
{
|
||||||
if (_neighborsTask != null)
|
if (_neighborsTask != null)
|
||||||
@@ -184,7 +181,7 @@ public final class L2WorldRegion
|
|||||||
_neighborsTask = null;
|
_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);
|
_neighborsTask = ThreadPool.schedule(new NeighborsTask(true), 1000 * Config.GRID_NEIGHBOR_TURNON_TIME);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -194,7 +191,7 @@ public final class L2WorldRegion
|
|||||||
*/
|
*/
|
||||||
private void startDeactivation()
|
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)
|
synchronized (this)
|
||||||
{
|
{
|
||||||
if (_neighborsTask != null)
|
if (_neighborsTask != null)
|
||||||
@@ -203,8 +200,8 @@ public final class L2WorldRegion
|
|||||||
_neighborsTask = null;
|
_neighborsTask = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// start a timer to "suggest" a deactivate to self and neighbors.
|
// 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.
|
// 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);
|
_neighborsTask = ThreadPool.schedule(new NeighborsTask(false), 1000 * Config.GRID_NEIGHBOR_TURNOFF_TIME);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -235,7 +232,7 @@ public final class L2WorldRegion
|
|||||||
|
|
||||||
if (object.isPlayable())
|
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))
|
if (!_active && (!Config.GRIDS_ALWAYS_ON))
|
||||||
{
|
{
|
||||||
startActivation();
|
startActivation();
|
||||||
@@ -274,46 +271,15 @@ public final class L2WorldRegion
|
|||||||
return _visibleObjects != null ? _visibleObjects : Collections.emptyMap();
|
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)
|
public boolean forEachSurroundingRegion(Predicate<L2WorldRegion> p)
|
||||||
{
|
{
|
||||||
for (int x = _regionX - 1; x <= (_regionX + 1); x++)
|
for (int x = _regionX - 1; x <= (_regionX + 1); x++)
|
||||||
{
|
{
|
||||||
for (int y = _regionY - 1; y <= (_regionY + 1); y++)
|
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];
|
||||||
{
|
|
||||||
final L2WorldRegion worldRegion = L2World.getInstance().getWorldRegions()[x][y][z];
|
|
||||||
if (!p.test(worldRegion))
|
if (!p.test(worldRegion))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
@@ -321,7 +287,6 @@ public final class L2WorldRegion
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -335,19 +300,14 @@ public final class L2WorldRegion
|
|||||||
return _regionY;
|
return _regionY;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getRegionZ()
|
|
||||||
{
|
|
||||||
return _regionZ;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isSurroundingRegion(L2WorldRegion region)
|
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
|
@Override
|
||||||
public String toString()
|
public String toString()
|
||||||
{
|
{
|
||||||
return "(" + _regionX + ", " + _regionY + ", " + _regionZ + ")";
|
return "(" + _regionX + ", " + _regionY + ")";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-27
@@ -73,7 +73,6 @@ import com.l2jmobius.gameserver.model.L2AccessLevel;
|
|||||||
import com.l2jmobius.gameserver.model.L2Clan;
|
import com.l2jmobius.gameserver.model.L2Clan;
|
||||||
import com.l2jmobius.gameserver.model.L2Object;
|
import com.l2jmobius.gameserver.model.L2Object;
|
||||||
import com.l2jmobius.gameserver.model.L2Party;
|
import com.l2jmobius.gameserver.model.L2Party;
|
||||||
import com.l2jmobius.gameserver.model.L2Spawn;
|
|
||||||
import com.l2jmobius.gameserver.model.L2World;
|
import com.l2jmobius.gameserver.model.L2World;
|
||||||
import com.l2jmobius.gameserver.model.L2WorldRegion;
|
import com.l2jmobius.gameserver.model.L2WorldRegion;
|
||||||
import com.l2jmobius.gameserver.model.Location;
|
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.FriendlyNpcInstance;
|
||||||
import com.l2jmobius.gameserver.model.actor.instance.L2MonsterInstance;
|
import com.l2jmobius.gameserver.model.actor.instance.L2MonsterInstance;
|
||||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
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.instance.L2TrapInstance;
|
||||||
import com.l2jmobius.gameserver.model.actor.stat.CharStat;
|
import com.l2jmobius.gameserver.model.actor.stat.CharStat;
|
||||||
import com.l2jmobius.gameserver.model.actor.status.CharStatus;
|
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?
|
else // Precaution. Moved at invalid region?
|
||||||
{
|
{
|
||||||
if (isPlayer())
|
L2World.getInstance().disposeOutOfBoundsObject(this);
|
||||||
{
|
|
||||||
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();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -226,50 +226,6 @@ public final class Util
|
|||||||
return calculateDistance(obj1, obj2, includeZAxis, false) <= range;
|
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
|
* @param text - the text to check
|
||||||
* @return {@code true} if {@code text} contains only numbers, {@code false} otherwise
|
* @return {@code true} if {@code text} contains only numbers, {@code false} otherwise
|
||||||
|
|||||||
Reference in New Issue
Block a user