Separated siege guard task to one task per residence.

This commit is contained in:
MobiusDevelopment 2020-01-27 16:55:04 +00:00
parent e7db7efaa7
commit de2871bef6
17 changed files with 1265 additions and 438 deletions

View File

@ -16,11 +16,16 @@
*/
package ai.others;
import java.util.Collection;
import java.util.concurrent.ConcurrentHashMap;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArrayList;
import org.l2jmobius.commons.concurrent.ThreadPool;
import org.l2jmobius.gameserver.ai.CtrlIntention;
import org.l2jmobius.gameserver.geoengine.GeoEngine;
import org.l2jmobius.gameserver.instancemanager.CastleManager;
import org.l2jmobius.gameserver.instancemanager.FortManager;
import org.l2jmobius.gameserver.model.World;
import org.l2jmobius.gameserver.model.WorldObject;
import org.l2jmobius.gameserver.model.actor.Attackable;
@ -87,7 +92,7 @@ public class SiegeGuards extends AbstractNpcAI
35134, 35135, 35136, 35176, 35177, 35178, 35218, 35219, 35220, 35261, 35262, 35263, 35264, 35265, 35308, 35309, 35310, 35352, 35353, 35354, 35497, 35498, 35499, 35500, 35501, 35544, 35545, 35546
};
//@formatter:on
private static final Collection<Npc> SPAWNED_GUARDS = ConcurrentHashMap.newKeySet();
private static final Map<Integer, List<Npc>> RESIDENCE_GUARD_MAP = new HashMap<>();
public SiegeGuards()
{
@ -104,22 +109,53 @@ public class SiegeGuards extends AbstractNpcAI
addKillId(MERCENARIES);
addKillId(STATIONARY_MERCENARIES);
startQuestTimer("AGGRO_CHECK", 3000, null, null, true);
// Start task for unknown residences.
RESIDENCE_GUARD_MAP.put(0, new CopyOnWriteArrayList<>());
ThreadPool.scheduleAtFixedRate(new AggroCheckTask(0), 0, 3000);
// Start tasks for castles.
for (Castle castle : CastleManager.getInstance().getCastles())
{
final int residenceId = castle.getResidenceId();
RESIDENCE_GUARD_MAP.put(residenceId, new CopyOnWriteArrayList<>());
ThreadPool.scheduleAtFixedRate(new AggroCheckTask(residenceId), residenceId * 100, 3000);
}
// Start tasks for fortresses.
for (Fort fort : FortManager.getInstance().getForts())
{
final int residenceId = fort.getResidenceId();
RESIDENCE_GUARD_MAP.put(residenceId, new CopyOnWriteArrayList<>());
ThreadPool.scheduleAtFixedRate(new AggroCheckTask(residenceId), 900 + ((residenceId - 100) * 100), 3000);
}
}
private class AggroCheckTask implements Runnable
{
private final int _residenceId;
public AggroCheckTask(int residenceId)
{
_residenceId = residenceId;
}
@Override
public String onAdvEvent(String event, Npc npc, PlayerInstance player)
public void run()
{
for (Npc guard : SPAWNED_GUARDS)
final List<Npc> guards = RESIDENCE_GUARD_MAP.get(_residenceId);
for (Npc guard : guards)
{
if (guard != null)
if (guard == null)
{
continue;
}
if (guard.isDead())
{
SPAWNED_GUARDS.remove(guard);
guards.remove(guard);
continue;
}
else
{
final WorldObject target = guard.getTarget();
if (!guard.isInCombat() || (target == null) || (guard.calculateDistance2D(target) > guard.getAggroRange()) || target.isInvul())
{
@ -131,9 +167,18 @@ public class SiegeGuards extends AbstractNpcAI
final PlayerInstance pl = summon == null ? (PlayerInstance) nearby : summon.getOwner();
if (((pl.getSiegeState() != 2) || pl.isRegisteredOnThisSiegeField(guard.getScriptValue())) && ((pl.getSiegeState() != 0) || (guard.getAI().getIntention() != CtrlIntention.AI_INTENTION_IDLE)))
{
if (!pl.isInvisible() && !pl.isInvul()) // skip invisible players
// skip invisible players
if (pl.isInvisible() || pl.isInvul())
{
addAttackPlayerDesire(guard, pl);
continue;
}
if (guard.isAttackable())
{
((Attackable) guard).addDamageHate(nearby, 0, 999);
}
guard.setRunning();
guard.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, target);
break; // no need to search more
}
}
@ -142,9 +187,6 @@ public class SiegeGuards extends AbstractNpcAI
}
}
}
}
return super.onAdvEvent(event, npc, player);
}
@Override
public String onAttack(Npc npc, PlayerInstance attacker, int damage, boolean isSummon)
@ -160,7 +202,7 @@ public class SiegeGuards extends AbstractNpcAI
@Override
public String onKill(Npc npc, PlayerInstance killer, boolean isSummon)
{
SPAWNED_GUARDS.remove(npc);
RESIDENCE_GUARD_MAP.get(npc.getScriptValue()).remove(npc);
return super.onKill(npc, killer, isSummon);
}
@ -172,10 +214,20 @@ public class SiegeGuards extends AbstractNpcAI
{
npc.setImmobilized(true);
}
final Castle castle = npc.getCastle();
final Fort fortress = npc.getFort();
npc.setScriptValue(fortress != null ? fortress.getResidenceId() : (castle != null ? castle.getResidenceId() : 0));
SPAWNED_GUARDS.add(npc);
final int residenceId = fortress != null ? fortress.getResidenceId() : (castle != null ? castle.getResidenceId() : 0);
npc.setScriptValue(residenceId);
if (RESIDENCE_GUARD_MAP.containsKey(residenceId))
{
RESIDENCE_GUARD_MAP.get(residenceId).add(npc);
}
else // Residence id not found.
{
RESIDENCE_GUARD_MAP.get(0).add(npc);
}
return super.onSpawn(npc);
}

View File

@ -16,11 +16,16 @@
*/
package ai.others;
import java.util.Collection;
import java.util.concurrent.ConcurrentHashMap;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArrayList;
import org.l2jmobius.commons.concurrent.ThreadPool;
import org.l2jmobius.gameserver.ai.CtrlIntention;
import org.l2jmobius.gameserver.geoengine.GeoEngine;
import org.l2jmobius.gameserver.instancemanager.CastleManager;
import org.l2jmobius.gameserver.instancemanager.FortManager;
import org.l2jmobius.gameserver.model.World;
import org.l2jmobius.gameserver.model.WorldObject;
import org.l2jmobius.gameserver.model.actor.Attackable;
@ -87,7 +92,7 @@ public class SiegeGuards extends AbstractNpcAI
35134, 35135, 35136, 35176, 35177, 35178, 35218, 35219, 35220, 35261, 35262, 35263, 35264, 35265, 35308, 35309, 35310, 35352, 35353, 35354, 35497, 35498, 35499, 35500, 35501, 35544, 35545, 35546
};
//@formatter:on
private static final Collection<Npc> SPAWNED_GUARDS = ConcurrentHashMap.newKeySet();
private static final Map<Integer, List<Npc>> RESIDENCE_GUARD_MAP = new HashMap<>();
public SiegeGuards()
{
@ -104,22 +109,53 @@ public class SiegeGuards extends AbstractNpcAI
addKillId(MERCENARIES);
addKillId(STATIONARY_MERCENARIES);
startQuestTimer("AGGRO_CHECK", 3000, null, null, true);
// Start task for unknown residences.
RESIDENCE_GUARD_MAP.put(0, new CopyOnWriteArrayList<>());
ThreadPool.scheduleAtFixedRate(new AggroCheckTask(0), 0, 3000);
// Start tasks for castles.
for (Castle castle : CastleManager.getInstance().getCastles())
{
final int residenceId = castle.getResidenceId();
RESIDENCE_GUARD_MAP.put(residenceId, new CopyOnWriteArrayList<>());
ThreadPool.scheduleAtFixedRate(new AggroCheckTask(residenceId), residenceId * 100, 3000);
}
// Start tasks for fortresses.
for (Fort fort : FortManager.getInstance().getForts())
{
final int residenceId = fort.getResidenceId();
RESIDENCE_GUARD_MAP.put(residenceId, new CopyOnWriteArrayList<>());
ThreadPool.scheduleAtFixedRate(new AggroCheckTask(residenceId), 900 + ((residenceId - 100) * 100), 3000);
}
}
private class AggroCheckTask implements Runnable
{
private final int _residenceId;
public AggroCheckTask(int residenceId)
{
_residenceId = residenceId;
}
@Override
public String onAdvEvent(String event, Npc npc, PlayerInstance player)
public void run()
{
for (Npc guard : SPAWNED_GUARDS)
final List<Npc> guards = RESIDENCE_GUARD_MAP.get(_residenceId);
for (Npc guard : guards)
{
if (guard != null)
if (guard == null)
{
continue;
}
if (guard.isDead())
{
SPAWNED_GUARDS.remove(guard);
guards.remove(guard);
continue;
}
else
{
final WorldObject target = guard.getTarget();
if (!guard.isInCombat() || (target == null) || (guard.calculateDistance2D(target) > guard.getAggroRange()) || target.isInvul())
{
@ -131,9 +167,18 @@ public class SiegeGuards extends AbstractNpcAI
final PlayerInstance pl = summon == null ? (PlayerInstance) nearby : summon.getOwner();
if (((pl.getSiegeState() != 2) || pl.isRegisteredOnThisSiegeField(guard.getScriptValue())) && ((pl.getSiegeState() != 0) || (guard.getAI().getIntention() != CtrlIntention.AI_INTENTION_IDLE)))
{
if (!pl.isInvisible() && !pl.isInvul()) // skip invisible players
// skip invisible players
if (pl.isInvisible() || pl.isInvul())
{
addAttackPlayerDesire(guard, pl);
continue;
}
if (guard.isAttackable())
{
((Attackable) guard).addDamageHate(nearby, 0, 999);
}
guard.setRunning();
guard.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, target);
break; // no need to search more
}
}
@ -142,9 +187,6 @@ public class SiegeGuards extends AbstractNpcAI
}
}
}
}
return super.onAdvEvent(event, npc, player);
}
@Override
public String onAttack(Npc npc, PlayerInstance attacker, int damage, boolean isSummon)
@ -160,7 +202,7 @@ public class SiegeGuards extends AbstractNpcAI
@Override
public String onKill(Npc npc, PlayerInstance killer, boolean isSummon)
{
SPAWNED_GUARDS.remove(npc);
RESIDENCE_GUARD_MAP.get(npc.getScriptValue()).remove(npc);
return super.onKill(npc, killer, isSummon);
}
@ -172,10 +214,20 @@ public class SiegeGuards extends AbstractNpcAI
{
npc.setImmobilized(true);
}
final Castle castle = npc.getCastle();
final Fort fortress = npc.getFort();
npc.setScriptValue(fortress != null ? fortress.getResidenceId() : (castle != null ? castle.getResidenceId() : 0));
SPAWNED_GUARDS.add(npc);
final int residenceId = fortress != null ? fortress.getResidenceId() : (castle != null ? castle.getResidenceId() : 0);
npc.setScriptValue(residenceId);
if (RESIDENCE_GUARD_MAP.containsKey(residenceId))
{
RESIDENCE_GUARD_MAP.get(residenceId).add(npc);
}
else // Residence id not found.
{
RESIDENCE_GUARD_MAP.get(0).add(npc);
}
return super.onSpawn(npc);
}

View File

