From 05af97be4264980207d81ff4de9f729f32236cf1 Mon Sep 17 00:00:00 2001 From: MobiusDevelopment <8391001+MobiusDevelopment@users.noreply.github.com> Date: Sun, 28 Jun 2020 00:57:45 +0000 Subject: [PATCH] Fixed lag coming from siege guards during siege. Contributed by Sahar. --- .../l2jmobius/gameserver/ai/AttackableAI.java | 38 ++++++++++--- .../l2jmobius/gameserver/ai/AttackableAI.java | 38 ++++++++++--- .../l2jmobius/gameserver/ai/AttackableAI.java | 38 ++++++++++--- .../l2jmobius/gameserver/ai/AttackableAI.java | 38 ++++++++++--- .../l2jmobius/gameserver/ai/AttackableAI.java | 38 ++++++++++--- .../l2jmobius/gameserver/ai/AttackableAI.java | 38 ++++++++++--- .../l2jmobius/gameserver/ai/AttackableAI.java | 38 ++++++++++--- .../l2jmobius/gameserver/ai/AttackableAI.java | 38 ++++++++++--- .../l2jmobius/gameserver/ai/AttackableAI.java | 56 +++++++++++++------ .../l2jmobius/gameserver/ai/AttackableAI.java | 56 +++++++++++++------ .../l2jmobius/gameserver/ai/AttackableAI.java | 38 ++++++++++--- .../l2jmobius/gameserver/ai/AttackableAI.java | 38 ++++++++++--- .../l2jmobius/gameserver/ai/AttackableAI.java | 38 ++++++++++--- .../l2jmobius/gameserver/ai/AttackableAI.java | 38 ++++++++++--- .../l2jmobius/gameserver/ai/AttackableAI.java | 38 ++++++++++--- .../l2jmobius/gameserver/ai/AttackableAI.java | 38 ++++++++++--- .../l2jmobius/gameserver/ai/AttackableAI.java | 38 ++++++++++--- 17 files changed, 528 insertions(+), 154 deletions(-) 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 2f4d9f423c..2aaa69961c 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 @@ -20,6 +20,7 @@ import static org.l2jmobius.gameserver.ai.CtrlIntention.AI_INTENTION_ACTIVE; import static org.l2jmobius.gameserver.ai.CtrlIntention.AI_INTENTION_ATTACK; import static org.l2jmobius.gameserver.ai.CtrlIntention.AI_INTENTION_IDLE; +import java.lang.ref.WeakReference; import java.util.Comparator; import java.util.List; import java.util.Set; @@ -697,16 +698,37 @@ public class AttackableAI extends CreatureAI try { final Creature finalTarget = target; - World.getInstance().forEachVisibleObjectInRange(npc, Npc.class, factionRange, called -> + + // Call friendly npcs for help only if this NPC was attacked by the target creature. + boolean targetExistsInAttackByList = false; + for (final WeakReference reference : npc.getAttackByList()) { - if (!getActiveChar().getTemplate().isClan(called.getTemplate().getClans())) + if (reference.get() == finalTarget) { - return; + targetExistsInAttackByList = true; + break; } - - // Check if the WorldObject is inside the Faction Range of the actor - if (called.hasAI() && (Math.abs(finalTarget.getZ() - called.getZ()) < 600) && npc.getAttackByList().stream().anyMatch(o -> o.get() == finalTarget) && ((called.getAI()._intention == CtrlIntention.AI_INTENTION_IDLE) || (called.getAI()._intention == CtrlIntention.AI_INTENTION_ACTIVE))) + } + if (targetExistsInAttackByList) + { + World.getInstance().forEachVisibleObjectInRange(npc, Npc.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)) + { + return; + } + // Don't call npcs who are already doing some action (e.g. attacking, casting). + if ((called.getAI()._intention != CtrlIntention.AI_INTENTION_IDLE) && (called.getAI()._intention != CtrlIntention.AI_INTENTION_ACTIVE)) + { + return; + } + // Don't call npcs who aren't in the same clan. + if (!getActiveChar().getTemplate().isClan(called.getTemplate().getClans())) + { + return; + } + if (finalTarget.isPlayable()) { // By default, when a faction member calls for help, attack the caller's attacker. @@ -719,8 +741,8 @@ public class AttackableAI extends CreatureAI ((Attackable) called).addDamageHate(finalTarget, 0, npc.getHating(finalTarget)); called.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, finalTarget); } - } - }); + }); + } } catch (NullPointerException e) { 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 2f4d9f423c..2aaa69961c 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 @@ -20,6 +20,7 @@ import static org.l2jmobius.gameserver.ai.CtrlIntention.AI_INTENTION_ACTIVE; import static org.l2jmobius.gameserver.ai.CtrlIntention.AI_INTENTION_ATTACK; import static org.l2jmobius.gameserver.ai.CtrlIntention.AI_INTENTION_IDLE; +import java.lang.ref.WeakReference; import java.util.Comparator; import java.util.List; import java.util.Set; @@ -697,16 +698,37 @@ public class AttackableAI extends CreatureAI try { final Creature finalTarget = target; - World.getInstance().forEachVisibleObjectInRange(npc, Npc.class, factionRange, called -> + + // Call friendly npcs for help only if this NPC was attacked by the target creature. + boolean targetExistsInAttackByList = false; + for (final WeakReference reference : npc.getAttackByList()) { - if (!getActiveChar().getTemplate().isClan(called.getTemplate().getClans())) + if (reference.get() == finalTarget) { - return; + targetExistsInAttackByList = true; + break; } - - // Check if the WorldObject is inside the Faction Range of the actor - if (called.hasAI() && (Math.abs(finalTarget.getZ() - called.getZ()) < 600) && npc.getAttackByList().stream().anyMatch(o -> o.get() == finalTarget) && ((called.getAI()._intention == CtrlIntention.AI_INTENTION_IDLE) || (called.getAI()._intention == CtrlIntention.AI_INTENTION_ACTIVE))) + } + if (targetExistsInAttackByList) + { + World.getInstance().forEachVisibleObjectInRange(npc, Npc.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)) + { + return; + } + // Don't call npcs who are already doing some action (e.g. attacking, casting). + if ((called.getAI()._intention != CtrlIntention.AI_INTENTION_IDLE) && (called.getAI()._intention != CtrlIntention.AI_INTENTION_ACTIVE)) + { + return; + } + // Don't call npcs who aren't in the same clan. + if (!getActiveChar().getTemplate().isClan(called.getTemplate().getClans())) + { + return; + } + if (finalTarget.isPlayable()) { // By default, when a faction member calls for help, attack the caller's attacker. @@ -719,8 +741,8 @@ public class AttackableAI extends CreatureAI ((Attackable) called).addDamageHate(finalTarget, 0, npc.getHating(finalTarget)); called.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, finalTarget); } - } - }); + }); + } } catch (NullPointerException e) { 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 2f4d9f423c..2aaa69961c 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 @@ -20,6 +20,7 @@ import static org.l2jmobius.gameserver.ai.CtrlIntention.AI_INTENTION_ACTIVE; import static org.l2jmobius.gameserver.ai.CtrlIntention.AI_INTENTION_ATTACK; import static org.l2jmobius.gameserver.ai.CtrlIntention.AI_INTENTION_IDLE; +import java.lang.ref.WeakReference; import java.util.Comparator; import java.util.List; import java.util.Set; @@ -697,16 +698,37 @@ public class AttackableAI extends CreatureAI try { final Creature finalTarget = target; - World.getInstance().forEachVisibleObjectInRange(npc, Npc.class, factionRange, called -> + + // Call friendly npcs for help only if this NPC was attacked by the target creature. + boolean targetExistsInAttackByList = false; + for (final WeakReference reference : npc.getAttackByList()) { - if (!getActiveChar().getTemplate().isClan(called.getTemplate().getClans())) + if (reference.get() == finalTarget) { - return; + targetExistsInAttackByList = true; + break; } - - // Check if the WorldObject is inside the Faction Range of the actor - if (called.hasAI() && (Math.abs(finalTarget.getZ() - called.getZ()) < 600) && npc.getAttackByList().stream().anyMatch(o -> o.get() == finalTarget) && ((called.getAI()._intention == CtrlIntention.AI_INTENTION_IDLE) || (called.getAI()._intention == CtrlIntention.AI_INTENTION_ACTIVE))) + } + if (targetExistsInAttackByList) + { + World.getInstance().forEachVisibleObjectInRange(npc, Npc.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)) + { + return; + } + // Don't call npcs who are already doing some action (e.g. attacking, casting). + if ((called.getAI()._intention != CtrlIntention.AI_INTENTION_IDLE) && (called.getAI()._intention != CtrlIntention.AI_INTENTION_ACTIVE)) + { + return; + } + // Don't call npcs who aren't in the same clan. + if (!getActiveChar().getTemplate().isClan(called.getTemplate().getClans())) + { + return; + } + if (finalTarget.isPlayable()) { // By default, when a faction member calls for help, attack the caller's attacker. @@ -719,8 +741,8 @@ public class AttackableAI extends CreatureAI ((Attackable) called).addDamageHate(finalTarget, 0, npc.getHating(finalTarget)); called.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, finalTarget); } - } - }); + }); + } } catch (NullPointerException e) { 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 2f4d9f423c..2aaa69961c 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 @@ -20,6 +20,7 @@ import static org.l2jmobius.gameserver.ai.CtrlIntention.AI_INTENTION_ACTIVE; import static org.l2jmobius.gameserver.ai.CtrlIntention.AI_INTENTION_ATTACK; import static org.l2jmobius.gameserver.ai.CtrlIntention.AI_INTENTION_IDLE; +import java.lang.ref.WeakReference; import java.util.Comparator; import java.util.List; import java.util.Set; @@ -697,16 +698,37 @@ public class AttackableAI extends CreatureAI try { final Creature finalTarget = target; - World.getInstance().forEachVisibleObjectInRange(npc, Npc.class, factionRange, called -> + + // Call friendly npcs for help only if this NPC was attacked by the target creature. + boolean targetExistsInAttackByList = false; + for (final WeakReference reference : npc.getAttackByList()) { - if (!getActiveChar().getTemplate().isClan(called.getTemplate().getClans())) + if (reference.get() == finalTarget) { - return; + targetExistsInAttackByList = true; + break; } - - // Check if the WorldObject is inside the Faction Range of the actor - if (called.hasAI() && (Math.abs(finalTarget.getZ() - called.getZ()) < 600) && npc.getAttackByList().stream().anyMatch(o -> o.get() == finalTarget) && ((called.getAI()._intention == CtrlIntention.AI_INTENTION_IDLE) || (called.getAI()._intention == CtrlIntention.AI_INTENTION_ACTIVE))) + } + if (targetExistsInAttackByList) + { + World.getInstance().forEachVisibleObjectInRange(npc, Npc.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)) + { + return; + } + // Don't call npcs who are already doing some action (e.g. attacking, casting). + if ((called.getAI()._intention != CtrlIntention.AI_INTENTION_IDLE) && (called.getAI()._intention != CtrlIntention.AI_INTENTION_ACTIVE)) + { + return; + } + // Don't call npcs who aren't in the same clan. + if (!getActiveChar().getTemplate().isClan(called.getTemplate().getClans())) + { + return; + } + if (finalTarget.isPlayable()) { // By default, when a faction member calls for help, attack the caller's attacker. @@ -719,8 +741,8 @@ public class AttackableAI extends CreatureAI ((Attackable) called).addDamageHate(finalTarget, 0, npc.getHating(finalTarget)); called.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, finalTarget); } - } - }); + }); + } } catch (NullPointerException e) { 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 2f4d9f423c..2aaa69961c 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 @@ -20,6 +20,7 @@ import static org.l2jmobius.gameserver.ai.CtrlIntention.AI_INTENTION_ACTIVE; import static org.l2jmobius.gameserver.ai.CtrlIntention.AI_INTENTION_ATTACK; import static org.l2jmobius.gameserver.ai.CtrlIntention.AI_INTENTION_IDLE; +import java.lang.ref.WeakReference; import java.util.Comparator; import java.util.List; import java.util.Set; @@ -697,16 +698,37 @@ public class AttackableAI extends CreatureAI try { final Creature finalTarget = target; - World.getInstance().forEachVisibleObjectInRange(npc, Npc.class, factionRange, called -> + + // Call friendly npcs for help only if this NPC was attacked by the target creature. + boolean targetExistsInAttackByList = false; + for (final WeakReference reference : npc.getAttackByList()) { - if (!getActiveChar().getTemplate().isClan(called.getTemplate().getClans())) + if (reference.get() == finalTarget) { - return; + targetExistsInAttackByList = true; + break; } - - // Check if the WorldObject is inside the Faction Range of the actor - if (called.hasAI() && (Math.abs(finalTarget.getZ() - called.getZ()) < 600) && npc.getAttackByList().stream().anyMatch(o -> o.get() == finalTarget) && ((called.getAI()._intention == CtrlIntention.AI_INTENTION_IDLE) || (called.getAI()._intention == CtrlIntention.AI_INTENTION_ACTIVE))) + } + if (targetExistsInAttackByList) + { + World.getInstance().forEachVisibleObjectInRange(npc, Npc.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)) + { + return; + } + // Don't call npcs who are already doing some action (e.g. attacking, casting). + if ((called.getAI()._intention != CtrlIntention.AI_INTENTION_IDLE) && (called.getAI()._intention != CtrlIntention.AI_INTENTION_ACTIVE)) + { + return; + } + // Don't call npcs who aren't in the same clan. + if (!getActiveChar().getTemplate().isClan(called.getTemplate().getClans())) + { + return; + } + if (finalTarget.isPlayable()) { // By default, when a faction member calls for help, attack the caller's attacker. @@ -719,8 +741,8 @@ public class AttackableAI extends CreatureAI ((Attackable) called).addDamageHate(finalTarget, 0, npc.getHating(finalTarget)); called.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, finalTarget); } - } - }); + }); + } } catch (NullPointerException e) { 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 2f4d9f423c..2aaa69961c 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 @@ -20,6 +20,7 @@ import static org.l2jmobius.gameserver.ai.CtrlIntention.AI_INTENTION_ACTIVE; import static org.l2jmobius.gameserver.ai.CtrlIntention.AI_INTENTION_ATTACK; import static org.l2jmobius.gameserver.ai.CtrlIntention.AI_INTENTION_IDLE; +import java.lang.ref.WeakReference; import java.util.Comparator; import java.util.List; import java.util.Set; @@ -697,16 +698,37 @@ public class AttackableAI extends CreatureAI try { final Creature finalTarget = target; - World.getInstance().forEachVisibleObjectInRange(npc, Npc.class, factionRange, called -> + + // Call friendly npcs for help only if this NPC was attacked by the target creature. + boolean targetExistsInAttackByList = false; + for (final WeakReference reference : npc.getAttackByList()) { - if (!getActiveChar().getTemplate().isClan(called.getTemplate().getClans())) + if (reference.get() == finalTarget) { - return; + targetExistsInAttackByList = true; + break; } - - // Check if the WorldObject is inside the Faction Range of the actor - if (called.hasAI() && (Math.abs(finalTarget.getZ() - called.getZ()) < 600) && npc.getAttackByList().stream().anyMatch(o -> o.get() == finalTarget) && ((called.getAI()._intention == CtrlIntention.AI_INTENTION_IDLE) || (called.getAI()._intention == CtrlIntention.AI_INTENTION_ACTIVE))) + } + if (targetExistsInAttackByList) + { + World.getInstance().forEachVisibleObjectInRange(npc, Npc.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)) + { + return; + } + // Don't call npcs who are already doing some action (e.g. attacking, casting). + if ((called.getAI()._intention != CtrlIntention.AI_INTENTION_IDLE) && (called.getAI()._intention != CtrlIntention.AI_INTENTION_ACTIVE)) + { + return; + } + // Don't call npcs who aren't in the same clan. + if (!getActiveChar().getTemplate().isClan(called.getTemplate().getClans())) + { + return; + } + if (finalTarget.isPlayable()) { // By default, when a faction member calls for help, attack the caller's attacker. @@ -719,8 +741,8 @@ public class AttackableAI extends CreatureAI ((Attackable) called).addDamageHate(finalTarget, 0, npc.getHating(finalTarget)); called.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, finalTarget); } - } - }); + }); + } } catch (NullPointerException e) { 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 2f4d9f423c..2aaa69961c 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 @@ -20,6 +20,7 @@ import static org.l2jmobius.gameserver.ai.CtrlIntention.AI_INTENTION_ACTIVE; import static org.l2jmobius.gameserver.ai.CtrlIntention.AI_INTENTION_ATTACK; import static org.l2jmobius.gameserver.ai.CtrlIntention.AI_INTENTION_IDLE; +import java.lang.ref.WeakReference; import java.util.Comparator; import java.util.List; import java.util.Set; @@ -697,16 +698,37 @@ public class AttackableAI extends CreatureAI try { final Creature finalTarget = target; - World.getInstance().forEachVisibleObjectInRange(npc, Npc.class, factionRange, called -> + + // Call friendly npcs for help only if this NPC was attacked by the target creature. + boolean targetExistsInAttackByList = false; + for (final WeakReference reference : npc.getAttackByList()) { - if (!getActiveChar().getTemplate().isClan(called.getTemplate().getClans())) + if (reference.get() == finalTarget) { - return; + targetExistsInAttackByList = true; + break; } - - // Check if the WorldObject is inside the Faction Range of the actor - if (called.hasAI() && (Math.abs(finalTarget.getZ() - called.getZ()) < 600) && npc.getAttackByList().stream().anyMatch(o -> o.get() == finalTarget) && ((called.getAI()._intention == CtrlIntention.AI_INTENTION_IDLE) || (called.getAI()._intention == CtrlIntention.AI_INTENTION_ACTIVE))) + } + if (targetExistsInAttackByList) + { + World.getInstance().forEachVisibleObjectInRange(npc, Npc.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)) + { + return; + } + // Don't call npcs who are already doing some action (e.g. attacking, casting). + if ((called.getAI()._intention != CtrlIntention.AI_INTENTION_IDLE) && (called.getAI()._intention != CtrlIntention.AI_INTENTION_ACTIVE)) + { + return; + } + // Don't call npcs who aren't in the same clan. + if (!getActiveChar().getTemplate().isClan(called.getTemplate().getClans())) + { + return; + } + if (finalTarget.isPlayable()) { // By default, when a faction member calls for help, attack the caller's attacker. @@ -719,8 +741,8 @@ public class AttackableAI extends CreatureAI ((Attackable) called).addDamageHate(finalTarget, 0, npc.getHating(finalTarget)); called.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, finalTarget); } - } - }); + }); + } } catch (NullPointerException e) { 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 2f4d9f423c..2aaa69961c 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 @@ -20,6 +20,7 @@ import static org.l2jmobius.gameserver.ai.CtrlIntention.AI_INTENTION_ACTIVE; import static org.l2jmobius.gameserver.ai.CtrlIntention.AI_INTENTION_ATTACK; import static org.l2jmobius.gameserver.ai.CtrlIntention.AI_INTENTION_IDLE; +import java.lang.ref.WeakReference; import java.util.Comparator; import java.util.List; import java.util.Set; @@ -697,16 +698,37 @@ public class AttackableAI extends CreatureAI try { final Creature finalTarget = target; - World.getInstance().forEachVisibleObjectInRange(npc, Npc.class, factionRange, called -> + + // Call friendly npcs for help only if this NPC was attacked by the target creature. + boolean targetExistsInAttackByList = false; + for (final WeakReference reference : npc.getAttackByList()) { - if (!getActiveChar().getTemplate().isClan(called.getTemplate().getClans())) + if (reference.get() == finalTarget) { - return; + targetExistsInAttackByList = true; + break; } - - // Check if the WorldObject is inside the Faction Range of the actor - if (called.hasAI() && (Math.abs(finalTarget.getZ() - called.getZ()) < 600) && npc.getAttackByList().stream().anyMatch(o -> o.get() == finalTarget) && ((called.getAI()._intention == CtrlIntention.AI_INTENTION_IDLE) || (called.getAI()._intention == CtrlIntention.AI_INTENTION_ACTIVE))) + } + if (targetExistsInAttackByList) + { + World.getInstance().forEachVisibleObjectInRange(npc, Npc.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)) + { + return; + } + // Don't call npcs who are already doing some action (e.g. attacking, casting). + if ((called.getAI()._intention != CtrlIntention.AI_INTENTION_IDLE) && (called.getAI()._intention != CtrlIntention.AI_INTENTION_ACTIVE)) + { + return; + } + // Don't call npcs who aren't in the same clan. + if (!getActiveChar().getTemplate().isClan(called.getTemplate().getClans())) + { + return; + } + if (finalTarget.isPlayable()) { // By default, when a faction member calls for help, attack the caller's attacker. @@ -719,8 +741,8 @@ public class AttackableAI extends CreatureAI ((Attackable) called).addDamageHate(finalTarget, 0, npc.getHating(finalTarget)); called.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, finalTarget); } - } - }); + }); + } } catch (NullPointerException e) { 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 de52ee3c27..598eca925f 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 @@ -846,39 +846,61 @@ public class AttackableAI extends CreatureAI // Go through all WorldObject that belong to its faction try { - for (Npc called : World.getInstance().getVisibleObjectsInRange(npc, Npc.class, factionRange)) + final Creature finalTarget = originalAttackTarget; + // Call friendly npcs for help only if this NPC was attacked by the target creature. + boolean targetExistsInAttackByList = false; + for (Creature reference : npc.getAttackByList()) { - if (!getActiveChar().getTemplate().isClan(called.getTemplate().getClans())) + if (reference == finalTarget) { - continue; + targetExistsInAttackByList = true; + break; } - - // Check if the WorldObject is inside the Faction Range of the actor - if (called.hasAI() && (Math.abs(originalAttackTarget.getZ() - called.getZ()) < 600) && npc.getAttackByList().contains(originalAttackTarget) && ((called.getAI()._intention == AI_INTENTION_IDLE) || (called.getAI()._intention == AI_INTENTION_ACTIVE)) && (called.getInstanceId() == npc.getInstanceId())) + } + if (targetExistsInAttackByList) + { + World.getInstance().forEachVisibleObjectInRange(npc, Npc.class, factionRange, called -> { - if (originalAttackTarget.isPlayable()) + // 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)) { - if (originalAttackTarget.isInParty() && originalAttackTarget.getParty().isInDimensionalRift()) + return; + } + // Don't call npcs who are already doing some action (e.g. attacking, casting). + if ((called.getAI()._intention != AI_INTENTION_IDLE) && (called.getAI()._intention != AI_INTENTION_ACTIVE)) + { + return; + } + // Don't call npcs who aren't in the same clan. + if (!getActiveChar().getTemplate().isClan(called.getTemplate().getClans())) + { + return; + } + + if (finalTarget.isPlayable()) + { + // Dimensional Rift check. + if (finalTarget.isInParty() && finalTarget.getParty().isInDimensionalRift()) { - final byte riftType = originalAttackTarget.getParty().getDimensionalRift().getType(); - final byte riftRoom = originalAttackTarget.getParty().getDimensionalRift().getCurrentRoom(); + final byte riftType = finalTarget.getParty().getDimensionalRift().getType(); + final byte riftRoom = finalTarget.getParty().getDimensionalRift().getCurrentRoom(); if ((npc instanceof RiftInvaderInstance) && !DimensionalRiftManager.getInstance().getRoom(riftType, riftRoom).checkIfInZone(npc.getX(), npc.getY(), npc.getZ())) { - continue; + return; } } // By default, when a faction member calls for help, attack the caller's attacker. // Notify the AI with EVT_AGGRESSION - called.getAI().notifyEvent(CtrlEvent.EVT_AGGRESSION, originalAttackTarget, 1); - EventDispatcher.getInstance().notifyEventAsync(new OnAttackableFactionCall(called, getActiveChar(), originalAttackTarget.getActingPlayer(), originalAttackTarget.isSummon()), called); + called.getAI().notifyEvent(CtrlEvent.EVT_AGGRESSION, finalTarget, 1); + EventDispatcher.getInstance().notifyEventAsync(new OnAttackableFactionCall(called, getActiveChar(), finalTarget.getActingPlayer(), finalTarget.isSummon()), called); } - else if (called.isAttackable() && (getAttackTarget() != null) && (called.getAI()._intention != AI_INTENTION_ATTACK)) + else if (called.isAttackable() && (called.getAI()._intention != AI_INTENTION_ATTACK)) { - ((Attackable) called).addDamageHate(getAttackTarget(), 0, npc.getHating(getAttackTarget())); - called.getAI().setIntention(AI_INTENTION_ATTACK, getAttackTarget()); + ((Attackable) called).addDamageHate(finalTarget, 0, npc.getHating(finalTarget)); + called.getAI().setIntention(AI_INTENTION_ATTACK, finalTarget); } - } + }); } } catch (NullPointerException e) 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 de52ee3c27..598eca925f 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 @@ -846,39 +846,61 @@ public class AttackableAI extends CreatureAI // Go through all WorldObject that belong to its faction try { - for (Npc called : World.getInstance().getVisibleObjectsInRange(npc, Npc.class, factionRange)) + final Creature finalTarget = originalAttackTarget; + // Call friendly npcs for help only if this NPC was attacked by the target creature. + boolean targetExistsInAttackByList = false; + for (Creature reference : npc.getAttackByList()) { - if (!getActiveChar().getTemplate().isClan(called.getTemplate().getClans())) + if (reference == finalTarget) { - continue; + targetExistsInAttackByList = true; + break; } - - // Check if the WorldObject is inside the Faction Range of the actor - if (called.hasAI() && (Math.abs(originalAttackTarget.getZ() - called.getZ()) < 600) && npc.getAttackByList().contains(originalAttackTarget) && ((called.getAI()._intention == AI_INTENTION_IDLE) || (called.getAI()._intention == AI_INTENTION_ACTIVE)) && (called.getInstanceId() == npc.getInstanceId())) + } + if (targetExistsInAttackByList) + { + World.getInstance().forEachVisibleObjectInRange(npc, Npc.class, factionRange, called -> { - if (originalAttackTarget.isPlayable()) + // 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)) { - if (originalAttackTarget.isInParty() && originalAttackTarget.getParty().isInDimensionalRift()) + return; + } + // Don't call npcs who are already doing some action (e.g. attacking, casting). + if ((called.getAI()._intention != AI_INTENTION_IDLE) && (called.getAI()._intention != AI_INTENTION_ACTIVE)) + { + return; + } + // Don't call npcs who aren't in the same clan. + if (!getActiveChar().getTemplate().isClan(called.getTemplate().getClans())) + { + return; + } + + if (finalTarget.isPlayable()) + { + // Dimensional Rift check. + if (finalTarget.isInParty() && finalTarget.getParty().isInDimensionalRift()) { - final byte riftType = originalAttackTarget.getParty().getDimensionalRift().getType(); - final byte riftRoom = originalAttackTarget.getParty().getDimensionalRift().getCurrentRoom(); + final byte riftType = finalTarget.getParty().getDimensionalRift().getType(); + final byte riftRoom = finalTarget.getParty().getDimensionalRift().getCurrentRoom(); if ((npc instanceof RiftInvaderInstance) && !DimensionalRiftManager.getInstance().getRoom(riftType, riftRoom).checkIfInZone(npc.getX(), npc.getY(), npc.getZ())) { - continue; + return; } } // By default, when a faction member calls for help, attack the caller's attacker. // Notify the AI with EVT_AGGRESSION - called.getAI().notifyEvent(CtrlEvent.EVT_AGGRESSION, originalAttackTarget, 1); - EventDispatcher.getInstance().notifyEventAsync(new OnAttackableFactionCall(called, getActiveChar(), originalAttackTarget.getActingPlayer(), originalAttackTarget.isSummon()), called); + called.getAI().notifyEvent(CtrlEvent.EVT_AGGRESSION, finalTarget, 1); + EventDispatcher.getInstance().notifyEventAsync(new OnAttackableFactionCall(called, getActiveChar(), finalTarget.getActingPlayer(), finalTarget.isSummon()), called); } - else if (called.isAttackable() && (getAttackTarget() != null) && (called.getAI()._intention != AI_INTENTION_ATTACK)) + else if (called.isAttackable() && (called.getAI()._intention != AI_INTENTION_ATTACK)) { - ((Attackable) called).addDamageHate(getAttackTarget(), 0, npc.getHating(getAttackTarget())); - called.getAI().setIntention(AI_INTENTION_ATTACK, getAttackTarget()); + ((Attackable) called).addDamageHate(finalTarget, 0, npc.getHating(finalTarget)); + called.getAI().setIntention(AI_INTENTION_ATTACK, finalTarget); } - } + }); } } catch (NullPointerException e) 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 2f4d9f423c..2aaa69961c 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 @@ -20,6 +20,7 @@ import static org.l2jmobius.gameserver.ai.CtrlIntention.AI_INTENTION_ACTIVE; import static org.l2jmobius.gameserver.ai.CtrlIntention.AI_INTENTION_ATTACK; import static org.l2jmobius.gameserver.ai.CtrlIntention.AI_INTENTION_IDLE; +import java.lang.ref.WeakReference; import java.util.Comparator; import java.util.List; import java.util.Set; @@ -697,16 +698,37 @@ public class AttackableAI extends CreatureAI try { final Creature finalTarget = target; - World.getInstance().forEachVisibleObjectInRange(npc, Npc.class, factionRange, called -> + + // Call friendly npcs for help only if this NPC was attacked by the target creature. + boolean targetExistsInAttackByList = false; + for (final WeakReference reference : npc.getAttackByList()) { - if (!getActiveChar().getTemplate().isClan(called.getTemplate().getClans())) + if (reference.get() == finalTarget) { - return; + targetExistsInAttackByList = true; + break; } - - // Check if the WorldObject is inside the Faction Range of the actor - if (called.hasAI() && (Math.abs(finalTarget.getZ() - called.getZ()) < 600) && npc.getAttackByList().stream().anyMatch(o -> o.get() == finalTarget) && ((called.getAI()._intention == CtrlIntention.AI_INTENTION_IDLE) || (called.getAI()._intention == CtrlIntention.AI_INTENTION_ACTIVE))) + } + if (targetExistsInAttackByList) + { + World.getInstance().forEachVisibleObjectInRange(npc, Npc.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)) + { + return; + } + // Don't call npcs who are already doing some action (e.g. attacking, casting). + if ((called.getAI()._intention != CtrlIntention.AI_INTENTION_IDLE) && (called.getAI()._intention != CtrlIntention.AI_INTENTION_ACTIVE)) + { + return; + } + // Don't call npcs who aren't in the same clan. + if (!getActiveChar().getTemplate().isClan(called.getTemplate().getClans())) + { + return; + } + if (finalTarget.isPlayable()) { // By default, when a faction member calls for help, attack the caller's attacker. @@ -719,8 +741,8 @@ public class AttackableAI extends CreatureAI ((Attackable) called).addDamageHate(finalTarget, 0, npc.getHating(finalTarget)); called.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, finalTarget); } - } - }); + }); + } } catch (NullPointerException e) { 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 2f4d9f423c..2aaa69961c 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 @@ -20,6 +20,7 @@ import static org.l2jmobius.gameserver.ai.CtrlIntention.AI_INTENTION_ACTIVE; import static org.l2jmobius.gameserver.ai.CtrlIntention.AI_INTENTION_ATTACK; import static org.l2jmobius.gameserver.ai.CtrlIntention.AI_INTENTION_IDLE; +import java.lang.ref.WeakReference; import java.util.Comparator; import java.util.List; import java.util.Set; @@ -697,16 +698,37 @@ public class AttackableAI extends CreatureAI try { final Creature finalTarget = target; - World.getInstance().forEachVisibleObjectInRange(npc, Npc.class, factionRange, called -> + + // Call friendly npcs for help only if this NPC was attacked by the target creature. + boolean targetExistsInAttackByList = false; + for (final WeakReference reference : npc.getAttackByList()) { - if (!getActiveChar().getTemplate().isClan(called.getTemplate().getClans())) + if (reference.get() == finalTarget) { - return; + targetExistsInAttackByList = true; + break; } - - // Check if the WorldObject is inside the Faction Range of the actor - if (called.hasAI() && (Math.abs(finalTarget.getZ() - called.getZ()) < 600) && npc.getAttackByList().stream().anyMatch(o -> o.get() == finalTarget) && ((called.getAI()._intention == CtrlIntention.AI_INTENTION_IDLE) || (called.getAI()._intention == CtrlIntention.AI_INTENTION_ACTIVE))) + } + if (targetExistsInAttackByList) + { + World.getInstance().forEachVisibleObjectInRange(npc, Npc.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)) + { + return; + } + // Don't call npcs who are already doing some action (e.g. attacking, casting). + if ((called.getAI()._intention != CtrlIntention.AI_INTENTION_IDLE) && (called.getAI()._intention != CtrlIntention.AI_INTENTION_ACTIVE)) + { + return; + } + // Don't call npcs who aren't in the same clan. + if (!getActiveChar().getTemplate().isClan(called.getTemplate().getClans())) + { + return; + } + if (finalTarget.isPlayable()) { // By default, when a faction member calls for help, attack the caller's attacker. @@ -719,8 +741,8 @@ public class AttackableAI extends CreatureAI ((Attackable) called).addDamageHate(finalTarget, 0, npc.getHating(finalTarget)); called.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, finalTarget); } - } - }); + }); + } } catch (NullPointerException e) { 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 2f4d9f423c..2aaa69961c 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 @@ -20,6 +20,7 @@ import static org.l2jmobius.gameserver.ai.CtrlIntention.AI_INTENTION_ACTIVE; import static org.l2jmobius.gameserver.ai.CtrlIntention.AI_INTENTION_ATTACK; import static org.l2jmobius.gameserver.ai.CtrlIntention.AI_INTENTION_IDLE; +import java.lang.ref.WeakReference; import java.util.Comparator; import java.util.List; import java.util.Set; @@ -697,16 +698,37 @@ public class AttackableAI extends CreatureAI try { final Creature finalTarget = target; - World.getInstance().forEachVisibleObjectInRange(npc, Npc.class, factionRange, called -> + + // Call friendly npcs for help only if this NPC was attacked by the target creature. + boolean targetExistsInAttackByList = false; + for (final WeakReference reference : npc.getAttackByList()) { - if (!getActiveChar().getTemplate().isClan(called.getTemplate().getClans())) + if (reference.get() == finalTarget) { - return; + targetExistsInAttackByList = true; + break; } - - // Check if the WorldObject is inside the Faction Range of the actor - if (called.hasAI() && (Math.abs(finalTarget.getZ() - called.getZ()) < 600) && npc.getAttackByList().stream().anyMatch(o -> o.get() == finalTarget) && ((called.getAI()._intention == CtrlIntention.AI_INTENTION_IDLE) || (called.getAI()._intention == CtrlIntention.AI_INTENTION_ACTIVE))) + } + if (targetExistsInAttackByList) + { + World.getInstance().forEachVisibleObjectInRange(npc, Npc.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)) + { + return; + } + // Don't call npcs who are already doing some action (e.g. attacking, casting). + if ((called.getAI()._intention != CtrlIntention.AI_INTENTION_IDLE) && (called.getAI()._intention != CtrlIntention.AI_INTENTION_ACTIVE)) + { + return; + } + // Don't call npcs who aren't in the same clan. + if (!getActiveChar().getTemplate().isClan(called.getTemplate().getClans())) + { + return; + } + if (finalTarget.isPlayable()) { // By default, when a faction member calls for help, attack the caller's attacker. @@ -719,8 +741,8 @@ public class AttackableAI extends CreatureAI ((Attackable) called).addDamageHate(finalTarget, 0, npc.getHating(finalTarget)); called.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, finalTarget); } - } - }); + }); + } } catch (NullPointerException e) { 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 2f4d9f423c..2aaa69961c 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 @@ -20,6 +20,7 @@ import static org.l2jmobius.gameserver.ai.CtrlIntention.AI_INTENTION_ACTIVE; import static org.l2jmobius.gameserver.ai.CtrlIntention.AI_INTENTION_ATTACK; import static org.l2jmobius.gameserver.ai.CtrlIntention.AI_INTENTION_IDLE; +import java.lang.ref.WeakReference; import java.util.Comparator; import java.util.List; import java.util.Set; @@ -697,16 +698,37 @@ public class AttackableAI extends CreatureAI try { final Creature finalTarget = target; - World.getInstance().forEachVisibleObjectInRange(npc, Npc.class, factionRange, called -> + + // Call friendly npcs for help only if this NPC was attacked by the target creature. + boolean targetExistsInAttackByList = false; + for (final WeakReference reference : npc.getAttackByList()) { - if (!getActiveChar().getTemplate().isClan(called.getTemplate().getClans())) + if (reference.get() == finalTarget) { - return; + targetExistsInAttackByList = true; + break; } - - // Check if the WorldObject is inside the Faction Range of the actor - if (called.hasAI() && (Math.abs(finalTarget.getZ() - called.getZ()) < 600) && npc.getAttackByList().stream().anyMatch(o -> o.get() == finalTarget) && ((called.getAI()._intention == CtrlIntention.AI_INTENTION_IDLE) || (called.getAI()._intention == CtrlIntention.AI_INTENTION_ACTIVE))) + } + if (targetExistsInAttackByList) + { + World.getInstance().forEachVisibleObjectInRange(npc, Npc.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)) + { + return; + } + // Don't call npcs who are already doing some action (e.g. attacking, casting). + if ((called.getAI()._intention != CtrlIntention.AI_INTENTION_IDLE) && (called.getAI()._intention != CtrlIntention.AI_INTENTION_ACTIVE)) + { + return; + } + // Don't call npcs who aren't in the same clan. + if (!getActiveChar().getTemplate().isClan(called.getTemplate().getClans())) + { + return; + } + if (finalTarget.isPlayable()) { // By default, when a faction member calls for help, attack the caller's attacker. @@ -719,8 +741,8 @@ public class AttackableAI extends CreatureAI ((Attackable) called).addDamageHate(finalTarget, 0, npc.getHating(finalTarget)); called.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, finalTarget); } - } - }); + }); + } } catch (NullPointerException e) { 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 2f4d9f423c..2aaa69961c 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 @@ -20,6 +20,7 @@ import static org.l2jmobius.gameserver.ai.CtrlIntention.AI_INTENTION_ACTIVE; import static org.l2jmobius.gameserver.ai.CtrlIntention.AI_INTENTION_ATTACK; import static org.l2jmobius.gameserver.ai.CtrlIntention.AI_INTENTION_IDLE; +import java.lang.ref.WeakReference; import java.util.Comparator; import java.util.List; import java.util.Set; @@ -697,16 +698,37 @@ public class AttackableAI extends CreatureAI try { final Creature finalTarget = target; - World.getInstance().forEachVisibleObjectInRange(npc, Npc.class, factionRange, called -> + + // Call friendly npcs for help only if this NPC was attacked by the target creature. + boolean targetExistsInAttackByList = false; + for (final WeakReference reference : npc.getAttackByList()) { - if (!getActiveChar().getTemplate().isClan(called.getTemplate().getClans())) + if (reference.get() == finalTarget) { - return; + targetExistsInAttackByList = true; + break; } - - // Check if the WorldObject is inside the Faction Range of the actor - if (called.hasAI() && (Math.abs(finalTarget.getZ() - called.getZ()) < 600) && npc.getAttackByList().stream().anyMatch(o -> o.get() == finalTarget) && ((called.getAI()._intention == CtrlIntention.AI_INTENTION_IDLE) || (called.getAI()._intention == CtrlIntention.AI_INTENTION_ACTIVE))) + } + if (targetExistsInAttackByList) + { + World.getInstance().forEachVisibleObjectInRange(npc, Npc.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)) + { + return; + } + // Don't call npcs who are already doing some action (e.g. attacking, casting). + if ((called.getAI()._intention != CtrlIntention.AI_INTENTION_IDLE) && (called.getAI()._intention != CtrlIntention.AI_INTENTION_ACTIVE)) + { + return; + } + // Don't call npcs who aren't in the same clan. + if (!getActiveChar().getTemplate().isClan(called.getTemplate().getClans())) + { + return; + } + if (finalTarget.isPlayable()) { // By default, when a faction member calls for help, attack the caller's attacker. @@ -719,8 +741,8 @@ public class AttackableAI extends CreatureAI ((Attackable) called).addDamageHate(finalTarget, 0, npc.getHating(finalTarget)); called.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, finalTarget); } - } - }); + }); + } } catch (NullPointerException e) { 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 2f4d9f423c..2aaa69961c 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 @@ -20,6 +20,7 @@ import static org.l2jmobius.gameserver.ai.CtrlIntention.AI_INTENTION_ACTIVE; import static org.l2jmobius.gameserver.ai.CtrlIntention.AI_INTENTION_ATTACK; import static org.l2jmobius.gameserver.ai.CtrlIntention.AI_INTENTION_IDLE; +import java.lang.ref.WeakReference; import java.util.Comparator; import java.util.List; import java.util.Set; @@ -697,16 +698,37 @@ public class AttackableAI extends CreatureAI try { final Creature finalTarget = target; - World.getInstance().forEachVisibleObjectInRange(npc, Npc.class, factionRange, called -> + + // Call friendly npcs for help only if this NPC was attacked by the target creature. + boolean targetExistsInAttackByList = false; + for (final WeakReference reference : npc.getAttackByList()) { - if (!getActiveChar().getTemplate().isClan(called.getTemplate().getClans())) + if (reference.get() == finalTarget) { - return; + targetExistsInAttackByList = true; + break; } - - // Check if the WorldObject is inside the Faction Range of the actor - if (called.hasAI() && (Math.abs(finalTarget.getZ() - called.getZ()) < 600) && npc.getAttackByList().stream().anyMatch(o -> o.get() == finalTarget) && ((called.getAI()._intention == CtrlIntention.AI_INTENTION_IDLE) || (called.getAI()._intention == CtrlIntention.AI_INTENTION_ACTIVE))) + } + if (targetExistsInAttackByList) + { + World.getInstance().forEachVisibleObjectInRange(npc, Npc.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)) + { + return; + } + // Don't call npcs who are already doing some action (e.g. attacking, casting). + if ((called.getAI()._intention != CtrlIntention.AI_INTENTION_IDLE) && (called.getAI()._intention != CtrlIntention.AI_INTENTION_ACTIVE)) + { + return; + } + // Don't call npcs who aren't in the same clan. + if (!getActiveChar().getTemplate().isClan(called.getTemplate().getClans())) + { + return; + } + if (finalTarget.isPlayable()) { // By default, when a faction member calls for help, attack the caller's attacker. @@ -719,8 +741,8 @@ public class AttackableAI extends CreatureAI ((Attackable) called).addDamageHate(finalTarget, 0, npc.getHating(finalTarget)); called.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, finalTarget); } - } - }); + }); + } } catch (NullPointerException e) { 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 eff965bafa..fa68a326d2 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 @@ -20,6 +20,7 @@ import static org.l2jmobius.gameserver.ai.CtrlIntention.AI_INTENTION_ACTIVE; import static org.l2jmobius.gameserver.ai.CtrlIntention.AI_INTENTION_ATTACK; import static org.l2jmobius.gameserver.ai.CtrlIntention.AI_INTENTION_IDLE; +import java.lang.ref.WeakReference; import java.util.Comparator; import java.util.List; import java.util.Set; @@ -697,16 +698,37 @@ public class AttackableAI extends CreatureAI try { final Creature finalTarget = target; - World.getInstance().forEachVisibleObjectInRange(npc, Npc.class, factionRange, called -> + + // Call friendly npcs for help only if this NPC was attacked by the target creature. + boolean targetExistsInAttackByList = false; + for (final WeakReference reference : npc.getAttackByList()) { - if (!getActiveChar().getTemplate().isClan(called.getTemplate().getClans())) + if (reference.get() == finalTarget) { - return; + targetExistsInAttackByList = true; + break; } - - // Check if the WorldObject is inside the Faction Range of the actor - if (called.hasAI() && (Math.abs(finalTarget.getZ() - called.getZ()) < 600) && npc.getAttackByList().stream().anyMatch(o -> o.get() == finalTarget) && ((called.getAI()._intention == CtrlIntention.AI_INTENTION_IDLE) || (called.getAI()._intention == CtrlIntention.AI_INTENTION_ACTIVE))) + } + if (targetExistsInAttackByList) + { + World.getInstance().forEachVisibleObjectInRange(npc, Npc.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)) + { + return; + } + // Don't call npcs who are already doing some action (e.g. attacking, casting). + if ((called.getAI()._intention != CtrlIntention.AI_INTENTION_IDLE) && (called.getAI()._intention != CtrlIntention.AI_INTENTION_ACTIVE)) + { + return; + } + // Don't call npcs who aren't in the same clan. + if (!getActiveChar().getTemplate().isClan(called.getTemplate().getClans())) + { + return; + } + if (finalTarget.isPlayable()) { // By default, when a faction member calls for help, attack the caller's attacker. @@ -719,8 +741,8 @@ public class AttackableAI extends CreatureAI ((Attackable) called).addDamageHate(finalTarget, 0, npc.getHating(finalTarget)); called.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, finalTarget); } - } - }); + }); + } } catch (NullPointerException e) {