WorldRegion class simplifications.
This commit is contained in:
@ -1174,12 +1174,6 @@ public class AttackableAI extends CreatureAI
|
||||
return;
|
||||
}
|
||||
|
||||
// Prevent thinking in non active regions.
|
||||
if (!_actor.isInActiveRegion())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Start thinking action
|
||||
_thinking = true;
|
||||
|
||||
|
@ -78,20 +78,20 @@ public class World
|
||||
private static final int REGIONS_Y = (MAP_MAX_Y >> SHIFT_BY) + OFFSET_Y;
|
||||
|
||||
/** Map containing all the players in game. */
|
||||
private final Map<Integer, PlayerInstance> _allPlayers = new ConcurrentHashMap<>();
|
||||
private static final Map<Integer, PlayerInstance> _allPlayers = new ConcurrentHashMap<>();
|
||||
/** Map containing all the Good players in game. */
|
||||
private static final Map<Integer, PlayerInstance> _allGoodPlayers = new ConcurrentHashMap<>();
|
||||
/** Map containing all the Evil players in game. */
|
||||
private static final Map<Integer, PlayerInstance> _allEvilPlayers = new ConcurrentHashMap<>();
|
||||
/** Map containing all visible objects. */
|
||||
private final Map<Integer, WorldObject> _allObjects = new ConcurrentHashMap<>();
|
||||
private static final Map<Integer, WorldObject> _allObjects = new ConcurrentHashMap<>();
|
||||
/** Map with the pets instances and their owner ID. */
|
||||
private final Map<Integer, PetInstance> _petsInstance = new ConcurrentHashMap<>();
|
||||
private static final Map<Integer, PetInstance> _petsInstance = new ConcurrentHashMap<>();
|
||||
|
||||
private final AtomicInteger _partyNumber = new AtomicInteger();
|
||||
private final AtomicInteger _memberInPartyNumber = new AtomicInteger();
|
||||
private static final AtomicInteger _partyNumber = new AtomicInteger();
|
||||
private static final AtomicInteger _memberInPartyNumber = new AtomicInteger();
|
||||
|
||||
private final WorldRegion[][] _worldRegions = new WorldRegion[REGIONS_X + 1][REGIONS_Y + 1];
|
||||
private static final WorldRegion[][] _worldRegions = new WorldRegion[REGIONS_X + 1][REGIONS_Y + 1];
|
||||
|
||||
/** Constructor of World. */
|
||||
protected World()
|
||||
@ -403,67 +403,63 @@ public class World
|
||||
*/
|
||||
public void removeVisibleObject(WorldObject object, WorldRegion oldRegion)
|
||||
{
|
||||
if (object == null)
|
||||
if ((object == null) || (oldRegion == null))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (oldRegion != null)
|
||||
oldRegion.removeVisibleObject(object);
|
||||
|
||||
// Go through all surrounding WorldRegion Creatures
|
||||
for (WorldRegion worldRegion : oldRegion.getSurroundingRegions())
|
||||
{
|
||||
oldRegion.removeVisibleObject(object);
|
||||
|
||||
// Go through all surrounding WorldRegion Creatures
|
||||
oldRegion.forEachSurroundingRegion(w ->
|
||||
for (WorldObject wo : worldRegion.getVisibleObjects().values())
|
||||
{
|
||||
for (WorldObject wo : w.getVisibleObjects().values())
|
||||
if (wo == object)
|
||||
{
|
||||
if (wo == object)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (object.isCreature())
|
||||
{
|
||||
final Creature objectCreature = (Creature) object;
|
||||
final CreatureAI ai = objectCreature.getAI();
|
||||
if (ai != null)
|
||||
{
|
||||
continue;
|
||||
ai.notifyEvent(CtrlEvent.EVT_FORGET_OBJECT, wo);
|
||||
}
|
||||
|
||||
if (object.isCreature())
|
||||
if (objectCreature.getTarget() == wo)
|
||||
{
|
||||
final Creature objectCreature = (Creature) object;
|
||||
final CreatureAI ai = objectCreature.getAI();
|
||||
if (ai != null)
|
||||
{
|
||||
ai.notifyEvent(CtrlEvent.EVT_FORGET_OBJECT, wo);
|
||||
}
|
||||
|
||||
if (objectCreature.getTarget() == wo)
|
||||
{
|
||||
objectCreature.setTarget(null);
|
||||
}
|
||||
|
||||
if (object.isPlayer())
|
||||
{
|
||||
object.sendPacket(new DeleteObject(wo));
|
||||
}
|
||||
objectCreature.setTarget(null);
|
||||
}
|
||||
|
||||
if (wo.isCreature())
|
||||
if (object.isPlayer())
|
||||
{
|
||||
final Creature woCreature = (Creature) wo;
|
||||
final CreatureAI ai = woCreature.getAI();
|
||||
if (ai != null)
|
||||
{
|
||||
ai.notifyEvent(CtrlEvent.EVT_FORGET_OBJECT, object);
|
||||
}
|
||||
|
||||
if (woCreature.getTarget() == object)
|
||||
{
|
||||
woCreature.setTarget(null);
|
||||
}
|
||||
|
||||
if (wo.isPlayer())
|
||||
{
|
||||
wo.sendPacket(new DeleteObject(object));
|
||||
}
|
||||
object.sendPacket(new DeleteObject(wo));
|
||||
}
|
||||
}
|
||||
return true;
|
||||
});
|
||||
|
||||
if (wo.isCreature())
|
||||
{
|
||||
final Creature woCreature = (Creature) wo;
|
||||
final CreatureAI ai = woCreature.getAI();
|
||||
if (ai != null)
|
||||
{
|
||||
ai.notifyEvent(CtrlEvent.EVT_FORGET_OBJECT, object);
|
||||
}
|
||||
|
||||
if (woCreature.getTarget() == object)
|
||||
{
|
||||
woCreature.setTarget(null);
|
||||
}
|
||||
|
||||
if (wo.isPlayer())
|
||||
{
|
||||
wo.sendPacket(new DeleteObject(object));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -475,125 +471,127 @@ public class World
|
||||
return;
|
||||
}
|
||||
|
||||
oldRegion.forEachSurroundingRegion(w ->
|
||||
for (WorldRegion worldRegion : oldRegion.getSurroundingRegions())
|
||||
{
|
||||
if (!newRegion.isSurroundingRegion(w))
|
||||
if (newRegion.isSurroundingRegion(worldRegion))
|
||||
{
|
||||
for (WorldObject wo : w.getVisibleObjects().values())
|
||||
continue;
|
||||
}
|
||||
|
||||
for (WorldObject wo : worldRegion.getVisibleObjects().values())
|
||||
{
|
||||
if (wo == object)
|
||||
{
|
||||
if (wo == object)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (object.isCreature())
|
||||
{
|
||||
final Creature objectCreature = (Creature) object;
|
||||
final CreatureAI ai = objectCreature.getAI();
|
||||
if (ai != null)
|
||||
{
|
||||
continue;
|
||||
ai.notifyEvent(CtrlEvent.EVT_FORGET_OBJECT, wo);
|
||||
}
|
||||
|
||||
if (object.isCreature())
|
||||
if (objectCreature.getTarget() == wo)
|
||||
{
|
||||
final Creature objectCreature = (Creature) object;
|
||||
final CreatureAI ai = objectCreature.getAI();
|
||||
if (ai != null)
|
||||
{
|
||||
ai.notifyEvent(CtrlEvent.EVT_FORGET_OBJECT, wo);
|
||||
}
|
||||
|
||||
if (objectCreature.getTarget() == wo)
|
||||
{
|
||||
objectCreature.setTarget(null);
|
||||
}
|
||||
|
||||
if (object.isPlayer())
|
||||
{
|
||||
object.sendPacket(new DeleteObject(wo));
|
||||
}
|
||||
objectCreature.setTarget(null);
|
||||
}
|
||||
|
||||
if (object.isPlayer())
|
||||
{
|
||||
object.sendPacket(new DeleteObject(wo));
|
||||
}
|
||||
}
|
||||
|
||||
if (wo.isCreature())
|
||||
{
|
||||
final Creature woCreature = (Creature) wo;
|
||||
final CreatureAI ai = woCreature.getAI();
|
||||
if (ai != null)
|
||||
{
|
||||
ai.notifyEvent(CtrlEvent.EVT_FORGET_OBJECT, object);
|
||||
}
|
||||
|
||||
if (woCreature.getTarget() == object)
|
||||
{
|
||||
woCreature.setTarget(null);
|
||||
}
|
||||
|
||||
if (wo.isPlayer())
|
||||
{
|
||||
wo.sendPacket(new DeleteObject(object));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (WorldRegion worldRegion : newRegion.getSurroundingRegions())
|
||||
{
|
||||
if (oldRegion.isSurroundingRegion(worldRegion))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
for (WorldObject wo : worldRegion.getVisibleObjects().values())
|
||||
{
|
||||
if ((wo == object) || (wo.getInstanceWorld() != object.getInstanceWorld()))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (object.isPlayer() && wo.isVisibleFor((PlayerInstance) object))
|
||||
{
|
||||
wo.sendInfo((PlayerInstance) object);
|
||||
if (wo.isCreature())
|
||||
{
|
||||
final Creature woCreature = (Creature) wo;
|
||||
final CreatureAI ai = woCreature.getAI();
|
||||
final CreatureAI ai = ((Creature) wo).getAI();
|
||||
if (ai != null)
|
||||
{
|
||||
ai.notifyEvent(CtrlEvent.EVT_FORGET_OBJECT, object);
|
||||
}
|
||||
|
||||
if (woCreature.getTarget() == object)
|
||||
{
|
||||
woCreature.setTarget(null);
|
||||
}
|
||||
|
||||
if (wo.isPlayer())
|
||||
{
|
||||
wo.sendPacket(new DeleteObject(object));
|
||||
ai.describeStateToPlayer((PlayerInstance) object);
|
||||
if (wo.isMonster())
|
||||
{
|
||||
if (ai.getIntention() == CtrlIntention.AI_INTENTION_IDLE)
|
||||
{
|
||||
ai.setIntention(CtrlIntention.AI_INTENTION_ACTIVE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
});
|
||||
|
||||
newRegion.forEachSurroundingRegion(w ->
|
||||
{
|
||||
if (!oldRegion.isSurroundingRegion(w))
|
||||
{
|
||||
for (WorldObject wo : w.getVisibleObjects().values())
|
||||
|
||||
if (wo.isPlayer() && object.isVisibleFor((PlayerInstance) wo))
|
||||
{
|
||||
if ((wo == object) || (wo.getInstanceWorld() != object.getInstanceWorld()))
|
||||
object.sendInfo((PlayerInstance) wo);
|
||||
if (object.isCreature())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (object.isPlayer() && wo.isVisibleFor((PlayerInstance) object))
|
||||
{
|
||||
wo.sendInfo((PlayerInstance) object);
|
||||
if (wo.isCreature())
|
||||
final CreatureAI ai = ((Creature) object).getAI();
|
||||
if (ai != null)
|
||||
{
|
||||
final CreatureAI ai = ((Creature) wo).getAI();
|
||||
if (ai != null)
|
||||
ai.describeStateToPlayer((PlayerInstance) wo);
|
||||
if (object.isMonster())
|
||||
{
|
||||
ai.describeStateToPlayer((PlayerInstance) object);
|
||||
if (wo.isMonster())
|
||||
if (ai.getIntention() == CtrlIntention.AI_INTENTION_IDLE)
|
||||
{
|
||||
if (ai.getIntention() == CtrlIntention.AI_INTENTION_IDLE)
|
||||
{
|
||||
ai.setIntention(CtrlIntention.AI_INTENTION_ACTIVE);
|
||||
}
|
||||
ai.setIntention(CtrlIntention.AI_INTENTION_ACTIVE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (wo.isPlayer() && object.isVisibleFor((PlayerInstance) wo))
|
||||
{
|
||||
object.sendInfo((PlayerInstance) wo);
|
||||
if (object.isCreature())
|
||||
{
|
||||
final CreatureAI ai = ((Creature) object).getAI();
|
||||
if (ai != null)
|
||||
{
|
||||
ai.describeStateToPlayer((PlayerInstance) wo);
|
||||
if (object.isMonster())
|
||||
{
|
||||
if (ai.getIntention() == CtrlIntention.AI_INTENTION_IDLE)
|
||||
{
|
||||
ai.setIntention(CtrlIntention.AI_INTENTION_ACTIVE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (wo.isNpc() && object.isCreature())
|
||||
{
|
||||
EventDispatcher.getInstance().notifyEventAsync(new OnNpcCreatureSee((Npc) wo, (Creature) object, object.isSummon()), (Npc) wo);
|
||||
}
|
||||
|
||||
if (object.isNpc() && wo.isCreature())
|
||||
{
|
||||
EventDispatcher.getInstance().notifyEventAsync(new OnNpcCreatureSee((Npc) object, (Creature) wo, wo.isSummon()), (Npc) object);
|
||||
}
|
||||
}
|
||||
|
||||
if (wo.isNpc() && object.isCreature())
|
||||
{
|
||||
EventDispatcher.getInstance().notifyEventAsync(new OnNpcCreatureSee((Npc) wo, (Creature) object, object.isSummon()), (Npc) wo);
|
||||
}
|
||||
|
||||
if (object.isNpc() && wo.isCreature())
|
||||
{
|
||||
EventDispatcher.getInstance().notifyEventAsync(new OnNpcCreatureSee((Npc) object, (Creature) wo, wo.isSummon()), (Npc) object);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public <T extends WorldObject> List<T> getVisibleObjects(WorldObject object, Class<T> clazz)
|
||||
|
@ -19,7 +19,6 @@ package org.l2jmobius.gameserver.model;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import org.l2jmobius.Config;
|
||||
import org.l2jmobius.commons.concurrent.ThreadPool;
|
||||
@ -35,40 +34,13 @@ public class WorldRegion
|
||||
private WorldRegion[] _surroundingRegions;
|
||||
private final int _regionX;
|
||||
private final int _regionY;
|
||||
private boolean _active = false;
|
||||
private boolean _active = Config.GRIDS_ALWAYS_ON;
|
||||
private ScheduledFuture<?> _neighborsTask = null;
|
||||
|
||||
public WorldRegion(int regionX, int regionY)
|
||||
{
|
||||
_regionX = regionX;
|
||||
_regionY = regionY;
|
||||
|
||||
// Default a newly initialized region to inactive, unless always on is specified.
|
||||
_active = Config.GRIDS_ALWAYS_ON;
|
||||
}
|
||||
|
||||
/** Task of AI notification */
|
||||
public class NeighborsTask implements Runnable
|
||||
{
|
||||
private final boolean _isActivating;
|
||||
|
||||
public NeighborsTask(boolean isActivating)
|
||||
{
|
||||
_isActivating = isActivating;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
forEachSurroundingRegion(w ->
|
||||
{
|
||||
if (_isActivating || w.areNeighborsEmpty())
|
||||
{
|
||||
w.setActive(_isActivating);
|
||||
}
|
||||
return true;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void switchAI(boolean isOn)
|
||||
@ -80,11 +52,11 @@ public class WorldRegion
|
||||
|
||||
if (!isOn)
|
||||
{
|
||||
for (WorldObject o : _visibleObjects.values())
|
||||
for (WorldObject wo : _visibleObjects.values())
|
||||
{
|
||||
if (o.isAttackable())
|
||||
if (wo.isAttackable())
|
||||
{
|
||||
final Attackable mob = (Attackable) o;
|
||||
final Attackable mob = (Attackable) wo;
|
||||
|
||||
// Set target to null and cancel attack or cast.
|
||||
mob.setTarget(null);
|
||||
@ -107,25 +79,25 @@ public class WorldRegion
|
||||
|
||||
RandomAnimationTaskManager.getInstance().remove(mob);
|
||||
}
|
||||
else if (o instanceof Npc)
|
||||
else if (wo instanceof Npc)
|
||||
{
|
||||
RandomAnimationTaskManager.getInstance().remove((Npc) o);
|
||||
RandomAnimationTaskManager.getInstance().remove((Npc) wo);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (WorldObject o : _visibleObjects.values())
|
||||
for (WorldObject wo : _visibleObjects.values())
|
||||
{
|
||||
if (o.isAttackable())
|
||||
if (wo.isAttackable())
|
||||
{
|
||||
// Start HP/MP/CP regeneration task.
|
||||
((Attackable) o).getStatus().startHpMpRegeneration();
|
||||
RandomAnimationTaskManager.getInstance().add((Npc) o);
|
||||
((Attackable) wo).getStatus().startHpMpRegeneration();
|
||||
RandomAnimationTaskManager.getInstance().add((Npc) wo);
|
||||
}
|
||||
else if (o instanceof Npc)
|
||||
else if (wo instanceof Npc)
|
||||
{
|
||||
RandomAnimationTaskManager.getInstance().add((Npc) o);
|
||||
RandomAnimationTaskManager.getInstance().add((Npc) wo);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -138,7 +110,14 @@ public class WorldRegion
|
||||
|
||||
public boolean areNeighborsEmpty()
|
||||
{
|
||||
return forEachSurroundingRegion(w -> !(w.isActive() && w.getVisibleObjects().values().stream().anyMatch(WorldObject::isPlayable)));
|
||||
for (WorldRegion worldRegion : _surroundingRegions)
|
||||
{
|
||||
if (worldRegion.isActive() && worldRegion.getVisibleObjects().values().stream().anyMatch(WorldObject::isPlayable))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -176,7 +155,13 @@ public class WorldRegion
|
||||
}
|
||||
|
||||
// Then, set a timer to activate the neighbors.
|
||||
_neighborsTask = ThreadPool.schedule(new NeighborsTask(true), 1000 * Config.GRID_NEIGHBOR_TURNON_TIME);
|
||||
_neighborsTask = ThreadPool.schedule(() ->
|
||||
{
|
||||
for (WorldRegion worldRegion : _surroundingRegions)
|
||||
{
|
||||
worldRegion.setActive(true);
|
||||
}
|
||||
}, 1000 * Config.GRID_NEIGHBOR_TURNON_TIME);
|
||||
}
|
||||
}
|
||||
|
||||
@ -196,7 +181,16 @@ public class WorldRegion
|
||||
|
||||
// Start a timer to "suggest" a deactivate to self and neighbors.
|
||||
// Suggest means: first check if a neighbor has PlayerInstances in it. If not, deactivate.
|
||||
_neighborsTask = ThreadPool.schedule(new NeighborsTask(false), 1000 * Config.GRID_NEIGHBOR_TURNOFF_TIME);
|
||||
_neighborsTask = ThreadPool.schedule(() ->
|
||||
{
|
||||
for (WorldRegion worldRegion : _surroundingRegions)
|
||||
{
|
||||
if (worldRegion.areNeighborsEmpty())
|
||||
{
|
||||
worldRegion.setActive(false);
|
||||
}
|
||||
}
|
||||
}, 1000 * Config.GRID_NEIGHBOR_TURNOFF_TIME);
|
||||
}
|
||||
}
|
||||
|
||||
@ -217,7 +211,7 @@ public class WorldRegion
|
||||
if (object.isPlayable())
|
||||
{
|
||||
// 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();
|
||||
}
|
||||
@ -255,18 +249,6 @@ public class WorldRegion
|
||||
return _visibleObjects;
|
||||
}
|
||||
|
||||
public boolean forEachSurroundingRegion(Predicate<WorldRegion> p)
|
||||
{
|
||||
for (WorldRegion worldRegion : _surroundingRegions)
|
||||
{
|
||||
if (!p.test(worldRegion))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public void setSurroundingRegions(WorldRegion[] regions)
|
||||
{
|
||||
_surroundingRegions = regions;
|
||||
|
Reference in New Issue
Block a user