@ -16,11 +16,16 @@
*/
package ai.others;
import java.util.Collection;
import java.util.concurrent.ConcurrentHashMap;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArrayList;
import org.l2jmobius.commons.concurrent.ThreadPool;
import org.l2jmobius.gameserver.ai.CtrlIntention;
import org.l2jmobius.gameserver.geoengine.GeoEngine;
import org.l2jmobius.gameserver.instancemanager.CastleManager;
import org.l2jmobius.gameserver.instancemanager.FortManager;
import org.l2jmobius.gameserver.model.World;
import org.l2jmobius.gameserver.model.WorldObject;
import org.l2jmobius.gameserver.model.actor.Attackable;
@ -87,7 +92,7 @@ public class SiegeGuards extends AbstractNpcAI
35134, 35135, 35136, 35176, 35177, 35178, 35218, 35219, 35220, 35261, 35262, 35263, 35264, 35265, 35308, 35309, 35310, 35352, 35353, 35354, 35497, 35498, 35499, 35500, 35501, 35544, 35545, 35546
};
//@formatter:on
private static final Collection<Npc> SPAWNED_GUARDS = ConcurrentHashMap.newKeySet();
private static final Map<Integer, List<Npc>> RESIDENCE_GUARD_MAP = new HashMap<>();
public SiegeGuards()
{
@ -104,22 +109,53 @@ public class SiegeGuards extends AbstractNpcAI
addKillId(MERCENARIES);
addKillId(STATIONARY_MERCENARIES);
startQuestTimer("AGGRO_CHECK", 3000, null, null, true);
// Start task for unknown residences.
RESIDENCE_GUARD_MAP.put(0, new CopyOnWriteArrayList<>());
ThreadPool.scheduleAtFixedRate(new AggroCheckTask(0), 0, 3000);
// Start tasks for castles.
for (Castle castle : CastleManager.getInstance().getCastles())
{
final int residenceId = castle.getResidenceId();
RESIDENCE_GUARD_MAP.put(residenceId, new CopyOnWriteArrayList<>());
ThreadPool.scheduleAtFixedRate(new AggroCheckTask(residenceId), residenceId * 100, 3000);
}
// Start tasks for fortresses.
for (Fort fort : FortManager.getInstance().getForts())
{
final int residenceId = fort.getResidenceId();
RESIDENCE_GUARD_MAP.put(residenceId, new CopyOnWriteArrayList<>());
ThreadPool.scheduleAtFixedRate(new AggroCheckTask(residenceId), 900 + ((residenceId - 100) * 100), 3000);
}
}
private class AggroCheckTask implements Runnable
{
private final int _residenceId;
public AggroCheckTask(int residenceId)
{
_residenceId = residenceId;
}
@Override
public String onAdvEvent(String event, Npc npc, PlayerInstance player)
public void run()
{
for (Npc guard : SPAWNED_GUARDS)
final List<Npc> guards = RESIDENCE_GUARD_MAP.get(_residenceId);
for (Npc guard : guards)
{
if (guard != null)
if (guard == null)
{
continue;
}
if (guard.isDead())
{
SPAWNED_GUARDS.remove(guard);
guards.remove(guard);
continue;
}
else
{
final WorldObject target = guard.getTarget();
if (!guard.isInCombat() || (target == null) || (guard.calculateDistance2D(target) > guard.getAggroRange()) || target.isInvul())
{
@ -131,9 +167,18 @@ public class SiegeGuards extends AbstractNpcAI
final PlayerInstance pl = summon == null ? (PlayerInstance) nearby : summon.getOwner();
if (((pl.getSiegeState() != 2) || pl.isRegisteredOnThisSiegeField(guard.getScriptValue())) && ((pl.getSiegeState() != 0) || (guard.getAI().getIntention() != CtrlIntention.AI_INTENTION_IDLE)))
{
if (!pl.isInvisible() && !pl.isInvul()) // skip invisible players
// skip invisible players
if (pl.isInvisible() || pl.isInvul())
{
addAttackPlayerDesire(guard, pl);
continue;
}
if (guard.isAttackable())
{
((Attackable) guard).addDamageHate(nearby, 0, 999);
}
guard.setRunning();
guard.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, target);
break; // no need to search more
}
}
@ -142,9 +187,6 @@ public class SiegeGuards extends AbstractNpcAI
}
}
}
}
return super.onAdvEvent(event, npc, player);
}
@Override
public String onAttack(Npc npc, PlayerInstance attacker, int damage, boolean isSummon)
@ -160,7 +202,7 @@ public class SiegeGuards extends AbstractNpcAI
@Override
public String onKill(Npc npc, PlayerInstance killer, boolean isSummon)
{
SPAWNED_GUARDS.remove(npc);
RESIDENCE_GUARD_MAP.get(npc.getScriptValue()).remove(npc);
return super.onKill(npc, killer, isSummon);
}
@ -172,10 +214,20 @@ public class SiegeGuards extends AbstractNpcAI
{
npc.setImmobilized(true);
}
final Castle castle = npc.getCastle();
final Fort fortress = npc.getFort();
npc.setScriptValue(fortress != null ? fortress.getResidenceId() : (castle != null ? castle.getResidenceId() : 0));
SPAWNED_GUARDS.add(npc);
final int residenceId = fortress != null ? fortress.getResidenceId() : (castle != null ? castle.getResidenceId() : 0);
npc.setScriptValue(residenceId);
if (RESIDENCE_GUARD_MAP.containsKey(residenceId))
{
RESIDENCE_GUARD_MAP.get(residenceId).add(npc);
}
else // Residence id not found.
{
RESIDENCE_GUARD_MAP.get(0).add(npc);
}
return super.onSpawn(npc);
}

View File

@ -16,11 +16,16 @@
*/
package ai.others;
import java.util.Collection;
import java.util.concurrent.ConcurrentHashMap;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArrayList;
import org.l2jmobius.commons.concurrent.ThreadPool;
import org.l2jmobius.gameserver.ai.CtrlIntention;
import org.l2jmobius.gameserver.geoengine.GeoEngine;
import org.l2jmobius.gameserver.instancemanager.CastleManager;
import org.l2jmobius.gameserver.instancemanager.FortManager;
import org.l2jmobius.gameserver.model.World;
import org.l2jmobius.gameserver.model.WorldObject;
import org.l2jmobius.gameserver.model.actor.Attackable;
@ -87,7 +92,7 @@ public class SiegeGuards extends AbstractNpcAI
35134, 35135, 35136, 35176, 35177, 35178, 35218, 35219, 35220, 35261, 35262, 35263, 35264, 35265, 35308, 35309, 35310, 35352, 35353, 35354, 35497, 35498, 35499, 35500, 35501, 35544, 35545, 35546
};
//@formatter:on
private static final Collection<Npc> SPAWNED_GUARDS = ConcurrentHashMap.newKeySet();
private static final Map<Integer, List<Npc>> RESIDENCE_GUARD_MAP = new HashMap<>();
public SiegeGuards()
{
@ -104,22 +109,53 @@ public class SiegeGuards extends AbstractNpcAI
addKillId(MERCENARIES);
addKillId(STATIONARY_MERCENARIES);
startQuestTimer("AGGRO_CHECK", 3000, null, null, true);
// Start task for unknown residences.
RESIDENCE_GUARD_MAP.put(0, new CopyOnWriteArrayList<>());
ThreadPool.scheduleAtFixedRate(new AggroCheckTask(0), 0, 3000);
// Start tasks for castles.
for (Castle castle : CastleManager.getInstance().getCastles())
{
final int residenceId = castle.getResidenceId();
RESIDENCE_GUARD_MAP.put(residenceId, new CopyOnWriteArrayList<>());
ThreadPool.scheduleAtFixedRate(new AggroCheckTask(residenceId), residenceId * 100, 3000);
}
// Start tasks for fortresses.
for (Fort fort : FortManager.getInstance().getForts())
{
final int residenceId = fort.getResidenceId();
RESIDENCE_GUARD_MAP.put(residenceId, new CopyOnWriteArrayList<>());
ThreadPool.scheduleAtFixedRate(new AggroCheckTask(residenceId), 900 + ((residenceId - 100) * 100), 3000);
}
}
private class AggroCheckTask implements Runnable
{
private final int _residenceId;
public AggroCheckTask(int residenceId)
{
_residenceId = residenceId;
}
@Override
public String onAdvEvent(String event, Npc npc, PlayerInstance player)
public void run()
{
for (Npc guard : SPAWNED_GUARDS)
final List<Npc> guards = RESIDENCE_GUARD_MAP.get(_residenceId);
for (Npc guard : guards)
{
if (guard != null)
if (guard == null)
{
continue;
}
if (guard.isDead())
{
SPAWNED_GUARDS.remove(guard);
guards.remove(guard);
continue;
}
else
{
final WorldObject target = guard.getTarget();
if (!guard.isInCombat() || (target == null) || (guard.calculateDistance2D(target) > guard.getAggroRange()) || target.isInvul())
{
@ -131,9 +167,18 @@ public class SiegeGuards extends AbstractNpcAI
final PlayerInstance pl = summon == null ? (PlayerInstance) nearby : summon.getOwner();
if (((pl.getSiegeState() != 2) || pl.isRegisteredOnThisSiegeField(guard.getScriptValue())) && ((pl.getSiegeState() != 0) || (guard.getAI().getIntention() != CtrlIntention.AI_INTENTION_IDLE)))
{
if (!pl.isInvisible() && !pl.isInvul()) // skip invisible players
// skip invisible players
if (pl.isInvisible() || pl.isInvul())
{
addAttackPlayerDesire(guard, pl);
continue;
}
if (guard.isAttackable())
{
((Attackable) guard).addDamageHate(nearby, 0, 999);
}
guard.setRunning();
guard.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, target);
break; // no need to search more
}
}
@ -142,9 +187,6 @@ public class SiegeGuards extends AbstractNpcAI
}
}
}
}
return super.onAdvEvent(event, npc, player);
}
@Override
public String onAttack(Npc npc, PlayerInstance attacker, int damage, boolean isSummon)
@ -160,7 +202,7 @@ public class SiegeGuards extends AbstractNpcAI
@Override
public String onKill(Npc npc, PlayerInstance killer, boolean isSummon)
{
SPAWNED_GUARDS.remove(npc);
RESIDENCE_GUARD_MAP.get(npc.getScriptValue()).remove(npc);
return super.onKill(npc, killer, isSummon);
}
@ -172,10 +214,20 @@ public class SiegeGuards extends AbstractNpcAI
{
npc.setImmobilized(true);
}
final Castle castle = npc.getCastle();
final Fort fortress = npc.getFort();
npc.setScriptValue(fortress != null ? fortress.getResidenceId() : (castle != null ? castle.getResidenceId() : 0));
SPAWNED_GUARDS.add(npc);
final int residenceId = fortress != null ? fortress.getResidenceId() : (castle != null ? castle.getResidenceId() : 0);
npc.setScriptValue(residenceId);
if (RESIDENCE_GUARD_MAP.containsKey(residenceId))
{
RESIDENCE_GUARD_MAP.get(residenceId).add(npc);
}
else // Residence id not found.
{
RESIDENCE_GUARD_MAP.get(0).add(npc);
}
return super.onSpawn(npc);
}

View File

