Чисто вот как пример - AI для нпс, на время своего существования создающий вокруг себя круглую зону с листенером, который при входе в эту зону вешает определенный скилл, а при выходе - снимает его.
 
	Я таких нпс юзаю для работы тотемов дающих бафф, ну тех что можно юзать у Антараса/Валакаса.
 
package ai;
import l2p.commons.collections.StatsSet;
import l2p.commons.geometry.Circle;
import l2p.gameserver.ai.DefaultAI;
import l2p.gameserver.data.holder.SkillHolder;
import l2p.gameserver.enums.ZoneType;
import l2p.gameserver.holders.world.ZoneTemplate;
import l2p.gameserver.listener.zone.OnZoneEnterLeaveListener;
import l2p.gameserver.model.Creature;
import l2p.gameserver.model.Territory;
import l2p.gameserver.model.World;
import l2p.gameserver.model.Zone;
import l2p.gameserver.model.instances.NpcInstance;
import l2p.gameserver.model.skills.Skill;
import l2p.gameserver.utils.Strings;
/**
 * AI, создающее на время круглую зону, при вхождении в которую на игроков накладывается заданное умение, а при выходе - снимается.
 * Радиус зоны берется из накладываемого умения.
 * 
 * @author Gaikotsu
 */
public class CastSkillZone extends DefaultAI
{
	private Skill _skill = null;
	private Zone _zone = null;
	private ZoneListener _listener = null;
	public CastSkillZone(NpcInstance actor)
	{
		super(actor);
	}
	@Override
	public boolean isGlobalAI()
	{
		return true;
	}
	@Override
	protected void onEvtSpawn()
	{
		super.onEvtSpawn();
		NpcInstance actor = getActor();
		i_ai0 = actor.getParameter("lifeTime", 0);
		i_ai1 = actor.getParameter("castPeriod", 0);
		addTimer(1001, i_ai0 * 1000L);
		addTimer(1002, i_ai1 * 1000L);
		String[] skill = actor.getParameter("castSkill", "0,0").split(",");
		if (skill.length != 2)
			return;
		_skill = SkillHolder.getInstance().getSkill(Integer.valueOf(skill[0]), Integer.valueOf(skill[1]));
		if (_skill == null)
			return;
		int radius = _skill.getAffectRange();
		Circle c = new Circle(actor.getLoc(), radius);
		int z = actor.getLoc().getZ();
		c.setMaxZ(z + radius);
		c.setMinZ(z - radius);
		StatsSet set = new StatsSet();
		set.set("name", Strings.EMPTY);
		set.set("type", ZoneType.dummy);
		set.set("territory", new Territory().add(c));
		_listener = new ZoneListener();
		_zone = new Zone(new ZoneTemplate(set));
		_zone.setReflection(actor.getReflection());
		_zone.addListener(_listener);
		_zone.setActive(true);
	}
	@Override
	public void onEvtDespawn()
	{
		super.onEvtDespawn();
		_zone.setActive(false);
		_zone.removeListener(_listener);
		_zone = null;
	}
	@Override
	protected void onEvtTimer(int timerId, Object arg1, Object arg2)
	{
		NpcInstance actor = getActor();
		if (actor == null)
			return;
		if (timerId == 1001)
		{
			actor.deleteMe();
		}
		else if (timerId == 1002)
		{
			if (_skill == null)
				return;
			World.getAroundPlayables(actor, _skill.getAffectRange(), _skill.getAffectRange()).stream().filter(cha -> cha != null && !cha.isDead()).forEach(cha -> _skill.getEffects(actor, cha, false));
			addTimer(1002, i_ai1 * 1000L);
		}
	}
	private class ZoneListener implements OnZoneEnterLeaveListener
	{
		@Override
		public void onEnter(Zone zone, Creature actor)
		{
			if (!actor.isPlayable())
				return;
			if (actor.getEffectList().checkEffectsBySkill(_skill))
				return;
			_skill.getEffects(getActor(), actor, false);
		}
		@Override
		public void onLeave(Zone zone, Creature actor)
		{
			if (!actor.isPlayable())
				return;
			if (!actor.getEffectList().checkEffectsBySkill(_skill))
				return;
			actor.getEffectList().stopEffect(_skill);
		}
	}
}