From 6b9ed818219a6524e1fb2213fd498bbade73edc6 Mon Sep 17 00:00:00 2001 From: MobiusDev <8391001+MobiusDevelopment@users.noreply.github.com> Date: Tue, 19 May 2015 14:57:13 +0000 Subject: [PATCH] Sync with L2jServer HighFive May 19th 2015. --- trunk/dist/game/data/html/default/32601.htm | 2 +- .../ai/group_template/MinionSpawnManager.java | 1 + .../ai/individual/Antharas/Antharas.java | 11 ++--- .../RainbowSpringsChateau.java | 43 ++++++++++--------- .../HallOfSuffering/HallOfSuffering.java | 3 +- .../handlers/actionhandlers/L2NpcAction.java | 22 ++++++---- .../actionhandlers/L2PcInstanceAction.java | 31 +++++++------ .../Q10502_FreyaEmbroideredSoulCloak.java | 2 +- .../ai/group_template/MinionSpawnManager.java | 1 + .../ai/individual/Antharas/Antharas.java | 10 ++--- .../handlers/actionhandlers/L2NpcAction.java | 22 ++++++---- .../actionhandlers/L2PcInstanceAction.java | 33 +++++++------- .../com/l2jserver/gameserver/GeoData.java | 11 +++++ .../gameserver/model/actor/L2Character.java | 36 +++++++++------- .../model/actor/instance/L2PcInstance.java | 17 +++----- .../gameserver/model/actor/stat/PcStat.java | 24 +++++------ .../serverpackets/ExReplySentPost.java | 1 + 17 files changed, 146 insertions(+), 124 deletions(-) diff --git a/trunk/dist/game/data/html/default/32601.htm b/trunk/dist/game/data/html/default/32601.htm index 6f1acfab11..9a4b6dd05a 100644 --- a/trunk/dist/game/data/html/default/32601.htm +++ b/trunk/dist/game/data/html/default/32601.htm @@ -1,4 +1,4 @@ Instant Moving Device:
This device can teleport you deep inside the Seed of Destruction.
- + \ No newline at end of file diff --git a/trunk/dist/game/data/scripts/ai/group_template/MinionSpawnManager.java b/trunk/dist/game/data/scripts/ai/group_template/MinionSpawnManager.java index 864aaa74ea..9253fb2584 100644 --- a/trunk/dist/game/data/scripts/ai/group_template/MinionSpawnManager.java +++ b/trunk/dist/game/data/scripts/ai/group_template/MinionSpawnManager.java @@ -380,6 +380,7 @@ public final class MinionSpawnManager extends AbstractNpcAI NPC.add(27266); // Fallen Angel Haures NPC.add(27267); // Fallen Angel Haures NPC.add(27290); // White Wing Commander + NPC.add(29001); // Queen Ant NPC.add(29030); // Fenril Hound Kerinne NPC.add(29033); // Fenril Hound Freki NPC.add(29037); // Fenril Hound Kinaz diff --git a/trunk/dist/game/data/scripts/ai/individual/Antharas/Antharas.java b/trunk/dist/game/data/scripts/ai/individual/Antharas/Antharas.java index 72a0204cab..b7cfd82d8b 100644 --- a/trunk/dist/game/data/scripts/ai/individual/Antharas/Antharas.java +++ b/trunk/dist/game/data/scripts/ai/individual/Antharas/Antharas.java @@ -520,7 +520,7 @@ public final class Antharas extends AbstractNpcAI } else { - player.sendMessage(getClass().getSimpleName() + ": You cant skip waiting time right now!"); + player.sendMessage(getClass().getSimpleName() + ": You can't skip waiting time right now!"); } break; } @@ -535,7 +535,7 @@ public final class Antharas extends AbstractNpcAI } else { - player.sendMessage(getClass().getSimpleName() + ": You cant respawn antharas while antharas is alive!"); + player.sendMessage(getClass().getSimpleName() + ": You can't respawn antharas while antharas is alive!"); } break; } @@ -553,12 +553,12 @@ public final class Antharas extends AbstractNpcAI } if (player != null) // Player dont will be null just when is this event called from GM command { - player.sendMessage(getClass().getSimpleName() + ": All minions has been deleted!"); + player.sendMessage(getClass().getSimpleName() + ": All minions have been deleted!"); } } else if (player != null) // Player dont will be null just when is this event called from GM command { - player.sendMessage(getClass().getSimpleName() + ": You cant despawn minions right now!"); + player.sendMessage(getClass().getSimpleName() + ": You can't despawn minions right now!"); } break; } @@ -594,7 +594,7 @@ public final class Antharas extends AbstractNpcAI } else { - player.sendMessage(getClass().getSimpleName() + ": You cant abort fight right now!"); + player.sendMessage(getClass().getSimpleName() + ": You can't abort fight right now!"); } break; } @@ -713,6 +713,7 @@ public final class Antharas extends AbstractNpcAI { cancelQuestTimer("SET_REGEN", npc, null); startQuestTimer("SET_REGEN", 60000, npc, null); + ((L2Attackable) npc).setOnKillDelay(0); } else { diff --git a/trunk/dist/game/data/scripts/conquerablehalls/RainbowSpringsChateau/RainbowSpringsChateau.java b/trunk/dist/game/data/scripts/conquerablehalls/RainbowSpringsChateau/RainbowSpringsChateau.java index d446db1369..6e0abedc3a 100644 --- a/trunk/dist/game/data/scripts/conquerablehalls/RainbowSpringsChateau/RainbowSpringsChateau.java +++ b/trunk/dist/game/data/scripts/conquerablehalls/RainbowSpringsChateau/RainbowSpringsChateau.java @@ -564,27 +564,28 @@ public final class RainbowSpringsChateau extends ClanHallSiegeEngine } } } - else if (event.startsWith("getItem")) - { - if (!_pendingItemToGet.containsKey(clan)) - { - html = "yeti_cannot_exchange.htm"; - } - - int left = _pendingItemToGet.get(clan); - if (left > 0) - { - int itemId = Integer.parseInt(event.split("_")[1]); - player.addItem("Rainbow Spring Chateau Siege", itemId, 1, npc, true); - --left; - _pendingItemToGet.put(clan, left); - html = "yeti_main.htm"; - } - else - { - html = "yeti_cannot_exchange.htm"; - } - } + // TODO(Zoey76): Rewrite this to prevent exploits... + // else if (event.startsWith("getItem")) + // { + // if (!_pendingItemToGet.containsKey(clan)) + // { + // html = "yeti_cannot_exchange.htm"; + // } + // + // int left = _pendingItemToGet.get(clan); + // if (left > 0) + // { + // int itemId = Integer.parseInt(event.split("_")[1]); + // player.addItem("Rainbow Spring Chateau Siege", itemId, 1, npc, true); + // --left; + // _pendingItemToGet.put(clan, left); + // html = "yeti_main.htm"; + // } + // else + // { + // html = "yeti_cannot_exchange.htm"; + // } + // } return html; } diff --git a/trunk/dist/game/data/scripts/gracia/instances/SeedOfInfinity/HallOfSuffering/HallOfSuffering.java b/trunk/dist/game/data/scripts/gracia/instances/SeedOfInfinity/HallOfSuffering/HallOfSuffering.java index 95e2f7f560..2965406431 100644 --- a/trunk/dist/game/data/scripts/gracia/instances/SeedOfInfinity/HallOfSuffering/HallOfSuffering.java +++ b/trunk/dist/game/data/scripts/gracia/instances/SeedOfInfinity/HallOfSuffering/HallOfSuffering.java @@ -183,6 +183,7 @@ public final class HallOfSuffering extends AbstractNpcAI // Misc private static final int TEMPLATE_ID = 115; private static final int MIN_LEVEL = 75; + private static final int MAX_LEVEL = 82; private static final boolean debug = false; public HallOfSuffering() @@ -219,7 +220,7 @@ public final class HallOfSuffering extends AbstractNpcAI for (L2PcInstance partyMember : party.getMembers()) { - if (partyMember.getLevel() < MIN_LEVEL) + if ((partyMember.getLevel() < MIN_LEVEL) || (partyMember.getLevel() > MAX_LEVEL)) { final SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.C1_S_LEVEL_DOES_NOT_CORRESPOND_TO_THE_REQUIREMENTS_FOR_ENTRY); sm.addPcName(partyMember); diff --git a/trunk/dist/game/data/scripts/handlers/actionhandlers/L2NpcAction.java b/trunk/dist/game/data/scripts/handlers/actionhandlers/L2NpcAction.java index e8289aae83..e486bdada6 100644 --- a/trunk/dist/game/data/scripts/handlers/actionhandlers/L2NpcAction.java +++ b/trunk/dist/game/data/scripts/handlers/actionhandlers/L2NpcAction.java @@ -19,18 +19,18 @@ package handlers.actionhandlers; import com.l2jserver.Config; +import com.l2jserver.gameserver.GeoData; import com.l2jserver.gameserver.ai.CtrlIntention; import com.l2jserver.gameserver.enums.InstanceType; import com.l2jserver.gameserver.handler.IActionHandler; import com.l2jserver.gameserver.model.L2Object; -import com.l2jserver.gameserver.model.actor.L2Character; +import com.l2jserver.gameserver.model.Location; import com.l2jserver.gameserver.model.actor.L2Npc; import com.l2jserver.gameserver.model.actor.instance.L2PcInstance; import com.l2jserver.gameserver.model.entity.L2Event; import com.l2jserver.gameserver.model.events.EventDispatcher; import com.l2jserver.gameserver.model.events.EventType; import com.l2jserver.gameserver.model.events.impl.character.npc.OnNpcFirstTalk; -import com.l2jserver.gameserver.network.serverpackets.ActionFailed; import com.l2jserver.gameserver.network.serverpackets.MoveToPawn; import com.l2jserver.util.Rnd; @@ -79,23 +79,27 @@ public class L2NpcAction implements IActionHandler else if (interact) { // Check if the activeChar is attackable (without a forced attack) and isn't dead - if (target.isAutoAttackable(activeChar) && !((L2Character) target).isAlikeDead()) + if (target.isAutoAttackable(activeChar) && !((L2Npc) target).isAlikeDead()) { - // Check the height difference - if (Math.abs(activeChar.getZ() - target.getZ()) < 400) // this max heigth difference might need some tweaking + if (GeoData.getInstance().canSeeTarget(activeChar, target)) { - // Set the L2PcInstance Intention to AI_INTENTION_ATTACK activeChar.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, target); - // activeChar.startAttack(this); } else { - // Send a Server->Client ActionFailed to the L2PcInstance in order to avoid that the client wait another packet - activeChar.sendPacket(ActionFailed.STATIC_PACKET); + final Location destination = GeoData.getInstance().moveCheck(activeChar, target); + activeChar.getAI().setIntention(CtrlIntention.AI_INTENTION_MOVE_TO, destination); } } else if (!target.isAutoAttackable(activeChar)) { + if (GeoData.getInstance().canSeeTarget(activeChar, target)) + { + final Location destination = GeoData.getInstance().moveCheck(activeChar, target); + activeChar.getAI().setIntention(CtrlIntention.AI_INTENTION_MOVE_TO, destination); + return true; + } + // Calculate the distance between the L2PcInstance and the L2Npc if (!((L2Npc) target).canInteract(activeChar)) { diff --git a/trunk/dist/game/data/scripts/handlers/actionhandlers/L2PcInstanceAction.java b/trunk/dist/game/data/scripts/handlers/actionhandlers/L2PcInstanceAction.java index 1144640612..569ddfdde3 100644 --- a/trunk/dist/game/data/scripts/handlers/actionhandlers/L2PcInstanceAction.java +++ b/trunk/dist/game/data/scripts/handlers/actionhandlers/L2PcInstanceAction.java @@ -25,7 +25,6 @@ import com.l2jserver.gameserver.enums.PrivateStoreType; import com.l2jserver.gameserver.handler.IActionHandler; import com.l2jserver.gameserver.model.L2Object; import com.l2jserver.gameserver.model.Location; -import com.l2jserver.gameserver.model.actor.L2Character; import com.l2jserver.gameserver.model.actor.instance.L2PcInstance; import com.l2jserver.gameserver.model.entity.TvTEvent; import com.l2jserver.gameserver.network.SystemMessageId; @@ -33,6 +32,8 @@ import com.l2jserver.gameserver.network.serverpackets.ActionFailed; public class L2PcInstanceAction implements IActionHandler { + private static final int CURSED_WEAPON_VICTIM_MIN_LEVEL = 21; + /** * Manage actions when a player click on this L2PcInstance.
*
@@ -83,50 +84,48 @@ public class L2PcInstanceAction implements IActionHandler } else if (interact) { + final L2PcInstance player = target.getActingPlayer(); // Check if this L2PcInstance has a Private Store - if (((L2PcInstance) target).getPrivateStoreType() != PrivateStoreType.NONE) + if (player.getPrivateStoreType() != PrivateStoreType.NONE) { - activeChar.getAI().setIntention(CtrlIntention.AI_INTENTION_INTERACT, target); + activeChar.getAI().setIntention(CtrlIntention.AI_INTENTION_INTERACT, player); } else { // Check if this L2PcInstance is autoAttackable - if (target.isAutoAttackable(activeChar)) + if (player.isAutoAttackable(activeChar)) { - // activeChar with lvl < 21 can't attack a cursed weapon holder - // And a cursed weapon holder can't attack activeChars with lvl < 21 - if ((((L2PcInstance) target).isCursedWeaponEquipped() && (activeChar.getLevel() < 21)) || (activeChar.isCursedWeaponEquipped() && (((L2Character) target).getLevel() < 21))) + if ((player.isCursedWeaponEquipped() && (activeChar.getLevel() < CURSED_WEAPON_VICTIM_MIN_LEVEL)) // + || (activeChar.isCursedWeaponEquipped() && (player.getLevel() < CURSED_WEAPON_VICTIM_MIN_LEVEL))) { activeChar.sendPacket(ActionFailed.STATIC_PACKET); } else { - if (GeoData.getInstance().canSeeTarget(activeChar, target)) + if (GeoData.getInstance().canSeeTarget(activeChar, player)) { - activeChar.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, target); - activeChar.onActionRequest(); + activeChar.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, player); } else { - final Location destination = GeoData.getInstance().moveCheck(activeChar.getX(), activeChar.getY(), activeChar.getZ(), target.getX(), target.getY(), target.getZ(), activeChar.getInstanceId()); + final Location destination = GeoData.getInstance().moveCheck(activeChar, player); activeChar.getAI().setIntention(CtrlIntention.AI_INTENTION_MOVE_TO, destination); - activeChar.onActionRequest(); } + activeChar.onActionRequest(); } } else { // This Action Failed packet avoids activeChar getting stuck when clicking three or more times activeChar.sendPacket(ActionFailed.STATIC_PACKET); - if (GeoData.getInstance().canSeeTarget(activeChar, target)) + if (GeoData.getInstance().canSeeTarget(activeChar, player)) { - activeChar.getAI().setIntention(CtrlIntention.AI_INTENTION_FOLLOW, target); + activeChar.getAI().setIntention(CtrlIntention.AI_INTENTION_FOLLOW, player); } else { - final Location destination = GeoData.getInstance().moveCheck(activeChar.getX(), activeChar.getY(), activeChar.getZ(), target.getX(), target.getY(), target.getZ(), activeChar.getInstanceId()); + final Location destination = GeoData.getInstance().moveCheck(activeChar, player); activeChar.getAI().setIntention(CtrlIntention.AI_INTENTION_MOVE_TO, destination); - activeChar.onActionRequest(); } } } diff --git a/trunk/dist/game/data/scripts/quests/Q10502_FreyaEmbroideredSoulCloak/Q10502_FreyaEmbroideredSoulCloak.java b/trunk/dist/game/data/scripts/quests/Q10502_FreyaEmbroideredSoulCloak/Q10502_FreyaEmbroideredSoulCloak.java index 769a5d73ae..c2fa9a3898 100644 --- a/trunk/dist/game/data/scripts/quests/Q10502_FreyaEmbroideredSoulCloak/Q10502_FreyaEmbroideredSoulCloak.java +++ b/trunk/dist/game/data/scripts/quests/Q10502_FreyaEmbroideredSoulCloak/Q10502_FreyaEmbroideredSoulCloak.java @@ -35,7 +35,7 @@ public class Q10502_FreyaEmbroideredSoulCloak extends Quest // NPC private static final int OLF_ADAMS = 32612; // Monster - private static final int FREYA = 29180; + private static final int FREYA = 29179; // Items private static final int FREYAS_SOUL_FRAGMENT = 21723; private static final int SOUL_CLOAK_OF_FREYA = 21720; diff --git a/trunk/dist/game/data_classic/scripts/ai/group_template/MinionSpawnManager.java b/trunk/dist/game/data_classic/scripts/ai/group_template/MinionSpawnManager.java index 0e0f59266b..b97db61def 100644 --- a/trunk/dist/game/data_classic/scripts/ai/group_template/MinionSpawnManager.java +++ b/trunk/dist/game/data_classic/scripts/ai/group_template/MinionSpawnManager.java @@ -251,6 +251,7 @@ public final class MinionSpawnManager extends AbstractNpcAI NPC.add(27186); // Fairy Tree of Star NPC.add(27187); // Fairy Tree of Twilight NPC.add(27188); // Fairy Tree of Abyss + NPC.add(29001); // Queen Ant } private static final NpcStringId[] ON_ATTACK_MSG = diff --git a/trunk/dist/game/data_classic/scripts/ai/individual/Antharas/Antharas.java b/trunk/dist/game/data_classic/scripts/ai/individual/Antharas/Antharas.java index 39a2c448fe..e8b1e48ddb 100644 --- a/trunk/dist/game/data_classic/scripts/ai/individual/Antharas/Antharas.java +++ b/trunk/dist/game/data_classic/scripts/ai/individual/Antharas/Antharas.java @@ -521,7 +521,7 @@ public final class Antharas extends AbstractNpcAI } else { - player.sendMessage(getClass().getSimpleName() + ": You cant skip waiting time right now!"); + player.sendMessage(getClass().getSimpleName() + ": You can't skip waiting time right now!"); } break; } @@ -536,7 +536,7 @@ public final class Antharas extends AbstractNpcAI } else { - player.sendMessage(getClass().getSimpleName() + ": You cant respawn antharas while antharas is alive!"); + player.sendMessage(getClass().getSimpleName() + ": You can't respawn antharas while antharas is alive!"); } break; } @@ -554,12 +554,12 @@ public final class Antharas extends AbstractNpcAI } if (player != null) // Player dont will be null just when is this event called from GM command { - player.sendMessage(getClass().getSimpleName() + ": All minions has been deleted!"); + player.sendMessage(getClass().getSimpleName() + ": All minions have been deleted!"); } } else if (player != null) // Player dont will be null just when is this event called from GM command { - player.sendMessage(getClass().getSimpleName() + ": You cant despawn minions right now!"); + player.sendMessage(getClass().getSimpleName() + ": You can't despawn minions right now!"); } break; } @@ -595,7 +595,7 @@ public final class Antharas extends AbstractNpcAI } else { - player.sendMessage(getClass().getSimpleName() + ": You cant abort fight right now!"); + player.sendMessage(getClass().getSimpleName() + ": You can't abort fight right now!"); } break; } diff --git a/trunk/dist/game/data_classic/scripts/handlers/actionhandlers/L2NpcAction.java b/trunk/dist/game/data_classic/scripts/handlers/actionhandlers/L2NpcAction.java index e8289aae83..e486bdada6 100644 --- a/trunk/dist/game/data_classic/scripts/handlers/actionhandlers/L2NpcAction.java +++ b/trunk/dist/game/data_classic/scripts/handlers/actionhandlers/L2NpcAction.java @@ -19,18 +19,18 @@ package handlers.actionhandlers; import com.l2jserver.Config; +import com.l2jserver.gameserver.GeoData; import com.l2jserver.gameserver.ai.CtrlIntention; import com.l2jserver.gameserver.enums.InstanceType; import com.l2jserver.gameserver.handler.IActionHandler; import com.l2jserver.gameserver.model.L2Object; -import com.l2jserver.gameserver.model.actor.L2Character; +import com.l2jserver.gameserver.model.Location; import com.l2jserver.gameserver.model.actor.L2Npc; import com.l2jserver.gameserver.model.actor.instance.L2PcInstance; import com.l2jserver.gameserver.model.entity.L2Event; import com.l2jserver.gameserver.model.events.EventDispatcher; import com.l2jserver.gameserver.model.events.EventType; import com.l2jserver.gameserver.model.events.impl.character.npc.OnNpcFirstTalk; -import com.l2jserver.gameserver.network.serverpackets.ActionFailed; import com.l2jserver.gameserver.network.serverpackets.MoveToPawn; import com.l2jserver.util.Rnd; @@ -79,23 +79,27 @@ public class L2NpcAction implements IActionHandler else if (interact) { // Check if the activeChar is attackable (without a forced attack) and isn't dead - if (target.isAutoAttackable(activeChar) && !((L2Character) target).isAlikeDead()) + if (target.isAutoAttackable(activeChar) && !((L2Npc) target).isAlikeDead()) { - // Check the height difference - if (Math.abs(activeChar.getZ() - target.getZ()) < 400) // this max heigth difference might need some tweaking + if (GeoData.getInstance().canSeeTarget(activeChar, target)) { - // Set the L2PcInstance Intention to AI_INTENTION_ATTACK activeChar.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, target); - // activeChar.startAttack(this); } else { - // Send a Server->Client ActionFailed to the L2PcInstance in order to avoid that the client wait another packet - activeChar.sendPacket(ActionFailed.STATIC_PACKET); + final Location destination = GeoData.getInstance().moveCheck(activeChar, target); + activeChar.getAI().setIntention(CtrlIntention.AI_INTENTION_MOVE_TO, destination); } } else if (!target.isAutoAttackable(activeChar)) { + if (GeoData.getInstance().canSeeTarget(activeChar, target)) + { + final Location destination = GeoData.getInstance().moveCheck(activeChar, target); + activeChar.getAI().setIntention(CtrlIntention.AI_INTENTION_MOVE_TO, destination); + return true; + } + // Calculate the distance between the L2PcInstance and the L2Npc if (!((L2Npc) target).canInteract(activeChar)) { diff --git a/trunk/dist/game/data_classic/scripts/handlers/actionhandlers/L2PcInstanceAction.java b/trunk/dist/game/data_classic/scripts/handlers/actionhandlers/L2PcInstanceAction.java index 1144640612..bdc126d141 100644 --- a/trunk/dist/game/data_classic/scripts/handlers/actionhandlers/L2PcInstanceAction.java +++ b/trunk/dist/game/data_classic/scripts/handlers/actionhandlers/L2PcInstanceAction.java @@ -25,7 +25,6 @@ import com.l2jserver.gameserver.enums.PrivateStoreType; import com.l2jserver.gameserver.handler.IActionHandler; import com.l2jserver.gameserver.model.L2Object; import com.l2jserver.gameserver.model.Location; -import com.l2jserver.gameserver.model.actor.L2Character; import com.l2jserver.gameserver.model.actor.instance.L2PcInstance; import com.l2jserver.gameserver.model.entity.TvTEvent; import com.l2jserver.gameserver.network.SystemMessageId; @@ -33,6 +32,8 @@ import com.l2jserver.gameserver.network.serverpackets.ActionFailed; public class L2PcInstanceAction implements IActionHandler { + private static final int CURSED_WEAPON_VICTIM_MIN_LEVEL = 21; + /** * Manage actions when a player click on this L2PcInstance.
*
@@ -71,7 +72,7 @@ public class L2PcInstanceAction implements IActionHandler // Aggression target lock effect if (activeChar.isLockedTarget() && (activeChar.getLockedTarget() != target)) { - activeChar.sendPacket(SystemMessageId.FAILED_TO_CHANGE_ENMITY); + activeChar.sendPacket(SystemMessageId.FAILED_CHANGE_TARGET); return false; } @@ -83,50 +84,48 @@ public class L2PcInstanceAction implements IActionHandler } else if (interact) { + final L2PcInstance player = target.getActingPlayer(); // Check if this L2PcInstance has a Private Store - if (((L2PcInstance) target).getPrivateStoreType() != PrivateStoreType.NONE) + if (player.getPrivateStoreType() != PrivateStoreType.NONE) { - activeChar.getAI().setIntention(CtrlIntention.AI_INTENTION_INTERACT, target); + activeChar.getAI().setIntention(CtrlIntention.AI_INTENTION_INTERACT, player); } else { // Check if this L2PcInstance is autoAttackable - if (target.isAutoAttackable(activeChar)) + if (player.isAutoAttackable(activeChar)) { - // activeChar with lvl < 21 can't attack a cursed weapon holder - // And a cursed weapon holder can't attack activeChars with lvl < 21 - if ((((L2PcInstance) target).isCursedWeaponEquipped() && (activeChar.getLevel() < 21)) || (activeChar.isCursedWeaponEquipped() && (((L2Character) target).getLevel() < 21))) + if ((player.isCursedWeaponEquipped() && (activeChar.getLevel() < CURSED_WEAPON_VICTIM_MIN_LEVEL)) // + || (activeChar.isCursedWeaponEquipped() && (player.getLevel() < CURSED_WEAPON_VICTIM_MIN_LEVEL))) { activeChar.sendPacket(ActionFailed.STATIC_PACKET); } else { - if (GeoData.getInstance().canSeeTarget(activeChar, target)) + if (GeoData.getInstance().canSeeTarget(activeChar, player)) { - activeChar.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, target); - activeChar.onActionRequest(); + activeChar.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, player); } else { - final Location destination = GeoData.getInstance().moveCheck(activeChar.getX(), activeChar.getY(), activeChar.getZ(), target.getX(), target.getY(), target.getZ(), activeChar.getInstanceId()); + final Location destination = GeoData.getInstance().moveCheck(activeChar, player); activeChar.getAI().setIntention(CtrlIntention.AI_INTENTION_MOVE_TO, destination); - activeChar.onActionRequest(); } + activeChar.onActionRequest(); } } else { // This Action Failed packet avoids activeChar getting stuck when clicking three or more times activeChar.sendPacket(ActionFailed.STATIC_PACKET); - if (GeoData.getInstance().canSeeTarget(activeChar, target)) + if (GeoData.getInstance().canSeeTarget(activeChar, player)) { - activeChar.getAI().setIntention(CtrlIntention.AI_INTENTION_FOLLOW, target); + activeChar.getAI().setIntention(CtrlIntention.AI_INTENTION_FOLLOW, player); } else { - final Location destination = GeoData.getInstance().moveCheck(activeChar.getX(), activeChar.getY(), activeChar.getZ(), target.getX(), target.getY(), target.getZ(), activeChar.getInstanceId()); + final Location destination = GeoData.getInstance().moveCheck(activeChar, player); activeChar.getAI().setIntention(CtrlIntention.AI_INTENTION_MOVE_TO, destination); - activeChar.onActionRequest(); } } } diff --git a/trunk/java/com/l2jserver/gameserver/GeoData.java b/trunk/java/com/l2jserver/gameserver/GeoData.java index 0aa156c2f6..79eb6f6728 100644 --- a/trunk/java/com/l2jserver/gameserver/GeoData.java +++ b/trunk/java/com/l2jserver/gameserver/GeoData.java @@ -436,6 +436,17 @@ public class GeoData return true; } + /** + * Verifies if the is a path between origin's location and destination, if not returns the closest location. + * @param origin the origin + * @param destination the destination + * @return the destination if there is a path or the closes location + */ + public Location moveCheck(ILocational origin, ILocational destination) + { + return moveCheck(origin.getX(), origin.getY(), origin.getZ(), destination.getX(), destination.getY(), destination.getZ(), origin.getInstanceId()); + } + /** * Move check. * @param x the x coordinate diff --git a/trunk/java/com/l2jserver/gameserver/model/actor/L2Character.java b/trunk/java/com/l2jserver/gameserver/model/actor/L2Character.java index 38b1378fdd..60d6b6b666 100644 --- a/trunk/java/com/l2jserver/gameserver/model/actor/L2Character.java +++ b/trunk/java/com/l2jserver/gameserver/model/actor/L2Character.java @@ -33,6 +33,7 @@ import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.Future; import java.util.concurrent.LinkedBlockingDeque; +import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.ReentrantLock; import java.util.concurrent.locks.StampedLock; import java.util.logging.Level; @@ -263,7 +264,7 @@ public abstract class L2Character extends L2Object implements ISkillsHolder, IDe /** This creature's target. */ private L2Object _target; - // set by the start of attack, in game ticks + /** Represents the time where the attack should end, in nanoseconds. */ private volatile long _attackEndTime; private int _disableBowAttackEndTime; private int _disableCrossBowAttackEndTime; @@ -1093,7 +1094,7 @@ public abstract class L2Character extends L2Object implements ISkillsHolder, IDe final int timeAtk = calculateTimeBetweenAttacks(target, weaponItem); // the hit is calculated to happen halfway to the animation - might need further tuning e.g. in bow case final int timeToHit = timeAtk / 2; - _attackEndTime = System.currentTimeMillis() + timeAtk; + _attackEndTime = System.nanoTime() + TimeUnit.NANOSECONDS.convert(timeAtk, TimeUnit.MILLISECONDS); final int ssGrade = (weaponItem != null) ? weaponItem.getItemGrade().ordinal() : 0; // Create a Server->Client packet Attack Attack attack = new Attack(this, target, wasSSCharged, ssGrade); @@ -4061,11 +4062,12 @@ public abstract class L2Character extends L2Object implements ISkillsHolder, IDe } /** - * @return True if the L2Character is attacking. + * Verifies if the creature is attacking now. + * @return {@code true} if the creature is attacking now, {@code false} otherwise */ public final boolean isAttackingNow() { - return _attackEndTime > System.currentTimeMillis(); + return _attackEndTime > System.nanoTime(); } /** @@ -5539,9 +5541,9 @@ public abstract class L2Character extends L2Object implements ISkillsHolder, IDe if ((targets.length > 0) && (escapeRange > 0)) { - int _skiprange = 0; - int _skipgeo = 0; - int _skippeace = 0; + int skipRange = 0; + int skipLOS = 0; + int skipPeaceZone = 0; final List targetList = new ArrayList<>(); for (L2Object target : targets) { @@ -5549,21 +5551,25 @@ public abstract class L2Character extends L2Object implements ISkillsHolder, IDe { if (!isInsideRadius(target.getX(), target.getY(), target.getZ(), escapeRange + getTemplate().getCollisionRadius(), true, false)) { - _skiprange++; + skipRange++; continue; } - if ((escapeRange > 0) && !GeoData.getInstance().canSeeTarget(this, target)) + + // Healing party members should ignore LOS. + if (((skill.getTargetType() != L2TargetType.PARTY) || !skill.hasEffectType(L2EffectType.HEAL)) // + && !GeoData.getInstance().canSeeTarget(this, target)) { - _skipgeo++; + skipLOS++; continue; } + if (skill.isBad()) { if (isPlayer()) { if (((L2Character) target).isInsidePeaceZone(getActingPlayer())) { - _skippeace++; + skipPeaceZone++; continue; } } @@ -5571,7 +5577,7 @@ public abstract class L2Character extends L2Object implements ISkillsHolder, IDe { if (((L2Character) target).isInsidePeaceZone(this, target)) { - _skippeace++; + skipPeaceZone++; continue; } } @@ -5583,15 +5589,15 @@ public abstract class L2Character extends L2Object implements ISkillsHolder, IDe { if (isPlayer()) { - if (_skiprange > 0) + if (skipRange > 0) { sendPacket(SystemMessageId.THE_DISTANCE_IS_TOO_FAR_AND_SO_THE_CASTING_HAS_BEEN_STOPPED); } - else if (_skipgeo > 0) + else if (skipLOS > 0) { sendPacket(SystemMessageId.CANNOT_SEE_TARGET); } - else if (_skippeace > 0) + else if (skipPeaceZone > 0) { sendPacket(SystemMessageId.A_MALICIOUS_SKILL_CANNOT_BE_USED_IN_A_PEACE_ZONE); } diff --git a/trunk/java/com/l2jserver/gameserver/model/actor/instance/L2PcInstance.java b/trunk/java/com/l2jserver/gameserver/model/actor/instance/L2PcInstance.java index 4bac0a9433..144b92857e 100644 --- a/trunk/java/com/l2jserver/gameserver/model/actor/instance/L2PcInstance.java +++ b/trunk/java/com/l2jserver/gameserver/model/actor/instance/L2PcInstance.java @@ -30,14 +30,15 @@ import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; -import java.util.Iterator; import java.util.LinkedHashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Map.Entry; +import java.util.Queue; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.ConcurrentSkipListMap; import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.Future; @@ -407,7 +408,7 @@ public final class L2PcInstance extends L2Playable public static final String WORLD_CHAT_VARIABLE_NAME = "WORLD_CHAT_POINTS"; - private final List _eventListeners = new CopyOnWriteArrayList<>(); + private final Queue _eventListeners = new ConcurrentLinkedQueue<>(); private L2GameClient _client; @@ -9038,6 +9039,7 @@ public final class L2PcInstance extends L2Playable case AURA: case FRONT_AURA: case BEHIND_AURA: + case AREA_SUMMON: case GROUND: case SELF: break; @@ -14667,16 +14669,7 @@ public final class L2PcInstance extends L2Playable public void removeEventListener(Class clazz) { - final Iterator it = _eventListeners.iterator(); - IEventListener event; - while (it.hasNext()) - { - event = it.next(); - if (event.getClass() == clazz) - { - it.remove(); - } - } + _eventListeners.removeIf(e -> e.getClass() == clazz); } public Collection getEventListeners() diff --git a/trunk/java/com/l2jserver/gameserver/model/actor/stat/PcStat.java b/trunk/java/com/l2jserver/gameserver/model/actor/stat/PcStat.java index a0fb7cc38b..965dd400b9 100644 --- a/trunk/java/com/l2jserver/gameserver/model/actor/stat/PcStat.java +++ b/trunk/java/com/l2jserver/gameserver/model/actor/stat/PcStat.java @@ -696,9 +696,9 @@ public class PcStat extends PlayableStat } } - public synchronized void updateVitalityPoints(int points, boolean useRates, boolean quiet) + public synchronized void updateVitalityPoints(int _value, boolean useRates, boolean quiet) { - if ((points == 0) || !Config.ENABLE_VITALITY) + if ((_value == 0) || !Config.ENABLE_VITALITY) { return; } @@ -710,7 +710,7 @@ public class PcStat extends PlayableStat return; } - if (points < 0) // vitality consumed + if (_value < 0) // vitality consumed { int stat = (int) calcStat(Stats.VITALITY_CONSUME_RATE, 1, getActiveChar(), null); @@ -720,37 +720,37 @@ public class PcStat extends PlayableStat } if (stat < 0) { - points = -points; + _value = -_value; } } - if (points > 0) + if (_value > 0) { // vitality increased - points *= Config.RATE_VITALITY_GAIN; + _value *= Config.RATE_VITALITY_GAIN; } else { // vitality decreased - points *= Config.RATE_VITALITY_LOST; + _value *= Config.RATE_VITALITY_LOST; } } - if (points > 0) + if (_value > 0) { - points = Math.min(getActiveChar().getVitalityPoints() + points, MAX_VITALITY_POINTS); + _value = Math.min(getActiveChar().getVitalityPoints() + _value, MAX_VITALITY_POINTS); } else { - points = Math.max(getActiveChar().getVitalityPoints() + points, MIN_VITALITY_POINTS); + _value = Math.max(getActiveChar().getVitalityPoints() + _value, MIN_VITALITY_POINTS); } - if (Math.abs(points - getActiveChar().getVitalityPoints()) <= 1e-6) + if (Math.abs(_value - getActiveChar().getVitalityPoints()) <= 1e-6) { return; } - getActiveChar().setVitalityPoints(points); + getActiveChar().setVitalityPoints(_value); } public double getVitalityMultiplier() diff --git a/trunk/java/com/l2jserver/gameserver/network/serverpackets/ExReplySentPost.java b/trunk/java/com/l2jserver/gameserver/network/serverpackets/ExReplySentPost.java index eef8232314..01fc195bd7 100644 --- a/trunk/java/com/l2jserver/gameserver/network/serverpackets/ExReplySentPost.java +++ b/trunk/java/com/l2jserver/gameserver/network/serverpackets/ExReplySentPost.java @@ -23,6 +23,7 @@ import com.l2jserver.gameserver.model.itemcontainer.ItemContainer; import com.l2jserver.gameserver.model.items.instance.L2ItemInstance; /** + * ExReplySentPost packet implementation. * @author Migi, DS */ public class ExReplySentPost extends AbstractItemPacket