@ -16,11 +16,16 @@
*/
package ai.others;
import java.util.Collection;
import java.util.concurrent.ConcurrentHashMap;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArrayList;
import org.l2jmobius.commons.concurrent.ThreadPool;
import org.l2jmobius.gameserver.ai.CtrlIntention;
import org.l2jmobius.gameserver.geoengine.GeoEngine;
import org.l2jmobius.gameserver.instancemanager.CastleManager;
import org.l2jmobius.gameserver.instancemanager.FortManager;
import org.l2jmobius.gameserver.model.World;
import org.l2jmobius.gameserver.model.WorldObject;
import org.l2jmobius.gameserver.model.actor.Attackable;
@ -87,7 +92,7 @@ public class SiegeGuards extends AbstractNpcAI
35134, 35135, 35136, 35176, 35177, 35178, 35218, 35219, 35220, 35261, 35262, 35263, 35264, 35265, 35308, 35309, 35310, 35352, 35353, 35354, 35497, 35498, 35499, 35500, 35501, 35544, 35545, 35546
};
//@formatter:on
private static final Collection<Npc> SPAWNED_GUARDS = ConcurrentHashMap.newKeySet();
private static final Map<Integer, List<Npc>> RESIDENCE_GUARD_MAP = new HashMap<>();
public SiegeGuards()
{
@ -104,22 +109,53 @@ public class SiegeGuards extends AbstractNpcAI
addKillId(MERCENARIES);
addKillId(STATIONARY_MERCENARIES);
startQuestTimer("AGGRO_CHECK", 3000, null, null, true);
// Start task for unknown residences.
RESIDENCE_GUARD_MAP.put(0, new CopyOnWriteArrayList<>());
ThreadPool.scheduleAtFixedRate(new AggroCheckTask(0), 0, 3000);
// Start tasks for castles.
for (Castle castle : CastleManager.getInstance().getCastles())
{
final int residenceId = castle.getResidenceId();
RESIDENCE_GUARD_MAP.put(residenceId, new CopyOnWriteArrayList<>());
ThreadPool.scheduleAtFixedRate(new AggroCheckTask(residenceId), residenceId * 100, 3000);
}
// Start tasks for fortresses.
for (Fort fort : FortManager.getInstance().getForts())
{
final int residenceId = fort.getResidenceId();
RESIDENCE_GUARD_MAP.put(residenceId, new CopyOnWriteArrayList<>());
ThreadPool.scheduleAtFixedRate(new AggroCheckTask(residenceId), 900 + ((residenceId - 100) * 100), 3000);
}
}
private class AggroCheckTask implements Runnable
{
private final int _residenceId;
public AggroCheckTask(int residenceId)
{
_residenceId = residenceId;
}
@Override
public String onAdvEvent(String event, Npc npc, PlayerInstance player)
public void run()
{
for (Npc guard : SPAWNED_GUARDS)
final List<Npc> guards = RESIDENCE_GUARD_MAP.get(_residenceId);
for (Npc guard : guards)
{
if (guard != null)
if (guard == null)
{
continue;
}
if (guard.isDead())
{
SPAWNED_GUARDS.remove(guard);
guards.remove(guard);
continue;
}
else
{
final WorldObject target = guard.getTarget();
if (!guard.isInCombat() || (target == null) || (guard.calculateDistance2D(target) > guard.getAggroRange()) || target.isInvul())
{
@ -131,9 +167,18 @@ public class SiegeGuards extends AbstractNpcAI
final PlayerInstance pl = summon == null ? (PlayerInstance) nearby : summon.getOwner();
if (((pl.getSiegeState() != 2) || pl.isRegisteredOnThisSiegeField(guard.getScriptValue())) && ((pl.getSiegeState() != 0) || (guard.getAI().getIntention() != CtrlIntention.AI_INTENTION_IDLE)))
{
if (!pl.isInvisible() && !pl.isInvul()) // skip invisible players
// skip invisible players
if (pl.isInvisible() || pl.isInvul())
{
addAttackPlayerDesire(guard, pl);
continue;
}
if (guard.isAttackable())
{
((Attackable) guard).addDamageHate(nearby, 0, 999);
}
guard.setRunning();
guard.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, target);
break; // no need to search more
}
}
@ -142,9 +187,6 @@ public class SiegeGuards extends AbstractNpcAI
}
}
}
}
return super.onAdvEvent(event, npc, player);
}
@Override
public String onAttack(Npc npc, PlayerInstance attacker, int damage, boolean isSummon)
@ -160,7 +202,7 @@ public class SiegeGuards extends AbstractNpcAI
@Override
public String onKill(Npc npc, PlayerInstance killer, boolean isSummon)
{
SPAWNED_GUARDS.remove(npc);
RESIDENCE_GUARD_MAP.get(npc.getScriptValue()).remove(npc);
return super.onKill(npc, killer, isSummon);
}
@ -172,10 +214,20 @@ public class SiegeGuards extends AbstractNpcAI
{
npc.setImmobilized(true);
}
final Castle castle = npc.getCastle();
final Fort fortress = npc.getFort();
npc.setScriptValue(fortress != null ? fortress.getResidenceId() : (castle != null ? castle.getResidenceId() : 0));
SPAWNED_GUARDS.add(npc);
final int residenceId = fortress != null ? fortress.getResidenceId() : (castle != null ? castle.getResidenceId() : 0);
npc.setScriptValue(residenceId);
if (RESIDENCE_GUARD_MAP.containsKey(residenceId))
{
RESIDENCE_GUARD_MAP.get(residenceId).add(npc);
}
else // Residence id not found.
{
RESIDENCE_GUARD_MAP.get(0).add(npc);
}
return super.onSpawn(npc);
}

View File

@ -16,11 +16,16 @@
*/
package ai.others;
import java.util.Collection;
import java.util.concurrent.ConcurrentHashMap;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArrayList;
import org.l2jmobius.commons.concurrent.ThreadPool;
import org.l2jmobius.gameserver.ai.CtrlIntention;
import org.l2jmobius.gameserver.geoengine.GeoEngine;
import org.l2jmobius.gameserver.instancemanager.CastleManager;
import org.l2jmobius.gameserver.instancemanager.FortManager;
import org.l2jmobius.gameserver.model.World;
import org.l2jmobius.gameserver.model.WorldObject;
import org.l2jmobius.gameserver.model.actor.Attackable;
@ -87,7 +92,7 @@ public class SiegeGuards extends AbstractNpcAI
35134, 35135, 35136, 35176, 35177, 35178, 35218, 35219, 35220, 35261, 35262, 35263, 35264, 35265, 35308, 35309, 35310, 35352, 35353, 35354, 35497, 35498, 35499, 35500, 35501, 35544, 35545, 35546
};
//@formatter:on
private static final Collection<Npc> SPAWNED_GUARDS = ConcurrentHashMap.newKeySet();
private static final Map<Integer, List<Npc>> RESIDENCE_GUARD_MAP = new HashMap<>();
public SiegeGuards()
{
@ -104,22 +109,53 @@ public class SiegeGuards extends AbstractNpcAI
addKillId(MERCENARIES);
addKillId(STATIONARY_MERCENARIES);
startQuestTimer("AGGRO_CHECK", 3000, null, null, true);
// Start task for unknown residences.
RESIDENCE_GUARD_MAP.put(0, new CopyOnWriteArrayList<>());
ThreadPool.scheduleAtFixedRate(new AggroCheckTask(0), 0, 3000);
// Start tasks for castles.
for (Castle castle : CastleManager.getInstance().getCastles())
{
final int residenceId = castle.getResidenceId();
RESIDENCE_GUARD_MAP.put(residenceId, new CopyOnWriteArrayList<>());
ThreadPool.scheduleAtFixedRate(new AggroCheckTask(residenceId), residenceId * 100, 3000);
}
// Start tasks for fortresses.
for (Fort fort : FortManager.getInstance().getForts())
{
final int residenceId = fort.getResidenceId();
RESIDENCE_GUARD_MAP.put(residenceId, new CopyOnWriteArrayList<>());
ThreadPool.scheduleAtFixedRate(new AggroCheckTask(residenceId), 900 + ((residenceId - 100) * 100), 3000);
}
}
private class AggroCheckTask implements Runnable
{
private final int _residenceId;
public AggroCheckTask(int residenceId)
{
_residenceId = residenceId;
}
@Override
public String onAdvEvent(String event, Npc npc, PlayerInstance player)
public void run()
{
for (Npc guard : SPAWNED_GUARDS)
final List<Npc> guards = RESIDENCE_GUARD_MAP.get(_residenceId);
for (Npc guard : guards)
{
if (guard != null)
if (guard == null)
{
continue;
}
if (guard.isDead())
{
SPAWNED_GUARDS.remove(guard);
guards.remove(guard);
continue;
}
else
{
final WorldObject target = guard.getTarget();
if (!guard.isInCombat() || (target == null) || (guard.calculateDistance2D(target) > guard.getAggroRange()) || target.isInvul())
{
@ -131,9 +167,18 @@ public class SiegeGuards extends AbstractNpcAI
final PlayerInstance pl = summon == null ? (PlayerInstance) nearby : summon.getOwner();
if (((pl.getSiegeState() != 2) || pl.isRegisteredOnThisSiegeField(guard.getScriptValue())) && ((pl.getSiegeState() != 0) || (guard.getAI().getIntention() != CtrlIntention.AI_INTENTION_IDLE)))
{
if (!pl.isInvisible() && !pl.isInvul()) // skip invisible players
// skip invisible players
if (pl.isInvisible() || pl.isInvul())
{
addAttackPlayerDesire(guard, pl);
continue;
}
if (guard.isAttackable())
{
((Attackable) guard).addDamageHate(nearby, 0, 999);
}
guard.setRunning();
guard.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, target);
break; // no need to search more
}
}
@ -142,9 +187,6 @@ public class SiegeGuards extends AbstractNpcAI
}
}
}
}
return super.onAdvEvent(event, npc, player);
}
@Override
public String onAttack(Npc npc, PlayerInstance attacker, int damage, boolean isSummon)
@ -160,7 +202,7 @@ public class SiegeGuards extends AbstractNpcAI
@Override
public String onKill(Npc npc, PlayerInstance killer, boolean isSummon)
{
SPAWNED_GUARDS.remove(npc);
RESIDENCE_GUARD_MAP.get(npc.getScriptValue()).remove(npc);
return super.onKill(npc, killer, isSummon);
}
@ -172,10 +214,20 @@ public class SiegeGuards extends AbstractNpcAI
{
npc.setImmobilized(true);
}
final Castle castle = npc.getCastle();
final Fort fortress = npc.getFort();
npc.setScriptValue(fortress != null ? fortress.getResidenceId() : (castle != null ? castle.getResidenceId() : 0));
SPAWNED_GUARDS.add(npc);
final int residenceId = fortress != null ? fortress.getResidenceId() : (castle != null ? castle.getResidenceId() : 0);
npc.setScriptValue(residenceId);
if (RESIDENCE_GUARD_MAP.containsKey(residenceId))
{
RESIDENCE_GUARD_MAP.get(residenceId).add(npc);
}
else // Residence id not found.
{
RESIDENCE_GUARD_MAP.get(0).add(npc);
}
return super.onSpawn(npc);
}

View File

