Removal of CreatureContainer class.
This commit is contained in:
@@ -254,6 +254,7 @@ public abstract class AbstractAI implements Ctrl
|
|||||||
{
|
{
|
||||||
case EVT_THINK:
|
case EVT_THINK:
|
||||||
{
|
{
|
||||||
|
_actor.updateSeenCreatures();
|
||||||
onEvtThink();
|
onEvtThink();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -325,7 +326,9 @@ public abstract class AbstractAI implements Ctrl
|
|||||||
}
|
}
|
||||||
case EVT_FORGET_OBJECT:
|
case EVT_FORGET_OBJECT:
|
||||||
{
|
{
|
||||||
onEvtForgetObject((WorldObject) arg0);
|
final WorldObject worldObject = (WorldObject) arg0;
|
||||||
|
_actor.removeSeenCreature(worldObject);
|
||||||
|
onEvtForgetObject(worldObject);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case EVT_CANCEL:
|
case EVT_CANCEL:
|
||||||
|
|||||||
@@ -1,106 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of the L2J Mobius project.
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
package org.l2jmobius.gameserver.model;
|
|
||||||
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
|
||||||
import java.util.concurrent.ScheduledFuture;
|
|
||||||
import java.util.function.Predicate;
|
|
||||||
|
|
||||||
import org.l2jmobius.commons.concurrent.ThreadPool;
|
|
||||||
import org.l2jmobius.gameserver.model.actor.Creature;
|
|
||||||
import org.l2jmobius.gameserver.model.events.EventDispatcher;
|
|
||||||
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureSee;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author UnAfraid
|
|
||||||
*/
|
|
||||||
public class CreatureContainer
|
|
||||||
{
|
|
||||||
private final Set<Integer> _seen = ConcurrentHashMap.newKeySet();
|
|
||||||
private final Creature _owner;
|
|
||||||
private final int _range;
|
|
||||||
private ScheduledFuture<?> _task;
|
|
||||||
private Predicate<Creature> _condition = null;
|
|
||||||
|
|
||||||
public CreatureContainer(Creature owner, int range, Predicate<Creature> condition)
|
|
||||||
{
|
|
||||||
_owner = owner;
|
|
||||||
_range = range;
|
|
||||||
_condition = condition;
|
|
||||||
start();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Creature getOwner()
|
|
||||||
{
|
|
||||||
return _owner;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getRange()
|
|
||||||
{
|
|
||||||
return _range;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Starts the task that scans for new creatures
|
|
||||||
*/
|
|
||||||
public void start()
|
|
||||||
{
|
|
||||||
if ((_task == null) || _task.isDone())
|
|
||||||
{
|
|
||||||
_task = ThreadPool.scheduleAtFixedRate(this::update, 1000, 1000);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return {@code false} if the task could not be cancelled, typically because it has already completed normally; {@code true} otherwise
|
|
||||||
*/
|
|
||||||
public boolean stop()
|
|
||||||
{
|
|
||||||
return (_task != null) && !_task.isDone() && _task.cancel(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Resets the creatures container, all previously seen creature will be discarded and next time update method is called will notify for each creature that owner sees!
|
|
||||||
*/
|
|
||||||
public void reset()
|
|
||||||
{
|
|
||||||
_seen.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Scans around the npc and notifies about new creature owner seen
|
|
||||||
*/
|
|
||||||
private void update()
|
|
||||||
{
|
|
||||||
final Set<Integer> verified = new HashSet<>();
|
|
||||||
World.getInstance().forEachVisibleObjectInRange(_owner, Creature.class, _range, creature ->
|
|
||||||
{
|
|
||||||
if ((_condition == null) || _condition.test(creature))
|
|
||||||
{
|
|
||||||
if (_seen.add(creature.getObjectId()))
|
|
||||||
{
|
|
||||||
EventDispatcher.getInstance().notifyEventAsync(new OnCreatureSee(_owner, creature), _owner);
|
|
||||||
}
|
|
||||||
verified.add(creature.getObjectId());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
_seen.retainAll(verified);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -69,7 +69,6 @@ import org.l2jmobius.gameserver.instancemanager.MapRegionManager;
|
|||||||
import org.l2jmobius.gameserver.instancemanager.QuestManager;
|
import org.l2jmobius.gameserver.instancemanager.QuestManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.ZoneManager;
|
import org.l2jmobius.gameserver.instancemanager.ZoneManager;
|
||||||
import org.l2jmobius.gameserver.model.AccessLevel;
|
import org.l2jmobius.gameserver.model.AccessLevel;
|
||||||
import org.l2jmobius.gameserver.model.CreatureContainer;
|
|
||||||
import org.l2jmobius.gameserver.model.EffectList;
|
import org.l2jmobius.gameserver.model.EffectList;
|
||||||
import org.l2jmobius.gameserver.model.Hit;
|
import org.l2jmobius.gameserver.model.Hit;
|
||||||
import org.l2jmobius.gameserver.model.Location;
|
import org.l2jmobius.gameserver.model.Location;
|
||||||
@@ -88,6 +87,7 @@ import org.l2jmobius.gameserver.model.actor.stat.CreatureStat;
|
|||||||
import org.l2jmobius.gameserver.model.actor.status.CreatureStatus;
|
import org.l2jmobius.gameserver.model.actor.status.CreatureStatus;
|
||||||
import org.l2jmobius.gameserver.model.actor.tasks.creature.NotifyAITask;
|
import org.l2jmobius.gameserver.model.actor.tasks.creature.NotifyAITask;
|
||||||
import org.l2jmobius.gameserver.model.actor.templates.CreatureTemplate;
|
import org.l2jmobius.gameserver.model.actor.templates.CreatureTemplate;
|
||||||
|
import org.l2jmobius.gameserver.model.actor.templates.NpcTemplate;
|
||||||
import org.l2jmobius.gameserver.model.actor.transform.Transform;
|
import org.l2jmobius.gameserver.model.actor.transform.Transform;
|
||||||
import org.l2jmobius.gameserver.model.clan.Clan;
|
import org.l2jmobius.gameserver.model.clan.Clan;
|
||||||
import org.l2jmobius.gameserver.model.effects.EffectFlag;
|
import org.l2jmobius.gameserver.model.effects.EffectFlag;
|
||||||
@@ -101,6 +101,7 @@ import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureDamageDealt
|
|||||||
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureDamageReceived;
|
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureDamageReceived;
|
||||||
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureDeath;
|
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureDeath;
|
||||||
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureKilled;
|
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureKilled;
|
||||||
|
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureSee;
|
||||||
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureTeleport;
|
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureTeleport;
|
||||||
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureTeleported;
|
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureTeleported;
|
||||||
import org.l2jmobius.gameserver.model.events.listeners.AbstractEventListener;
|
import org.l2jmobius.gameserver.model.events.listeners.AbstractEventListener;
|
||||||
@@ -271,7 +272,8 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
|
|
||||||
private final Map<Integer, RelationCache> _knownRelations = new ConcurrentHashMap<>();
|
private final Map<Integer, RelationCache> _knownRelations = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
private CreatureContainer _seenCreatures;
|
private Set<Creature> _seenCreatures = null;
|
||||||
|
private int _seenCreatureRange = Config.ALT_PARTY_RANGE;
|
||||||
|
|
||||||
private final Map<StatusUpdateType, Integer> _statusUpdates = new ConcurrentHashMap<>();
|
private final Map<StatusUpdateType, Integer> _statusUpdates = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
@@ -563,13 +565,6 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
{
|
{
|
||||||
_summoner.removeSummonedNpc(getObjectId());
|
_summoner.removeSummonedNpc(getObjectId());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stop on creature see task and clear the data
|
|
||||||
if (_seenCreatures != null)
|
|
||||||
{
|
|
||||||
_seenCreatures.stop();
|
|
||||||
_seenCreatures.reset();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -577,12 +572,6 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
{
|
{
|
||||||
super.onSpawn();
|
super.onSpawn();
|
||||||
revalidateZone(true);
|
revalidateZone(true);
|
||||||
|
|
||||||
// restart task
|
|
||||||
if (_seenCreatures != null)
|
|
||||||
{
|
|
||||||
_seenCreatures.start();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized void onTeleported()
|
public synchronized void onTeleported()
|
||||||
@@ -591,6 +580,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
spawnMe(getX(), getY(), getZ());
|
spawnMe(getX(), getY(), getZ());
|
||||||
setTeleporting(false);
|
setTeleporting(false);
|
||||||
EventDispatcher.getInstance().notifyEventAsync(new OnCreatureTeleported(this), this);
|
EventDispatcher.getInstance().notifyEventAsync(new OnCreatureTeleported(this), this);
|
||||||
@@ -1727,6 +1717,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
{
|
{
|
||||||
getSkillChannelized().abortChannelization();
|
getSkillChannelized().abortChannelization();
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1757,6 +1748,12 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
// Remove all active, passive and option effects, do not broadcast changes.
|
// Remove all active, passive and option effects, do not broadcast changes.
|
||||||
_effectList.stopAllEffectsWithoutExclusions(false, false);
|
_effectList.stopAllEffectsWithoutExclusions(false, false);
|
||||||
|
|
||||||
|
// Forget all seen creatures.
|
||||||
|
if (_seenCreatures != null)
|
||||||
|
{
|
||||||
|
_seenCreatures.clear();
|
||||||
|
}
|
||||||
|
|
||||||
// Cancel the BuffFinishTask related to this creature.
|
// Cancel the BuffFinishTask related to this creature.
|
||||||
cancelBuffFinishTask();
|
cancelBuffFinishTask();
|
||||||
|
|
||||||
@@ -5428,22 +5425,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
return _blockActionsAllowedSkills.containsKey(skill.getId());
|
return _blockActionsAllowedSkills.containsKey(skill.getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public void initSeenCreatures()
|
||||||
* Initialize creature container that looks up for creatures around its owner, and notifies with onCreatureSee upon discovery.
|
|
||||||
* @param range
|
|
||||||
*/
|
|
||||||
public void initSeenCreatures(int range)
|
|
||||||
{
|
|
||||||
initSeenCreatures(range, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialize creature container that looks up for creatures around its owner, and notifies with onCreatureSee upon discovery.<br>
|
|
||||||
* <i>The condition can be null</i>
|
|
||||||
* @param range
|
|
||||||
* @param condition
|
|
||||||
*/
|
|
||||||
public void initSeenCreatures(int range, Predicate<Creature> condition)
|
|
||||||
{
|
{
|
||||||
if (_seenCreatures == null)
|
if (_seenCreatures == null)
|
||||||
{
|
{
|
||||||
@@ -5451,15 +5433,45 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
{
|
{
|
||||||
if (_seenCreatures == null)
|
if (_seenCreatures == null)
|
||||||
{
|
{
|
||||||
_seenCreatures = new CreatureContainer(this, range, condition);
|
if (isNpc())
|
||||||
|
{
|
||||||
|
final NpcTemplate template = ((Npc) this).getTemplate();
|
||||||
|
if ((template != null) && (template.getAggroRange() > 0))
|
||||||
|
{
|
||||||
|
_seenCreatureRange = template.getAggroRange();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_seenCreatures = ConcurrentHashMap.newKeySet(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public CreatureContainer getSeenCreatures()
|
public void updateSeenCreatures()
|
||||||
{
|
{
|
||||||
return _seenCreatures;
|
if ((_seenCreatures == null) || _isDead || !isSpawned())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
World.getInstance().forEachVisibleObjectInRange(this, Creature.class, _seenCreatureRange, creature ->
|
||||||
|
{
|
||||||
|
if (_seenCreatures.add(creature))
|
||||||
|
{
|
||||||
|
EventDispatcher.getInstance().notifyEventAsync(new OnCreatureSee(this, creature), this);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeSeenCreature(WorldObject worldObject)
|
||||||
|
{
|
||||||
|
if (_seenCreatures == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_seenCreatures.remove(worldObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
public MoveType getMoveType()
|
public MoveType getMoveType()
|
||||||
|
|||||||
@@ -1832,14 +1832,6 @@ public class Npc extends Creature
|
|||||||
return Rnd.get(100) < Rnd.get(getTemplate().getMinSkillChance(), getTemplate().getMaxSkillChance());
|
return Rnd.get(100) < Rnd.get(getTemplate().getMinSkillChance(), getTemplate().getMaxSkillChance());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialize creature container that looks up for creatures around its owner, and notifies with onCreatureSee upon discovery.
|
|
||||||
*/
|
|
||||||
public void initSeenCreatures()
|
|
||||||
{
|
|
||||||
initSeenCreatures(getTemplate().getAggroRange());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the NpcStringId for name
|
* @return the NpcStringId for name
|
||||||
*/
|
*/
|
||||||
|
|||||||
+14
-3
@@ -962,6 +962,17 @@ public abstract class AbstractScript extends ManagedScript implements IEventTime
|
|||||||
return registerConsumer(callback, EventType.ON_NPC_CREATURE_SEE, ListenerRegisterType.NPC, npcIds);
|
return registerConsumer(callback, EventType.ON_NPC_CREATURE_SEE, ListenerRegisterType.NPC, npcIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides instant callback operation when {@link Npc} sees another creature.
|
||||||
|
* @param callback
|
||||||
|
* @param npcIds
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
protected final List<AbstractEventListener> setNpcCreatureSeeId(Consumer<OnNpcCreatureSee> callback, Collection<Integer> npcIds)
|
||||||
|
{
|
||||||
|
return registerConsumer(callback, EventType.ON_NPC_CREATURE_SEE, ListenerRegisterType.NPC, npcIds);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides instant callback operation when {@link Creature} sees another creature.
|
* Provides instant callback operation when {@link Creature} sees another creature.
|
||||||
* @param callback
|
* @param callback
|
||||||
@@ -974,14 +985,14 @@ public abstract class AbstractScript extends ManagedScript implements IEventTime
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides instant callback operation when {@link Npc} sees another creature.
|
* Provides instant callback operation when {@link Creature} sees another creature.
|
||||||
* @param callback
|
* @param callback
|
||||||
* @param npcIds
|
* @param npcIds
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
protected final List<AbstractEventListener> setNpcCreatureSeeId(Consumer<OnNpcCreatureSee> callback, Collection<Integer> npcIds)
|
protected final List<AbstractEventListener> setCreatureSeeId(Consumer<OnCreatureSee> callback, Collection<Integer> npcIds)
|
||||||
{
|
{
|
||||||
return registerConsumer(callback, EventType.ON_NPC_CREATURE_SEE, ListenerRegisterType.NPC, npcIds);
|
return registerConsumer(callback, EventType.ON_CREATURE_SEE, ListenerRegisterType.NPC, npcIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -254,6 +254,7 @@ public abstract class AbstractAI implements Ctrl
|
|||||||
{
|
{
|
||||||
case EVT_THINK:
|
case EVT_THINK:
|
||||||
{
|
{
|
||||||
|
_actor.updateSeenCreatures();
|
||||||
onEvtThink();
|
onEvtThink();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -325,7 +326,9 @@ public abstract class AbstractAI implements Ctrl
|
|||||||
}
|
}
|
||||||
case EVT_FORGET_OBJECT:
|
case EVT_FORGET_OBJECT:
|
||||||
{
|
{
|
||||||
onEvtForgetObject((WorldObject) arg0);
|
final WorldObject worldObject = (WorldObject) arg0;
|
||||||
|
_actor.removeSeenCreature(worldObject);
|
||||||
|
onEvtForgetObject(worldObject);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case EVT_CANCEL:
|
case EVT_CANCEL:
|
||||||
|
|||||||
-106
@@ -1,106 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of the L2J Mobius project.
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
package org.l2jmobius.gameserver.model;
|
|
||||||
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
|
||||||
import java.util.concurrent.ScheduledFuture;
|
|
||||||
import java.util.function.Predicate;
|
|
||||||
|
|
||||||
import org.l2jmobius.commons.concurrent.ThreadPool;
|
|
||||||
import org.l2jmobius.gameserver.model.actor.Creature;
|
|
||||||
import org.l2jmobius.gameserver.model.events.EventDispatcher;
|
|
||||||
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureSee;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author UnAfraid
|
|
||||||
*/
|
|
||||||
public class CreatureContainer
|
|
||||||
{
|
|
||||||
private final Set<Integer> _seen = ConcurrentHashMap.newKeySet();
|
|
||||||
private final Creature _owner;
|
|
||||||
private final int _range;
|
|
||||||
private ScheduledFuture<?> _task;
|
|
||||||
private Predicate<Creature> _condition = null;
|
|
||||||
|
|
||||||
public CreatureContainer(Creature owner, int range, Predicate<Creature> condition)
|
|
||||||
{
|
|
||||||
_owner = owner;
|
|
||||||
_range = range;
|
|
||||||
_condition = condition;
|
|
||||||
start();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Creature getOwner()
|
|
||||||
{
|
|
||||||
return _owner;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getRange()
|
|
||||||
{
|
|
||||||
return _range;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Starts the task that scans for new creatures
|
|
||||||
*/
|
|
||||||
public void start()
|
|
||||||
{
|
|
||||||
if ((_task == null) || _task.isDone())
|
|
||||||
{
|
|
||||||
_task = ThreadPool.scheduleAtFixedRate(this::update, 1000, 1000);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return {@code false} if the task could not be cancelled, typically because it has already completed normally; {@code true} otherwise
|
|
||||||
*/
|
|
||||||
public boolean stop()
|
|
||||||
{
|
|
||||||
return (_task != null) && !_task.isDone() && _task.cancel(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Resets the creatures container, all previously seen creature will be discarded and next time update method is called will notify for each creature that owner sees!
|
|
||||||
*/
|
|
||||||
public void reset()
|
|
||||||
{
|
|
||||||
_seen.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Scans around the npc and notifies about new creature owner seen
|
|
||||||
*/
|
|
||||||
private void update()
|
|
||||||
{
|
|
||||||
final Set<Integer> verified = new HashSet<>();
|
|
||||||
World.getInstance().forEachVisibleObjectInRange(_owner, Creature.class, _range, creature ->
|
|
||||||
{
|
|
||||||
if ((_condition == null) || _condition.test(creature))
|
|
||||||
{
|
|
||||||
if (_seen.add(creature.getObjectId()))
|
|
||||||
{
|
|
||||||
EventDispatcher.getInstance().notifyEventAsync(new OnCreatureSee(_owner, creature), _owner);
|
|
||||||
}
|
|
||||||
verified.add(creature.getObjectId());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
_seen.retainAll(verified);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+46
-34
@@ -69,7 +69,6 @@ import org.l2jmobius.gameserver.instancemanager.MapRegionManager;
|
|||||||
import org.l2jmobius.gameserver.instancemanager.QuestManager;
|
import org.l2jmobius.gameserver.instancemanager.QuestManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.ZoneManager;
|
import org.l2jmobius.gameserver.instancemanager.ZoneManager;
|
||||||
import org.l2jmobius.gameserver.model.AccessLevel;
|
import org.l2jmobius.gameserver.model.AccessLevel;
|
||||||
import org.l2jmobius.gameserver.model.CreatureContainer;
|
|
||||||
import org.l2jmobius.gameserver.model.EffectList;
|
import org.l2jmobius.gameserver.model.EffectList;
|
||||||
import org.l2jmobius.gameserver.model.Hit;
|
import org.l2jmobius.gameserver.model.Hit;
|
||||||
import org.l2jmobius.gameserver.model.Location;
|
import org.l2jmobius.gameserver.model.Location;
|
||||||
@@ -88,6 +87,7 @@ import org.l2jmobius.gameserver.model.actor.stat.CreatureStat;
|
|||||||
import org.l2jmobius.gameserver.model.actor.status.CreatureStatus;
|
import org.l2jmobius.gameserver.model.actor.status.CreatureStatus;
|
||||||
import org.l2jmobius.gameserver.model.actor.tasks.creature.NotifyAITask;
|
import org.l2jmobius.gameserver.model.actor.tasks.creature.NotifyAITask;
|
||||||
import org.l2jmobius.gameserver.model.actor.templates.CreatureTemplate;
|
import org.l2jmobius.gameserver.model.actor.templates.CreatureTemplate;
|
||||||
|
import org.l2jmobius.gameserver.model.actor.templates.NpcTemplate;
|
||||||
import org.l2jmobius.gameserver.model.actor.transform.Transform;
|
import org.l2jmobius.gameserver.model.actor.transform.Transform;
|
||||||
import org.l2jmobius.gameserver.model.clan.Clan;
|
import org.l2jmobius.gameserver.model.clan.Clan;
|
||||||
import org.l2jmobius.gameserver.model.effects.EffectFlag;
|
import org.l2jmobius.gameserver.model.effects.EffectFlag;
|
||||||
@@ -101,6 +101,7 @@ import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureDamageDealt
|
|||||||
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureDamageReceived;
|
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureDamageReceived;
|
||||||
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureDeath;
|
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureDeath;
|
||||||
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureKilled;
|
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureKilled;
|
||||||
|
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureSee;
|
||||||
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureTeleport;
|
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureTeleport;
|
||||||
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureTeleported;
|
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureTeleported;
|
||||||
import org.l2jmobius.gameserver.model.events.listeners.AbstractEventListener;
|
import org.l2jmobius.gameserver.model.events.listeners.AbstractEventListener;
|
||||||
@@ -271,7 +272,8 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
|
|
||||||
private final Map<Integer, RelationCache> _knownRelations = new ConcurrentHashMap<>();
|
private final Map<Integer, RelationCache> _knownRelations = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
private CreatureContainer _seenCreatures;
|
private Set<Creature> _seenCreatures = null;
|
||||||
|
private int _seenCreatureRange = Config.ALT_PARTY_RANGE;
|
||||||
|
|
||||||
private final Map<StatusUpdateType, Integer> _statusUpdates = new ConcurrentHashMap<>();
|
private final Map<StatusUpdateType, Integer> _statusUpdates = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
@@ -563,13 +565,6 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
{
|
{
|
||||||
_summoner.removeSummonedNpc(getObjectId());
|
_summoner.removeSummonedNpc(getObjectId());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stop on creature see task and clear the data
|
|
||||||
if (_seenCreatures != null)
|
|
||||||
{
|
|
||||||
_seenCreatures.stop();
|
|
||||||
_seenCreatures.reset();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -577,12 +572,6 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
{
|
{
|
||||||
super.onSpawn();
|
super.onSpawn();
|
||||||
revalidateZone(true);
|
revalidateZone(true);
|
||||||
|
|
||||||
// restart task
|
|
||||||
if (_seenCreatures != null)
|
|
||||||
{
|
|
||||||
_seenCreatures.start();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized void onTeleported()
|
public synchronized void onTeleported()
|
||||||
@@ -591,6 +580,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
spawnMe(getX(), getY(), getZ());
|
spawnMe(getX(), getY(), getZ());
|
||||||
setTeleporting(false);
|
setTeleporting(false);
|
||||||
EventDispatcher.getInstance().notifyEventAsync(new OnCreatureTeleported(this), this);
|
EventDispatcher.getInstance().notifyEventAsync(new OnCreatureTeleported(this), this);
|
||||||
@@ -1727,6 +1717,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
{
|
{
|
||||||
getSkillChannelized().abortChannelization();
|
getSkillChannelized().abortChannelization();
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1757,6 +1748,12 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
// Remove all active, passive and option effects, do not broadcast changes.
|
// Remove all active, passive and option effects, do not broadcast changes.
|
||||||
_effectList.stopAllEffectsWithoutExclusions(false, false);
|
_effectList.stopAllEffectsWithoutExclusions(false, false);
|
||||||
|
|
||||||
|
// Forget all seen creatures.
|
||||||
|
if (_seenCreatures != null)
|
||||||
|
{
|
||||||
|
_seenCreatures.clear();
|
||||||
|
}
|
||||||
|
|
||||||
// Cancel the BuffFinishTask related to this creature.
|
// Cancel the BuffFinishTask related to this creature.
|
||||||
cancelBuffFinishTask();
|
cancelBuffFinishTask();
|
||||||
|
|
||||||
@@ -5428,22 +5425,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
return _blockActionsAllowedSkills.containsKey(skill.getId());
|
return _blockActionsAllowedSkills.containsKey(skill.getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public void initSeenCreatures()
|
||||||
* Initialize creature container that looks up for creatures around its owner, and notifies with onCreatureSee upon discovery.
|
|
||||||
* @param range
|
|
||||||
*/
|
|
||||||
public void initSeenCreatures(int range)
|
|
||||||
{
|
|
||||||
initSeenCreatures(range, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialize creature container that looks up for creatures around its owner, and notifies with onCreatureSee upon discovery.<br>
|
|
||||||
* <i>The condition can be null</i>
|
|
||||||
* @param range
|
|
||||||
* @param condition
|
|
||||||
*/
|
|
||||||
public void initSeenCreatures(int range, Predicate<Creature> condition)
|
|
||||||
{
|
{
|
||||||
if (_seenCreatures == null)
|
if (_seenCreatures == null)
|
||||||
{
|
{
|
||||||
@@ -5451,15 +5433,45 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
{
|
{
|
||||||
if (_seenCreatures == null)
|
if (_seenCreatures == null)
|
||||||
{
|
{
|
||||||
_seenCreatures = new CreatureContainer(this, range, condition);
|
if (isNpc())
|
||||||
|
{
|
||||||
|
final NpcTemplate template = ((Npc) this).getTemplate();
|
||||||
|
if ((template != null) && (template.getAggroRange() > 0))
|
||||||
|
{
|
||||||
|
_seenCreatureRange = template.getAggroRange();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_seenCreatures = ConcurrentHashMap.newKeySet(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public CreatureContainer getSeenCreatures()
|
public void updateSeenCreatures()
|
||||||
{
|
{
|
||||||
return _seenCreatures;
|
if ((_seenCreatures == null) || _isDead || !isSpawned())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
World.getInstance().forEachVisibleObjectInRange(this, Creature.class, _seenCreatureRange, creature ->
|
||||||
|
{
|
||||||
|
if (_seenCreatures.add(creature))
|
||||||
|
{
|
||||||
|
EventDispatcher.getInstance().notifyEventAsync(new OnCreatureSee(this, creature), this);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeSeenCreature(WorldObject worldObject)
|
||||||
|
{
|
||||||
|
if (_seenCreatures == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_seenCreatures.remove(worldObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
public MoveType getMoveType()
|
public MoveType getMoveType()
|
||||||
|
|||||||
@@ -1832,14 +1832,6 @@ public class Npc extends Creature
|
|||||||
return Rnd.get(100) < Rnd.get(getTemplate().getMinSkillChance(), getTemplate().getMaxSkillChance());
|
return Rnd.get(100) < Rnd.get(getTemplate().getMinSkillChance(), getTemplate().getMaxSkillChance());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialize creature container that looks up for creatures around its owner, and notifies with onCreatureSee upon discovery.
|
|
||||||
*/
|
|
||||||
public void initSeenCreatures()
|
|
||||||
{
|
|
||||||
initSeenCreatures(getTemplate().getAggroRange());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the NpcStringId for name
|
* @return the NpcStringId for name
|
||||||
*/
|
*/
|
||||||
|
|||||||
+14
-3
@@ -962,6 +962,17 @@ public abstract class AbstractScript extends ManagedScript implements IEventTime
|
|||||||
return registerConsumer(callback, EventType.ON_NPC_CREATURE_SEE, ListenerRegisterType.NPC, npcIds);
|
return registerConsumer(callback, EventType.ON_NPC_CREATURE_SEE, ListenerRegisterType.NPC, npcIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides instant callback operation when {@link Npc} sees another creature.
|
||||||
|
* @param callback
|
||||||
|
* @param npcIds
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
protected final List<AbstractEventListener> setNpcCreatureSeeId(Consumer<OnNpcCreatureSee> callback, Collection<Integer> npcIds)
|
||||||
|
{
|
||||||
|
return registerConsumer(callback, EventType.ON_NPC_CREATURE_SEE, ListenerRegisterType.NPC, npcIds);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides instant callback operation when {@link Creature} sees another creature.
|
* Provides instant callback operation when {@link Creature} sees another creature.
|
||||||
* @param callback
|
* @param callback
|
||||||
@@ -974,14 +985,14 @@ public abstract class AbstractScript extends ManagedScript implements IEventTime
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides instant callback operation when {@link Npc} sees another creature.
|
* Provides instant callback operation when {@link Creature} sees another creature.
|
||||||
* @param callback
|
* @param callback
|
||||||
* @param npcIds
|
* @param npcIds
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
protected final List<AbstractEventListener> setNpcCreatureSeeId(Consumer<OnNpcCreatureSee> callback, Collection<Integer> npcIds)
|
protected final List<AbstractEventListener> setCreatureSeeId(Consumer<OnCreatureSee> callback, Collection<Integer> npcIds)
|
||||||
{
|
{
|
||||||
return registerConsumer(callback, EventType.ON_NPC_CREATURE_SEE, ListenerRegisterType.NPC, npcIds);
|
return registerConsumer(callback, EventType.ON_CREATURE_SEE, ListenerRegisterType.NPC, npcIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -254,6 +254,7 @@ public abstract class AbstractAI implements Ctrl
|
|||||||
{
|
{
|
||||||
case EVT_THINK:
|
case EVT_THINK:
|
||||||
{
|
{
|
||||||
|
_actor.updateSeenCreatures();
|
||||||
onEvtThink();
|
onEvtThink();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -325,7 +326,9 @@ public abstract class AbstractAI implements Ctrl
|
|||||||
}
|
}
|
||||||
case EVT_FORGET_OBJECT:
|
case EVT_FORGET_OBJECT:
|
||||||
{
|
{
|
||||||
onEvtForgetObject((WorldObject) arg0);
|
final WorldObject worldObject = (WorldObject) arg0;
|
||||||
|
_actor.removeSeenCreature(worldObject);
|
||||||
|
onEvtForgetObject(worldObject);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case EVT_CANCEL:
|
case EVT_CANCEL:
|
||||||
|
|||||||
@@ -1,106 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of the L2J Mobius project.
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
package org.l2jmobius.gameserver.model;
|
|
||||||
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
|
||||||
import java.util.concurrent.ScheduledFuture;
|
|
||||||
import java.util.function.Predicate;
|
|
||||||
|
|
||||||
import org.l2jmobius.commons.concurrent.ThreadPool;
|
|
||||||
import org.l2jmobius.gameserver.model.actor.Creature;
|
|
||||||
import org.l2jmobius.gameserver.model.events.EventDispatcher;
|
|
||||||
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureSee;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author UnAfraid
|
|
||||||
*/
|
|
||||||
public class CreatureContainer
|
|
||||||
{
|
|
||||||
private final Set<Integer> _seen = ConcurrentHashMap.newKeySet();
|
|
||||||
private final Creature _owner;
|
|
||||||
private final int _range;
|
|
||||||
private ScheduledFuture<?> _task;
|
|
||||||
private Predicate<Creature> _condition = null;
|
|
||||||
|
|
||||||
public CreatureContainer(Creature owner, int range, Predicate<Creature> condition)
|
|
||||||
{
|
|
||||||
_owner = owner;
|
|
||||||
_range = range;
|
|
||||||
_condition = condition;
|
|
||||||
start();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Creature getOwner()
|
|
||||||
{
|
|
||||||
return _owner;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getRange()
|
|
||||||
{
|
|
||||||
return _range;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Starts the task that scans for new creatures
|
|
||||||
*/
|
|
||||||
public void start()
|
|
||||||
{
|
|
||||||
if ((_task == null) || _task.isDone())
|
|
||||||
{
|
|
||||||
_task = ThreadPool.scheduleAtFixedRate(this::update, 1000, 1000);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return {@code false} if the task could not be cancelled, typically because it has already completed normally; {@code true} otherwise
|
|
||||||
*/
|
|
||||||
public boolean stop()
|
|
||||||
{
|
|
||||||
return (_task != null) && !_task.isDone() && _task.cancel(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Resets the creatures container, all previously seen creature will be discarded and next time update method is called will notify for each creature that owner sees!
|
|
||||||
*/
|
|
||||||
public void reset()
|
|
||||||
{
|
|
||||||
_seen.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Scans around the npc and notifies about new creature owner seen
|
|
||||||
*/
|
|
||||||
private void update()
|
|
||||||
{
|
|
||||||
final Set<Integer> verified = new HashSet<>();
|
|
||||||
World.getInstance().forEachVisibleObjectInRange(_owner, Creature.class, _range, creature ->
|
|
||||||
{
|
|
||||||
if ((_condition == null) || _condition.test(creature))
|
|
||||||
{
|
|
||||||
if (_seen.add(creature.getObjectId()))
|
|
||||||
{
|
|
||||||
EventDispatcher.getInstance().notifyEventAsync(new OnCreatureSee(_owner, creature), _owner);
|
|
||||||
}
|
|
||||||
verified.add(creature.getObjectId());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
_seen.retainAll(verified);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -69,7 +69,6 @@ import org.l2jmobius.gameserver.instancemanager.MapRegionManager;
|
|||||||
import org.l2jmobius.gameserver.instancemanager.QuestManager;
|
import org.l2jmobius.gameserver.instancemanager.QuestManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.ZoneManager;
|
import org.l2jmobius.gameserver.instancemanager.ZoneManager;
|
||||||
import org.l2jmobius.gameserver.model.AccessLevel;
|
import org.l2jmobius.gameserver.model.AccessLevel;
|
||||||
import org.l2jmobius.gameserver.model.CreatureContainer;
|
|
||||||
import org.l2jmobius.gameserver.model.EffectList;
|
import org.l2jmobius.gameserver.model.EffectList;
|
||||||
import org.l2jmobius.gameserver.model.Hit;
|
import org.l2jmobius.gameserver.model.Hit;
|
||||||
import org.l2jmobius.gameserver.model.Location;
|
import org.l2jmobius.gameserver.model.Location;
|
||||||
@@ -88,6 +87,7 @@ import org.l2jmobius.gameserver.model.actor.stat.CreatureStat;
|
|||||||
import org.l2jmobius.gameserver.model.actor.status.CreatureStatus;
|
import org.l2jmobius.gameserver.model.actor.status.CreatureStatus;
|
||||||
import org.l2jmobius.gameserver.model.actor.tasks.creature.NotifyAITask;
|
import org.l2jmobius.gameserver.model.actor.tasks.creature.NotifyAITask;
|
||||||
import org.l2jmobius.gameserver.model.actor.templates.CreatureTemplate;
|
import org.l2jmobius.gameserver.model.actor.templates.CreatureTemplate;
|
||||||
|
import org.l2jmobius.gameserver.model.actor.templates.NpcTemplate;
|
||||||
import org.l2jmobius.gameserver.model.actor.transform.Transform;
|
import org.l2jmobius.gameserver.model.actor.transform.Transform;
|
||||||
import org.l2jmobius.gameserver.model.clan.Clan;
|
import org.l2jmobius.gameserver.model.clan.Clan;
|
||||||
import org.l2jmobius.gameserver.model.effects.EffectFlag;
|
import org.l2jmobius.gameserver.model.effects.EffectFlag;
|
||||||
@@ -101,6 +101,7 @@ import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureDamageDealt
|
|||||||
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureDamageReceived;
|
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureDamageReceived;
|
||||||
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureDeath;
|
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureDeath;
|
||||||
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureKilled;
|
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureKilled;
|
||||||
|
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureSee;
|
||||||
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureTeleport;
|
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureTeleport;
|
||||||
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureTeleported;
|
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureTeleported;
|
||||||
import org.l2jmobius.gameserver.model.events.listeners.AbstractEventListener;
|
import org.l2jmobius.gameserver.model.events.listeners.AbstractEventListener;
|
||||||
@@ -271,7 +272,8 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
|
|
||||||
private final Map<Integer, RelationCache> _knownRelations = new ConcurrentHashMap<>();
|
private final Map<Integer, RelationCache> _knownRelations = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
private CreatureContainer _seenCreatures;
|
private Set<Creature> _seenCreatures = null;
|
||||||
|
private int _seenCreatureRange = Config.ALT_PARTY_RANGE;
|
||||||
|
|
||||||
private final Map<StatusUpdateType, Integer> _statusUpdates = new ConcurrentHashMap<>();
|
private final Map<StatusUpdateType, Integer> _statusUpdates = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
@@ -563,13 +565,6 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
{
|
{
|
||||||
_summoner.removeSummonedNpc(getObjectId());
|
_summoner.removeSummonedNpc(getObjectId());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stop on creature see task and clear the data
|
|
||||||
if (_seenCreatures != null)
|
|
||||||
{
|
|
||||||
_seenCreatures.stop();
|
|
||||||
_seenCreatures.reset();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -577,12 +572,6 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
{
|
{
|
||||||
super.onSpawn();
|
super.onSpawn();
|
||||||
revalidateZone(true);
|
revalidateZone(true);
|
||||||
|
|
||||||
// restart task
|
|
||||||
if (_seenCreatures != null)
|
|
||||||
{
|
|
||||||
_seenCreatures.start();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized void onTeleported()
|
public synchronized void onTeleported()
|
||||||
@@ -591,6 +580,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
spawnMe(getX(), getY(), getZ());
|
spawnMe(getX(), getY(), getZ());
|
||||||
setTeleporting(false);
|
setTeleporting(false);
|
||||||
EventDispatcher.getInstance().notifyEventAsync(new OnCreatureTeleported(this), this);
|
EventDispatcher.getInstance().notifyEventAsync(new OnCreatureTeleported(this), this);
|
||||||
@@ -1727,6 +1717,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
{
|
{
|
||||||
getSkillChannelized().abortChannelization();
|
getSkillChannelized().abortChannelization();
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1757,6 +1748,12 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
// Remove all active, passive and option effects, do not broadcast changes.
|
// Remove all active, passive and option effects, do not broadcast changes.
|
||||||
_effectList.stopAllEffectsWithoutExclusions(false, false);
|
_effectList.stopAllEffectsWithoutExclusions(false, false);
|
||||||
|
|
||||||
|
// Forget all seen creatures.
|
||||||
|
if (_seenCreatures != null)
|
||||||
|
{
|
||||||
|
_seenCreatures.clear();
|
||||||
|
}
|
||||||
|
|
||||||
// Cancel the BuffFinishTask related to this creature.
|
// Cancel the BuffFinishTask related to this creature.
|
||||||
cancelBuffFinishTask();
|
cancelBuffFinishTask();
|
||||||
|
|
||||||
@@ -5428,22 +5425,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
return _blockActionsAllowedSkills.containsKey(skill.getId());
|
return _blockActionsAllowedSkills.containsKey(skill.getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public void initSeenCreatures()
|
||||||
* Initialize creature container that looks up for creatures around its owner, and notifies with onCreatureSee upon discovery.
|
|
||||||
* @param range
|
|
||||||
*/
|
|
||||||
public void initSeenCreatures(int range)
|
|
||||||
{
|
|
||||||
initSeenCreatures(range, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialize creature container that looks up for creatures around its owner, and notifies with onCreatureSee upon discovery.<br>
|
|
||||||
* <i>The condition can be null</i>
|
|
||||||
* @param range
|
|
||||||
* @param condition
|
|
||||||
*/
|
|
||||||
public void initSeenCreatures(int range, Predicate<Creature> condition)
|
|
||||||
{
|
{
|
||||||
if (_seenCreatures == null)
|
if (_seenCreatures == null)
|
||||||
{
|
{
|
||||||
@@ -5451,15 +5433,45 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
{
|
{
|
||||||
if (_seenCreatures == null)
|
if (_seenCreatures == null)
|
||||||
{
|
{
|
||||||
_seenCreatures = new CreatureContainer(this, range, condition);
|
if (isNpc())
|
||||||
|
{
|
||||||
|
final NpcTemplate template = ((Npc) this).getTemplate();
|
||||||
|
if ((template != null) && (template.getAggroRange() > 0))
|
||||||
|
{
|
||||||
|
_seenCreatureRange = template.getAggroRange();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_seenCreatures = ConcurrentHashMap.newKeySet(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public CreatureContainer getSeenCreatures()
|
public void updateSeenCreatures()
|
||||||
{
|
{
|
||||||
return _seenCreatures;
|
if ((_seenCreatures == null) || _isDead || !isSpawned())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
World.getInstance().forEachVisibleObjectInRange(this, Creature.class, _seenCreatureRange, creature ->
|
||||||
|
{
|
||||||
|
if (_seenCreatures.add(creature))
|
||||||
|
{
|
||||||
|
EventDispatcher.getInstance().notifyEventAsync(new OnCreatureSee(this, creature), this);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeSeenCreature(WorldObject worldObject)
|
||||||
|
{
|
||||||
|
if (_seenCreatures == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_seenCreatures.remove(worldObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
public MoveType getMoveType()
|
public MoveType getMoveType()
|
||||||
|
|||||||
@@ -1832,14 +1832,6 @@ public class Npc extends Creature
|
|||||||
return Rnd.get(100) < Rnd.get(getTemplate().getMinSkillChance(), getTemplate().getMaxSkillChance());
|
return Rnd.get(100) < Rnd.get(getTemplate().getMinSkillChance(), getTemplate().getMaxSkillChance());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialize creature container that looks up for creatures around its owner, and notifies with onCreatureSee upon discovery.
|
|
||||||
*/
|
|
||||||
public void initSeenCreatures()
|
|
||||||
{
|
|
||||||
initSeenCreatures(getTemplate().getAggroRange());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the NpcStringId for name
|
* @return the NpcStringId for name
|
||||||
*/
|
*/
|
||||||
|
|||||||
+14
-3
@@ -963,6 +963,17 @@ public abstract class AbstractScript extends ManagedScript implements IEventTime
|
|||||||
return registerConsumer(callback, EventType.ON_NPC_CREATURE_SEE, ListenerRegisterType.NPC, npcIds);
|
return registerConsumer(callback, EventType.ON_NPC_CREATURE_SEE, ListenerRegisterType.NPC, npcIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides instant callback operation when {@link Npc} sees another creature.
|
||||||
|
* @param callback
|
||||||
|
* @param npcIds
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
protected final List<AbstractEventListener> setNpcCreatureSeeId(Consumer<OnNpcCreatureSee> callback, Collection<Integer> npcIds)
|
||||||
|
{
|
||||||
|
return registerConsumer(callback, EventType.ON_NPC_CREATURE_SEE, ListenerRegisterType.NPC, npcIds);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides instant callback operation when {@link Creature} sees another creature.
|
* Provides instant callback operation when {@link Creature} sees another creature.
|
||||||
* @param callback
|
* @param callback
|
||||||
@@ -975,14 +986,14 @@ public abstract class AbstractScript extends ManagedScript implements IEventTime
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides instant callback operation when {@link Npc} sees another creature.
|
* Provides instant callback operation when {@link Creature} sees another creature.
|
||||||
* @param callback
|
* @param callback
|
||||||
* @param npcIds
|
* @param npcIds
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
protected final List<AbstractEventListener> setNpcCreatureSeeId(Consumer<OnNpcCreatureSee> callback, Collection<Integer> npcIds)
|
protected final List<AbstractEventListener> setCreatureSeeId(Consumer<OnCreatureSee> callback, Collection<Integer> npcIds)
|
||||||
{
|
{
|
||||||
return registerConsumer(callback, EventType.ON_NPC_CREATURE_SEE, ListenerRegisterType.NPC, npcIds);
|
return registerConsumer(callback, EventType.ON_CREATURE_SEE, ListenerRegisterType.NPC, npcIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -254,6 +254,7 @@ public abstract class AbstractAI implements Ctrl
|
|||||||
{
|
{
|
||||||
case EVT_THINK:
|
case EVT_THINK:
|
||||||
{
|
{
|
||||||
|
_actor.updateSeenCreatures();
|
||||||
onEvtThink();
|
onEvtThink();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -325,7 +326,9 @@ public abstract class AbstractAI implements Ctrl
|
|||||||
}
|
}
|
||||||
case EVT_FORGET_OBJECT:
|
case EVT_FORGET_OBJECT:
|
||||||
{
|
{
|
||||||
onEvtForgetObject((WorldObject) arg0);
|
final WorldObject worldObject = (WorldObject) arg0;
|
||||||
|
_actor.removeSeenCreature(worldObject);
|
||||||
|
onEvtForgetObject(worldObject);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case EVT_CANCEL:
|
case EVT_CANCEL:
|
||||||
|
|||||||
-106
@@ -1,106 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of the L2J Mobius project.
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
package org.l2jmobius.gameserver.model;
|
|
||||||
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
|
||||||
import java.util.concurrent.ScheduledFuture;
|
|
||||||
import java.util.function.Predicate;
|
|
||||||
|
|
||||||
import org.l2jmobius.commons.concurrent.ThreadPool;
|
|
||||||
import org.l2jmobius.gameserver.model.actor.Creature;
|
|
||||||
import org.l2jmobius.gameserver.model.events.EventDispatcher;
|
|
||||||
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureSee;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author UnAfraid
|
|
||||||
*/
|
|
||||||
public class CreatureContainer
|
|
||||||
{
|
|
||||||
private final Set<Integer> _seen = ConcurrentHashMap.newKeySet();
|
|
||||||
private final Creature _owner;
|
|
||||||
private final int _range;
|
|
||||||
private ScheduledFuture<?> _task;
|
|
||||||
private Predicate<Creature> _condition = null;
|
|
||||||
|
|
||||||
public CreatureContainer(Creature owner, int range, Predicate<Creature> condition)
|
|
||||||
{
|
|
||||||
_owner = owner;
|
|
||||||
_range = range;
|
|
||||||
_condition = condition;
|
|
||||||
start();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Creature getOwner()
|
|
||||||
{
|
|
||||||
return _owner;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getRange()
|
|
||||||
{
|
|
||||||
return _range;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Starts the task that scans for new creatures
|
|
||||||
*/
|
|
||||||
public void start()
|
|
||||||
{
|
|
||||||
if ((_task == null) || _task.isDone())
|
|
||||||
{
|
|
||||||
_task = ThreadPool.scheduleAtFixedRate(this::update, 1000, 1000);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return {@code false} if the task could not be cancelled, typically because it has already completed normally; {@code true} otherwise
|
|
||||||
*/
|
|
||||||
public boolean stop()
|
|
||||||
{
|
|
||||||
return (_task != null) && !_task.isDone() && _task.cancel(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Resets the creatures container, all previously seen creature will be discarded and next time update method is called will notify for each creature that owner sees!
|
|
||||||
*/
|
|
||||||
public void reset()
|
|
||||||
{
|
|
||||||
_seen.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Scans around the npc and notifies about new creature owner seen
|
|
||||||
*/
|
|
||||||
private void update()
|
|
||||||
{
|
|
||||||
final Set<Integer> verified = new HashSet<>();
|
|
||||||
World.getInstance().forEachVisibleObjectInRange(_owner, Creature.class, _range, creature ->
|
|
||||||
{
|
|
||||||
if ((_condition == null) || _condition.test(creature))
|
|
||||||
{
|
|
||||||
if (_seen.add(creature.getObjectId()))
|
|
||||||
{
|
|
||||||
EventDispatcher.getInstance().notifyEventAsync(new OnCreatureSee(_owner, creature), _owner);
|
|
||||||
}
|
|
||||||
verified.add(creature.getObjectId());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
_seen.retainAll(verified);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+46
-34
@@ -69,7 +69,6 @@ import org.l2jmobius.gameserver.instancemanager.MapRegionManager;
|
|||||||
import org.l2jmobius.gameserver.instancemanager.QuestManager;
|
import org.l2jmobius.gameserver.instancemanager.QuestManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.ZoneManager;
|
import org.l2jmobius.gameserver.instancemanager.ZoneManager;
|
||||||
import org.l2jmobius.gameserver.model.AccessLevel;
|
import org.l2jmobius.gameserver.model.AccessLevel;
|
||||||
import org.l2jmobius.gameserver.model.CreatureContainer;
|
|
||||||
import org.l2jmobius.gameserver.model.EffectList;
|
import org.l2jmobius.gameserver.model.EffectList;
|
||||||
import org.l2jmobius.gameserver.model.Hit;
|
import org.l2jmobius.gameserver.model.Hit;
|
||||||
import org.l2jmobius.gameserver.model.Location;
|
import org.l2jmobius.gameserver.model.Location;
|
||||||
@@ -88,6 +87,7 @@ import org.l2jmobius.gameserver.model.actor.stat.CreatureStat;
|
|||||||
import org.l2jmobius.gameserver.model.actor.status.CreatureStatus;
|
import org.l2jmobius.gameserver.model.actor.status.CreatureStatus;
|
||||||
import org.l2jmobius.gameserver.model.actor.tasks.creature.NotifyAITask;
|
import org.l2jmobius.gameserver.model.actor.tasks.creature.NotifyAITask;
|
||||||
import org.l2jmobius.gameserver.model.actor.templates.CreatureTemplate;
|
import org.l2jmobius.gameserver.model.actor.templates.CreatureTemplate;
|
||||||
|
import org.l2jmobius.gameserver.model.actor.templates.NpcTemplate;
|
||||||
import org.l2jmobius.gameserver.model.actor.transform.Transform;
|
import org.l2jmobius.gameserver.model.actor.transform.Transform;
|
||||||
import org.l2jmobius.gameserver.model.clan.Clan;
|
import org.l2jmobius.gameserver.model.clan.Clan;
|
||||||
import org.l2jmobius.gameserver.model.effects.EffectFlag;
|
import org.l2jmobius.gameserver.model.effects.EffectFlag;
|
||||||
@@ -101,6 +101,7 @@ import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureDamageDealt
|
|||||||
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureDamageReceived;
|
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureDamageReceived;
|
||||||
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureDeath;
|
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureDeath;
|
||||||
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureKilled;
|
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureKilled;
|
||||||
|
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureSee;
|
||||||
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureTeleport;
|
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureTeleport;
|
||||||
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureTeleported;
|
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureTeleported;
|
||||||
import org.l2jmobius.gameserver.model.events.listeners.AbstractEventListener;
|
import org.l2jmobius.gameserver.model.events.listeners.AbstractEventListener;
|
||||||
@@ -271,7 +272,8 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
|
|
||||||
private final Map<Integer, RelationCache> _knownRelations = new ConcurrentHashMap<>();
|
private final Map<Integer, RelationCache> _knownRelations = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
private CreatureContainer _seenCreatures;
|
private Set<Creature> _seenCreatures = null;
|
||||||
|
private int _seenCreatureRange = Config.ALT_PARTY_RANGE;
|
||||||
|
|
||||||
private final Map<StatusUpdateType, Integer> _statusUpdates = new ConcurrentHashMap<>();
|
private final Map<StatusUpdateType, Integer> _statusUpdates = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
@@ -563,13 +565,6 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
{
|
{
|
||||||
_summoner.removeSummonedNpc(getObjectId());
|
_summoner.removeSummonedNpc(getObjectId());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stop on creature see task and clear the data
|
|
||||||
if (_seenCreatures != null)
|
|
||||||
{
|
|
||||||
_seenCreatures.stop();
|
|
||||||
_seenCreatures.reset();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -577,12 +572,6 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
{
|
{
|
||||||
super.onSpawn();
|
super.onSpawn();
|
||||||
revalidateZone(true);
|
revalidateZone(true);
|
||||||
|
|
||||||
// restart task
|
|
||||||
if (_seenCreatures != null)
|
|
||||||
{
|
|
||||||
_seenCreatures.start();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized void onTeleported()
|
public synchronized void onTeleported()
|
||||||
@@ -591,6 +580,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
spawnMe(getX(), getY(), getZ());
|
spawnMe(getX(), getY(), getZ());
|
||||||
setTeleporting(false);
|
setTeleporting(false);
|
||||||
EventDispatcher.getInstance().notifyEventAsync(new OnCreatureTeleported(this), this);
|
EventDispatcher.getInstance().notifyEventAsync(new OnCreatureTeleported(this), this);
|
||||||
@@ -1727,6 +1717,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
{
|
{
|
||||||
getSkillChannelized().abortChannelization();
|
getSkillChannelized().abortChannelization();
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1757,6 +1748,12 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
// Remove all active, passive and option effects, do not broadcast changes.
|
// Remove all active, passive and option effects, do not broadcast changes.
|
||||||
_effectList.stopAllEffectsWithoutExclusions(false, false);
|
_effectList.stopAllEffectsWithoutExclusions(false, false);
|
||||||
|
|
||||||
|
// Forget all seen creatures.
|
||||||
|
if (_seenCreatures != null)
|
||||||
|
{
|
||||||
|
_seenCreatures.clear();
|
||||||
|
}
|
||||||
|
|
||||||
// Cancel the BuffFinishTask related to this creature.
|
// Cancel the BuffFinishTask related to this creature.
|
||||||
cancelBuffFinishTask();
|
cancelBuffFinishTask();
|
||||||
|
|
||||||
@@ -5428,22 +5425,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
return _blockActionsAllowedSkills.containsKey(skill.getId());
|
return _blockActionsAllowedSkills.containsKey(skill.getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public void initSeenCreatures()
|
||||||
* Initialize creature container that looks up for creatures around its owner, and notifies with onCreatureSee upon discovery.
|
|
||||||
* @param range
|
|
||||||
*/
|
|
||||||
public void initSeenCreatures(int range)
|
|
||||||
{
|
|
||||||
initSeenCreatures(range, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialize creature container that looks up for creatures around its owner, and notifies with onCreatureSee upon discovery.<br>
|
|
||||||
* <i>The condition can be null</i>
|
|
||||||
* @param range
|
|
||||||
* @param condition
|
|
||||||
*/
|
|
||||||
public void initSeenCreatures(int range, Predicate<Creature> condition)
|
|
||||||
{
|
{
|
||||||
if (_seenCreatures == null)
|
if (_seenCreatures == null)
|
||||||
{
|
{
|
||||||
@@ -5451,15 +5433,45 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
{
|
{
|
||||||
if (_seenCreatures == null)
|
if (_seenCreatures == null)
|
||||||
{
|
{
|
||||||
_seenCreatures = new CreatureContainer(this, range, condition);
|
if (isNpc())
|
||||||
|
{
|
||||||
|
final NpcTemplate template = ((Npc) this).getTemplate();
|
||||||
|
if ((template != null) && (template.getAggroRange() > 0))
|
||||||
|
{
|
||||||
|
_seenCreatureRange = template.getAggroRange();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_seenCreatures = ConcurrentHashMap.newKeySet(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public CreatureContainer getSeenCreatures()
|
public void updateSeenCreatures()
|
||||||
{
|
{
|
||||||
return _seenCreatures;
|
if ((_seenCreatures == null) || _isDead || !isSpawned())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
World.getInstance().forEachVisibleObjectInRange(this, Creature.class, _seenCreatureRange, creature ->
|
||||||
|
{
|
||||||
|
if (_seenCreatures.add(creature))
|
||||||
|
{
|
||||||
|
EventDispatcher.getInstance().notifyEventAsync(new OnCreatureSee(this, creature), this);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeSeenCreature(WorldObject worldObject)
|
||||||
|
{
|
||||||
|
if (_seenCreatures == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_seenCreatures.remove(worldObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
public MoveType getMoveType()
|
public MoveType getMoveType()
|
||||||
|
|||||||
@@ -1832,14 +1832,6 @@ public class Npc extends Creature
|
|||||||
return Rnd.get(100) < Rnd.get(getTemplate().getMinSkillChance(), getTemplate().getMaxSkillChance());
|
return Rnd.get(100) < Rnd.get(getTemplate().getMinSkillChance(), getTemplate().getMaxSkillChance());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialize creature container that looks up for creatures around its owner, and notifies with onCreatureSee upon discovery.
|
|
||||||
*/
|
|
||||||
public void initSeenCreatures()
|
|
||||||
{
|
|
||||||
initSeenCreatures(getTemplate().getAggroRange());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the NpcStringId for name
|
* @return the NpcStringId for name
|
||||||
*/
|
*/
|
||||||
|
|||||||
+14
-3
@@ -963,6 +963,17 @@ public abstract class AbstractScript extends ManagedScript implements IEventTime
|
|||||||
return registerConsumer(callback, EventType.ON_NPC_CREATURE_SEE, ListenerRegisterType.NPC, npcIds);
|
return registerConsumer(callback, EventType.ON_NPC_CREATURE_SEE, ListenerRegisterType.NPC, npcIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides instant callback operation when {@link Npc} sees another creature.
|
||||||
|
* @param callback
|
||||||
|
* @param npcIds
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
protected final List<AbstractEventListener> setNpcCreatureSeeId(Consumer<OnNpcCreatureSee> callback, Collection<Integer> npcIds)
|
||||||
|
{
|
||||||
|
return registerConsumer(callback, EventType.ON_NPC_CREATURE_SEE, ListenerRegisterType.NPC, npcIds);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides instant callback operation when {@link Creature} sees another creature.
|
* Provides instant callback operation when {@link Creature} sees another creature.
|
||||||
* @param callback
|
* @param callback
|
||||||
@@ -975,14 +986,14 @@ public abstract class AbstractScript extends ManagedScript implements IEventTime
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides instant callback operation when {@link Npc} sees another creature.
|
* Provides instant callback operation when {@link Creature} sees another creature.
|
||||||
* @param callback
|
* @param callback
|
||||||
* @param npcIds
|
* @param npcIds
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
protected final List<AbstractEventListener> setNpcCreatureSeeId(Consumer<OnNpcCreatureSee> callback, Collection<Integer> npcIds)
|
protected final List<AbstractEventListener> setCreatureSeeId(Consumer<OnCreatureSee> callback, Collection<Integer> npcIds)
|
||||||
{
|
{
|
||||||
return registerConsumer(callback, EventType.ON_NPC_CREATURE_SEE, ListenerRegisterType.NPC, npcIds);
|
return registerConsumer(callback, EventType.ON_CREATURE_SEE, ListenerRegisterType.NPC, npcIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -254,6 +254,7 @@ public abstract class AbstractAI implements Ctrl
|
|||||||
{
|
{
|
||||||
case EVT_THINK:
|
case EVT_THINK:
|
||||||
{
|
{
|
||||||
|
_actor.updateSeenCreatures();
|
||||||
onEvtThink();
|
onEvtThink();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -325,7 +326,9 @@ public abstract class AbstractAI implements Ctrl
|
|||||||
}
|
}
|
||||||
case EVT_FORGET_OBJECT:
|
case EVT_FORGET_OBJECT:
|
||||||
{
|
{
|
||||||
onEvtForgetObject((WorldObject) arg0);
|
final WorldObject worldObject = (WorldObject) arg0;
|
||||||
|
_actor.removeSeenCreature(worldObject);
|
||||||
|
onEvtForgetObject(worldObject);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case EVT_CANCEL:
|
case EVT_CANCEL:
|
||||||
|
|||||||
@@ -1,106 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of the L2J Mobius project.
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
package org.l2jmobius.gameserver.model;
|
|
||||||
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
|
||||||
import java.util.concurrent.ScheduledFuture;
|
|
||||||
import java.util.function.Predicate;
|
|
||||||
|
|
||||||
import org.l2jmobius.commons.concurrent.ThreadPool;
|
|
||||||
import org.l2jmobius.gameserver.model.actor.Creature;
|
|
||||||
import org.l2jmobius.gameserver.model.events.EventDispatcher;
|
|
||||||
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureSee;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author UnAfraid
|
|
||||||
*/
|
|
||||||
public class CreatureContainer
|
|
||||||
{
|
|
||||||
private final Set<Integer> _seen = ConcurrentHashMap.newKeySet();
|
|
||||||
private final Creature _owner;
|
|
||||||
private final int _range;
|
|
||||||
private ScheduledFuture<?> _task;
|
|
||||||
private Predicate<Creature> _condition = null;
|
|
||||||
|
|
||||||
public CreatureContainer(Creature owner, int range, Predicate<Creature> condition)
|
|
||||||
{
|
|
||||||
_owner = owner;
|
|
||||||
_range = range;
|
|
||||||
_condition = condition;
|
|
||||||
start();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Creature getOwner()
|
|
||||||
{
|
|
||||||
return _owner;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getRange()
|
|
||||||
{
|
|
||||||
return _range;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Starts the task that scans for new creatures
|
|
||||||
*/
|
|
||||||
public void start()
|
|
||||||
{
|
|
||||||
if ((_task == null) || _task.isDone())
|
|
||||||
{
|
|
||||||
_task = ThreadPool.scheduleAtFixedRate(this::update, 1000, 1000);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return {@code false} if the task could not be cancelled, typically because it has already completed normally; {@code true} otherwise
|
|
||||||
*/
|
|
||||||
public boolean stop()
|
|
||||||
{
|
|
||||||
return (_task != null) && !_task.isDone() && _task.cancel(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Resets the creatures container, all previously seen creature will be discarded and next time update method is called will notify for each creature that owner sees!
|
|
||||||
*/
|
|
||||||
public void reset()
|
|
||||||
{
|
|
||||||
_seen.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Scans around the npc and notifies about new creature owner seen
|
|
||||||
*/
|
|
||||||
private void update()
|
|
||||||
{
|
|
||||||
final Set<Integer> verified = new HashSet<>();
|
|
||||||
World.getInstance().forEachVisibleObjectInRange(_owner, Creature.class, _range, creature ->
|
|
||||||
{
|
|
||||||
if ((_condition == null) || _condition.test(creature))
|
|
||||||
{
|
|
||||||
if (_seen.add(creature.getObjectId()))
|
|
||||||
{
|
|
||||||
EventDispatcher.getInstance().notifyEventAsync(new OnCreatureSee(_owner, creature), _owner);
|
|
||||||
}
|
|
||||||
verified.add(creature.getObjectId());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
_seen.retainAll(verified);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -69,7 +69,6 @@ import org.l2jmobius.gameserver.instancemanager.MapRegionManager;
|
|||||||
import org.l2jmobius.gameserver.instancemanager.QuestManager;
|
import org.l2jmobius.gameserver.instancemanager.QuestManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.ZoneManager;
|
import org.l2jmobius.gameserver.instancemanager.ZoneManager;
|
||||||
import org.l2jmobius.gameserver.model.AccessLevel;
|
import org.l2jmobius.gameserver.model.AccessLevel;
|
||||||
import org.l2jmobius.gameserver.model.CreatureContainer;
|
|
||||||
import org.l2jmobius.gameserver.model.EffectList;
|
import org.l2jmobius.gameserver.model.EffectList;
|
||||||
import org.l2jmobius.gameserver.model.Hit;
|
import org.l2jmobius.gameserver.model.Hit;
|
||||||
import org.l2jmobius.gameserver.model.Location;
|
import org.l2jmobius.gameserver.model.Location;
|
||||||
@@ -88,6 +87,7 @@ import org.l2jmobius.gameserver.model.actor.stat.CreatureStat;
|
|||||||
import org.l2jmobius.gameserver.model.actor.status.CreatureStatus;
|
import org.l2jmobius.gameserver.model.actor.status.CreatureStatus;
|
||||||
import org.l2jmobius.gameserver.model.actor.tasks.creature.NotifyAITask;
|
import org.l2jmobius.gameserver.model.actor.tasks.creature.NotifyAITask;
|
||||||
import org.l2jmobius.gameserver.model.actor.templates.CreatureTemplate;
|
import org.l2jmobius.gameserver.model.actor.templates.CreatureTemplate;
|
||||||
|
import org.l2jmobius.gameserver.model.actor.templates.NpcTemplate;
|
||||||
import org.l2jmobius.gameserver.model.actor.transform.Transform;
|
import org.l2jmobius.gameserver.model.actor.transform.Transform;
|
||||||
import org.l2jmobius.gameserver.model.clan.Clan;
|
import org.l2jmobius.gameserver.model.clan.Clan;
|
||||||
import org.l2jmobius.gameserver.model.effects.EffectFlag;
|
import org.l2jmobius.gameserver.model.effects.EffectFlag;
|
||||||
@@ -101,6 +101,7 @@ import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureDamageDealt
|
|||||||
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureDamageReceived;
|
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureDamageReceived;
|
||||||
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureDeath;
|
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureDeath;
|
||||||
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureKilled;
|
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureKilled;
|
||||||
|
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureSee;
|
||||||
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureTeleport;
|
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureTeleport;
|
||||||
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureTeleported;
|
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureTeleported;
|
||||||
import org.l2jmobius.gameserver.model.events.listeners.AbstractEventListener;
|
import org.l2jmobius.gameserver.model.events.listeners.AbstractEventListener;
|
||||||
@@ -271,7 +272,8 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
|
|
||||||
private final Map<Integer, RelationCache> _knownRelations = new ConcurrentHashMap<>();
|
private final Map<Integer, RelationCache> _knownRelations = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
private CreatureContainer _seenCreatures;
|
private Set<Creature> _seenCreatures = null;
|
||||||
|
private int _seenCreatureRange = Config.ALT_PARTY_RANGE;
|
||||||
|
|
||||||
private final Map<StatusUpdateType, Integer> _statusUpdates = new ConcurrentHashMap<>();
|
private final Map<StatusUpdateType, Integer> _statusUpdates = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
@@ -563,13 +565,6 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
{
|
{
|
||||||
_summoner.removeSummonedNpc(getObjectId());
|
_summoner.removeSummonedNpc(getObjectId());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stop on creature see task and clear the data
|
|
||||||
if (_seenCreatures != null)
|
|
||||||
{
|
|
||||||
_seenCreatures.stop();
|
|
||||||
_seenCreatures.reset();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -577,12 +572,6 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
{
|
{
|
||||||
super.onSpawn();
|
super.onSpawn();
|
||||||
revalidateZone(true);
|
revalidateZone(true);
|
||||||
|
|
||||||
// restart task
|
|
||||||
if (_seenCreatures != null)
|
|
||||||
{
|
|
||||||
_seenCreatures.start();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized void onTeleported()
|
public synchronized void onTeleported()
|
||||||
@@ -591,6 +580,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
spawnMe(getX(), getY(), getZ());
|
spawnMe(getX(), getY(), getZ());
|
||||||
setTeleporting(false);
|
setTeleporting(false);
|
||||||
EventDispatcher.getInstance().notifyEventAsync(new OnCreatureTeleported(this), this);
|
EventDispatcher.getInstance().notifyEventAsync(new OnCreatureTeleported(this), this);
|
||||||
@@ -1727,6 +1717,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
{
|
{
|
||||||
getSkillChannelized().abortChannelization();
|
getSkillChannelized().abortChannelization();
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1757,6 +1748,12 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
// Remove all active, passive and option effects, do not broadcast changes.
|
// Remove all active, passive and option effects, do not broadcast changes.
|
||||||
_effectList.stopAllEffectsWithoutExclusions(false, false);
|
_effectList.stopAllEffectsWithoutExclusions(false, false);
|
||||||
|
|
||||||
|
// Forget all seen creatures.
|
||||||
|
if (_seenCreatures != null)
|
||||||
|
{
|
||||||
|
_seenCreatures.clear();
|
||||||
|
}
|
||||||
|
|
||||||
// Cancel the BuffFinishTask related to this creature.
|
// Cancel the BuffFinishTask related to this creature.
|
||||||
cancelBuffFinishTask();
|
cancelBuffFinishTask();
|
||||||
|
|
||||||
@@ -5437,22 +5434,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
return _blockActionsAllowedSkills.containsKey(skill.getId());
|
return _blockActionsAllowedSkills.containsKey(skill.getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public void initSeenCreatures()
|
||||||
* Initialize creature container that looks up for creatures around its owner, and notifies with onCreatureSee upon discovery.
|
|
||||||
* @param range
|
|
||||||
*/
|
|
||||||
public void initSeenCreatures(int range)
|
|
||||||
{
|
|
||||||
initSeenCreatures(range, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialize creature container that looks up for creatures around its owner, and notifies with onCreatureSee upon discovery.<br>
|
|
||||||
* <i>The condition can be null</i>
|
|
||||||
* @param range
|
|
||||||
* @param condition
|
|
||||||
*/
|
|
||||||
public void initSeenCreatures(int range, Predicate<Creature> condition)
|
|
||||||
{
|
{
|
||||||
if (_seenCreatures == null)
|
if (_seenCreatures == null)
|
||||||
{
|
{
|
||||||
@@ -5460,15 +5442,45 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
{
|
{
|
||||||
if (_seenCreatures == null)
|
if (_seenCreatures == null)
|
||||||
{
|
{
|
||||||
_seenCreatures = new CreatureContainer(this, range, condition);
|
if (isNpc())
|
||||||
|
{
|
||||||
|
final NpcTemplate template = ((Npc) this).getTemplate();
|
||||||
|
if ((template != null) && (template.getAggroRange() > 0))
|
||||||
|
{
|
||||||
|
_seenCreatureRange = template.getAggroRange();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_seenCreatures = ConcurrentHashMap.newKeySet(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public CreatureContainer getSeenCreatures()
|
public void updateSeenCreatures()
|
||||||
{
|
{
|
||||||
return _seenCreatures;
|
if ((_seenCreatures == null) || _isDead || !isSpawned())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
World.getInstance().forEachVisibleObjectInRange(this, Creature.class, _seenCreatureRange, creature ->
|
||||||
|
{
|
||||||
|
if (_seenCreatures.add(creature))
|
||||||
|
{
|
||||||
|
EventDispatcher.getInstance().notifyEventAsync(new OnCreatureSee(this, creature), this);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeSeenCreature(WorldObject worldObject)
|
||||||
|
{
|
||||||
|
if (_seenCreatures == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_seenCreatures.remove(worldObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
public MoveType getMoveType()
|
public MoveType getMoveType()
|
||||||
|
|||||||
@@ -1832,14 +1832,6 @@ public class Npc extends Creature
|
|||||||
return Rnd.get(100) < Rnd.get(getTemplate().getMinSkillChance(), getTemplate().getMaxSkillChance());
|
return Rnd.get(100) < Rnd.get(getTemplate().getMinSkillChance(), getTemplate().getMaxSkillChance());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialize creature container that looks up for creatures around its owner, and notifies with onCreatureSee upon discovery.
|
|
||||||
*/
|
|
||||||
public void initSeenCreatures()
|
|
||||||
{
|
|
||||||
initSeenCreatures(getTemplate().getAggroRange());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the NpcStringId for name
|
* @return the NpcStringId for name
|
||||||
*/
|
*/
|
||||||
|
|||||||
+14
-3
@@ -963,6 +963,17 @@ public abstract class AbstractScript extends ManagedScript implements IEventTime
|
|||||||
return registerConsumer(callback, EventType.ON_NPC_CREATURE_SEE, ListenerRegisterType.NPC, npcIds);
|
return registerConsumer(callback, EventType.ON_NPC_CREATURE_SEE, ListenerRegisterType.NPC, npcIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides instant callback operation when {@link Npc} sees another creature.
|
||||||
|
* @param callback
|
||||||
|
* @param npcIds
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
protected final List<AbstractEventListener> setNpcCreatureSeeId(Consumer<OnNpcCreatureSee> callback, Collection<Integer> npcIds)
|
||||||
|
{
|
||||||
|
return registerConsumer(callback, EventType.ON_NPC_CREATURE_SEE, ListenerRegisterType.NPC, npcIds);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides instant callback operation when {@link Creature} sees another creature.
|
* Provides instant callback operation when {@link Creature} sees another creature.
|
||||||
* @param callback
|
* @param callback
|
||||||
@@ -975,14 +986,14 @@ public abstract class AbstractScript extends ManagedScript implements IEventTime
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides instant callback operation when {@link Npc} sees another creature.
|
* Provides instant callback operation when {@link Creature} sees another creature.
|
||||||
* @param callback
|
* @param callback
|
||||||
* @param npcIds
|
* @param npcIds
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
protected final List<AbstractEventListener> setNpcCreatureSeeId(Consumer<OnNpcCreatureSee> callback, Collection<Integer> npcIds)
|
protected final List<AbstractEventListener> setCreatureSeeId(Consumer<OnCreatureSee> callback, Collection<Integer> npcIds)
|
||||||
{
|
{
|
||||||
return registerConsumer(callback, EventType.ON_NPC_CREATURE_SEE, ListenerRegisterType.NPC, npcIds);
|
return registerConsumer(callback, EventType.ON_CREATURE_SEE, ListenerRegisterType.NPC, npcIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -254,6 +254,7 @@ public abstract class AbstractAI implements Ctrl
|
|||||||
{
|
{
|
||||||
case EVT_THINK:
|
case EVT_THINK:
|
||||||
{
|
{
|
||||||
|
_actor.updateSeenCreatures();
|
||||||
onEvtThink();
|
onEvtThink();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -325,7 +326,9 @@ public abstract class AbstractAI implements Ctrl
|
|||||||
}
|
}
|
||||||
case EVT_FORGET_OBJECT:
|
case EVT_FORGET_OBJECT:
|
||||||
{
|
{
|
||||||
onEvtForgetObject((WorldObject) arg0);
|
final WorldObject worldObject = (WorldObject) arg0;
|
||||||
|
_actor.removeSeenCreature(worldObject);
|
||||||
|
onEvtForgetObject(worldObject);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case EVT_CANCEL:
|
case EVT_CANCEL:
|
||||||
|
|||||||
@@ -1,106 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of the L2J Mobius project.
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
package org.l2jmobius.gameserver.model;
|
|
||||||
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
|
||||||
import java.util.concurrent.ScheduledFuture;
|
|
||||||
import java.util.function.Predicate;
|
|
||||||
|
|
||||||
import org.l2jmobius.commons.concurrent.ThreadPool;
|
|
||||||
import org.l2jmobius.gameserver.model.actor.Creature;
|
|
||||||
import org.l2jmobius.gameserver.model.events.EventDispatcher;
|
|
||||||
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureSee;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author UnAfraid
|
|
||||||
*/
|
|
||||||
public class CreatureContainer
|
|
||||||
{
|
|
||||||
private final Set<Integer> _seen = ConcurrentHashMap.newKeySet();
|
|
||||||
private final Creature _owner;
|
|
||||||
private final int _range;
|
|
||||||
private ScheduledFuture<?> _task;
|
|
||||||
private Predicate<Creature> _condition = null;
|
|
||||||
|
|
||||||
public CreatureContainer(Creature owner, int range, Predicate<Creature> condition)
|
|
||||||
{
|
|
||||||
_owner = owner;
|
|
||||||
_range = range;
|
|
||||||
_condition = condition;
|
|
||||||
start();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Creature getOwner()
|
|
||||||
{
|
|
||||||
return _owner;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getRange()
|
|
||||||
{
|
|
||||||
return _range;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Starts the task that scans for new creatures
|
|
||||||
*/
|
|
||||||
public void start()
|
|
||||||
{
|
|
||||||
if ((_task == null) || _task.isDone())
|
|
||||||
{
|
|
||||||
_task = ThreadPool.scheduleAtFixedRate(this::update, 1000, 1000);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return {@code false} if the task could not be cancelled, typically because it has already completed normally; {@code true} otherwise
|
|
||||||
*/
|
|
||||||
public boolean stop()
|
|
||||||
{
|
|
||||||
return (_task != null) && !_task.isDone() && _task.cancel(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Resets the creatures container, all previously seen creature will be discarded and next time update method is called will notify for each creature that owner sees!
|
|
||||||
*/
|
|
||||||
public void reset()
|
|
||||||
{
|
|
||||||
_seen.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Scans around the npc and notifies about new creature owner seen
|
|
||||||
*/
|
|
||||||
private void update()
|
|
||||||
{
|
|
||||||
final Set<Integer> verified = new HashSet<>();
|
|
||||||
World.getInstance().forEachVisibleObjectInRange(_owner, Creature.class, _range, creature ->
|
|
||||||
{
|
|
||||||
if ((_condition == null) || _condition.test(creature))
|
|
||||||
{
|
|
||||||
if (_seen.add(creature.getObjectId()))
|
|
||||||
{
|
|
||||||
EventDispatcher.getInstance().notifyEventAsync(new OnCreatureSee(_owner, creature), _owner);
|
|
||||||
}
|
|
||||||
verified.add(creature.getObjectId());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
_seen.retainAll(verified);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -69,7 +69,6 @@ import org.l2jmobius.gameserver.instancemanager.MapRegionManager;
|
|||||||
import org.l2jmobius.gameserver.instancemanager.QuestManager;
|
import org.l2jmobius.gameserver.instancemanager.QuestManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.ZoneManager;
|
import org.l2jmobius.gameserver.instancemanager.ZoneManager;
|
||||||
import org.l2jmobius.gameserver.model.AccessLevel;
|
import org.l2jmobius.gameserver.model.AccessLevel;
|
||||||
import org.l2jmobius.gameserver.model.CreatureContainer;
|
|
||||||
import org.l2jmobius.gameserver.model.EffectList;
|
import org.l2jmobius.gameserver.model.EffectList;
|
||||||
import org.l2jmobius.gameserver.model.Hit;
|
import org.l2jmobius.gameserver.model.Hit;
|
||||||
import org.l2jmobius.gameserver.model.Location;
|
import org.l2jmobius.gameserver.model.Location;
|
||||||
@@ -88,6 +87,7 @@ import org.l2jmobius.gameserver.model.actor.stat.CreatureStat;
|
|||||||
import org.l2jmobius.gameserver.model.actor.status.CreatureStatus;
|
import org.l2jmobius.gameserver.model.actor.status.CreatureStatus;
|
||||||
import org.l2jmobius.gameserver.model.actor.tasks.creature.NotifyAITask;
|
import org.l2jmobius.gameserver.model.actor.tasks.creature.NotifyAITask;
|
||||||
import org.l2jmobius.gameserver.model.actor.templates.CreatureTemplate;
|
import org.l2jmobius.gameserver.model.actor.templates.CreatureTemplate;
|
||||||
|
import org.l2jmobius.gameserver.model.actor.templates.NpcTemplate;
|
||||||
import org.l2jmobius.gameserver.model.actor.transform.Transform;
|
import org.l2jmobius.gameserver.model.actor.transform.Transform;
|
||||||
import org.l2jmobius.gameserver.model.clan.Clan;
|
import org.l2jmobius.gameserver.model.clan.Clan;
|
||||||
import org.l2jmobius.gameserver.model.effects.EffectFlag;
|
import org.l2jmobius.gameserver.model.effects.EffectFlag;
|
||||||
@@ -101,6 +101,7 @@ import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureDamageDealt
|
|||||||
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureDamageReceived;
|
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureDamageReceived;
|
||||||
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureDeath;
|
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureDeath;
|
||||||
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureKilled;
|
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureKilled;
|
||||||
|
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureSee;
|
||||||
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureTeleport;
|
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureTeleport;
|
||||||
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureTeleported;
|
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureTeleported;
|
||||||
import org.l2jmobius.gameserver.model.events.listeners.AbstractEventListener;
|
import org.l2jmobius.gameserver.model.events.listeners.AbstractEventListener;
|
||||||
@@ -271,7 +272,8 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
|
|
||||||
private final Map<Integer, RelationCache> _knownRelations = new ConcurrentHashMap<>();
|
private final Map<Integer, RelationCache> _knownRelations = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
private CreatureContainer _seenCreatures;
|
private Set<Creature> _seenCreatures = null;
|
||||||
|
private int _seenCreatureRange = Config.ALT_PARTY_RANGE;
|
||||||
|
|
||||||
private final Map<StatusUpdateType, Integer> _statusUpdates = new ConcurrentHashMap<>();
|
private final Map<StatusUpdateType, Integer> _statusUpdates = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
@@ -563,13 +565,6 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
{
|
{
|
||||||
_summoner.removeSummonedNpc(getObjectId());
|
_summoner.removeSummonedNpc(getObjectId());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stop on creature see task and clear the data
|
|
||||||
if (_seenCreatures != null)
|
|
||||||
{
|
|
||||||
_seenCreatures.stop();
|
|
||||||
_seenCreatures.reset();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -577,12 +572,6 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
{
|
{
|
||||||
super.onSpawn();
|
super.onSpawn();
|
||||||
revalidateZone(true);
|
revalidateZone(true);
|
||||||
|
|
||||||
// restart task
|
|
||||||
if (_seenCreatures != null)
|
|
||||||
{
|
|
||||||
_seenCreatures.start();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized void onTeleported()
|
public synchronized void onTeleported()
|
||||||
@@ -591,6 +580,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
spawnMe(getX(), getY(), getZ());
|
spawnMe(getX(), getY(), getZ());
|
||||||
setTeleporting(false);
|
setTeleporting(false);
|
||||||
EventDispatcher.getInstance().notifyEventAsync(new OnCreatureTeleported(this), this);
|
EventDispatcher.getInstance().notifyEventAsync(new OnCreatureTeleported(this), this);
|
||||||
@@ -1727,6 +1717,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
{
|
{
|
||||||
getSkillChannelized().abortChannelization();
|
getSkillChannelized().abortChannelization();
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1757,6 +1748,12 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
// Remove all active, passive and option effects, do not broadcast changes.
|
// Remove all active, passive and option effects, do not broadcast changes.
|
||||||
_effectList.stopAllEffectsWithoutExclusions(false, false);
|
_effectList.stopAllEffectsWithoutExclusions(false, false);
|
||||||
|
|
||||||
|
// Forget all seen creatures.
|
||||||
|
if (_seenCreatures != null)
|
||||||
|
{
|
||||||
|
_seenCreatures.clear();
|
||||||
|
}
|
||||||
|
|
||||||
// Cancel the BuffFinishTask related to this creature.
|
// Cancel the BuffFinishTask related to this creature.
|
||||||
cancelBuffFinishTask();
|
cancelBuffFinishTask();
|
||||||
|
|
||||||
@@ -5437,22 +5434,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
return _blockActionsAllowedSkills.containsKey(skill.getId());
|
return _blockActionsAllowedSkills.containsKey(skill.getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public void initSeenCreatures()
|
||||||
* Initialize creature container that looks up for creatures around its owner, and notifies with onCreatureSee upon discovery.
|
|
||||||
* @param range
|
|
||||||
*/
|
|
||||||
public void initSeenCreatures(int range)
|
|
||||||
{
|
|
||||||
initSeenCreatures(range, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialize creature container that looks up for creatures around its owner, and notifies with onCreatureSee upon discovery.<br>
|
|
||||||
* <i>The condition can be null</i>
|
|
||||||
* @param range
|
|
||||||
* @param condition
|
|
||||||
*/
|
|
||||||
public void initSeenCreatures(int range, Predicate<Creature> condition)
|
|
||||||
{
|
{
|
||||||
if (_seenCreatures == null)
|
if (_seenCreatures == null)
|
||||||
{
|
{
|
||||||
@@ -5460,15 +5442,45 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
{
|
{
|
||||||
if (_seenCreatures == null)
|
if (_seenCreatures == null)
|
||||||
{
|
{
|
||||||
_seenCreatures = new CreatureContainer(this, range, condition);
|
if (isNpc())
|
||||||
|
{
|
||||||
|
final NpcTemplate template = ((Npc) this).getTemplate();
|
||||||
|
if ((template != null) && (template.getAggroRange() > 0))
|
||||||
|
{
|
||||||
|
_seenCreatureRange = template.getAggroRange();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_seenCreatures = ConcurrentHashMap.newKeySet(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public CreatureContainer getSeenCreatures()
|
public void updateSeenCreatures()
|
||||||
{
|
{
|
||||||
return _seenCreatures;
|
if ((_seenCreatures == null) || _isDead || !isSpawned())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
World.getInstance().forEachVisibleObjectInRange(this, Creature.class, _seenCreatureRange, creature ->
|
||||||
|
{
|
||||||
|
if (_seenCreatures.add(creature))
|
||||||
|
{
|
||||||
|
EventDispatcher.getInstance().notifyEventAsync(new OnCreatureSee(this, creature), this);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeSeenCreature(WorldObject worldObject)
|
||||||
|
{
|
||||||
|
if (_seenCreatures == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_seenCreatures.remove(worldObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
public MoveType getMoveType()
|
public MoveType getMoveType()
|
||||||
|
|||||||
@@ -1832,14 +1832,6 @@ public class Npc extends Creature
|
|||||||
return Rnd.get(100) < Rnd.get(getTemplate().getMinSkillChance(), getTemplate().getMaxSkillChance());
|
return Rnd.get(100) < Rnd.get(getTemplate().getMinSkillChance(), getTemplate().getMaxSkillChance());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialize creature container that looks up for creatures around its owner, and notifies with onCreatureSee upon discovery.
|
|
||||||
*/
|
|
||||||
public void initSeenCreatures()
|
|
||||||
{
|
|
||||||
initSeenCreatures(getTemplate().getAggroRange());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the NpcStringId for name
|
* @return the NpcStringId for name
|
||||||
*/
|
*/
|
||||||
|
|||||||
+14
-3
@@ -963,6 +963,17 @@ public abstract class AbstractScript extends ManagedScript implements IEventTime
|
|||||||
return registerConsumer(callback, EventType.ON_NPC_CREATURE_SEE, ListenerRegisterType.NPC, npcIds);
|
return registerConsumer(callback, EventType.ON_NPC_CREATURE_SEE, ListenerRegisterType.NPC, npcIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides instant callback operation when {@link Npc} sees another creature.
|
||||||
|
* @param callback
|
||||||
|
* @param npcIds
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
protected final List<AbstractEventListener> setNpcCreatureSeeId(Consumer<OnNpcCreatureSee> callback, Collection<Integer> npcIds)
|
||||||
|
{
|
||||||
|
return registerConsumer(callback, EventType.ON_NPC_CREATURE_SEE, ListenerRegisterType.NPC, npcIds);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides instant callback operation when {@link Creature} sees another creature.
|
* Provides instant callback operation when {@link Creature} sees another creature.
|
||||||
* @param callback
|
* @param callback
|
||||||
@@ -975,14 +986,14 @@ public abstract class AbstractScript extends ManagedScript implements IEventTime
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides instant callback operation when {@link Npc} sees another creature.
|
* Provides instant callback operation when {@link Creature} sees another creature.
|
||||||
* @param callback
|
* @param callback
|
||||||
* @param npcIds
|
* @param npcIds
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
protected final List<AbstractEventListener> setNpcCreatureSeeId(Consumer<OnNpcCreatureSee> callback, Collection<Integer> npcIds)
|
protected final List<AbstractEventListener> setCreatureSeeId(Consumer<OnCreatureSee> callback, Collection<Integer> npcIds)
|
||||||
{
|
{
|
||||||
return registerConsumer(callback, EventType.ON_NPC_CREATURE_SEE, ListenerRegisterType.NPC, npcIds);
|
return registerConsumer(callback, EventType.ON_CREATURE_SEE, ListenerRegisterType.NPC, npcIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -254,6 +254,7 @@ public abstract class AbstractAI implements Ctrl
|
|||||||
{
|
{
|
||||||
case EVT_THINK:
|
case EVT_THINK:
|
||||||
{
|
{
|
||||||
|
_actor.updateSeenCreatures();
|
||||||
onEvtThink();
|
onEvtThink();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -325,7 +326,9 @@ public abstract class AbstractAI implements Ctrl
|
|||||||
}
|
}
|
||||||
case EVT_FORGET_OBJECT:
|
case EVT_FORGET_OBJECT:
|
||||||
{
|
{
|
||||||
onEvtForgetObject((WorldObject) arg0);
|
final WorldObject worldObject = (WorldObject) arg0;
|
||||||
|
_actor.removeSeenCreature(worldObject);
|
||||||
|
onEvtForgetObject(worldObject);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case EVT_CANCEL:
|
case EVT_CANCEL:
|
||||||
|
|||||||
@@ -1,106 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of the L2J Mobius project.
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
package org.l2jmobius.gameserver.model;
|
|
||||||
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
|
||||||
import java.util.concurrent.ScheduledFuture;
|
|
||||||
import java.util.function.Predicate;
|
|
||||||
|
|
||||||
import org.l2jmobius.commons.concurrent.ThreadPool;
|
|
||||||
import org.l2jmobius.gameserver.model.actor.Creature;
|
|
||||||
import org.l2jmobius.gameserver.model.events.EventDispatcher;
|
|
||||||
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureSee;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author UnAfraid
|
|
||||||
*/
|
|
||||||
public class CreatureContainer
|
|
||||||
{
|
|
||||||
private final Set<Integer> _seen = ConcurrentHashMap.newKeySet();
|
|
||||||
private final Creature _owner;
|
|
||||||
private final int _range;
|
|
||||||
private ScheduledFuture<?> _task;
|
|
||||||
private Predicate<Creature> _condition = null;
|
|
||||||
|
|
||||||
public CreatureContainer(Creature owner, int range, Predicate<Creature> condition)
|
|
||||||
{
|
|
||||||
_owner = owner;
|
|
||||||
_range = range;
|
|
||||||
_condition = condition;
|
|
||||||
start();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Creature getOwner()
|
|
||||||
{
|
|
||||||
return _owner;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getRange()
|
|
||||||
{
|
|
||||||
return _range;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Starts the task that scans for new creatures
|
|
||||||
*/
|
|
||||||
public void start()
|
|
||||||
{
|
|
||||||
if ((_task == null) || _task.isDone())
|
|
||||||
{
|
|
||||||
_task = ThreadPool.scheduleAtFixedRate(this::update, 1000, 1000);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return {@code false} if the task could not be cancelled, typically because it has already completed normally; {@code true} otherwise
|
|
||||||
*/
|
|
||||||
public boolean stop()
|
|
||||||
{
|
|
||||||
return (_task != null) && !_task.isDone() && _task.cancel(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Resets the creatures container, all previously seen creature will be discarded and next time update method is called will notify for each creature that owner sees!
|
|
||||||
*/
|
|
||||||
public void reset()
|
|
||||||
{
|
|
||||||
_seen.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Scans around the npc and notifies about new creature owner seen
|
|
||||||
*/
|
|
||||||
private void update()
|
|
||||||
{
|
|
||||||
final Set<Integer> verified = new HashSet<>();
|
|
||||||
World.getInstance().forEachVisibleObjectInRange(_owner, Creature.class, _range, creature ->
|
|
||||||
{
|
|
||||||
if ((_condition == null) || _condition.test(creature))
|
|
||||||
{
|
|
||||||
if (_seen.add(creature.getObjectId()))
|
|
||||||
{
|
|
||||||
EventDispatcher.getInstance().notifyEventAsync(new OnCreatureSee(_owner, creature), _owner);
|
|
||||||
}
|
|
||||||
verified.add(creature.getObjectId());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
_seen.retainAll(verified);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -69,7 +69,6 @@ import org.l2jmobius.gameserver.instancemanager.MapRegionManager;
|
|||||||
import org.l2jmobius.gameserver.instancemanager.QuestManager;
|
import org.l2jmobius.gameserver.instancemanager.QuestManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.ZoneManager;
|
import org.l2jmobius.gameserver.instancemanager.ZoneManager;
|
||||||
import org.l2jmobius.gameserver.model.AccessLevel;
|
import org.l2jmobius.gameserver.model.AccessLevel;
|
||||||
import org.l2jmobius.gameserver.model.CreatureContainer;
|
|
||||||
import org.l2jmobius.gameserver.model.EffectList;
|
import org.l2jmobius.gameserver.model.EffectList;
|
||||||
import org.l2jmobius.gameserver.model.Hit;
|
import org.l2jmobius.gameserver.model.Hit;
|
||||||
import org.l2jmobius.gameserver.model.Location;
|
import org.l2jmobius.gameserver.model.Location;
|
||||||
@@ -88,6 +87,7 @@ import org.l2jmobius.gameserver.model.actor.stat.CreatureStat;
|
|||||||
import org.l2jmobius.gameserver.model.actor.status.CreatureStatus;
|
import org.l2jmobius.gameserver.model.actor.status.CreatureStatus;
|
||||||
import org.l2jmobius.gameserver.model.actor.tasks.creature.NotifyAITask;
|
import org.l2jmobius.gameserver.model.actor.tasks.creature.NotifyAITask;
|
||||||
import org.l2jmobius.gameserver.model.actor.templates.CreatureTemplate;
|
import org.l2jmobius.gameserver.model.actor.templates.CreatureTemplate;
|
||||||
|
import org.l2jmobius.gameserver.model.actor.templates.NpcTemplate;
|
||||||
import org.l2jmobius.gameserver.model.actor.transform.Transform;
|
import org.l2jmobius.gameserver.model.actor.transform.Transform;
|
||||||
import org.l2jmobius.gameserver.model.clan.Clan;
|
import org.l2jmobius.gameserver.model.clan.Clan;
|
||||||
import org.l2jmobius.gameserver.model.effects.EffectFlag;
|
import org.l2jmobius.gameserver.model.effects.EffectFlag;
|
||||||
@@ -101,6 +101,7 @@ import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureDamageDealt
|
|||||||
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureDamageReceived;
|
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureDamageReceived;
|
||||||
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureDeath;
|
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureDeath;
|
||||||
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureKilled;
|
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureKilled;
|
||||||
|
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureSee;
|
||||||
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureTeleport;
|
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureTeleport;
|
||||||
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureTeleported;
|
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureTeleported;
|
||||||
import org.l2jmobius.gameserver.model.events.listeners.AbstractEventListener;
|
import org.l2jmobius.gameserver.model.events.listeners.AbstractEventListener;
|
||||||
@@ -271,7 +272,8 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
|
|
||||||
private final Map<Integer, RelationCache> _knownRelations = new ConcurrentHashMap<>();
|
private final Map<Integer, RelationCache> _knownRelations = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
private CreatureContainer _seenCreatures;
|
private Set<Creature> _seenCreatures = null;
|
||||||
|
private int _seenCreatureRange = Config.ALT_PARTY_RANGE;
|
||||||
|
|
||||||
private final Map<StatusUpdateType, Integer> _statusUpdates = new ConcurrentHashMap<>();
|
private final Map<StatusUpdateType, Integer> _statusUpdates = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
@@ -563,13 +565,6 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
{
|
{
|
||||||
_summoner.removeSummonedNpc(getObjectId());
|
_summoner.removeSummonedNpc(getObjectId());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stop on creature see task and clear the data
|
|
||||||
if (_seenCreatures != null)
|
|
||||||
{
|
|
||||||
_seenCreatures.stop();
|
|
||||||
_seenCreatures.reset();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -577,12 +572,6 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
{
|
{
|
||||||
super.onSpawn();
|
super.onSpawn();
|
||||||
revalidateZone(true);
|
revalidateZone(true);
|
||||||
|
|
||||||
// restart task
|
|
||||||
if (_seenCreatures != null)
|
|
||||||
{
|
|
||||||
_seenCreatures.start();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized void onTeleported()
|
public synchronized void onTeleported()
|
||||||
@@ -591,6 +580,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
spawnMe(getX(), getY(), getZ());
|
spawnMe(getX(), getY(), getZ());
|
||||||
setTeleporting(false);
|
setTeleporting(false);
|
||||||
EventDispatcher.getInstance().notifyEventAsync(new OnCreatureTeleported(this), this);
|
EventDispatcher.getInstance().notifyEventAsync(new OnCreatureTeleported(this), this);
|
||||||
@@ -1727,6 +1717,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
{
|
{
|
||||||
getSkillChannelized().abortChannelization();
|
getSkillChannelized().abortChannelization();
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1757,6 +1748,12 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
// Remove all active, passive and option effects, do not broadcast changes.
|
// Remove all active, passive and option effects, do not broadcast changes.
|
||||||
_effectList.stopAllEffectsWithoutExclusions(false, false);
|
_effectList.stopAllEffectsWithoutExclusions(false, false);
|
||||||
|
|
||||||
|
// Forget all seen creatures.
|
||||||
|
if (_seenCreatures != null)
|
||||||
|
{
|
||||||
|
_seenCreatures.clear();
|
||||||
|
}
|
||||||
|
|
||||||
// Cancel the BuffFinishTask related to this creature.
|
// Cancel the BuffFinishTask related to this creature.
|
||||||
cancelBuffFinishTask();
|
cancelBuffFinishTask();
|
||||||
|
|
||||||
@@ -5437,22 +5434,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
return _blockActionsAllowedSkills.containsKey(skill.getId());
|
return _blockActionsAllowedSkills.containsKey(skill.getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public void initSeenCreatures()
|
||||||
* Initialize creature container that looks up for creatures around its owner, and notifies with onCreatureSee upon discovery.
|
|
||||||
* @param range
|
|
||||||
*/
|
|
||||||
public void initSeenCreatures(int range)
|
|
||||||
{
|
|
||||||
initSeenCreatures(range, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialize creature container that looks up for creatures around its owner, and notifies with onCreatureSee upon discovery.<br>
|
|
||||||
* <i>The condition can be null</i>
|
|
||||||
* @param range
|
|
||||||
* @param condition
|
|
||||||
*/
|
|
||||||
public void initSeenCreatures(int range, Predicate<Creature> condition)
|
|
||||||
{
|
{
|
||||||
if (_seenCreatures == null)
|
if (_seenCreatures == null)
|
||||||
{
|
{
|
||||||
@@ -5460,15 +5442,45 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
{
|
{
|
||||||
if (_seenCreatures == null)
|
if (_seenCreatures == null)
|
||||||
{
|
{
|
||||||
_seenCreatures = new CreatureContainer(this, range, condition);
|
if (isNpc())
|
||||||
|
{
|
||||||
|
final NpcTemplate template = ((Npc) this).getTemplate();
|
||||||
|
if ((template != null) && (template.getAggroRange() > 0))
|
||||||
|
{
|
||||||
|
_seenCreatureRange = template.getAggroRange();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_seenCreatures = ConcurrentHashMap.newKeySet(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public CreatureContainer getSeenCreatures()
|
public void updateSeenCreatures()
|
||||||
{
|
{
|
||||||
return _seenCreatures;
|
if ((_seenCreatures == null) || _isDead || !isSpawned())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
World.getInstance().forEachVisibleObjectInRange(this, Creature.class, _seenCreatureRange, creature ->
|
||||||
|
{
|
||||||
|
if (_seenCreatures.add(creature))
|
||||||
|
{
|
||||||
|
EventDispatcher.getInstance().notifyEventAsync(new OnCreatureSee(this, creature), this);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeSeenCreature(WorldObject worldObject)
|
||||||
|
{
|
||||||
|
if (_seenCreatures == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_seenCreatures.remove(worldObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
public MoveType getMoveType()
|
public MoveType getMoveType()
|
||||||
|
|||||||
@@ -1832,14 +1832,6 @@ public class Npc extends Creature
|
|||||||
return Rnd.get(100) < Rnd.get(getTemplate().getMinSkillChance(), getTemplate().getMaxSkillChance());
|
return Rnd.get(100) < Rnd.get(getTemplate().getMinSkillChance(), getTemplate().getMaxSkillChance());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialize creature container that looks up for creatures around its owner, and notifies with onCreatureSee upon discovery.
|
|
||||||
*/
|
|
||||||
public void initSeenCreatures()
|
|
||||||
{
|
|
||||||
initSeenCreatures(getTemplate().getAggroRange());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the NpcStringId for name
|
* @return the NpcStringId for name
|
||||||
*/
|
*/
|
||||||
|
|||||||
+14
-3
@@ -963,6 +963,17 @@ public abstract class AbstractScript extends ManagedScript implements IEventTime
|
|||||||
return registerConsumer(callback, EventType.ON_NPC_CREATURE_SEE, ListenerRegisterType.NPC, npcIds);
|
return registerConsumer(callback, EventType.ON_NPC_CREATURE_SEE, ListenerRegisterType.NPC, npcIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides instant callback operation when {@link Npc} sees another creature.
|
||||||
|
* @param callback
|
||||||
|
* @param npcIds
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
protected final List<AbstractEventListener> setNpcCreatureSeeId(Consumer<OnNpcCreatureSee> callback, Collection<Integer> npcIds)
|
||||||
|
{
|
||||||
|
return registerConsumer(callback, EventType.ON_NPC_CREATURE_SEE, ListenerRegisterType.NPC, npcIds);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides instant callback operation when {@link Creature} sees another creature.
|
* Provides instant callback operation when {@link Creature} sees another creature.
|
||||||
* @param callback
|
* @param callback
|
||||||
@@ -975,14 +986,14 @@ public abstract class AbstractScript extends ManagedScript implements IEventTime
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides instant callback operation when {@link Npc} sees another creature.
|
* Provides instant callback operation when {@link Creature} sees another creature.
|
||||||
* @param callback
|
* @param callback
|
||||||
* @param npcIds
|
* @param npcIds
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
protected final List<AbstractEventListener> setNpcCreatureSeeId(Consumer<OnNpcCreatureSee> callback, Collection<Integer> npcIds)
|
protected final List<AbstractEventListener> setCreatureSeeId(Consumer<OnCreatureSee> callback, Collection<Integer> npcIds)
|
||||||
{
|
{
|
||||||
return registerConsumer(callback, EventType.ON_NPC_CREATURE_SEE, ListenerRegisterType.NPC, npcIds);
|
return registerConsumer(callback, EventType.ON_CREATURE_SEE, ListenerRegisterType.NPC, npcIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -254,6 +254,7 @@ public abstract class AbstractAI implements Ctrl
|
|||||||
{
|
{
|
||||||
case EVT_THINK:
|
case EVT_THINK:
|
||||||
{
|
{
|
||||||
|
_actor.updateSeenCreatures();
|
||||||
onEvtThink();
|
onEvtThink();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -325,7 +326,9 @@ public abstract class AbstractAI implements Ctrl
|
|||||||
}
|
}
|
||||||
case EVT_FORGET_OBJECT:
|
case EVT_FORGET_OBJECT:
|
||||||
{
|
{
|
||||||
onEvtForgetObject((WorldObject) arg0);
|
final WorldObject worldObject = (WorldObject) arg0;
|
||||||
|
_actor.removeSeenCreature(worldObject);
|
||||||
|
onEvtForgetObject(worldObject);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case EVT_CANCEL:
|
case EVT_CANCEL:
|
||||||
|
|||||||
-106
@@ -1,106 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of the L2J Mobius project.
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
package org.l2jmobius.gameserver.model;
|
|
||||||
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
|
||||||
import java.util.concurrent.ScheduledFuture;
|
|
||||||
import java.util.function.Predicate;
|
|
||||||
|
|
||||||
import org.l2jmobius.commons.concurrent.ThreadPool;
|
|
||||||
import org.l2jmobius.gameserver.model.actor.Creature;
|
|
||||||
import org.l2jmobius.gameserver.model.events.EventDispatcher;
|
|
||||||
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureSee;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author UnAfraid
|
|
||||||
*/
|
|
||||||
public class CreatureContainer
|
|
||||||
{
|
|
||||||
private final Set<Integer> _seen = ConcurrentHashMap.newKeySet();
|
|
||||||
private final Creature _owner;
|
|
||||||
private final int _range;
|
|
||||||
private ScheduledFuture<?> _task;
|
|
||||||
private Predicate<Creature> _condition = null;
|
|
||||||
|
|
||||||
public CreatureContainer(Creature owner, int range, Predicate<Creature> condition)
|
|
||||||
{
|
|
||||||
_owner = owner;
|
|
||||||
_range = range;
|
|
||||||
_condition = condition;
|
|
||||||
start();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Creature getOwner()
|
|
||||||
{
|
|
||||||
return _owner;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getRange()
|
|
||||||
{
|
|
||||||
return _range;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Starts the task that scans for new creatures
|
|
||||||
*/
|
|
||||||
public void start()
|
|
||||||
{
|
|
||||||
if ((_task == null) || _task.isDone())
|
|
||||||
{
|
|
||||||
_task = ThreadPool.scheduleAtFixedRate(this::update, 1000, 1000);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return {@code false} if the task could not be cancelled, typically because it has already completed normally; {@code true} otherwise
|
|
||||||
*/
|
|
||||||
public boolean stop()
|
|
||||||
{
|
|
||||||
return (_task != null) && !_task.isDone() && _task.cancel(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Resets the creatures container, all previously seen creature will be discarded and next time update method is called will notify for each creature that owner sees!
|
|
||||||
*/
|
|
||||||
public void reset()
|
|
||||||
{
|
|
||||||
_seen.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Scans around the npc and notifies about new creature owner seen
|
|
||||||
*/
|
|
||||||
private void update()
|
|
||||||
{
|
|
||||||
final Set<Integer> verified = new HashSet<>();
|
|
||||||
World.getInstance().forEachVisibleObjectInRange(_owner, Creature.class, _range, creature ->
|
|
||||||
{
|
|
||||||
if ((_condition == null) || _condition.test(creature))
|
|
||||||
{
|
|
||||||
if (_seen.add(creature.getObjectId()))
|
|
||||||
{
|
|
||||||
EventDispatcher.getInstance().notifyEventAsync(new OnCreatureSee(_owner, creature), _owner);
|
|
||||||
}
|
|
||||||
verified.add(creature.getObjectId());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
_seen.retainAll(verified);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+46
-34
@@ -69,7 +69,6 @@ import org.l2jmobius.gameserver.instancemanager.MapRegionManager;
|
|||||||
import org.l2jmobius.gameserver.instancemanager.QuestManager;
|
import org.l2jmobius.gameserver.instancemanager.QuestManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.ZoneManager;
|
import org.l2jmobius.gameserver.instancemanager.ZoneManager;
|
||||||
import org.l2jmobius.gameserver.model.AccessLevel;
|
import org.l2jmobius.gameserver.model.AccessLevel;
|
||||||
import org.l2jmobius.gameserver.model.CreatureContainer;
|
|
||||||
import org.l2jmobius.gameserver.model.EffectList;
|
import org.l2jmobius.gameserver.model.EffectList;
|
||||||
import org.l2jmobius.gameserver.model.Hit;
|
import org.l2jmobius.gameserver.model.Hit;
|
||||||
import org.l2jmobius.gameserver.model.Location;
|
import org.l2jmobius.gameserver.model.Location;
|
||||||
@@ -88,6 +87,7 @@ import org.l2jmobius.gameserver.model.actor.stat.CreatureStat;
|
|||||||
import org.l2jmobius.gameserver.model.actor.status.CreatureStatus;
|
import org.l2jmobius.gameserver.model.actor.status.CreatureStatus;
|
||||||
import org.l2jmobius.gameserver.model.actor.tasks.creature.NotifyAITask;
|
import org.l2jmobius.gameserver.model.actor.tasks.creature.NotifyAITask;
|
||||||
import org.l2jmobius.gameserver.model.actor.templates.CreatureTemplate;
|
import org.l2jmobius.gameserver.model.actor.templates.CreatureTemplate;
|
||||||
|
import org.l2jmobius.gameserver.model.actor.templates.NpcTemplate;
|
||||||
import org.l2jmobius.gameserver.model.actor.transform.Transform;
|
import org.l2jmobius.gameserver.model.actor.transform.Transform;
|
||||||
import org.l2jmobius.gameserver.model.clan.Clan;
|
import org.l2jmobius.gameserver.model.clan.Clan;
|
||||||
import org.l2jmobius.gameserver.model.effects.EffectFlag;
|
import org.l2jmobius.gameserver.model.effects.EffectFlag;
|
||||||
@@ -101,6 +101,7 @@ import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureDamageDealt
|
|||||||
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureDamageReceived;
|
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureDamageReceived;
|
||||||
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureDeath;
|
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureDeath;
|
||||||
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureKilled;
|
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureKilled;
|
||||||
|
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureSee;
|
||||||
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureTeleport;
|
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureTeleport;
|
||||||
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureTeleported;
|
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureTeleported;
|
||||||
import org.l2jmobius.gameserver.model.events.listeners.AbstractEventListener;
|
import org.l2jmobius.gameserver.model.events.listeners.AbstractEventListener;
|
||||||
@@ -271,7 +272,8 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
|
|
||||||
private final Map<Integer, RelationCache> _knownRelations = new ConcurrentHashMap<>();
|
private final Map<Integer, RelationCache> _knownRelations = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
private CreatureContainer _seenCreatures;
|
private Set<Creature> _seenCreatures = null;
|
||||||
|
private int _seenCreatureRange = Config.ALT_PARTY_RANGE;
|
||||||
|
|
||||||
private final Map<StatusUpdateType, Integer> _statusUpdates = new ConcurrentHashMap<>();
|
private final Map<StatusUpdateType, Integer> _statusUpdates = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
@@ -563,13 +565,6 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
{
|
{
|
||||||
_summoner.removeSummonedNpc(getObjectId());
|
_summoner.removeSummonedNpc(getObjectId());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stop on creature see task and clear the data
|
|
||||||
if (_seenCreatures != null)
|
|
||||||
{
|
|
||||||
_seenCreatures.stop();
|
|
||||||
_seenCreatures.reset();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -577,12 +572,6 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
{
|
{
|
||||||
super.onSpawn();
|
super.onSpawn();
|
||||||
revalidateZone(true);
|
revalidateZone(true);
|
||||||
|
|
||||||
// restart task
|
|
||||||
if (_seenCreatures != null)
|
|
||||||
{
|
|
||||||
_seenCreatures.start();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized void onTeleported()
|
public synchronized void onTeleported()
|
||||||
@@ -591,6 +580,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
spawnMe(getX(), getY(), getZ());
|
spawnMe(getX(), getY(), getZ());
|
||||||
setTeleporting(false);
|
setTeleporting(false);
|
||||||
EventDispatcher.getInstance().notifyEventAsync(new OnCreatureTeleported(this), this);
|
EventDispatcher.getInstance().notifyEventAsync(new OnCreatureTeleported(this), this);
|
||||||
@@ -1727,6 +1717,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
{
|
{
|
||||||
getSkillChannelized().abortChannelization();
|
getSkillChannelized().abortChannelization();
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1757,6 +1748,12 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
// Remove all active, passive and option effects, do not broadcast changes.
|
// Remove all active, passive and option effects, do not broadcast changes.
|
||||||
_effectList.stopAllEffectsWithoutExclusions(false, false);
|
_effectList.stopAllEffectsWithoutExclusions(false, false);
|
||||||
|
|
||||||
|
// Forget all seen creatures.
|
||||||
|
if (_seenCreatures != null)
|
||||||
|
{
|
||||||
|
_seenCreatures.clear();
|
||||||
|
}
|
||||||
|
|
||||||
// Cancel the BuffFinishTask related to this creature.
|
// Cancel the BuffFinishTask related to this creature.
|
||||||
cancelBuffFinishTask();
|
cancelBuffFinishTask();
|
||||||
|
|
||||||
@@ -5436,22 +5433,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
return _blockActionsAllowedSkills.containsKey(skill.getId());
|
return _blockActionsAllowedSkills.containsKey(skill.getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public void initSeenCreatures()
|
||||||
* Initialize creature container that looks up for creatures around its owner, and notifies with onCreatureSee upon discovery.
|
|
||||||
* @param range
|
|
||||||
*/
|
|
||||||
public void initSeenCreatures(int range)
|
|
||||||
{
|
|
||||||
initSeenCreatures(range, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialize creature container that looks up for creatures around its owner, and notifies with onCreatureSee upon discovery.<br>
|
|
||||||
* <i>The condition can be null</i>
|
|
||||||
* @param range
|
|
||||||
* @param condition
|
|
||||||
*/
|
|
||||||
public void initSeenCreatures(int range, Predicate<Creature> condition)
|
|
||||||
{
|
{
|
||||||
if (_seenCreatures == null)
|
if (_seenCreatures == null)
|
||||||
{
|
{
|
||||||
@@ -5459,15 +5441,45 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
{
|
{
|
||||||
if (_seenCreatures == null)
|
if (_seenCreatures == null)
|
||||||
{
|
{
|
||||||
_seenCreatures = new CreatureContainer(this, range, condition);
|
if (isNpc())
|
||||||
|
{
|
||||||
|
final NpcTemplate template = ((Npc) this).getTemplate();
|
||||||
|
if ((template != null) && (template.getAggroRange() > 0))
|
||||||
|
{
|
||||||
|
_seenCreatureRange = template.getAggroRange();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_seenCreatures = ConcurrentHashMap.newKeySet(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public CreatureContainer getSeenCreatures()
|
public void updateSeenCreatures()
|
||||||
{
|
{
|
||||||
return _seenCreatures;
|
if ((_seenCreatures == null) || _isDead || !isSpawned())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
World.getInstance().forEachVisibleObjectInRange(this, Creature.class, _seenCreatureRange, creature ->
|
||||||
|
{
|
||||||
|
if (_seenCreatures.add(creature))
|
||||||
|
{
|
||||||
|
EventDispatcher.getInstance().notifyEventAsync(new OnCreatureSee(this, creature), this);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeSeenCreature(WorldObject worldObject)
|
||||||
|
{
|
||||||
|
if (_seenCreatures == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_seenCreatures.remove(worldObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
public MoveType getMoveType()
|
public MoveType getMoveType()
|
||||||
|
|||||||
@@ -1832,14 +1832,6 @@ public class Npc extends Creature
|
|||||||
return Rnd.get(100) < Rnd.get(getTemplate().getMinSkillChance(), getTemplate().getMaxSkillChance());
|
return Rnd.get(100) < Rnd.get(getTemplate().getMinSkillChance(), getTemplate().getMaxSkillChance());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialize creature container that looks up for creatures around its owner, and notifies with onCreatureSee upon discovery.
|
|
||||||
*/
|
|
||||||
public void initSeenCreatures()
|
|
||||||
{
|
|
||||||
initSeenCreatures(getTemplate().getAggroRange());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the NpcStringId for name
|
* @return the NpcStringId for name
|
||||||
*/
|
*/
|
||||||
|
|||||||
+14
-3
@@ -963,6 +963,17 @@ public abstract class AbstractScript extends ManagedScript implements IEventTime
|
|||||||
return registerConsumer(callback, EventType.ON_NPC_CREATURE_SEE, ListenerRegisterType.NPC, npcIds);
|
return registerConsumer(callback, EventType.ON_NPC_CREATURE_SEE, ListenerRegisterType.NPC, npcIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides instant callback operation when {@link Npc} sees another creature.
|
||||||
|
* @param callback
|
||||||
|
* @param npcIds
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
protected final List<AbstractEventListener> setNpcCreatureSeeId(Consumer<OnNpcCreatureSee> callback, Collection<Integer> npcIds)
|
||||||
|
{
|
||||||
|
return registerConsumer(callback, EventType.ON_NPC_CREATURE_SEE, ListenerRegisterType.NPC, npcIds);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides instant callback operation when {@link Creature} sees another creature.
|
* Provides instant callback operation when {@link Creature} sees another creature.
|
||||||
* @param callback
|
* @param callback
|
||||||
@@ -975,14 +986,14 @@ public abstract class AbstractScript extends ManagedScript implements IEventTime
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides instant callback operation when {@link Npc} sees another creature.
|
* Provides instant callback operation when {@link Creature} sees another creature.
|
||||||
* @param callback
|
* @param callback
|
||||||
* @param npcIds
|
* @param npcIds
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
protected final List<AbstractEventListener> setNpcCreatureSeeId(Consumer<OnNpcCreatureSee> callback, Collection<Integer> npcIds)
|
protected final List<AbstractEventListener> setCreatureSeeId(Consumer<OnCreatureSee> callback, Collection<Integer> npcIds)
|
||||||
{
|
{
|
||||||
return registerConsumer(callback, EventType.ON_NPC_CREATURE_SEE, ListenerRegisterType.NPC, npcIds);
|
return registerConsumer(callback, EventType.ON_CREATURE_SEE, ListenerRegisterType.NPC, npcIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -254,6 +254,7 @@ public abstract class AbstractAI implements Ctrl
|
|||||||
{
|
{
|
||||||
case EVT_THINK:
|
case EVT_THINK:
|
||||||
{
|
{
|
||||||
|
_actor.updateSeenCreatures();
|
||||||
onEvtThink();
|
onEvtThink();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -325,7 +326,9 @@ public abstract class AbstractAI implements Ctrl
|
|||||||
}
|
}
|
||||||
case EVT_FORGET_OBJECT:
|
case EVT_FORGET_OBJECT:
|
||||||
{
|
{
|
||||||
onEvtForgetObject((WorldObject) arg0);
|
final WorldObject worldObject = (WorldObject) arg0;
|
||||||
|
_actor.removeSeenCreature(worldObject);
|
||||||
|
onEvtForgetObject(worldObject);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case EVT_CANCEL:
|
case EVT_CANCEL:
|
||||||
|
|||||||
@@ -1,106 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of the L2J Mobius project.
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
package org.l2jmobius.gameserver.model;
|
|
||||||
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
|
||||||
import java.util.concurrent.ScheduledFuture;
|
|
||||||
import java.util.function.Predicate;
|
|
||||||
|
|
||||||
import org.l2jmobius.commons.concurrent.ThreadPool;
|
|
||||||
import org.l2jmobius.gameserver.model.actor.Creature;
|
|
||||||
import org.l2jmobius.gameserver.model.events.EventDispatcher;
|
|
||||||
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureSee;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author UnAfraid
|
|
||||||
*/
|
|
||||||
public class CreatureContainer
|
|
||||||
{
|
|
||||||
private final Set<Integer> _seen = ConcurrentHashMap.newKeySet();
|
|
||||||
private final Creature _owner;
|
|
||||||
private final int _range;
|
|
||||||
private ScheduledFuture<?> _task;
|
|
||||||
private Predicate<Creature> _condition = null;
|
|
||||||
|
|
||||||
public CreatureContainer(Creature owner, int range, Predicate<Creature> condition)
|
|
||||||
{
|
|
||||||
_owner = owner;
|
|
||||||
_range = range;
|
|
||||||
_condition = condition;
|
|
||||||
start();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Creature getOwner()
|
|
||||||
{
|
|
||||||
return _owner;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getRange()
|
|
||||||
{
|
|
||||||
return _range;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Starts the task that scans for new creatures
|
|
||||||
*/
|
|
||||||
public void start()
|
|
||||||
{
|
|
||||||
if ((_task == null) || _task.isDone())
|
|
||||||
{
|
|
||||||
_task = ThreadPool.scheduleAtFixedRate(this::update, 1000, 1000);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return {@code false} if the task could not be cancelled, typically because it has already completed normally; {@code true} otherwise
|
|
||||||
*/
|
|
||||||
public boolean stop()
|
|
||||||
{
|
|
||||||
return (_task != null) && !_task.isDone() && _task.cancel(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Resets the creatures container, all previously seen creature will be discarded and next time update method is called will notify for each creature that owner sees!
|
|
||||||
*/
|
|
||||||
public void reset()
|
|
||||||
{
|
|
||||||
_seen.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Scans around the npc and notifies about new creature owner seen
|
|
||||||
*/
|
|
||||||
private void update()
|
|
||||||
{
|
|
||||||
final Set<Integer> verified = new HashSet<>();
|
|
||||||
World.getInstance().forEachVisibleObjectInRange(_owner, Creature.class, _range, creature ->
|
|
||||||
{
|
|
||||||
if ((_condition == null) || _condition.test(creature))
|
|
||||||
{
|
|
||||||
if (_seen.add(creature.getObjectId()))
|
|
||||||
{
|
|
||||||
EventDispatcher.getInstance().notifyEventAsync(new OnCreatureSee(_owner, creature), _owner);
|
|
||||||
}
|
|
||||||
verified.add(creature.getObjectId());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
_seen.retainAll(verified);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -69,7 +69,6 @@ import org.l2jmobius.gameserver.instancemanager.MapRegionManager;
|
|||||||
import org.l2jmobius.gameserver.instancemanager.QuestManager;
|
import org.l2jmobius.gameserver.instancemanager.QuestManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.ZoneManager;
|
import org.l2jmobius.gameserver.instancemanager.ZoneManager;
|
||||||
import org.l2jmobius.gameserver.model.AccessLevel;
|
import org.l2jmobius.gameserver.model.AccessLevel;
|
||||||
import org.l2jmobius.gameserver.model.CreatureContainer;
|
|
||||||
import org.l2jmobius.gameserver.model.EffectList;
|
import org.l2jmobius.gameserver.model.EffectList;
|
||||||
import org.l2jmobius.gameserver.model.Hit;
|
import org.l2jmobius.gameserver.model.Hit;
|
||||||
import org.l2jmobius.gameserver.model.Location;
|
import org.l2jmobius.gameserver.model.Location;
|
||||||
@@ -88,6 +87,7 @@ import org.l2jmobius.gameserver.model.actor.stat.CreatureStat;
|
|||||||
import org.l2jmobius.gameserver.model.actor.status.CreatureStatus;
|
import org.l2jmobius.gameserver.model.actor.status.CreatureStatus;
|
||||||
import org.l2jmobius.gameserver.model.actor.tasks.creature.NotifyAITask;
|
import org.l2jmobius.gameserver.model.actor.tasks.creature.NotifyAITask;
|
||||||
import org.l2jmobius.gameserver.model.actor.templates.CreatureTemplate;
|
import org.l2jmobius.gameserver.model.actor.templates.CreatureTemplate;
|
||||||
|
import org.l2jmobius.gameserver.model.actor.templates.NpcTemplate;
|
||||||
import org.l2jmobius.gameserver.model.actor.transform.Transform;
|
import org.l2jmobius.gameserver.model.actor.transform.Transform;
|
||||||
import org.l2jmobius.gameserver.model.clan.Clan;
|
import org.l2jmobius.gameserver.model.clan.Clan;
|
||||||
import org.l2jmobius.gameserver.model.effects.EffectFlag;
|
import org.l2jmobius.gameserver.model.effects.EffectFlag;
|
||||||
@@ -101,6 +101,7 @@ import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureDamageDealt
|
|||||||
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureDamageReceived;
|
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureDamageReceived;
|
||||||
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureDeath;
|
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureDeath;
|
||||||
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureKilled;
|
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureKilled;
|
||||||
|
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureSee;
|
||||||
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureTeleport;
|
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureTeleport;
|
||||||
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureTeleported;
|
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureTeleported;
|
||||||
import org.l2jmobius.gameserver.model.events.listeners.AbstractEventListener;
|
import org.l2jmobius.gameserver.model.events.listeners.AbstractEventListener;
|
||||||
@@ -271,7 +272,8 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
|
|
||||||
private final Map<Integer, RelationCache> _knownRelations = new ConcurrentHashMap<>();
|
private final Map<Integer, RelationCache> _knownRelations = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
private CreatureContainer _seenCreatures;
|
private Set<Creature> _seenCreatures = null;
|
||||||
|
private int _seenCreatureRange = Config.ALT_PARTY_RANGE;
|
||||||
|
|
||||||
private final Map<StatusUpdateType, Integer> _statusUpdates = new ConcurrentHashMap<>();
|
private final Map<StatusUpdateType, Integer> _statusUpdates = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
@@ -563,13 +565,6 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
{
|
{
|
||||||
_summoner.removeSummonedNpc(getObjectId());
|
_summoner.removeSummonedNpc(getObjectId());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stop on creature see task and clear the data
|
|
||||||
if (_seenCreatures != null)
|
|
||||||
{
|
|
||||||
_seenCreatures.stop();
|
|
||||||
_seenCreatures.reset();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -577,12 +572,6 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
{
|
{
|
||||||
super.onSpawn();
|
super.onSpawn();
|
||||||
revalidateZone(true);
|
revalidateZone(true);
|
||||||
|
|
||||||
// restart task
|
|
||||||
if (_seenCreatures != null)
|
|
||||||
{
|
|
||||||
_seenCreatures.start();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized void onTeleported()
|
public synchronized void onTeleported()
|
||||||
@@ -591,6 +580,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
spawnMe(getX(), getY(), getZ());
|
spawnMe(getX(), getY(), getZ());
|
||||||
setTeleporting(false);
|
setTeleporting(false);
|
||||||
EventDispatcher.getInstance().notifyEventAsync(new OnCreatureTeleported(this), this);
|
EventDispatcher.getInstance().notifyEventAsync(new OnCreatureTeleported(this), this);
|
||||||
@@ -1727,6 +1717,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
{
|
{
|
||||||
getSkillChannelized().abortChannelization();
|
getSkillChannelized().abortChannelization();
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1757,6 +1748,12 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
// Remove all active, passive and option effects, do not broadcast changes.
|
// Remove all active, passive and option effects, do not broadcast changes.
|
||||||
_effectList.stopAllEffectsWithoutExclusions(false, false);
|
_effectList.stopAllEffectsWithoutExclusions(false, false);
|
||||||
|
|
||||||
|
// Forget all seen creatures.
|
||||||
|
if (_seenCreatures != null)
|
||||||
|
{
|
||||||
|
_seenCreatures.clear();
|
||||||
|
}
|
||||||
|
|
||||||
// Cancel the BuffFinishTask related to this creature.
|
// Cancel the BuffFinishTask related to this creature.
|
||||||
cancelBuffFinishTask();
|
cancelBuffFinishTask();
|
||||||
|
|
||||||
@@ -5436,22 +5433,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
return _blockActionsAllowedSkills.containsKey(skill.getId());
|
return _blockActionsAllowedSkills.containsKey(skill.getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public void initSeenCreatures()
|
||||||
* Initialize creature container that looks up for creatures around its owner, and notifies with onCreatureSee upon discovery.
|
|
||||||
* @param range
|
|
||||||
*/
|
|
||||||
public void initSeenCreatures(int range)
|
|
||||||
{
|
|
||||||
initSeenCreatures(range, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialize creature container that looks up for creatures around its owner, and notifies with onCreatureSee upon discovery.<br>
|
|
||||||
* <i>The condition can be null</i>
|
|
||||||
* @param range
|
|
||||||
* @param condition
|
|
||||||
*/
|
|
||||||
public void initSeenCreatures(int range, Predicate<Creature> condition)
|
|
||||||
{
|
{
|
||||||
if (_seenCreatures == null)
|
if (_seenCreatures == null)
|
||||||
{
|
{
|
||||||
@@ -5459,15 +5441,45 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
{
|
{
|
||||||
if (_seenCreatures == null)
|
if (_seenCreatures == null)
|
||||||
{
|
{
|
||||||
_seenCreatures = new CreatureContainer(this, range, condition);
|
if (isNpc())
|
||||||
|
{
|
||||||
|
final NpcTemplate template = ((Npc) this).getTemplate();
|
||||||
|
if ((template != null) && (template.getAggroRange() > 0))
|
||||||
|
{
|
||||||
|
_seenCreatureRange = template.getAggroRange();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_seenCreatures = ConcurrentHashMap.newKeySet(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public CreatureContainer getSeenCreatures()
|
public void updateSeenCreatures()
|
||||||
{
|
{
|
||||||
return _seenCreatures;
|
if ((_seenCreatures == null) || _isDead || !isSpawned())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
World.getInstance().forEachVisibleObjectInRange(this, Creature.class, _seenCreatureRange, creature ->
|
||||||
|
{
|
||||||
|
if (_seenCreatures.add(creature))
|
||||||
|
{
|
||||||
|
EventDispatcher.getInstance().notifyEventAsync(new OnCreatureSee(this, creature), this);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeSeenCreature(WorldObject worldObject)
|
||||||
|
{
|
||||||
|
if (_seenCreatures == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_seenCreatures.remove(worldObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
public MoveType getMoveType()
|
public MoveType getMoveType()
|
||||||
|
|||||||
@@ -1833,14 +1833,6 @@ public class Npc extends Creature
|
|||||||
return Rnd.get(100) < Rnd.get(getTemplate().getMinSkillChance(), getTemplate().getMaxSkillChance());
|
return Rnd.get(100) < Rnd.get(getTemplate().getMinSkillChance(), getTemplate().getMaxSkillChance());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialize creature container that looks up for creatures around its owner, and notifies with onCreatureSee upon discovery.
|
|
||||||
*/
|
|
||||||
public void initSeenCreatures()
|
|
||||||
{
|
|
||||||
initSeenCreatures(getTemplate().getAggroRange());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the NpcStringId for name
|
* @return the NpcStringId for name
|
||||||
*/
|
*/
|
||||||
|
|||||||
+14
-3
@@ -963,6 +963,17 @@ public abstract class AbstractScript extends ManagedScript implements IEventTime
|
|||||||
return registerConsumer(callback, EventType.ON_NPC_CREATURE_SEE, ListenerRegisterType.NPC, npcIds);
|
return registerConsumer(callback, EventType.ON_NPC_CREATURE_SEE, ListenerRegisterType.NPC, npcIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides instant callback operation when {@link Npc} sees another creature.
|
||||||
|
* @param callback
|
||||||
|
* @param npcIds
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
protected final List<AbstractEventListener> setNpcCreatureSeeId(Consumer<OnNpcCreatureSee> callback, Collection<Integer> npcIds)
|
||||||
|
{
|
||||||
|
return registerConsumer(callback, EventType.ON_NPC_CREATURE_SEE, ListenerRegisterType.NPC, npcIds);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides instant callback operation when {@link Creature} sees another creature.
|
* Provides instant callback operation when {@link Creature} sees another creature.
|
||||||
* @param callback
|
* @param callback
|
||||||
@@ -975,14 +986,14 @@ public abstract class AbstractScript extends ManagedScript implements IEventTime
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides instant callback operation when {@link Npc} sees another creature.
|
* Provides instant callback operation when {@link Creature} sees another creature.
|
||||||
* @param callback
|
* @param callback
|
||||||
* @param npcIds
|
* @param npcIds
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
protected final List<AbstractEventListener> setNpcCreatureSeeId(Consumer<OnNpcCreatureSee> callback, Collection<Integer> npcIds)
|
protected final List<AbstractEventListener> setCreatureSeeId(Consumer<OnCreatureSee> callback, Collection<Integer> npcIds)
|
||||||
{
|
{
|
||||||
return registerConsumer(callback, EventType.ON_NPC_CREATURE_SEE, ListenerRegisterType.NPC, npcIds);
|
return registerConsumer(callback, EventType.ON_CREATURE_SEE, ListenerRegisterType.NPC, npcIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -254,6 +254,7 @@ public abstract class AbstractAI implements Ctrl
|
|||||||
{
|
{
|
||||||
case EVT_THINK:
|
case EVT_THINK:
|
||||||
{
|
{
|
||||||
|
_actor.updateSeenCreatures();
|
||||||
onEvtThink();
|
onEvtThink();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -325,7 +326,9 @@ public abstract class AbstractAI implements Ctrl
|
|||||||
}
|
}
|
||||||
case EVT_FORGET_OBJECT:
|
case EVT_FORGET_OBJECT:
|
||||||
{
|
{
|
||||||
onEvtForgetObject((WorldObject) arg0);
|
final WorldObject worldObject = (WorldObject) arg0;
|
||||||
|
_actor.removeSeenCreature(worldObject);
|
||||||
|
onEvtForgetObject(worldObject);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case EVT_CANCEL:
|
case EVT_CANCEL:
|
||||||
|
|||||||
-106
@@ -1,106 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of the L2J Mobius project.
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
package org.l2jmobius.gameserver.model;
|
|
||||||
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
|
||||||
import java.util.concurrent.ScheduledFuture;
|
|
||||||
import java.util.function.Predicate;
|
|
||||||
|
|
||||||
import org.l2jmobius.commons.concurrent.ThreadPool;
|
|
||||||
import org.l2jmobius.gameserver.model.actor.Creature;
|
|
||||||
import org.l2jmobius.gameserver.model.events.EventDispatcher;
|
|
||||||
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureSee;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author UnAfraid
|
|
||||||
*/
|
|
||||||
public class CreatureContainer
|
|
||||||
{
|
|
||||||
private final Set<Integer> _seen = ConcurrentHashMap.newKeySet();
|
|
||||||
private final Creature _owner;
|
|
||||||
private final int _range;
|
|
||||||
private ScheduledFuture<?> _task;
|
|
||||||
private Predicate<Creature> _condition = null;
|
|
||||||
|
|
||||||
public CreatureContainer(Creature owner, int range, Predicate<Creature> condition)
|
|
||||||
{
|
|
||||||
_owner = owner;
|
|
||||||
_range = range;
|
|
||||||
_condition = condition;
|
|
||||||
start();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Creature getOwner()
|
|
||||||
{
|
|
||||||
return _owner;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getRange()
|
|
||||||
{
|
|
||||||
return _range;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Starts the task that scans for new creatures
|
|
||||||
*/
|
|
||||||
public void start()
|
|
||||||
{
|
|
||||||
if ((_task == null) || _task.isDone())
|
|
||||||
{
|
|
||||||
_task = ThreadPool.scheduleAtFixedRate(this::update, 1000, 1000);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return {@code false} if the task could not be cancelled, typically because it has already completed normally; {@code true} otherwise
|
|
||||||
*/
|
|
||||||
public boolean stop()
|
|
||||||
{
|
|
||||||
return (_task != null) && !_task.isDone() && _task.cancel(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Resets the creatures container, all previously seen creature will be discarded and next time update method is called will notify for each creature that owner sees!
|
|
||||||
*/
|
|
||||||
public void reset()
|
|
||||||
{
|
|
||||||
_seen.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Scans around the npc and notifies about new creature owner seen
|
|
||||||
*/
|
|
||||||
private void update()
|
|
||||||
{
|
|
||||||
final Set<Integer> verified = new HashSet<>();
|
|
||||||
World.getInstance().forEachVisibleObjectInRange(_owner, Creature.class, _range, creature ->
|
|
||||||
{
|
|
||||||
if ((_condition == null) || _condition.test(creature))
|
|
||||||
{
|
|
||||||
if (_seen.add(creature.getObjectId()))
|
|
||||||
{
|
|
||||||
EventDispatcher.getInstance().notifyEventAsync(new OnCreatureSee(_owner, creature), _owner);
|
|
||||||
}
|
|
||||||
verified.add(creature.getObjectId());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
_seen.retainAll(verified);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+46
-34
@@ -69,7 +69,6 @@ import org.l2jmobius.gameserver.instancemanager.MapRegionManager;
|
|||||||
import org.l2jmobius.gameserver.instancemanager.QuestManager;
|
import org.l2jmobius.gameserver.instancemanager.QuestManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.ZoneManager;
|
import org.l2jmobius.gameserver.instancemanager.ZoneManager;
|
||||||
import org.l2jmobius.gameserver.model.AccessLevel;
|
import org.l2jmobius.gameserver.model.AccessLevel;
|
||||||
import org.l2jmobius.gameserver.model.CreatureContainer;
|
|
||||||
import org.l2jmobius.gameserver.model.EffectList;
|
import org.l2jmobius.gameserver.model.EffectList;
|
||||||
import org.l2jmobius.gameserver.model.Hit;
|
import org.l2jmobius.gameserver.model.Hit;
|
||||||
import org.l2jmobius.gameserver.model.Location;
|
import org.l2jmobius.gameserver.model.Location;
|
||||||
@@ -88,6 +87,7 @@ import org.l2jmobius.gameserver.model.actor.stat.CreatureStat;
|
|||||||
import org.l2jmobius.gameserver.model.actor.status.CreatureStatus;
|
import org.l2jmobius.gameserver.model.actor.status.CreatureStatus;
|
||||||
import org.l2jmobius.gameserver.model.actor.tasks.creature.NotifyAITask;
|
import org.l2jmobius.gameserver.model.actor.tasks.creature.NotifyAITask;
|
||||||
import org.l2jmobius.gameserver.model.actor.templates.CreatureTemplate;
|
import org.l2jmobius.gameserver.model.actor.templates.CreatureTemplate;
|
||||||
|
import org.l2jmobius.gameserver.model.actor.templates.NpcTemplate;
|
||||||
import org.l2jmobius.gameserver.model.actor.transform.Transform;
|
import org.l2jmobius.gameserver.model.actor.transform.Transform;
|
||||||
import org.l2jmobius.gameserver.model.clan.Clan;
|
import org.l2jmobius.gameserver.model.clan.Clan;
|
||||||
import org.l2jmobius.gameserver.model.effects.EffectFlag;
|
import org.l2jmobius.gameserver.model.effects.EffectFlag;
|
||||||
@@ -101,6 +101,7 @@ import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureDamageDealt
|
|||||||
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureDamageReceived;
|
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureDamageReceived;
|
||||||
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureDeath;
|
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureDeath;
|
||||||
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureKilled;
|
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureKilled;
|
||||||
|
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureSee;
|
||||||
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureTeleport;
|
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureTeleport;
|
||||||
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureTeleported;
|
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureTeleported;
|
||||||
import org.l2jmobius.gameserver.model.events.listeners.AbstractEventListener;
|
import org.l2jmobius.gameserver.model.events.listeners.AbstractEventListener;
|
||||||
@@ -271,7 +272,8 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
|
|
||||||
private final Map<Integer, RelationCache> _knownRelations = new ConcurrentHashMap<>();
|
private final Map<Integer, RelationCache> _knownRelations = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
private CreatureContainer _seenCreatures;
|
private Set<Creature> _seenCreatures = null;
|
||||||
|
private int _seenCreatureRange = Config.ALT_PARTY_RANGE;
|
||||||
|
|
||||||
private final Map<StatusUpdateType, Integer> _statusUpdates = new ConcurrentHashMap<>();
|
private final Map<StatusUpdateType, Integer> _statusUpdates = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
@@ -563,13 +565,6 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
{
|
{
|
||||||
_summoner.removeSummonedNpc(getObjectId());
|
_summoner.removeSummonedNpc(getObjectId());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stop on creature see task and clear the data
|
|
||||||
if (_seenCreatures != null)
|
|
||||||
{
|
|
||||||
_seenCreatures.stop();
|
|
||||||
_seenCreatures.reset();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -577,12 +572,6 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
{
|
{
|
||||||
super.onSpawn();
|
super.onSpawn();
|
||||||
revalidateZone(true);
|
revalidateZone(true);
|
||||||
|
|
||||||
// restart task
|
|
||||||
if (_seenCreatures != null)
|
|
||||||
{
|
|
||||||
_seenCreatures.start();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized void onTeleported()
|
public synchronized void onTeleported()
|
||||||
@@ -591,6 +580,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
spawnMe(getX(), getY(), getZ());
|
spawnMe(getX(), getY(), getZ());
|
||||||
setTeleporting(false);
|
setTeleporting(false);
|
||||||
EventDispatcher.getInstance().notifyEventAsync(new OnCreatureTeleported(this), this);
|
EventDispatcher.getInstance().notifyEventAsync(new OnCreatureTeleported(this), this);
|
||||||
@@ -1727,6 +1717,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
{
|
{
|
||||||
getSkillChannelized().abortChannelization();
|
getSkillChannelized().abortChannelization();
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1757,6 +1748,12 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
// Remove all active, passive and option effects, do not broadcast changes.
|
// Remove all active, passive and option effects, do not broadcast changes.
|
||||||
_effectList.stopAllEffectsWithoutExclusions(false, false);
|
_effectList.stopAllEffectsWithoutExclusions(false, false);
|
||||||
|
|
||||||
|
// Forget all seen creatures.
|
||||||
|
if (_seenCreatures != null)
|
||||||
|
{
|
||||||
|
_seenCreatures.clear();
|
||||||
|
}
|
||||||
|
|
||||||
// Cancel the BuffFinishTask related to this creature.
|
// Cancel the BuffFinishTask related to this creature.
|
||||||
cancelBuffFinishTask();
|
cancelBuffFinishTask();
|
||||||
|
|
||||||
@@ -5436,22 +5433,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
return _blockActionsAllowedSkills.containsKey(skill.getId());
|
return _blockActionsAllowedSkills.containsKey(skill.getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public void initSeenCreatures()
|
||||||
* Initialize creature container that looks up for creatures around its owner, and notifies with onCreatureSee upon discovery.
|
|
||||||
* @param range
|
|
||||||
*/
|
|
||||||
public void initSeenCreatures(int range)
|
|
||||||
{
|
|
||||||
initSeenCreatures(range, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialize creature container that looks up for creatures around its owner, and notifies with onCreatureSee upon discovery.<br>
|
|
||||||
* <i>The condition can be null</i>
|
|
||||||
* @param range
|
|
||||||
* @param condition
|
|
||||||
*/
|
|
||||||
public void initSeenCreatures(int range, Predicate<Creature> condition)
|
|
||||||
{
|
{
|
||||||
if (_seenCreatures == null)
|
if (_seenCreatures == null)
|
||||||
{
|
{
|
||||||
@@ -5459,15 +5441,45 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
{
|
{
|
||||||
if (_seenCreatures == null)
|
if (_seenCreatures == null)
|
||||||
{
|
{
|
||||||
_seenCreatures = new CreatureContainer(this, range, condition);
|
if (isNpc())
|
||||||
|
{
|
||||||
|
final NpcTemplate template = ((Npc) this).getTemplate();
|
||||||
|
if ((template != null) && (template.getAggroRange() > 0))
|
||||||
|
{
|
||||||
|
_seenCreatureRange = template.getAggroRange();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_seenCreatures = ConcurrentHashMap.newKeySet(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public CreatureContainer getSeenCreatures()
|
public void updateSeenCreatures()
|
||||||
{
|
{
|
||||||
return _seenCreatures;
|
if ((_seenCreatures == null) || _isDead || !isSpawned())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
World.getInstance().forEachVisibleObjectInRange(this, Creature.class, _seenCreatureRange, creature ->
|
||||||
|
{
|
||||||
|
if (_seenCreatures.add(creature))
|
||||||
|
{
|
||||||
|
EventDispatcher.getInstance().notifyEventAsync(new OnCreatureSee(this, creature), this);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeSeenCreature(WorldObject worldObject)
|
||||||
|
{
|
||||||
|
if (_seenCreatures == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_seenCreatures.remove(worldObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
public MoveType getMoveType()
|
public MoveType getMoveType()
|
||||||
|
|||||||
@@ -1833,14 +1833,6 @@ public class Npc extends Creature
|
|||||||
return Rnd.get(100) < Rnd.get(getTemplate().getMinSkillChance(), getTemplate().getMaxSkillChance());
|
return Rnd.get(100) < Rnd.get(getTemplate().getMinSkillChance(), getTemplate().getMaxSkillChance());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialize creature container that looks up for creatures around its owner, and notifies with onCreatureSee upon discovery.
|
|
||||||
*/
|
|
||||||
public void initSeenCreatures()
|
|
||||||
{
|
|
||||||
initSeenCreatures(getTemplate().getAggroRange());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the NpcStringId for name
|
* @return the NpcStringId for name
|
||||||
*/
|
*/
|
||||||
|
|||||||
+14
-3
@@ -963,6 +963,17 @@ public abstract class AbstractScript extends ManagedScript implements IEventTime
|
|||||||
return registerConsumer(callback, EventType.ON_NPC_CREATURE_SEE, ListenerRegisterType.NPC, npcIds);
|
return registerConsumer(callback, EventType.ON_NPC_CREATURE_SEE, ListenerRegisterType.NPC, npcIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides instant callback operation when {@link Npc} sees another creature.
|
||||||
|
* @param callback
|
||||||
|
* @param npcIds
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
protected final List<AbstractEventListener> setNpcCreatureSeeId(Consumer<OnNpcCreatureSee> callback, Collection<Integer> npcIds)
|
||||||
|
{
|
||||||
|
return registerConsumer(callback, EventType.ON_NPC_CREATURE_SEE, ListenerRegisterType.NPC, npcIds);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides instant callback operation when {@link Creature} sees another creature.
|
* Provides instant callback operation when {@link Creature} sees another creature.
|
||||||
* @param callback
|
* @param callback
|
||||||
@@ -975,14 +986,14 @@ public abstract class AbstractScript extends ManagedScript implements IEventTime
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides instant callback operation when {@link Npc} sees another creature.
|
* Provides instant callback operation when {@link Creature} sees another creature.
|
||||||
* @param callback
|
* @param callback
|
||||||
* @param npcIds
|
* @param npcIds
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
protected final List<AbstractEventListener> setNpcCreatureSeeId(Consumer<OnNpcCreatureSee> callback, Collection<Integer> npcIds)
|
protected final List<AbstractEventListener> setCreatureSeeId(Consumer<OnCreatureSee> callback, Collection<Integer> npcIds)
|
||||||
{
|
{
|
||||||
return registerConsumer(callback, EventType.ON_NPC_CREATURE_SEE, ListenerRegisterType.NPC, npcIds);
|
return registerConsumer(callback, EventType.ON_CREATURE_SEE, ListenerRegisterType.NPC, npcIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -254,6 +254,7 @@ public abstract class AbstractAI implements Ctrl
|
|||||||
{
|
{
|
||||||
case EVT_THINK:
|
case EVT_THINK:
|
||||||
{
|
{
|
||||||
|
_actor.updateSeenCreatures();
|
||||||
onEvtThink();
|
onEvtThink();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -325,7 +326,9 @@ public abstract class AbstractAI implements Ctrl
|
|||||||
}
|
}
|
||||||
case EVT_FORGET_OBJECT:
|
case EVT_FORGET_OBJECT:
|
||||||
{
|
{
|
||||||
onEvtForgetObject((WorldObject) arg0);
|
final WorldObject worldObject = (WorldObject) arg0;
|
||||||
|
_actor.removeSeenCreature(worldObject);
|
||||||
|
onEvtForgetObject(worldObject);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case EVT_CANCEL:
|
case EVT_CANCEL:
|
||||||
|
|||||||
-106
@@ -1,106 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of the L2J Mobius project.
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
package org.l2jmobius.gameserver.model;
|
|
||||||
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
|
||||||
import java.util.concurrent.ScheduledFuture;
|
|
||||||
import java.util.function.Predicate;
|
|
||||||
|
|
||||||
import org.l2jmobius.commons.concurrent.ThreadPool;
|
|
||||||
import org.l2jmobius.gameserver.model.actor.Creature;
|
|
||||||
import org.l2jmobius.gameserver.model.events.EventDispatcher;
|
|
||||||
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureSee;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author UnAfraid
|
|
||||||
*/
|
|
||||||
public class CreatureContainer
|
|
||||||
{
|
|
||||||
private final Set<Integer> _seen = ConcurrentHashMap.newKeySet();
|
|
||||||
private final Creature _owner;
|
|
||||||
private final int _range;
|
|
||||||
private ScheduledFuture<?> _task;
|
|
||||||
private Predicate<Creature> _condition = null;
|
|
||||||
|
|
||||||
public CreatureContainer(Creature owner, int range, Predicate<Creature> condition)
|
|
||||||
{
|
|
||||||
_owner = owner;
|
|
||||||
_range = range;
|
|
||||||
_condition = condition;
|
|
||||||
start();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Creature getOwner()
|
|
||||||
{
|
|
||||||
return _owner;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getRange()
|
|
||||||
{
|
|
||||||
return _range;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Starts the task that scans for new creatures
|
|
||||||
*/
|
|
||||||
public void start()
|
|
||||||
{
|
|
||||||
if ((_task == null) || _task.isDone())
|
|
||||||
{
|
|
||||||
_task = ThreadPool.scheduleAtFixedRate(this::update, 1000, 1000);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return {@code false} if the task could not be cancelled, typically because it has already completed normally; {@code true} otherwise
|
|
||||||
*/
|
|
||||||
public boolean stop()
|
|
||||||
{
|
|
||||||
return (_task != null) && !_task.isDone() && _task.cancel(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Resets the creatures container, all previously seen creature will be discarded and next time update method is called will notify for each creature that owner sees!
|
|
||||||
*/
|
|
||||||
public void reset()
|
|
||||||
{
|
|
||||||
_seen.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Scans around the npc and notifies about new creature owner seen
|
|
||||||
*/
|
|
||||||
private void update()
|
|
||||||
{
|
|
||||||
final Set<Integer> verified = new HashSet<>();
|
|
||||||
World.getInstance().forEachVisibleObjectInRange(_owner, Creature.class, _range, creature ->
|
|
||||||
{
|
|
||||||
if ((_condition == null) || _condition.test(creature))
|
|
||||||
{
|
|
||||||
if (_seen.add(creature.getObjectId()))
|
|
||||||
{
|
|
||||||
EventDispatcher.getInstance().notifyEventAsync(new OnCreatureSee(_owner, creature), _owner);
|
|
||||||
}
|
|
||||||
verified.add(creature.getObjectId());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
_seen.retainAll(verified);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+46
-34
@@ -69,7 +69,6 @@ import org.l2jmobius.gameserver.instancemanager.MapRegionManager;
|
|||||||
import org.l2jmobius.gameserver.instancemanager.QuestManager;
|
import org.l2jmobius.gameserver.instancemanager.QuestManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.ZoneManager;
|
import org.l2jmobius.gameserver.instancemanager.ZoneManager;
|
||||||
import org.l2jmobius.gameserver.model.AccessLevel;
|
import org.l2jmobius.gameserver.model.AccessLevel;
|
||||||
import org.l2jmobius.gameserver.model.CreatureContainer;
|
|
||||||
import org.l2jmobius.gameserver.model.EffectList;
|
import org.l2jmobius.gameserver.model.EffectList;
|
||||||
import org.l2jmobius.gameserver.model.Hit;
|
import org.l2jmobius.gameserver.model.Hit;
|
||||||
import org.l2jmobius.gameserver.model.Location;
|
import org.l2jmobius.gameserver.model.Location;
|
||||||
@@ -88,6 +87,7 @@ import org.l2jmobius.gameserver.model.actor.stat.CreatureStat;
|
|||||||
import org.l2jmobius.gameserver.model.actor.status.CreatureStatus;
|
import org.l2jmobius.gameserver.model.actor.status.CreatureStatus;
|
||||||
import org.l2jmobius.gameserver.model.actor.tasks.creature.NotifyAITask;
|
import org.l2jmobius.gameserver.model.actor.tasks.creature.NotifyAITask;
|
||||||
import org.l2jmobius.gameserver.model.actor.templates.CreatureTemplate;
|
import org.l2jmobius.gameserver.model.actor.templates.CreatureTemplate;
|
||||||
|
import org.l2jmobius.gameserver.model.actor.templates.NpcTemplate;
|
||||||
import org.l2jmobius.gameserver.model.actor.transform.Transform;
|
import org.l2jmobius.gameserver.model.actor.transform.Transform;
|
||||||
import org.l2jmobius.gameserver.model.clan.Clan;
|
import org.l2jmobius.gameserver.model.clan.Clan;
|
||||||
import org.l2jmobius.gameserver.model.effects.EffectFlag;
|
import org.l2jmobius.gameserver.model.effects.EffectFlag;
|
||||||
@@ -101,6 +101,7 @@ import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureDamageDealt
|
|||||||
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureDamageReceived;
|
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureDamageReceived;
|
||||||
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureDeath;
|
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureDeath;
|
||||||
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureKilled;
|
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureKilled;
|
||||||
|
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureSee;
|
||||||
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureTeleport;
|
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureTeleport;
|
||||||
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureTeleported;
|
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureTeleported;
|
||||||
import org.l2jmobius.gameserver.model.events.listeners.AbstractEventListener;
|
import org.l2jmobius.gameserver.model.events.listeners.AbstractEventListener;
|
||||||
@@ -271,7 +272,8 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
|
|
||||||
private final Map<Integer, RelationCache> _knownRelations = new ConcurrentHashMap<>();
|
private final Map<Integer, RelationCache> _knownRelations = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
private CreatureContainer _seenCreatures;
|
private Set<Creature> _seenCreatures = null;
|
||||||
|
private int _seenCreatureRange = Config.ALT_PARTY_RANGE;
|
||||||
|
|
||||||
private final Map<StatusUpdateType, Integer> _statusUpdates = new ConcurrentHashMap<>();
|
private final Map<StatusUpdateType, Integer> _statusUpdates = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
@@ -563,13 +565,6 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
{
|
{
|
||||||
_summoner.removeSummonedNpc(getObjectId());
|
_summoner.removeSummonedNpc(getObjectId());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stop on creature see task and clear the data
|
|
||||||
if (_seenCreatures != null)
|
|
||||||
{
|
|
||||||
_seenCreatures.stop();
|
|
||||||
_seenCreatures.reset();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -577,12 +572,6 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
{
|
{
|
||||||
super.onSpawn();
|
super.onSpawn();
|
||||||
revalidateZone(true);
|
revalidateZone(true);
|
||||||
|
|
||||||
// restart task
|
|
||||||
if (_seenCreatures != null)
|
|
||||||
{
|
|
||||||
_seenCreatures.start();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized void onTeleported()
|
public synchronized void onTeleported()
|
||||||
@@ -591,6 +580,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
spawnMe(getX(), getY(), getZ());
|
spawnMe(getX(), getY(), getZ());
|
||||||
setTeleporting(false);
|
setTeleporting(false);
|
||||||
EventDispatcher.getInstance().notifyEventAsync(new OnCreatureTeleported(this), this);
|
EventDispatcher.getInstance().notifyEventAsync(new OnCreatureTeleported(this), this);
|
||||||
@@ -1727,6 +1717,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
{
|
{
|
||||||
getSkillChannelized().abortChannelization();
|
getSkillChannelized().abortChannelization();
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1757,6 +1748,12 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
// Remove all active, passive and option effects, do not broadcast changes.
|
// Remove all active, passive and option effects, do not broadcast changes.
|
||||||
_effectList.stopAllEffectsWithoutExclusions(false, false);
|
_effectList.stopAllEffectsWithoutExclusions(false, false);
|
||||||
|
|
||||||
|
// Forget all seen creatures.
|
||||||
|
if (_seenCreatures != null)
|
||||||
|
{
|
||||||
|
_seenCreatures.clear();
|
||||||
|
}
|
||||||
|
|
||||||
// Cancel the BuffFinishTask related to this creature.
|
// Cancel the BuffFinishTask related to this creature.
|
||||||
cancelBuffFinishTask();
|
cancelBuffFinishTask();
|
||||||
|
|
||||||
@@ -5427,22 +5424,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
return _blockActionsAllowedSkills.containsKey(skill.getId());
|
return _blockActionsAllowedSkills.containsKey(skill.getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public void initSeenCreatures()
|
||||||
* Initialize creature container that looks up for creatures around its owner, and notifies with onCreatureSee upon discovery.
|
|
||||||
* @param range
|
|
||||||
*/
|
|
||||||
public void initSeenCreatures(int range)
|
|
||||||
{
|
|
||||||
initSeenCreatures(range, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialize creature container that looks up for creatures around its owner, and notifies with onCreatureSee upon discovery.<br>
|
|
||||||
* <i>The condition can be null</i>
|
|
||||||
* @param range
|
|
||||||
* @param condition
|
|
||||||
*/
|
|
||||||
public void initSeenCreatures(int range, Predicate<Creature> condition)
|
|
||||||
{
|
{
|
||||||
if (_seenCreatures == null)
|
if (_seenCreatures == null)
|
||||||
{
|
{
|
||||||
@@ -5450,15 +5432,45 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
{
|
{
|
||||||
if (_seenCreatures == null)
|
if (_seenCreatures == null)
|
||||||
{
|
{
|
||||||
_seenCreatures = new CreatureContainer(this, range, condition);
|
if (isNpc())
|
||||||
|
{
|
||||||
|
final NpcTemplate template = ((Npc) this).getTemplate();
|
||||||
|
if ((template != null) && (template.getAggroRange() > 0))
|
||||||
|
{
|
||||||
|
_seenCreatureRange = template.getAggroRange();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_seenCreatures = ConcurrentHashMap.newKeySet(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public CreatureContainer getSeenCreatures()
|
public void updateSeenCreatures()
|
||||||
{
|
{
|
||||||
return _seenCreatures;
|
if ((_seenCreatures == null) || _isDead || !isSpawned())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
World.getInstance().forEachVisibleObjectInRange(this, Creature.class, _seenCreatureRange, creature ->
|
||||||
|
{
|
||||||
|
if (_seenCreatures.add(creature))
|
||||||
|
{
|
||||||
|
EventDispatcher.getInstance().notifyEventAsync(new OnCreatureSee(this, creature), this);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeSeenCreature(WorldObject worldObject)
|
||||||
|
{
|
||||||
|
if (_seenCreatures == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_seenCreatures.remove(worldObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
public MoveType getMoveType()
|
public MoveType getMoveType()
|
||||||
|
|||||||
@@ -1832,14 +1832,6 @@ public class Npc extends Creature
|
|||||||
return Rnd.get(100) < Rnd.get(getTemplate().getMinSkillChance(), getTemplate().getMaxSkillChance());
|
return Rnd.get(100) < Rnd.get(getTemplate().getMinSkillChance(), getTemplate().getMaxSkillChance());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialize creature container that looks up for creatures around its owner, and notifies with onCreatureSee upon discovery.
|
|
||||||
*/
|
|
||||||
public void initSeenCreatures()
|
|
||||||
{
|
|
||||||
initSeenCreatures(getTemplate().getAggroRange());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the NpcStringId for name
|
* @return the NpcStringId for name
|
||||||
*/
|
*/
|
||||||
|
|||||||
+14
-3
@@ -937,6 +937,17 @@ public abstract class AbstractScript extends ManagedScript implements IEventTime
|
|||||||
return registerConsumer(callback, EventType.ON_NPC_CREATURE_SEE, ListenerRegisterType.NPC, npcIds);
|
return registerConsumer(callback, EventType.ON_NPC_CREATURE_SEE, ListenerRegisterType.NPC, npcIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides instant callback operation when {@link Npc} sees another creature.
|
||||||
|
* @param callback
|
||||||
|
* @param npcIds
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
protected final List<AbstractEventListener> setNpcCreatureSeeId(Consumer<OnNpcCreatureSee> callback, Collection<Integer> npcIds)
|
||||||
|
{
|
||||||
|
return registerConsumer(callback, EventType.ON_NPC_CREATURE_SEE, ListenerRegisterType.NPC, npcIds);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides instant callback operation when {@link Creature} sees another creature.
|
* Provides instant callback operation when {@link Creature} sees another creature.
|
||||||
* @param callback
|
* @param callback
|
||||||
@@ -949,14 +960,14 @@ public abstract class AbstractScript extends ManagedScript implements IEventTime
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides instant callback operation when {@link Npc} sees another creature.
|
* Provides instant callback operation when {@link Creature} sees another creature.
|
||||||
* @param callback
|
* @param callback
|
||||||
* @param npcIds
|
* @param npcIds
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
protected final List<AbstractEventListener> setNpcCreatureSeeId(Consumer<OnNpcCreatureSee> callback, Collection<Integer> npcIds)
|
protected final List<AbstractEventListener> setCreatureSeeId(Consumer<OnCreatureSee> callback, Collection<Integer> npcIds)
|
||||||
{
|
{
|
||||||
return registerConsumer(callback, EventType.ON_NPC_CREATURE_SEE, ListenerRegisterType.NPC, npcIds);
|
return registerConsumer(callback, EventType.ON_CREATURE_SEE, ListenerRegisterType.NPC, npcIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -254,6 +254,7 @@ public abstract class AbstractAI implements Ctrl
|
|||||||
{
|
{
|
||||||
case EVT_THINK:
|
case EVT_THINK:
|
||||||
{
|
{
|
||||||
|
_actor.updateSeenCreatures();
|
||||||
onEvtThink();
|
onEvtThink();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -325,7 +326,9 @@ public abstract class AbstractAI implements Ctrl
|
|||||||
}
|
}
|
||||||
case EVT_FORGET_OBJECT:
|
case EVT_FORGET_OBJECT:
|
||||||
{
|
{
|
||||||
onEvtForgetObject((WorldObject) arg0);
|
final WorldObject worldObject = (WorldObject) arg0;
|
||||||
|
_actor.removeSeenCreature(worldObject);
|
||||||
|
onEvtForgetObject(worldObject);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case EVT_CANCEL:
|
case EVT_CANCEL:
|
||||||
|
|||||||
-106
@@ -1,106 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of the L2J Mobius project.
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
package org.l2jmobius.gameserver.model;
|
|
||||||
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
|
||||||
import java.util.concurrent.ScheduledFuture;
|
|
||||||
import java.util.function.Predicate;
|
|
||||||
|
|
||||||
import org.l2jmobius.commons.concurrent.ThreadPool;
|
|
||||||
import org.l2jmobius.gameserver.model.actor.Creature;
|
|
||||||
import org.l2jmobius.gameserver.model.events.EventDispatcher;
|
|
||||||
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureSee;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author UnAfraid
|
|
||||||
*/
|
|
||||||
public class CreatureContainer
|
|
||||||
{
|
|
||||||
private final Set<Integer> _seen = ConcurrentHashMap.newKeySet();
|
|
||||||
private final Creature _owner;
|
|
||||||
private final int _range;
|
|
||||||
private ScheduledFuture<?> _task;
|
|
||||||
private Predicate<Creature> _condition = null;
|
|
||||||
|
|
||||||
public CreatureContainer(Creature owner, int range, Predicate<Creature> condition)
|
|
||||||
{
|
|
||||||
_owner = owner;
|
|
||||||
_range = range;
|
|
||||||
_condition = condition;
|
|
||||||
start();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Creature getOwner()
|
|
||||||
{
|
|
||||||
return _owner;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getRange()
|
|
||||||
{
|
|
||||||
return _range;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Starts the task that scans for new creatures
|
|
||||||
*/
|
|
||||||
public void start()
|
|
||||||
{
|
|
||||||
if ((_task == null) || _task.isDone())
|
|
||||||
{
|
|
||||||
_task = ThreadPool.scheduleAtFixedRate(this::update, 1000, 1000);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return {@code false} if the task could not be cancelled, typically because it has already completed normally; {@code true} otherwise
|
|
||||||
*/
|
|
||||||
public boolean stop()
|
|
||||||
{
|
|
||||||
return (_task != null) && !_task.isDone() && _task.cancel(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Resets the creatures container, all previously seen creature will be discarded and next time update method is called will notify for each creature that owner sees!
|
|
||||||
*/
|
|
||||||
public void reset()
|
|
||||||
{
|
|
||||||
_seen.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Scans around the npc and notifies about new creature owner seen
|
|
||||||
*/
|
|
||||||
private void update()
|
|
||||||
{
|
|
||||||
final Set<Integer> verified = new HashSet<>();
|
|
||||||
World.getInstance().forEachVisibleObjectInRange(_owner, Creature.class, _range, creature ->
|
|
||||||
{
|
|
||||||
if ((_condition == null) || _condition.test(creature))
|
|
||||||
{
|
|
||||||
if (_seen.add(creature.getObjectId()))
|
|
||||||
{
|
|
||||||
EventDispatcher.getInstance().notifyEventAsync(new OnCreatureSee(_owner, creature), _owner);
|
|
||||||
}
|
|
||||||
verified.add(creature.getObjectId());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
_seen.retainAll(verified);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+46
-34
@@ -69,7 +69,6 @@ import org.l2jmobius.gameserver.instancemanager.MapRegionManager;
|
|||||||
import org.l2jmobius.gameserver.instancemanager.QuestManager;
|
import org.l2jmobius.gameserver.instancemanager.QuestManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.ZoneManager;
|
import org.l2jmobius.gameserver.instancemanager.ZoneManager;
|
||||||
import org.l2jmobius.gameserver.model.AccessLevel;
|
import org.l2jmobius.gameserver.model.AccessLevel;
|
||||||
import org.l2jmobius.gameserver.model.CreatureContainer;
|
|
||||||
import org.l2jmobius.gameserver.model.EffectList;
|
import org.l2jmobius.gameserver.model.EffectList;
|
||||||
import org.l2jmobius.gameserver.model.Hit;
|
import org.l2jmobius.gameserver.model.Hit;
|
||||||
import org.l2jmobius.gameserver.model.Location;
|
import org.l2jmobius.gameserver.model.Location;
|
||||||
@@ -88,6 +87,7 @@ import org.l2jmobius.gameserver.model.actor.stat.CreatureStat;
|
|||||||
import org.l2jmobius.gameserver.model.actor.status.CreatureStatus;
|
import org.l2jmobius.gameserver.model.actor.status.CreatureStatus;
|
||||||
import org.l2jmobius.gameserver.model.actor.tasks.creature.NotifyAITask;
|
import org.l2jmobius.gameserver.model.actor.tasks.creature.NotifyAITask;
|
||||||
import org.l2jmobius.gameserver.model.actor.templates.CreatureTemplate;
|
import org.l2jmobius.gameserver.model.actor.templates.CreatureTemplate;
|
||||||
|
import org.l2jmobius.gameserver.model.actor.templates.NpcTemplate;
|
||||||
import org.l2jmobius.gameserver.model.actor.transform.Transform;
|
import org.l2jmobius.gameserver.model.actor.transform.Transform;
|
||||||
import org.l2jmobius.gameserver.model.clan.Clan;
|
import org.l2jmobius.gameserver.model.clan.Clan;
|
||||||
import org.l2jmobius.gameserver.model.effects.EffectFlag;
|
import org.l2jmobius.gameserver.model.effects.EffectFlag;
|
||||||
@@ -101,6 +101,7 @@ import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureDamageDealt
|
|||||||
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureDamageReceived;
|
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureDamageReceived;
|
||||||
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureDeath;
|
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureDeath;
|
||||||
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureKilled;
|
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureKilled;
|
||||||
|
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureSee;
|
||||||
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureTeleport;
|
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureTeleport;
|
||||||
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureTeleported;
|
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureTeleported;
|
||||||
import org.l2jmobius.gameserver.model.events.listeners.AbstractEventListener;
|
import org.l2jmobius.gameserver.model.events.listeners.AbstractEventListener;
|
||||||
@@ -271,7 +272,8 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
|
|
||||||
private final Map<Integer, RelationCache> _knownRelations = new ConcurrentHashMap<>();
|
private final Map<Integer, RelationCache> _knownRelations = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
private CreatureContainer _seenCreatures;
|
private Set<Creature> _seenCreatures = null;
|
||||||
|
private int _seenCreatureRange = Config.ALT_PARTY_RANGE;
|
||||||
|
|
||||||
private final Map<StatusUpdateType, Integer> _statusUpdates = new ConcurrentHashMap<>();
|
private final Map<StatusUpdateType, Integer> _statusUpdates = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
@@ -563,13 +565,6 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
{
|
{
|
||||||
_summoner.removeSummonedNpc(getObjectId());
|
_summoner.removeSummonedNpc(getObjectId());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stop on creature see task and clear the data
|
|
||||||
if (_seenCreatures != null)
|
|
||||||
{
|
|
||||||
_seenCreatures.stop();
|
|
||||||
_seenCreatures.reset();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -577,12 +572,6 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
{
|
{
|
||||||
super.onSpawn();
|
super.onSpawn();
|
||||||
revalidateZone(true);
|
revalidateZone(true);
|
||||||
|
|
||||||
// restart task
|
|
||||||
if (_seenCreatures != null)
|
|
||||||
{
|
|
||||||
_seenCreatures.start();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized void onTeleported()
|
public synchronized void onTeleported()
|
||||||
@@ -591,6 +580,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
spawnMe(getX(), getY(), getZ());
|
spawnMe(getX(), getY(), getZ());
|
||||||
setTeleporting(false);
|
setTeleporting(false);
|
||||||
EventDispatcher.getInstance().notifyEventAsync(new OnCreatureTeleported(this), this);
|
EventDispatcher.getInstance().notifyEventAsync(new OnCreatureTeleported(this), this);
|
||||||
@@ -1727,6 +1717,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
{
|
{
|
||||||
getSkillChannelized().abortChannelization();
|
getSkillChannelized().abortChannelization();
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1757,6 +1748,12 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
// Remove all active, passive and option effects, do not broadcast changes.
|
// Remove all active, passive and option effects, do not broadcast changes.
|
||||||
_effectList.stopAllEffectsWithoutExclusions(false, false);
|
_effectList.stopAllEffectsWithoutExclusions(false, false);
|
||||||
|
|
||||||
|
// Forget all seen creatures.
|
||||||
|
if (_seenCreatures != null)
|
||||||
|
{
|
||||||
|
_seenCreatures.clear();
|
||||||
|
}
|
||||||
|
|
||||||
// Cancel the BuffFinishTask related to this creature.
|
// Cancel the BuffFinishTask related to this creature.
|
||||||
cancelBuffFinishTask();
|
cancelBuffFinishTask();
|
||||||
|
|
||||||
@@ -5427,22 +5424,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
return _blockActionsAllowedSkills.containsKey(skill.getId());
|
return _blockActionsAllowedSkills.containsKey(skill.getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public void initSeenCreatures()
|
||||||
* Initialize creature container that looks up for creatures around its owner, and notifies with onCreatureSee upon discovery.
|
|
||||||
* @param range
|
|
||||||
*/
|
|
||||||
public void initSeenCreatures(int range)
|
|
||||||
{
|
|
||||||
initSeenCreatures(range, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialize creature container that looks up for creatures around its owner, and notifies with onCreatureSee upon discovery.<br>
|
|
||||||
* <i>The condition can be null</i>
|
|
||||||
* @param range
|
|
||||||
* @param condition
|
|
||||||
*/
|
|
||||||
public void initSeenCreatures(int range, Predicate<Creature> condition)
|
|
||||||
{
|
{
|
||||||
if (_seenCreatures == null)
|
if (_seenCreatures == null)
|
||||||
{
|
{
|
||||||
@@ -5450,15 +5432,45 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
{
|
{
|
||||||
if (_seenCreatures == null)
|
if (_seenCreatures == null)
|
||||||
{
|
{
|
||||||
_seenCreatures = new CreatureContainer(this, range, condition);
|
if (isNpc())
|
||||||
|
{
|
||||||
|
final NpcTemplate template = ((Npc) this).getTemplate();
|
||||||
|
if ((template != null) && (template.getAggroRange() > 0))
|
||||||
|
{
|
||||||
|
_seenCreatureRange = template.getAggroRange();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_seenCreatures = ConcurrentHashMap.newKeySet(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public CreatureContainer getSeenCreatures()
|
public void updateSeenCreatures()
|
||||||
{
|
{
|
||||||
return _seenCreatures;
|
if ((_seenCreatures == null) || _isDead || !isSpawned())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
World.getInstance().forEachVisibleObjectInRange(this, Creature.class, _seenCreatureRange, creature ->
|
||||||
|
{
|
||||||
|
if (_seenCreatures.add(creature))
|
||||||
|
{
|
||||||
|
EventDispatcher.getInstance().notifyEventAsync(new OnCreatureSee(this, creature), this);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeSeenCreature(WorldObject worldObject)
|
||||||
|
{
|
||||||
|
if (_seenCreatures == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_seenCreatures.remove(worldObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
public MoveType getMoveType()
|
public MoveType getMoveType()
|
||||||
|
|||||||
@@ -1832,14 +1832,6 @@ public class Npc extends Creature
|
|||||||
return Rnd.get(100) < Rnd.get(getTemplate().getMinSkillChance(), getTemplate().getMaxSkillChance());
|
return Rnd.get(100) < Rnd.get(getTemplate().getMinSkillChance(), getTemplate().getMaxSkillChance());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialize creature container that looks up for creatures around its owner, and notifies with onCreatureSee upon discovery.
|
|
||||||
*/
|
|
||||||
public void initSeenCreatures()
|
|
||||||
{
|
|
||||||
initSeenCreatures(getTemplate().getAggroRange());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the NpcStringId for name
|
* @return the NpcStringId for name
|
||||||
*/
|
*/
|
||||||
|
|||||||
+14
-3
@@ -937,6 +937,17 @@ public abstract class AbstractScript extends ManagedScript implements IEventTime
|
|||||||
return registerConsumer(callback, EventType.ON_NPC_CREATURE_SEE, ListenerRegisterType.NPC, npcIds);
|
return registerConsumer(callback, EventType.ON_NPC_CREATURE_SEE, ListenerRegisterType.NPC, npcIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides instant callback operation when {@link Npc} sees another creature.
|
||||||
|
* @param callback
|
||||||
|
* @param npcIds
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
protected final List<AbstractEventListener> setNpcCreatureSeeId(Consumer<OnNpcCreatureSee> callback, Collection<Integer> npcIds)
|
||||||
|
{
|
||||||
|
return registerConsumer(callback, EventType.ON_NPC_CREATURE_SEE, ListenerRegisterType.NPC, npcIds);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides instant callback operation when {@link Creature} sees another creature.
|
* Provides instant callback operation when {@link Creature} sees another creature.
|
||||||
* @param callback
|
* @param callback
|
||||||
@@ -949,14 +960,14 @@ public abstract class AbstractScript extends ManagedScript implements IEventTime
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides instant callback operation when {@link Npc} sees another creature.
|
* Provides instant callback operation when {@link Creature} sees another creature.
|
||||||
* @param callback
|
* @param callback
|
||||||
* @param npcIds
|
* @param npcIds
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
protected final List<AbstractEventListener> setNpcCreatureSeeId(Consumer<OnNpcCreatureSee> callback, Collection<Integer> npcIds)
|
protected final List<AbstractEventListener> setCreatureSeeId(Consumer<OnCreatureSee> callback, Collection<Integer> npcIds)
|
||||||
{
|
{
|
||||||
return registerConsumer(callback, EventType.ON_NPC_CREATURE_SEE, ListenerRegisterType.NPC, npcIds);
|
return registerConsumer(callback, EventType.ON_CREATURE_SEE, ListenerRegisterType.NPC, npcIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -254,6 +254,7 @@ public abstract class AbstractAI implements Ctrl
|
|||||||
{
|
{
|
||||||
case EVT_THINK:
|
case EVT_THINK:
|
||||||
{
|
{
|
||||||
|
_actor.updateSeenCreatures();
|
||||||
onEvtThink();
|
onEvtThink();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -325,7 +326,9 @@ public abstract class AbstractAI implements Ctrl
|
|||||||
}
|
}
|
||||||
case EVT_FORGET_OBJECT:
|
case EVT_FORGET_OBJECT:
|
||||||
{
|
{
|
||||||
onEvtForgetObject((WorldObject) arg0);
|
final WorldObject worldObject = (WorldObject) arg0;
|
||||||
|
_actor.removeSeenCreature(worldObject);
|
||||||
|
onEvtForgetObject(worldObject);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case EVT_CANCEL:
|
case EVT_CANCEL:
|
||||||
|
|||||||
-106
@@ -1,106 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of the L2J Mobius project.
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
package org.l2jmobius.gameserver.model;
|
|
||||||
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
|
||||||
import java.util.concurrent.ScheduledFuture;
|
|
||||||
import java.util.function.Predicate;
|
|
||||||
|
|
||||||
import org.l2jmobius.commons.concurrent.ThreadPool;
|
|
||||||
import org.l2jmobius.gameserver.model.actor.Creature;
|
|
||||||
import org.l2jmobius.gameserver.model.events.EventDispatcher;
|
|
||||||
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureSee;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author UnAfraid
|
|
||||||
*/
|
|
||||||
public class CreatureContainer
|
|
||||||
{
|
|
||||||
private final Set<Integer> _seen = ConcurrentHashMap.newKeySet();
|
|
||||||
private final Creature _owner;
|
|
||||||
private final int _range;
|
|
||||||
private ScheduledFuture<?> _task;
|
|
||||||
private Predicate<Creature> _condition = null;
|
|
||||||
|
|
||||||
public CreatureContainer(Creature owner, int range, Predicate<Creature> condition)
|
|
||||||
{
|
|
||||||
_owner = owner;
|
|
||||||
_range = range;
|
|
||||||
_condition = condition;
|
|
||||||
start();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Creature getOwner()
|
|
||||||
{
|
|
||||||
return _owner;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getRange()
|
|
||||||
{
|
|
||||||
return _range;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Starts the task that scans for new creatures
|
|
||||||
*/
|
|
||||||
public void start()
|
|
||||||
{
|
|
||||||
if ((_task == null) || _task.isDone())
|
|
||||||
{
|
|
||||||
_task = ThreadPool.scheduleAtFixedRate(this::update, 1000, 1000);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return {@code false} if the task could not be cancelled, typically because it has already completed normally; {@code true} otherwise
|
|
||||||
*/
|
|
||||||
public boolean stop()
|
|
||||||
{
|
|
||||||
return (_task != null) && !_task.isDone() && _task.cancel(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Resets the creatures container, all previously seen creature will be discarded and next time update method is called will notify for each creature that owner sees!
|
|
||||||
*/
|
|
||||||
public void reset()
|
|
||||||
{
|
|
||||||
_seen.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Scans around the npc and notifies about new creature owner seen
|
|
||||||
*/
|
|
||||||
private void update()
|
|
||||||
{
|
|
||||||
final Set<Integer> verified = new HashSet<>();
|
|
||||||
World.getInstance().forEachVisibleObjectInRange(_owner, Creature.class, _range, creature ->
|
|
||||||
{
|
|
||||||
if ((_condition == null) || _condition.test(creature))
|
|
||||||
{
|
|
||||||
if (_seen.add(creature.getObjectId()))
|
|
||||||
{
|
|
||||||
EventDispatcher.getInstance().notifyEventAsync(new OnCreatureSee(_owner, creature), _owner);
|
|
||||||
}
|
|
||||||
verified.add(creature.getObjectId());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
_seen.retainAll(verified);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+46
-34
@@ -69,7 +69,6 @@ import org.l2jmobius.gameserver.instancemanager.MapRegionManager;
|
|||||||
import org.l2jmobius.gameserver.instancemanager.QuestManager;
|
import org.l2jmobius.gameserver.instancemanager.QuestManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.ZoneManager;
|
import org.l2jmobius.gameserver.instancemanager.ZoneManager;
|
||||||
import org.l2jmobius.gameserver.model.AccessLevel;
|
import org.l2jmobius.gameserver.model.AccessLevel;
|
||||||
import org.l2jmobius.gameserver.model.CreatureContainer;
|
|
||||||
import org.l2jmobius.gameserver.model.EffectList;
|
import org.l2jmobius.gameserver.model.EffectList;
|
||||||
import org.l2jmobius.gameserver.model.Hit;
|
import org.l2jmobius.gameserver.model.Hit;
|
||||||
import org.l2jmobius.gameserver.model.Location;
|
import org.l2jmobius.gameserver.model.Location;
|
||||||
@@ -88,6 +87,7 @@ import org.l2jmobius.gameserver.model.actor.stat.CreatureStat;
|
|||||||
import org.l2jmobius.gameserver.model.actor.status.CreatureStatus;
|
import org.l2jmobius.gameserver.model.actor.status.CreatureStatus;
|
||||||
import org.l2jmobius.gameserver.model.actor.tasks.creature.NotifyAITask;
|
import org.l2jmobius.gameserver.model.actor.tasks.creature.NotifyAITask;
|
||||||
import org.l2jmobius.gameserver.model.actor.templates.CreatureTemplate;
|
import org.l2jmobius.gameserver.model.actor.templates.CreatureTemplate;
|
||||||
|
import org.l2jmobius.gameserver.model.actor.templates.NpcTemplate;
|
||||||
import org.l2jmobius.gameserver.model.actor.transform.Transform;
|
import org.l2jmobius.gameserver.model.actor.transform.Transform;
|
||||||
import org.l2jmobius.gameserver.model.clan.Clan;
|
import org.l2jmobius.gameserver.model.clan.Clan;
|
||||||
import org.l2jmobius.gameserver.model.effects.EffectFlag;
|
import org.l2jmobius.gameserver.model.effects.EffectFlag;
|
||||||
@@ -101,6 +101,7 @@ import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureDamageDealt
|
|||||||
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureDamageReceived;
|
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureDamageReceived;
|
||||||
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureDeath;
|
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureDeath;
|
||||||
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureKilled;
|
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureKilled;
|
||||||
|
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureSee;
|
||||||
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureTeleport;
|
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureTeleport;
|
||||||
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureTeleported;
|
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureTeleported;
|
||||||
import org.l2jmobius.gameserver.model.events.listeners.AbstractEventListener;
|
import org.l2jmobius.gameserver.model.events.listeners.AbstractEventListener;
|
||||||
@@ -271,7 +272,8 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
|
|
||||||
private final Map<Integer, RelationCache> _knownRelations = new ConcurrentHashMap<>();
|
private final Map<Integer, RelationCache> _knownRelations = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
private CreatureContainer _seenCreatures;
|
private Set<Creature> _seenCreatures = null;
|
||||||
|
private int _seenCreatureRange = Config.ALT_PARTY_RANGE;
|
||||||
|
|
||||||
private final Map<StatusUpdateType, Integer> _statusUpdates = new ConcurrentHashMap<>();
|
private final Map<StatusUpdateType, Integer> _statusUpdates = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
@@ -563,13 +565,6 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
{
|
{
|
||||||
_summoner.removeSummonedNpc(getObjectId());
|
_summoner.removeSummonedNpc(getObjectId());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stop on creature see task and clear the data
|
|
||||||
if (_seenCreatures != null)
|
|
||||||
{
|
|
||||||
_seenCreatures.stop();
|
|
||||||
_seenCreatures.reset();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -577,12 +572,6 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
{
|
{
|
||||||
super.onSpawn();
|
super.onSpawn();
|
||||||
revalidateZone(true);
|
revalidateZone(true);
|
||||||
|
|
||||||
// restart task
|
|
||||||
if (_seenCreatures != null)
|
|
||||||
{
|
|
||||||
_seenCreatures.start();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized void onTeleported()
|
public synchronized void onTeleported()
|
||||||
@@ -591,6 +580,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
spawnMe(getX(), getY(), getZ());
|
spawnMe(getX(), getY(), getZ());
|
||||||
setTeleporting(false);
|
setTeleporting(false);
|
||||||
EventDispatcher.getInstance().notifyEventAsync(new OnCreatureTeleported(this), this);
|
EventDispatcher.getInstance().notifyEventAsync(new OnCreatureTeleported(this), this);
|
||||||
@@ -1727,6 +1717,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
{
|
{
|
||||||
getSkillChannelized().abortChannelization();
|
getSkillChannelized().abortChannelization();
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1757,6 +1748,12 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
// Remove all active, passive and option effects, do not broadcast changes.
|
// Remove all active, passive and option effects, do not broadcast changes.
|
||||||
_effectList.stopAllEffectsWithoutExclusions(false, false);
|
_effectList.stopAllEffectsWithoutExclusions(false, false);
|
||||||
|
|
||||||
|
// Forget all seen creatures.
|
||||||
|
if (_seenCreatures != null)
|
||||||
|
{
|
||||||
|
_seenCreatures.clear();
|
||||||
|
}
|
||||||
|
|
||||||
// Cancel the BuffFinishTask related to this creature.
|
// Cancel the BuffFinishTask related to this creature.
|
||||||
cancelBuffFinishTask();
|
cancelBuffFinishTask();
|
||||||
|
|
||||||
@@ -5436,22 +5433,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
return _blockActionsAllowedSkills.containsKey(skill.getId());
|
return _blockActionsAllowedSkills.containsKey(skill.getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public void initSeenCreatures()
|
||||||
* Initialize creature container that looks up for creatures around its owner, and notifies with onCreatureSee upon discovery.
|
|
||||||
* @param range
|
|
||||||
*/
|
|
||||||
public void initSeenCreatures(int range)
|
|
||||||
{
|
|
||||||
initSeenCreatures(range, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialize creature container that looks up for creatures around its owner, and notifies with onCreatureSee upon discovery.<br>
|
|
||||||
* <i>The condition can be null</i>
|
|
||||||
* @param range
|
|
||||||
* @param condition
|
|
||||||
*/
|
|
||||||
public void initSeenCreatures(int range, Predicate<Creature> condition)
|
|
||||||
{
|
{
|
||||||
if (_seenCreatures == null)
|
if (_seenCreatures == null)
|
||||||
{
|
{
|
||||||
@@ -5459,15 +5441,45 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
{
|
{
|
||||||
if (_seenCreatures == null)
|
if (_seenCreatures == null)
|
||||||
{
|
{
|
||||||
_seenCreatures = new CreatureContainer(this, range, condition);
|
if (isNpc())
|
||||||
|
{
|
||||||
|
final NpcTemplate template = ((Npc) this).getTemplate();
|
||||||
|
if ((template != null) && (template.getAggroRange() > 0))
|
||||||
|
{
|
||||||
|
_seenCreatureRange = template.getAggroRange();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_seenCreatures = ConcurrentHashMap.newKeySet(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public CreatureContainer getSeenCreatures()
|
public void updateSeenCreatures()
|
||||||
{
|
{
|
||||||
return _seenCreatures;
|
if ((_seenCreatures == null) || _isDead || !isSpawned())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
World.getInstance().forEachVisibleObjectInRange(this, Creature.class, _seenCreatureRange, creature ->
|
||||||
|
{
|
||||||
|
if (_seenCreatures.add(creature))
|
||||||
|
{
|
||||||
|
EventDispatcher.getInstance().notifyEventAsync(new OnCreatureSee(this, creature), this);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeSeenCreature(WorldObject worldObject)
|
||||||
|
{
|
||||||
|
if (_seenCreatures == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_seenCreatures.remove(worldObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
public MoveType getMoveType()
|
public MoveType getMoveType()
|
||||||
|
|||||||
@@ -1832,14 +1832,6 @@ public class Npc extends Creature
|
|||||||
return Rnd.get(100) < Rnd.get(getTemplate().getMinSkillChance(), getTemplate().getMaxSkillChance());
|
return Rnd.get(100) < Rnd.get(getTemplate().getMinSkillChance(), getTemplate().getMaxSkillChance());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialize creature container that looks up for creatures around its owner, and notifies with onCreatureSee upon discovery.
|
|
||||||
*/
|
|
||||||
public void initSeenCreatures()
|
|
||||||
{
|
|
||||||
initSeenCreatures(getTemplate().getAggroRange());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the NpcStringId for name
|
* @return the NpcStringId for name
|
||||||
*/
|
*/
|
||||||
|
|||||||
+14
-3
@@ -937,6 +937,17 @@ public abstract class AbstractScript extends ManagedScript implements IEventTime
|
|||||||
return registerConsumer(callback, EventType.ON_NPC_CREATURE_SEE, ListenerRegisterType.NPC, npcIds);
|
return registerConsumer(callback, EventType.ON_NPC_CREATURE_SEE, ListenerRegisterType.NPC, npcIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides instant callback operation when {@link Npc} sees another creature.
|
||||||
|
* @param callback
|
||||||
|
* @param npcIds
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
protected final List<AbstractEventListener> setNpcCreatureSeeId(Consumer<OnNpcCreatureSee> callback, Collection<Integer> npcIds)
|
||||||
|
{
|
||||||
|
return registerConsumer(callback, EventType.ON_NPC_CREATURE_SEE, ListenerRegisterType.NPC, npcIds);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides instant callback operation when {@link Creature} sees another creature.
|
* Provides instant callback operation when {@link Creature} sees another creature.
|
||||||
* @param callback
|
* @param callback
|
||||||
@@ -949,14 +960,14 @@ public abstract class AbstractScript extends ManagedScript implements IEventTime
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides instant callback operation when {@link Npc} sees another creature.
|
* Provides instant callback operation when {@link Creature} sees another creature.
|
||||||
* @param callback
|
* @param callback
|
||||||
* @param npcIds
|
* @param npcIds
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
protected final List<AbstractEventListener> setNpcCreatureSeeId(Consumer<OnNpcCreatureSee> callback, Collection<Integer> npcIds)
|
protected final List<AbstractEventListener> setCreatureSeeId(Consumer<OnCreatureSee> callback, Collection<Integer> npcIds)
|
||||||
{
|
{
|
||||||
return registerConsumer(callback, EventType.ON_NPC_CREATURE_SEE, ListenerRegisterType.NPC, npcIds);
|
return registerConsumer(callback, EventType.ON_CREATURE_SEE, ListenerRegisterType.NPC, npcIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -254,6 +254,7 @@ public abstract class AbstractAI implements Ctrl
|
|||||||
{
|
{
|
||||||
case EVT_THINK:
|
case EVT_THINK:
|
||||||
{
|
{
|
||||||
|
_actor.updateSeenCreatures();
|
||||||
onEvtThink();
|
onEvtThink();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -325,7 +326,9 @@ public abstract class AbstractAI implements Ctrl
|
|||||||
}
|
}
|
||||||
case EVT_FORGET_OBJECT:
|
case EVT_FORGET_OBJECT:
|
||||||
{
|
{
|
||||||
onEvtForgetObject((WorldObject) arg0);
|
final WorldObject worldObject = (WorldObject) arg0;
|
||||||
|
_actor.removeSeenCreature(worldObject);
|
||||||
|
onEvtForgetObject(worldObject);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case EVT_CANCEL:
|
case EVT_CANCEL:
|
||||||
|
|||||||
-106
@@ -1,106 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of the L2J Mobius project.
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
package org.l2jmobius.gameserver.model;
|
|
||||||
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
|
||||||
import java.util.concurrent.ScheduledFuture;
|
|
||||||
import java.util.function.Predicate;
|
|
||||||
|
|
||||||
import org.l2jmobius.commons.concurrent.ThreadPool;
|
|
||||||
import org.l2jmobius.gameserver.model.actor.Creature;
|
|
||||||
import org.l2jmobius.gameserver.model.events.EventDispatcher;
|
|
||||||
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureSee;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author UnAfraid
|
|
||||||
*/
|
|
||||||
public class CreatureContainer
|
|
||||||
{
|
|
||||||
private final Set<Integer> _seen = ConcurrentHashMap.newKeySet();
|
|
||||||
private final Creature _owner;
|
|
||||||
private final int _range;
|
|
||||||
private ScheduledFuture<?> _task;
|
|
||||||
private Predicate<Creature> _condition = null;
|
|
||||||
|
|
||||||
public CreatureContainer(Creature owner, int range, Predicate<Creature> condition)
|
|
||||||
{
|
|
||||||
_owner = owner;
|
|
||||||
_range = range;
|
|
||||||
_condition = condition;
|
|
||||||
start();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Creature getOwner()
|
|
||||||
{
|
|
||||||
return _owner;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getRange()
|
|
||||||
{
|
|
||||||
return _range;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Starts the task that scans for new creatures
|
|
||||||
*/
|
|
||||||
public void start()
|
|
||||||
{
|
|
||||||
if ((_task == null) || _task.isDone())
|
|
||||||
{
|
|
||||||
_task = ThreadPool.scheduleAtFixedRate(this::update, 1000, 1000);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return {@code false} if the task could not be cancelled, typically because it has already completed normally; {@code true} otherwise
|
|
||||||
*/
|
|
||||||
public boolean stop()
|
|
||||||
{
|
|
||||||
return (_task != null) && !_task.isDone() && _task.cancel(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Resets the creatures container, all previously seen creature will be discarded and next time update method is called will notify for each creature that owner sees!
|
|
||||||
*/
|
|
||||||
public void reset()
|
|
||||||
{
|
|
||||||
_seen.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Scans around the npc and notifies about new creature owner seen
|
|
||||||
*/
|
|
||||||
private void update()
|
|
||||||
{
|
|
||||||
final Set<Integer> verified = new HashSet<>();
|
|
||||||
World.getInstance().forEachVisibleObjectInRange(_owner, Creature.class, _range, creature ->
|
|
||||||
{
|
|
||||||
if ((_condition == null) || _condition.test(creature))
|
|
||||||
{
|
|
||||||
if (_seen.add(creature.getObjectId()))
|
|
||||||
{
|
|
||||||
EventDispatcher.getInstance().notifyEventAsync(new OnCreatureSee(_owner, creature), _owner);
|
|
||||||
}
|
|
||||||
verified.add(creature.getObjectId());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
_seen.retainAll(verified);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+46
-34
@@ -70,7 +70,6 @@ import org.l2jmobius.gameserver.instancemanager.MapRegionManager;
|
|||||||
import org.l2jmobius.gameserver.instancemanager.QuestManager;
|
import org.l2jmobius.gameserver.instancemanager.QuestManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.ZoneManager;
|
import org.l2jmobius.gameserver.instancemanager.ZoneManager;
|
||||||
import org.l2jmobius.gameserver.model.AccessLevel;
|
import org.l2jmobius.gameserver.model.AccessLevel;
|
||||||
import org.l2jmobius.gameserver.model.CreatureContainer;
|
|
||||||
import org.l2jmobius.gameserver.model.EffectList;
|
import org.l2jmobius.gameserver.model.EffectList;
|
||||||
import org.l2jmobius.gameserver.model.Hit;
|
import org.l2jmobius.gameserver.model.Hit;
|
||||||
import org.l2jmobius.gameserver.model.Location;
|
import org.l2jmobius.gameserver.model.Location;
|
||||||
@@ -89,6 +88,7 @@ import org.l2jmobius.gameserver.model.actor.stat.CreatureStat;
|
|||||||
import org.l2jmobius.gameserver.model.actor.status.CreatureStatus;
|
import org.l2jmobius.gameserver.model.actor.status.CreatureStatus;
|
||||||
import org.l2jmobius.gameserver.model.actor.tasks.creature.NotifyAITask;
|
import org.l2jmobius.gameserver.model.actor.tasks.creature.NotifyAITask;
|
||||||
import org.l2jmobius.gameserver.model.actor.templates.CreatureTemplate;
|
import org.l2jmobius.gameserver.model.actor.templates.CreatureTemplate;
|
||||||
|
import org.l2jmobius.gameserver.model.actor.templates.NpcTemplate;
|
||||||
import org.l2jmobius.gameserver.model.actor.transform.Transform;
|
import org.l2jmobius.gameserver.model.actor.transform.Transform;
|
||||||
import org.l2jmobius.gameserver.model.clan.Clan;
|
import org.l2jmobius.gameserver.model.clan.Clan;
|
||||||
import org.l2jmobius.gameserver.model.effects.EffectFlag;
|
import org.l2jmobius.gameserver.model.effects.EffectFlag;
|
||||||
@@ -102,6 +102,7 @@ import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureDamageDealt
|
|||||||
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureDamageReceived;
|
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureDamageReceived;
|
||||||
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureDeath;
|
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureDeath;
|
||||||
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureKilled;
|
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureKilled;
|
||||||
|
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureSee;
|
||||||
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureTeleport;
|
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureTeleport;
|
||||||
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureTeleported;
|
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureTeleported;
|
||||||
import org.l2jmobius.gameserver.model.events.listeners.AbstractEventListener;
|
import org.l2jmobius.gameserver.model.events.listeners.AbstractEventListener;
|
||||||
@@ -272,7 +273,8 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
|
|
||||||
private final Map<Integer, RelationCache> _knownRelations = new ConcurrentHashMap<>();
|
private final Map<Integer, RelationCache> _knownRelations = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
private CreatureContainer _seenCreatures;
|
private Set<Creature> _seenCreatures = null;
|
||||||
|
private int _seenCreatureRange = Config.ALT_PARTY_RANGE;
|
||||||
|
|
||||||
private final Map<StatusUpdateType, Integer> _statusUpdates = new ConcurrentHashMap<>();
|
private final Map<StatusUpdateType, Integer> _statusUpdates = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
@@ -564,13 +566,6 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
{
|
{
|
||||||
_summoner.removeSummonedNpc(getObjectId());
|
_summoner.removeSummonedNpc(getObjectId());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stop on creature see task and clear the data
|
|
||||||
if (_seenCreatures != null)
|
|
||||||
{
|
|
||||||
_seenCreatures.stop();
|
|
||||||
_seenCreatures.reset();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -578,12 +573,6 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
{
|
{
|
||||||
super.onSpawn();
|
super.onSpawn();
|
||||||
revalidateZone(true);
|
revalidateZone(true);
|
||||||
|
|
||||||
// restart task
|
|
||||||
if (_seenCreatures != null)
|
|
||||||
{
|
|
||||||
_seenCreatures.start();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized void onTeleported()
|
public synchronized void onTeleported()
|
||||||
@@ -592,6 +581,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
spawnMe(getX(), getY(), getZ());
|
spawnMe(getX(), getY(), getZ());
|
||||||
setTeleporting(false);
|
setTeleporting(false);
|
||||||
EventDispatcher.getInstance().notifyEventAsync(new OnCreatureTeleported(this), this);
|
EventDispatcher.getInstance().notifyEventAsync(new OnCreatureTeleported(this), this);
|
||||||
@@ -1728,6 +1718,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
{
|
{
|
||||||
getSkillChannelized().abortChannelization();
|
getSkillChannelized().abortChannelization();
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1758,6 +1749,12 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
// Remove all active, passive and option effects, do not broadcast changes.
|
// Remove all active, passive and option effects, do not broadcast changes.
|
||||||
_effectList.stopAllEffectsWithoutExclusions(false, false);
|
_effectList.stopAllEffectsWithoutExclusions(false, false);
|
||||||
|
|
||||||
|
// Forget all seen creatures.
|
||||||
|
if (_seenCreatures != null)
|
||||||
|
{
|
||||||
|
_seenCreatures.clear();
|
||||||
|
}
|
||||||
|
|
||||||
// Cancel the BuffFinishTask related to this creature.
|
// Cancel the BuffFinishTask related to this creature.
|
||||||
cancelBuffFinishTask();
|
cancelBuffFinishTask();
|
||||||
|
|
||||||
@@ -5461,22 +5458,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
return _blockActionsAllowedSkills.containsKey(skill.getId());
|
return _blockActionsAllowedSkills.containsKey(skill.getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public void initSeenCreatures()
|
||||||
* Initialize creature container that looks up for creatures around its owner, and notifies with onCreatureSee upon discovery.
|
|
||||||
* @param range
|
|
||||||
*/
|
|
||||||
public void initSeenCreatures(int range)
|
|
||||||
{
|
|
||||||
initSeenCreatures(range, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialize creature container that looks up for creatures around its owner, and notifies with onCreatureSee upon discovery.<br>
|
|
||||||
* <i>The condition can be null</i>
|
|
||||||
* @param range
|
|
||||||
* @param condition
|
|
||||||
*/
|
|
||||||
public void initSeenCreatures(int range, Predicate<Creature> condition)
|
|
||||||
{
|
{
|
||||||
if (_seenCreatures == null)
|
if (_seenCreatures == null)
|
||||||
{
|
{
|
||||||
@@ -5484,15 +5466,45 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
{
|
{
|
||||||
if (_seenCreatures == null)
|
if (_seenCreatures == null)
|
||||||
{
|
{
|
||||||
_seenCreatures = new CreatureContainer(this, range, condition);
|
if (isNpc())
|
||||||
|
{
|
||||||
|
final NpcTemplate template = ((Npc) this).getTemplate();
|
||||||
|
if ((template != null) && (template.getAggroRange() > 0))
|
||||||
|
{
|
||||||
|
_seenCreatureRange = template.getAggroRange();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_seenCreatures = ConcurrentHashMap.newKeySet(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public CreatureContainer getSeenCreatures()
|
public void updateSeenCreatures()
|
||||||
{
|
{
|
||||||
return _seenCreatures;
|
if ((_seenCreatures == null) || _isDead || !isSpawned())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
World.getInstance().forEachVisibleObjectInRange(this, Creature.class, _seenCreatureRange, creature ->
|
||||||
|
{
|
||||||
|
if (_seenCreatures.add(creature))
|
||||||
|
{
|
||||||
|
EventDispatcher.getInstance().notifyEventAsync(new OnCreatureSee(this, creature), this);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeSeenCreature(WorldObject worldObject)
|
||||||
|
{
|
||||||
|
if (_seenCreatures == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_seenCreatures.remove(worldObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
public MoveType getMoveType()
|
public MoveType getMoveType()
|
||||||
|
|||||||
@@ -1844,14 +1844,6 @@ public class Npc extends Creature
|
|||||||
return Rnd.get(100) < Rnd.get(getTemplate().getMinSkillChance(), getTemplate().getMaxSkillChance());
|
return Rnd.get(100) < Rnd.get(getTemplate().getMinSkillChance(), getTemplate().getMaxSkillChance());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialize creature container that looks up for creatures around its owner, and notifies with onCreatureSee upon discovery.
|
|
||||||
*/
|
|
||||||
public void initSeenCreatures()
|
|
||||||
{
|
|
||||||
initSeenCreatures(getTemplate().getAggroRange());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the NpcStringId for name
|
* @return the NpcStringId for name
|
||||||
*/
|
*/
|
||||||
|
|||||||
+14
-3
@@ -937,6 +937,17 @@ public abstract class AbstractScript extends ManagedScript implements IEventTime
|
|||||||
return registerConsumer(callback, EventType.ON_NPC_CREATURE_SEE, ListenerRegisterType.NPC, npcIds);
|
return registerConsumer(callback, EventType.ON_NPC_CREATURE_SEE, ListenerRegisterType.NPC, npcIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides instant callback operation when {@link Npc} sees another creature.
|
||||||
|
* @param callback
|
||||||
|
* @param npcIds
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
protected final List<AbstractEventListener> setNpcCreatureSeeId(Consumer<OnNpcCreatureSee> callback, Collection<Integer> npcIds)
|
||||||
|
{
|
||||||
|
return registerConsumer(callback, EventType.ON_NPC_CREATURE_SEE, ListenerRegisterType.NPC, npcIds);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides instant callback operation when {@link Creature} sees another creature.
|
* Provides instant callback operation when {@link Creature} sees another creature.
|
||||||
* @param callback
|
* @param callback
|
||||||
@@ -949,14 +960,14 @@ public abstract class AbstractScript extends ManagedScript implements IEventTime
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides instant callback operation when {@link Npc} sees another creature.
|
* Provides instant callback operation when {@link Creature} sees another creature.
|
||||||
* @param callback
|
* @param callback
|
||||||
* @param npcIds
|
* @param npcIds
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
protected final List<AbstractEventListener> setNpcCreatureSeeId(Consumer<OnNpcCreatureSee> callback, Collection<Integer> npcIds)
|
protected final List<AbstractEventListener> setCreatureSeeId(Consumer<OnCreatureSee> callback, Collection<Integer> npcIds)
|
||||||
{
|
{
|
||||||
return registerConsumer(callback, EventType.ON_NPC_CREATURE_SEE, ListenerRegisterType.NPC, npcIds);
|
return registerConsumer(callback, EventType.ON_CREATURE_SEE, ListenerRegisterType.NPC, npcIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|||||||
+4
-1
@@ -254,6 +254,7 @@ public abstract class AbstractAI implements Ctrl
|
|||||||
{
|
{
|
||||||
case EVT_THINK:
|
case EVT_THINK:
|
||||||
{
|
{
|
||||||
|
_actor.updateSeenCreatures();
|
||||||
onEvtThink();
|
onEvtThink();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -325,7 +326,9 @@ public abstract class AbstractAI implements Ctrl
|
|||||||
}
|
}
|
||||||
case EVT_FORGET_OBJECT:
|
case EVT_FORGET_OBJECT:
|
||||||
{
|
{
|
||||||
onEvtForgetObject((WorldObject) arg0);
|
final WorldObject worldObject = (WorldObject) arg0;
|
||||||
|
_actor.removeSeenCreature(worldObject);
|
||||||
|
onEvtForgetObject(worldObject);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case EVT_CANCEL:
|
case EVT_CANCEL:
|
||||||
|
|||||||
-106
@@ -1,106 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of the L2J Mobius project.
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
package org.l2jmobius.gameserver.model;
|
|
||||||
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
|
||||||
import java.util.concurrent.ScheduledFuture;
|
|
||||||
import java.util.function.Predicate;
|
|
||||||
|
|
||||||
import org.l2jmobius.commons.concurrent.ThreadPool;
|
|
||||||
import org.l2jmobius.gameserver.model.actor.Creature;
|
|
||||||
import org.l2jmobius.gameserver.model.events.EventDispatcher;
|
|
||||||
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureSee;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author UnAfraid
|
|
||||||
*/
|
|
||||||
public class CreatureContainer
|
|
||||||
{
|
|
||||||
private final Set<Integer> _seen = ConcurrentHashMap.newKeySet();
|
|
||||||
private final Creature _owner;
|
|
||||||
private final int _range;
|
|
||||||
private ScheduledFuture<?> _task;
|
|
||||||
private Predicate<Creature> _condition = null;
|
|
||||||
|
|
||||||
public CreatureContainer(Creature owner, int range, Predicate<Creature> condition)
|
|
||||||
{
|
|
||||||
_owner = owner;
|
|
||||||
_range = range;
|
|
||||||
_condition = condition;
|
|
||||||
start();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Creature getOwner()
|
|
||||||
{
|
|
||||||
return _owner;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getRange()
|
|
||||||
{
|
|
||||||
return _range;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Starts the task that scans for new creatures
|
|
||||||
*/
|
|
||||||
public void start()
|
|
||||||
{
|
|
||||||
if ((_task == null) || _task.isDone())
|
|
||||||
{
|
|
||||||
_task = ThreadPool.scheduleAtFixedRate(this::update, 1000, 1000);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return {@code false} if the task could not be cancelled, typically because it has already completed normally; {@code true} otherwise
|
|
||||||
*/
|
|
||||||
public boolean stop()
|
|
||||||
{
|
|
||||||
return (_task != null) && !_task.isDone() && _task.cancel(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Resets the creatures container, all previously seen creature will be discarded and next time update method is called will notify for each creature that owner sees!
|
|
||||||
*/
|
|
||||||
public void reset()
|
|
||||||
{
|
|
||||||
_seen.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Scans around the npc and notifies about new creature owner seen
|
|
||||||
*/
|
|
||||||
private void update()
|
|
||||||
{
|
|
||||||
final Set<Integer> verified = new HashSet<>();
|
|
||||||
World.getInstance().forEachVisibleObjectInRange(_owner, Creature.class, _range, creature ->
|
|
||||||
{
|
|
||||||
if ((_condition == null) || _condition.test(creature))
|
|
||||||
{
|
|
||||||
if (_seen.add(creature.getObjectId()))
|
|
||||||
{
|
|
||||||
EventDispatcher.getInstance().notifyEventAsync(new OnCreatureSee(_owner, creature), _owner);
|
|
||||||
}
|
|
||||||
verified.add(creature.getObjectId());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
_seen.retainAll(verified);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+46
-34
@@ -70,7 +70,6 @@ import org.l2jmobius.gameserver.instancemanager.MapRegionManager;
|
|||||||
import org.l2jmobius.gameserver.instancemanager.QuestManager;
|
import org.l2jmobius.gameserver.instancemanager.QuestManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.ZoneManager;
|
import org.l2jmobius.gameserver.instancemanager.ZoneManager;
|
||||||
import org.l2jmobius.gameserver.model.AccessLevel;
|
import org.l2jmobius.gameserver.model.AccessLevel;
|
||||||
import org.l2jmobius.gameserver.model.CreatureContainer;
|
|
||||||
import org.l2jmobius.gameserver.model.EffectList;
|
import org.l2jmobius.gameserver.model.EffectList;
|
||||||
import org.l2jmobius.gameserver.model.Hit;
|
import org.l2jmobius.gameserver.model.Hit;
|
||||||
import org.l2jmobius.gameserver.model.Location;
|
import org.l2jmobius.gameserver.model.Location;
|
||||||
@@ -89,6 +88,7 @@ import org.l2jmobius.gameserver.model.actor.stat.CreatureStat;
|
|||||||
import org.l2jmobius.gameserver.model.actor.status.CreatureStatus;
|
import org.l2jmobius.gameserver.model.actor.status.CreatureStatus;
|
||||||
import org.l2jmobius.gameserver.model.actor.tasks.creature.NotifyAITask;
|
import org.l2jmobius.gameserver.model.actor.tasks.creature.NotifyAITask;
|
||||||
import org.l2jmobius.gameserver.model.actor.templates.CreatureTemplate;
|
import org.l2jmobius.gameserver.model.actor.templates.CreatureTemplate;
|
||||||
|
import org.l2jmobius.gameserver.model.actor.templates.NpcTemplate;
|
||||||
import org.l2jmobius.gameserver.model.actor.transform.Transform;
|
import org.l2jmobius.gameserver.model.actor.transform.Transform;
|
||||||
import org.l2jmobius.gameserver.model.clan.Clan;
|
import org.l2jmobius.gameserver.model.clan.Clan;
|
||||||
import org.l2jmobius.gameserver.model.effects.EffectFlag;
|
import org.l2jmobius.gameserver.model.effects.EffectFlag;
|
||||||
@@ -102,6 +102,7 @@ import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureDamageDealt
|
|||||||
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureDamageReceived;
|
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureDamageReceived;
|
||||||
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureDeath;
|
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureDeath;
|
||||||
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureKilled;
|
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureKilled;
|
||||||
|
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureSee;
|
||||||
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureTeleport;
|
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureTeleport;
|
||||||
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureTeleported;
|
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureTeleported;
|
||||||
import org.l2jmobius.gameserver.model.events.listeners.AbstractEventListener;
|
import org.l2jmobius.gameserver.model.events.listeners.AbstractEventListener;
|
||||||
@@ -272,7 +273,8 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
|
|
||||||
private final Map<Integer, RelationCache> _knownRelations = new ConcurrentHashMap<>();
|
private final Map<Integer, RelationCache> _knownRelations = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
private CreatureContainer _seenCreatures;
|
private Set<Creature> _seenCreatures = null;
|
||||||
|
private int _seenCreatureRange = Config.ALT_PARTY_RANGE;
|
||||||
|
|
||||||
private final Map<StatusUpdateType, Integer> _statusUpdates = new ConcurrentHashMap<>();
|
private final Map<StatusUpdateType, Integer> _statusUpdates = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
@@ -564,13 +566,6 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
{
|
{
|
||||||
_summoner.removeSummonedNpc(getObjectId());
|
_summoner.removeSummonedNpc(getObjectId());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stop on creature see task and clear the data
|
|
||||||
if (_seenCreatures != null)
|
|
||||||
{
|
|
||||||
_seenCreatures.stop();
|
|
||||||
_seenCreatures.reset();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -578,12 +573,6 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
{
|
{
|
||||||
super.onSpawn();
|
super.onSpawn();
|
||||||
revalidateZone(true);
|
revalidateZone(true);
|
||||||
|
|
||||||
// restart task
|
|
||||||
if (_seenCreatures != null)
|
|
||||||
{
|
|
||||||
_seenCreatures.start();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized void onTeleported()
|
public synchronized void onTeleported()
|
||||||
@@ -592,6 +581,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
spawnMe(getX(), getY(), getZ());
|
spawnMe(getX(), getY(), getZ());
|
||||||
setTeleporting(false);
|
setTeleporting(false);
|
||||||
EventDispatcher.getInstance().notifyEventAsync(new OnCreatureTeleported(this), this);
|
EventDispatcher.getInstance().notifyEventAsync(new OnCreatureTeleported(this), this);
|
||||||
@@ -1728,6 +1718,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
{
|
{
|
||||||
getSkillChannelized().abortChannelization();
|
getSkillChannelized().abortChannelization();
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1758,6 +1749,12 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
// Remove all active, passive and option effects, do not broadcast changes.
|
// Remove all active, passive and option effects, do not broadcast changes.
|
||||||
_effectList.stopAllEffectsWithoutExclusions(false, false);
|
_effectList.stopAllEffectsWithoutExclusions(false, false);
|
||||||
|
|
||||||
|
// Forget all seen creatures.
|
||||||
|
if (_seenCreatures != null)
|
||||||
|
{
|
||||||
|
_seenCreatures.clear();
|
||||||
|
}
|
||||||
|
|
||||||
// Cancel the BuffFinishTask related to this creature.
|
// Cancel the BuffFinishTask related to this creature.
|
||||||
cancelBuffFinishTask();
|
cancelBuffFinishTask();
|
||||||
|
|
||||||
@@ -5461,22 +5458,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
return _blockActionsAllowedSkills.containsKey(skill.getId());
|
return _blockActionsAllowedSkills.containsKey(skill.getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public void initSeenCreatures()
|
||||||
* Initialize creature container that looks up for creatures around its owner, and notifies with onCreatureSee upon discovery.
|
|
||||||
* @param range
|
|
||||||
*/
|
|
||||||
public void initSeenCreatures(int range)
|
|
||||||
{
|
|
||||||
initSeenCreatures(range, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialize creature container that looks up for creatures around its owner, and notifies with onCreatureSee upon discovery.<br>
|
|
||||||
* <i>The condition can be null</i>
|
|
||||||
* @param range
|
|
||||||
* @param condition
|
|
||||||
*/
|
|
||||||
public void initSeenCreatures(int range, Predicate<Creature> condition)
|
|
||||||
{
|
{
|
||||||
if (_seenCreatures == null)
|
if (_seenCreatures == null)
|
||||||
{
|
{
|
||||||
@@ -5484,15 +5466,45 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
{
|
{
|
||||||
if (_seenCreatures == null)
|
if (_seenCreatures == null)
|
||||||
{
|
{
|
||||||
_seenCreatures = new CreatureContainer(this, range, condition);
|
if (isNpc())
|
||||||
|
{
|
||||||
|
final NpcTemplate template = ((Npc) this).getTemplate();
|
||||||
|
if ((template != null) && (template.getAggroRange() > 0))
|
||||||
|
{
|
||||||
|
_seenCreatureRange = template.getAggroRange();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_seenCreatures = ConcurrentHashMap.newKeySet(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public CreatureContainer getSeenCreatures()
|
public void updateSeenCreatures()
|
||||||
{
|
{
|
||||||
return _seenCreatures;
|
if ((_seenCreatures == null) || _isDead || !isSpawned())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
World.getInstance().forEachVisibleObjectInRange(this, Creature.class, _seenCreatureRange, creature ->
|
||||||
|
{
|
||||||
|
if (_seenCreatures.add(creature))
|
||||||
|
{
|
||||||
|
EventDispatcher.getInstance().notifyEventAsync(new OnCreatureSee(this, creature), this);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeSeenCreature(WorldObject worldObject)
|
||||||
|
{
|
||||||
|
if (_seenCreatures == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_seenCreatures.remove(worldObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
public MoveType getMoveType()
|
public MoveType getMoveType()
|
||||||
|
|||||||
-8
@@ -1844,14 +1844,6 @@ public class Npc extends Creature
|
|||||||
return Rnd.get(100) < Rnd.get(getTemplate().getMinSkillChance(), getTemplate().getMaxSkillChance());
|
return Rnd.get(100) < Rnd.get(getTemplate().getMinSkillChance(), getTemplate().getMaxSkillChance());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialize creature container that looks up for creatures around its owner, and notifies with onCreatureSee upon discovery.
|
|
||||||
*/
|
|
||||||
public void initSeenCreatures()
|
|
||||||
{
|
|
||||||
initSeenCreatures(getTemplate().getAggroRange());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the NpcStringId for name
|
* @return the NpcStringId for name
|
||||||
*/
|
*/
|
||||||
|
|||||||
+14
-3
@@ -937,6 +937,17 @@ public abstract class AbstractScript extends ManagedScript implements IEventTime
|
|||||||
return registerConsumer(callback, EventType.ON_NPC_CREATURE_SEE, ListenerRegisterType.NPC, npcIds);
|
return registerConsumer(callback, EventType.ON_NPC_CREATURE_SEE, ListenerRegisterType.NPC, npcIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides instant callback operation when {@link Npc} sees another creature.
|
||||||
|
* @param callback
|
||||||
|
* @param npcIds
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
protected final List<AbstractEventListener> setNpcCreatureSeeId(Consumer<OnNpcCreatureSee> callback, Collection<Integer> npcIds)
|
||||||
|
{
|
||||||
|
return registerConsumer(callback, EventType.ON_NPC_CREATURE_SEE, ListenerRegisterType.NPC, npcIds);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides instant callback operation when {@link Creature} sees another creature.
|
* Provides instant callback operation when {@link Creature} sees another creature.
|
||||||
* @param callback
|
* @param callback
|
||||||
@@ -949,14 +960,14 @@ public abstract class AbstractScript extends ManagedScript implements IEventTime
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides instant callback operation when {@link Npc} sees another creature.
|
* Provides instant callback operation when {@link Creature} sees another creature.
|
||||||
* @param callback
|
* @param callback
|
||||||
* @param npcIds
|
* @param npcIds
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
protected final List<AbstractEventListener> setNpcCreatureSeeId(Consumer<OnNpcCreatureSee> callback, Collection<Integer> npcIds)
|
protected final List<AbstractEventListener> setCreatureSeeId(Consumer<OnCreatureSee> callback, Collection<Integer> npcIds)
|
||||||
{
|
{
|
||||||
return registerConsumer(callback, EventType.ON_NPC_CREATURE_SEE, ListenerRegisterType.NPC, npcIds);
|
return registerConsumer(callback, EventType.ON_CREATURE_SEE, ListenerRegisterType.NPC, npcIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -254,6 +254,7 @@ public abstract class AbstractAI implements Ctrl
|
|||||||
{
|
{
|
||||||
case EVT_THINK:
|
case EVT_THINK:
|
||||||
{
|
{
|
||||||
|
_actor.updateSeenCreatures();
|
||||||
onEvtThink();
|
onEvtThink();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -325,7 +326,9 @@ public abstract class AbstractAI implements Ctrl
|
|||||||
}
|
}
|
||||||
case EVT_FORGET_OBJECT:
|
case EVT_FORGET_OBJECT:
|
||||||
{
|
{
|
||||||
onEvtForgetObject((WorldObject) arg0);
|
final WorldObject worldObject = (WorldObject) arg0;
|
||||||
|
_actor.removeSeenCreature(worldObject);
|
||||||
|
onEvtForgetObject(worldObject);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case EVT_CANCEL:
|
case EVT_CANCEL:
|
||||||
|
|||||||
-106
@@ -1,106 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of the L2J Mobius project.
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
package org.l2jmobius.gameserver.model;
|
|
||||||
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
|
||||||
import java.util.concurrent.ScheduledFuture;
|
|
||||||
import java.util.function.Predicate;
|
|
||||||
|
|
||||||
import org.l2jmobius.commons.concurrent.ThreadPool;
|
|
||||||
import org.l2jmobius.gameserver.model.actor.Creature;
|
|
||||||
import org.l2jmobius.gameserver.model.events.EventDispatcher;
|
|
||||||
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureSee;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author UnAfraid
|
|
||||||
*/
|
|
||||||
public class CreatureContainer
|
|
||||||
{
|
|
||||||
private final Set<Integer> _seen = ConcurrentHashMap.newKeySet();
|
|
||||||
private final Creature _owner;
|
|
||||||
private final int _range;
|
|
||||||
private ScheduledFuture<?> _task;
|
|
||||||
private Predicate<Creature> _condition = null;
|
|
||||||
|
|
||||||
public CreatureContainer(Creature owner, int range, Predicate<Creature> condition)
|
|
||||||
{
|
|
||||||
_owner = owner;
|
|
||||||
_range = range;
|
|
||||||
_condition = condition;
|
|
||||||
start();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Creature getOwner()
|
|
||||||
{
|
|
||||||
return _owner;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getRange()
|
|
||||||
{
|
|
||||||
return _range;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Starts the task that scans for new creatures
|
|
||||||
*/
|
|
||||||
public void start()
|
|
||||||
{
|
|
||||||
if ((_task == null) || _task.isDone())
|
|
||||||
{
|
|
||||||
_task = ThreadPool.scheduleAtFixedRate(this::update, 1000, 1000);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return {@code false} if the task could not be cancelled, typically because it has already completed normally; {@code true} otherwise
|
|
||||||
*/
|
|
||||||
public boolean stop()
|
|
||||||
{
|
|
||||||
return (_task != null) && !_task.isDone() && _task.cancel(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Resets the creatures container, all previously seen creature will be discarded and next time update method is called will notify for each creature that owner sees!
|
|
||||||
*/
|
|
||||||
public void reset()
|
|
||||||
{
|
|
||||||
_seen.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Scans around the npc and notifies about new creature owner seen
|
|
||||||
*/
|
|
||||||
private void update()
|
|
||||||
{
|
|
||||||
final Set<Integer> verified = new HashSet<>();
|
|
||||||
World.getInstance().forEachVisibleObjectInRange(_owner, Creature.class, _range, creature ->
|
|
||||||
{
|
|
||||||
if ((_condition == null) || _condition.test(creature))
|
|
||||||
{
|
|
||||||
if (_seen.add(creature.getObjectId()))
|
|
||||||
{
|
|
||||||
EventDispatcher.getInstance().notifyEventAsync(new OnCreatureSee(_owner, creature), _owner);
|
|
||||||
}
|
|
||||||
verified.add(creature.getObjectId());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
_seen.retainAll(verified);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+46
-34
@@ -70,7 +70,6 @@ import org.l2jmobius.gameserver.instancemanager.MapRegionManager;
|
|||||||
import org.l2jmobius.gameserver.instancemanager.QuestManager;
|
import org.l2jmobius.gameserver.instancemanager.QuestManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.ZoneManager;
|
import org.l2jmobius.gameserver.instancemanager.ZoneManager;
|
||||||
import org.l2jmobius.gameserver.model.AccessLevel;
|
import org.l2jmobius.gameserver.model.AccessLevel;
|
||||||
import org.l2jmobius.gameserver.model.CreatureContainer;
|
|
||||||
import org.l2jmobius.gameserver.model.EffectList;
|
import org.l2jmobius.gameserver.model.EffectList;
|
||||||
import org.l2jmobius.gameserver.model.Hit;
|
import org.l2jmobius.gameserver.model.Hit;
|
||||||
import org.l2jmobius.gameserver.model.Location;
|
import org.l2jmobius.gameserver.model.Location;
|
||||||
@@ -89,6 +88,7 @@ import org.l2jmobius.gameserver.model.actor.stat.CreatureStat;
|
|||||||
import org.l2jmobius.gameserver.model.actor.status.CreatureStatus;
|
import org.l2jmobius.gameserver.model.actor.status.CreatureStatus;
|
||||||
import org.l2jmobius.gameserver.model.actor.tasks.creature.NotifyAITask;
|
import org.l2jmobius.gameserver.model.actor.tasks.creature.NotifyAITask;
|
||||||
import org.l2jmobius.gameserver.model.actor.templates.CreatureTemplate;
|
import org.l2jmobius.gameserver.model.actor.templates.CreatureTemplate;
|
||||||
|
import org.l2jmobius.gameserver.model.actor.templates.NpcTemplate;
|
||||||
import org.l2jmobius.gameserver.model.actor.transform.Transform;
|
import org.l2jmobius.gameserver.model.actor.transform.Transform;
|
||||||
import org.l2jmobius.gameserver.model.clan.Clan;
|
import org.l2jmobius.gameserver.model.clan.Clan;
|
||||||
import org.l2jmobius.gameserver.model.effects.EffectFlag;
|
import org.l2jmobius.gameserver.model.effects.EffectFlag;
|
||||||
@@ -102,6 +102,7 @@ import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureDamageDealt
|
|||||||
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureDamageReceived;
|
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureDamageReceived;
|
||||||
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureDeath;
|
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureDeath;
|
||||||
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureKilled;
|
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureKilled;
|
||||||
|
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureSee;
|
||||||
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureTeleport;
|
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureTeleport;
|
||||||
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureTeleported;
|
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureTeleported;
|
||||||
import org.l2jmobius.gameserver.model.events.listeners.AbstractEventListener;
|
import org.l2jmobius.gameserver.model.events.listeners.AbstractEventListener;
|
||||||
@@ -272,7 +273,8 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
|
|
||||||
private final Map<Integer, RelationCache> _knownRelations = new ConcurrentHashMap<>();
|
private final Map<Integer, RelationCache> _knownRelations = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
private CreatureContainer _seenCreatures;
|
private Set<Creature> _seenCreatures = null;
|
||||||
|
private int _seenCreatureRange = Config.ALT_PARTY_RANGE;
|
||||||
|
|
||||||
private final Map<StatusUpdateType, Integer> _statusUpdates = new ConcurrentHashMap<>();
|
private final Map<StatusUpdateType, Integer> _statusUpdates = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
@@ -564,13 +566,6 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
{
|
{
|
||||||
_summoner.removeSummonedNpc(getObjectId());
|
_summoner.removeSummonedNpc(getObjectId());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stop on creature see task and clear the data
|
|
||||||
if (_seenCreatures != null)
|
|
||||||
{
|
|
||||||
_seenCreatures.stop();
|
|
||||||
_seenCreatures.reset();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -578,12 +573,6 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
{
|
{
|
||||||
super.onSpawn();
|
super.onSpawn();
|
||||||
revalidateZone(true);
|
revalidateZone(true);
|
||||||
|
|
||||||
// restart task
|
|
||||||
if (_seenCreatures != null)
|
|
||||||
{
|
|
||||||
_seenCreatures.start();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized void onTeleported()
|
public synchronized void onTeleported()
|
||||||
@@ -592,6 +581,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
spawnMe(getX(), getY(), getZ());
|
spawnMe(getX(), getY(), getZ());
|
||||||
setTeleporting(false);
|
setTeleporting(false);
|
||||||
EventDispatcher.getInstance().notifyEventAsync(new OnCreatureTeleported(this), this);
|
EventDispatcher.getInstance().notifyEventAsync(new OnCreatureTeleported(this), this);
|
||||||
@@ -1728,6 +1718,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
{
|
{
|
||||||
getSkillChannelized().abortChannelization();
|
getSkillChannelized().abortChannelization();
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1758,6 +1749,12 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
// Remove all active, passive and option effects, do not broadcast changes.
|
// Remove all active, passive and option effects, do not broadcast changes.
|
||||||
_effectList.stopAllEffectsWithoutExclusions(false, false);
|
_effectList.stopAllEffectsWithoutExclusions(false, false);
|
||||||
|
|
||||||
|
// Forget all seen creatures.
|
||||||
|
if (_seenCreatures != null)
|
||||||
|
{
|
||||||
|
_seenCreatures.clear();
|
||||||
|
}
|
||||||
|
|
||||||
// Cancel the BuffFinishTask related to this creature.
|
// Cancel the BuffFinishTask related to this creature.
|
||||||
cancelBuffFinishTask();
|
cancelBuffFinishTask();
|
||||||
|
|
||||||
@@ -5460,22 +5457,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
return _blockActionsAllowedSkills.containsKey(skill.getId());
|
return _blockActionsAllowedSkills.containsKey(skill.getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public void initSeenCreatures()
|
||||||
* Initialize creature container that looks up for creatures around its owner, and notifies with onCreatureSee upon discovery.
|
|
||||||
* @param range
|
|
||||||
*/
|
|
||||||
public void initSeenCreatures(int range)
|
|
||||||
{
|
|
||||||
initSeenCreatures(range, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialize creature container that looks up for creatures around its owner, and notifies with onCreatureSee upon discovery.<br>
|
|
||||||
* <i>The condition can be null</i>
|
|
||||||
* @param range
|
|
||||||
* @param condition
|
|
||||||
*/
|
|
||||||
public void initSeenCreatures(int range, Predicate<Creature> condition)
|
|
||||||
{
|
{
|
||||||
if (_seenCreatures == null)
|
if (_seenCreatures == null)
|
||||||
{
|
{
|
||||||
@@ -5483,15 +5465,45 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
{
|
{
|
||||||
if (_seenCreatures == null)
|
if (_seenCreatures == null)
|
||||||
{
|
{
|
||||||
_seenCreatures = new CreatureContainer(this, range, condition);
|
if (isNpc())
|
||||||
|
{
|
||||||
|
final NpcTemplate template = ((Npc) this).getTemplate();
|
||||||
|
if ((template != null) && (template.getAggroRange() > 0))
|
||||||
|
{
|
||||||
|
_seenCreatureRange = template.getAggroRange();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_seenCreatures = ConcurrentHashMap.newKeySet(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public CreatureContainer getSeenCreatures()
|
public void updateSeenCreatures()
|
||||||
{
|
{
|
||||||
return _seenCreatures;
|
if ((_seenCreatures == null) || _isDead || !isSpawned())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
World.getInstance().forEachVisibleObjectInRange(this, Creature.class, _seenCreatureRange, creature ->
|
||||||
|
{
|
||||||
|
if (_seenCreatures.add(creature))
|
||||||
|
{
|
||||||
|
EventDispatcher.getInstance().notifyEventAsync(new OnCreatureSee(this, creature), this);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeSeenCreature(WorldObject worldObject)
|
||||||
|
{
|
||||||
|
if (_seenCreatures == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_seenCreatures.remove(worldObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
public MoveType getMoveType()
|
public MoveType getMoveType()
|
||||||
|
|||||||
@@ -1844,14 +1844,6 @@ public class Npc extends Creature
|
|||||||
return Rnd.get(100) < Rnd.get(getTemplate().getMinSkillChance(), getTemplate().getMaxSkillChance());
|
return Rnd.get(100) < Rnd.get(getTemplate().getMinSkillChance(), getTemplate().getMaxSkillChance());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialize creature container that looks up for creatures around its owner, and notifies with onCreatureSee upon discovery.
|
|
||||||
*/
|
|
||||||
public void initSeenCreatures()
|
|
||||||
{
|
|
||||||
initSeenCreatures(getTemplate().getAggroRange());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the NpcStringId for name
|
* @return the NpcStringId for name
|
||||||
*/
|
*/
|
||||||
|
|||||||
+14
-3
@@ -937,6 +937,17 @@ public abstract class AbstractScript extends ManagedScript implements IEventTime
|
|||||||
return registerConsumer(callback, EventType.ON_NPC_CREATURE_SEE, ListenerRegisterType.NPC, npcIds);
|
return registerConsumer(callback, EventType.ON_NPC_CREATURE_SEE, ListenerRegisterType.NPC, npcIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides instant callback operation when {@link Npc} sees another creature.
|
||||||
|
* @param callback
|
||||||
|
* @param npcIds
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
protected final List<AbstractEventListener> setNpcCreatureSeeId(Consumer<OnNpcCreatureSee> callback, Collection<Integer> npcIds)
|
||||||
|
{
|
||||||
|
return registerConsumer(callback, EventType.ON_NPC_CREATURE_SEE, ListenerRegisterType.NPC, npcIds);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides instant callback operation when {@link Creature} sees another creature.
|
* Provides instant callback operation when {@link Creature} sees another creature.
|
||||||
* @param callback
|
* @param callback
|
||||||
@@ -949,14 +960,14 @@ public abstract class AbstractScript extends ManagedScript implements IEventTime
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides instant callback operation when {@link Npc} sees another creature.
|
* Provides instant callback operation when {@link Creature} sees another creature.
|
||||||
* @param callback
|
* @param callback
|
||||||
* @param npcIds
|
* @param npcIds
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
protected final List<AbstractEventListener> setNpcCreatureSeeId(Consumer<OnNpcCreatureSee> callback, Collection<Integer> npcIds)
|
protected final List<AbstractEventListener> setCreatureSeeId(Consumer<OnCreatureSee> callback, Collection<Integer> npcIds)
|
||||||
{
|
{
|
||||||
return registerConsumer(callback, EventType.ON_NPC_CREATURE_SEE, ListenerRegisterType.NPC, npcIds);
|
return registerConsumer(callback, EventType.ON_CREATURE_SEE, ListenerRegisterType.NPC, npcIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -254,6 +254,7 @@ public abstract class AbstractAI implements Ctrl
|
|||||||
{
|
{
|
||||||
case EVT_THINK:
|
case EVT_THINK:
|
||||||
{
|
{
|
||||||
|
_actor.updateSeenCreatures();
|
||||||
onEvtThink();
|
onEvtThink();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -325,7 +326,9 @@ public abstract class AbstractAI implements Ctrl
|
|||||||
}
|
}
|
||||||
case EVT_FORGET_OBJECT:
|
case EVT_FORGET_OBJECT:
|
||||||
{
|
{
|
||||||
onEvtForgetObject((WorldObject) arg0);
|
final WorldObject worldObject = (WorldObject) arg0;
|
||||||
|
_actor.removeSeenCreature(worldObject);
|
||||||
|
onEvtForgetObject(worldObject);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case EVT_CANCEL:
|
case EVT_CANCEL:
|
||||||
|
|||||||
-106
@@ -1,106 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of the L2J Mobius project.
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
package org.l2jmobius.gameserver.model;
|
|
||||||
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
|
||||||
import java.util.concurrent.ScheduledFuture;
|
|
||||||
import java.util.function.Predicate;
|
|
||||||
|
|
||||||
import org.l2jmobius.commons.concurrent.ThreadPool;
|
|
||||||
import org.l2jmobius.gameserver.model.actor.Creature;
|
|
||||||
import org.l2jmobius.gameserver.model.events.EventDispatcher;
|
|
||||||
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureSee;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author UnAfraid
|
|
||||||
*/
|
|
||||||
public class CreatureContainer
|
|
||||||
{
|
|
||||||
private final Set<Integer> _seen = ConcurrentHashMap.newKeySet();
|
|
||||||
private final Creature _owner;
|
|
||||||
private final int _range;
|
|
||||||
private ScheduledFuture<?> _task;
|
|
||||||
private Predicate<Creature> _condition = null;
|
|
||||||
|
|
||||||
public CreatureContainer(Creature owner, int range, Predicate<Creature> condition)
|
|
||||||
{
|
|
||||||
_owner = owner;
|
|
||||||
_range = range;
|
|
||||||
_condition = condition;
|
|
||||||
start();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Creature getOwner()
|
|
||||||
{
|
|
||||||
return _owner;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getRange()
|
|
||||||
{
|
|
||||||
return _range;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Starts the task that scans for new creatures
|
|
||||||
*/
|
|
||||||
public void start()
|
|
||||||
{
|
|
||||||
if ((_task == null) || _task.isDone())
|
|
||||||
{
|
|
||||||
_task = ThreadPool.scheduleAtFixedRate(this::update, 1000, 1000);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return {@code false} if the task could not be cancelled, typically because it has already completed normally; {@code true} otherwise
|
|
||||||
*/
|
|
||||||
public boolean stop()
|
|
||||||
{
|
|
||||||
return (_task != null) && !_task.isDone() && _task.cancel(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Resets the creatures container, all previously seen creature will be discarded and next time update method is called will notify for each creature that owner sees!
|
|
||||||
*/
|
|
||||||
public void reset()
|
|
||||||
{
|
|
||||||
_seen.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Scans around the npc and notifies about new creature owner seen
|
|
||||||
*/
|
|
||||||
private void update()
|
|
||||||
{
|
|
||||||
final Set<Integer> verified = new HashSet<>();
|
|
||||||
World.getInstance().forEachVisibleObjectInRange(_owner, Creature.class, _range, creature ->
|
|
||||||
{
|
|
||||||
if ((_condition == null) || _condition.test(creature))
|
|
||||||
{
|
|
||||||
if (_seen.add(creature.getObjectId()))
|
|
||||||
{
|
|
||||||
EventDispatcher.getInstance().notifyEventAsync(new OnCreatureSee(_owner, creature), _owner);
|
|
||||||
}
|
|
||||||
verified.add(creature.getObjectId());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
_seen.retainAll(verified);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+46
-34
@@ -69,7 +69,6 @@ import org.l2jmobius.gameserver.instancemanager.MapRegionManager;
|
|||||||
import org.l2jmobius.gameserver.instancemanager.QuestManager;
|
import org.l2jmobius.gameserver.instancemanager.QuestManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.ZoneManager;
|
import org.l2jmobius.gameserver.instancemanager.ZoneManager;
|
||||||
import org.l2jmobius.gameserver.model.AccessLevel;
|
import org.l2jmobius.gameserver.model.AccessLevel;
|
||||||
import org.l2jmobius.gameserver.model.CreatureContainer;
|
|
||||||
import org.l2jmobius.gameserver.model.EffectList;
|
import org.l2jmobius.gameserver.model.EffectList;
|
||||||
import org.l2jmobius.gameserver.model.Hit;
|
import org.l2jmobius.gameserver.model.Hit;
|
||||||
import org.l2jmobius.gameserver.model.Location;
|
import org.l2jmobius.gameserver.model.Location;
|
||||||
@@ -88,6 +87,7 @@ import org.l2jmobius.gameserver.model.actor.stat.CreatureStat;
|
|||||||
import org.l2jmobius.gameserver.model.actor.status.CreatureStatus;
|
import org.l2jmobius.gameserver.model.actor.status.CreatureStatus;
|
||||||
import org.l2jmobius.gameserver.model.actor.tasks.creature.NotifyAITask;
|
import org.l2jmobius.gameserver.model.actor.tasks.creature.NotifyAITask;
|
||||||
import org.l2jmobius.gameserver.model.actor.templates.CreatureTemplate;
|
import org.l2jmobius.gameserver.model.actor.templates.CreatureTemplate;
|
||||||
|
import org.l2jmobius.gameserver.model.actor.templates.NpcTemplate;
|
||||||
import org.l2jmobius.gameserver.model.actor.transform.Transform;
|
import org.l2jmobius.gameserver.model.actor.transform.Transform;
|
||||||
import org.l2jmobius.gameserver.model.clan.Clan;
|
import org.l2jmobius.gameserver.model.clan.Clan;
|
||||||
import org.l2jmobius.gameserver.model.effects.EffectFlag;
|
import org.l2jmobius.gameserver.model.effects.EffectFlag;
|
||||||
@@ -101,6 +101,7 @@ import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureDamageDealt
|
|||||||
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureDamageReceived;
|
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureDamageReceived;
|
||||||
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureDeath;
|
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureDeath;
|
||||||
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureKilled;
|
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureKilled;
|
||||||
|
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureSee;
|
||||||
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureTeleport;
|
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureTeleport;
|
||||||
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureTeleported;
|
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureTeleported;
|
||||||
import org.l2jmobius.gameserver.model.events.listeners.AbstractEventListener;
|
import org.l2jmobius.gameserver.model.events.listeners.AbstractEventListener;
|
||||||
@@ -271,7 +272,8 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
|
|
||||||
private final Map<Integer, RelationCache> _knownRelations = new ConcurrentHashMap<>();
|
private final Map<Integer, RelationCache> _knownRelations = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
private CreatureContainer _seenCreatures;
|
private Set<Creature> _seenCreatures = null;
|
||||||
|
private int _seenCreatureRange = Config.ALT_PARTY_RANGE;
|
||||||
|
|
||||||
private final Map<StatusUpdateType, Integer> _statusUpdates = new ConcurrentHashMap<>();
|
private final Map<StatusUpdateType, Integer> _statusUpdates = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
@@ -563,13 +565,6 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
{
|
{
|
||||||
_summoner.removeSummonedNpc(getObjectId());
|
_summoner.removeSummonedNpc(getObjectId());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stop on creature see task and clear the data
|
|
||||||
if (_seenCreatures != null)
|
|
||||||
{
|
|
||||||
_seenCreatures.stop();
|
|
||||||
_seenCreatures.reset();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -577,12 +572,6 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
{
|
{
|
||||||
super.onSpawn();
|
super.onSpawn();
|
||||||
revalidateZone(true);
|
revalidateZone(true);
|
||||||
|
|
||||||
// restart task
|
|
||||||
if (_seenCreatures != null)
|
|
||||||
{
|
|
||||||
_seenCreatures.start();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized void onTeleported()
|
public synchronized void onTeleported()
|
||||||
@@ -591,6 +580,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
spawnMe(getX(), getY(), getZ());
|
spawnMe(getX(), getY(), getZ());
|
||||||
setTeleporting(false);
|
setTeleporting(false);
|
||||||
EventDispatcher.getInstance().notifyEventAsync(new OnCreatureTeleported(this), this);
|
EventDispatcher.getInstance().notifyEventAsync(new OnCreatureTeleported(this), this);
|
||||||
@@ -1727,6 +1717,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
{
|
{
|
||||||
getSkillChannelized().abortChannelization();
|
getSkillChannelized().abortChannelization();
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1757,6 +1748,12 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
// Remove all active, passive and option effects, do not broadcast changes.
|
// Remove all active, passive and option effects, do not broadcast changes.
|
||||||
_effectList.stopAllEffectsWithoutExclusions(false, false);
|
_effectList.stopAllEffectsWithoutExclusions(false, false);
|
||||||
|
|
||||||
|
// Forget all seen creatures.
|
||||||
|
if (_seenCreatures != null)
|
||||||
|
{
|
||||||
|
_seenCreatures.clear();
|
||||||
|
}
|
||||||
|
|
||||||
// Cancel the BuffFinishTask related to this creature.
|
// Cancel the BuffFinishTask related to this creature.
|
||||||
cancelBuffFinishTask();
|
cancelBuffFinishTask();
|
||||||
|
|
||||||
@@ -5427,22 +5424,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
return _blockActionsAllowedSkills.containsKey(skill.getId());
|
return _blockActionsAllowedSkills.containsKey(skill.getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public void initSeenCreatures()
|
||||||
* Initialize creature container that looks up for creatures around its owner, and notifies with onCreatureSee upon discovery.
|
|
||||||
* @param range
|
|
||||||
*/
|
|
||||||
public void initSeenCreatures(int range)
|
|
||||||
{
|
|
||||||
initSeenCreatures(range, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialize creature container that looks up for creatures around its owner, and notifies with onCreatureSee upon discovery.<br>
|
|
||||||
* <i>The condition can be null</i>
|
|
||||||
* @param range
|
|
||||||
* @param condition
|
|
||||||
*/
|
|
||||||
public void initSeenCreatures(int range, Predicate<Creature> condition)
|
|
||||||
{
|
{
|
||||||
if (_seenCreatures == null)
|
if (_seenCreatures == null)
|
||||||
{
|
{
|
||||||
@@ -5450,15 +5432,45 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
{
|
{
|
||||||
if (_seenCreatures == null)
|
if (_seenCreatures == null)
|
||||||
{
|
{
|
||||||
_seenCreatures = new CreatureContainer(this, range, condition);
|
if (isNpc())
|
||||||
|
{
|
||||||
|
final NpcTemplate template = ((Npc) this).getTemplate();
|
||||||
|
if ((template != null) && (template.getAggroRange() > 0))
|
||||||
|
{
|
||||||
|
_seenCreatureRange = template.getAggroRange();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_seenCreatures = ConcurrentHashMap.newKeySet(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public CreatureContainer getSeenCreatures()
|
public void updateSeenCreatures()
|
||||||
{
|
{
|
||||||
return _seenCreatures;
|
if ((_seenCreatures == null) || _isDead || !isSpawned())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
World.getInstance().forEachVisibleObjectInRange(this, Creature.class, _seenCreatureRange, creature ->
|
||||||
|
{
|
||||||
|
if (_seenCreatures.add(creature))
|
||||||
|
{
|
||||||
|
EventDispatcher.getInstance().notifyEventAsync(new OnCreatureSee(this, creature), this);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeSeenCreature(WorldObject worldObject)
|
||||||
|
{
|
||||||
|
if (_seenCreatures == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_seenCreatures.remove(worldObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
public MoveType getMoveType()
|
public MoveType getMoveType()
|
||||||
|
|||||||
@@ -1816,14 +1816,6 @@ public class Npc extends Creature
|
|||||||
return Rnd.get(100) < Rnd.get(getTemplate().getMinSkillChance(), getTemplate().getMaxSkillChance());
|
return Rnd.get(100) < Rnd.get(getTemplate().getMinSkillChance(), getTemplate().getMaxSkillChance());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialize creature container that looks up for creatures around its owner, and notifies with onCreatureSee upon discovery.
|
|
||||||
*/
|
|
||||||
public void initSeenCreatures()
|
|
||||||
{
|
|
||||||
initSeenCreatures(getTemplate().getAggroRange());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the NpcStringId for name
|
* @return the NpcStringId for name
|
||||||
*/
|
*/
|
||||||
|
|||||||
+14
-3
@@ -937,6 +937,17 @@ public abstract class AbstractScript extends ManagedScript implements IEventTime
|
|||||||
return registerConsumer(callback, EventType.ON_NPC_CREATURE_SEE, ListenerRegisterType.NPC, npcIds);
|
return registerConsumer(callback, EventType.ON_NPC_CREATURE_SEE, ListenerRegisterType.NPC, npcIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides instant callback operation when {@link Npc} sees another creature.
|
||||||
|
* @param callback
|
||||||
|
* @param npcIds
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
protected final List<AbstractEventListener> setNpcCreatureSeeId(Consumer<OnNpcCreatureSee> callback, Collection<Integer> npcIds)
|
||||||
|
{
|
||||||
|
return registerConsumer(callback, EventType.ON_NPC_CREATURE_SEE, ListenerRegisterType.NPC, npcIds);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides instant callback operation when {@link Creature} sees another creature.
|
* Provides instant callback operation when {@link Creature} sees another creature.
|
||||||
* @param callback
|
* @param callback
|
||||||
@@ -949,14 +960,14 @@ public abstract class AbstractScript extends ManagedScript implements IEventTime
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides instant callback operation when {@link Npc} sees another creature.
|
* Provides instant callback operation when {@link Creature} sees another creature.
|
||||||
* @param callback
|
* @param callback
|
||||||
* @param npcIds
|
* @param npcIds
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
protected final List<AbstractEventListener> setNpcCreatureSeeId(Consumer<OnNpcCreatureSee> callback, Collection<Integer> npcIds)
|
protected final List<AbstractEventListener> setCreatureSeeId(Consumer<OnCreatureSee> callback, Collection<Integer> npcIds)
|
||||||
{
|
{
|
||||||
return registerConsumer(callback, EventType.ON_NPC_CREATURE_SEE, ListenerRegisterType.NPC, npcIds);
|
return registerConsumer(callback, EventType.ON_CREATURE_SEE, ListenerRegisterType.NPC, npcIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|||||||
+4
-1
@@ -254,6 +254,7 @@ public abstract class AbstractAI implements Ctrl
|
|||||||
{
|
{
|
||||||
case EVT_THINK:
|
case EVT_THINK:
|
||||||
{
|
{
|
||||||
|
_actor.updateSeenCreatures();
|
||||||
onEvtThink();
|
onEvtThink();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -325,7 +326,9 @@ public abstract class AbstractAI implements Ctrl
|
|||||||
}
|
}
|
||||||
case EVT_FORGET_OBJECT:
|
case EVT_FORGET_OBJECT:
|
||||||
{
|
{
|
||||||
onEvtForgetObject((WorldObject) arg0);
|
final WorldObject worldObject = (WorldObject) arg0;
|
||||||
|
_actor.removeSeenCreature(worldObject);
|
||||||
|
onEvtForgetObject(worldObject);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case EVT_CANCEL:
|
case EVT_CANCEL:
|
||||||
|
|||||||
-106
@@ -1,106 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of the L2J Mobius project.
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
package org.l2jmobius.gameserver.model;
|
|
||||||
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
|
||||||
import java.util.concurrent.ScheduledFuture;
|
|
||||||
import java.util.function.Predicate;
|
|
||||||
|
|
||||||
import org.l2jmobius.commons.concurrent.ThreadPool;
|
|
||||||
import org.l2jmobius.gameserver.model.actor.Creature;
|
|
||||||
import org.l2jmobius.gameserver.model.events.EventDispatcher;
|
|
||||||
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureSee;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author UnAfraid
|
|
||||||
*/
|
|
||||||
public class CreatureContainer
|
|
||||||
{
|
|
||||||
private final Set<Integer> _seen = ConcurrentHashMap.newKeySet();
|
|
||||||
private final Creature _owner;
|
|
||||||
private final int _range;
|
|
||||||
private ScheduledFuture<?> _task;
|
|
||||||
private Predicate<Creature> _condition = null;
|
|
||||||
|
|
||||||
public CreatureContainer(Creature owner, int range, Predicate<Creature> condition)
|
|
||||||
{
|
|
||||||
_owner = owner;
|
|
||||||
_range = range;
|
|
||||||
_condition = condition;
|
|
||||||
start();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Creature getOwner()
|
|
||||||
{
|
|
||||||
return _owner;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getRange()
|
|
||||||
{
|
|
||||||
return _range;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Starts the task that scans for new creatures
|
|
||||||
*/
|
|
||||||
public void start()
|
|
||||||
{
|
|
||||||
if ((_task == null) || _task.isDone())
|
|
||||||
{
|
|
||||||
_task = ThreadPool.scheduleAtFixedRate(this::update, 1000, 1000);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return {@code false} if the task could not be cancelled, typically because it has already completed normally; {@code true} otherwise
|
|
||||||
*/
|
|
||||||
public boolean stop()
|
|
||||||
{
|
|
||||||
return (_task != null) && !_task.isDone() && _task.cancel(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Resets the creatures container, all previously seen creature will be discarded and next time update method is called will notify for each creature that owner sees!
|
|
||||||
*/
|
|
||||||
public void reset()
|
|
||||||
{
|
|
||||||
_seen.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Scans around the npc and notifies about new creature owner seen
|
|
||||||
*/
|
|
||||||
private void update()
|
|
||||||
{
|
|
||||||
final Set<Integer> verified = new HashSet<>();
|
|
||||||
World.getInstance().forEachVisibleObjectInRange(_owner, Creature.class, _range, creature ->
|
|
||||||
{
|
|
||||||
if ((_condition == null) || _condition.test(creature))
|
|
||||||
{
|
|
||||||
if (_seen.add(creature.getObjectId()))
|
|
||||||
{
|
|
||||||
EventDispatcher.getInstance().notifyEventAsync(new OnCreatureSee(_owner, creature), _owner);
|
|
||||||
}
|
|
||||||
verified.add(creature.getObjectId());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
_seen.retainAll(verified);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+46
-34
@@ -70,7 +70,6 @@ import org.l2jmobius.gameserver.instancemanager.MapRegionManager;
|
|||||||
import org.l2jmobius.gameserver.instancemanager.QuestManager;
|
import org.l2jmobius.gameserver.instancemanager.QuestManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.ZoneManager;
|
import org.l2jmobius.gameserver.instancemanager.ZoneManager;
|
||||||
import org.l2jmobius.gameserver.model.AccessLevel;
|
import org.l2jmobius.gameserver.model.AccessLevel;
|
||||||
import org.l2jmobius.gameserver.model.CreatureContainer;
|
|
||||||
import org.l2jmobius.gameserver.model.EffectList;
|
import org.l2jmobius.gameserver.model.EffectList;
|
||||||
import org.l2jmobius.gameserver.model.Hit;
|
import org.l2jmobius.gameserver.model.Hit;
|
||||||
import org.l2jmobius.gameserver.model.Location;
|
import org.l2jmobius.gameserver.model.Location;
|
||||||
@@ -89,6 +88,7 @@ import org.l2jmobius.gameserver.model.actor.stat.CreatureStat;
|
|||||||
import org.l2jmobius.gameserver.model.actor.status.CreatureStatus;
|
import org.l2jmobius.gameserver.model.actor.status.CreatureStatus;
|
||||||
import org.l2jmobius.gameserver.model.actor.tasks.creature.NotifyAITask;
|
import org.l2jmobius.gameserver.model.actor.tasks.creature.NotifyAITask;
|
||||||
import org.l2jmobius.gameserver.model.actor.templates.CreatureTemplate;
|
import org.l2jmobius.gameserver.model.actor.templates.CreatureTemplate;
|
||||||
|
import org.l2jmobius.gameserver.model.actor.templates.NpcTemplate;
|
||||||
import org.l2jmobius.gameserver.model.actor.transform.Transform;
|
import org.l2jmobius.gameserver.model.actor.transform.Transform;
|
||||||
import org.l2jmobius.gameserver.model.clan.Clan;
|
import org.l2jmobius.gameserver.model.clan.Clan;
|
||||||
import org.l2jmobius.gameserver.model.effects.EffectFlag;
|
import org.l2jmobius.gameserver.model.effects.EffectFlag;
|
||||||
@@ -102,6 +102,7 @@ import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureDamageDealt
|
|||||||
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureDamageReceived;
|
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureDamageReceived;
|
||||||
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureDeath;
|
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureDeath;
|
||||||
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureKilled;
|
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureKilled;
|
||||||
|
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureSee;
|
||||||
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureTeleport;
|
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureTeleport;
|
||||||
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureTeleported;
|
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureTeleported;
|
||||||
import org.l2jmobius.gameserver.model.events.listeners.AbstractEventListener;
|
import org.l2jmobius.gameserver.model.events.listeners.AbstractEventListener;
|
||||||
@@ -272,7 +273,8 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
|
|
||||||
private final Map<Integer, RelationCache> _knownRelations = new ConcurrentHashMap<>();
|
private final Map<Integer, RelationCache> _knownRelations = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
private CreatureContainer _seenCreatures;
|
private Set<Creature> _seenCreatures = null;
|
||||||
|
private int _seenCreatureRange = Config.ALT_PARTY_RANGE;
|
||||||
|
|
||||||
private final Map<StatusUpdateType, Integer> _statusUpdates = new ConcurrentHashMap<>();
|
private final Map<StatusUpdateType, Integer> _statusUpdates = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
@@ -564,13 +566,6 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
{
|
{
|
||||||
_summoner.removeSummonedNpc(getObjectId());
|
_summoner.removeSummonedNpc(getObjectId());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stop on creature see task and clear the data
|
|
||||||
if (_seenCreatures != null)
|
|
||||||
{
|
|
||||||
_seenCreatures.stop();
|
|
||||||
_seenCreatures.reset();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -578,12 +573,6 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
{
|
{
|
||||||
super.onSpawn();
|
super.onSpawn();
|
||||||
revalidateZone(true);
|
revalidateZone(true);
|
||||||
|
|
||||||
// restart task
|
|
||||||
if (_seenCreatures != null)
|
|
||||||
{
|
|
||||||
_seenCreatures.start();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized void onTeleported()
|
public synchronized void onTeleported()
|
||||||
@@ -592,6 +581,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
spawnMe(getX(), getY(), getZ());
|
spawnMe(getX(), getY(), getZ());
|
||||||
setTeleporting(false);
|
setTeleporting(false);
|
||||||
EventDispatcher.getInstance().notifyEventAsync(new OnCreatureTeleported(this), this);
|
EventDispatcher.getInstance().notifyEventAsync(new OnCreatureTeleported(this), this);
|
||||||
@@ -1731,6 +1721,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
{
|
{
|
||||||
getSkillChannelized().abortChannelization();
|
getSkillChannelized().abortChannelization();
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1761,6 +1752,12 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
// Remove all active, passive and option effects, do not broadcast changes.
|
// Remove all active, passive and option effects, do not broadcast changes.
|
||||||
_effectList.stopAllEffectsWithoutExclusions(false, false);
|
_effectList.stopAllEffectsWithoutExclusions(false, false);
|
||||||
|
|
||||||
|
// Forget all seen creatures.
|
||||||
|
if (_seenCreatures != null)
|
||||||
|
{
|
||||||
|
_seenCreatures.clear();
|
||||||
|
}
|
||||||
|
|
||||||
// Cancel the BuffFinishTask related to this creature.
|
// Cancel the BuffFinishTask related to this creature.
|
||||||
cancelBuffFinishTask();
|
cancelBuffFinishTask();
|
||||||
|
|
||||||
@@ -5470,22 +5467,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
return _blockActionsAllowedSkills.containsKey(skill.getId());
|
return _blockActionsAllowedSkills.containsKey(skill.getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public void initSeenCreatures()
|
||||||
* Initialize creature container that looks up for creatures around its owner, and notifies with onCreatureSee upon discovery.
|
|
||||||
* @param range
|
|
||||||
*/
|
|
||||||
public void initSeenCreatures(int range)
|
|
||||||
{
|
|
||||||
initSeenCreatures(range, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialize creature container that looks up for creatures around its owner, and notifies with onCreatureSee upon discovery.<br>
|
|
||||||
* <i>The condition can be null</i>
|
|
||||||
* @param range
|
|
||||||
* @param condition
|
|
||||||
*/
|
|
||||||
public void initSeenCreatures(int range, Predicate<Creature> condition)
|
|
||||||
{
|
{
|
||||||
if (_seenCreatures == null)
|
if (_seenCreatures == null)
|
||||||
{
|
{
|
||||||
@@ -5493,15 +5475,45 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
{
|
{
|
||||||
if (_seenCreatures == null)
|
if (_seenCreatures == null)
|
||||||
{
|
{
|
||||||
_seenCreatures = new CreatureContainer(this, range, condition);
|
if (isNpc())
|
||||||
|
{
|
||||||
|
final NpcTemplate template = ((Npc) this).getTemplate();
|
||||||
|
if ((template != null) && (template.getAggroRange() > 0))
|
||||||
|
{
|
||||||
|
_seenCreatureRange = template.getAggroRange();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_seenCreatures = ConcurrentHashMap.newKeySet(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public CreatureContainer getSeenCreatures()
|
public void updateSeenCreatures()
|
||||||
{
|
{
|
||||||
return _seenCreatures;
|
if ((_seenCreatures == null) || _isDead || !isSpawned())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
World.getInstance().forEachVisibleObjectInRange(this, Creature.class, _seenCreatureRange, creature ->
|
||||||
|
{
|
||||||
|
if (_seenCreatures.add(creature))
|
||||||
|
{
|
||||||
|
EventDispatcher.getInstance().notifyEventAsync(new OnCreatureSee(this, creature), this);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeSeenCreature(WorldObject worldObject)
|
||||||
|
{
|
||||||
|
if (_seenCreatures == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_seenCreatures.remove(worldObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
public MoveType getMoveType()
|
public MoveType getMoveType()
|
||||||
|
|||||||
-8
@@ -1845,14 +1845,6 @@ public class Npc extends Creature
|
|||||||
return Rnd.get(100) < Rnd.get(getTemplate().getMinSkillChance(), getTemplate().getMaxSkillChance());
|
return Rnd.get(100) < Rnd.get(getTemplate().getMinSkillChance(), getTemplate().getMaxSkillChance());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialize creature container that looks up for creatures around its owner, and notifies with onCreatureSee upon discovery.
|
|
||||||
*/
|
|
||||||
public void initSeenCreatures()
|
|
||||||
{
|
|
||||||
initSeenCreatures(getTemplate().getAggroRange());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the NpcStringId for name
|
* @return the NpcStringId for name
|
||||||
*/
|
*/
|
||||||
|
|||||||
+14
-3
@@ -938,6 +938,17 @@ public abstract class AbstractScript extends ManagedScript implements IEventTime
|
|||||||
return registerConsumer(callback, EventType.ON_NPC_CREATURE_SEE, ListenerRegisterType.NPC, npcIds);
|
return registerConsumer(callback, EventType.ON_NPC_CREATURE_SEE, ListenerRegisterType.NPC, npcIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides instant callback operation when {@link Npc} sees another creature.
|
||||||
|
* @param callback
|
||||||
|
* @param npcIds
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
protected final List<AbstractEventListener> setNpcCreatureSeeId(Consumer<OnNpcCreatureSee> callback, Collection<Integer> npcIds)
|
||||||
|
{
|
||||||
|
return registerConsumer(callback, EventType.ON_NPC_CREATURE_SEE, ListenerRegisterType.NPC, npcIds);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides instant callback operation when {@link Creature} sees another creature.
|
* Provides instant callback operation when {@link Creature} sees another creature.
|
||||||
* @param callback
|
* @param callback
|
||||||
@@ -950,14 +961,14 @@ public abstract class AbstractScript extends ManagedScript implements IEventTime
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides instant callback operation when {@link Npc} sees another creature.
|
* Provides instant callback operation when {@link Creature} sees another creature.
|
||||||
* @param callback
|
* @param callback
|
||||||
* @param npcIds
|
* @param npcIds
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
protected final List<AbstractEventListener> setNpcCreatureSeeId(Consumer<OnNpcCreatureSee> callback, Collection<Integer> npcIds)
|
protected final List<AbstractEventListener> setCreatureSeeId(Consumer<OnCreatureSee> callback, Collection<Integer> npcIds)
|
||||||
{
|
{
|
||||||
return registerConsumer(callback, EventType.ON_NPC_CREATURE_SEE, ListenerRegisterType.NPC, npcIds);
|
return registerConsumer(callback, EventType.ON_CREATURE_SEE, ListenerRegisterType.NPC, npcIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -254,6 +254,7 @@ public abstract class AbstractAI implements Ctrl
|
|||||||
{
|
{
|
||||||
case EVT_THINK:
|
case EVT_THINK:
|
||||||
{
|
{
|
||||||
|
_actor.updateSeenCreatures();
|
||||||
onEvtThink();
|
onEvtThink();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -325,7 +326,9 @@ public abstract class AbstractAI implements Ctrl
|
|||||||
}
|
}
|
||||||
case EVT_FORGET_OBJECT:
|
case EVT_FORGET_OBJECT:
|
||||||
{
|
{
|
||||||
onEvtForgetObject((WorldObject) arg0);
|
final WorldObject worldObject = (WorldObject) arg0;
|
||||||
|
_actor.removeSeenCreature(worldObject);
|
||||||
|
onEvtForgetObject(worldObject);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case EVT_CANCEL:
|
case EVT_CANCEL:
|
||||||
|
|||||||
-106
@@ -1,106 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of the L2J Mobius project.
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
package org.l2jmobius.gameserver.model;
|
|
||||||
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
|
||||||
import java.util.concurrent.ScheduledFuture;
|
|
||||||
import java.util.function.Predicate;
|
|
||||||
|
|
||||||
import org.l2jmobius.commons.concurrent.ThreadPool;
|
|
||||||
import org.l2jmobius.gameserver.model.actor.Creature;
|
|
||||||
import org.l2jmobius.gameserver.model.events.EventDispatcher;
|
|
||||||
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureSee;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author UnAfraid
|
|
||||||
*/
|
|
||||||
public class CreatureContainer
|
|
||||||
{
|
|
||||||
private final Set<Integer> _seen = ConcurrentHashMap.newKeySet();
|
|
||||||
private final Creature _owner;
|
|
||||||
private final int _range;
|
|
||||||
private ScheduledFuture<?> _task;
|
|
||||||
private Predicate<Creature> _condition = null;
|
|
||||||
|
|
||||||
public CreatureContainer(Creature owner, int range, Predicate<Creature> condition)
|
|
||||||
{
|
|
||||||
_owner = owner;
|
|
||||||
_range = range;
|
|
||||||
_condition = condition;
|
|
||||||
start();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Creature getOwner()
|
|
||||||
{
|
|
||||||
return _owner;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getRange()
|
|
||||||
{
|
|
||||||
return _range;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Starts the task that scans for new creatures
|
|
||||||
*/
|
|
||||||
public void start()
|
|
||||||
{
|
|
||||||
if ((_task == null) || _task.isDone())
|
|
||||||
{
|
|
||||||
_task = ThreadPool.scheduleAtFixedRate(this::update, 1000, 1000);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return {@code false} if the task could not be cancelled, typically because it has already completed normally; {@code true} otherwise
|
|
||||||
*/
|
|
||||||
public boolean stop()
|
|
||||||
{
|
|
||||||
return (_task != null) && !_task.isDone() && _task.cancel(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Resets the creatures container, all previously seen creature will be discarded and next time update method is called will notify for each creature that owner sees!
|
|
||||||
*/
|
|
||||||
public void reset()
|
|
||||||
{
|
|
||||||
_seen.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Scans around the npc and notifies about new creature owner seen
|
|
||||||
*/
|
|
||||||
private void update()
|
|
||||||
{
|
|
||||||
final Set<Integer> verified = new HashSet<>();
|
|
||||||
World.getInstance().forEachVisibleObjectInRange(_owner, Creature.class, _range, creature ->
|
|
||||||
{
|
|
||||||
if ((_condition == null) || _condition.test(creature))
|
|
||||||
{
|
|
||||||
if (_seen.add(creature.getObjectId()))
|
|
||||||
{
|
|
||||||
EventDispatcher.getInstance().notifyEventAsync(new OnCreatureSee(_owner, creature), _owner);
|
|
||||||
}
|
|
||||||
verified.add(creature.getObjectId());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
_seen.retainAll(verified);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+46
-34
@@ -70,7 +70,6 @@ import org.l2jmobius.gameserver.instancemanager.MapRegionManager;
|
|||||||
import org.l2jmobius.gameserver.instancemanager.QuestManager;
|
import org.l2jmobius.gameserver.instancemanager.QuestManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.ZoneManager;
|
import org.l2jmobius.gameserver.instancemanager.ZoneManager;
|
||||||
import org.l2jmobius.gameserver.model.AccessLevel;
|
import org.l2jmobius.gameserver.model.AccessLevel;
|
||||||
import org.l2jmobius.gameserver.model.CreatureContainer;
|
|
||||||
import org.l2jmobius.gameserver.model.EffectList;
|
import org.l2jmobius.gameserver.model.EffectList;
|
||||||
import org.l2jmobius.gameserver.model.Hit;
|
import org.l2jmobius.gameserver.model.Hit;
|
||||||
import org.l2jmobius.gameserver.model.Location;
|
import org.l2jmobius.gameserver.model.Location;
|
||||||
@@ -89,6 +88,7 @@ import org.l2jmobius.gameserver.model.actor.stat.CreatureStat;
|
|||||||
import org.l2jmobius.gameserver.model.actor.status.CreatureStatus;
|
import org.l2jmobius.gameserver.model.actor.status.CreatureStatus;
|
||||||
import org.l2jmobius.gameserver.model.actor.tasks.creature.NotifyAITask;
|
import org.l2jmobius.gameserver.model.actor.tasks.creature.NotifyAITask;
|
||||||
import org.l2jmobius.gameserver.model.actor.templates.CreatureTemplate;
|
import org.l2jmobius.gameserver.model.actor.templates.CreatureTemplate;
|
||||||
|
import org.l2jmobius.gameserver.model.actor.templates.NpcTemplate;
|
||||||
import org.l2jmobius.gameserver.model.actor.transform.Transform;
|
import org.l2jmobius.gameserver.model.actor.transform.Transform;
|
||||||
import org.l2jmobius.gameserver.model.clan.Clan;
|
import org.l2jmobius.gameserver.model.clan.Clan;
|
||||||
import org.l2jmobius.gameserver.model.effects.EffectFlag;
|
import org.l2jmobius.gameserver.model.effects.EffectFlag;
|
||||||
@@ -102,6 +102,7 @@ import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureDamageDealt
|
|||||||
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureDamageReceived;
|
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureDamageReceived;
|
||||||
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureDeath;
|
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureDeath;
|
||||||
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureKilled;
|
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureKilled;
|
||||||
|
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureSee;
|
||||||
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureTeleport;
|
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureTeleport;
|
||||||
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureTeleported;
|
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureTeleported;
|
||||||
import org.l2jmobius.gameserver.model.events.listeners.AbstractEventListener;
|
import org.l2jmobius.gameserver.model.events.listeners.AbstractEventListener;
|
||||||
@@ -272,7 +273,8 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
|
|
||||||
private final Map<Integer, RelationCache> _knownRelations = new ConcurrentHashMap<>();
|
private final Map<Integer, RelationCache> _knownRelations = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
private CreatureContainer _seenCreatures;
|
private Set<Creature> _seenCreatures = null;
|
||||||
|
private int _seenCreatureRange = Config.ALT_PARTY_RANGE;
|
||||||
|
|
||||||
private final Map<StatusUpdateType, Integer> _statusUpdates = new ConcurrentHashMap<>();
|
private final Map<StatusUpdateType, Integer> _statusUpdates = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
@@ -564,13 +566,6 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
{
|
{
|
||||||
_summoner.removeSummonedNpc(getObjectId());
|
_summoner.removeSummonedNpc(getObjectId());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stop on creature see task and clear the data
|
|
||||||
if (_seenCreatures != null)
|
|
||||||
{
|
|
||||||
_seenCreatures.stop();
|
|
||||||
_seenCreatures.reset();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -578,12 +573,6 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
{
|
{
|
||||||
super.onSpawn();
|
super.onSpawn();
|
||||||
revalidateZone(true);
|
revalidateZone(true);
|
||||||
|
|
||||||
// restart task
|
|
||||||
if (_seenCreatures != null)
|
|
||||||
{
|
|
||||||
_seenCreatures.start();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized void onTeleported()
|
public synchronized void onTeleported()
|
||||||
@@ -592,6 +581,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
spawnMe(getX(), getY(), getZ());
|
spawnMe(getX(), getY(), getZ());
|
||||||
setTeleporting(false);
|
setTeleporting(false);
|
||||||
EventDispatcher.getInstance().notifyEventAsync(new OnCreatureTeleported(this), this);
|
EventDispatcher.getInstance().notifyEventAsync(new OnCreatureTeleported(this), this);
|
||||||
@@ -1738,6 +1728,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
{
|
{
|
||||||
getSkillChannelized().abortChannelization();
|
getSkillChannelized().abortChannelization();
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1768,6 +1759,12 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
// Remove all active, passive and option effects, do not broadcast changes.
|
// Remove all active, passive and option effects, do not broadcast changes.
|
||||||
_effectList.stopAllEffectsWithoutExclusions(false, false);
|
_effectList.stopAllEffectsWithoutExclusions(false, false);
|
||||||
|
|
||||||
|
// Forget all seen creatures.
|
||||||
|
if (_seenCreatures != null)
|
||||||
|
{
|
||||||
|
_seenCreatures.clear();
|
||||||
|
}
|
||||||
|
|
||||||
// Cancel the BuffFinishTask related to this creature.
|
// Cancel the BuffFinishTask related to this creature.
|
||||||
cancelBuffFinishTask();
|
cancelBuffFinishTask();
|
||||||
|
|
||||||
@@ -5477,22 +5474,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
return _blockActionsAllowedSkills.containsKey(skill.getId());
|
return _blockActionsAllowedSkills.containsKey(skill.getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public void initSeenCreatures()
|
||||||
* Initialize creature container that looks up for creatures around its owner, and notifies with onCreatureSee upon discovery.
|
|
||||||
* @param range
|
|
||||||
*/
|
|
||||||
public void initSeenCreatures(int range)
|
|
||||||
{
|
|
||||||
initSeenCreatures(range, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialize creature container that looks up for creatures around its owner, and notifies with onCreatureSee upon discovery.<br>
|
|
||||||
* <i>The condition can be null</i>
|
|
||||||
* @param range
|
|
||||||
* @param condition
|
|
||||||
*/
|
|
||||||
public void initSeenCreatures(int range, Predicate<Creature> condition)
|
|
||||||
{
|
{
|
||||||
if (_seenCreatures == null)
|
if (_seenCreatures == null)
|
||||||
{
|
{
|
||||||
@@ -5500,15 +5482,45 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
{
|
{
|
||||||
if (_seenCreatures == null)
|
if (_seenCreatures == null)
|
||||||
{
|
{
|
||||||
_seenCreatures = new CreatureContainer(this, range, condition);
|
if (isNpc())
|
||||||
|
{
|
||||||
|
final NpcTemplate template = ((Npc) this).getTemplate();
|
||||||
|
if ((template != null) && (template.getAggroRange() > 0))
|
||||||
|
{
|
||||||
|
_seenCreatureRange = template.getAggroRange();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_seenCreatures = ConcurrentHashMap.newKeySet(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public CreatureContainer getSeenCreatures()
|
public void updateSeenCreatures()
|
||||||
{
|
{
|
||||||
return _seenCreatures;
|
if ((_seenCreatures == null) || _isDead || !isSpawned())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
World.getInstance().forEachVisibleObjectInRange(this, Creature.class, _seenCreatureRange, creature ->
|
||||||
|
{
|
||||||
|
if (_seenCreatures.add(creature))
|
||||||
|
{
|
||||||
|
EventDispatcher.getInstance().notifyEventAsync(new OnCreatureSee(this, creature), this);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeSeenCreature(WorldObject worldObject)
|
||||||
|
{
|
||||||
|
if (_seenCreatures == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_seenCreatures.remove(worldObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
public MoveType getMoveType()
|
public MoveType getMoveType()
|
||||||
|
|||||||
@@ -1845,14 +1845,6 @@ public class Npc extends Creature
|
|||||||
return Rnd.get(100) < Rnd.get(getTemplate().getMinSkillChance(), getTemplate().getMaxSkillChance());
|
return Rnd.get(100) < Rnd.get(getTemplate().getMinSkillChance(), getTemplate().getMaxSkillChance());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialize creature container that looks up for creatures around its owner, and notifies with onCreatureSee upon discovery.
|
|
||||||
*/
|
|
||||||
public void initSeenCreatures()
|
|
||||||
{
|
|
||||||
initSeenCreatures(getTemplate().getAggroRange());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the NpcStringId for name
|
* @return the NpcStringId for name
|
||||||
*/
|
*/
|
||||||
|
|||||||
+14
-3
@@ -938,6 +938,17 @@ public abstract class AbstractScript extends ManagedScript implements IEventTime
|
|||||||
return registerConsumer(callback, EventType.ON_NPC_CREATURE_SEE, ListenerRegisterType.NPC, npcIds);
|
return registerConsumer(callback, EventType.ON_NPC_CREATURE_SEE, ListenerRegisterType.NPC, npcIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides instant callback operation when {@link Npc} sees another creature.
|
||||||
|
* @param callback
|
||||||
|
* @param npcIds
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
protected final List<AbstractEventListener> setNpcCreatureSeeId(Consumer<OnNpcCreatureSee> callback, Collection<Integer> npcIds)
|
||||||
|
{
|
||||||
|
return registerConsumer(callback, EventType.ON_NPC_CREATURE_SEE, ListenerRegisterType.NPC, npcIds);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides instant callback operation when {@link Creature} sees another creature.
|
* Provides instant callback operation when {@link Creature} sees another creature.
|
||||||
* @param callback
|
* @param callback
|
||||||
@@ -950,14 +961,14 @@ public abstract class AbstractScript extends ManagedScript implements IEventTime
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides instant callback operation when {@link Npc} sees another creature.
|
* Provides instant callback operation when {@link Creature} sees another creature.
|
||||||
* @param callback
|
* @param callback
|
||||||
* @param npcIds
|
* @param npcIds
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
protected final List<AbstractEventListener> setNpcCreatureSeeId(Consumer<OnNpcCreatureSee> callback, Collection<Integer> npcIds)
|
protected final List<AbstractEventListener> setCreatureSeeId(Consumer<OnCreatureSee> callback, Collection<Integer> npcIds)
|
||||||
{
|
{
|
||||||
return registerConsumer(callback, EventType.ON_NPC_CREATURE_SEE, ListenerRegisterType.NPC, npcIds);
|
return registerConsumer(callback, EventType.ON_CREATURE_SEE, ListenerRegisterType.NPC, npcIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -254,6 +254,7 @@ public abstract class AbstractAI implements Ctrl
|
|||||||
{
|
{
|
||||||
case EVT_THINK:
|
case EVT_THINK:
|
||||||
{
|
{
|
||||||
|
_actor.updateSeenCreatures();
|
||||||
onEvtThink();
|
onEvtThink();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -325,7 +326,9 @@ public abstract class AbstractAI implements Ctrl
|
|||||||
}
|
}
|
||||||
case EVT_FORGET_OBJECT:
|
case EVT_FORGET_OBJECT:
|
||||||
{
|
{
|
||||||
onEvtForgetObject((WorldObject) arg0);
|
final WorldObject worldObject = (WorldObject) arg0;
|
||||||
|
_actor.removeSeenCreature(worldObject);
|
||||||
|
onEvtForgetObject(worldObject);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case EVT_CANCEL:
|
case EVT_CANCEL:
|
||||||
|
|||||||
-106
@@ -1,106 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of the L2J Mobius project.
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
package org.l2jmobius.gameserver.model;
|
|
||||||
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
|
||||||
import java.util.concurrent.ScheduledFuture;
|
|
||||||
import java.util.function.Predicate;
|
|
||||||
|
|
||||||
import org.l2jmobius.commons.concurrent.ThreadPool;
|
|
||||||
import org.l2jmobius.gameserver.model.actor.Creature;
|
|
||||||
import org.l2jmobius.gameserver.model.events.EventDispatcher;
|
|
||||||
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureSee;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author UnAfraid
|
|
||||||
*/
|
|
||||||
public class CreatureContainer
|
|
||||||
{
|
|
||||||
private final Set<Integer> _seen = ConcurrentHashMap.newKeySet();
|
|
||||||
private final Creature _owner;
|
|
||||||
private final int _range;
|
|
||||||
private ScheduledFuture<?> _task;
|
|
||||||
private Predicate<Creature> _condition = null;
|
|
||||||
|
|
||||||
public CreatureContainer(Creature owner, int range, Predicate<Creature> condition)
|
|
||||||
{
|
|
||||||
_owner = owner;
|
|
||||||
_range = range;
|
|
||||||
_condition = condition;
|
|
||||||
start();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Creature getOwner()
|
|
||||||
{
|
|
||||||
return _owner;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getRange()
|
|
||||||
{
|
|
||||||
return _range;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Starts the task that scans for new creatures
|
|
||||||
*/
|
|
||||||
public void start()
|
|
||||||
{
|
|
||||||
if ((_task == null) || _task.isDone())
|
|
||||||
{
|
|
||||||
_task = ThreadPool.scheduleAtFixedRate(this::update, 1000, 1000);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return {@code false} if the task could not be cancelled, typically because it has already completed normally; {@code true} otherwise
|
|
||||||
*/
|
|
||||||
public boolean stop()
|
|
||||||
{
|
|
||||||
return (_task != null) && !_task.isDone() && _task.cancel(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Resets the creatures container, all previously seen creature will be discarded and next time update method is called will notify for each creature that owner sees!
|
|
||||||
*/
|
|
||||||
public void reset()
|
|
||||||
{
|
|
||||||
_seen.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Scans around the npc and notifies about new creature owner seen
|
|
||||||
*/
|
|
||||||
private void update()
|
|
||||||
{
|
|
||||||
final Set<Integer> verified = new HashSet<>();
|
|
||||||
World.getInstance().forEachVisibleObjectInRange(_owner, Creature.class, _range, creature ->
|
|
||||||
{
|
|
||||||
if ((_condition == null) || _condition.test(creature))
|
|
||||||
{
|
|
||||||
if (_seen.add(creature.getObjectId()))
|
|
||||||
{
|
|
||||||
EventDispatcher.getInstance().notifyEventAsync(new OnCreatureSee(_owner, creature), _owner);
|
|
||||||
}
|
|
||||||
verified.add(creature.getObjectId());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
_seen.retainAll(verified);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+46
-34
@@ -70,7 +70,6 @@ import org.l2jmobius.gameserver.instancemanager.MapRegionManager;
|
|||||||
import org.l2jmobius.gameserver.instancemanager.QuestManager;
|
import org.l2jmobius.gameserver.instancemanager.QuestManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.ZoneManager;
|
import org.l2jmobius.gameserver.instancemanager.ZoneManager;
|
||||||
import org.l2jmobius.gameserver.model.AccessLevel;
|
import org.l2jmobius.gameserver.model.AccessLevel;
|
||||||
import org.l2jmobius.gameserver.model.CreatureContainer;
|
|
||||||
import org.l2jmobius.gameserver.model.EffectList;
|
import org.l2jmobius.gameserver.model.EffectList;
|
||||||
import org.l2jmobius.gameserver.model.Hit;
|
import org.l2jmobius.gameserver.model.Hit;
|
||||||
import org.l2jmobius.gameserver.model.Location;
|
import org.l2jmobius.gameserver.model.Location;
|
||||||
@@ -89,6 +88,7 @@ import org.l2jmobius.gameserver.model.actor.stat.CreatureStat;
|
|||||||
import org.l2jmobius.gameserver.model.actor.status.CreatureStatus;
|
import org.l2jmobius.gameserver.model.actor.status.CreatureStatus;
|
||||||
import org.l2jmobius.gameserver.model.actor.tasks.creature.NotifyAITask;
|
import org.l2jmobius.gameserver.model.actor.tasks.creature.NotifyAITask;
|
||||||
import org.l2jmobius.gameserver.model.actor.templates.CreatureTemplate;
|
import org.l2jmobius.gameserver.model.actor.templates.CreatureTemplate;
|
||||||
|
import org.l2jmobius.gameserver.model.actor.templates.NpcTemplate;
|
||||||
import org.l2jmobius.gameserver.model.actor.transform.Transform;
|
import org.l2jmobius.gameserver.model.actor.transform.Transform;
|
||||||
import org.l2jmobius.gameserver.model.clan.Clan;
|
import org.l2jmobius.gameserver.model.clan.Clan;
|
||||||
import org.l2jmobius.gameserver.model.effects.EffectFlag;
|
import org.l2jmobius.gameserver.model.effects.EffectFlag;
|
||||||
@@ -102,6 +102,7 @@ import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureDamageDealt
|
|||||||
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureDamageReceived;
|
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureDamageReceived;
|
||||||
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureDeath;
|
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureDeath;
|
||||||
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureKilled;
|
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureKilled;
|
||||||
|
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureSee;
|
||||||
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureTeleport;
|
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureTeleport;
|
||||||
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureTeleported;
|
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureTeleported;
|
||||||
import org.l2jmobius.gameserver.model.events.listeners.AbstractEventListener;
|
import org.l2jmobius.gameserver.model.events.listeners.AbstractEventListener;
|
||||||
@@ -272,7 +273,8 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
|
|
||||||
private final Map<Integer, RelationCache> _knownRelations = new ConcurrentHashMap<>();
|
private final Map<Integer, RelationCache> _knownRelations = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
private CreatureContainer _seenCreatures;
|
private Set<Creature> _seenCreatures = null;
|
||||||
|
private int _seenCreatureRange = Config.ALT_PARTY_RANGE;
|
||||||
|
|
||||||
private final Map<StatusUpdateType, Integer> _statusUpdates = new ConcurrentHashMap<>();
|
private final Map<StatusUpdateType, Integer> _statusUpdates = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
@@ -564,13 +566,6 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
{
|
{
|
||||||
_summoner.removeSummonedNpc(getObjectId());
|
_summoner.removeSummonedNpc(getObjectId());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stop on creature see task and clear the data
|
|
||||||
if (_seenCreatures != null)
|
|
||||||
{
|
|
||||||
_seenCreatures.stop();
|
|
||||||
_seenCreatures.reset();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -578,12 +573,6 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
{
|
{
|
||||||
super.onSpawn();
|
super.onSpawn();
|
||||||
revalidateZone(true);
|
revalidateZone(true);
|
||||||
|
|
||||||
// restart task
|
|
||||||
if (_seenCreatures != null)
|
|
||||||
{
|
|
||||||
_seenCreatures.start();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized void onTeleported()
|
public synchronized void onTeleported()
|
||||||
@@ -592,6 +581,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
spawnMe(getX(), getY(), getZ());
|
spawnMe(getX(), getY(), getZ());
|
||||||
setTeleporting(false);
|
setTeleporting(false);
|
||||||
EventDispatcher.getInstance().notifyEventAsync(new OnCreatureTeleported(this), this);
|
EventDispatcher.getInstance().notifyEventAsync(new OnCreatureTeleported(this), this);
|
||||||
@@ -1738,6 +1728,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
{
|
{
|
||||||
getSkillChannelized().abortChannelization();
|
getSkillChannelized().abortChannelization();
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1768,6 +1759,12 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
// Remove all active, passive and option effects, do not broadcast changes.
|
// Remove all active, passive and option effects, do not broadcast changes.
|
||||||
_effectList.stopAllEffectsWithoutExclusions(false, false);
|
_effectList.stopAllEffectsWithoutExclusions(false, false);
|
||||||
|
|
||||||
|
// Forget all seen creatures.
|
||||||
|
if (_seenCreatures != null)
|
||||||
|
{
|
||||||
|
_seenCreatures.clear();
|
||||||
|
}
|
||||||
|
|
||||||
// Cancel the BuffFinishTask related to this creature.
|
// Cancel the BuffFinishTask related to this creature.
|
||||||
cancelBuffFinishTask();
|
cancelBuffFinishTask();
|
||||||
|
|
||||||
@@ -5477,22 +5474,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
return _blockActionsAllowedSkills.containsKey(skill.getId());
|
return _blockActionsAllowedSkills.containsKey(skill.getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public void initSeenCreatures()
|
||||||
* Initialize creature container that looks up for creatures around its owner, and notifies with onCreatureSee upon discovery.
|
|
||||||
* @param range
|
|
||||||
*/
|
|
||||||
public void initSeenCreatures(int range)
|
|
||||||
{
|
|
||||||
initSeenCreatures(range, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialize creature container that looks up for creatures around its owner, and notifies with onCreatureSee upon discovery.<br>
|
|
||||||
* <i>The condition can be null</i>
|
|
||||||
* @param range
|
|
||||||
* @param condition
|
|
||||||
*/
|
|
||||||
public void initSeenCreatures(int range, Predicate<Creature> condition)
|
|
||||||
{
|
{
|
||||||
if (_seenCreatures == null)
|
if (_seenCreatures == null)
|
||||||
{
|
{
|
||||||
@@ -5500,15 +5482,45 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
|||||||
{
|
{
|
||||||
if (_seenCreatures == null)
|
if (_seenCreatures == null)
|
||||||
{
|
{
|
||||||
_seenCreatures = new CreatureContainer(this, range, condition);
|
if (isNpc())
|
||||||
|
{
|
||||||
|
final NpcTemplate template = ((Npc) this).getTemplate();
|
||||||
|
if ((template != null) && (template.getAggroRange() > 0))
|
||||||
|
{
|
||||||
|
_seenCreatureRange = template.getAggroRange();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_seenCreatures = ConcurrentHashMap.newKeySet(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public CreatureContainer getSeenCreatures()
|
public void updateSeenCreatures()
|
||||||
{
|
{
|
||||||
return _seenCreatures;
|
if ((_seenCreatures == null) || _isDead || !isSpawned())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
World.getInstance().forEachVisibleObjectInRange(this, Creature.class, _seenCreatureRange, creature ->
|
||||||
|
{
|
||||||
|
if (_seenCreatures.add(creature))
|
||||||
|
{
|
||||||
|
EventDispatcher.getInstance().notifyEventAsync(new OnCreatureSee(this, creature), this);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeSeenCreature(WorldObject worldObject)
|
||||||
|
{
|
||||||
|
if (_seenCreatures == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_seenCreatures.remove(worldObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
public MoveType getMoveType()
|
public MoveType getMoveType()
|
||||||
|
|||||||
@@ -1845,14 +1845,6 @@ public class Npc extends Creature
|
|||||||
return Rnd.get(100) < Rnd.get(getTemplate().getMinSkillChance(), getTemplate().getMaxSkillChance());
|
return Rnd.get(100) < Rnd.get(getTemplate().getMinSkillChance(), getTemplate().getMaxSkillChance());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialize creature container that looks up for creatures around its owner, and notifies with onCreatureSee upon discovery.
|
|
||||||
*/
|
|
||||||
public void initSeenCreatures()
|
|
||||||
{
|
|
||||||
initSeenCreatures(getTemplate().getAggroRange());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the NpcStringId for name
|
* @return the NpcStringId for name
|
||||||
*/
|
*/
|
||||||
|
|||||||
+14
-3
@@ -938,6 +938,17 @@ public abstract class AbstractScript extends ManagedScript implements IEventTime
|
|||||||
return registerConsumer(callback, EventType.ON_NPC_CREATURE_SEE, ListenerRegisterType.NPC, npcIds);
|
return registerConsumer(callback, EventType.ON_NPC_CREATURE_SEE, ListenerRegisterType.NPC, npcIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides instant callback operation when {@link Npc} sees another creature.
|
||||||
|
* @param callback
|
||||||
|
* @param npcIds
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
protected final List<AbstractEventListener> setNpcCreatureSeeId(Consumer<OnNpcCreatureSee> callback, Collection<Integer> npcIds)
|
||||||
|
{
|
||||||
|
return registerConsumer(callback, EventType.ON_NPC_CREATURE_SEE, ListenerRegisterType.NPC, npcIds);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides instant callback operation when {@link Creature} sees another creature.
|
* Provides instant callback operation when {@link Creature} sees another creature.
|
||||||
* @param callback
|
* @param callback
|
||||||
@@ -950,14 +961,14 @@ public abstract class AbstractScript extends ManagedScript implements IEventTime
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides instant callback operation when {@link Npc} sees another creature.
|
* Provides instant callback operation when {@link Creature} sees another creature.
|
||||||
* @param callback
|
* @param callback
|
||||||
* @param npcIds
|
* @param npcIds
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
protected final List<AbstractEventListener> setNpcCreatureSeeId(Consumer<OnNpcCreatureSee> callback, Collection<Integer> npcIds)
|
protected final List<AbstractEventListener> setCreatureSeeId(Consumer<OnCreatureSee> callback, Collection<Integer> npcIds)
|
||||||
{
|
{
|
||||||
return registerConsumer(callback, EventType.ON_NPC_CREATURE_SEE, ListenerRegisterType.NPC, npcIds);
|
return registerConsumer(callback, EventType.ON_CREATURE_SEE, ListenerRegisterType.NPC, npcIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|||||||
Reference in New Issue
Block a user