From e11a5bb9163b5f2ea024f883c2f48f369fe86445 Mon Sep 17 00:00:00 2001 From: MobiusDevelopment <8391001+MobiusDevelopment@users.noreply.github.com> Date: Fri, 3 Jul 2020 22:49:50 +0000 Subject: [PATCH] Fixed and improved and SiegeGuard related behaviors. Contributed by Sahar. --- .../data/scripts/ai/others/SiegeGuards.java | 61 +++++++++++-------- .../l2jmobius/gameserver/ai/AttackableAI.java | 7 +-- .../actor/instance/DefenderInstance.java | 4 +- .../data/scripts/ai/others/SiegeGuards.java | 61 +++++++++++-------- .../l2jmobius/gameserver/ai/AttackableAI.java | 7 +-- .../actor/instance/DefenderInstance.java | 4 +- .../data/scripts/ai/others/SiegeGuards.java | 61 +++++++++++-------- .../l2jmobius/gameserver/ai/AttackableAI.java | 7 +-- .../actor/instance/DefenderInstance.java | 4 +- .../data/scripts/ai/others/SiegeGuards.java | 61 +++++++++++-------- .../l2jmobius/gameserver/ai/AttackableAI.java | 7 +-- .../actor/instance/DefenderInstance.java | 4 +- .../data/scripts/ai/others/SiegeGuards.java | 61 +++++++++++-------- .../l2jmobius/gameserver/ai/AttackableAI.java | 7 +-- .../actor/instance/DefenderInstance.java | 4 +- .../data/scripts/ai/others/SiegeGuards.java | 61 +++++++++++-------- .../l2jmobius/gameserver/ai/AttackableAI.java | 7 +-- .../actor/instance/DefenderInstance.java | 4 +- .../data/scripts/ai/others/SiegeGuards.java | 61 +++++++++++-------- .../l2jmobius/gameserver/ai/AttackableAI.java | 7 +-- .../actor/instance/DefenderInstance.java | 4 +- .../data/scripts/ai/others/SiegeGuards.java | 61 +++++++++++-------- .../l2jmobius/gameserver/ai/AttackableAI.java | 7 +-- .../actor/instance/DefenderInstance.java | 4 +- .../data/scripts/ai/others/SiegeGuards.java | 61 +++++++++++-------- .../l2jmobius/gameserver/ai/AttackableAI.java | 6 +- .../actor/instance/DefenderInstance.java | 4 +- .../data/scripts/ai/others/SiegeGuards.java | 61 +++++++++++-------- .../l2jmobius/gameserver/ai/AttackableAI.java | 6 +- .../actor/instance/DefenderInstance.java | 4 +- .../data/scripts/ai/others/SiegeGuards.java | 61 +++++++++++-------- .../l2jmobius/gameserver/ai/AttackableAI.java | 7 +-- .../actor/instance/DefenderInstance.java | 4 +- .../data/scripts/ai/others/SiegeGuards.java | 61 +++++++++++-------- .../l2jmobius/gameserver/ai/AttackableAI.java | 7 +-- .../actor/instance/DefenderInstance.java | 4 +- .../data/scripts/ai/others/SiegeGuards.java | 61 +++++++++++-------- .../l2jmobius/gameserver/ai/AttackableAI.java | 7 +-- .../actor/instance/DefenderInstance.java | 4 +- .../data/scripts/ai/others/SiegeGuards.java | 61 +++++++++++-------- .../l2jmobius/gameserver/ai/AttackableAI.java | 7 +-- .../actor/instance/DefenderInstance.java | 4 +- .../data/scripts/ai/others/SiegeGuards.java | 61 +++++++++++-------- .../l2jmobius/gameserver/ai/AttackableAI.java | 7 +-- .../actor/instance/DefenderInstance.java | 4 +- .../data/scripts/ai/others/SiegeGuards.java | 61 +++++++++++-------- .../l2jmobius/gameserver/ai/AttackableAI.java | 7 +-- .../actor/instance/DefenderInstance.java | 4 +- .../data/scripts/ai/others/SiegeGuards.java | 61 +++++++++++-------- .../l2jmobius/gameserver/ai/AttackableAI.java | 7 +-- .../actor/instance/DefenderInstance.java | 4 +- 51 files changed, 680 insertions(+), 542 deletions(-) diff --git a/L2J_Mobius_1.0_Ertheia/dist/game/data/scripts/ai/others/SiegeGuards.java b/L2J_Mobius_1.0_Ertheia/dist/game/data/scripts/ai/others/SiegeGuards.java index 880eeef21a..174255624f 100644 --- a/L2J_Mobius_1.0_Ertheia/dist/game/data/scripts/ai/others/SiegeGuards.java +++ b/L2J_Mobius_1.0_Ertheia/dist/game/data/scripts/ai/others/SiegeGuards.java @@ -20,7 +20,6 @@ import java.util.List; 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; @@ -29,7 +28,7 @@ import org.l2jmobius.gameserver.model.WorldObject; import org.l2jmobius.gameserver.model.actor.Attackable; import org.l2jmobius.gameserver.model.actor.Creature; import org.l2jmobius.gameserver.model.actor.Npc; -import org.l2jmobius.gameserver.model.actor.Summon; +import org.l2jmobius.gameserver.model.actor.Playable; import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; import org.l2jmobius.gameserver.model.entity.Castle; import org.l2jmobius.gameserver.model.entity.Fort; @@ -154,44 +153,52 @@ public class SiegeGuards extends AbstractNpcAI final List guards = RESIDENCE_GUARD_MAP[_residenceId]; for (Npc guard : guards) { - if (guard == null) + // Should never happen. + if ((guard == null) || !guard.isAttackable()) { continue; } + // Remove dead guards. if (guard.isDead()) { guards.remove(guard); continue; } - final WorldObject target = guard.getTarget(); - if (!guard.isInCombat() || (target == null) || (guard.calculateDistance2D(target) > guard.getAggroRange()) || target.isInvul()) + // Skip if guard is currently attacking. + if (guard.isInCombat()) { - for (Creature nearby : World.getInstance().getVisibleObjectsInRange(guard, Creature.class, guard.getAggroRange())) + continue; + } + + // Skip if guard has an active target (not dead/invis/invul and is within range). + final WorldObject target = guard.getTarget(); + final Creature targetCreature = (target != null) && target.isCreature() ? (Creature) target : null; + if ((targetCreature != null) && !targetCreature.isDead() && !targetCreature.isInvisible() && !targetCreature.isInvul() && (guard.calculateDistance2D(targetCreature) < guard.getAggroRange())) + { + continue; + } + + // Iterate all players/summons within aggro range... + for (Playable nearby : World.getInstance().getVisibleObjectsInRange(guard, Playable.class, guard.getAggroRange())) + { + // Do not attack players/summons who are dead/invis/invul or cannot be seen. + if (nearby.isDead() || nearby.isInvisible() || nearby.isInvul() || !GeoEngine.getInstance().canSeeTarget(guard, nearby)) { - if (nearby.isPlayable() && GeoEngine.getInstance().canSeeTarget(guard, nearby)) - { - 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))) - { - // 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 - } - } + continue; } + + // Do not attack defenders who are registered to this castle. + final PlayerInstance player = nearby.getActingPlayer(); + if ((player.getSiegeState() == 2) && player.isRegisteredOnThisSiegeField(guard.getScriptValue())) + { + continue; + } + + // Attack the target and stop searching. + ((Attackable) guard).addDamageHate(nearby, 0, 999); + break; } } diff --git a/L2J_Mobius_1.0_Ertheia/java/org/l2jmobius/gameserver/ai/AttackableAI.java b/L2J_Mobius_1.0_Ertheia/java/org/l2jmobius/gameserver/ai/AttackableAI.java index 2aaa69961c..75db827845 100644 --- a/L2J_Mobius_1.0_Ertheia/java/org/l2jmobius/gameserver/ai/AttackableAI.java +++ b/L2J_Mobius_1.0_Ertheia/java/org/l2jmobius/gameserver/ai/AttackableAI.java @@ -40,7 +40,6 @@ import org.l2jmobius.gameserver.model.World; import org.l2jmobius.gameserver.model.WorldObject; import org.l2jmobius.gameserver.model.actor.Attackable; import org.l2jmobius.gameserver.model.actor.Creature; -import org.l2jmobius.gameserver.model.actor.Npc; import org.l2jmobius.gameserver.model.actor.Playable; import org.l2jmobius.gameserver.model.actor.instance.DefenderInstance; import org.l2jmobius.gameserver.model.actor.instance.GrandBossInstance; @@ -711,7 +710,7 @@ public class AttackableAI extends CreatureAI } if (targetExistsInAttackByList) { - World.getInstance().forEachVisibleObjectInRange(npc, Npc.class, factionRange, called -> + World.getInstance().forEachVisibleObjectInRange(npc, Attackable.class, factionRange, called -> { // Don't call dead npcs, npcs without ai or npcs which are too far away. if (called.isDead() || !called.hasAI() || (Math.abs(finalTarget.getZ() - called.getZ()) > 600)) @@ -736,9 +735,9 @@ public class AttackableAI extends CreatureAI called.getAI().notifyEvent(CtrlEvent.EVT_AGGRESSION, finalTarget, 1); EventDispatcher.getInstance().notifyEventAsync(new OnAttackableFactionCall(called, getActiveChar(), finalTarget.getActingPlayer(), finalTarget.isSummon()), called); } - else if (called.isAttackable() && (called.getAI()._intention != CtrlIntention.AI_INTENTION_ATTACK)) + else if (called.getAI()._intention != CtrlIntention.AI_INTENTION_ATTACK) { - ((Attackable) called).addDamageHate(finalTarget, 0, npc.getHating(finalTarget)); + called.addDamageHate(finalTarget, 0, npc.getHating(finalTarget)); called.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, finalTarget); } }); diff --git a/L2J_Mobius_1.0_Ertheia/java/org/l2jmobius/gameserver/model/actor/instance/DefenderInstance.java b/L2J_Mobius_1.0_Ertheia/java/org/l2jmobius/gameserver/model/actor/instance/DefenderInstance.java index c544782ef2..b882c183a6 100644 --- a/L2J_Mobius_1.0_Ertheia/java/org/l2jmobius/gameserver/model/actor/instance/DefenderInstance.java +++ b/L2J_Mobius_1.0_Ertheia/java/org/l2jmobius/gameserver/model/actor/instance/DefenderInstance.java @@ -215,7 +215,9 @@ public class DefenderInstance extends Attackable if (((_fort != null) && _fort.getZone().isActive()) || ((_castle != null) && _castle.getZone().isActive())) { final int activeSiegeId = (_fort != null) ? _fort.getResidenceId() : _castle.getResidenceId(); - if ((player != null) && (((player.getSiegeState() == 2) && player.isRegisteredOnThisSiegeField(activeSiegeId)) || ((player.getSiegeState() == 1)))) + + // Do not add hate on defenders. + if ((player.getSiegeState() == 2) && player.isRegisteredOnThisSiegeField(activeSiegeId)) { return; } diff --git a/L2J_Mobius_2.5_Underground/dist/game/data/scripts/ai/others/SiegeGuards.java b/L2J_Mobius_2.5_Underground/dist/game/data/scripts/ai/others/SiegeGuards.java index 880eeef21a..174255624f 100644 --- a/L2J_Mobius_2.5_Underground/dist/game/data/scripts/ai/others/SiegeGuards.java +++ b/L2J_Mobius_2.5_Underground/dist/game/data/scripts/ai/others/SiegeGuards.java @@ -20,7 +20,6 @@ import java.util.List; 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; @@ -29,7 +28,7 @@ import org.l2jmobius.gameserver.model.WorldObject; import org.l2jmobius.gameserver.model.actor.Attackable; import org.l2jmobius.gameserver.model.actor.Creature; import org.l2jmobius.gameserver.model.actor.Npc; -import org.l2jmobius.gameserver.model.actor.Summon; +import org.l2jmobius.gameserver.model.actor.Playable; import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; import org.l2jmobius.gameserver.model.entity.Castle; import org.l2jmobius.gameserver.model.entity.Fort; @@ -154,44 +153,52 @@ public class SiegeGuards extends AbstractNpcAI final List guards = RESIDENCE_GUARD_MAP[_residenceId]; for (Npc guard : guards) { - if (guard == null) + // Should never happen. + if ((guard == null) || !guard.isAttackable()) { continue; } + // Remove dead guards. if (guard.isDead()) { guards.remove(guard); continue; } - final WorldObject target = guard.getTarget(); - if (!guard.isInCombat() || (target == null) || (guard.calculateDistance2D(target) > guard.getAggroRange()) || target.isInvul()) + // Skip if guard is currently attacking. + if (guard.isInCombat()) { - for (Creature nearby : World.getInstance().getVisibleObjectsInRange(guard, Creature.class, guard.getAggroRange())) + continue; + } + + // Skip if guard has an active target (not dead/invis/invul and is within range). + final WorldObject target = guard.getTarget(); + final Creature targetCreature = (target != null) && target.isCreature() ? (Creature) target : null; + if ((targetCreature != null) && !targetCreature.isDead() && !targetCreature.isInvisible() && !targetCreature.isInvul() && (guard.calculateDistance2D(targetCreature) < guard.getAggroRange())) + { + continue; + } + + // Iterate all players/summons within aggro range... + for (Playable nearby : World.getInstance().getVisibleObjectsInRange(guard, Playable.class, guard.getAggroRange())) + { + // Do not attack players/summons who are dead/invis/invul or cannot be seen. + if (nearby.isDead() || nearby.isInvisible() || nearby.isInvul() || !GeoEngine.getInstance().canSeeTarget(guard, nearby)) { - if (nearby.isPlayable() && GeoEngine.getInstance().canSeeTarget(guard, nearby)) - { - 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))) - { - // 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 - } - } + continue; } + + // Do not attack defenders who are registered to this castle. + final PlayerInstance player = nearby.getActingPlayer(); + if ((player.getSiegeState() == 2) && player.isRegisteredOnThisSiegeField(guard.getScriptValue())) + { + continue; + } + + // Attack the target and stop searching. + ((Attackable) guard).addDamageHate(nearby, 0, 999); + break; } } diff --git a/L2J_Mobius_2.5_Underground/java/org/l2jmobius/gameserver/ai/AttackableAI.java b/L2J_Mobius_2.5_Underground/java/org/l2jmobius/gameserver/ai/AttackableAI.java index 2aaa69961c..75db827845 100644 --- a/L2J_Mobius_2.5_Underground/java/org/l2jmobius/gameserver/ai/AttackableAI.java +++ b/L2J_Mobius_2.5_Underground/java/org/l2jmobius/gameserver/ai/AttackableAI.java @@ -40,7 +40,6 @@ import org.l2jmobius.gameserver.model.World; import org.l2jmobius.gameserver.model.WorldObject; import org.l2jmobius.gameserver.model.actor.Attackable; import org.l2jmobius.gameserver.model.actor.Creature; -import org.l2jmobius.gameserver.model.actor.Npc; import org.l2jmobius.gameserver.model.actor.Playable; import org.l2jmobius.gameserver.model.actor.instance.DefenderInstance; import org.l2jmobius.gameserver.model.actor.instance.GrandBossInstance; @@ -711,7 +710,7 @@ public class AttackableAI extends CreatureAI } if (targetExistsInAttackByList) { - World.getInstance().forEachVisibleObjectInRange(npc, Npc.class, factionRange, called -> + World.getInstance().forEachVisibleObjectInRange(npc, Attackable.class, factionRange, called -> { // Don't call dead npcs, npcs without ai or npcs which are too far away. if (called.isDead() || !called.hasAI() || (Math.abs(finalTarget.getZ() - called.getZ()) > 600)) @@ -736,9 +735,9 @@ public class AttackableAI extends CreatureAI called.getAI().notifyEvent(CtrlEvent.EVT_AGGRESSION, finalTarget, 1); EventDispatcher.getInstance().notifyEventAsync(new OnAttackableFactionCall(called, getActiveChar(), finalTarget.getActingPlayer(), finalTarget.isSummon()), called); } - else if (called.isAttackable() && (called.getAI()._intention != CtrlIntention.AI_INTENTION_ATTACK)) + else if (called.getAI()._intention != CtrlIntention.AI_INTENTION_ATTACK) { - ((Attackable) called).addDamageHate(finalTarget, 0, npc.getHating(finalTarget)); + called.addDamageHate(finalTarget, 0, npc.getHating(finalTarget)); called.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, finalTarget); } }); diff --git a/L2J_Mobius_2.5_Underground/java/org/l2jmobius/gameserver/model/actor/instance/DefenderInstance.java b/L2J_Mobius_2.5_Underground/java/org/l2jmobius/gameserver/model/actor/instance/DefenderInstance.java index c544782ef2..b882c183a6 100644 --- a/L2J_Mobius_2.5_Underground/java/org/l2jmobius/gameserver/model/actor/instance/DefenderInstance.java +++ b/L2J_Mobius_2.5_Underground/java/org/l2jmobius/gameserver/model/actor/instance/DefenderInstance.java @@ -215,7 +215,9 @@ public class DefenderInstance extends Attackable if (((_fort != null) && _fort.getZone().isActive()) || ((_castle != null) && _castle.getZone().isActive())) { final int activeSiegeId = (_fort != null) ? _fort.getResidenceId() : _castle.getResidenceId(); - if ((player != null) && (((player.getSiegeState() == 2) && player.isRegisteredOnThisSiegeField(activeSiegeId)) || ((player.getSiegeState() == 1)))) + + // Do not add hate on defenders. + if ((player.getSiegeState() == 2) && player.isRegisteredOnThisSiegeField(activeSiegeId)) { return; } diff --git a/L2J_Mobius_3.0_Helios/dist/game/data/scripts/ai/others/SiegeGuards.java b/L2J_Mobius_3.0_Helios/dist/game/data/scripts/ai/others/SiegeGuards.java index 880eeef21a..174255624f 100644 --- a/L2J_Mobius_3.0_Helios/dist/game/data/scripts/ai/others/SiegeGuards.java +++ b/L2J_Mobius_3.0_Helios/dist/game/data/scripts/ai/others/SiegeGuards.java @@ -20,7 +20,6 @@ import java.util.List; 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; @@ -29,7 +28,7 @@ import org.l2jmobius.gameserver.model.WorldObject; import org.l2jmobius.gameserver.model.actor.Attackable; import org.l2jmobius.gameserver.model.actor.Creature; import org.l2jmobius.gameserver.model.actor.Npc; -import org.l2jmobius.gameserver.model.actor.Summon; +import org.l2jmobius.gameserver.model.actor.Playable; import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; import org.l2jmobius.gameserver.model.entity.Castle; import org.l2jmobius.gameserver.model.entity.Fort; @@ -154,44 +153,52 @@ public class SiegeGuards extends AbstractNpcAI final List guards = RESIDENCE_GUARD_MAP[_residenceId]; for (Npc guard : guards) { - if (guard == null) + // Should never happen. + if ((guard == null) || !guard.isAttackable()) { continue; } + // Remove dead guards. if (guard.isDead()) { guards.remove(guard); continue; } - final WorldObject target = guard.getTarget(); - if (!guard.isInCombat() || (target == null) || (guard.calculateDistance2D(target) > guard.getAggroRange()) || target.isInvul()) + // Skip if guard is currently attacking. + if (guard.isInCombat()) { - for (Creature nearby : World.getInstance().getVisibleObjectsInRange(guard, Creature.class, guard.getAggroRange())) + continue; + } + + // Skip if guard has an active target (not dead/invis/invul and is within range). + final WorldObject target = guard.getTarget(); + final Creature targetCreature = (target != null) && target.isCreature() ? (Creature) target : null; + if ((targetCreature != null) && !targetCreature.isDead() && !targetCreature.isInvisible() && !targetCreature.isInvul() && (guard.calculateDistance2D(targetCreature) < guard.getAggroRange())) + { + continue; + } + + // Iterate all players/summons within aggro range... + for (Playable nearby : World.getInstance().getVisibleObjectsInRange(guard, Playable.class, guard.getAggroRange())) + { + // Do not attack players/summons who are dead/invis/invul or cannot be seen. + if (nearby.isDead() || nearby.isInvisible() || nearby.isInvul() || !GeoEngine.getInstance().canSeeTarget(guard, nearby)) { - if (nearby.isPlayable() && GeoEngine.getInstance().canSeeTarget(guard, nearby)) - { - 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))) - { - // 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 - } - } + continue; } + + // Do not attack defenders who are registered to this castle. + final PlayerInstance player = nearby.getActingPlayer(); + if ((player.getSiegeState() == 2) && player.isRegisteredOnThisSiegeField(guard.getScriptValue())) + { + continue; + } + + // Attack the target and stop searching. + ((Attackable) guard).addDamageHate(nearby, 0, 999); + break; } } diff --git a/L2J_Mobius_3.0_Helios/java/org/l2jmobius/gameserver/ai/AttackableAI.java b/L2J_Mobius_3.0_Helios/java/org/l2jmobius/gameserver/ai/AttackableAI.java index 2aaa69961c..75db827845 100644 --- a/L2J_Mobius_3.0_Helios/java/org/l2jmobius/gameserver/ai/AttackableAI.java +++ b/L2J_Mobius_3.0_Helios/java/org/l2jmobius/gameserver/ai/AttackableAI.java @@ -40,7 +40,6 @@ import org.l2jmobius.gameserver.model.World; import org.l2jmobius.gameserver.model.WorldObject; import org.l2jmobius.gameserver.model.actor.Attackable; import org.l2jmobius.gameserver.model.actor.Creature; -import org.l2jmobius.gameserver.model.actor.Npc; import org.l2jmobius.gameserver.model.actor.Playable; import org.l2jmobius.gameserver.model.actor.instance.DefenderInstance; import org.l2jmobius.gameserver.model.actor.instance.GrandBossInstance; @@ -711,7 +710,7 @@ public class AttackableAI extends CreatureAI } if (targetExistsInAttackByList) { - World.getInstance().forEachVisibleObjectInRange(npc, Npc.class, factionRange, called -> + World.getInstance().forEachVisibleObjectInRange(npc, Attackable.class, factionRange, called -> { // Don't call dead npcs, npcs without ai or npcs which are too far away. if (called.isDead() || !called.hasAI() || (Math.abs(finalTarget.getZ() - called.getZ()) > 600)) @@ -736,9 +735,9 @@ public class AttackableAI extends CreatureAI called.getAI().notifyEvent(CtrlEvent.EVT_AGGRESSION, finalTarget, 1); EventDispatcher.getInstance().notifyEventAsync(new OnAttackableFactionCall(called, getActiveChar(), finalTarget.getActingPlayer(), finalTarget.isSummon()), called); } - else if (called.isAttackable() && (called.getAI()._intention != CtrlIntention.AI_INTENTION_ATTACK)) + else if (called.getAI()._intention != CtrlIntention.AI_INTENTION_ATTACK) { - ((Attackable) called).addDamageHate(finalTarget, 0, npc.getHating(finalTarget)); + called.addDamageHate(finalTarget, 0, npc.getHating(finalTarget)); called.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, finalTarget); } }); diff --git a/L2J_Mobius_3.0_Helios/java/org/l2jmobius/gameserver/model/actor/instance/DefenderInstance.java b/L2J_Mobius_3.0_Helios/java/org/l2jmobius/gameserver/model/actor/instance/DefenderInstance.java index c544782ef2..b882c183a6 100644 --- a/L2J_Mobius_3.0_Helios/java/org/l2jmobius/gameserver/model/actor/instance/DefenderInstance.java +++ b/L2J_Mobius_3.0_Helios/java/org/l2jmobius/gameserver/model/actor/instance/DefenderInstance.java @@ -215,7 +215,9 @@ public class DefenderInstance extends Attackable if (((_fort != null) && _fort.getZone().isActive()) || ((_castle != null) && _castle.getZone().isActive())) { final int activeSiegeId = (_fort != null) ? _fort.getResidenceId() : _castle.getResidenceId(); - if ((player != null) && (((player.getSiegeState() == 2) && player.isRegisteredOnThisSiegeField(activeSiegeId)) || ((player.getSiegeState() == 1)))) + + // Do not add hate on defenders. + if ((player.getSiegeState() == 2) && player.isRegisteredOnThisSiegeField(activeSiegeId)) { return; } diff --git a/L2J_Mobius_4.0_GrandCrusade/dist/game/data/scripts/ai/others/SiegeGuards.java b/L2J_Mobius_4.0_GrandCrusade/dist/game/data/scripts/ai/others/SiegeGuards.java index 880eeef21a..174255624f 100644 --- a/L2J_Mobius_4.0_GrandCrusade/dist/game/data/scripts/ai/others/SiegeGuards.java +++ b/L2J_Mobius_4.0_GrandCrusade/dist/game/data/scripts/ai/others/SiegeGuards.java @@ -20,7 +20,6 @@ import java.util.List; 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; @@ -29,7 +28,7 @@ import org.l2jmobius.gameserver.model.WorldObject; import org.l2jmobius.gameserver.model.actor.Attackable; import org.l2jmobius.gameserver.model.actor.Creature; import org.l2jmobius.gameserver.model.actor.Npc; -import org.l2jmobius.gameserver.model.actor.Summon; +import org.l2jmobius.gameserver.model.actor.Playable; import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; import org.l2jmobius.gameserver.model.entity.Castle; import org.l2jmobius.gameserver.model.entity.Fort; @@ -154,44 +153,52 @@ public class SiegeGuards extends AbstractNpcAI final List guards = RESIDENCE_GUARD_MAP[_residenceId]; for (Npc guard : guards) { - if (guard == null) + // Should never happen. + if ((guard == null) || !guard.isAttackable()) { continue; } + // Remove dead guards. if (guard.isDead()) { guards.remove(guard); continue; } - final WorldObject target = guard.getTarget(); - if (!guard.isInCombat() || (target == null) || (guard.calculateDistance2D(target) > guard.getAggroRange()) || target.isInvul()) + // Skip if guard is currently attacking. + if (guard.isInCombat()) { - for (Creature nearby : World.getInstance().getVisibleObjectsInRange(guard, Creature.class, guard.getAggroRange())) + continue; + } + + // Skip if guard has an active target (not dead/invis/invul and is within range). + final WorldObject target = guard.getTarget(); + final Creature targetCreature = (target != null) && target.isCreature() ? (Creature) target : null; + if ((targetCreature != null) && !targetCreature.isDead() && !targetCreature.isInvisible() && !targetCreature.isInvul() && (guard.calculateDistance2D(targetCreature) < guard.getAggroRange())) + { + continue; + } + + // Iterate all players/summons within aggro range... + for (Playable nearby : World.getInstance().getVisibleObjectsInRange(guard, Playable.class, guard.getAggroRange())) + { + // Do not attack players/summons who are dead/invis/invul or cannot be seen. + if (nearby.isDead() || nearby.isInvisible() || nearby.isInvul() || !GeoEngine.getInstance().canSeeTarget(guard, nearby)) { - if (nearby.isPlayable() && GeoEngine.getInstance().canSeeTarget(guard, nearby)) - { - 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))) - { - // 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 - } - } + continue; } + + // Do not attack defenders who are registered to this castle. + final PlayerInstance player = nearby.getActingPlayer(); + if ((player.getSiegeState() == 2) && player.isRegisteredOnThisSiegeField(guard.getScriptValue())) + { + continue; + } + + // Attack the target and stop searching. + ((Attackable) guard).addDamageHate(nearby, 0, 999); + break; } } diff --git a/L2J_Mobius_4.0_GrandCrusade/java/org/l2jmobius/gameserver/ai/AttackableAI.java b/L2J_Mobius_4.0_GrandCrusade/java/org/l2jmobius/gameserver/ai/AttackableAI.java index 2aaa69961c..75db827845 100644 --- a/L2J_Mobius_4.0_GrandCrusade/java/org/l2jmobius/gameserver/ai/AttackableAI.java +++ b/L2J_Mobius_4.0_GrandCrusade/java/org/l2jmobius/gameserver/ai/AttackableAI.java @@ -40,7 +40,6 @@ import org.l2jmobius.gameserver.model.World; import org.l2jmobius.gameserver.model.WorldObject; import org.l2jmobius.gameserver.model.actor.Attackable; import org.l2jmobius.gameserver.model.actor.Creature; -import org.l2jmobius.gameserver.model.actor.Npc; import org.l2jmobius.gameserver.model.actor.Playable; import org.l2jmobius.gameserver.model.actor.instance.DefenderInstance; import org.l2jmobius.gameserver.model.actor.instance.GrandBossInstance; @@ -711,7 +710,7 @@ public class AttackableAI extends CreatureAI } if (targetExistsInAttackByList) { - World.getInstance().forEachVisibleObjectInRange(npc, Npc.class, factionRange, called -> + World.getInstance().forEachVisibleObjectInRange(npc, Attackable.class, factionRange, called -> { // Don't call dead npcs, npcs without ai or npcs which are too far away. if (called.isDead() || !called.hasAI() || (Math.abs(finalTarget.getZ() - called.getZ()) > 600)) @@ -736,9 +735,9 @@ public class AttackableAI extends CreatureAI called.getAI().notifyEvent(CtrlEvent.EVT_AGGRESSION, finalTarget, 1); EventDispatcher.getInstance().notifyEventAsync(new OnAttackableFactionCall(called, getActiveChar(), finalTarget.getActingPlayer(), finalTarget.isSummon()), called); } - else if (called.isAttackable() && (called.getAI()._intention != CtrlIntention.AI_INTENTION_ATTACK)) + else if (called.getAI()._intention != CtrlIntention.AI_INTENTION_ATTACK) { - ((Attackable) called).addDamageHate(finalTarget, 0, npc.getHating(finalTarget)); + called.addDamageHate(finalTarget, 0, npc.getHating(finalTarget)); called.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, finalTarget); } }); diff --git a/L2J_Mobius_4.0_GrandCrusade/java/org/l2jmobius/gameserver/model/actor/instance/DefenderInstance.java b/L2J_Mobius_4.0_GrandCrusade/java/org/l2jmobius/gameserver/model/actor/instance/DefenderInstance.java index c544782ef2..b882c183a6 100644 --- a/L2J_Mobius_4.0_GrandCrusade/java/org/l2jmobius/gameserver/model/actor/instance/DefenderInstance.java +++ b/L2J_Mobius_4.0_GrandCrusade/java/org/l2jmobius/gameserver/model/actor/instance/DefenderInstance.java @@ -215,7 +215,9 @@ public class DefenderInstance extends Attackable if (((_fort != null) && _fort.getZone().isActive()) || ((_castle != null) && _castle.getZone().isActive())) { final int activeSiegeId = (_fort != null) ? _fort.getResidenceId() : _castle.getResidenceId(); - if ((player != null) && (((player.getSiegeState() == 2) && player.isRegisteredOnThisSiegeField(activeSiegeId)) || ((player.getSiegeState() == 1)))) + + // Do not add hate on defenders. + if ((player.getSiegeState() == 2) && player.isRegisteredOnThisSiegeField(activeSiegeId)) { return; } diff --git a/L2J_Mobius_5.0_Salvation/dist/game/data/scripts/ai/others/SiegeGuards.java b/L2J_Mobius_5.0_Salvation/dist/game/data/scripts/ai/others/SiegeGuards.java index 880eeef21a..174255624f 100644 --- a/L2J_Mobius_5.0_Salvation/dist/game/data/scripts/ai/others/SiegeGuards.java +++ b/L2J_Mobius_5.0_Salvation/dist/game/data/scripts/ai/others/SiegeGuards.java @@ -20,7 +20,6 @@ import java.util.List; 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; @@ -29,7 +28,7 @@ import org.l2jmobius.gameserver.model.WorldObject; import org.l2jmobius.gameserver.model.actor.Attackable; import org.l2jmobius.gameserver.model.actor.Creature; import org.l2jmobius.gameserver.model.actor.Npc; -import org.l2jmobius.gameserver.model.actor.Summon; +import org.l2jmobius.gameserver.model.actor.Playable; import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; import org.l2jmobius.gameserver.model.entity.Castle; import org.l2jmobius.gameserver.model.entity.Fort; @@ -154,44 +153,52 @@ public class SiegeGuards extends AbstractNpcAI final List guards = RESIDENCE_GUARD_MAP[_residenceId]; for (Npc guard : guards) { - if (guard == null) + // Should never happen. + if ((guard == null) || !guard.isAttackable()) { continue; } + // Remove dead guards. if (guard.isDead()) { guards.remove(guard); continue; } - final WorldObject target = guard.getTarget(); - if (!guard.isInCombat() || (target == null) || (guard.calculateDistance2D(target) > guard.getAggroRange()) || target.isInvul()) + // Skip if guard is currently attacking. + if (guard.isInCombat()) { - for (Creature nearby : World.getInstance().getVisibleObjectsInRange(guard, Creature.class, guard.getAggroRange())) + continue; + } + + // Skip if guard has an active target (not dead/invis/invul and is within range). + final WorldObject target = guard.getTarget(); + final Creature targetCreature = (target != null) && target.isCreature() ? (Creature) target : null; + if ((targetCreature != null) && !targetCreature.isDead() && !targetCreature.isInvisible() && !targetCreature.isInvul() && (guard.calculateDistance2D(targetCreature) < guard.getAggroRange())) + { + continue; + } + + // Iterate all players/summons within aggro range... + for (Playable nearby : World.getInstance().getVisibleObjectsInRange(guard, Playable.class, guard.getAggroRange())) + { + // Do not attack players/summons who are dead/invis/invul or cannot be seen. + if (nearby.isDead() || nearby.isInvisible() || nearby.isInvul() || !GeoEngine.getInstance().canSeeTarget(guard, nearby)) { - if (nearby.isPlayable() && GeoEngine.getInstance().canSeeTarget(guard, nearby)) - { - 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))) - { - // 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 - } - } + continue; } + + // Do not attack defenders who are registered to this castle. + final PlayerInstance player = nearby.getActingPlayer(); + if ((player.getSiegeState() == 2) && player.isRegisteredOnThisSiegeField(guard.getScriptValue())) + { + continue; + } + + // Attack the target and stop searching. + ((Attackable) guard).addDamageHate(nearby, 0, 999); + break; } } diff --git a/L2J_Mobius_5.0_Salvation/java/org/l2jmobius/gameserver/ai/AttackableAI.java b/L2J_Mobius_5.0_Salvation/java/org/l2jmobius/gameserver/ai/AttackableAI.java index 2aaa69961c..75db827845 100644 --- a/L2J_Mobius_5.0_Salvation/java/org/l2jmobius/gameserver/ai/AttackableAI.java +++ b/L2J_Mobius_5.0_Salvation/java/org/l2jmobius/gameserver/ai/AttackableAI.java @@ -40,7 +40,6 @@ import org.l2jmobius.gameserver.model.World; import org.l2jmobius.gameserver.model.WorldObject; import org.l2jmobius.gameserver.model.actor.Attackable; import org.l2jmobius.gameserver.model.actor.Creature; -import org.l2jmobius.gameserver.model.actor.Npc; import org.l2jmobius.gameserver.model.actor.Playable; import org.l2jmobius.gameserver.model.actor.instance.DefenderInstance; import org.l2jmobius.gameserver.model.actor.instance.GrandBossInstance; @@ -711,7 +710,7 @@ public class AttackableAI extends CreatureAI } if (targetExistsInAttackByList) { - World.getInstance().forEachVisibleObjectInRange(npc, Npc.class, factionRange, called -> + World.getInstance().forEachVisibleObjectInRange(npc, Attackable.class, factionRange, called -> { // Don't call dead npcs, npcs without ai or npcs which are too far away. if (called.isDead() || !called.hasAI() || (Math.abs(finalTarget.getZ() - called.getZ()) > 600)) @@ -736,9 +735,9 @@ public class AttackableAI extends CreatureAI called.getAI().notifyEvent(CtrlEvent.EVT_AGGRESSION, finalTarget, 1); EventDispatcher.getInstance().notifyEventAsync(new OnAttackableFactionCall(called, getActiveChar(), finalTarget.getActingPlayer(), finalTarget.isSummon()), called); } - else if (called.isAttackable() && (called.getAI()._intention != CtrlIntention.AI_INTENTION_ATTACK)) + else if (called.getAI()._intention != CtrlIntention.AI_INTENTION_ATTACK) { - ((Attackable) called).addDamageHate(finalTarget, 0, npc.getHating(finalTarget)); + called.addDamageHate(finalTarget, 0, npc.getHating(finalTarget)); called.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, finalTarget); } }); diff --git a/L2J_Mobius_5.0_Salvation/java/org/l2jmobius/gameserver/model/actor/instance/DefenderInstance.java b/L2J_Mobius_5.0_Salvation/java/org/l2jmobius/gameserver/model/actor/instance/DefenderInstance.java index c544782ef2..b882c183a6 100644 --- a/L2J_Mobius_5.0_Salvation/java/org/l2jmobius/gameserver/model/actor/instance/DefenderInstance.java +++ b/L2J_Mobius_5.0_Salvation/java/org/l2jmobius/gameserver/model/actor/instance/DefenderInstance.java @@ -215,7 +215,9 @@ public class DefenderInstance extends Attackable if (((_fort != null) && _fort.getZone().isActive()) || ((_castle != null) && _castle.getZone().isActive())) { final int activeSiegeId = (_fort != null) ? _fort.getResidenceId() : _castle.getResidenceId(); - if ((player != null) && (((player.getSiegeState() == 2) && player.isRegisteredOnThisSiegeField(activeSiegeId)) || ((player.getSiegeState() == 1)))) + + // Do not add hate on defenders. + if ((player.getSiegeState() == 2) && player.isRegisteredOnThisSiegeField(activeSiegeId)) { return; } diff --git a/L2J_Mobius_5.5_EtinasFate/dist/game/data/scripts/ai/others/SiegeGuards.java b/L2J_Mobius_5.5_EtinasFate/dist/game/data/scripts/ai/others/SiegeGuards.java index 880eeef21a..174255624f 100644 --- a/L2J_Mobius_5.5_EtinasFate/dist/game/data/scripts/ai/others/SiegeGuards.java +++ b/L2J_Mobius_5.5_EtinasFate/dist/game/data/scripts/ai/others/SiegeGuards.java @@ -20,7 +20,6 @@ import java.util.List; 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; @@ -29,7 +28,7 @@ import org.l2jmobius.gameserver.model.WorldObject; import org.l2jmobius.gameserver.model.actor.Attackable; import org.l2jmobius.gameserver.model.actor.Creature; import org.l2jmobius.gameserver.model.actor.Npc; -import org.l2jmobius.gameserver.model.actor.Summon; +import org.l2jmobius.gameserver.model.actor.Playable; import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; import org.l2jmobius.gameserver.model.entity.Castle; import org.l2jmobius.gameserver.model.entity.Fort; @@ -154,44 +153,52 @@ public class SiegeGuards extends AbstractNpcAI final List guards = RESIDENCE_GUARD_MAP[_residenceId]; for (Npc guard : guards) { - if (guard == null) + // Should never happen. + if ((guard == null) || !guard.isAttackable()) { continue; } + // Remove dead guards. if (guard.isDead()) { guards.remove(guard); continue; } - final WorldObject target = guard.getTarget(); - if (!guard.isInCombat() || (target == null) || (guard.calculateDistance2D(target) > guard.getAggroRange()) || target.isInvul()) + // Skip if guard is currently attacking. + if (guard.isInCombat()) { - for (Creature nearby : World.getInstance().getVisibleObjectsInRange(guard, Creature.class, guard.getAggroRange())) + continue; + } + + // Skip if guard has an active target (not dead/invis/invul and is within range). + final WorldObject target = guard.getTarget(); + final Creature targetCreature = (target != null) && target.isCreature() ? (Creature) target : null; + if ((targetCreature != null) && !targetCreature.isDead() && !targetCreature.isInvisible() && !targetCreature.isInvul() && (guard.calculateDistance2D(targetCreature) < guard.getAggroRange())) + { + continue; + } + + // Iterate all players/summons within aggro range... + for (Playable nearby : World.getInstance().getVisibleObjectsInRange(guard, Playable.class, guard.getAggroRange())) + { + // Do not attack players/summons who are dead/invis/invul or cannot be seen. + if (nearby.isDead() || nearby.isInvisible() || nearby.isInvul() || !GeoEngine.getInstance().canSeeTarget(guard, nearby)) { - if (nearby.isPlayable() && GeoEngine.getInstance().canSeeTarget(guard, nearby)) - { - 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))) - { - // 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 - } - } + continue; } + + // Do not attack defenders who are registered to this castle. + final PlayerInstance player = nearby.getActingPlayer(); + if ((player.getSiegeState() == 2) && player.isRegisteredOnThisSiegeField(guard.getScriptValue())) + { + continue; + } + + // Attack the target and stop searching. + ((Attackable) guard).addDamageHate(nearby, 0, 999); + break; } } diff --git a/L2J_Mobius_5.5_EtinasFate/java/org/l2jmobius/gameserver/ai/AttackableAI.java b/L2J_Mobius_5.5_EtinasFate/java/org/l2jmobius/gameserver/ai/AttackableAI.java index 2aaa69961c..75db827845 100644 --- a/L2J_Mobius_5.5_EtinasFate/java/org/l2jmobius/gameserver/ai/AttackableAI.java +++ b/L2J_Mobius_5.5_EtinasFate/java/org/l2jmobius/gameserver/ai/AttackableAI.java @@ -40,7 +40,6 @@ import org.l2jmobius.gameserver.model.World; import org.l2jmobius.gameserver.model.WorldObject; import org.l2jmobius.gameserver.model.actor.Attackable; import org.l2jmobius.gameserver.model.actor.Creature; -import org.l2jmobius.gameserver.model.actor.Npc; import org.l2jmobius.gameserver.model.actor.Playable; import org.l2jmobius.gameserver.model.actor.instance.DefenderInstance; import org.l2jmobius.gameserver.model.actor.instance.GrandBossInstance; @@ -711,7 +710,7 @@ public class AttackableAI extends CreatureAI } if (targetExistsInAttackByList) { - World.getInstance().forEachVisibleObjectInRange(npc, Npc.class, factionRange, called -> + World.getInstance().forEachVisibleObjectInRange(npc, Attackable.class, factionRange, called -> { // Don't call dead npcs, npcs without ai or npcs which are too far away. if (called.isDead() || !called.hasAI() || (Math.abs(finalTarget.getZ() - called.getZ()) > 600)) @@ -736,9 +735,9 @@ public class AttackableAI extends CreatureAI called.getAI().notifyEvent(CtrlEvent.EVT_AGGRESSION, finalTarget, 1); EventDispatcher.getInstance().notifyEventAsync(new OnAttackableFactionCall(called, getActiveChar(), finalTarget.getActingPlayer(), finalTarget.isSummon()), called); } - else if (called.isAttackable() && (called.getAI()._intention != CtrlIntention.AI_INTENTION_ATTACK)) + else if (called.getAI()._intention != CtrlIntention.AI_INTENTION_ATTACK) { - ((Attackable) called).addDamageHate(finalTarget, 0, npc.getHating(finalTarget)); + called.addDamageHate(finalTarget, 0, npc.getHating(finalTarget)); called.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, finalTarget); } }); diff --git a/L2J_Mobius_5.5_EtinasFate/java/org/l2jmobius/gameserver/model/actor/instance/DefenderInstance.java b/L2J_Mobius_5.5_EtinasFate/java/org/l2jmobius/gameserver/model/actor/instance/DefenderInstance.java index c544782ef2..b882c183a6 100644 --- a/L2J_Mobius_5.5_EtinasFate/java/org/l2jmobius/gameserver/model/actor/instance/DefenderInstance.java +++ b/L2J_Mobius_5.5_EtinasFate/java/org/l2jmobius/gameserver/model/actor/instance/DefenderInstance.java @@ -215,7 +215,9 @@ public class DefenderInstance extends Attackable if (((_fort != null) && _fort.getZone().isActive()) || ((_castle != null) && _castle.getZone().isActive())) { final int activeSiegeId = (_fort != null) ? _fort.getResidenceId() : _castle.getResidenceId(); - if ((player != null) && (((player.getSiegeState() == 2) && player.isRegisteredOnThisSiegeField(activeSiegeId)) || ((player.getSiegeState() == 1)))) + + // Do not add hate on defenders. + if ((player.getSiegeState() == 2) && player.isRegisteredOnThisSiegeField(activeSiegeId)) { return; } diff --git a/L2J_Mobius_6.0_Fafurion/dist/game/data/scripts/ai/others/SiegeGuards.java b/L2J_Mobius_6.0_Fafurion/dist/game/data/scripts/ai/others/SiegeGuards.java index 880eeef21a..174255624f 100644 --- a/L2J_Mobius_6.0_Fafurion/dist/game/data/scripts/ai/others/SiegeGuards.java +++ b/L2J_Mobius_6.0_Fafurion/dist/game/data/scripts/ai/others/SiegeGuards.java @@ -20,7 +20,6 @@ import java.util.List; 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; @@ -29,7 +28,7 @@ import org.l2jmobius.gameserver.model.WorldObject; import org.l2jmobius.gameserver.model.actor.Attackable; import org.l2jmobius.gameserver.model.actor.Creature; import org.l2jmobius.gameserver.model.actor.Npc; -import org.l2jmobius.gameserver.model.actor.Summon; +import org.l2jmobius.gameserver.model.actor.Playable; import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; import org.l2jmobius.gameserver.model.entity.Castle; import org.l2jmobius.gameserver.model.entity.Fort; @@ -154,44 +153,52 @@ public class SiegeGuards extends AbstractNpcAI final List guards = RESIDENCE_GUARD_MAP[_residenceId]; for (Npc guard : guards) { - if (guard == null) + // Should never happen. + if ((guard == null) || !guard.isAttackable()) { continue; } + // Remove dead guards. if (guard.isDead()) { guards.remove(guard); continue; } - final WorldObject target = guard.getTarget(); - if (!guard.isInCombat() || (target == null) || (guard.calculateDistance2D(target) > guard.getAggroRange()) || target.isInvul()) + // Skip if guard is currently attacking. + if (guard.isInCombat()) { - for (Creature nearby : World.getInstance().getVisibleObjectsInRange(guard, Creature.class, guard.getAggroRange())) + continue; + } + + // Skip if guard has an active target (not dead/invis/invul and is within range). + final WorldObject target = guard.getTarget(); + final Creature targetCreature = (target != null) && target.isCreature() ? (Creature) target : null; + if ((targetCreature != null) && !targetCreature.isDead() && !targetCreature.isInvisible() && !targetCreature.isInvul() && (guard.calculateDistance2D(targetCreature) < guard.getAggroRange())) + { + continue; + } + + // Iterate all players/summons within aggro range... + for (Playable nearby : World.getInstance().getVisibleObjectsInRange(guard, Playable.class, guard.getAggroRange())) + { + // Do not attack players/summons who are dead/invis/invul or cannot be seen. + if (nearby.isDead() || nearby.isInvisible() || nearby.isInvul() || !GeoEngine.getInstance().canSeeTarget(guard, nearby)) { - if (nearby.isPlayable() && GeoEngine.getInstance().canSeeTarget(guard, nearby)) - { - 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))) - { - // 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 - } - } + continue; } + + // Do not attack defenders who are registered to this castle. + final PlayerInstance player = nearby.getActingPlayer(); + if ((player.getSiegeState() == 2) && player.isRegisteredOnThisSiegeField(guard.getScriptValue())) + { + continue; + } + + // Attack the target and stop searching. + ((Attackable) guard).addDamageHate(nearby, 0, 999); + break; } } diff --git a/L2J_Mobius_6.0_Fafurion/java/org/l2jmobius/gameserver/ai/AttackableAI.java b/L2J_Mobius_6.0_Fafurion/java/org/l2jmobius/gameserver/ai/AttackableAI.java index 2aaa69961c..75db827845 100644 --- a/L2J_Mobius_6.0_Fafurion/java/org/l2jmobius/gameserver/ai/AttackableAI.java +++ b/L2J_Mobius_6.0_Fafurion/java/org/l2jmobius/gameserver/ai/AttackableAI.java @@ -40,7 +40,6 @@ import org.l2jmobius.gameserver.model.World; import org.l2jmobius.gameserver.model.WorldObject; import org.l2jmobius.gameserver.model.actor.Attackable; import org.l2jmobius.gameserver.model.actor.Creature; -import org.l2jmobius.gameserver.model.actor.Npc; import org.l2jmobius.gameserver.model.actor.Playable; import org.l2jmobius.gameserver.model.actor.instance.DefenderInstance; import org.l2jmobius.gameserver.model.actor.instance.GrandBossInstance; @@ -711,7 +710,7 @@ public class AttackableAI extends CreatureAI } if (targetExistsInAttackByList) { - World.getInstance().forEachVisibleObjectInRange(npc, Npc.class, factionRange, called -> + World.getInstance().forEachVisibleObjectInRange(npc, Attackable.class, factionRange, called -> { // Don't call dead npcs, npcs without ai or npcs which are too far away. if (called.isDead() || !called.hasAI() || (Math.abs(finalTarget.getZ() - called.getZ()) > 600)) @@ -736,9 +735,9 @@ public class AttackableAI extends CreatureAI called.getAI().notifyEvent(CtrlEvent.EVT_AGGRESSION, finalTarget, 1); EventDispatcher.getInstance().notifyEventAsync(new OnAttackableFactionCall(called, getActiveChar(), finalTarget.getActingPlayer(), finalTarget.isSummon()), called); } - else if (called.isAttackable() && (called.getAI()._intention != CtrlIntention.AI_INTENTION_ATTACK)) + else if (called.getAI()._intention != CtrlIntention.AI_INTENTION_ATTACK) { - ((Attackable) called).addDamageHate(finalTarget, 0, npc.getHating(finalTarget)); + called.addDamageHate(finalTarget, 0, npc.getHating(finalTarget)); called.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, finalTarget); } }); diff --git a/L2J_Mobius_6.0_Fafurion/java/org/l2jmobius/gameserver/model/actor/instance/DefenderInstance.java b/L2J_Mobius_6.0_Fafurion/java/org/l2jmobius/gameserver/model/actor/instance/DefenderInstance.java index c544782ef2..b882c183a6 100644 --- a/L2J_Mobius_6.0_Fafurion/java/org/l2jmobius/gameserver/model/actor/instance/DefenderInstance.java +++ b/L2J_Mobius_6.0_Fafurion/java/org/l2jmobius/gameserver/model/actor/instance/DefenderInstance.java @@ -215,7 +215,9 @@ public class DefenderInstance extends Attackable if (((_fort != null) && _fort.getZone().isActive()) || ((_castle != null) && _castle.getZone().isActive())) { final int activeSiegeId = (_fort != null) ? _fort.getResidenceId() : _castle.getResidenceId(); - if ((player != null) && (((player.getSiegeState() == 2) && player.isRegisteredOnThisSiegeField(activeSiegeId)) || ((player.getSiegeState() == 1)))) + + // Do not add hate on defenders. + if ((player.getSiegeState() == 2) && player.isRegisteredOnThisSiegeField(activeSiegeId)) { return; } diff --git a/L2J_Mobius_7.0_PreludeOfWar/dist/game/data/scripts/ai/others/SiegeGuards.java b/L2J_Mobius_7.0_PreludeOfWar/dist/game/data/scripts/ai/others/SiegeGuards.java index 880eeef21a..174255624f 100644 --- a/L2J_Mobius_7.0_PreludeOfWar/dist/game/data/scripts/ai/others/SiegeGuards.java +++ b/L2J_Mobius_7.0_PreludeOfWar/dist/game/data/scripts/ai/others/SiegeGuards.java @@ -20,7 +20,6 @@ import java.util.List; 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; @@ -29,7 +28,7 @@ import org.l2jmobius.gameserver.model.WorldObject; import org.l2jmobius.gameserver.model.actor.Attackable; import org.l2jmobius.gameserver.model.actor.Creature; import org.l2jmobius.gameserver.model.actor.Npc; -import org.l2jmobius.gameserver.model.actor.Summon; +import org.l2jmobius.gameserver.model.actor.Playable; import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; import org.l2jmobius.gameserver.model.entity.Castle; import org.l2jmobius.gameserver.model.entity.Fort; @@ -154,44 +153,52 @@ public class SiegeGuards extends AbstractNpcAI final List guards = RESIDENCE_GUARD_MAP[_residenceId]; for (Npc guard : guards) { - if (guard == null) + // Should never happen. + if ((guard == null) || !guard.isAttackable()) { continue; } + // Remove dead guards. if (guard.isDead()) { guards.remove(guard); continue; } - final WorldObject target = guard.getTarget(); - if (!guard.isInCombat() || (target == null) || (guard.calculateDistance2D(target) > guard.getAggroRange()) || target.isInvul()) + // Skip if guard is currently attacking. + if (guard.isInCombat()) { - for (Creature nearby : World.getInstance().getVisibleObjectsInRange(guard, Creature.class, guard.getAggroRange())) + continue; + } + + // Skip if guard has an active target (not dead/invis/invul and is within range). + final WorldObject target = guard.getTarget(); + final Creature targetCreature = (target != null) && target.isCreature() ? (Creature) target : null; + if ((targetCreature != null) && !targetCreature.isDead() && !targetCreature.isInvisible() && !targetCreature.isInvul() && (guard.calculateDistance2D(targetCreature) < guard.getAggroRange())) + { + continue; + } + + // Iterate all players/summons within aggro range... + for (Playable nearby : World.getInstance().getVisibleObjectsInRange(guard, Playable.class, guard.getAggroRange())) + { + // Do not attack players/summons who are dead/invis/invul or cannot be seen. + if (nearby.isDead() || nearby.isInvisible() || nearby.isInvul() || !GeoEngine.getInstance().canSeeTarget(guard, nearby)) { - if (nearby.isPlayable() && GeoEngine.getInstance().canSeeTarget(guard, nearby)) - { - 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))) - { - // 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 - } - } + continue; } + + // Do not attack defenders who are registered to this castle. + final PlayerInstance player = nearby.getActingPlayer(); + if ((player.getSiegeState() == 2) && player.isRegisteredOnThisSiegeField(guard.getScriptValue())) + { + continue; + } + + // Attack the target and stop searching. + ((Attackable) guard).addDamageHate(nearby, 0, 999); + break; } } diff --git a/L2J_Mobius_7.0_PreludeOfWar/java/org/l2jmobius/gameserver/ai/AttackableAI.java b/L2J_Mobius_7.0_PreludeOfWar/java/org/l2jmobius/gameserver/ai/AttackableAI.java index 2aaa69961c..75db827845 100644 --- a/L2J_Mobius_7.0_PreludeOfWar/java/org/l2jmobius/gameserver/ai/AttackableAI.java +++ b/L2J_Mobius_7.0_PreludeOfWar/java/org/l2jmobius/gameserver/ai/AttackableAI.java @@ -40,7 +40,6 @@ import org.l2jmobius.gameserver.model.World; import org.l2jmobius.gameserver.model.WorldObject; import org.l2jmobius.gameserver.model.actor.Attackable; import org.l2jmobius.gameserver.model.actor.Creature; -import org.l2jmobius.gameserver.model.actor.Npc; import org.l2jmobius.gameserver.model.actor.Playable; import org.l2jmobius.gameserver.model.actor.instance.DefenderInstance; import org.l2jmobius.gameserver.model.actor.instance.GrandBossInstance; @@ -711,7 +710,7 @@ public class AttackableAI extends CreatureAI } if (targetExistsInAttackByList) { - World.getInstance().forEachVisibleObjectInRange(npc, Npc.class, factionRange, called -> + World.getInstance().forEachVisibleObjectInRange(npc, Attackable.class, factionRange, called -> { // Don't call dead npcs, npcs without ai or npcs which are too far away. if (called.isDead() || !called.hasAI() || (Math.abs(finalTarget.getZ() - called.getZ()) > 600)) @@ -736,9 +735,9 @@ public class AttackableAI extends CreatureAI called.getAI().notifyEvent(CtrlEvent.EVT_AGGRESSION, finalTarget, 1); EventDispatcher.getInstance().notifyEventAsync(new OnAttackableFactionCall(called, getActiveChar(), finalTarget.getActingPlayer(), finalTarget.isSummon()), called); } - else if (called.isAttackable() && (called.getAI()._intention != CtrlIntention.AI_INTENTION_ATTACK)) + else if (called.getAI()._intention != CtrlIntention.AI_INTENTION_ATTACK) { - ((Attackable) called).addDamageHate(finalTarget, 0, npc.getHating(finalTarget)); + called.addDamageHate(finalTarget, 0, npc.getHating(finalTarget)); called.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, finalTarget); } }); diff --git a/L2J_Mobius_7.0_PreludeOfWar/java/org/l2jmobius/gameserver/model/actor/instance/DefenderInstance.java b/L2J_Mobius_7.0_PreludeOfWar/java/org/l2jmobius/gameserver/model/actor/instance/DefenderInstance.java index c544782ef2..b882c183a6 100644 --- a/L2J_Mobius_7.0_PreludeOfWar/java/org/l2jmobius/gameserver/model/actor/instance/DefenderInstance.java +++ b/L2J_Mobius_7.0_PreludeOfWar/java/org/l2jmobius/gameserver/model/actor/instance/DefenderInstance.java @@ -215,7 +215,9 @@ public class DefenderInstance extends Attackable if (((_fort != null) && _fort.getZone().isActive()) || ((_castle != null) && _castle.getZone().isActive())) { final int activeSiegeId = (_fort != null) ? _fort.getResidenceId() : _castle.getResidenceId(); - if ((player != null) && (((player.getSiegeState() == 2) && player.isRegisteredOnThisSiegeField(activeSiegeId)) || ((player.getSiegeState() == 1)))) + + // Do not add hate on defenders. + if ((player.getSiegeState() == 2) && player.isRegisteredOnThisSiegeField(activeSiegeId)) { return; } diff --git a/L2J_Mobius_CT_2.4_Epilogue/dist/game/data/scripts/ai/others/SiegeGuards.java b/L2J_Mobius_CT_2.4_Epilogue/dist/game/data/scripts/ai/others/SiegeGuards.java index 2605cd604b..174255624f 100644 --- a/L2J_Mobius_CT_2.4_Epilogue/dist/game/data/scripts/ai/others/SiegeGuards.java +++ b/L2J_Mobius_CT_2.4_Epilogue/dist/game/data/scripts/ai/others/SiegeGuards.java @@ -20,7 +20,6 @@ import java.util.List; 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; @@ -29,7 +28,7 @@ import org.l2jmobius.gameserver.model.WorldObject; import org.l2jmobius.gameserver.model.actor.Attackable; import org.l2jmobius.gameserver.model.actor.Creature; import org.l2jmobius.gameserver.model.actor.Npc; -import org.l2jmobius.gameserver.model.actor.Summon; +import org.l2jmobius.gameserver.model.actor.Playable; import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; import org.l2jmobius.gameserver.model.entity.Castle; import org.l2jmobius.gameserver.model.entity.Fort; @@ -154,44 +153,52 @@ public class SiegeGuards extends AbstractNpcAI final List guards = RESIDENCE_GUARD_MAP[_residenceId]; for (Npc guard : guards) { - if (guard == null) + // Should never happen. + if ((guard == null) || !guard.isAttackable()) { continue; } + // Remove dead guards. if (guard.isDead()) { guards.remove(guard); continue; } - final WorldObject target = guard.getTarget(); - if (!guard.isInCombat() || (target == null) || (guard.calculateDistance2D(target) > guard.getAggroRange()) || (target.isPlayer() && target.getActingPlayer().isInvul())) + // Skip if guard is currently attacking. + if (guard.isInCombat()) { - for (Creature nearby : World.getInstance().getVisibleObjectsInRange(guard, Creature.class, guard.getAggroRange())) + continue; + } + + // Skip if guard has an active target (not dead/invis/invul and is within range). + final WorldObject target = guard.getTarget(); + final Creature targetCreature = (target != null) && target.isCreature() ? (Creature) target : null; + if ((targetCreature != null) && !targetCreature.isDead() && !targetCreature.isInvisible() && !targetCreature.isInvul() && (guard.calculateDistance2D(targetCreature) < guard.getAggroRange())) + { + continue; + } + + // Iterate all players/summons within aggro range... + for (Playable nearby : World.getInstance().getVisibleObjectsInRange(guard, Playable.class, guard.getAggroRange())) + { + // Do not attack players/summons who are dead/invis/invul or cannot be seen. + if (nearby.isDead() || nearby.isInvisible() || nearby.isInvul() || !GeoEngine.getInstance().canSeeTarget(guard, nearby)) { - if (nearby.isPlayable() && GeoEngine.getInstance().canSeeTarget(guard, nearby)) - { - 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))) - { - // 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 - } - } + continue; } + + // Do not attack defenders who are registered to this castle. + final PlayerInstance player = nearby.getActingPlayer(); + if ((player.getSiegeState() == 2) && player.isRegisteredOnThisSiegeField(guard.getScriptValue())) + { + continue; + } + + // Attack the target and stop searching. + ((Attackable) guard).addDamageHate(nearby, 0, 999); + break; } } diff --git a/L2J_Mobius_CT_2.4_Epilogue/java/org/l2jmobius/gameserver/ai/AttackableAI.java b/L2J_Mobius_CT_2.4_Epilogue/java/org/l2jmobius/gameserver/ai/AttackableAI.java index 598eca925f..8fbd535b61 100644 --- a/L2J_Mobius_CT_2.4_Epilogue/java/org/l2jmobius/gameserver/ai/AttackableAI.java +++ b/L2J_Mobius_CT_2.4_Epilogue/java/org/l2jmobius/gameserver/ai/AttackableAI.java @@ -859,7 +859,7 @@ public class AttackableAI extends CreatureAI } if (targetExistsInAttackByList) { - World.getInstance().forEachVisibleObjectInRange(npc, Npc.class, factionRange, called -> + World.getInstance().forEachVisibleObjectInRange(npc, Attackable.class, factionRange, called -> { // Don't call dead npcs, npcs without ai or npcs which are too far away. if (called.isDead() || !called.hasAI() || (Math.abs(finalTarget.getZ() - called.getZ()) > 600)) @@ -895,9 +895,9 @@ public class AttackableAI extends CreatureAI called.getAI().notifyEvent(CtrlEvent.EVT_AGGRESSION, finalTarget, 1); EventDispatcher.getInstance().notifyEventAsync(new OnAttackableFactionCall(called, getActiveChar(), finalTarget.getActingPlayer(), finalTarget.isSummon()), called); } - else if (called.isAttackable() && (called.getAI()._intention != AI_INTENTION_ATTACK)) + else if (called.getAI()._intention != AI_INTENTION_ATTACK) { - ((Attackable) called).addDamageHate(finalTarget, 0, npc.getHating(finalTarget)); + called.addDamageHate(finalTarget, 0, npc.getHating(finalTarget)); called.getAI().setIntention(AI_INTENTION_ATTACK, finalTarget); } }); diff --git a/L2J_Mobius_CT_2.4_Epilogue/java/org/l2jmobius/gameserver/model/actor/instance/DefenderInstance.java b/L2J_Mobius_CT_2.4_Epilogue/java/org/l2jmobius/gameserver/model/actor/instance/DefenderInstance.java index 6b94a11b0f..730645dd90 100644 --- a/L2J_Mobius_CT_2.4_Epilogue/java/org/l2jmobius/gameserver/model/actor/instance/DefenderInstance.java +++ b/L2J_Mobius_CT_2.4_Epilogue/java/org/l2jmobius/gameserver/model/actor/instance/DefenderInstance.java @@ -190,7 +190,9 @@ public class DefenderInstance extends Attackable if (((_fort != null) && _fort.getZone().isActive()) || ((_castle != null) && _castle.getZone().isActive()) || ((_hall != null) && _hall.getSiegeZone().isActive())) { final int activeSiegeId = (_fort != null ? _fort.getResidenceId() : (_castle != null ? _castle.getResidenceId() : (_hall != null ? _hall.getId() : 0))); - if ((player != null) && (((player.getSiegeState() == 2) && player.isRegisteredOnThisSiegeField(activeSiegeId)) || ((player.getSiegeState() == 1) && TerritoryWarManager.getInstance().isAllyField(player, activeSiegeId)))) + + // Do not add hate on defenders. + if ((player.getSiegeState() == 2) && player.isRegisteredOnThisSiegeField(activeSiegeId)) { return; } diff --git a/L2J_Mobius_CT_2.6_HighFive/dist/game/data/scripts/ai/others/SiegeGuards.java b/L2J_Mobius_CT_2.6_HighFive/dist/game/data/scripts/ai/others/SiegeGuards.java index 2605cd604b..174255624f 100644 --- a/L2J_Mobius_CT_2.6_HighFive/dist/game/data/scripts/ai/others/SiegeGuards.java +++ b/L2J_Mobius_CT_2.6_HighFive/dist/game/data/scripts/ai/others/SiegeGuards.java @@ -20,7 +20,6 @@ import java.util.List; 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; @@ -29,7 +28,7 @@ import org.l2jmobius.gameserver.model.WorldObject; import org.l2jmobius.gameserver.model.actor.Attackable; import org.l2jmobius.gameserver.model.actor.Creature; import org.l2jmobius.gameserver.model.actor.Npc; -import org.l2jmobius.gameserver.model.actor.Summon; +import org.l2jmobius.gameserver.model.actor.Playable; import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; import org.l2jmobius.gameserver.model.entity.Castle; import org.l2jmobius.gameserver.model.entity.Fort; @@ -154,44 +153,52 @@ public class SiegeGuards extends AbstractNpcAI final List guards = RESIDENCE_GUARD_MAP[_residenceId]; for (Npc guard : guards) { - if (guard == null) + // Should never happen. + if ((guard == null) || !guard.isAttackable()) { continue; } + // Remove dead guards. if (guard.isDead()) { guards.remove(guard); continue; } - final WorldObject target = guard.getTarget(); - if (!guard.isInCombat() || (target == null) || (guard.calculateDistance2D(target) > guard.getAggroRange()) || (target.isPlayer() && target.getActingPlayer().isInvul())) + // Skip if guard is currently attacking. + if (guard.isInCombat()) { - for (Creature nearby : World.getInstance().getVisibleObjectsInRange(guard, Creature.class, guard.getAggroRange())) + continue; + } + + // Skip if guard has an active target (not dead/invis/invul and is within range). + final WorldObject target = guard.getTarget(); + final Creature targetCreature = (target != null) && target.isCreature() ? (Creature) target : null; + if ((targetCreature != null) && !targetCreature.isDead() && !targetCreature.isInvisible() && !targetCreature.isInvul() && (guard.calculateDistance2D(targetCreature) < guard.getAggroRange())) + { + continue; + } + + // Iterate all players/summons within aggro range... + for (Playable nearby : World.getInstance().getVisibleObjectsInRange(guard, Playable.class, guard.getAggroRange())) + { + // Do not attack players/summons who are dead/invis/invul or cannot be seen. + if (nearby.isDead() || nearby.isInvisible() || nearby.isInvul() || !GeoEngine.getInstance().canSeeTarget(guard, nearby)) { - if (nearby.isPlayable() && GeoEngine.getInstance().canSeeTarget(guard, nearby)) - { - 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))) - { - // 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 - } - } + continue; } + + // Do not attack defenders who are registered to this castle. + final PlayerInstance player = nearby.getActingPlayer(); + if ((player.getSiegeState() == 2) && player.isRegisteredOnThisSiegeField(guard.getScriptValue())) + { + continue; + } + + // Attack the target and stop searching. + ((Attackable) guard).addDamageHate(nearby, 0, 999); + break; } } diff --git a/L2J_Mobius_CT_2.6_HighFive/java/org/l2jmobius/gameserver/ai/AttackableAI.java b/L2J_Mobius_CT_2.6_HighFive/java/org/l2jmobius/gameserver/ai/AttackableAI.java index 598eca925f..8fbd535b61 100644 --- a/L2J_Mobius_CT_2.6_HighFive/java/org/l2jmobius/gameserver/ai/AttackableAI.java +++ b/L2J_Mobius_CT_2.6_HighFive/java/org/l2jmobius/gameserver/ai/AttackableAI.java @@ -859,7 +859,7 @@ public class AttackableAI extends CreatureAI } if (targetExistsInAttackByList) { - World.getInstance().forEachVisibleObjectInRange(npc, Npc.class, factionRange, called -> + World.getInstance().forEachVisibleObjectInRange(npc, Attackable.class, factionRange, called -> { // Don't call dead npcs, npcs without ai or npcs which are too far away. if (called.isDead() || !called.hasAI() || (Math.abs(finalTarget.getZ() - called.getZ()) > 600)) @@ -895,9 +895,9 @@ public class AttackableAI extends CreatureAI called.getAI().notifyEvent(CtrlEvent.EVT_AGGRESSION, finalTarget, 1); EventDispatcher.getInstance().notifyEventAsync(new OnAttackableFactionCall(called, getActiveChar(), finalTarget.getActingPlayer(), finalTarget.isSummon()), called); } - else if (called.isAttackable() && (called.getAI()._intention != AI_INTENTION_ATTACK)) + else if (called.getAI()._intention != AI_INTENTION_ATTACK) { - ((Attackable) called).addDamageHate(finalTarget, 0, npc.getHating(finalTarget)); + called.addDamageHate(finalTarget, 0, npc.getHating(finalTarget)); called.getAI().setIntention(AI_INTENTION_ATTACK, finalTarget); } }); diff --git a/L2J_Mobius_CT_2.6_HighFive/java/org/l2jmobius/gameserver/model/actor/instance/DefenderInstance.java b/L2J_Mobius_CT_2.6_HighFive/java/org/l2jmobius/gameserver/model/actor/instance/DefenderInstance.java index 6b94a11b0f..730645dd90 100644 --- a/L2J_Mobius_CT_2.6_HighFive/java/org/l2jmobius/gameserver/model/actor/instance/DefenderInstance.java +++ b/L2J_Mobius_CT_2.6_HighFive/java/org/l2jmobius/gameserver/model/actor/instance/DefenderInstance.java @@ -190,7 +190,9 @@ public class DefenderInstance extends Attackable if (((_fort != null) && _fort.getZone().isActive()) || ((_castle != null) && _castle.getZone().isActive()) || ((_hall != null) && _hall.getSiegeZone().isActive())) { final int activeSiegeId = (_fort != null ? _fort.getResidenceId() : (_castle != null ? _castle.getResidenceId() : (_hall != null ? _hall.getId() : 0))); - if ((player != null) && (((player.getSiegeState() == 2) && player.isRegisteredOnThisSiegeField(activeSiegeId)) || ((player.getSiegeState() == 1) && TerritoryWarManager.getInstance().isAllyField(player, activeSiegeId)))) + + // Do not add hate on defenders. + if ((player.getSiegeState() == 2) && player.isRegisteredOnThisSiegeField(activeSiegeId)) { return; } diff --git a/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/scripts/ai/others/SiegeGuards.java b/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/scripts/ai/others/SiegeGuards.java index f8bd77161f..74ac32d395 100644 --- a/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/scripts/ai/others/SiegeGuards.java +++ b/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/scripts/ai/others/SiegeGuards.java @@ -20,7 +20,6 @@ import java.util.List; 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; @@ -28,7 +27,7 @@ import org.l2jmobius.gameserver.model.WorldObject; import org.l2jmobius.gameserver.model.actor.Attackable; import org.l2jmobius.gameserver.model.actor.Creature; import org.l2jmobius.gameserver.model.actor.Npc; -import org.l2jmobius.gameserver.model.actor.Summon; +import org.l2jmobius.gameserver.model.actor.Playable; import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; import org.l2jmobius.gameserver.model.entity.Castle; import org.l2jmobius.gameserver.model.entity.Fort; @@ -118,44 +117,52 @@ public class SiegeGuards extends AbstractNpcAI final List guards = RESIDENCE_GUARD_MAP[_residenceId]; for (Npc guard : guards) { - if (guard == null) + // Should never happen. + if ((guard == null) || !guard.isAttackable()) { continue; } + // Remove dead guards. if (guard.isDead()) { guards.remove(guard); continue; } - final WorldObject target = guard.getTarget(); - if (!guard.isInCombat() || (target == null) || (guard.calculateDistance2D(target) > guard.getAggroRange()) || target.isInvul()) + // Skip if guard is currently attacking. + if (guard.isInCombat()) { - for (Creature nearby : World.getInstance().getVisibleObjectsInRange(guard, Creature.class, guard.getAggroRange())) + continue; + } + + // Skip if guard has an active target (not dead/invis/invul and is within range). + final WorldObject target = guard.getTarget(); + final Creature targetCreature = (target != null) && target.isCreature() ? (Creature) target : null; + if ((targetCreature != null) && !targetCreature.isDead() && !targetCreature.isInvisible() && !targetCreature.isInvul() && (guard.calculateDistance2D(targetCreature) < guard.getAggroRange())) + { + continue; + } + + // Iterate all players/summons within aggro range... + for (Playable nearby : World.getInstance().getVisibleObjectsInRange(guard, Playable.class, guard.getAggroRange())) + { + // Do not attack players/summons who are dead/invis/invul or cannot be seen. + if (nearby.isDead() || nearby.isInvisible() || nearby.isInvul() || !GeoEngine.getInstance().canSeeTarget(guard, nearby)) { - if (nearby.isPlayable() && GeoEngine.getInstance().canSeeTarget(guard, nearby)) - { - 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))) - { - // 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 - } - } + continue; } + + // Do not attack defenders who are registered to this castle. + final PlayerInstance player = nearby.getActingPlayer(); + if ((player.getSiegeState() == 2) && player.isRegisteredOnThisSiegeField(guard.getScriptValue())) + { + continue; + } + + // Attack the target and stop searching. + ((Attackable) guard).addDamageHate(nearby, 0, 999); + break; } } diff --git a/L2J_Mobius_Classic_2.0_Saviors/java/org/l2jmobius/gameserver/ai/AttackableAI.java b/L2J_Mobius_Classic_2.0_Saviors/java/org/l2jmobius/gameserver/ai/AttackableAI.java index 2aaa69961c..75db827845 100644 --- a/L2J_Mobius_Classic_2.0_Saviors/java/org/l2jmobius/gameserver/ai/AttackableAI.java +++ b/L2J_Mobius_Classic_2.0_Saviors/java/org/l2jmobius/gameserver/ai/AttackableAI.java @@ -40,7 +40,6 @@ import org.l2jmobius.gameserver.model.World; import org.l2jmobius.gameserver.model.WorldObject; import org.l2jmobius.gameserver.model.actor.Attackable; import org.l2jmobius.gameserver.model.actor.Creature; -import org.l2jmobius.gameserver.model.actor.Npc; import org.l2jmobius.gameserver.model.actor.Playable; import org.l2jmobius.gameserver.model.actor.instance.DefenderInstance; import org.l2jmobius.gameserver.model.actor.instance.GrandBossInstance; @@ -711,7 +710,7 @@ public class AttackableAI extends CreatureAI } if (targetExistsInAttackByList) { - World.getInstance().forEachVisibleObjectInRange(npc, Npc.class, factionRange, called -> + World.getInstance().forEachVisibleObjectInRange(npc, Attackable.class, factionRange, called -> { // Don't call dead npcs, npcs without ai or npcs which are too far away. if (called.isDead() || !called.hasAI() || (Math.abs(finalTarget.getZ() - called.getZ()) > 600)) @@ -736,9 +735,9 @@ public class AttackableAI extends CreatureAI called.getAI().notifyEvent(CtrlEvent.EVT_AGGRESSION, finalTarget, 1); EventDispatcher.getInstance().notifyEventAsync(new OnAttackableFactionCall(called, getActiveChar(), finalTarget.getActingPlayer(), finalTarget.isSummon()), called); } - else if (called.isAttackable() && (called.getAI()._intention != CtrlIntention.AI_INTENTION_ATTACK)) + else if (called.getAI()._intention != CtrlIntention.AI_INTENTION_ATTACK) { - ((Attackable) called).addDamageHate(finalTarget, 0, npc.getHating(finalTarget)); + called.addDamageHate(finalTarget, 0, npc.getHating(finalTarget)); called.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, finalTarget); } }); diff --git a/L2J_Mobius_Classic_2.0_Saviors/java/org/l2jmobius/gameserver/model/actor/instance/DefenderInstance.java b/L2J_Mobius_Classic_2.0_Saviors/java/org/l2jmobius/gameserver/model/actor/instance/DefenderInstance.java index c544782ef2..b882c183a6 100644 --- a/L2J_Mobius_Classic_2.0_Saviors/java/org/l2jmobius/gameserver/model/actor/instance/DefenderInstance.java +++ b/L2J_Mobius_Classic_2.0_Saviors/java/org/l2jmobius/gameserver/model/actor/instance/DefenderInstance.java @@ -215,7 +215,9 @@ public class DefenderInstance extends Attackable if (((_fort != null) && _fort.getZone().isActive()) || ((_castle != null) && _castle.getZone().isActive())) { final int activeSiegeId = (_fort != null) ? _fort.getResidenceId() : _castle.getResidenceId(); - if ((player != null) && (((player.getSiegeState() == 2) && player.isRegisteredOnThisSiegeField(activeSiegeId)) || ((player.getSiegeState() == 1)))) + + // Do not add hate on defenders. + if ((player.getSiegeState() == 2) && player.isRegisteredOnThisSiegeField(activeSiegeId)) { return; } diff --git a/L2J_Mobius_Classic_2.1_Zaken/dist/game/data/scripts/ai/others/SiegeGuards.java b/L2J_Mobius_Classic_2.1_Zaken/dist/game/data/scripts/ai/others/SiegeGuards.java index f8bd77161f..74ac32d395 100644 --- a/L2J_Mobius_Classic_2.1_Zaken/dist/game/data/scripts/ai/others/SiegeGuards.java +++ b/L2J_Mobius_Classic_2.1_Zaken/dist/game/data/scripts/ai/others/SiegeGuards.java @@ -20,7 +20,6 @@ import java.util.List; 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; @@ -28,7 +27,7 @@ import org.l2jmobius.gameserver.model.WorldObject; import org.l2jmobius.gameserver.model.actor.Attackable; import org.l2jmobius.gameserver.model.actor.Creature; import org.l2jmobius.gameserver.model.actor.Npc; -import org.l2jmobius.gameserver.model.actor.Summon; +import org.l2jmobius.gameserver.model.actor.Playable; import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; import org.l2jmobius.gameserver.model.entity.Castle; import org.l2jmobius.gameserver.model.entity.Fort; @@ -118,44 +117,52 @@ public class SiegeGuards extends AbstractNpcAI final List guards = RESIDENCE_GUARD_MAP[_residenceId]; for (Npc guard : guards) { - if (guard == null) + // Should never happen. + if ((guard == null) || !guard.isAttackable()) { continue; } + // Remove dead guards. if (guard.isDead()) { guards.remove(guard); continue; } - final WorldObject target = guard.getTarget(); - if (!guard.isInCombat() || (target == null) || (guard.calculateDistance2D(target) > guard.getAggroRange()) || target.isInvul()) + // Skip if guard is currently attacking. + if (guard.isInCombat()) { - for (Creature nearby : World.getInstance().getVisibleObjectsInRange(guard, Creature.class, guard.getAggroRange())) + continue; + } + + // Skip if guard has an active target (not dead/invis/invul and is within range). + final WorldObject target = guard.getTarget(); + final Creature targetCreature = (target != null) && target.isCreature() ? (Creature) target : null; + if ((targetCreature != null) && !targetCreature.isDead() && !targetCreature.isInvisible() && !targetCreature.isInvul() && (guard.calculateDistance2D(targetCreature) < guard.getAggroRange())) + { + continue; + } + + // Iterate all players/summons within aggro range... + for (Playable nearby : World.getInstance().getVisibleObjectsInRange(guard, Playable.class, guard.getAggroRange())) + { + // Do not attack players/summons who are dead/invis/invul or cannot be seen. + if (nearby.isDead() || nearby.isInvisible() || nearby.isInvul() || !GeoEngine.getInstance().canSeeTarget(guard, nearby)) { - if (nearby.isPlayable() && GeoEngine.getInstance().canSeeTarget(guard, nearby)) - { - 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))) - { - // 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 - } - } + continue; } + + // Do not attack defenders who are registered to this castle. + final PlayerInstance player = nearby.getActingPlayer(); + if ((player.getSiegeState() == 2) && player.isRegisteredOnThisSiegeField(guard.getScriptValue())) + { + continue; + } + + // Attack the target and stop searching. + ((Attackable) guard).addDamageHate(nearby, 0, 999); + break; } } diff --git a/L2J_Mobius_Classic_2.1_Zaken/java/org/l2jmobius/gameserver/ai/AttackableAI.java b/L2J_Mobius_Classic_2.1_Zaken/java/org/l2jmobius/gameserver/ai/AttackableAI.java index 2aaa69961c..75db827845 100644 --- a/L2J_Mobius_Classic_2.1_Zaken/java/org/l2jmobius/gameserver/ai/AttackableAI.java +++ b/L2J_Mobius_Classic_2.1_Zaken/java/org/l2jmobius/gameserver/ai/AttackableAI.java @@ -40,7 +40,6 @@ import org.l2jmobius.gameserver.model.World; import org.l2jmobius.gameserver.model.WorldObject; import org.l2jmobius.gameserver.model.actor.Attackable; import org.l2jmobius.gameserver.model.actor.Creature; -import org.l2jmobius.gameserver.model.actor.Npc; import org.l2jmobius.gameserver.model.actor.Playable; import org.l2jmobius.gameserver.model.actor.instance.DefenderInstance; import org.l2jmobius.gameserver.model.actor.instance.GrandBossInstance; @@ -711,7 +710,7 @@ public class AttackableAI extends CreatureAI } if (targetExistsInAttackByList) { - World.getInstance().forEachVisibleObjectInRange(npc, Npc.class, factionRange, called -> + World.getInstance().forEachVisibleObjectInRange(npc, Attackable.class, factionRange, called -> { // Don't call dead npcs, npcs without ai or npcs which are too far away. if (called.isDead() || !called.hasAI() || (Math.abs(finalTarget.getZ() - called.getZ()) > 600)) @@ -736,9 +735,9 @@ public class AttackableAI extends CreatureAI called.getAI().notifyEvent(CtrlEvent.EVT_AGGRESSION, finalTarget, 1); EventDispatcher.getInstance().notifyEventAsync(new OnAttackableFactionCall(called, getActiveChar(), finalTarget.getActingPlayer(), finalTarget.isSummon()), called); } - else if (called.isAttackable() && (called.getAI()._intention != CtrlIntention.AI_INTENTION_ATTACK)) + else if (called.getAI()._intention != CtrlIntention.AI_INTENTION_ATTACK) { - ((Attackable) called).addDamageHate(finalTarget, 0, npc.getHating(finalTarget)); + called.addDamageHate(finalTarget, 0, npc.getHating(finalTarget)); called.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, finalTarget); } }); diff --git a/L2J_Mobius_Classic_2.1_Zaken/java/org/l2jmobius/gameserver/model/actor/instance/DefenderInstance.java b/L2J_Mobius_Classic_2.1_Zaken/java/org/l2jmobius/gameserver/model/actor/instance/DefenderInstance.java index c544782ef2..b882c183a6 100644 --- a/L2J_Mobius_Classic_2.1_Zaken/java/org/l2jmobius/gameserver/model/actor/instance/DefenderInstance.java +++ b/L2J_Mobius_Classic_2.1_Zaken/java/org/l2jmobius/gameserver/model/actor/instance/DefenderInstance.java @@ -215,7 +215,9 @@ public class DefenderInstance extends Attackable if (((_fort != null) && _fort.getZone().isActive()) || ((_castle != null) && _castle.getZone().isActive())) { final int activeSiegeId = (_fort != null) ? _fort.getResidenceId() : _castle.getResidenceId(); - if ((player != null) && (((player.getSiegeState() == 2) && player.isRegisteredOnThisSiegeField(activeSiegeId)) || ((player.getSiegeState() == 1)))) + + // Do not add hate on defenders. + if ((player.getSiegeState() == 2) && player.isRegisteredOnThisSiegeField(activeSiegeId)) { return; } diff --git a/L2J_Mobius_Classic_2.2_Antharas/dist/game/data/scripts/ai/others/SiegeGuards.java b/L2J_Mobius_Classic_2.2_Antharas/dist/game/data/scripts/ai/others/SiegeGuards.java index f8bd77161f..74ac32d395 100644 --- a/L2J_Mobius_Classic_2.2_Antharas/dist/game/data/scripts/ai/others/SiegeGuards.java +++ b/L2J_Mobius_Classic_2.2_Antharas/dist/game/data/scripts/ai/others/SiegeGuards.java @@ -20,7 +20,6 @@ import java.util.List; 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; @@ -28,7 +27,7 @@ import org.l2jmobius.gameserver.model.WorldObject; import org.l2jmobius.gameserver.model.actor.Attackable; import org.l2jmobius.gameserver.model.actor.Creature; import org.l2jmobius.gameserver.model.actor.Npc; -import org.l2jmobius.gameserver.model.actor.Summon; +import org.l2jmobius.gameserver.model.actor.Playable; import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; import org.l2jmobius.gameserver.model.entity.Castle; import org.l2jmobius.gameserver.model.entity.Fort; @@ -118,44 +117,52 @@ public class SiegeGuards extends AbstractNpcAI final List guards = RESIDENCE_GUARD_MAP[_residenceId]; for (Npc guard : guards) { - if (guard == null) + // Should never happen. + if ((guard == null) || !guard.isAttackable()) { continue; } + // Remove dead guards. if (guard.isDead()) { guards.remove(guard); continue; } - final WorldObject target = guard.getTarget(); - if (!guard.isInCombat() || (target == null) || (guard.calculateDistance2D(target) > guard.getAggroRange()) || target.isInvul()) + // Skip if guard is currently attacking. + if (guard.isInCombat()) { - for (Creature nearby : World.getInstance().getVisibleObjectsInRange(guard, Creature.class, guard.getAggroRange())) + continue; + } + + // Skip if guard has an active target (not dead/invis/invul and is within range). + final WorldObject target = guard.getTarget(); + final Creature targetCreature = (target != null) && target.isCreature() ? (Creature) target : null; + if ((targetCreature != null) && !targetCreature.isDead() && !targetCreature.isInvisible() && !targetCreature.isInvul() && (guard.calculateDistance2D(targetCreature) < guard.getAggroRange())) + { + continue; + } + + // Iterate all players/summons within aggro range... + for (Playable nearby : World.getInstance().getVisibleObjectsInRange(guard, Playable.class, guard.getAggroRange())) + { + // Do not attack players/summons who are dead/invis/invul or cannot be seen. + if (nearby.isDead() || nearby.isInvisible() || nearby.isInvul() || !GeoEngine.getInstance().canSeeTarget(guard, nearby)) { - if (nearby.isPlayable() && GeoEngine.getInstance().canSeeTarget(guard, nearby)) - { - 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))) - { - // 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 - } - } + continue; } + + // Do not attack defenders who are registered to this castle. + final PlayerInstance player = nearby.getActingPlayer(); + if ((player.getSiegeState() == 2) && player.isRegisteredOnThisSiegeField(guard.getScriptValue())) + { + continue; + } + + // Attack the target and stop searching. + ((Attackable) guard).addDamageHate(nearby, 0, 999); + break; } } diff --git a/L2J_Mobius_Classic_2.2_Antharas/java/org/l2jmobius/gameserver/ai/AttackableAI.java b/L2J_Mobius_Classic_2.2_Antharas/java/org/l2jmobius/gameserver/ai/AttackableAI.java index 2aaa69961c..75db827845 100644 --- a/L2J_Mobius_Classic_2.2_Antharas/java/org/l2jmobius/gameserver/ai/AttackableAI.java +++ b/L2J_Mobius_Classic_2.2_Antharas/java/org/l2jmobius/gameserver/ai/AttackableAI.java @@ -40,7 +40,6 @@ import org.l2jmobius.gameserver.model.World; import org.l2jmobius.gameserver.model.WorldObject; import org.l2jmobius.gameserver.model.actor.Attackable; import org.l2jmobius.gameserver.model.actor.Creature; -import org.l2jmobius.gameserver.model.actor.Npc; import org.l2jmobius.gameserver.model.actor.Playable; import org.l2jmobius.gameserver.model.actor.instance.DefenderInstance; import org.l2jmobius.gameserver.model.actor.instance.GrandBossInstance; @@ -711,7 +710,7 @@ public class AttackableAI extends CreatureAI } if (targetExistsInAttackByList) { - World.getInstance().forEachVisibleObjectInRange(npc, Npc.class, factionRange, called -> + World.getInstance().forEachVisibleObjectInRange(npc, Attackable.class, factionRange, called -> { // Don't call dead npcs, npcs without ai or npcs which are too far away. if (called.isDead() || !called.hasAI() || (Math.abs(finalTarget.getZ() - called.getZ()) > 600)) @@ -736,9 +735,9 @@ public class AttackableAI extends CreatureAI called.getAI().notifyEvent(CtrlEvent.EVT_AGGRESSION, finalTarget, 1); EventDispatcher.getInstance().notifyEventAsync(new OnAttackableFactionCall(called, getActiveChar(), finalTarget.getActingPlayer(), finalTarget.isSummon()), called); } - else if (called.isAttackable() && (called.getAI()._intention != CtrlIntention.AI_INTENTION_ATTACK)) + else if (called.getAI()._intention != CtrlIntention.AI_INTENTION_ATTACK) { - ((Attackable) called).addDamageHate(finalTarget, 0, npc.getHating(finalTarget)); + called.addDamageHate(finalTarget, 0, npc.getHating(finalTarget)); called.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, finalTarget); } }); diff --git a/L2J_Mobius_Classic_2.2_Antharas/java/org/l2jmobius/gameserver/model/actor/instance/DefenderInstance.java b/L2J_Mobius_Classic_2.2_Antharas/java/org/l2jmobius/gameserver/model/actor/instance/DefenderInstance.java index c544782ef2..b882c183a6 100644 --- a/L2J_Mobius_Classic_2.2_Antharas/java/org/l2jmobius/gameserver/model/actor/instance/DefenderInstance.java +++ b/L2J_Mobius_Classic_2.2_Antharas/java/org/l2jmobius/gameserver/model/actor/instance/DefenderInstance.java @@ -215,7 +215,9 @@ public class DefenderInstance extends Attackable if (((_fort != null) && _fort.getZone().isActive()) || ((_castle != null) && _castle.getZone().isActive())) { final int activeSiegeId = (_fort != null) ? _fort.getResidenceId() : _castle.getResidenceId(); - if ((player != null) && (((player.getSiegeState() == 2) && player.isRegisteredOnThisSiegeField(activeSiegeId)) || ((player.getSiegeState() == 1)))) + + // Do not add hate on defenders. + if ((player.getSiegeState() == 2) && player.isRegisteredOnThisSiegeField(activeSiegeId)) { return; } diff --git a/L2J_Mobius_Classic_2.3_SevenSigns/dist/game/data/scripts/ai/others/SiegeGuards.java b/L2J_Mobius_Classic_2.3_SevenSigns/dist/game/data/scripts/ai/others/SiegeGuards.java index f8bd77161f..74ac32d395 100644 --- a/L2J_Mobius_Classic_2.3_SevenSigns/dist/game/data/scripts/ai/others/SiegeGuards.java +++ b/L2J_Mobius_Classic_2.3_SevenSigns/dist/game/data/scripts/ai/others/SiegeGuards.java @@ -20,7 +20,6 @@ import java.util.List; 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; @@ -28,7 +27,7 @@ import org.l2jmobius.gameserver.model.WorldObject; import org.l2jmobius.gameserver.model.actor.Attackable; import org.l2jmobius.gameserver.model.actor.Creature; import org.l2jmobius.gameserver.model.actor.Npc; -import org.l2jmobius.gameserver.model.actor.Summon; +import org.l2jmobius.gameserver.model.actor.Playable; import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; import org.l2jmobius.gameserver.model.entity.Castle; import org.l2jmobius.gameserver.model.entity.Fort; @@ -118,44 +117,52 @@ public class SiegeGuards extends AbstractNpcAI final List guards = RESIDENCE_GUARD_MAP[_residenceId]; for (Npc guard : guards) { - if (guard == null) + // Should never happen. + if ((guard == null) || !guard.isAttackable()) { continue; } + // Remove dead guards. if (guard.isDead()) { guards.remove(guard); continue; } - final WorldObject target = guard.getTarget(); - if (!guard.isInCombat() || (target == null) || (guard.calculateDistance2D(target) > guard.getAggroRange()) || target.isInvul()) + // Skip if guard is currently attacking. + if (guard.isInCombat()) { - for (Creature nearby : World.getInstance().getVisibleObjectsInRange(guard, Creature.class, guard.getAggroRange())) + continue; + } + + // Skip if guard has an active target (not dead/invis/invul and is within range). + final WorldObject target = guard.getTarget(); + final Creature targetCreature = (target != null) && target.isCreature() ? (Creature) target : null; + if ((targetCreature != null) && !targetCreature.isDead() && !targetCreature.isInvisible() && !targetCreature.isInvul() && (guard.calculateDistance2D(targetCreature) < guard.getAggroRange())) + { + continue; + } + + // Iterate all players/summons within aggro range... + for (Playable nearby : World.getInstance().getVisibleObjectsInRange(guard, Playable.class, guard.getAggroRange())) + { + // Do not attack players/summons who are dead/invis/invul or cannot be seen. + if (nearby.isDead() || nearby.isInvisible() || nearby.isInvul() || !GeoEngine.getInstance().canSeeTarget(guard, nearby)) { - if (nearby.isPlayable() && GeoEngine.getInstance().canSeeTarget(guard, nearby)) - { - 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))) - { - // 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 - } - } + continue; } + + // Do not attack defenders who are registered to this castle. + final PlayerInstance player = nearby.getActingPlayer(); + if ((player.getSiegeState() == 2) && player.isRegisteredOnThisSiegeField(guard.getScriptValue())) + { + continue; + } + + // Attack the target and stop searching. + ((Attackable) guard).addDamageHate(nearby, 0, 999); + break; } } diff --git a/L2J_Mobius_Classic_2.3_SevenSigns/java/org/l2jmobius/gameserver/ai/AttackableAI.java b/L2J_Mobius_Classic_2.3_SevenSigns/java/org/l2jmobius/gameserver/ai/AttackableAI.java index 2aaa69961c..75db827845 100644 --- a/L2J_Mobius_Classic_2.3_SevenSigns/java/org/l2jmobius/gameserver/ai/AttackableAI.java +++ b/L2J_Mobius_Classic_2.3_SevenSigns/java/org/l2jmobius/gameserver/ai/AttackableAI.java @@ -40,7 +40,6 @@ import org.l2jmobius.gameserver.model.World; import org.l2jmobius.gameserver.model.WorldObject; import org.l2jmobius.gameserver.model.actor.Attackable; import org.l2jmobius.gameserver.model.actor.Creature; -import org.l2jmobius.gameserver.model.actor.Npc; import org.l2jmobius.gameserver.model.actor.Playable; import org.l2jmobius.gameserver.model.actor.instance.DefenderInstance; import org.l2jmobius.gameserver.model.actor.instance.GrandBossInstance; @@ -711,7 +710,7 @@ public class AttackableAI extends CreatureAI } if (targetExistsInAttackByList) { - World.getInstance().forEachVisibleObjectInRange(npc, Npc.class, factionRange, called -> + World.getInstance().forEachVisibleObjectInRange(npc, Attackable.class, factionRange, called -> { // Don't call dead npcs, npcs without ai or npcs which are too far away. if (called.isDead() || !called.hasAI() || (Math.abs(finalTarget.getZ() - called.getZ()) > 600)) @@ -736,9 +735,9 @@ public class AttackableAI extends CreatureAI called.getAI().notifyEvent(CtrlEvent.EVT_AGGRESSION, finalTarget, 1); EventDispatcher.getInstance().notifyEventAsync(new OnAttackableFactionCall(called, getActiveChar(), finalTarget.getActingPlayer(), finalTarget.isSummon()), called); } - else if (called.isAttackable() && (called.getAI()._intention != CtrlIntention.AI_INTENTION_ATTACK)) + else if (called.getAI()._intention != CtrlIntention.AI_INTENTION_ATTACK) { - ((Attackable) called).addDamageHate(finalTarget, 0, npc.getHating(finalTarget)); + called.addDamageHate(finalTarget, 0, npc.getHating(finalTarget)); called.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, finalTarget); } }); diff --git a/L2J_Mobius_Classic_2.3_SevenSigns/java/org/l2jmobius/gameserver/model/actor/instance/DefenderInstance.java b/L2J_Mobius_Classic_2.3_SevenSigns/java/org/l2jmobius/gameserver/model/actor/instance/DefenderInstance.java index c544782ef2..b882c183a6 100644 --- a/L2J_Mobius_Classic_2.3_SevenSigns/java/org/l2jmobius/gameserver/model/actor/instance/DefenderInstance.java +++ b/L2J_Mobius_Classic_2.3_SevenSigns/java/org/l2jmobius/gameserver/model/actor/instance/DefenderInstance.java @@ -215,7 +215,9 @@ public class DefenderInstance extends Attackable if (((_fort != null) && _fort.getZone().isActive()) || ((_castle != null) && _castle.getZone().isActive())) { final int activeSiegeId = (_fort != null) ? _fort.getResidenceId() : _castle.getResidenceId(); - if ((player != null) && (((player.getSiegeState() == 2) && player.isRegisteredOnThisSiegeField(activeSiegeId)) || ((player.getSiegeState() == 1)))) + + // Do not add hate on defenders. + if ((player.getSiegeState() == 2) && player.isRegisteredOnThisSiegeField(activeSiegeId)) { return; } diff --git a/L2J_Mobius_Classic_2.4_SecretOfEmpire/dist/game/data/scripts/ai/others/SiegeGuards.java b/L2J_Mobius_Classic_2.4_SecretOfEmpire/dist/game/data/scripts/ai/others/SiegeGuards.java index f8bd77161f..74ac32d395 100644 --- a/L2J_Mobius_Classic_2.4_SecretOfEmpire/dist/game/data/scripts/ai/others/SiegeGuards.java +++ b/L2J_Mobius_Classic_2.4_SecretOfEmpire/dist/game/data/scripts/ai/others/SiegeGuards.java @@ -20,7 +20,6 @@ import java.util.List; 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; @@ -28,7 +27,7 @@ import org.l2jmobius.gameserver.model.WorldObject; import org.l2jmobius.gameserver.model.actor.Attackable; import org.l2jmobius.gameserver.model.actor.Creature; import org.l2jmobius.gameserver.model.actor.Npc; -import org.l2jmobius.gameserver.model.actor.Summon; +import org.l2jmobius.gameserver.model.actor.Playable; import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; import org.l2jmobius.gameserver.model.entity.Castle; import org.l2jmobius.gameserver.model.entity.Fort; @@ -118,44 +117,52 @@ public class SiegeGuards extends AbstractNpcAI final List guards = RESIDENCE_GUARD_MAP[_residenceId]; for (Npc guard : guards) { - if (guard == null) + // Should never happen. + if ((guard == null) || !guard.isAttackable()) { continue; } + // Remove dead guards. if (guard.isDead()) { guards.remove(guard); continue; } - final WorldObject target = guard.getTarget(); - if (!guard.isInCombat() || (target == null) || (guard.calculateDistance2D(target) > guard.getAggroRange()) || target.isInvul()) + // Skip if guard is currently attacking. + if (guard.isInCombat()) { - for (Creature nearby : World.getInstance().getVisibleObjectsInRange(guard, Creature.class, guard.getAggroRange())) + continue; + } + + // Skip if guard has an active target (not dead/invis/invul and is within range). + final WorldObject target = guard.getTarget(); + final Creature targetCreature = (target != null) && target.isCreature() ? (Creature) target : null; + if ((targetCreature != null) && !targetCreature.isDead() && !targetCreature.isInvisible() && !targetCreature.isInvul() && (guard.calculateDistance2D(targetCreature) < guard.getAggroRange())) + { + continue; + } + + // Iterate all players/summons within aggro range... + for (Playable nearby : World.getInstance().getVisibleObjectsInRange(guard, Playable.class, guard.getAggroRange())) + { + // Do not attack players/summons who are dead/invis/invul or cannot be seen. + if (nearby.isDead() || nearby.isInvisible() || nearby.isInvul() || !GeoEngine.getInstance().canSeeTarget(guard, nearby)) { - if (nearby.isPlayable() && GeoEngine.getInstance().canSeeTarget(guard, nearby)) - { - 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))) - { - // 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 - } - } + continue; } + + // Do not attack defenders who are registered to this castle. + final PlayerInstance player = nearby.getActingPlayer(); + if ((player.getSiegeState() == 2) && player.isRegisteredOnThisSiegeField(guard.getScriptValue())) + { + continue; + } + + // Attack the target and stop searching. + ((Attackable) guard).addDamageHate(nearby, 0, 999); + break; } } diff --git a/L2J_Mobius_Classic_2.4_SecretOfEmpire/java/org/l2jmobius/gameserver/ai/AttackableAI.java b/L2J_Mobius_Classic_2.4_SecretOfEmpire/java/org/l2jmobius/gameserver/ai/AttackableAI.java index 2aaa69961c..75db827845 100644 --- a/L2J_Mobius_Classic_2.4_SecretOfEmpire/java/org/l2jmobius/gameserver/ai/AttackableAI.java +++ b/L2J_Mobius_Classic_2.4_SecretOfEmpire/java/org/l2jmobius/gameserver/ai/AttackableAI.java @@ -40,7 +40,6 @@ import org.l2jmobius.gameserver.model.World; import org.l2jmobius.gameserver.model.WorldObject; import org.l2jmobius.gameserver.model.actor.Attackable; import org.l2jmobius.gameserver.model.actor.Creature; -import org.l2jmobius.gameserver.model.actor.Npc; import org.l2jmobius.gameserver.model.actor.Playable; import org.l2jmobius.gameserver.model.actor.instance.DefenderInstance; import org.l2jmobius.gameserver.model.actor.instance.GrandBossInstance; @@ -711,7 +710,7 @@ public class AttackableAI extends CreatureAI } if (targetExistsInAttackByList) { - World.getInstance().forEachVisibleObjectInRange(npc, Npc.class, factionRange, called -> + World.getInstance().forEachVisibleObjectInRange(npc, Attackable.class, factionRange, called -> { // Don't call dead npcs, npcs without ai or npcs which are too far away. if (called.isDead() || !called.hasAI() || (Math.abs(finalTarget.getZ() - called.getZ()) > 600)) @@ -736,9 +735,9 @@ public class AttackableAI extends CreatureAI called.getAI().notifyEvent(CtrlEvent.EVT_AGGRESSION, finalTarget, 1); EventDispatcher.getInstance().notifyEventAsync(new OnAttackableFactionCall(called, getActiveChar(), finalTarget.getActingPlayer(), finalTarget.isSummon()), called); } - else if (called.isAttackable() && (called.getAI()._intention != CtrlIntention.AI_INTENTION_ATTACK)) + else if (called.getAI()._intention != CtrlIntention.AI_INTENTION_ATTACK) { - ((Attackable) called).addDamageHate(finalTarget, 0, npc.getHating(finalTarget)); + called.addDamageHate(finalTarget, 0, npc.getHating(finalTarget)); called.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, finalTarget); } }); diff --git a/L2J_Mobius_Classic_2.4_SecretOfEmpire/java/org/l2jmobius/gameserver/model/actor/instance/DefenderInstance.java b/L2J_Mobius_Classic_2.4_SecretOfEmpire/java/org/l2jmobius/gameserver/model/actor/instance/DefenderInstance.java index c544782ef2..b882c183a6 100644 --- a/L2J_Mobius_Classic_2.4_SecretOfEmpire/java/org/l2jmobius/gameserver/model/actor/instance/DefenderInstance.java +++ b/L2J_Mobius_Classic_2.4_SecretOfEmpire/java/org/l2jmobius/gameserver/model/actor/instance/DefenderInstance.java @@ -215,7 +215,9 @@ public class DefenderInstance extends Attackable if (((_fort != null) && _fort.getZone().isActive()) || ((_castle != null) && _castle.getZone().isActive())) { final int activeSiegeId = (_fort != null) ? _fort.getResidenceId() : _castle.getResidenceId(); - if ((player != null) && (((player.getSiegeState() == 2) && player.isRegisteredOnThisSiegeField(activeSiegeId)) || ((player.getSiegeState() == 1)))) + + // Do not add hate on defenders. + if ((player.getSiegeState() == 2) && player.isRegisteredOnThisSiegeField(activeSiegeId)) { return; } diff --git a/L2J_Mobius_Classic_3.0_TheKamael/dist/game/data/scripts/ai/others/SiegeGuards.java b/L2J_Mobius_Classic_3.0_TheKamael/dist/game/data/scripts/ai/others/SiegeGuards.java index f8bd77161f..74ac32d395 100644 --- a/L2J_Mobius_Classic_3.0_TheKamael/dist/game/data/scripts/ai/others/SiegeGuards.java +++ b/L2J_Mobius_Classic_3.0_TheKamael/dist/game/data/scripts/ai/others/SiegeGuards.java @@ -20,7 +20,6 @@ import java.util.List; 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; @@ -28,7 +27,7 @@ import org.l2jmobius.gameserver.model.WorldObject; import org.l2jmobius.gameserver.model.actor.Attackable; import org.l2jmobius.gameserver.model.actor.Creature; import org.l2jmobius.gameserver.model.actor.Npc; -import org.l2jmobius.gameserver.model.actor.Summon; +import org.l2jmobius.gameserver.model.actor.Playable; import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; import org.l2jmobius.gameserver.model.entity.Castle; import org.l2jmobius.gameserver.model.entity.Fort; @@ -118,44 +117,52 @@ public class SiegeGuards extends AbstractNpcAI final List guards = RESIDENCE_GUARD_MAP[_residenceId]; for (Npc guard : guards) { - if (guard == null) + // Should never happen. + if ((guard == null) || !guard.isAttackable()) { continue; } + // Remove dead guards. if (guard.isDead()) { guards.remove(guard); continue; } - final WorldObject target = guard.getTarget(); - if (!guard.isInCombat() || (target == null) || (guard.calculateDistance2D(target) > guard.getAggroRange()) || target.isInvul()) + // Skip if guard is currently attacking. + if (guard.isInCombat()) { - for (Creature nearby : World.getInstance().getVisibleObjectsInRange(guard, Creature.class, guard.getAggroRange())) + continue; + } + + // Skip if guard has an active target (not dead/invis/invul and is within range). + final WorldObject target = guard.getTarget(); + final Creature targetCreature = (target != null) && target.isCreature() ? (Creature) target : null; + if ((targetCreature != null) && !targetCreature.isDead() && !targetCreature.isInvisible() && !targetCreature.isInvul() && (guard.calculateDistance2D(targetCreature) < guard.getAggroRange())) + { + continue; + } + + // Iterate all players/summons within aggro range... + for (Playable nearby : World.getInstance().getVisibleObjectsInRange(guard, Playable.class, guard.getAggroRange())) + { + // Do not attack players/summons who are dead/invis/invul or cannot be seen. + if (nearby.isDead() || nearby.isInvisible() || nearby.isInvul() || !GeoEngine.getInstance().canSeeTarget(guard, nearby)) { - if (nearby.isPlayable() && GeoEngine.getInstance().canSeeTarget(guard, nearby)) - { - 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))) - { - // 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 - } - } + continue; } + + // Do not attack defenders who are registered to this castle. + final PlayerInstance player = nearby.getActingPlayer(); + if ((player.getSiegeState() == 2) && player.isRegisteredOnThisSiegeField(guard.getScriptValue())) + { + continue; + } + + // Attack the target and stop searching. + ((Attackable) guard).addDamageHate(nearby, 0, 999); + break; } } diff --git a/L2J_Mobius_Classic_3.0_TheKamael/java/org/l2jmobius/gameserver/ai/AttackableAI.java b/L2J_Mobius_Classic_3.0_TheKamael/java/org/l2jmobius/gameserver/ai/AttackableAI.java index 2aaa69961c..75db827845 100644 --- a/L2J_Mobius_Classic_3.0_TheKamael/java/org/l2jmobius/gameserver/ai/AttackableAI.java +++ b/L2J_Mobius_Classic_3.0_TheKamael/java/org/l2jmobius/gameserver/ai/AttackableAI.java @@ -40,7 +40,6 @@ import org.l2jmobius.gameserver.model.World; import org.l2jmobius.gameserver.model.WorldObject; import org.l2jmobius.gameserver.model.actor.Attackable; import org.l2jmobius.gameserver.model.actor.Creature; -import org.l2jmobius.gameserver.model.actor.Npc; import org.l2jmobius.gameserver.model.actor.Playable; import org.l2jmobius.gameserver.model.actor.instance.DefenderInstance; import org.l2jmobius.gameserver.model.actor.instance.GrandBossInstance; @@ -711,7 +710,7 @@ public class AttackableAI extends CreatureAI } if (targetExistsInAttackByList) { - World.getInstance().forEachVisibleObjectInRange(npc, Npc.class, factionRange, called -> + World.getInstance().forEachVisibleObjectInRange(npc, Attackable.class, factionRange, called -> { // Don't call dead npcs, npcs without ai or npcs which are too far away. if (called.isDead() || !called.hasAI() || (Math.abs(finalTarget.getZ() - called.getZ()) > 600)) @@ -736,9 +735,9 @@ public class AttackableAI extends CreatureAI called.getAI().notifyEvent(CtrlEvent.EVT_AGGRESSION, finalTarget, 1); EventDispatcher.getInstance().notifyEventAsync(new OnAttackableFactionCall(called, getActiveChar(), finalTarget.getActingPlayer(), finalTarget.isSummon()), called); } - else if (called.isAttackable() && (called.getAI()._intention != CtrlIntention.AI_INTENTION_ATTACK)) + else if (called.getAI()._intention != CtrlIntention.AI_INTENTION_ATTACK) { - ((Attackable) called).addDamageHate(finalTarget, 0, npc.getHating(finalTarget)); + called.addDamageHate(finalTarget, 0, npc.getHating(finalTarget)); called.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, finalTarget); } }); diff --git a/L2J_Mobius_Classic_3.0_TheKamael/java/org/l2jmobius/gameserver/model/actor/instance/DefenderInstance.java b/L2J_Mobius_Classic_3.0_TheKamael/java/org/l2jmobius/gameserver/model/actor/instance/DefenderInstance.java index c544782ef2..b882c183a6 100644 --- a/L2J_Mobius_Classic_3.0_TheKamael/java/org/l2jmobius/gameserver/model/actor/instance/DefenderInstance.java +++ b/L2J_Mobius_Classic_3.0_TheKamael/java/org/l2jmobius/gameserver/model/actor/instance/DefenderInstance.java @@ -215,7 +215,9 @@ public class DefenderInstance extends Attackable if (((_fort != null) && _fort.getZone().isActive()) || ((_castle != null) && _castle.getZone().isActive())) { final int activeSiegeId = (_fort != null) ? _fort.getResidenceId() : _castle.getResidenceId(); - if ((player != null) && (((player.getSiegeState() == 2) && player.isRegisteredOnThisSiegeField(activeSiegeId)) || ((player.getSiegeState() == 1)))) + + // Do not add hate on defenders. + if ((player.getSiegeState() == 2) && player.isRegisteredOnThisSiegeField(activeSiegeId)) { return; } diff --git a/L2J_Mobius_Classic_Interlude/dist/game/data/scripts/ai/others/SiegeGuards.java b/L2J_Mobius_Classic_Interlude/dist/game/data/scripts/ai/others/SiegeGuards.java index f8bd77161f..74ac32d395 100644 --- a/L2J_Mobius_Classic_Interlude/dist/game/data/scripts/ai/others/SiegeGuards.java +++ b/L2J_Mobius_Classic_Interlude/dist/game/data/scripts/ai/others/SiegeGuards.java @@ -20,7 +20,6 @@ import java.util.List; 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; @@ -28,7 +27,7 @@ import org.l2jmobius.gameserver.model.WorldObject; import org.l2jmobius.gameserver.model.actor.Attackable; import org.l2jmobius.gameserver.model.actor.Creature; import org.l2jmobius.gameserver.model.actor.Npc; -import org.l2jmobius.gameserver.model.actor.Summon; +import org.l2jmobius.gameserver.model.actor.Playable; import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; import org.l2jmobius.gameserver.model.entity.Castle; import org.l2jmobius.gameserver.model.entity.Fort; @@ -118,44 +117,52 @@ public class SiegeGuards extends AbstractNpcAI final List guards = RESIDENCE_GUARD_MAP[_residenceId]; for (Npc guard : guards) { - if (guard == null) + // Should never happen. + if ((guard == null) || !guard.isAttackable()) { continue; } + // Remove dead guards. if (guard.isDead()) { guards.remove(guard); continue; } - final WorldObject target = guard.getTarget(); - if (!guard.isInCombat() || (target == null) || (guard.calculateDistance2D(target) > guard.getAggroRange()) || target.isInvul()) + // Skip if guard is currently attacking. + if (guard.isInCombat()) { - for (Creature nearby : World.getInstance().getVisibleObjectsInRange(guard, Creature.class, guard.getAggroRange())) + continue; + } + + // Skip if guard has an active target (not dead/invis/invul and is within range). + final WorldObject target = guard.getTarget(); + final Creature targetCreature = (target != null) && target.isCreature() ? (Creature) target : null; + if ((targetCreature != null) && !targetCreature.isDead() && !targetCreature.isInvisible() && !targetCreature.isInvul() && (guard.calculateDistance2D(targetCreature) < guard.getAggroRange())) + { + continue; + } + + // Iterate all players/summons within aggro range... + for (Playable nearby : World.getInstance().getVisibleObjectsInRange(guard, Playable.class, guard.getAggroRange())) + { + // Do not attack players/summons who are dead/invis/invul or cannot be seen. + if (nearby.isDead() || nearby.isInvisible() || nearby.isInvul() || !GeoEngine.getInstance().canSeeTarget(guard, nearby)) { - if (nearby.isPlayable() && GeoEngine.getInstance().canSeeTarget(guard, nearby)) - { - 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))) - { - // 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 - } - } + continue; } + + // Do not attack defenders who are registered to this castle. + final PlayerInstance player = nearby.getActingPlayer(); + if ((player.getSiegeState() == 2) && player.isRegisteredOnThisSiegeField(guard.getScriptValue())) + { + continue; + } + + // Attack the target and stop searching. + ((Attackable) guard).addDamageHate(nearby, 0, 999); + break; } } diff --git a/L2J_Mobius_Classic_Interlude/java/org/l2jmobius/gameserver/ai/AttackableAI.java b/L2J_Mobius_Classic_Interlude/java/org/l2jmobius/gameserver/ai/AttackableAI.java index fa68a326d2..534abca6dd 100644 --- a/L2J_Mobius_Classic_Interlude/java/org/l2jmobius/gameserver/ai/AttackableAI.java +++ b/L2J_Mobius_Classic_Interlude/java/org/l2jmobius/gameserver/ai/AttackableAI.java @@ -40,7 +40,6 @@ import org.l2jmobius.gameserver.model.World; import org.l2jmobius.gameserver.model.WorldObject; import org.l2jmobius.gameserver.model.actor.Attackable; import org.l2jmobius.gameserver.model.actor.Creature; -import org.l2jmobius.gameserver.model.actor.Npc; import org.l2jmobius.gameserver.model.actor.Playable; import org.l2jmobius.gameserver.model.actor.instance.DefenderInstance; import org.l2jmobius.gameserver.model.actor.instance.GrandBossInstance; @@ -711,7 +710,7 @@ public class AttackableAI extends CreatureAI } if (targetExistsInAttackByList) { - World.getInstance().forEachVisibleObjectInRange(npc, Npc.class, factionRange, called -> + World.getInstance().forEachVisibleObjectInRange(npc, Attackable.class, factionRange, called -> { // Don't call dead npcs, npcs without ai or npcs which are too far away. if (called.isDead() || !called.hasAI() || (Math.abs(finalTarget.getZ() - called.getZ()) > 600)) @@ -736,9 +735,9 @@ public class AttackableAI extends CreatureAI called.getAI().notifyEvent(CtrlEvent.EVT_AGGRESSION, finalTarget, 1); EventDispatcher.getInstance().notifyEventAsync(new OnAttackableFactionCall(called, getActiveChar(), finalTarget.getActingPlayer(), finalTarget.isSummon()), called); } - else if (called.isAttackable() && (called.getAI()._intention != CtrlIntention.AI_INTENTION_ATTACK)) + else if (called.getAI()._intention != CtrlIntention.AI_INTENTION_ATTACK) { - ((Attackable) called).addDamageHate(finalTarget, 0, npc.getHating(finalTarget)); + called.addDamageHate(finalTarget, 0, npc.getHating(finalTarget)); called.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, finalTarget); } }); diff --git a/L2J_Mobius_Classic_Interlude/java/org/l2jmobius/gameserver/model/actor/instance/DefenderInstance.java b/L2J_Mobius_Classic_Interlude/java/org/l2jmobius/gameserver/model/actor/instance/DefenderInstance.java index c544782ef2..b882c183a6 100644 --- a/L2J_Mobius_Classic_Interlude/java/org/l2jmobius/gameserver/model/actor/instance/DefenderInstance.java +++ b/L2J_Mobius_Classic_Interlude/java/org/l2jmobius/gameserver/model/actor/instance/DefenderInstance.java @@ -215,7 +215,9 @@ public class DefenderInstance extends Attackable if (((_fort != null) && _fort.getZone().isActive()) || ((_castle != null) && _castle.getZone().isActive())) { final int activeSiegeId = (_fort != null) ? _fort.getResidenceId() : _castle.getResidenceId(); - if ((player != null) && (((player.getSiegeState() == 2) && player.isRegisteredOnThisSiegeField(activeSiegeId)) || ((player.getSiegeState() == 1)))) + + // Do not add hate on defenders. + if ((player.getSiegeState() == 2) && player.isRegisteredOnThisSiegeField(activeSiegeId)) { return; }