@ -16,11 +16,16 @@
*/
package ai.others;
import java.util.Collection;
import java.util.concurrent.ConcurrentHashMap;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArrayList;
import org.l2jmobius.commons.concurrent.ThreadPool;
import org.l2jmobius.gameserver.ai.CtrlIntention;
import org.l2jmobius.gameserver.geoengine.GeoEngine;
import org.l2jmobius.gameserver.instancemanager.CastleManager;
import org.l2jmobius.gameserver.instancemanager.FortManager;
import org.l2jmobius.gameserver.model.World;
import org.l2jmobius.gameserver.model.WorldObject;
import org.l2jmobius.gameserver.model.actor.Attackable;
@ -87,7 +92,7 @@ public class SiegeGuards extends AbstractNpcAI
35134, 35135, 35136, 35176, 35177, 35178, 35218, 35219, 35220, 35261, 35262, 35263, 35264, 35265, 35308, 35309, 35310, 35352, 35353, 35354, 35497, 35498, 35499, 35500, 35501, 35544, 35545, 35546
};
//@formatter:on
private static final Collection<Npc> SPAWNED_GUARDS = ConcurrentHashMap.newKeySet();
private static final Map<Integer, List<Npc>> RESIDENCE_GUARD_MAP = new HashMap<>();
public SiegeGuards()
{
@ -104,22 +109,53 @@ public class SiegeGuards extends AbstractNpcAI
addKillId(MERCENARIES);
addKillId(STATIONARY_MERCENARIES);
startQuestTimer("AGGRO_CHECK", 3000, null, null, true);
// Start task for unknown residences.
RESIDENCE_GUARD_MAP.put(0, new CopyOnWriteArrayList<>());
ThreadPool.scheduleAtFixedRate(new AggroCheckTask(0), 0, 3000);
// Start tasks for castles.
for (Castle castle : CastleManager.getInstance().getCastles())
{
final int residenceId = castle.getResidenceId();
RESIDENCE_GUARD_MAP.put(residenceId, new CopyOnWriteArrayList<>());
ThreadPool.scheduleAtFixedRate(new AggroCheckTask(residenceId), residenceId * 100, 3000);
}
// Start tasks for fortresses.
for (Fort fort : FortManager.getInstance().getForts())
{
final int residenceId = fort.getResidenceId();
RESIDENCE_GUARD_MAP.put(residenceId, new CopyOnWriteArrayList<>());
ThreadPool.scheduleAtFixedRate(new AggroCheckTask(residenceId), 900 + ((residenceId - 100) * 100), 3000);
}
}
private class AggroCheckTask implements Runnable
{
private final int _residenceId;
public AggroCheckTask(int residenceId)
{
_residenceId = residenceId;
}
@Override
public String onAdvEvent(String event, Npc npc, PlayerInstance player)
public void run()
{
for (Npc guard : SPAWNED_GUARDS)
final List<Npc> guards = RESIDENCE_GUARD_MAP.get(_residenceId);
for (Npc guard : guards)
{
if (guard != null)
if (guard == null)
{
continue;
}
if (guard.isDead())
{
SPAWNED_GUARDS.remove(guard);
guards.remove(guard);
continue;
}
else
{
final WorldObject target = guard.getTarget();
if (!guard.isInCombat() || (target == null) || (guard.calculateDistance2D(target) > guard.getAggroRange()) || target.isInvul())
{
@ -131,9 +167,18 @@ public class SiegeGuards extends AbstractNpcAI
final PlayerInstance pl = summon == null ? (PlayerInstance) nearby : summon.getOwner();
if (((pl.getSiegeState() != 2) || pl.isRegisteredOnThisSiegeField(guard.getScriptValue())) && ((pl.getSiegeState() != 0) || (guard.getAI().getIntention() != CtrlIntention.AI_INTENTION_IDLE)))
{
if (!pl.isInvisible() && !pl.isInvul()) // skip invisible players
// skip invisible players
if (pl.isInvisible() || pl.isInvul())
{
addAttackPlayerDesire(guard, pl);
continue;
}
if (guard.isAttackable())
{
((Attackable) guard).addDamageHate(nearby, 0, 999);
}
guard.setRunning();
guard.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, target);
break; // no need to search more
}
}
@ -142,9 +187,6 @@ public class SiegeGuards extends AbstractNpcAI
}
}
}
}
return super.onAdvEvent(event, npc, player);
}
@Override
public String onAttack(Npc npc, PlayerInstance attacker, int damage, boolean isSummon)
@ -160,7 +202,7 @@ public class SiegeGuards extends AbstractNpcAI
@Override
public String onKill(Npc npc, PlayerInstance killer, boolean isSummon)
{
SPAWNED_GUARDS.remove(npc);
RESIDENCE_GUARD_MAP.get(npc.getScriptValue()).remove(npc);
return super.onKill(npc, killer, isSummon);
}
@ -172,10 +214,20 @@ public class SiegeGuards extends AbstractNpcAI
{
npc.setImmobilized(true);
}
final Castle castle = npc.getCastle();
final Fort fortress = npc.getFort();
npc.setScriptValue(fortress != null ? fortress.getResidenceId() : (castle != null ? castle.getResidenceId() : 0));
SPAWNED_GUARDS.add(npc);
final int residenceId = fortress != null ? fortress.getResidenceId() : (castle != null ? castle.getResidenceId() : 0);
npc.setScriptValue(residenceId);
if (RESIDENCE_GUARD_MAP.containsKey(residenceId))
{
RESIDENCE_GUARD_MAP.get(residenceId).add(npc);
}
else // Residence id not found.
{
RESIDENCE_GUARD_MAP.get(0).add(npc);
}
return super.onSpawn(npc);
}

View File

@ -16,11 +16,16 @@
*/
package ai.others;
import java.util.Collection;
import java.util.concurrent.ConcurrentHashMap;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArrayList;
import org.l2jmobius.commons.concurrent.ThreadPool;
import org.l2jmobius.gameserver.ai.CtrlIntention;
import org.l2jmobius.gameserver.geoengine.GeoEngine;
import org.l2jmobius.gameserver.instancemanager.CastleManager;
import org.l2jmobius.gameserver.instancemanager.FortManager;
import org.l2jmobius.gameserver.model.World;
import org.l2jmobius.gameserver.model.WorldObject;
import org.l2jmobius.gameserver.model.actor.Attackable;
@ -87,7 +92,7 @@ public class SiegeGuards extends AbstractNpcAI
35134, 35135, 35136, 35176, 35177, 35178, 35218, 35219, 35220, 35261, 35262, 35263, 35264, 35265, 35308, 35309, 35310, 35352, 35353, 35354, 35497, 35498, 35499, 35500, 35501, 35544, 35545, 35546
};
//@formatter:on
private static final Collection<Npc> SPAWNED_GUARDS = ConcurrentHashMap.newKeySet();
private static final Map<Integer, List<Npc>> RESIDENCE_GUARD_MAP = new HashMap<>();
public SiegeGuards()
{
@ -104,22 +109,53 @@ public class SiegeGuards extends AbstractNpcAI
addKillId(MERCENARIES);
addKillId(STATIONARY_MERCENARIES);
startQuestTimer("AGGRO_CHECK", 3000, null, null, true);
// Start task for unknown residences.
RESIDENCE_GUARD_MAP.put(0, new CopyOnWriteArrayList<>());
ThreadPool.scheduleAtFixedRate(new AggroCheckTask(0), 0, 3000);
// Start tasks for castles.
for (Castle castle : CastleManager.getInstance().getCastles())
{
final int residenceId = castle.getResidenceId();
RESIDENCE_GUARD_MAP.put(residenceId, new CopyOnWriteArrayList<>());
ThreadPool.scheduleAtFixedRate(new AggroCheckTask(residenceId), residenceId * 100, 3000);
}
// Start tasks for fortresses.
for (Fort fort : FortManager.getInstance().getForts())
{
final int residenceId = fort.getResidenceId();
RESIDENCE_GUARD_MAP.put(residenceId, new CopyOnWriteArrayList<>());
ThreadPool.scheduleAtFixedRate(new AggroCheckTask(residenceId), 900 + ((residenceId - 100) * 100), 3000);
}
}
private class AggroCheckTask implements Runnable
{
private final int _residenceId;
public AggroCheckTask(int residenceId)
{
_residenceId = residenceId;
}
@Override
public String onAdvEvent(String event, Npc npc, PlayerInstance player)
public void run()
{
for (Npc guard : SPAWNED_GUARDS)
final List<Npc> guards = RESIDENCE_GUARD_MAP.get(_residenceId);
for (Npc guard : guards)
{
if (guard != null)
if (guard == null)
{
continue;
}
if (guard.isDead())
{
SPAWNED_GUARDS.remove(guard);
guards.remove(guard);
continue;
}
else
{
final WorldObject target = guard.getTarget();
if (!guard.isInCombat() || (target == null) || (guard.calculateDistance2D(target) > guard.getAggroRange()) || target.isInvul())
{
@ -131,9 +167,18 @@ public class SiegeGuards extends AbstractNpcAI
final PlayerInstance pl = summon == null ? (PlayerInstance) nearby : summon.getOwner();
if (((pl.getSiegeState() != 2) || pl.isRegisteredOnThisSiegeField(guard.getScriptValue())) && ((pl.getSiegeState() != 0) || (guard.getAI().getIntention() != CtrlIntention.AI_INTENTION_IDLE)))
{
if (!pl.isInvisible() && !pl.isInvul()) // skip invisible players
// skip invisible players
if (pl.isInvisible() || pl.isInvul())
{
addAttackPlayerDesire(guard, pl);
continue;
}
if (guard.isAttackable())
{
((Attackable) guard).addDamageHate(nearby, 0, 999);
}
guard.setRunning();
guard.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, target);
break; // no need to search more
}
}
@ -142,9 +187,6 @@ public class SiegeGuards extends AbstractNpcAI
}
}
}
}
return super.onAdvEvent(event, npc, player);
}
@Override
public String onAttack(Npc npc, PlayerInstance attacker, int damage, boolean isSummon)
@ -160,7 +202,7 @@ public class SiegeGuards extends AbstractNpcAI
@Override
public String onKill(Npc npc, PlayerInstance killer, boolean isSummon)
{
SPAWNED_GUARDS.remove(npc);
RESIDENCE_GUARD_MAP.get(npc.getScriptValue()).remove(npc);
return super.onKill(npc, killer, isSummon);
}
@ -172,10 +214,20 @@ public class SiegeGuards extends AbstractNpcAI
{
npc.setImmobilized(true);
}
final Castle castle = npc.getCastle();
final Fort fortress = npc.getFort();
npc.setScriptValue(fortress != null ? fortress.getResidenceId() : (castle != null ? castle.getResidenceId() : 0));
SPAWNED_GUARDS.add(npc);
final int residenceId = fortress != null ? fortress.getResidenceId() : (castle != null ? castle.getResidenceId() : 0);
npc.setScriptValue(residenceId);
if (RESIDENCE_GUARD_MAP.containsKey(residenceId))
{
RESIDENCE_GUARD_MAP.get(residenceId).add(npc);
}
else // Residence id not found.
{
RESIDENCE_GUARD_MAP.get(0).add(npc);
}
return super.onSpawn(npc);
}

View File

@ -16,11 +16,16 @@
*/
package ai.others;
import java.util.Collection;
import java.util.concurrent.ConcurrentHashMap;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArrayList;
import org.l2jmobius.commons.concurrent.ThreadPool;
import org.l2jmobius.gameserver.ai.CtrlIntention;
import org.l2jmobius.gameserver.geoengine.GeoEngine;
import org.l2jmobius.gameserver.instancemanager.CastleManager;
import org.l2jmobius.gameserver.instancemanager.FortManager;
import org.l2jmobius.gameserver.model.World;
import org.l2jmobius.gameserver.model.WorldObject;
import org.l2jmobius.gameserver.model.actor.Attackable;
@ -87,7 +92,7 @@ public class SiegeGuards extends AbstractNpcAI
35134, 35135, 35136, 35176, 35177, 35178, 35218, 35219, 35220, 35261, 35262, 35263, 35264, 35265, 35308, 35309, 35310, 35352, 35353, 35354, 35497, 35498, 35499, 35500, 35501, 35544, 35545, 35546
};
//@formatter:on
private static final Collection<Npc> SPAWNED_GUARDS = ConcurrentHashMap.newKeySet();
private static final Map<Integer, List<Npc>> RESIDENCE_GUARD_MAP = new HashMap<>();
public SiegeGuards()
{
@ -104,24 +109,55 @@ public class SiegeGuards extends AbstractNpcAI
addKillId(MERCENARIES);
addKillId(STATIONARY_MERCENARIES);
startQuestTimer("AGGRO_CHECK", 3000, null, null, true);
// Start task for unknown residences.
RESIDENCE_GUARD_MAP.put(0, new CopyOnWriteArrayList<>());
ThreadPool.scheduleAtFixedRate(new AggroCheckTask(0), 0, 3000);
// Start tasks for castles.
for (Castle castle : CastleManager.getInstance().getCastles())
{
final int residenceId = castle.getResidenceId();
RESIDENCE_GUARD_MAP.put(residenceId, new CopyOnWriteArrayList<>());
ThreadPool.scheduleAtFixedRate(new AggroCheckTask(residenceId), residenceId * 100, 3000);
}
// Start tasks for fortresses.
for (Fort fort : FortManager.getInstance().getForts())
{
final int residenceId = fort.getResidenceId();
RESIDENCE_GUARD_MAP.put(residenceId, new CopyOnWriteArrayList<>());
ThreadPool.scheduleAtFixedRate(new AggroCheckTask(residenceId), 900 + ((residenceId - 100) * 100), 3000);
}
}
private class AggroCheckTask implements Runnable
{
private final int _residenceId;
public AggroCheckTask(int residenceId)
{
_residenceId = residenceId;
}
@Override
public String onAdvEvent(String event, Npc npc, PlayerInstance player)
public void run()
{
for (Npc guard : SPAWNED_GUARDS)
final List<Npc> guards = RESIDENCE_GUARD_MAP.get(_residenceId);
for (Npc guard : guards)
{
if (guard != null)
if (guard == null)
{
continue;
}
if (guard.isDead())
{
SPAWNED_GUARDS.remove(guard);
guards.remove(guard);
continue;
}
else
{
final WorldObject target = guard.getTarget();
if (!guard.isInCombat() || (target == null) || (guard.calculateDistance2D(target) > guard.getAggroRange()))
if (!guard.isInCombat() || (target == null) || (guard.calculateDistance2D(target) > guard.getAggroRange()) || (target.isPlayer() && target.getActingPlayer().isInvul()))
{
for (Creature nearby : World.getInstance().getVisibleObjectsInRange(guard, Creature.class, guard.getAggroRange()))
{
@ -129,9 +165,20 @@ public class SiegeGuards extends AbstractNpcAI
{
final Summon summon = nearby.isSummon() ? (Summon) nearby : null;
final PlayerInstance pl = summon == null ? (PlayerInstance) nearby : summon.getOwner();
if (((pl.getSiegeState() != 2) || pl.isRegisteredOnThisSiegeField(guard.getScriptValue())) && ((pl.getSiegeState() != 0) || (guard.getAI().getIntention() != CtrlIntention.AI_INTENTION_IDLE)) && (!pl.isInvisible() && !pl.isInvul()))
if (((pl.getSiegeState() != 2) || pl.isRegisteredOnThisSiegeField(guard.getScriptValue())) && ((pl.getSiegeState() != 0) || (guard.getAI().getIntention() != CtrlIntention.AI_INTENTION_IDLE)))
{
addAttackDesire(guard, pl);
// skip invisible players
if (pl.isInvisible() || pl.isInvul())
{
continue;
}
if (guard.isAttackable())
{
((Attackable) guard).addDamageHate(nearby, 0, 999);
}
guard.setRunning();
guard.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, target);
break; // no need to search more
}
}
@ -140,8 +187,6 @@ public class SiegeGuards extends AbstractNpcAI
}
}
}
return super.onAdvEvent(event, npc, player);
}
@Override
public String onAttack(Npc npc, PlayerInstance attacker, int damage, boolean isSummon)
@ -157,22 +202,32 @@ public class SiegeGuards extends AbstractNpcAI
@Override
public String onKill(Npc npc, PlayerInstance killer, boolean isSummon)
{
SPAWNED_GUARDS.remove(npc);
RESIDENCE_GUARD_MAP.get(npc.getScriptValue()).remove(npc);
return super.onKill(npc, killer, isSummon);
}
@Override
public String onSpawn(Npc npc)
{
// npc.setRandomWalking(false);
npc.setRandomWalking(false);
if ((npc.getTemplate().getBaseAttackType() != WeaponType.SWORD) && (npc.getTemplate().getBaseAttackType() != WeaponType.POLE))
{
npc.setImmobilized(true);
}
final Castle castle = npc.getCastle();
final Fort fortress = npc.getFort();
npc.setScriptValue(fortress != null ? fortress.getResidenceId() : (castle != null ? castle.getResidenceId() : 0));
SPAWNED_GUARDS.add(npc);
final int residenceId = fortress != null ? fortress.getResidenceId() : (castle != null ? castle.getResidenceId() : 0);
npc.setScriptValue(residenceId);
if (RESIDENCE_GUARD_MAP.containsKey(residenceId))
{
RESIDENCE_GUARD_MAP.get(residenceId).add(npc);
}
else // Residence id not found.
{
RESIDENCE_GUARD_MAP.get(0).add(npc);
}
return super.onSpawn(npc);
}

View File

@ -16,11 +16,16 @@
*/
package ai.others;
import java.util.Collection;
import java.util.concurrent.ConcurrentHashMap;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArrayList;
import org.l2jmobius.commons.concurrent.ThreadPool;
import org.l2jmobius.gameserver.ai.CtrlIntention;
import org.l2jmobius.gameserver.geoengine.GeoEngine;
import org.l2jmobius.gameserver.instancemanager.CastleManager;
import org.l2jmobius.gameserver.instancemanager.FortManager;
import org.l2jmobius.gameserver.model.World;
import org.l2jmobius.gameserver.model.WorldObject;
import org.l2jmobius.gameserver.model.actor.Attackable;
@ -87,7 +92,7 @@ public class SiegeGuards extends AbstractNpcAI
35134, 35135, 35136, 35176, 35177, 35178, 35218, 35219, 35220, 35261, 35262, 35263, 35264, 35265, 35308, 35309, 35310, 35352, 35353, 35354, 35497, 35498, 35499, 35500, 35501, 35544, 35545, 35546
};
//@formatter:on
private static final Collection<Npc> SPAWNED_GUARDS = ConcurrentHashMap.newKeySet();
private static final Map<Integer, List<Npc>> RESIDENCE_GUARD_MAP = new HashMap<>();
public SiegeGuards()
{
@ -104,24 +109,55 @@ public class SiegeGuards extends AbstractNpcAI
addKillId(MERCENARIES);
addKillId(STATIONARY_MERCENARIES);
startQuestTimer("AGGRO_CHECK", 3000, null, null, true);
// Start task for unknown residences.
RESIDENCE_GUARD_MAP.put(0, new CopyOnWriteArrayList<>());
ThreadPool.scheduleAtFixedRate(new AggroCheckTask(0), 0, 3000);
// Start tasks for castles.
for (Castle castle : CastleManager.getInstance().getCastles())
{
final int residenceId = castle.getResidenceId();
RESIDENCE_GUARD_MAP.put(residenceId, new CopyOnWriteArrayList<>());
ThreadPool.scheduleAtFixedRate(new AggroCheckTask(residenceId), residenceId * 100, 3000);
}
// Start tasks for fortresses.
for (Fort fort : FortManager.getInstance().getForts())
{
final int residenceId = fort.getResidenceId();
RESIDENCE_GUARD_MAP.put(residenceId, new CopyOnWriteArrayList<>());
ThreadPool.scheduleAtFixedRate(new AggroCheckTask(residenceId), 900 + ((residenceId - 100) * 100), 3000);
}
}
private class AggroCheckTask implements Runnable
{
private final int _residenceId;
public AggroCheckTask(int residenceId)
{
_residenceId = residenceId;
}
@Override
public String onAdvEvent(String event, Npc npc, PlayerInstance player)
public void run()
{
for (Npc guard : SPAWNED_GUARDS)
final List<Npc> guards = RESIDENCE_GUARD_MAP.get(_residenceId);
for (Npc guard : guards)
{
if (guard != null)
if (guard == null)
{
continue;
}
if (guard.isDead())
{
SPAWNED_GUARDS.remove(guard);
guards.remove(guard);
continue;
}
else
{
final WorldObject target = guard.getTarget();
if (!guard.isInCombat() || (target == null) || (guard.calculateDistance2D(target) > guard.getAggroRange()))
if (!guard.isInCombat() || (target == null) || (guard.calculateDistance2D(target) > guard.getAggroRange()) || (target.isPlayer() && target.getActingPlayer().isInvul()))
{
for (Creature nearby : World.getInstance().getVisibleObjectsInRange(guard, Creature.class, guard.getAggroRange()))
{
@ -129,9 +165,20 @@ public class SiegeGuards extends AbstractNpcAI
{
final Summon summon = nearby.isSummon() ? (Summon) nearby : null;
final PlayerInstance pl = summon == null ? (PlayerInstance) nearby : summon.getOwner();
if (((pl.getSiegeState() != 2) || pl.isRegisteredOnThisSiegeField(guard.getScriptValue())) && ((pl.getSiegeState() != 0) || (guard.getAI().getIntention() != CtrlIntention.AI_INTENTION_IDLE)) && (!pl.isInvisible() && !pl.isInvul()))
if (((pl.getSiegeState() != 2) || pl.isRegisteredOnThisSiegeField(guard.getScriptValue())) && ((pl.getSiegeState() != 0) || (guard.getAI().getIntention() != CtrlIntention.AI_INTENTION_IDLE)))
{
addAttackDesire(guard, pl);
// skip invisible players
if (pl.isInvisible() || pl.isInvul())
{
continue;
}
if (guard.isAttackable())
{
((Attackable) guard).addDamageHate(nearby, 0, 999);
}
guard.setRunning();
guard.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, target);
break; // no need to search more
}
}
@ -140,8 +187,6 @@ public class SiegeGuards extends AbstractNpcAI
}
}
}
return super.onAdvEvent(event, npc, player);
}
@Override
public String onAttack(Npc npc, PlayerInstance attacker, int damage, boolean isSummon)
@ -157,22 +202,32 @@ public class SiegeGuards extends AbstractNpcAI
@Override
public String onKill(Npc npc, PlayerInstance killer, boolean isSummon)
{
SPAWNED_GUARDS.remove(npc);
RESIDENCE_GUARD_MAP.get(npc.getScriptValue()).remove(npc);
return super.onKill(npc, killer, isSummon);
}
@Override
public String onSpawn(Npc npc)
{
// npc.setRandomWalking(false);
npc.setRandomWalking(false);
if ((npc.getTemplate().getBaseAttackType() != WeaponType.SWORD) && (npc.getTemplate().getBaseAttackType() != WeaponType.POLE))
{
npc.setImmobilized(true);
}
final Castle castle = npc.getCastle();
final Fort fortress = npc.getFort();
npc.setScriptValue(fortress != null ? fortress.getResidenceId() : (castle != null ? castle.getResidenceId() : 0));
SPAWNED_GUARDS.add(npc);
final int residenceId = fortress != null ? fortress.getResidenceId() : (castle != null ? castle.getResidenceId() : 0);
npc.setScriptValue(residenceId);
if (RESIDENCE_GUARD_MAP.containsKey(residenceId))
{
RESIDENCE_GUARD_MAP.get(residenceId).add(npc);
}
else // Residence id not found.
{
RESIDENCE_GUARD_MAP.get(0).add(npc);
}
return super.onSpawn(npc);
}

View File

@ -16,11 +16,15 @@
*/
package ai.others;
import java.util.Collection;
import java.util.concurrent.ConcurrentHashMap;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArrayList;
import org.l2jmobius.commons.concurrent.ThreadPool;
import org.l2jmobius.gameserver.ai.CtrlIntention;
import org.l2jmobius.gameserver.geoengine.GeoEngine;
import org.l2jmobius.gameserver.instancemanager.CastleManager;
import org.l2jmobius.gameserver.model.World;
import org.l2jmobius.gameserver.model.WorldObject;
import org.l2jmobius.gameserver.model.actor.Attackable;
@ -63,7 +67,7 @@ public class SiegeGuards extends AbstractNpcAI
35134, 35135, 35136, 35176, 35177, 35178, 35218, 35219, 35220, 35261, 35262, 35263, 35264, 35265, 35308, 35309, 35310, 35352, 35353, 35354, 35497, 35498, 35499, 35500, 35501, 35544, 35545, 35546
};
//@formatter:on
private static final Collection<Npc> SPAWNED_GUARDS = ConcurrentHashMap.newKeySet();
private static final Map<Integer, List<Npc>> RESIDENCE_GUARD_MAP = new HashMap<>();
public SiegeGuards()
{
@ -77,22 +81,45 @@ public class SiegeGuards extends AbstractNpcAI
addKillId(MERCENARIES);
addKillId(STATIONARY_MERCENARIES);
startQuestTimer("AGGRO_CHECK", 3000, null, null, true);
// Start task for unknown residences.
RESIDENCE_GUARD_MAP.put(0, new CopyOnWriteArrayList<>());
ThreadPool.scheduleAtFixedRate(new AggroCheckTask(0), 0, 3000);
// Start tasks for castles.
for (Castle castle : CastleManager.getInstance().getCastles())
{
final int residenceId = castle.getResidenceId();
RESIDENCE_GUARD_MAP.put(residenceId, new CopyOnWriteArrayList<>());
ThreadPool.scheduleAtFixedRate(new AggroCheckTask(residenceId), residenceId * 100, 3000);
}
}
private class AggroCheckTask implements Runnable
{
private final int _residenceId;
public AggroCheckTask(int residenceId)
{
_residenceId = residenceId;
}
@Override
public String onAdvEvent(String event, Npc npc, PlayerInstance player)
public void run()
{
for (Npc guard : SPAWNED_GUARDS)
final List<Npc> guards = RESIDENCE_GUARD_MAP.get(_residenceId);
for (Npc guard : guards)
{
if (guard != null)
if (guard == null)
{
continue;
}
if (guard.isDead())
{
SPAWNED_GUARDS.remove(guard);
guards.remove(guard);
continue;
}
else
{
final WorldObject target = guard.getTarget();
if (!guard.isInCombat() || (target == null) || (guard.calculateDistance2D(target) > guard.getAggroRange()) || target.isInvul())
{
@ -104,9 +131,18 @@ public class SiegeGuards extends AbstractNpcAI
final PlayerInstance pl = summon == null ? (PlayerInstance) nearby : summon.getOwner();
if (((pl.getSiegeState() != 2) || pl.isRegisteredOnThisSiegeField(guard.getScriptValue())) && ((pl.getSiegeState() != 0) || (guard.getAI().getIntention() != CtrlIntention.AI_INTENTION_IDLE)))
{
if (!pl.isInvisible() && !pl.isInvul()) // skip invisible players
// skip invisible players
if (pl.isInvisible() || pl.isInvul())
{
addAttackPlayerDesire(guard, pl);
continue;
}
if (guard.isAttackable())
{
((Attackable) guard).addDamageHate(nearby, 0, 999);
}
guard.setRunning();
guard.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, target);
break; // no need to search more
}
}
@ -115,9 +151,6 @@ public class SiegeGuards extends AbstractNpcAI
}
}
}
}
return super.onAdvEvent(event, npc, player);
}
@Override
public String onAttack(Npc npc, PlayerInstance attacker, int damage, boolean isSummon)
@ -133,7 +166,7 @@ public class SiegeGuards extends AbstractNpcAI
@Override
public String onKill(Npc npc, PlayerInstance killer, boolean isSummon)
{
SPAWNED_GUARDS.remove(npc);
RESIDENCE_GUARD_MAP.get(npc.getScriptValue()).remove(npc);
return super.onKill(npc, killer, isSummon);
}
@ -145,10 +178,20 @@ public class SiegeGuards extends AbstractNpcAI
{
npc.setImmobilized(true);
}
final Castle castle = npc.getCastle();
final Fort fortress = npc.getFort();
npc.setScriptValue(fortress != null ? fortress.getResidenceId() : (castle != null ? castle.getResidenceId() : 0));
SPAWNED_GUARDS.add(npc);
final int residenceId = fortress != null ? fortress.getResidenceId() : (castle != null ? castle.getResidenceId() : 0);
npc.setScriptValue(residenceId);
if (RESIDENCE_GUARD_MAP.containsKey(residenceId))
{
RESIDENCE_GUARD_MAP.get(residenceId).add(npc);
}
else // Residence id not found.
{
RESIDENCE_GUARD_MAP.get(0).add(npc);
}
return super.onSpawn(npc);
}

View File

@ -16,11 +16,15 @@
*/
package ai.others;
import java.util.Collection;
import java.util.concurrent.ConcurrentHashMap;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArrayList;
import org.l2jmobius.commons.concurrent.ThreadPool;
import org.l2jmobius.gameserver.ai.CtrlIntention;
import org.l2jmobius.gameserver.geoengine.GeoEngine;
import org.l2jmobius.gameserver.instancemanager.CastleManager;
import org.l2jmobius.gameserver.model.World;
import org.l2jmobius.gameserver.model.WorldObject;
import org.l2jmobius.gameserver.model.actor.Attackable;
@ -63,7 +67,7 @@ public class SiegeGuards extends AbstractNpcAI
35134, 35135, 35136, 35176, 35177, 35178, 35218, 35219, 35220, 35261, 35262, 35263, 35264, 35265, 35308, 35309, 35310, 35352, 35353, 35354, 35497, 35498, 35499, 35500, 35501, 35544, 35545, 35546
};
//@formatter:on
private static final Collection<Npc> SPAWNED_GUARDS = ConcurrentHashMap.newKeySet();
private static final Map<Integer, List<Npc>> RESIDENCE_GUARD_MAP = new HashMap<>();
public SiegeGuards()
{
@ -77,22 +81,45 @@ public class SiegeGuards extends AbstractNpcAI
addKillId(MERCENARIES);
addKillId(STATIONARY_MERCENARIES);
startQuestTimer("AGGRO_CHECK", 3000, null, null, true);
// Start task for unknown residences.
RESIDENCE_GUARD_MAP.put(0, new CopyOnWriteArrayList<>());
ThreadPool.scheduleAtFixedRate(new AggroCheckTask(0), 0, 3000);
// Start tasks for castles.
for (Castle castle : CastleManager.getInstance().getCastles())
{
final int residenceId = castle.getResidenceId();
RESIDENCE_GUARD_MAP.put(residenceId, new CopyOnWriteArrayList<>());
ThreadPool.scheduleAtFixedRate(new AggroCheckTask(residenceId), residenceId * 100, 3000);
}
}
private class AggroCheckTask implements Runnable
{
private final int _residenceId;
public AggroCheckTask(int residenceId)
{
_residenceId = residenceId;
}
@Override
public String onAdvEvent(String event, Npc npc, PlayerInstance player)
public void run()
{
for (Npc guard : SPAWNED_GUARDS)
final List<Npc> guards = RESIDENCE_GUARD_MAP.get(_residenceId);
for (Npc guard : guards)
{
if (guard != null)
if (guard == null)
{
continue;
}
if (guard.isDead())
{
SPAWNED_GUARDS.remove(guard);
guards.remove(guard);
continue;
}
else
{
final WorldObject target = guard.getTarget();
if (!guard.isInCombat() || (target == null) || (guard.calculateDistance2D(target) > guard.getAggroRange()) || target.isInvul())
{
@ -104,9 +131,18 @@ public class SiegeGuards extends AbstractNpcAI
final PlayerInstance pl = summon == null ? (PlayerInstance) nearby : summon.getOwner();
if (((pl.getSiegeState() != 2) || pl.isRegisteredOnThisSiegeField(guard.getScriptValue())) && ((pl.getSiegeState() != 0) || (guard.getAI().getIntention() != CtrlIntention.AI_INTENTION_IDLE)))
{
if (!pl.isInvisible() && !pl.isInvul()) // skip invisible players
// skip invisible players
if (pl.isInvisible() || pl.isInvul())
{
addAttackPlayerDesire(guard, pl);
continue;
}
if (guard.isAttackable())
{
((Attackable) guard).addDamageHate(nearby, 0, 999);
}
guard.setRunning();
guard.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, target);
break; // no need to search more
}
}
@ -115,9 +151,6 @@ public class SiegeGuards extends AbstractNpcAI
}
}
}
}
return super.onAdvEvent(event, npc, player);
}
@Override
public String onAttack(Npc npc, PlayerInstance attacker, int damage, boolean isSummon)
@ -133,7 +166,7 @@ public class SiegeGuards extends AbstractNpcAI
@Override
public String onKill(Npc npc, PlayerInstance killer, boolean isSummon)
{
SPAWNED_GUARDS.remove(npc);
RESIDENCE_GUARD_MAP.get(npc.getScriptValue()).remove(npc);
return super.onKill(npc, killer, isSummon);
}
@ -145,10 +178,20 @@ public class SiegeGuards extends AbstractNpcAI
{
npc.setImmobilized(true);
}
final Castle castle = npc.getCastle();
final Fort fortress = npc.getFort();
npc.setScriptValue(fortress != null ? fortress.getResidenceId() : (castle != null ? castle.getResidenceId() : 0));
SPAWNED_GUARDS.add(npc);
final int residenceId = fortress != null ? fortress.getResidenceId() : (castle != null ? castle.getResidenceId() : 0);
npc.setScriptValue(residenceId);
if (RESIDENCE_GUARD_MAP.containsKey(residenceId))
{
RESIDENCE_GUARD_MAP.get(residenceId).add(npc);
}
else // Residence id not found.
{
RESIDENCE_GUARD_MAP.get(0).add(npc);
}
return super.onSpawn(npc);
}

View File

@ -16,11 +16,15 @@
*/
package ai.others;
import java.util.Collection;
import java.util.concurrent.ConcurrentHashMap;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArrayList;
import org.l2jmobius.commons.concurrent.ThreadPool;
import org.l2jmobius.gameserver.ai.CtrlIntention;
import org.l2jmobius.gameserver.geoengine.GeoEngine;
import org.l2jmobius.gameserver.instancemanager.CastleManager;
import org.l2jmobius.gameserver.model.World;
import org.l2jmobius.gameserver.model.WorldObject;
import org.l2jmobius.gameserver.model.actor.Attackable;
@ -63,7 +67,7 @@ public class SiegeGuards extends AbstractNpcAI
35134, 35135, 35136, 35176, 35177, 35178, 35218, 35219, 35220, 35261, 35262, 35263, 35264, 35265, 35308, 35309, 35310, 35352, 35353, 35354, 35497, 35498, 35499, 35500, 35501, 35544, 35545, 35546
};
//@formatter:on
private static final Collection<Npc> SPAWNED_GUARDS = ConcurrentHashMap.newKeySet();
private static final Map<Integer, List<Npc>> RESIDENCE_GUARD_MAP = new HashMap<>();
public SiegeGuards()
{
@ -77,22 +81,45 @@ public class SiegeGuards extends AbstractNpcAI
addKillId(MERCENARIES);
addKillId(STATIONARY_MERCENARIES);
startQuestTimer("AGGRO_CHECK", 3000, null, null, true);
// Start task for unknown residences.
RESIDENCE_GUARD_MAP.put(0, new CopyOnWriteArrayList<>());
ThreadPool.scheduleAtFixedRate(new AggroCheckTask(0), 0, 3000);
// Start tasks for castles.
for (Castle castle : CastleManager.getInstance().getCastles())
{
final int residenceId = castle.getResidenceId();
RESIDENCE_GUARD_MAP.put(residenceId, new CopyOnWriteArrayList<>());
ThreadPool.scheduleAtFixedRate(new AggroCheckTask(residenceId), residenceId * 100, 3000);
}
}
private class AggroCheckTask implements Runnable
{
private final int _residenceId;
public AggroCheckTask(int residenceId)
{
_residenceId = residenceId;
}
@Override
public String onAdvEvent(String event, Npc npc, PlayerInstance player)
public void run()
{
for (Npc guard : SPAWNED_GUARDS)
final List<Npc> guards = RESIDENCE_GUARD_MAP.get(_residenceId);
for (Npc guard : guards)
{
if (guard != null)
if (guard == null)
{
continue;
}
if (guard.isDead())
{
SPAWNED_GUARDS.remove(guard);
guards.remove(guard);
continue;
}
else
{
final WorldObject target = guard.getTarget();
if (!guard.isInCombat() || (target == null) || (guard.calculateDistance2D(target) > guard.getAggroRange()) || target.isInvul())
{
@ -104,9 +131,18 @@ public class SiegeGuards extends AbstractNpcAI
final PlayerInstance pl = summon == null ? (PlayerInstance) nearby : summon.getOwner();
if (((pl.getSiegeState() != 2) || pl.isRegisteredOnThisSiegeField(guard.getScriptValue())) && ((pl.getSiegeState() != 0) || (guard.getAI().getIntention() != CtrlIntention.AI_INTENTION_IDLE)))
{
if (!pl.isInvisible() && !pl.isInvul()) // skip invisible players
// skip invisible players
if (pl.isInvisible() || pl.isInvul())
{
addAttackPlayerDesire(guard, pl);
continue;
}
if (guard.isAttackable())
{
((Attackable) guard).addDamageHate(nearby, 0, 999);
}
guard.setRunning();
guard.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, target);
break; // no need to search more
}
}
@ -115,9 +151,6 @@ public class SiegeGuards extends AbstractNpcAI
}
}
}
}
return super.onAdvEvent(event, npc, player);
}
@Override
public String onAttack(Npc npc, PlayerInstance attacker, int damage, boolean isSummon)
@ -133,7 +166,7 @@ public class SiegeGuards extends AbstractNpcAI
@Override
public String onKill(Npc npc, PlayerInstance killer, boolean isSummon)
{
SPAWNED_GUARDS.remove(npc);
RESIDENCE_GUARD_MAP.get(npc.getScriptValue()).remove(npc);
return super.onKill(npc, killer, isSummon);
}
@ -145,10 +178,20 @@ public class SiegeGuards extends AbstractNpcAI
{
npc.setImmobilized(true);
}
final Castle castle = npc.getCastle();
final Fort fortress = npc.getFort();
npc.setScriptValue(fortress != null ? fortress.getResidenceId() : (castle != null ? castle.getResidenceId() : 0));
SPAWNED_GUARDS.add(npc);
final int residenceId = fortress != null ? fortress.getResidenceId() : (castle != null ? castle.getResidenceId() : 0);
npc.setScriptValue(residenceId);
if (RESIDENCE_GUARD_MAP.containsKey(residenceId))
{
RESIDENCE_GUARD_MAP.get(residenceId).add(npc);
}
else // Residence id not found.
{
RESIDENCE_GUARD_MAP.get(0).add(npc);
}
return super.onSpawn(npc);
}

View File

@ -16,11 +16,15 @@
*/
package ai.others;
import java.util.Collection;
import java.util.concurrent.ConcurrentHashMap;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArrayList;
import org.l2jmobius.commons.concurrent.ThreadPool;
import org.l2jmobius.gameserver.ai.CtrlIntention;
import org.l2jmobius.gameserver.geoengine.GeoEngine;
import org.l2jmobius.gameserver.instancemanager.CastleManager;
import org.l2jmobius.gameserver.model.World;
import org.l2jmobius.gameserver.model.WorldObject;
import org.l2jmobius.gameserver.model.actor.Attackable;
@ -63,7 +67,7 @@ public class SiegeGuards extends AbstractNpcAI
35134, 35135, 35136, 35176, 35177, 35178, 35218, 35219, 35220, 35261, 35262, 35263, 35264, 35265, 35308, 35309, 35310, 35352, 35353, 35354, 35497, 35498, 35499, 35500, 35501, 35544, 35545, 35546
};
//@formatter:on
private static final Collection<Npc> SPAWNED_GUARDS = ConcurrentHashMap.newKeySet();
private static final Map<Integer, List<Npc>> RESIDENCE_GUARD_MAP = new HashMap<>();
public SiegeGuards()
{
@ -77,22 +81,45 @@ public class SiegeGuards extends AbstractNpcAI
addKillId(MERCENARIES);
addKillId(STATIONARY_MERCENARIES);
startQuestTimer("AGGRO_CHECK", 3000, null, null, true);
// Start task for unknown residences.
RESIDENCE_GUARD_MAP.put(0, new CopyOnWriteArrayList<>());
ThreadPool.scheduleAtFixedRate(new AggroCheckTask(0), 0, 3000);
// Start tasks for castles.
for (Castle castle : CastleManager.getInstance().getCastles())
{
final int residenceId = castle.getResidenceId();
RESIDENCE_GUARD_MAP.put(residenceId, new CopyOnWriteArrayList<>());
ThreadPool.scheduleAtFixedRate(new AggroCheckTask(residenceId), residenceId * 100, 3000);
}
}
private class AggroCheckTask implements Runnable
{
private final int _residenceId;
public AggroCheckTask(int residenceId)
{
_residenceId = residenceId;
}
@Override
public String onAdvEvent(String event, Npc npc, PlayerInstance player)
public void run()
{
for (Npc guard : SPAWNED_GUARDS)
final List<Npc> guards = RESIDENCE_GUARD_MAP.get(_residenceId);
for (Npc guard : guards)
{
if (guard != null)
if (guard == null)
{
continue;
}
if (guard.isDead())
{
SPAWNED_GUARDS.remove(guard);
guards.remove(guard);
continue;
}
else
{
final WorldObject target = guard.getTarget();
if (!guard.isInCombat() || (target == null) || (guard.calculateDistance2D(target) > guard.getAggroRange()) || target.isInvul())
{
@ -104,9 +131,18 @@ public class SiegeGuards extends AbstractNpcAI
final PlayerInstance pl = summon == null ? (PlayerInstance) nearby : summon.getOwner();
if (((pl.getSiegeState() != 2) || pl.isRegisteredOnThisSiegeField(guard.getScriptValue())) && ((pl.getSiegeState() != 0) || (guard.getAI().getIntention() != CtrlIntention.AI_INTENTION_IDLE)))
{
if (!pl.isInvisible() && !pl.isInvul()) // skip invisible players
// skip invisible players
if (pl.isInvisible() || pl.isInvul())
{
addAttackPlayerDesire(guard, pl);
continue;
}
if (guard.isAttackable())
{
((Attackable) guard).addDamageHate(nearby, 0, 999);
}
guard.setRunning();
guard.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, target);
break; // no need to search more
}
}
@ -115,9 +151,6 @@ public class SiegeGuards extends AbstractNpcAI
}
}
}
}
return super.onAdvEvent(event, npc, player);
}
@Override
public String onAttack(Npc npc, PlayerInstance attacker, int damage, boolean isSummon)
@ -133,7 +166,7 @@ public class SiegeGuards extends AbstractNpcAI
@Override
public String onKill(Npc npc, PlayerInstance killer, boolean isSummon)
{
SPAWNED_GUARDS.remove(npc);
RESIDENCE_GUARD_MAP.get(npc.getScriptValue()).remove(npc);
return super.onKill(npc, killer, isSummon);
}
@ -145,10 +178,20 @@ public class SiegeGuards extends AbstractNpcAI
{
npc.setImmobilized(true);
}
final Castle castle = npc.getCastle();
final Fort fortress = npc.getFort();
npc.setScriptValue(fortress != null ? fortress.getResidenceId() : (castle != null ? castle.getResidenceId() : 0));
SPAWNED_GUARDS.add(npc);
final int residenceId = fortress != null ? fortress.getResidenceId() : (castle != null ? castle.getResidenceId() : 0);
npc.setScriptValue(residenceId);
if (RESIDENCE_GUARD_MAP.containsKey(residenceId))
{
RESIDENCE_GUARD_MAP.get(residenceId).add(npc);
}
else // Residence id not found.
{
RESIDENCE_GUARD_MAP.get(0).add(npc);
}
return super.onSpawn(npc);
}

View File

@ -16,11 +16,15 @@
*/
package ai.others;
import java.util.Collection;
import java.util.concurrent.ConcurrentHashMap;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArrayList;
import org.l2jmobius.commons.concurrent.ThreadPool;
import org.l2jmobius.gameserver.ai.CtrlIntention;
import org.l2jmobius.gameserver.geoengine.GeoEngine;
import org.l2jmobius.gameserver.instancemanager.CastleManager;
import org.l2jmobius.gameserver.model.World;
import org.l2jmobius.gameserver.model.WorldObject;
import org.l2jmobius.gameserver.model.actor.Attackable;
@ -63,7 +67,7 @@ public class SiegeGuards extends AbstractNpcAI
35134, 35135, 35136, 35176, 35177, 35178, 35218, 35219, 35220, 35261, 35262, 35263, 35264, 35265, 35308, 35309, 35310, 35352, 35353, 35354, 35497, 35498, 35499, 35500, 35501, 35544, 35545, 35546
};
//@formatter:on
private static final Collection<Npc> SPAWNED_GUARDS = ConcurrentHashMap.newKeySet();
private static final Map<Integer, List<Npc>> RESIDENCE_GUARD_MAP = new HashMap<>();
public SiegeGuards()
{
@ -77,22 +81,45 @@ public class SiegeGuards extends AbstractNpcAI
addKillId(MERCENARIES);
addKillId(STATIONARY_MERCENARIES);
startQuestTimer("AGGRO_CHECK", 3000, null, null, true);
// Start task for unknown residences.
RESIDENCE_GUARD_MAP.put(0, new CopyOnWriteArrayList<>());
ThreadPool.scheduleAtFixedRate(new AggroCheckTask(0), 0, 3000);
// Start tasks for castles.
for (Castle castle : CastleManager.getInstance().getCastles())
{
final int residenceId = castle.getResidenceId();
RESIDENCE_GUARD_MAP.put(residenceId, new CopyOnWriteArrayList<>());
ThreadPool.scheduleAtFixedRate(new AggroCheckTask(residenceId), residenceId * 100, 3000);
}
}
private class AggroCheckTask implements Runnable
{
private final int _residenceId;
public AggroCheckTask(int residenceId)
{
_residenceId = residenceId;
}
@Override
public String onAdvEvent(String event, Npc npc, PlayerInstance player)
public void run()
{
for (Npc guard : SPAWNED_GUARDS)
final List<Npc> guards = RESIDENCE_GUARD_MAP.get(_residenceId);
for (Npc guard : guards)
{
if (guard != null)
if (guard == null)
{
continue;
}
if (guard.isDead())
{
SPAWNED_GUARDS.remove(guard);
guards.remove(guard);
continue;
}
else
{
final WorldObject target = guard.getTarget();
if (!guard.isInCombat() || (target == null) || (guard.calculateDistance2D(target) > guard.getAggroRange()) || target.isInvul())
{
@ -104,9 +131,18 @@ public class SiegeGuards extends AbstractNpcAI
final PlayerInstance pl = summon == null ? (PlayerInstance) nearby : summon.getOwner();
if (((pl.getSiegeState() != 2) || pl.isRegisteredOnThisSiegeField(guard.getScriptValue())) && ((pl.getSiegeState() != 0) || (guard.getAI().getIntention() != CtrlIntention.AI_INTENTION_IDLE)))
{
if (!pl.isInvisible() && !pl.isInvul()) // skip invisible players
// skip invisible players
if (pl.isInvisible() || pl.isInvul())
{
addAttackPlayerDesire(guard, pl);
continue;
}
if (guard.isAttackable())
{
((Attackable) guard).addDamageHate(nearby, 0, 999);
}
guard.setRunning();
guard.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, target);
break; // no need to search more
}
}
@ -115,9 +151,6 @@ public class SiegeGuards extends AbstractNpcAI
}
}
}
}
return super.onAdvEvent(event, npc, player);
}
@Override
public String onAttack(Npc npc, PlayerInstance attacker, int damage, boolean isSummon)
@ -133,7 +166,7 @@ public class SiegeGuards extends AbstractNpcAI
@Override
public String onKill(Npc npc, PlayerInstance killer, boolean isSummon)
{
SPAWNED_GUARDS.remove(npc);
RESIDENCE_GUARD_MAP.get(npc.getScriptValue()).remove(npc);
return super.onKill(npc, killer, isSummon);
}
@ -145,10 +178,20 @@ public class SiegeGuards extends AbstractNpcAI
{
npc.setImmobilized(true);
}
final Castle castle = npc.getCastle();
final Fort fortress = npc.getFort();
npc.setScriptValue(fortress != null ? fortress.getResidenceId() : (castle != null ? castle.getResidenceId() : 0));
SPAWNED_GUARDS.add(npc);
final int residenceId = fortress != null ? fortress.getResidenceId() : (castle != null ? castle.getResidenceId() : 0);
npc.setScriptValue(residenceId);
if (RESIDENCE_GUARD_MAP.containsKey(residenceId))
{
RESIDENCE_GUARD_MAP.get(residenceId).add(npc);
}
else // Residence id not found.
{
RESIDENCE_GUARD_MAP.get(0).add(npc);
}
return super.onSpawn(npc);
}

View File

@ -16,11 +16,15 @@
*/
package ai.others;
import java.util.Collection;
import java.util.concurrent.ConcurrentHashMap;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArrayList;
import org.l2jmobius.commons.concurrent.ThreadPool;
import org.l2jmobius.gameserver.ai.CtrlIntention;
import org.l2jmobius.gameserver.geoengine.GeoEngine;
import org.l2jmobius.gameserver.instancemanager.CastleManager;
import org.l2jmobius.gameserver.model.World;
import org.l2jmobius.gameserver.model.WorldObject;
import org.l2jmobius.gameserver.model.actor.Attackable;
@ -63,7 +67,7 @@ public class SiegeGuards extends AbstractNpcAI
35134, 35135, 35136, 35176, 35177, 35178, 35218, 35219, 35220, 35261, 35262, 35263, 35264, 35265, 35308, 35309, 35310, 35352, 35353, 35354, 35497, 35498, 35499, 35500, 35501, 35544, 35545, 35546
};
//@formatter:on
private static final Collection<Npc> SPAWNED_GUARDS = ConcurrentHashMap.newKeySet();
private static final Map<Integer, List<Npc>> RESIDENCE_GUARD_MAP = new HashMap<>();
public SiegeGuards()
{
@ -77,22 +81,45 @@ public class SiegeGuards extends AbstractNpcAI
addKillId(MERCENARIES);
addKillId(STATIONARY_MERCENARIES);
startQuestTimer("AGGRO_CHECK", 3000, null, null, true);
// Start task for unknown residences.
RESIDENCE_GUARD_MAP.put(0, new CopyOnWriteArrayList<>());
ThreadPool.scheduleAtFixedRate(new AggroCheckTask(0), 0, 3000);
// Start tasks for castles.
for (Castle castle : CastleManager.getInstance().getCastles())
{
final int residenceId = castle.getResidenceId();
RESIDENCE_GUARD_MAP.put(residenceId, new CopyOnWriteArrayList<>());
ThreadPool.scheduleAtFixedRate(new AggroCheckTask(residenceId), residenceId * 100, 3000);
}
}
private class AggroCheckTask implements Runnable
{
private final int _residenceId;
public AggroCheckTask(int residenceId)
{
_residenceId = residenceId;
}
@Override
public String onAdvEvent(String event, Npc npc, PlayerInstance player)
public void run()
{
for (Npc guard : SPAWNED_GUARDS)
final List<Npc> guards = RESIDENCE_GUARD_MAP.get(_residenceId);
for (Npc guard : guards)
{
if (guard != null)
if (guard == null)
{
continue;
}
if (guard.isDead())
{
SPAWNED_GUARDS.remove(guard);
guards.remove(guard);
continue;
}
else
{
final WorldObject target = guard.getTarget();
if (!guard.isInCombat() || (target == null) || (guard.calculateDistance2D(target) > guard.getAggroRange()) || target.isInvul())
{
@ -104,9 +131,18 @@ public class SiegeGuards extends AbstractNpcAI
final PlayerInstance pl = summon == null ? (PlayerInstance) nearby : summon.getOwner();
if (((pl.getSiegeState() != 2) || pl.isRegisteredOnThisSiegeField(guard.getScriptValue())) && ((pl.getSiegeState() != 0) || (guard.getAI().getIntention() != CtrlIntention.AI_INTENTION_IDLE)))
{
if (!pl.isInvisible() && !pl.isInvul()) // skip invisible players
// skip invisible players
if (pl.isInvisible() || pl.isInvul())
{
addAttackPlayerDesire(guard, pl);
continue;
}
if (guard.isAttackable())
{
((Attackable) guard).addDamageHate(nearby, 0, 999);
}
guard.setRunning();
guard.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, target);
break; // no need to search more
}
}
@ -115,9 +151,6 @@ public class SiegeGuards extends AbstractNpcAI
}
}
}
}
return super.onAdvEvent(event, npc, player);
}
@Override
public String onAttack(Npc npc, PlayerInstance attacker, int damage, boolean isSummon)
@ -133,7 +166,7 @@ public class SiegeGuards extends AbstractNpcAI
@Override
public String onKill(Npc npc, PlayerInstance killer, boolean isSummon)
{
SPAWNED_GUARDS.remove(npc);
RESIDENCE_GUARD_MAP.get(npc.getScriptValue()).remove(npc);
return super.onKill(npc, killer, isSummon);
}
@ -145,10 +178,20 @@ public class SiegeGuards extends AbstractNpcAI
{
npc.setImmobilized(true);
}
final Castle castle = npc.getCastle();
final Fort fortress = npc.getFort();
npc.setScriptValue(fortress != null ? fortress.getResidenceId() : (castle != null ? castle.getResidenceId() : 0));
SPAWNED_GUARDS.add(npc);
final int residenceId = fortress != null ? fortress.getResidenceId() : (castle != null ? castle.getResidenceId() : 0);
npc.setScriptValue(residenceId);
if (RESIDENCE_GUARD_MAP.containsKey(residenceId))
{
RESIDENCE_GUARD_MAP.get(residenceId).add(npc);
}
else // Residence id not found.
{
RESIDENCE_GUARD_MAP.get(0).add(npc);
}
return super.onSpawn(npc);
}

View File

@ -16,11 +16,15 @@
*/
package ai.others;
import java.util.Collection;
import java.util.concurrent.ConcurrentHashMap;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArrayList;
import org.l2jmobius.commons.concurrent.ThreadPool;
import org.l2jmobius.gameserver.ai.CtrlIntention;
import org.l2jmobius.gameserver.geoengine.GeoEngine;
import org.l2jmobius.gameserver.instancemanager.CastleManager;
import org.l2jmobius.gameserver.model.World;
import org.l2jmobius.gameserver.model.WorldObject;
import org.l2jmobius.gameserver.model.actor.Attackable;
@ -63,7 +67,7 @@ public class SiegeGuards extends AbstractNpcAI
35134, 35135, 35136, 35176, 35177, 35178, 35218, 35219, 35220, 35261, 35262, 35263, 35264, 35265, 35308, 35309, 35310, 35352, 35353, 35354, 35497, 35498, 35499, 35500, 35501, 35544, 35545, 35546
};
//@formatter:on
private static final Collection<Npc> SPAWNED_GUARDS = ConcurrentHashMap.newKeySet();
private static final Map<Integer, List<Npc>> RESIDENCE_GUARD_MAP = new HashMap<>();
public SiegeGuards()
{
@ -77,22 +81,45 @@ public class SiegeGuards extends AbstractNpcAI
addKillId(MERCENARIES);
addKillId(STATIONARY_MERCENARIES);
startQuestTimer("AGGRO_CHECK", 3000, null, null, true);
// Start task for unknown residences.
RESIDENCE_GUARD_MAP.put(0, new CopyOnWriteArrayList<>());
ThreadPool.scheduleAtFixedRate(new AggroCheckTask(0), 0, 3000);
// Start tasks for castles.
for (Castle castle : CastleManager.getInstance().getCastles())
{
final int residenceId = castle.getResidenceId();
RESIDENCE_GUARD_MAP.put(residenceId, new CopyOnWriteArrayList<>());
ThreadPool.scheduleAtFixedRate(new AggroCheckTask(residenceId), residenceId * 100, 3000);
}
}
private class AggroCheckTask implements Runnable
{
private final int _residenceId;
public AggroCheckTask(int residenceId)
{
_residenceId = residenceId;
}
@Override
public String onAdvEvent(String event, Npc npc, PlayerInstance player)
public void run()
{
for (Npc guard : SPAWNED_GUARDS)
final List<Npc> guards = RESIDENCE_GUARD_MAP.get(_residenceId);
for (Npc guard : guards)
{
if (guard != null)
if (guard == null)
{
continue;
}
if (guard.isDead())
{
SPAWNED_GUARDS.remove(guard);
guards.remove(guard);
continue;
}
else
{
final WorldObject target = guard.getTarget();
if (!guard.isInCombat() || (target == null) || (guard.calculateDistance2D(target) > guard.getAggroRange()) || target.isInvul())
{
@ -104,9 +131,18 @@ public class SiegeGuards extends AbstractNpcAI
final PlayerInstance pl = summon == null ? (PlayerInstance) nearby : summon.getOwner();
if (((pl.getSiegeState() != 2) || pl.isRegisteredOnThisSiegeField(guard.getScriptValue())) && ((pl.getSiegeState() != 0) || (guard.getAI().getIntention() != CtrlIntention.AI_INTENTION_IDLE)))
{
if (!pl.isInvisible() && !pl.isInvul()) // skip invisible players
// skip invisible players
if (pl.isInvisible() || pl.isInvul())
{
addAttackPlayerDesire(guard, pl);
continue;
}
if (guard.isAttackable())
{
((Attackable) guard).addDamageHate(nearby, 0, 999);
}
guard.setRunning();
guard.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, target);
break; // no need to search more
}
}
@ -115,9 +151,6 @@ public class SiegeGuards extends AbstractNpcAI
}
}
}
}
return super.onAdvEvent(event, npc, player);
}
@Override
public String onAttack(Npc npc, PlayerInstance attacker, int damage, boolean isSummon)
@ -133,7 +166,7 @@ public class SiegeGuards extends AbstractNpcAI
@Override
public String onKill(Npc npc, PlayerInstance killer, boolean isSummon)
{
SPAWNED_GUARDS.remove(npc);
RESIDENCE_GUARD_MAP.get(npc.getScriptValue()).remove(npc);
return super.onKill(npc, killer, isSummon);
}
@ -145,10 +178,20 @@ public class SiegeGuards extends AbstractNpcAI
{
npc.setImmobilized(true);
}
final Castle castle = npc.getCastle();
final Fort fortress = npc.getFort();
npc.setScriptValue(fortress != null ? fortress.getResidenceId() : (castle != null ? castle.getResidenceId() : 0));
SPAWNED_GUARDS.add(npc);
final int residenceId = fortress != null ? fortress.getResidenceId() : (castle != null ? castle.getResidenceId() : 0);
npc.setScriptValue(residenceId);
if (RESIDENCE_GUARD_MAP.containsKey(residenceId))
{
RESIDENCE_GUARD_MAP.get(residenceId).add(npc);
}
else // Residence id not found.
{
RESIDENCE_GUARD_MAP.get(0).add(npc);
}
return super.onSpawn(npc);
}