From 488038138345032cbdadc130500075a2ad3c526c Mon Sep 17 00:00:00 2001 From: MobiusDevelopment <8391001+MobiusDevelopment@users.noreply.github.com> Date: Tue, 20 Apr 2021 23:08:52 +0000 Subject: [PATCH] Inventory item skill checks. --- .../model/itemcontainer/Inventory.java | 313 +++++++---- .../gameserver/model/items/Item.java | 5 + .../model/itemcontainer/Inventory.java | 313 +++++++---- .../gameserver/model/items/Item.java | 5 + .../model/itemcontainer/Inventory.java | 313 +++++++---- .../gameserver/model/items/Item.java | 5 + .../model/itemcontainer/Inventory.java | 313 +++++++---- .../gameserver/model/items/Item.java | 5 + .../model/itemcontainer/Inventory.java | 309 +++++++---- .../gameserver/model/items/Item.java | 5 + .../model/itemcontainer/Inventory.java | 309 +++++++---- .../gameserver/model/items/Item.java | 5 + .../model/itemcontainer/Inventory.java | 309 +++++++---- .../gameserver/model/items/Item.java | 5 + .../model/itemcontainer/Inventory.java | 308 +++++++---- .../gameserver/model/items/Item.java | 5 + .../model/itemcontainer/Inventory.java | 308 +++++++---- .../gameserver/model/items/Item.java | 5 + .../model/itemcontainer/Inventory.java | 308 +++++++---- .../gameserver/model/items/Item.java | 5 + .../model/itemcontainer/Inventory.java | 311 +++++++---- .../gameserver/model/items/Item.java | 5 + .../model/itemcontainer/Inventory.java | 311 +++++++---- .../gameserver/model/items/Item.java | 5 + .../model/itemcontainer/Inventory.java | 309 +++++++---- .../gameserver/model/items/Item.java | 5 + .../model/itemcontainer/Inventory.java | 309 +++++++---- .../gameserver/model/items/Item.java | 5 + .../model/itemcontainer/Inventory.java | 309 +++++++---- .../gameserver/model/items/Item.java | 5 + .../model/itemcontainer/Inventory.java | 308 +++++++---- .../gameserver/model/items/Item.java | 5 + .../model/itemcontainer/Inventory.java | 311 +++++++---- .../gameserver/model/items/Item.java | 5 + .../model/itemcontainer/Inventory.java | 308 +++++++---- .../gameserver/model/items/Item.java | 5 + .../model/itemcontainer/Inventory.java | 514 +++++++++++------- .../gameserver/model/items/Item.java | 5 + 38 files changed, 4111 insertions(+), 2077 deletions(-) diff --git a/L2J_Mobius_1.0_Ertheia/java/org/l2jmobius/gameserver/model/itemcontainer/Inventory.java b/L2J_Mobius_1.0_Ertheia/java/org/l2jmobius/gameserver/model/itemcontainer/Inventory.java index 3017ab91d8..5e6c5b0f0f 100644 --- a/L2J_Mobius_1.0_Ertheia/java/org/l2jmobius/gameserver/model/itemcontainer/Inventory.java +++ b/L2J_Mobius_1.0_Ertheia/java/org/l2jmobius/gameserver/model/itemcontainer/Inventory.java @@ -21,7 +21,9 @@ import java.sql.PreparedStatement; import java.sql.ResultSet; import java.util.ArrayList; import java.util.Collection; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.Objects; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; @@ -298,6 +300,8 @@ public abstract class Inventory extends ItemContainer final PlayerInstance player = (PlayerInstance) inventory.getOwner(); final Item it = item.getItem(); + final Map addedSkills = new HashMap<>(1); + final Map removedSkills = new HashMap<>(1); boolean update = false; boolean updateTimestamp = false; @@ -310,78 +314,108 @@ public abstract class Inventory extends ItemContainer // Recalculate all stats player.getStat().recalculateStats(true); - final List onEnchantSkills = it.getSkills(ItemSkillType.ON_ENCHANT); - if (onEnchantSkills != null) - { - for (ItemSkillHolder holder : onEnchantSkills) - { - // Remove skills bestowed from +4 armor - if (item.getEnchantLevel() >= holder.getValue()) - { - player.removeSkill(holder.getSkill(), false, holder.getSkill().isPassive()); - update = true; - } - } - } - // Clear enchant bonus item.clearEnchantStats(); - final List normalSkills = it.getSkills(ItemSkillType.NORMAL); - if (normalSkills != null) + if (it.hasSkills()) { - for (ItemSkillHolder holder : normalSkills) + final List onEnchantSkills = it.getSkills(ItemSkillType.ON_ENCHANT); + if (onEnchantSkills != null) { - final Skill skill = holder.getSkill(); - if (skill != null) + for (ItemSkillHolder holder : onEnchantSkills) { - player.removeSkill(skill, false, skill.isPassive()); - update = true; - } - else - { - LOGGER.warning("Inventory.ItemSkillsListener.Weapon: Incorrect skill: " + holder); + // Remove skills bestowed from +4 armor + if (item.getEnchantLevel() >= holder.getValue()) + { + if (removedSkills.containsKey(holder.getSkill().getId())) + { + if (removedSkills.get(holder.getSkill().getId()).getLevel() < holder.getSkill().getLevel()) + { + removedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + } + else + { + removedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + update = true; + } } } - } - - if (item.isArmor()) - { - for (ItemInstance itm : inventory.getItems()) + + final List normalSkills = it.getSkills(ItemSkillType.NORMAL); + if (normalSkills != null) { - if (!itm.isEquipped() || itm.equals(item)) + for (ItemSkillHolder holder : normalSkills) { - continue; + final Skill skill = holder.getSkill(); + if (skill != null) + { + if (removedSkills.containsKey(holder.getSkill().getId())) + { + if (removedSkills.get(holder.getSkill().getId()).getLevel() < holder.getSkill().getLevel()) + { + removedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + } + else + { + removedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + update = true; + } } - - final List otherNormalSkills = itm.getItem().getSkills(ItemSkillType.NORMAL); - if (otherNormalSkills == null) + } + + if (item.isArmor()) + { + for (ItemInstance itm : inventory.getItems()) { - continue; - } - - for (ItemSkillHolder holder : otherNormalSkills) - { - if (player.getSkillLevel(holder.getSkillId()) != 0) + if (!itm.isEquipped() || itm.equals(item)) { continue; } - final Skill skill = holder.getSkill(); - if (skill != null) + final List otherNormalSkills = itm.getItem().getSkills(ItemSkillType.NORMAL); + if (otherNormalSkills == null) { - player.addSkill(skill, false); - if (skill.isActive() && !player.hasSkillReuse(skill.getReuseHashCode())) + continue; + } + + for (ItemSkillHolder holder : otherNormalSkills) + { + if (player.getSkillLevel(holder.getSkillId()) != 0) { - final int equipDelay = item.getEquipReuseDelay(); - if (equipDelay > 0) - { - player.addTimeStamp(skill, equipDelay); - player.disableSkill(skill, equipDelay); - } - updateTimestamp = true; + continue; + } + + final Skill skill = holder.getSkill(); + if (skill != null) + { + if (addedSkills.containsKey(holder.getSkill().getId())) + { + if (addedSkills.get(holder.getSkill().getId()).getLevel() < holder.getSkill().getLevel()) + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + } + else + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + + if (skill.isActive() && !player.hasSkillReuse(skill.getReuseHashCode())) + { + final int equipDelay = item.getEquipReuseDelay(); + if (equipDelay > 0) + { + player.addTimeStamp(skill, equipDelay); + player.disableSkill(skill, equipDelay); + } + updateTimestamp = true; + } + update = true; } - update = true; } } } @@ -390,6 +424,11 @@ public abstract class Inventory extends ItemContainer // Must check all equipped items for enchant conditions. for (ItemInstance equipped : inventory.getPaperdollItems()) { + if (!equipped.getItem().hasSkills()) + { + continue; + } + final List otherEnchantSkills = equipped.getItem().getSkills(ItemSkillType.ON_ENCHANT); if (otherEnchantSkills == null) { @@ -405,7 +444,17 @@ public abstract class Inventory extends ItemContainer // Check passive skill conditions. if (skill.isPassive() && !skill.checkConditions(SkillConditionScope.PASSIVE, player, player)) { - player.removeSkill(holder.getSkill(), false, holder.getSkill().isPassive()); + if (removedSkills.containsKey(holder.getSkill().getId())) + { + if (removedSkills.get(holder.getSkill().getId()).getLevel() < holder.getSkill().getLevel()) + { + removedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + } + else + { + removedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } update = true; } } @@ -425,10 +474,22 @@ public abstract class Inventory extends ItemContainer // Apply skill, if weapon have "skills on unequip" it.forEachSkill(ItemSkillType.ON_UNEQUIP, holder -> holder.getSkill().activateSkill(player, player)); + if (update) { + for (Skill skill : removedSkills.values()) + { + player.removeSkill(skill, false, skill.isPassive()); + } + + for (Skill skill : addedSkills.values()) + { + player.addSkill(skill, false); + } + player.sendSkillList(); } + if (updateTimestamp) { player.sendPacket(new SkillCoolTime(player)); @@ -449,14 +510,13 @@ public abstract class Inventory extends ItemContainer } final PlayerInstance player = (PlayerInstance) inventory.getOwner(); - // Any items equipped that result in expertise penalty do not give any skills at all. if (item.getItem().getCrystalType().getLevel() > player.getExpertiseLevel()) { return; } - boolean update = false; + final Map addedSkills = new HashMap<>(1); boolean updateTimestamp = false; // Apply augmentation bonuses on equip @@ -468,68 +528,87 @@ public abstract class Inventory extends ItemContainer // Recalculate all stats player.getStat().recalculateStats(true); - final List onEnchantSkills = item.getItem().getSkills(ItemSkillType.ON_ENCHANT); - if (onEnchantSkills != null) - { - for (ItemSkillHolder holder : onEnchantSkills) - { - if (player.getSkillLevel(holder.getSkillId()) >= holder.getSkillLevel()) - { - continue; - } - - // Add skills bestowed from +4 armor - if (item.getEnchantLevel() >= holder.getValue()) - { - final Skill skill = holder.getSkill(); - // Check passive skill conditions. - if (skill.isPassive() && !skill.checkConditions(SkillConditionScope.PASSIVE, player, player)) - { - continue; - } - player.addSkill(skill, false); - update = true; - } - } - } - // Apply enchant stats item.applyEnchantStats(); - final List normalSkills = item.getItem().getSkills(ItemSkillType.NORMAL); - if (normalSkills != null) + if (item.getItem().hasSkills()) { - for (ItemSkillHolder holder : normalSkills) + final List onEnchantSkills = item.getItem().getSkills(ItemSkillType.ON_ENCHANT); + if (onEnchantSkills != null) { - if (player.getSkillLevel(holder.getSkillId()) >= holder.getSkillLevel()) + for (ItemSkillHolder holder : onEnchantSkills) { - continue; - } - - final Skill skill = holder.getSkill(); - if (skill != null) - { - if (skill.isPassive() && !skill.checkConditions(SkillConditionScope.PASSIVE, player, player)) + if (player.getSkillLevel(holder.getSkillId()) >= holder.getSkillLevel()) { continue; } - player.addSkill(skill, false); - if (skill.isActive() && !player.hasSkillReuse(skill.getReuseHashCode())) + // Add skills bestowed from +4 armor + if (item.getEnchantLevel() >= holder.getValue()) { - final int equipDelay = item.getEquipReuseDelay(); - if (equipDelay > 0) + final Skill skill = holder.getSkill(); + // Check passive skill conditions. + if (skill.isPassive() && !skill.checkConditions(SkillConditionScope.PASSIVE, player, player)) { - player.addTimeStamp(skill, equipDelay); - player.disableSkill(skill, equipDelay); + continue; + } + + if (addedSkills.containsKey(holder.getSkill().getId())) + { + if (addedSkills.get(holder.getSkill().getId()).getLevel() < holder.getSkill().getLevel()) + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + } + else + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); } - updateTimestamp = true; } - update = true; } - else + } + + final List normalSkills = item.getItem().getSkills(ItemSkillType.NORMAL); + if (normalSkills != null) + { + for (ItemSkillHolder holder : normalSkills) { - LOGGER.warning("Inventory.ItemSkillsListener.Weapon: Incorrect skill: " + holder); + if (player.getSkillLevel(holder.getSkillId()) >= holder.getSkillLevel()) + { + continue; + } + + final Skill skill = holder.getSkill(); + if (skill != null) + { + if (skill.isPassive() && !skill.checkConditions(SkillConditionScope.PASSIVE, player, player)) + { + continue; + } + + if (addedSkills.containsKey(holder.getSkill().getId())) + { + if (addedSkills.get(holder.getSkill().getId()).getLevel() < holder.getSkill().getLevel()) + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + } + else + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + + if (skill.isActive() && !player.hasSkillReuse(skill.getReuseHashCode())) + { + final int equipDelay = item.getEquipReuseDelay(); + if (equipDelay > 0) + { + player.addTimeStamp(skill, equipDelay); + player.disableSkill(skill, equipDelay); + } + updateTimestamp = true; + } + } } } } @@ -537,6 +616,11 @@ public abstract class Inventory extends ItemContainer // Must check all equipped items for enchant conditions. for (ItemInstance equipped : inventory.getPaperdollItems()) { + if (!equipped.getItem().hasSkills()) + { + continue; + } + final List otherEnchantSkills = equipped.getItem().getSkills(ItemSkillType.ON_ENCHANT); if (otherEnchantSkills == null) { @@ -559,18 +643,35 @@ public abstract class Inventory extends ItemContainer { continue; } - player.addSkill(skill, false); - update = true; + + if (addedSkills.containsKey(holder.getSkill().getId())) + { + if (addedSkills.get(holder.getSkill().getId()).getLevel() < holder.getSkill().getLevel()) + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + } + else + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } } } } // Apply skill, if weapon have "skills on equip" item.getItem().forEachSkill(ItemSkillType.ON_EQUIP, holder -> holder.getSkill().activateSkill(player, player)); - if (update) + + if (!addedSkills.isEmpty()) { + for (Skill skill : addedSkills.values()) + { + player.addSkill(skill, false); + } + player.sendSkillList(); } + if (updateTimestamp) { player.sendPacket(new SkillCoolTime(player)); @@ -2082,7 +2183,7 @@ public abstract class Inventory extends ItemContainer { if ((_paperdoll[i] != null) && (getPaperdollItemId(i) == item.getId())) { - // overwtite + // overwrite setPaperdollItem(i, item); return; } diff --git a/L2J_Mobius_1.0_Ertheia/java/org/l2jmobius/gameserver/model/items/Item.java b/L2J_Mobius_1.0_Ertheia/java/org/l2jmobius/gameserver/model/items/Item.java index e2255f8244..5556524f8d 100644 --- a/L2J_Mobius_1.0_Ertheia/java/org/l2jmobius/gameserver/model/items/Item.java +++ b/L2J_Mobius_1.0_Ertheia/java/org/l2jmobius/gameserver/model/items/Item.java @@ -747,6 +747,11 @@ public abstract class Item extends ListenersContainer implements IIdentifiable return _preConditions; } + public boolean hasSkills() + { + return _skills != null; + } + /** * Method to retrieve skills linked to this item armor and weapon: passive skills etcitem: skills used on item use <-- ??? * @return Skills linked to this item as SkillHolder[] diff --git a/L2J_Mobius_2.5_Underground/java/org/l2jmobius/gameserver/model/itemcontainer/Inventory.java b/L2J_Mobius_2.5_Underground/java/org/l2jmobius/gameserver/model/itemcontainer/Inventory.java index 372a79c0ed..47360c75df 100644 --- a/L2J_Mobius_2.5_Underground/java/org/l2jmobius/gameserver/model/itemcontainer/Inventory.java +++ b/L2J_Mobius_2.5_Underground/java/org/l2jmobius/gameserver/model/itemcontainer/Inventory.java @@ -21,7 +21,9 @@ import java.sql.PreparedStatement; import java.sql.ResultSet; import java.util.ArrayList; import java.util.Collection; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.Objects; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; @@ -298,6 +300,8 @@ public abstract class Inventory extends ItemContainer final PlayerInstance player = (PlayerInstance) inventory.getOwner(); final Item it = item.getItem(); + final Map addedSkills = new HashMap<>(1); + final Map removedSkills = new HashMap<>(1); boolean update = false; boolean updateTimestamp = false; @@ -310,81 +314,111 @@ public abstract class Inventory extends ItemContainer // Recalculate all stats player.getStat().recalculateStats(true); - final List onEnchantSkills = it.getSkills(ItemSkillType.ON_ENCHANT); - if (onEnchantSkills != null) - { - for (ItemSkillHolder holder : onEnchantSkills) - { - // Remove skills bestowed from +4 armor - if (item.getEnchantLevel() >= holder.getValue()) - { - player.removeSkill(holder.getSkill(), false, holder.getSkill().isPassive()); - update = true; - } - } - } - // Clear enchant bonus item.clearEnchantStats(); // Clear SA Bonus item.clearSpecialAbilities(); - final List normalSkills = it.getSkills(ItemSkillType.NORMAL); - if (normalSkills != null) + if (it.hasSkills()) { - for (ItemSkillHolder holder : normalSkills) + final List onEnchantSkills = it.getSkills(ItemSkillType.ON_ENCHANT); + if (onEnchantSkills != null) { - final Skill skill = holder.getSkill(); - if (skill != null) + for (ItemSkillHolder holder : onEnchantSkills) { - player.removeSkill(skill, false, skill.isPassive()); - update = true; - } - else - { - LOGGER.warning("Inventory.ItemSkillsListener.Weapon: Incorrect skill: " + holder); + // Remove skills bestowed from +4 armor + if (item.getEnchantLevel() >= holder.getValue()) + { + if (removedSkills.containsKey(holder.getSkill().getId())) + { + if (removedSkills.get(holder.getSkill().getId()).getLevel() < holder.getSkill().getLevel()) + { + removedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + } + else + { + removedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + update = true; + } } } - } - - if (item.isArmor()) - { - for (ItemInstance itm : inventory.getItems()) + + final List normalSkills = it.getSkills(ItemSkillType.NORMAL); + if (normalSkills != null) { - if (!itm.isEquipped() || itm.equals(item)) + for (ItemSkillHolder holder : normalSkills) { - continue; + final Skill skill = holder.getSkill(); + if (skill != null) + { + if (removedSkills.containsKey(holder.getSkill().getId())) + { + if (removedSkills.get(holder.getSkill().getId()).getLevel() < holder.getSkill().getLevel()) + { + removedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + } + else + { + removedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + update = true; + } } - - final List otherNormalSkills = itm.getItem().getSkills(ItemSkillType.NORMAL); - if (otherNormalSkills == null) + } + + if (item.isArmor()) + { + for (ItemInstance itm : inventory.getItems()) { - continue; - } - - for (ItemSkillHolder holder : otherNormalSkills) - { - if (player.getSkillLevel(holder.getSkillId()) != 0) + if (!itm.isEquipped() || itm.equals(item)) { continue; } - final Skill skill = holder.getSkill(); - if (skill != null) + final List otherNormalSkills = itm.getItem().getSkills(ItemSkillType.NORMAL); + if (otherNormalSkills == null) { - player.addSkill(skill, false); - if (skill.isActive() && !player.hasSkillReuse(skill.getReuseHashCode())) + continue; + } + + for (ItemSkillHolder holder : otherNormalSkills) + { + if (player.getSkillLevel(holder.getSkillId()) != 0) { - final int equipDelay = item.getEquipReuseDelay(); - if (equipDelay > 0) - { - player.addTimeStamp(skill, equipDelay); - player.disableSkill(skill, equipDelay); - } - updateTimestamp = true; + continue; + } + + final Skill skill = holder.getSkill(); + if (skill != null) + { + if (addedSkills.containsKey(holder.getSkill().getId())) + { + if (addedSkills.get(holder.getSkill().getId()).getLevel() < holder.getSkill().getLevel()) + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + } + else + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + + if (skill.isActive() && !player.hasSkillReuse(skill.getReuseHashCode())) + { + final int equipDelay = item.getEquipReuseDelay(); + if (equipDelay > 0) + { + player.addTimeStamp(skill, equipDelay); + player.disableSkill(skill, equipDelay); + } + updateTimestamp = true; + } + update = true; } - update = true; } } } @@ -393,6 +427,11 @@ public abstract class Inventory extends ItemContainer // Must check all equipped items for enchant conditions. for (ItemInstance equipped : inventory.getPaperdollItems()) { + if (!equipped.getItem().hasSkills()) + { + continue; + } + final List otherEnchantSkills = equipped.getItem().getSkills(ItemSkillType.ON_ENCHANT); if (otherEnchantSkills == null) { @@ -408,7 +447,17 @@ public abstract class Inventory extends ItemContainer // Check passive skill conditions. if (skill.isPassive() && !skill.checkConditions(SkillConditionScope.PASSIVE, player, player)) { - player.removeSkill(holder.getSkill(), false, holder.getSkill().isPassive()); + if (removedSkills.containsKey(holder.getSkill().getId())) + { + if (removedSkills.get(holder.getSkill().getId()).getLevel() < holder.getSkill().getLevel()) + { + removedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + } + else + { + removedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } update = true; } } @@ -428,10 +477,22 @@ public abstract class Inventory extends ItemContainer // Apply skill, if weapon have "skills on unequip" it.forEachSkill(ItemSkillType.ON_UNEQUIP, holder -> holder.getSkill().activateSkill(player, player)); + if (update) { + for (Skill skill : removedSkills.values()) + { + player.removeSkill(skill, false, skill.isPassive()); + } + + for (Skill skill : addedSkills.values()) + { + player.addSkill(skill, false); + } + player.sendSkillList(); } + if (updateTimestamp) { player.sendPacket(new SkillCoolTime(player)); @@ -452,14 +513,13 @@ public abstract class Inventory extends ItemContainer } final PlayerInstance player = (PlayerInstance) inventory.getOwner(); - // Any items equipped that result in expertise penalty do not give any skills at all. if (item.getItem().getCrystalType().getLevel() > player.getExpertiseLevel()) { return; } - boolean update = false; + final Map addedSkills = new HashMap<>(1); boolean updateTimestamp = false; // Apply augmentation bonuses on equip @@ -471,71 +531,90 @@ public abstract class Inventory extends ItemContainer // Recalculate all stats player.getStat().recalculateStats(true); - final List onEnchantSkills = item.getItem().getSkills(ItemSkillType.ON_ENCHANT); - if (onEnchantSkills != null) - { - for (ItemSkillHolder holder : onEnchantSkills) - { - if (player.getSkillLevel(holder.getSkillId()) >= holder.getSkillLevel()) - { - continue; - } - - // Add skills bestowed from +4 armor - if (item.getEnchantLevel() >= holder.getValue()) - { - final Skill skill = holder.getSkill(); - // Check passive skill conditions. - if (skill.isPassive() && !skill.checkConditions(SkillConditionScope.PASSIVE, player, player)) - { - continue; - } - player.addSkill(skill, false); - update = true; - } - } - } - // Apply enchant stats item.applyEnchantStats(); // Apply SA skill item.applySpecialAbilities(); - final List normalSkills = item.getItem().getSkills(ItemSkillType.NORMAL); - if (normalSkills != null) + if (item.getItem().hasSkills()) { - for (ItemSkillHolder holder : normalSkills) + final List onEnchantSkills = item.getItem().getSkills(ItemSkillType.ON_ENCHANT); + if (onEnchantSkills != null) { - if (player.getSkillLevel(holder.getSkillId()) >= holder.getSkillLevel()) + for (ItemSkillHolder holder : onEnchantSkills) { - continue; - } - - final Skill skill = holder.getSkill(); - if (skill != null) - { - if (skill.isPassive() && !skill.checkConditions(SkillConditionScope.PASSIVE, player, player)) + if (player.getSkillLevel(holder.getSkillId()) >= holder.getSkillLevel()) { continue; } - player.addSkill(skill, false); - if (skill.isActive() && !player.hasSkillReuse(skill.getReuseHashCode())) + // Add skills bestowed from +4 armor + if (item.getEnchantLevel() >= holder.getValue()) { - final int equipDelay = item.getEquipReuseDelay(); - if (equipDelay > 0) + final Skill skill = holder.getSkill(); + // Check passive skill conditions. + if (skill.isPassive() && !skill.checkConditions(SkillConditionScope.PASSIVE, player, player)) { - player.addTimeStamp(skill, equipDelay); - player.disableSkill(skill, equipDelay); + continue; + } + + if (addedSkills.containsKey(holder.getSkill().getId())) + { + if (addedSkills.get(holder.getSkill().getId()).getLevel() < holder.getSkill().getLevel()) + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + } + else + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); } - updateTimestamp = true; } - update = true; } - else + } + + final List normalSkills = item.getItem().getSkills(ItemSkillType.NORMAL); + if (normalSkills != null) + { + for (ItemSkillHolder holder : normalSkills) { - LOGGER.warning("Inventory.ItemSkillsListener.Weapon: Incorrect skill: " + holder); + if (player.getSkillLevel(holder.getSkillId()) >= holder.getSkillLevel()) + { + continue; + } + + final Skill skill = holder.getSkill(); + if (skill != null) + { + if (skill.isPassive() && !skill.checkConditions(SkillConditionScope.PASSIVE, player, player)) + { + continue; + } + + if (addedSkills.containsKey(holder.getSkill().getId())) + { + if (addedSkills.get(holder.getSkill().getId()).getLevel() < holder.getSkill().getLevel()) + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + } + else + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + + if (skill.isActive() && !player.hasSkillReuse(skill.getReuseHashCode())) + { + final int equipDelay = item.getEquipReuseDelay(); + if (equipDelay > 0) + { + player.addTimeStamp(skill, equipDelay); + player.disableSkill(skill, equipDelay); + } + updateTimestamp = true; + } + } } } } @@ -543,6 +622,11 @@ public abstract class Inventory extends ItemContainer // Must check all equipped items for enchant conditions. for (ItemInstance equipped : inventory.getPaperdollItems()) { + if (!equipped.getItem().hasSkills()) + { + continue; + } + final List otherEnchantSkills = equipped.getItem().getSkills(ItemSkillType.ON_ENCHANT); if (otherEnchantSkills == null) { @@ -565,18 +649,35 @@ public abstract class Inventory extends ItemContainer { continue; } - player.addSkill(skill, false); - update = true; + + if (addedSkills.containsKey(holder.getSkill().getId())) + { + if (addedSkills.get(holder.getSkill().getId()).getLevel() < holder.getSkill().getLevel()) + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + } + else + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } } } } // Apply skill, if weapon have "skills on equip" item.getItem().forEachSkill(ItemSkillType.ON_EQUIP, holder -> holder.getSkill().activateSkill(player, player)); - if (update) + + if (!addedSkills.isEmpty()) { + for (Skill skill : addedSkills.values()) + { + player.addSkill(skill, false); + } + player.sendSkillList(); } + if (updateTimestamp) { player.sendPacket(new SkillCoolTime(player)); @@ -2088,7 +2189,7 @@ public abstract class Inventory extends ItemContainer { if ((_paperdoll[i] != null) && (getPaperdollItemId(i) == item.getId())) { - // overwtite + // overwrite setPaperdollItem(i, item); return; } diff --git a/L2J_Mobius_2.5_Underground/java/org/l2jmobius/gameserver/model/items/Item.java b/L2J_Mobius_2.5_Underground/java/org/l2jmobius/gameserver/model/items/Item.java index e2255f8244..5556524f8d 100644 --- a/L2J_Mobius_2.5_Underground/java/org/l2jmobius/gameserver/model/items/Item.java +++ b/L2J_Mobius_2.5_Underground/java/org/l2jmobius/gameserver/model/items/Item.java @@ -747,6 +747,11 @@ public abstract class Item extends ListenersContainer implements IIdentifiable return _preConditions; } + public boolean hasSkills() + { + return _skills != null; + } + /** * Method to retrieve skills linked to this item armor and weapon: passive skills etcitem: skills used on item use <-- ??? * @return Skills linked to this item as SkillHolder[] diff --git a/L2J_Mobius_3.0_Helios/java/org/l2jmobius/gameserver/model/itemcontainer/Inventory.java b/L2J_Mobius_3.0_Helios/java/org/l2jmobius/gameserver/model/itemcontainer/Inventory.java index 372a79c0ed..47360c75df 100644 --- a/L2J_Mobius_3.0_Helios/java/org/l2jmobius/gameserver/model/itemcontainer/Inventory.java +++ b/L2J_Mobius_3.0_Helios/java/org/l2jmobius/gameserver/model/itemcontainer/Inventory.java @@ -21,7 +21,9 @@ import java.sql.PreparedStatement; import java.sql.ResultSet; import java.util.ArrayList; import java.util.Collection; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.Objects; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; @@ -298,6 +300,8 @@ public abstract class Inventory extends ItemContainer final PlayerInstance player = (PlayerInstance) inventory.getOwner(); final Item it = item.getItem(); + final Map addedSkills = new HashMap<>(1); + final Map removedSkills = new HashMap<>(1); boolean update = false; boolean updateTimestamp = false; @@ -310,81 +314,111 @@ public abstract class Inventory extends ItemContainer // Recalculate all stats player.getStat().recalculateStats(true); - final List onEnchantSkills = it.getSkills(ItemSkillType.ON_ENCHANT); - if (onEnchantSkills != null) - { - for (ItemSkillHolder holder : onEnchantSkills) - { - // Remove skills bestowed from +4 armor - if (item.getEnchantLevel() >= holder.getValue()) - { - player.removeSkill(holder.getSkill(), false, holder.getSkill().isPassive()); - update = true; - } - } - } - // Clear enchant bonus item.clearEnchantStats(); // Clear SA Bonus item.clearSpecialAbilities(); - final List normalSkills = it.getSkills(ItemSkillType.NORMAL); - if (normalSkills != null) + if (it.hasSkills()) { - for (ItemSkillHolder holder : normalSkills) + final List onEnchantSkills = it.getSkills(ItemSkillType.ON_ENCHANT); + if (onEnchantSkills != null) { - final Skill skill = holder.getSkill(); - if (skill != null) + for (ItemSkillHolder holder : onEnchantSkills) { - player.removeSkill(skill, false, skill.isPassive()); - update = true; - } - else - { - LOGGER.warning("Inventory.ItemSkillsListener.Weapon: Incorrect skill: " + holder); + // Remove skills bestowed from +4 armor + if (item.getEnchantLevel() >= holder.getValue()) + { + if (removedSkills.containsKey(holder.getSkill().getId())) + { + if (removedSkills.get(holder.getSkill().getId()).getLevel() < holder.getSkill().getLevel()) + { + removedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + } + else + { + removedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + update = true; + } } } - } - - if (item.isArmor()) - { - for (ItemInstance itm : inventory.getItems()) + + final List normalSkills = it.getSkills(ItemSkillType.NORMAL); + if (normalSkills != null) { - if (!itm.isEquipped() || itm.equals(item)) + for (ItemSkillHolder holder : normalSkills) { - continue; + final Skill skill = holder.getSkill(); + if (skill != null) + { + if (removedSkills.containsKey(holder.getSkill().getId())) + { + if (removedSkills.get(holder.getSkill().getId()).getLevel() < holder.getSkill().getLevel()) + { + removedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + } + else + { + removedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + update = true; + } } - - final List otherNormalSkills = itm.getItem().getSkills(ItemSkillType.NORMAL); - if (otherNormalSkills == null) + } + + if (item.isArmor()) + { + for (ItemInstance itm : inventory.getItems()) { - continue; - } - - for (ItemSkillHolder holder : otherNormalSkills) - { - if (player.getSkillLevel(holder.getSkillId()) != 0) + if (!itm.isEquipped() || itm.equals(item)) { continue; } - final Skill skill = holder.getSkill(); - if (skill != null) + final List otherNormalSkills = itm.getItem().getSkills(ItemSkillType.NORMAL); + if (otherNormalSkills == null) { - player.addSkill(skill, false); - if (skill.isActive() && !player.hasSkillReuse(skill.getReuseHashCode())) + continue; + } + + for (ItemSkillHolder holder : otherNormalSkills) + { + if (player.getSkillLevel(holder.getSkillId()) != 0) { - final int equipDelay = item.getEquipReuseDelay(); - if (equipDelay > 0) - { - player.addTimeStamp(skill, equipDelay); - player.disableSkill(skill, equipDelay); - } - updateTimestamp = true; + continue; + } + + final Skill skill = holder.getSkill(); + if (skill != null) + { + if (addedSkills.containsKey(holder.getSkill().getId())) + { + if (addedSkills.get(holder.getSkill().getId()).getLevel() < holder.getSkill().getLevel()) + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + } + else + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + + if (skill.isActive() && !player.hasSkillReuse(skill.getReuseHashCode())) + { + final int equipDelay = item.getEquipReuseDelay(); + if (equipDelay > 0) + { + player.addTimeStamp(skill, equipDelay); + player.disableSkill(skill, equipDelay); + } + updateTimestamp = true; + } + update = true; } - update = true; } } } @@ -393,6 +427,11 @@ public abstract class Inventory extends ItemContainer // Must check all equipped items for enchant conditions. for (ItemInstance equipped : inventory.getPaperdollItems()) { + if (!equipped.getItem().hasSkills()) + { + continue; + } + final List otherEnchantSkills = equipped.getItem().getSkills(ItemSkillType.ON_ENCHANT); if (otherEnchantSkills == null) { @@ -408,7 +447,17 @@ public abstract class Inventory extends ItemContainer // Check passive skill conditions. if (skill.isPassive() && !skill.checkConditions(SkillConditionScope.PASSIVE, player, player)) { - player.removeSkill(holder.getSkill(), false, holder.getSkill().isPassive()); + if (removedSkills.containsKey(holder.getSkill().getId())) + { + if (removedSkills.get(holder.getSkill().getId()).getLevel() < holder.getSkill().getLevel()) + { + removedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + } + else + { + removedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } update = true; } } @@ -428,10 +477,22 @@ public abstract class Inventory extends ItemContainer // Apply skill, if weapon have "skills on unequip" it.forEachSkill(ItemSkillType.ON_UNEQUIP, holder -> holder.getSkill().activateSkill(player, player)); + if (update) { + for (Skill skill : removedSkills.values()) + { + player.removeSkill(skill, false, skill.isPassive()); + } + + for (Skill skill : addedSkills.values()) + { + player.addSkill(skill, false); + } + player.sendSkillList(); } + if (updateTimestamp) { player.sendPacket(new SkillCoolTime(player)); @@ -452,14 +513,13 @@ public abstract class Inventory extends ItemContainer } final PlayerInstance player = (PlayerInstance) inventory.getOwner(); - // Any items equipped that result in expertise penalty do not give any skills at all. if (item.getItem().getCrystalType().getLevel() > player.getExpertiseLevel()) { return; } - boolean update = false; + final Map addedSkills = new HashMap<>(1); boolean updateTimestamp = false; // Apply augmentation bonuses on equip @@ -471,71 +531,90 @@ public abstract class Inventory extends ItemContainer // Recalculate all stats player.getStat().recalculateStats(true); - final List onEnchantSkills = item.getItem().getSkills(ItemSkillType.ON_ENCHANT); - if (onEnchantSkills != null) - { - for (ItemSkillHolder holder : onEnchantSkills) - { - if (player.getSkillLevel(holder.getSkillId()) >= holder.getSkillLevel()) - { - continue; - } - - // Add skills bestowed from +4 armor - if (item.getEnchantLevel() >= holder.getValue()) - { - final Skill skill = holder.getSkill(); - // Check passive skill conditions. - if (skill.isPassive() && !skill.checkConditions(SkillConditionScope.PASSIVE, player, player)) - { - continue; - } - player.addSkill(skill, false); - update = true; - } - } - } - // Apply enchant stats item.applyEnchantStats(); // Apply SA skill item.applySpecialAbilities(); - final List normalSkills = item.getItem().getSkills(ItemSkillType.NORMAL); - if (normalSkills != null) + if (item.getItem().hasSkills()) { - for (ItemSkillHolder holder : normalSkills) + final List onEnchantSkills = item.getItem().getSkills(ItemSkillType.ON_ENCHANT); + if (onEnchantSkills != null) { - if (player.getSkillLevel(holder.getSkillId()) >= holder.getSkillLevel()) + for (ItemSkillHolder holder : onEnchantSkills) { - continue; - } - - final Skill skill = holder.getSkill(); - if (skill != null) - { - if (skill.isPassive() && !skill.checkConditions(SkillConditionScope.PASSIVE, player, player)) + if (player.getSkillLevel(holder.getSkillId()) >= holder.getSkillLevel()) { continue; } - player.addSkill(skill, false); - if (skill.isActive() && !player.hasSkillReuse(skill.getReuseHashCode())) + // Add skills bestowed from +4 armor + if (item.getEnchantLevel() >= holder.getValue()) { - final int equipDelay = item.getEquipReuseDelay(); - if (equipDelay > 0) + final Skill skill = holder.getSkill(); + // Check passive skill conditions. + if (skill.isPassive() && !skill.checkConditions(SkillConditionScope.PASSIVE, player, player)) { - player.addTimeStamp(skill, equipDelay); - player.disableSkill(skill, equipDelay); + continue; + } + + if (addedSkills.containsKey(holder.getSkill().getId())) + { + if (addedSkills.get(holder.getSkill().getId()).getLevel() < holder.getSkill().getLevel()) + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + } + else + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); } - updateTimestamp = true; } - update = true; } - else + } + + final List normalSkills = item.getItem().getSkills(ItemSkillType.NORMAL); + if (normalSkills != null) + { + for (ItemSkillHolder holder : normalSkills) { - LOGGER.warning("Inventory.ItemSkillsListener.Weapon: Incorrect skill: " + holder); + if (player.getSkillLevel(holder.getSkillId()) >= holder.getSkillLevel()) + { + continue; + } + + final Skill skill = holder.getSkill(); + if (skill != null) + { + if (skill.isPassive() && !skill.checkConditions(SkillConditionScope.PASSIVE, player, player)) + { + continue; + } + + if (addedSkills.containsKey(holder.getSkill().getId())) + { + if (addedSkills.get(holder.getSkill().getId()).getLevel() < holder.getSkill().getLevel()) + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + } + else + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + + if (skill.isActive() && !player.hasSkillReuse(skill.getReuseHashCode())) + { + final int equipDelay = item.getEquipReuseDelay(); + if (equipDelay > 0) + { + player.addTimeStamp(skill, equipDelay); + player.disableSkill(skill, equipDelay); + } + updateTimestamp = true; + } + } } } } @@ -543,6 +622,11 @@ public abstract class Inventory extends ItemContainer // Must check all equipped items for enchant conditions. for (ItemInstance equipped : inventory.getPaperdollItems()) { + if (!equipped.getItem().hasSkills()) + { + continue; + } + final List otherEnchantSkills = equipped.getItem().getSkills(ItemSkillType.ON_ENCHANT); if (otherEnchantSkills == null) { @@ -565,18 +649,35 @@ public abstract class Inventory extends ItemContainer { continue; } - player.addSkill(skill, false); - update = true; + + if (addedSkills.containsKey(holder.getSkill().getId())) + { + if (addedSkills.get(holder.getSkill().getId()).getLevel() < holder.getSkill().getLevel()) + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + } + else + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } } } } // Apply skill, if weapon have "skills on equip" item.getItem().forEachSkill(ItemSkillType.ON_EQUIP, holder -> holder.getSkill().activateSkill(player, player)); - if (update) + + if (!addedSkills.isEmpty()) { + for (Skill skill : addedSkills.values()) + { + player.addSkill(skill, false); + } + player.sendSkillList(); } + if (updateTimestamp) { player.sendPacket(new SkillCoolTime(player)); @@ -2088,7 +2189,7 @@ public abstract class Inventory extends ItemContainer { if ((_paperdoll[i] != null) && (getPaperdollItemId(i) == item.getId())) { - // overwtite + // overwrite setPaperdollItem(i, item); return; } diff --git a/L2J_Mobius_3.0_Helios/java/org/l2jmobius/gameserver/model/items/Item.java b/L2J_Mobius_3.0_Helios/java/org/l2jmobius/gameserver/model/items/Item.java index e2255f8244..5556524f8d 100644 --- a/L2J_Mobius_3.0_Helios/java/org/l2jmobius/gameserver/model/items/Item.java +++ b/L2J_Mobius_3.0_Helios/java/org/l2jmobius/gameserver/model/items/Item.java @@ -747,6 +747,11 @@ public abstract class Item extends ListenersContainer implements IIdentifiable return _preConditions; } + public boolean hasSkills() + { + return _skills != null; + } + /** * Method to retrieve skills linked to this item armor and weapon: passive skills etcitem: skills used on item use <-- ??? * @return Skills linked to this item as SkillHolder[] diff --git a/L2J_Mobius_4.0_GrandCrusade/java/org/l2jmobius/gameserver/model/itemcontainer/Inventory.java b/L2J_Mobius_4.0_GrandCrusade/java/org/l2jmobius/gameserver/model/itemcontainer/Inventory.java index aea95b5c05..479bc56509 100644 --- a/L2J_Mobius_4.0_GrandCrusade/java/org/l2jmobius/gameserver/model/itemcontainer/Inventory.java +++ b/L2J_Mobius_4.0_GrandCrusade/java/org/l2jmobius/gameserver/model/itemcontainer/Inventory.java @@ -21,7 +21,9 @@ import java.sql.PreparedStatement; import java.sql.ResultSet; import java.util.ArrayList; import java.util.Collection; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.Objects; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; @@ -298,6 +300,8 @@ public abstract class Inventory extends ItemContainer final PlayerInstance player = (PlayerInstance) inventory.getOwner(); final Item it = item.getItem(); + final Map addedSkills = new HashMap<>(1); + final Map removedSkills = new HashMap<>(1); boolean update = false; boolean updateTimestamp = false; @@ -310,81 +314,111 @@ public abstract class Inventory extends ItemContainer // Recalculate all stats player.getStat().recalculateStats(true); - final List onEnchantSkills = it.getSkills(ItemSkillType.ON_ENCHANT); - if (onEnchantSkills != null) - { - for (ItemSkillHolder holder : onEnchantSkills) - { - // Remove skills bestowed from +4 armor - if (item.getEnchantLevel() >= holder.getValue()) - { - player.removeSkill(holder.getSkill(), false, holder.getSkill().isPassive()); - update = true; - } - } - } - // Clear enchant bonus item.clearEnchantStats(); // Clear SA Bonus item.clearSpecialAbilities(); - final List normalSkills = it.getSkills(ItemSkillType.NORMAL); - if (normalSkills != null) + if (it.hasSkills()) { - for (ItemSkillHolder holder : normalSkills) + final List onEnchantSkills = it.getSkills(ItemSkillType.ON_ENCHANT); + if (onEnchantSkills != null) { - final Skill skill = holder.getSkill(); - if (skill != null) + for (ItemSkillHolder holder : onEnchantSkills) { - player.removeSkill(skill, false, skill.isPassive()); - update = true; - } - else - { - LOGGER.warning("Inventory.ItemSkillsListener.Weapon: Incorrect skill: " + holder); + // Remove skills bestowed from +4 armor + if (item.getEnchantLevel() >= holder.getValue()) + { + if (removedSkills.containsKey(holder.getSkill().getId())) + { + if (removedSkills.get(holder.getSkill().getId()).getLevel() < holder.getSkill().getLevel()) + { + removedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + } + else + { + removedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + update = true; + } } } - } - - if (item.isArmor()) - { - for (ItemInstance itm : inventory.getItems()) + + final List normalSkills = it.getSkills(ItemSkillType.NORMAL); + if (normalSkills != null) { - if (!itm.isEquipped() || itm.equals(item)) + for (ItemSkillHolder holder : normalSkills) { - continue; + final Skill skill = holder.getSkill(); + if (skill != null) + { + if (removedSkills.containsKey(holder.getSkill().getId())) + { + if (removedSkills.get(holder.getSkill().getId()).getLevel() < holder.getSkill().getLevel()) + { + removedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + } + else + { + removedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + update = true; + } } - - final List otherNormalSkills = itm.getItem().getSkills(ItemSkillType.NORMAL); - if (otherNormalSkills == null) + } + + if (item.isArmor()) + { + for (ItemInstance itm : inventory.getItems()) { - continue; - } - - for (ItemSkillHolder holder : otherNormalSkills) - { - if (player.getSkillLevel(holder.getSkillId()) != 0) + if (!itm.isEquipped() || itm.equals(item)) { continue; } - final Skill skill = holder.getSkill(); - if (skill != null) + final List otherNormalSkills = itm.getItem().getSkills(ItemSkillType.NORMAL); + if (otherNormalSkills == null) { - player.addSkill(skill, false); - if (skill.isActive() && !player.hasSkillReuse(skill.getReuseHashCode())) + continue; + } + + for (ItemSkillHolder holder : otherNormalSkills) + { + if (player.getSkillLevel(holder.getSkillId()) != 0) { - final int equipDelay = item.getEquipReuseDelay(); - if (equipDelay > 0) - { - player.addTimeStamp(skill, equipDelay); - player.disableSkill(skill, equipDelay); - } - updateTimestamp = true; + continue; + } + + final Skill skill = holder.getSkill(); + if (skill != null) + { + if (addedSkills.containsKey(holder.getSkill().getId())) + { + if (addedSkills.get(holder.getSkill().getId()).getLevel() < holder.getSkill().getLevel()) + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + } + else + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + + if (skill.isActive() && !player.hasSkillReuse(skill.getReuseHashCode())) + { + final int equipDelay = item.getEquipReuseDelay(); + if (equipDelay > 0) + { + player.addTimeStamp(skill, equipDelay); + player.disableSkill(skill, equipDelay); + } + updateTimestamp = true; + } + update = true; } - update = true; } } } @@ -393,6 +427,11 @@ public abstract class Inventory extends ItemContainer // Must check all equipped items for enchant conditions. for (ItemInstance equipped : inventory.getPaperdollItems()) { + if (!equipped.getItem().hasSkills()) + { + continue; + } + final List otherEnchantSkills = equipped.getItem().getSkills(ItemSkillType.ON_ENCHANT); if (otherEnchantSkills == null) { @@ -408,7 +447,17 @@ public abstract class Inventory extends ItemContainer // Check passive skill conditions. if (skill.isPassive() && !skill.checkConditions(SkillConditionScope.PASSIVE, player, player)) { - player.removeSkill(holder.getSkill(), false, holder.getSkill().isPassive()); + if (removedSkills.containsKey(holder.getSkill().getId())) + { + if (removedSkills.get(holder.getSkill().getId()).getLevel() < holder.getSkill().getLevel()) + { + removedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + } + else + { + removedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } update = true; } } @@ -428,10 +477,22 @@ public abstract class Inventory extends ItemContainer // Apply skill, if weapon have "skills on unequip" it.forEachSkill(ItemSkillType.ON_UNEQUIP, holder -> holder.getSkill().activateSkill(player, player)); + if (update) { + for (Skill skill : removedSkills.values()) + { + player.removeSkill(skill, false, skill.isPassive()); + } + + for (Skill skill : addedSkills.values()) + { + player.addSkill(skill, false); + } + player.sendSkillList(); } + if (updateTimestamp) { player.sendPacket(new SkillCoolTime(player)); @@ -452,14 +513,13 @@ public abstract class Inventory extends ItemContainer } final PlayerInstance player = (PlayerInstance) inventory.getOwner(); - // Any items equipped that result in expertise penalty do not give any skills at all. if (item.getItem().getCrystalType().isGreater(player.getExpertiseLevel())) { return; } - boolean update = false; + final Map addedSkills = new HashMap<>(1); boolean updateTimestamp = false; // Apply augmentation bonuses on equip @@ -471,71 +531,90 @@ public abstract class Inventory extends ItemContainer // Recalculate all stats player.getStat().recalculateStats(true); - final List onEnchantSkills = item.getItem().getSkills(ItemSkillType.ON_ENCHANT); - if (onEnchantSkills != null) - { - for (ItemSkillHolder holder : onEnchantSkills) - { - if (player.getSkillLevel(holder.getSkillId()) >= holder.getSkillLevel()) - { - continue; - } - - // Add skills bestowed from +4 armor - if (item.getEnchantLevel() >= holder.getValue()) - { - final Skill skill = holder.getSkill(); - // Check passive skill conditions. - if (skill.isPassive() && !skill.checkConditions(SkillConditionScope.PASSIVE, player, player)) - { - continue; - } - player.addSkill(skill, false); - update = true; - } - } - } - // Apply enchant stats item.applyEnchantStats(); // Apply SA skill item.applySpecialAbilities(); - final List normalSkills = item.getItem().getSkills(ItemSkillType.NORMAL); - if (normalSkills != null) + if (item.getItem().hasSkills()) { - for (ItemSkillHolder holder : normalSkills) + final List onEnchantSkills = item.getItem().getSkills(ItemSkillType.ON_ENCHANT); + if (onEnchantSkills != null) { - if (player.getSkillLevel(holder.getSkillId()) >= holder.getSkillLevel()) + for (ItemSkillHolder holder : onEnchantSkills) { - continue; - } - - final Skill skill = holder.getSkill(); - if (skill != null) - { - if (skill.isPassive() && !skill.checkConditions(SkillConditionScope.PASSIVE, player, player)) + if (player.getSkillLevel(holder.getSkillId()) >= holder.getSkillLevel()) { continue; } - player.addSkill(skill, false); - if (skill.isActive() && !player.hasSkillReuse(skill.getReuseHashCode())) + // Add skills bestowed from +4 armor + if (item.getEnchantLevel() >= holder.getValue()) { - final int equipDelay = item.getEquipReuseDelay(); - if (equipDelay > 0) + final Skill skill = holder.getSkill(); + // Check passive skill conditions. + if (skill.isPassive() && !skill.checkConditions(SkillConditionScope.PASSIVE, player, player)) { - player.addTimeStamp(skill, equipDelay); - player.disableSkill(skill, equipDelay); + continue; + } + + if (addedSkills.containsKey(holder.getSkill().getId())) + { + if (addedSkills.get(holder.getSkill().getId()).getLevel() < holder.getSkill().getLevel()) + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + } + else + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); } - updateTimestamp = true; } - update = true; } - else + } + + final List normalSkills = item.getItem().getSkills(ItemSkillType.NORMAL); + if (normalSkills != null) + { + for (ItemSkillHolder holder : normalSkills) { - LOGGER.warning("Inventory.ItemSkillsListener.Weapon: Incorrect skill: " + holder); + if (player.getSkillLevel(holder.getSkillId()) >= holder.getSkillLevel()) + { + continue; + } + + final Skill skill = holder.getSkill(); + if (skill != null) + { + if (skill.isPassive() && !skill.checkConditions(SkillConditionScope.PASSIVE, player, player)) + { + continue; + } + + if (addedSkills.containsKey(holder.getSkill().getId())) + { + if (addedSkills.get(holder.getSkill().getId()).getLevel() < holder.getSkill().getLevel()) + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + } + else + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + + if (skill.isActive() && !player.hasSkillReuse(skill.getReuseHashCode())) + { + final int equipDelay = item.getEquipReuseDelay(); + if (equipDelay > 0) + { + player.addTimeStamp(skill, equipDelay); + player.disableSkill(skill, equipDelay); + } + updateTimestamp = true; + } + } } } } @@ -543,6 +622,11 @@ public abstract class Inventory extends ItemContainer // Must check all equipped items for enchant conditions. for (ItemInstance equipped : inventory.getPaperdollItems()) { + if (!equipped.getItem().hasSkills()) + { + continue; + } + final List otherEnchantSkills = equipped.getItem().getSkills(ItemSkillType.ON_ENCHANT); if (otherEnchantSkills == null) { @@ -565,18 +649,35 @@ public abstract class Inventory extends ItemContainer { continue; } - player.addSkill(skill, false); - update = true; + + if (addedSkills.containsKey(holder.getSkill().getId())) + { + if (addedSkills.get(holder.getSkill().getId()).getLevel() < holder.getSkill().getLevel()) + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + } + else + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } } } } // Apply skill, if weapon have "skills on equip" item.getItem().forEachSkill(ItemSkillType.ON_EQUIP, holder -> holder.getSkill().activateSkill(player, player)); - if (update) + + if (!addedSkills.isEmpty()) { + for (Skill skill : addedSkills.values()) + { + player.addSkill(skill, false); + } + player.sendSkillList(); } + if (updateTimestamp) { player.sendPacket(new SkillCoolTime(player)); @@ -2088,7 +2189,7 @@ public abstract class Inventory extends ItemContainer { if ((_paperdoll[i] != null) && (getPaperdollItemId(i) == item.getId())) { - // overwtite + // overwrite setPaperdollItem(i, item); return; } diff --git a/L2J_Mobius_4.0_GrandCrusade/java/org/l2jmobius/gameserver/model/items/Item.java b/L2J_Mobius_4.0_GrandCrusade/java/org/l2jmobius/gameserver/model/items/Item.java index 4b90bea687..4660056074 100644 --- a/L2J_Mobius_4.0_GrandCrusade/java/org/l2jmobius/gameserver/model/items/Item.java +++ b/L2J_Mobius_4.0_GrandCrusade/java/org/l2jmobius/gameserver/model/items/Item.java @@ -747,6 +747,11 @@ public abstract class Item extends ListenersContainer implements IIdentifiable return _preConditions; } + public boolean hasSkills() + { + return _skills != null; + } + /** * Method to retrieve skills linked to this item armor and weapon: passive skills etcitem: skills used on item use <-- ??? * @return Skills linked to this item as SkillHolder[] diff --git a/L2J_Mobius_5.0_Salvation/java/org/l2jmobius/gameserver/model/itemcontainer/Inventory.java b/L2J_Mobius_5.0_Salvation/java/org/l2jmobius/gameserver/model/itemcontainer/Inventory.java index e151ca6ba8..2585945510 100644 --- a/L2J_Mobius_5.0_Salvation/java/org/l2jmobius/gameserver/model/itemcontainer/Inventory.java +++ b/L2J_Mobius_5.0_Salvation/java/org/l2jmobius/gameserver/model/itemcontainer/Inventory.java @@ -21,7 +21,9 @@ import java.sql.PreparedStatement; import java.sql.ResultSet; import java.util.ArrayList; import java.util.Collection; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.Objects; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; @@ -306,6 +308,8 @@ public abstract class Inventory extends ItemContainer final PlayerInstance player = (PlayerInstance) inventory.getOwner(); final Item it = item.getItem(); + final Map addedSkills = new HashMap<>(1); + final Map removedSkills = new HashMap<>(1); boolean update = false; boolean updateTimestamp = false; @@ -318,81 +322,111 @@ public abstract class Inventory extends ItemContainer // Recalculate all stats player.getStat().recalculateStats(true); - final List onEnchantSkills = it.getSkills(ItemSkillType.ON_ENCHANT); - if (onEnchantSkills != null) - { - for (ItemSkillHolder holder : onEnchantSkills) - { - // Remove skills bestowed from +4 armor - if (item.getEnchantLevel() >= holder.getValue()) - { - player.removeSkill(holder.getSkill(), false, holder.getSkill().isPassive()); - update = true; - } - } - } - // Clear enchant bonus item.clearEnchantStats(); // Clear SA Bonus item.clearSpecialAbilities(); - final List normalSkills = it.getSkills(ItemSkillType.NORMAL); - if (normalSkills != null) + if (it.hasSkills()) { - for (ItemSkillHolder holder : normalSkills) + final List onEnchantSkills = it.getSkills(ItemSkillType.ON_ENCHANT); + if (onEnchantSkills != null) { - final Skill skill = holder.getSkill(); - if (skill != null) + for (ItemSkillHolder holder : onEnchantSkills) { - player.removeSkill(skill, false, skill.isPassive()); - update = true; - } - else - { - LOGGER.warning("Inventory.ItemSkillsListener.Weapon: Incorrect skill: " + holder); + // Remove skills bestowed from +4 armor + if (item.getEnchantLevel() >= holder.getValue()) + { + if (removedSkills.containsKey(holder.getSkill().getId())) + { + if (removedSkills.get(holder.getSkill().getId()).getLevel() < holder.getSkill().getLevel()) + { + removedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + } + else + { + removedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + update = true; + } } } - } - - if (item.isArmor()) - { - for (ItemInstance itm : inventory.getItems()) + + final List normalSkills = it.getSkills(ItemSkillType.NORMAL); + if (normalSkills != null) { - if (!itm.isEquipped() || itm.equals(item)) + for (ItemSkillHolder holder : normalSkills) { - continue; + final Skill skill = holder.getSkill(); + if (skill != null) + { + if (removedSkills.containsKey(holder.getSkill().getId())) + { + if (removedSkills.get(holder.getSkill().getId()).getLevel() < holder.getSkill().getLevel()) + { + removedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + } + else + { + removedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + update = true; + } } - - final List otherNormalSkills = itm.getItem().getSkills(ItemSkillType.NORMAL); - if (otherNormalSkills == null) + } + + if (item.isArmor()) + { + for (ItemInstance itm : inventory.getItems()) { - continue; - } - - for (ItemSkillHolder holder : otherNormalSkills) - { - if (player.getSkillLevel(holder.getSkillId()) != 0) + if (!itm.isEquipped() || itm.equals(item)) { continue; } - final Skill skill = holder.getSkill(); - if (skill != null) + final List otherNormalSkills = itm.getItem().getSkills(ItemSkillType.NORMAL); + if (otherNormalSkills == null) { - player.addSkill(skill, false); - if (skill.isActive() && !player.hasSkillReuse(skill.getReuseHashCode())) + continue; + } + + for (ItemSkillHolder holder : otherNormalSkills) + { + if (player.getSkillLevel(holder.getSkillId()) != 0) { - final int equipDelay = item.getEquipReuseDelay(); - if (equipDelay > 0) - { - player.addTimeStamp(skill, equipDelay); - player.disableSkill(skill, equipDelay); - } - updateTimestamp = true; + continue; + } + + final Skill skill = holder.getSkill(); + if (skill != null) + { + if (addedSkills.containsKey(holder.getSkill().getId())) + { + if (addedSkills.get(holder.getSkill().getId()).getLevel() < holder.getSkill().getLevel()) + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + } + else + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + + if (skill.isActive() && !player.hasSkillReuse(skill.getReuseHashCode())) + { + final int equipDelay = item.getEquipReuseDelay(); + if (equipDelay > 0) + { + player.addTimeStamp(skill, equipDelay); + player.disableSkill(skill, equipDelay); + } + updateTimestamp = true; + } + update = true; } - update = true; } } } @@ -401,6 +435,11 @@ public abstract class Inventory extends ItemContainer // Must check all equipped items for enchant conditions. for (ItemInstance equipped : inventory.getPaperdollItems()) { + if (!equipped.getItem().hasSkills()) + { + continue; + } + final List otherEnchantSkills = equipped.getItem().getSkills(ItemSkillType.ON_ENCHANT); if (otherEnchantSkills == null) { @@ -416,7 +455,17 @@ public abstract class Inventory extends ItemContainer // Check passive skill conditions. if (skill.isPassive() && !skill.checkConditions(SkillConditionScope.PASSIVE, player, player)) { - player.removeSkill(holder.getSkill(), false, holder.getSkill().isPassive()); + if (removedSkills.containsKey(holder.getSkill().getId())) + { + if (removedSkills.get(holder.getSkill().getId()).getLevel() < holder.getSkill().getLevel()) + { + removedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + } + else + { + removedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } update = true; } } @@ -442,8 +491,19 @@ public abstract class Inventory extends ItemContainer if (update) { + for (Skill skill : removedSkills.values()) + { + player.removeSkill(skill, false, skill.isPassive()); + } + + for (Skill skill : addedSkills.values()) + { + player.addSkill(skill, false); + } + player.sendSkillList(); } + if (updateTimestamp) { player.sendPacket(new SkillCoolTime(player)); @@ -464,14 +524,13 @@ public abstract class Inventory extends ItemContainer } final PlayerInstance player = (PlayerInstance) inventory.getOwner(); - // Any items equipped that result in expertise penalty do not give any skills at all. if (item.getItem().getCrystalType().isGreater(player.getExpertiseLevel())) { return; } - boolean update = false; + final Map addedSkills = new HashMap<>(1); boolean updateTimestamp = false; // Apply augmentation bonuses on equip @@ -483,71 +542,90 @@ public abstract class Inventory extends ItemContainer // Recalculate all stats player.getStat().recalculateStats(true); - final List onEnchantSkills = item.getItem().getSkills(ItemSkillType.ON_ENCHANT); - if (onEnchantSkills != null) - { - for (ItemSkillHolder holder : onEnchantSkills) - { - if (player.getSkillLevel(holder.getSkillId()) >= holder.getSkillLevel()) - { - continue; - } - - // Add skills bestowed from +4 armor - if (item.getEnchantLevel() >= holder.getValue()) - { - final Skill skill = holder.getSkill(); - // Check passive skill conditions. - if (skill.isPassive() && !skill.checkConditions(SkillConditionScope.PASSIVE, player, player)) - { - continue; - } - player.addSkill(skill, false); - update = true; - } - } - } - // Apply enchant stats item.applyEnchantStats(); // Apply SA skill item.applySpecialAbilities(); - final List normalSkills = item.getItem().getSkills(ItemSkillType.NORMAL); - if (normalSkills != null) + if (item.getItem().hasSkills()) { - for (ItemSkillHolder holder : normalSkills) + final List onEnchantSkills = item.getItem().getSkills(ItemSkillType.ON_ENCHANT); + if (onEnchantSkills != null) { - if (player.getSkillLevel(holder.getSkillId()) >= holder.getSkillLevel()) + for (ItemSkillHolder holder : onEnchantSkills) { - continue; - } - - final Skill skill = holder.getSkill(); - if (skill != null) - { - if (skill.isPassive() && !skill.checkConditions(SkillConditionScope.PASSIVE, player, player)) + if (player.getSkillLevel(holder.getSkillId()) >= holder.getSkillLevel()) { continue; } - player.addSkill(skill, false); - if (skill.isActive() && !player.hasSkillReuse(skill.getReuseHashCode())) + // Add skills bestowed from +4 armor + if (item.getEnchantLevel() >= holder.getValue()) { - final int equipDelay = item.getEquipReuseDelay(); - if (equipDelay > 0) + final Skill skill = holder.getSkill(); + // Check passive skill conditions. + if (skill.isPassive() && !skill.checkConditions(SkillConditionScope.PASSIVE, player, player)) { - player.addTimeStamp(skill, equipDelay); - player.disableSkill(skill, equipDelay); + continue; + } + + if (addedSkills.containsKey(holder.getSkill().getId())) + { + if (addedSkills.get(holder.getSkill().getId()).getLevel() < holder.getSkill().getLevel()) + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + } + else + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); } - updateTimestamp = true; } - update = true; } - else + } + + final List normalSkills = item.getItem().getSkills(ItemSkillType.NORMAL); + if (normalSkills != null) + { + for (ItemSkillHolder holder : normalSkills) { - LOGGER.warning("Inventory.ItemSkillsListener.Weapon: Incorrect skill: " + holder); + if (player.getSkillLevel(holder.getSkillId()) >= holder.getSkillLevel()) + { + continue; + } + + final Skill skill = holder.getSkill(); + if (skill != null) + { + if (skill.isPassive() && !skill.checkConditions(SkillConditionScope.PASSIVE, player, player)) + { + continue; + } + + if (addedSkills.containsKey(holder.getSkill().getId())) + { + if (addedSkills.get(holder.getSkill().getId()).getLevel() < holder.getSkill().getLevel()) + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + } + else + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + + if (skill.isActive() && !player.hasSkillReuse(skill.getReuseHashCode())) + { + final int equipDelay = item.getEquipReuseDelay(); + if (equipDelay > 0) + { + player.addTimeStamp(skill, equipDelay); + player.disableSkill(skill, equipDelay); + } + updateTimestamp = true; + } + } } } } @@ -555,6 +633,11 @@ public abstract class Inventory extends ItemContainer // Must check all equipped items for enchant conditions. for (ItemInstance equipped : inventory.getPaperdollItems()) { + if (!equipped.getItem().hasSkills()) + { + continue; + } + final List otherEnchantSkills = equipped.getItem().getSkills(ItemSkillType.ON_ENCHANT); if (otherEnchantSkills == null) { @@ -577,8 +660,18 @@ public abstract class Inventory extends ItemContainer { continue; } - player.addSkill(skill, false); - update = true; + + if (addedSkills.containsKey(holder.getSkill().getId())) + { + if (addedSkills.get(holder.getSkill().getId()).getLevel() < holder.getSkill().getLevel()) + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + } + else + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } } } } @@ -589,10 +682,16 @@ public abstract class Inventory extends ItemContainer item.getItem().forEachSkill(ItemSkillType.ON_EQUIP, holder -> holder.getSkill().activateSkill(player, player)); } - if (update) + if (!addedSkills.isEmpty()) { + for (Skill skill : addedSkills.values()) + { + player.addSkill(skill, false); + } + player.sendSkillList(); } + if (updateTimestamp) { player.sendPacket(new SkillCoolTime(player)); diff --git a/L2J_Mobius_5.0_Salvation/java/org/l2jmobius/gameserver/model/items/Item.java b/L2J_Mobius_5.0_Salvation/java/org/l2jmobius/gameserver/model/items/Item.java index 8d7986f570..edc729883d 100644 --- a/L2J_Mobius_5.0_Salvation/java/org/l2jmobius/gameserver/model/items/Item.java +++ b/L2J_Mobius_5.0_Salvation/java/org/l2jmobius/gameserver/model/items/Item.java @@ -748,6 +748,11 @@ public abstract class Item extends ListenersContainer implements IIdentifiable return _preConditions; } + public boolean hasSkills() + { + return _skills != null; + } + /** * Method to retrieve skills linked to this item armor and weapon: passive skills etcitem: skills used on item use <-- ??? * @return Skills linked to this item as SkillHolder[] diff --git a/L2J_Mobius_5.5_EtinasFate/java/org/l2jmobius/gameserver/model/itemcontainer/Inventory.java b/L2J_Mobius_5.5_EtinasFate/java/org/l2jmobius/gameserver/model/itemcontainer/Inventory.java index fcd22d3e7b..08e4d99d8a 100644 --- a/L2J_Mobius_5.5_EtinasFate/java/org/l2jmobius/gameserver/model/itemcontainer/Inventory.java +++ b/L2J_Mobius_5.5_EtinasFate/java/org/l2jmobius/gameserver/model/itemcontainer/Inventory.java @@ -21,7 +21,9 @@ import java.sql.PreparedStatement; import java.sql.ResultSet; import java.util.ArrayList; import java.util.Collection; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.Objects; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; @@ -329,6 +331,8 @@ public abstract class Inventory extends ItemContainer final PlayerInstance player = (PlayerInstance) inventory.getOwner(); final Item it = item.getItem(); + final Map addedSkills = new HashMap<>(1); + final Map removedSkills = new HashMap<>(1); boolean update = false; boolean updateTimestamp = false; @@ -341,81 +345,111 @@ public abstract class Inventory extends ItemContainer // Recalculate all stats player.getStat().recalculateStats(true); - final List onEnchantSkills = it.getSkills(ItemSkillType.ON_ENCHANT); - if (onEnchantSkills != null) - { - for (ItemSkillHolder holder : onEnchantSkills) - { - // Remove skills bestowed from +4 armor - if (item.getEnchantLevel() >= holder.getValue()) - { - player.removeSkill(holder.getSkill(), false, holder.getSkill().isPassive()); - update = true; - } - } - } - // Clear enchant bonus item.clearEnchantStats(); // Clear SA Bonus item.clearSpecialAbilities(); - final List normalSkills = it.getSkills(ItemSkillType.NORMAL); - if (normalSkills != null) + if (it.hasSkills()) { - for (ItemSkillHolder holder : normalSkills) + final List onEnchantSkills = it.getSkills(ItemSkillType.ON_ENCHANT); + if (onEnchantSkills != null) { - final Skill skill = holder.getSkill(); - if (skill != null) + for (ItemSkillHolder holder : onEnchantSkills) { - player.removeSkill(skill, false, skill.isPassive()); - update = true; - } - else - { - LOGGER.warning("Inventory.ItemSkillsListener.Weapon: Incorrect skill: " + holder); + // Remove skills bestowed from +4 armor + if (item.getEnchantLevel() >= holder.getValue()) + { + if (removedSkills.containsKey(holder.getSkill().getId())) + { + if (removedSkills.get(holder.getSkill().getId()).getLevel() < holder.getSkill().getLevel()) + { + removedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + } + else + { + removedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + update = true; + } } } - } - - if (item.isArmor()) - { - for (ItemInstance itm : inventory.getItems()) + + final List normalSkills = it.getSkills(ItemSkillType.NORMAL); + if (normalSkills != null) { - if (!itm.isEquipped() || itm.equals(item)) + for (ItemSkillHolder holder : normalSkills) { - continue; + final Skill skill = holder.getSkill(); + if (skill != null) + { + if (removedSkills.containsKey(holder.getSkill().getId())) + { + if (removedSkills.get(holder.getSkill().getId()).getLevel() < holder.getSkill().getLevel()) + { + removedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + } + else + { + removedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + update = true; + } } - - final List otherNormalSkills = itm.getItem().getSkills(ItemSkillType.NORMAL); - if (otherNormalSkills == null) + } + + if (item.isArmor()) + { + for (ItemInstance itm : inventory.getItems()) { - continue; - } - - for (ItemSkillHolder holder : otherNormalSkills) - { - if (player.getSkillLevel(holder.getSkillId()) != 0) + if (!itm.isEquipped() || itm.equals(item)) { continue; } - final Skill skill = holder.getSkill(); - if (skill != null) + final List otherNormalSkills = itm.getItem().getSkills(ItemSkillType.NORMAL); + if (otherNormalSkills == null) { - player.addSkill(skill, false); - if (skill.isActive() && !player.hasSkillReuse(skill.getReuseHashCode())) + continue; + } + + for (ItemSkillHolder holder : otherNormalSkills) + { + if (player.getSkillLevel(holder.getSkillId()) != 0) { - final int equipDelay = item.getEquipReuseDelay(); - if (equipDelay > 0) - { - player.addTimeStamp(skill, equipDelay); - player.disableSkill(skill, equipDelay); - } - updateTimestamp = true; + continue; + } + + final Skill skill = holder.getSkill(); + if (skill != null) + { + if (addedSkills.containsKey(holder.getSkill().getId())) + { + if (addedSkills.get(holder.getSkill().getId()).getLevel() < holder.getSkill().getLevel()) + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + } + else + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + + if (skill.isActive() && !player.hasSkillReuse(skill.getReuseHashCode())) + { + final int equipDelay = item.getEquipReuseDelay(); + if (equipDelay > 0) + { + player.addTimeStamp(skill, equipDelay); + player.disableSkill(skill, equipDelay); + } + updateTimestamp = true; + } + update = true; } - update = true; } } } @@ -424,6 +458,11 @@ public abstract class Inventory extends ItemContainer // Must check all equipped items for enchant conditions. for (ItemInstance equipped : inventory.getPaperdollItems()) { + if (!equipped.getItem().hasSkills()) + { + continue; + } + final List otherEnchantSkills = equipped.getItem().getSkills(ItemSkillType.ON_ENCHANT); if (otherEnchantSkills == null) { @@ -439,7 +478,17 @@ public abstract class Inventory extends ItemContainer // Check passive skill conditions. if (skill.isPassive() && !skill.checkConditions(SkillConditionScope.PASSIVE, player, player)) { - player.removeSkill(holder.getSkill(), false, holder.getSkill().isPassive()); + if (removedSkills.containsKey(holder.getSkill().getId())) + { + if (removedSkills.get(holder.getSkill().getId()).getLevel() < holder.getSkill().getLevel()) + { + removedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + } + else + { + removedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } update = true; } } @@ -465,8 +514,19 @@ public abstract class Inventory extends ItemContainer if (update) { + for (Skill skill : removedSkills.values()) + { + player.removeSkill(skill, false, skill.isPassive()); + } + + for (Skill skill : addedSkills.values()) + { + player.addSkill(skill, false); + } + player.sendSkillList(); } + if (updateTimestamp) { player.sendPacket(new SkillCoolTime(player)); @@ -487,14 +547,13 @@ public abstract class Inventory extends ItemContainer } final PlayerInstance player = (PlayerInstance) inventory.getOwner(); - // Any items equipped that result in expertise penalty do not give any skills at all. if (item.getItem().getCrystalType().isGreater(player.getExpertiseLevel())) { return; } - boolean update = false; + final Map addedSkills = new HashMap<>(1); boolean updateTimestamp = false; // Apply augmentation bonuses on equip @@ -506,71 +565,90 @@ public abstract class Inventory extends ItemContainer // Recalculate all stats player.getStat().recalculateStats(true); - final List onEnchantSkills = item.getItem().getSkills(ItemSkillType.ON_ENCHANT); - if (onEnchantSkills != null) - { - for (ItemSkillHolder holder : onEnchantSkills) - { - if (player.getSkillLevel(holder.getSkillId()) >= holder.getSkillLevel()) - { - continue; - } - - // Add skills bestowed from +4 armor - if (item.getEnchantLevel() >= holder.getValue()) - { - final Skill skill = holder.getSkill(); - // Check passive skill conditions. - if (skill.isPassive() && !skill.checkConditions(SkillConditionScope.PASSIVE, player, player)) - { - continue; - } - player.addSkill(skill, false); - update = true; - } - } - } - // Apply enchant stats item.applyEnchantStats(); // Apply SA skill item.applySpecialAbilities(); - final List normalSkills = item.getItem().getSkills(ItemSkillType.NORMAL); - if (normalSkills != null) + if (item.getItem().hasSkills()) { - for (ItemSkillHolder holder : normalSkills) + final List onEnchantSkills = item.getItem().getSkills(ItemSkillType.ON_ENCHANT); + if (onEnchantSkills != null) { - if (player.getSkillLevel(holder.getSkillId()) >= holder.getSkillLevel()) + for (ItemSkillHolder holder : onEnchantSkills) { - continue; - } - - final Skill skill = holder.getSkill(); - if (skill != null) - { - if (skill.isPassive() && !skill.checkConditions(SkillConditionScope.PASSIVE, player, player)) + if (player.getSkillLevel(holder.getSkillId()) >= holder.getSkillLevel()) { continue; } - player.addSkill(skill, false); - if (skill.isActive() && !player.hasSkillReuse(skill.getReuseHashCode())) + // Add skills bestowed from +4 armor + if (item.getEnchantLevel() >= holder.getValue()) { - final int equipDelay = item.getEquipReuseDelay(); - if (equipDelay > 0) + final Skill skill = holder.getSkill(); + // Check passive skill conditions. + if (skill.isPassive() && !skill.checkConditions(SkillConditionScope.PASSIVE, player, player)) { - player.addTimeStamp(skill, equipDelay); - player.disableSkill(skill, equipDelay); + continue; + } + + if (addedSkills.containsKey(holder.getSkill().getId())) + { + if (addedSkills.get(holder.getSkill().getId()).getLevel() < holder.getSkill().getLevel()) + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + } + else + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); } - updateTimestamp = true; } - update = true; } - else + } + + final List normalSkills = item.getItem().getSkills(ItemSkillType.NORMAL); + if (normalSkills != null) + { + for (ItemSkillHolder holder : normalSkills) { - LOGGER.warning("Inventory.ItemSkillsListener.Weapon: Incorrect skill: " + holder); + if (player.getSkillLevel(holder.getSkillId()) >= holder.getSkillLevel()) + { + continue; + } + + final Skill skill = holder.getSkill(); + if (skill != null) + { + if (skill.isPassive() && !skill.checkConditions(SkillConditionScope.PASSIVE, player, player)) + { + continue; + } + + if (addedSkills.containsKey(holder.getSkill().getId())) + { + if (addedSkills.get(holder.getSkill().getId()).getLevel() < holder.getSkill().getLevel()) + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + } + else + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + + if (skill.isActive() && !player.hasSkillReuse(skill.getReuseHashCode())) + { + final int equipDelay = item.getEquipReuseDelay(); + if (equipDelay > 0) + { + player.addTimeStamp(skill, equipDelay); + player.disableSkill(skill, equipDelay); + } + updateTimestamp = true; + } + } } } } @@ -578,6 +656,11 @@ public abstract class Inventory extends ItemContainer // Must check all equipped items for enchant conditions. for (ItemInstance equipped : inventory.getPaperdollItems()) { + if (!equipped.getItem().hasSkills()) + { + continue; + } + final List otherEnchantSkills = equipped.getItem().getSkills(ItemSkillType.ON_ENCHANT); if (otherEnchantSkills == null) { @@ -600,8 +683,18 @@ public abstract class Inventory extends ItemContainer { continue; } - player.addSkill(skill, false); - update = true; + + if (addedSkills.containsKey(holder.getSkill().getId())) + { + if (addedSkills.get(holder.getSkill().getId()).getLevel() < holder.getSkill().getLevel()) + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + } + else + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } } } } @@ -612,10 +705,16 @@ public abstract class Inventory extends ItemContainer item.getItem().forEachSkill(ItemSkillType.ON_EQUIP, holder -> holder.getSkill().activateSkill(player, player)); } - if (update) + if (!addedSkills.isEmpty()) { + for (Skill skill : addedSkills.values()) + { + player.addSkill(skill, false); + } + player.sendSkillList(); } + if (updateTimestamp) { player.sendPacket(new SkillCoolTime(player)); diff --git a/L2J_Mobius_5.5_EtinasFate/java/org/l2jmobius/gameserver/model/items/Item.java b/L2J_Mobius_5.5_EtinasFate/java/org/l2jmobius/gameserver/model/items/Item.java index ceb245879d..e55815b751 100644 --- a/L2J_Mobius_5.5_EtinasFate/java/org/l2jmobius/gameserver/model/items/Item.java +++ b/L2J_Mobius_5.5_EtinasFate/java/org/l2jmobius/gameserver/model/items/Item.java @@ -753,6 +753,11 @@ public abstract class Item extends ListenersContainer implements IIdentifiable return _preConditions; } + public boolean hasSkills() + { + return _skills != null; + } + /** * Method to retrieve skills linked to this item armor and weapon: passive skills etcitem: skills used on item use <-- ??? * @return Skills linked to this item as SkillHolder[] diff --git a/L2J_Mobius_6.0_Fafurion/java/org/l2jmobius/gameserver/model/itemcontainer/Inventory.java b/L2J_Mobius_6.0_Fafurion/java/org/l2jmobius/gameserver/model/itemcontainer/Inventory.java index fcd22d3e7b..08e4d99d8a 100644 --- a/L2J_Mobius_6.0_Fafurion/java/org/l2jmobius/gameserver/model/itemcontainer/Inventory.java +++ b/L2J_Mobius_6.0_Fafurion/java/org/l2jmobius/gameserver/model/itemcontainer/Inventory.java @@ -21,7 +21,9 @@ import java.sql.PreparedStatement; import java.sql.ResultSet; import java.util.ArrayList; import java.util.Collection; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.Objects; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; @@ -329,6 +331,8 @@ public abstract class Inventory extends ItemContainer final PlayerInstance player = (PlayerInstance) inventory.getOwner(); final Item it = item.getItem(); + final Map addedSkills = new HashMap<>(1); + final Map removedSkills = new HashMap<>(1); boolean update = false; boolean updateTimestamp = false; @@ -341,81 +345,111 @@ public abstract class Inventory extends ItemContainer // Recalculate all stats player.getStat().recalculateStats(true); - final List onEnchantSkills = it.getSkills(ItemSkillType.ON_ENCHANT); - if (onEnchantSkills != null) - { - for (ItemSkillHolder holder : onEnchantSkills) - { - // Remove skills bestowed from +4 armor - if (item.getEnchantLevel() >= holder.getValue()) - { - player.removeSkill(holder.getSkill(), false, holder.getSkill().isPassive()); - update = true; - } - } - } - // Clear enchant bonus item.clearEnchantStats(); // Clear SA Bonus item.clearSpecialAbilities(); - final List normalSkills = it.getSkills(ItemSkillType.NORMAL); - if (normalSkills != null) + if (it.hasSkills()) { - for (ItemSkillHolder holder : normalSkills) + final List onEnchantSkills = it.getSkills(ItemSkillType.ON_ENCHANT); + if (onEnchantSkills != null) { - final Skill skill = holder.getSkill(); - if (skill != null) + for (ItemSkillHolder holder : onEnchantSkills) { - player.removeSkill(skill, false, skill.isPassive()); - update = true; - } - else - { - LOGGER.warning("Inventory.ItemSkillsListener.Weapon: Incorrect skill: " + holder); + // Remove skills bestowed from +4 armor + if (item.getEnchantLevel() >= holder.getValue()) + { + if (removedSkills.containsKey(holder.getSkill().getId())) + { + if (removedSkills.get(holder.getSkill().getId()).getLevel() < holder.getSkill().getLevel()) + { + removedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + } + else + { + removedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + update = true; + } } } - } - - if (item.isArmor()) - { - for (ItemInstance itm : inventory.getItems()) + + final List normalSkills = it.getSkills(ItemSkillType.NORMAL); + if (normalSkills != null) { - if (!itm.isEquipped() || itm.equals(item)) + for (ItemSkillHolder holder : normalSkills) { - continue; + final Skill skill = holder.getSkill(); + if (skill != null) + { + if (removedSkills.containsKey(holder.getSkill().getId())) + { + if (removedSkills.get(holder.getSkill().getId()).getLevel() < holder.getSkill().getLevel()) + { + removedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + } + else + { + removedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + update = true; + } } - - final List otherNormalSkills = itm.getItem().getSkills(ItemSkillType.NORMAL); - if (otherNormalSkills == null) + } + + if (item.isArmor()) + { + for (ItemInstance itm : inventory.getItems()) { - continue; - } - - for (ItemSkillHolder holder : otherNormalSkills) - { - if (player.getSkillLevel(holder.getSkillId()) != 0) + if (!itm.isEquipped() || itm.equals(item)) { continue; } - final Skill skill = holder.getSkill(); - if (skill != null) + final List otherNormalSkills = itm.getItem().getSkills(ItemSkillType.NORMAL); + if (otherNormalSkills == null) { - player.addSkill(skill, false); - if (skill.isActive() && !player.hasSkillReuse(skill.getReuseHashCode())) + continue; + } + + for (ItemSkillHolder holder : otherNormalSkills) + { + if (player.getSkillLevel(holder.getSkillId()) != 0) { - final int equipDelay = item.getEquipReuseDelay(); - if (equipDelay > 0) - { - player.addTimeStamp(skill, equipDelay); - player.disableSkill(skill, equipDelay); - } - updateTimestamp = true; + continue; + } + + final Skill skill = holder.getSkill(); + if (skill != null) + { + if (addedSkills.containsKey(holder.getSkill().getId())) + { + if (addedSkills.get(holder.getSkill().getId()).getLevel() < holder.getSkill().getLevel()) + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + } + else + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + + if (skill.isActive() && !player.hasSkillReuse(skill.getReuseHashCode())) + { + final int equipDelay = item.getEquipReuseDelay(); + if (equipDelay > 0) + { + player.addTimeStamp(skill, equipDelay); + player.disableSkill(skill, equipDelay); + } + updateTimestamp = true; + } + update = true; } - update = true; } } } @@ -424,6 +458,11 @@ public abstract class Inventory extends ItemContainer // Must check all equipped items for enchant conditions. for (ItemInstance equipped : inventory.getPaperdollItems()) { + if (!equipped.getItem().hasSkills()) + { + continue; + } + final List otherEnchantSkills = equipped.getItem().getSkills(ItemSkillType.ON_ENCHANT); if (otherEnchantSkills == null) { @@ -439,7 +478,17 @@ public abstract class Inventory extends ItemContainer // Check passive skill conditions. if (skill.isPassive() && !skill.checkConditions(SkillConditionScope.PASSIVE, player, player)) { - player.removeSkill(holder.getSkill(), false, holder.getSkill().isPassive()); + if (removedSkills.containsKey(holder.getSkill().getId())) + { + if (removedSkills.get(holder.getSkill().getId()).getLevel() < holder.getSkill().getLevel()) + { + removedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + } + else + { + removedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } update = true; } } @@ -465,8 +514,19 @@ public abstract class Inventory extends ItemContainer if (update) { + for (Skill skill : removedSkills.values()) + { + player.removeSkill(skill, false, skill.isPassive()); + } + + for (Skill skill : addedSkills.values()) + { + player.addSkill(skill, false); + } + player.sendSkillList(); } + if (updateTimestamp) { player.sendPacket(new SkillCoolTime(player)); @@ -487,14 +547,13 @@ public abstract class Inventory extends ItemContainer } final PlayerInstance player = (PlayerInstance) inventory.getOwner(); - // Any items equipped that result in expertise penalty do not give any skills at all. if (item.getItem().getCrystalType().isGreater(player.getExpertiseLevel())) { return; } - boolean update = false; + final Map addedSkills = new HashMap<>(1); boolean updateTimestamp = false; // Apply augmentation bonuses on equip @@ -506,71 +565,90 @@ public abstract class Inventory extends ItemContainer // Recalculate all stats player.getStat().recalculateStats(true); - final List onEnchantSkills = item.getItem().getSkills(ItemSkillType.ON_ENCHANT); - if (onEnchantSkills != null) - { - for (ItemSkillHolder holder : onEnchantSkills) - { - if (player.getSkillLevel(holder.getSkillId()) >= holder.getSkillLevel()) - { - continue; - } - - // Add skills bestowed from +4 armor - if (item.getEnchantLevel() >= holder.getValue()) - { - final Skill skill = holder.getSkill(); - // Check passive skill conditions. - if (skill.isPassive() && !skill.checkConditions(SkillConditionScope.PASSIVE, player, player)) - { - continue; - } - player.addSkill(skill, false); - update = true; - } - } - } - // Apply enchant stats item.applyEnchantStats(); // Apply SA skill item.applySpecialAbilities(); - final List normalSkills = item.getItem().getSkills(ItemSkillType.NORMAL); - if (normalSkills != null) + if (item.getItem().hasSkills()) { - for (ItemSkillHolder holder : normalSkills) + final List onEnchantSkills = item.getItem().getSkills(ItemSkillType.ON_ENCHANT); + if (onEnchantSkills != null) { - if (player.getSkillLevel(holder.getSkillId()) >= holder.getSkillLevel()) + for (ItemSkillHolder holder : onEnchantSkills) { - continue; - } - - final Skill skill = holder.getSkill(); - if (skill != null) - { - if (skill.isPassive() && !skill.checkConditions(SkillConditionScope.PASSIVE, player, player)) + if (player.getSkillLevel(holder.getSkillId()) >= holder.getSkillLevel()) { continue; } - player.addSkill(skill, false); - if (skill.isActive() && !player.hasSkillReuse(skill.getReuseHashCode())) + // Add skills bestowed from +4 armor + if (item.getEnchantLevel() >= holder.getValue()) { - final int equipDelay = item.getEquipReuseDelay(); - if (equipDelay > 0) + final Skill skill = holder.getSkill(); + // Check passive skill conditions. + if (skill.isPassive() && !skill.checkConditions(SkillConditionScope.PASSIVE, player, player)) { - player.addTimeStamp(skill, equipDelay); - player.disableSkill(skill, equipDelay); + continue; + } + + if (addedSkills.containsKey(holder.getSkill().getId())) + { + if (addedSkills.get(holder.getSkill().getId()).getLevel() < holder.getSkill().getLevel()) + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + } + else + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); } - updateTimestamp = true; } - update = true; } - else + } + + final List normalSkills = item.getItem().getSkills(ItemSkillType.NORMAL); + if (normalSkills != null) + { + for (ItemSkillHolder holder : normalSkills) { - LOGGER.warning("Inventory.ItemSkillsListener.Weapon: Incorrect skill: " + holder); + if (player.getSkillLevel(holder.getSkillId()) >= holder.getSkillLevel()) + { + continue; + } + + final Skill skill = holder.getSkill(); + if (skill != null) + { + if (skill.isPassive() && !skill.checkConditions(SkillConditionScope.PASSIVE, player, player)) + { + continue; + } + + if (addedSkills.containsKey(holder.getSkill().getId())) + { + if (addedSkills.get(holder.getSkill().getId()).getLevel() < holder.getSkill().getLevel()) + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + } + else + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + + if (skill.isActive() && !player.hasSkillReuse(skill.getReuseHashCode())) + { + final int equipDelay = item.getEquipReuseDelay(); + if (equipDelay > 0) + { + player.addTimeStamp(skill, equipDelay); + player.disableSkill(skill, equipDelay); + } + updateTimestamp = true; + } + } } } } @@ -578,6 +656,11 @@ public abstract class Inventory extends ItemContainer // Must check all equipped items for enchant conditions. for (ItemInstance equipped : inventory.getPaperdollItems()) { + if (!equipped.getItem().hasSkills()) + { + continue; + } + final List otherEnchantSkills = equipped.getItem().getSkills(ItemSkillType.ON_ENCHANT); if (otherEnchantSkills == null) { @@ -600,8 +683,18 @@ public abstract class Inventory extends ItemContainer { continue; } - player.addSkill(skill, false); - update = true; + + if (addedSkills.containsKey(holder.getSkill().getId())) + { + if (addedSkills.get(holder.getSkill().getId()).getLevel() < holder.getSkill().getLevel()) + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + } + else + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } } } } @@ -612,10 +705,16 @@ public abstract class Inventory extends ItemContainer item.getItem().forEachSkill(ItemSkillType.ON_EQUIP, holder -> holder.getSkill().activateSkill(player, player)); } - if (update) + if (!addedSkills.isEmpty()) { + for (Skill skill : addedSkills.values()) + { + player.addSkill(skill, false); + } + player.sendSkillList(); } + if (updateTimestamp) { player.sendPacket(new SkillCoolTime(player)); diff --git a/L2J_Mobius_6.0_Fafurion/java/org/l2jmobius/gameserver/model/items/Item.java b/L2J_Mobius_6.0_Fafurion/java/org/l2jmobius/gameserver/model/items/Item.java index 58fd46ecb2..7a1819fabf 100644 --- a/L2J_Mobius_6.0_Fafurion/java/org/l2jmobius/gameserver/model/items/Item.java +++ b/L2J_Mobius_6.0_Fafurion/java/org/l2jmobius/gameserver/model/items/Item.java @@ -754,6 +754,11 @@ public abstract class Item extends ListenersContainer implements IIdentifiable return _preConditions; } + public boolean hasSkills() + { + return _skills != null; + } + /** * Method to retrieve skills linked to this item armor and weapon: passive skills etcitem: skills used on item use <-- ??? * @return Skills linked to this item as SkillHolder[] diff --git a/L2J_Mobius_7.0_PreludeOfWar/java/org/l2jmobius/gameserver/model/itemcontainer/Inventory.java b/L2J_Mobius_7.0_PreludeOfWar/java/org/l2jmobius/gameserver/model/itemcontainer/Inventory.java index 65c6a450a3..affda3e80e 100644 --- a/L2J_Mobius_7.0_PreludeOfWar/java/org/l2jmobius/gameserver/model/itemcontainer/Inventory.java +++ b/L2J_Mobius_7.0_PreludeOfWar/java/org/l2jmobius/gameserver/model/itemcontainer/Inventory.java @@ -21,7 +21,9 @@ import java.sql.PreparedStatement; import java.sql.ResultSet; import java.util.ArrayList; import java.util.Collection; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.Objects; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; @@ -329,6 +331,8 @@ public abstract class Inventory extends ItemContainer final PlayerInstance player = (PlayerInstance) inventory.getOwner(); final Item it = item.getItem(); + final Map addedSkills = new HashMap<>(1); + final Map removedSkills = new HashMap<>(1); boolean update = false; boolean updateTimestamp = false; @@ -341,81 +345,111 @@ public abstract class Inventory extends ItemContainer // Recalculate all stats player.getStat().recalculateStats(true); - final List onEnchantSkills = it.getSkills(ItemSkillType.ON_ENCHANT); - if (onEnchantSkills != null) - { - for (ItemSkillHolder holder : onEnchantSkills) - { - // Remove skills bestowed from +4 armor - if (item.getEnchantLevel() >= holder.getValue()) - { - player.removeSkill(holder.getSkill(), false, holder.getSkill().isPassive()); - update = true; - } - } - } - // Clear enchant bonus item.clearEnchantStats(); // Clear SA Bonus item.clearSpecialAbilities(); - final List normalSkills = it.getSkills(ItemSkillType.NORMAL); - if (normalSkills != null) + if (it.hasSkills()) { - for (ItemSkillHolder holder : normalSkills) + final List onEnchantSkills = it.getSkills(ItemSkillType.ON_ENCHANT); + if (onEnchantSkills != null) { - final Skill skill = holder.getSkill(); - if (skill != null) + for (ItemSkillHolder holder : onEnchantSkills) { - player.removeSkill(skill, false, skill.isPassive()); - update = true; - } - else - { - LOGGER.warning("Inventory.ItemSkillsListener.Weapon: Incorrect skill: " + holder); + // Remove skills bestowed from +4 armor + if (item.getEnchantLevel() >= holder.getValue()) + { + if (removedSkills.containsKey(holder.getSkill().getId())) + { + if (removedSkills.get(holder.getSkill().getId()).getLevel() < holder.getSkill().getLevel()) + { + removedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + } + else + { + removedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + update = true; + } } } - } - - if (item.isArmor()) - { - for (ItemInstance itm : inventory.getItems()) + + final List normalSkills = it.getSkills(ItemSkillType.NORMAL); + if (normalSkills != null) { - if (!itm.isEquipped() || itm.equals(item)) + for (ItemSkillHolder holder : normalSkills) { - continue; + final Skill skill = holder.getSkill(); + if (skill != null) + { + if (removedSkills.containsKey(holder.getSkill().getId())) + { + if (removedSkills.get(holder.getSkill().getId()).getLevel() < holder.getSkill().getLevel()) + { + removedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + } + else + { + removedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + update = true; + } } - - final List otherNormalSkills = itm.getItem().getSkills(ItemSkillType.NORMAL); - if (otherNormalSkills == null) + } + + if (item.isArmor()) + { + for (ItemInstance itm : inventory.getItems()) { - continue; - } - - for (ItemSkillHolder holder : otherNormalSkills) - { - if (player.getSkillLevel(holder.getSkillId()) != 0) + if (!itm.isEquipped() || itm.equals(item)) { continue; } - final Skill skill = holder.getSkill(); - if (skill != null) + final List otherNormalSkills = itm.getItem().getSkills(ItemSkillType.NORMAL); + if (otherNormalSkills == null) { - player.addSkill(skill, false); - if (skill.isActive() && !player.hasSkillReuse(skill.getReuseHashCode())) + continue; + } + + for (ItemSkillHolder holder : otherNormalSkills) + { + if (player.getSkillLevel(holder.getSkillId()) != 0) { - final int equipDelay = item.getEquipReuseDelay(); - if (equipDelay > 0) - { - player.addTimeStamp(skill, equipDelay); - player.disableSkill(skill, equipDelay); - } - updateTimestamp = true; + continue; + } + + final Skill skill = holder.getSkill(); + if (skill != null) + { + if (addedSkills.containsKey(holder.getSkill().getId())) + { + if (addedSkills.get(holder.getSkill().getId()).getLevel() < holder.getSkill().getLevel()) + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + } + else + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + + if (skill.isActive() && !player.hasSkillReuse(skill.getReuseHashCode())) + { + final int equipDelay = item.getEquipReuseDelay(); + if (equipDelay > 0) + { + player.addTimeStamp(skill, equipDelay); + player.disableSkill(skill, equipDelay); + } + updateTimestamp = true; + } + update = true; } - update = true; } } } @@ -424,6 +458,11 @@ public abstract class Inventory extends ItemContainer // Must check all equipped items for enchant conditions. for (ItemInstance equipped : inventory.getPaperdollItems()) { + if (!equipped.getItem().hasSkills()) + { + continue; + } + final List otherEnchantSkills = equipped.getItem().getSkills(ItemSkillType.ON_ENCHANT); if (otherEnchantSkills == null) { @@ -439,7 +478,17 @@ public abstract class Inventory extends ItemContainer // Check passive skill conditions. if (skill.isPassive() && !skill.checkConditions(SkillConditionScope.PASSIVE, player, player)) { - player.removeSkill(holder.getSkill(), false, holder.getSkill().isPassive()); + if (removedSkills.containsKey(holder.getSkill().getId())) + { + if (removedSkills.get(holder.getSkill().getId()).getLevel() < holder.getSkill().getLevel()) + { + removedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + } + else + { + removedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } update = true; } } @@ -465,8 +514,19 @@ public abstract class Inventory extends ItemContainer if (update) { + for (Skill skill : removedSkills.values()) + { + player.removeSkill(skill, false, skill.isPassive()); + } + + for (Skill skill : addedSkills.values()) + { + player.addSkill(skill, false); + } + player.sendSkillList(); } + if (updateTimestamp) { player.sendPacket(new SkillCoolTime(player)); @@ -487,7 +547,7 @@ public abstract class Inventory extends ItemContainer } final PlayerInstance player = (PlayerInstance) inventory.getOwner(); - boolean update = false; + final Map addedSkills = new HashMap<>(1); boolean updateTimestamp = false; // Apply augmentation bonuses on equip @@ -499,71 +559,90 @@ public abstract class Inventory extends ItemContainer // Recalculate all stats player.getStat().recalculateStats(true); - final List onEnchantSkills = item.getItem().getSkills(ItemSkillType.ON_ENCHANT); - if (onEnchantSkills != null) - { - for (ItemSkillHolder holder : onEnchantSkills) - { - if (player.getSkillLevel(holder.getSkillId()) >= holder.getSkillLevel()) - { - continue; - } - - // Add skills bestowed from +4 armor - if (item.getEnchantLevel() >= holder.getValue()) - { - final Skill skill = holder.getSkill(); - // Check passive skill conditions. - if (skill.isPassive() && !skill.checkConditions(SkillConditionScope.PASSIVE, player, player)) - { - continue; - } - player.addSkill(skill, false); - update = true; - } - } - } - // Apply enchant stats item.applyEnchantStats(); // Apply SA skill item.applySpecialAbilities(); - final List normalSkills = item.getItem().getSkills(ItemSkillType.NORMAL); - if (normalSkills != null) + if (item.getItem().hasSkills()) { - for (ItemSkillHolder holder : normalSkills) + final List onEnchantSkills = item.getItem().getSkills(ItemSkillType.ON_ENCHANT); + if (onEnchantSkills != null) { - if (player.getSkillLevel(holder.getSkillId()) >= holder.getSkillLevel()) + for (ItemSkillHolder holder : onEnchantSkills) { - continue; - } - - final Skill skill = holder.getSkill(); - if (skill != null) - { - if (skill.isPassive() && !skill.checkConditions(SkillConditionScope.PASSIVE, player, player)) + if (player.getSkillLevel(holder.getSkillId()) >= holder.getSkillLevel()) { continue; } - player.addSkill(skill, false); - if (skill.isActive() && !player.hasSkillReuse(skill.getReuseHashCode())) + // Add skills bestowed from +4 armor + if (item.getEnchantLevel() >= holder.getValue()) { - final int equipDelay = item.getEquipReuseDelay(); - if (equipDelay > 0) + final Skill skill = holder.getSkill(); + // Check passive skill conditions. + if (skill.isPassive() && !skill.checkConditions(SkillConditionScope.PASSIVE, player, player)) { - player.addTimeStamp(skill, equipDelay); - player.disableSkill(skill, equipDelay); + continue; + } + + if (addedSkills.containsKey(holder.getSkill().getId())) + { + if (addedSkills.get(holder.getSkill().getId()).getLevel() < holder.getSkill().getLevel()) + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + } + else + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); } - updateTimestamp = true; } - update = true; } - else + } + + final List normalSkills = item.getItem().getSkills(ItemSkillType.NORMAL); + if (normalSkills != null) + { + for (ItemSkillHolder holder : normalSkills) { - LOGGER.warning("Inventory.ItemSkillsListener.Weapon: Incorrect skill: " + holder); + if (player.getSkillLevel(holder.getSkillId()) >= holder.getSkillLevel()) + { + continue; + } + + final Skill skill = holder.getSkill(); + if (skill != null) + { + if (skill.isPassive() && !skill.checkConditions(SkillConditionScope.PASSIVE, player, player)) + { + continue; + } + + if (addedSkills.containsKey(holder.getSkill().getId())) + { + if (addedSkills.get(holder.getSkill().getId()).getLevel() < holder.getSkill().getLevel()) + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + } + else + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + + if (skill.isActive() && !player.hasSkillReuse(skill.getReuseHashCode())) + { + final int equipDelay = item.getEquipReuseDelay(); + if (equipDelay > 0) + { + player.addTimeStamp(skill, equipDelay); + player.disableSkill(skill, equipDelay); + } + updateTimestamp = true; + } + } } } } @@ -571,6 +650,11 @@ public abstract class Inventory extends ItemContainer // Must check all equipped items for enchant conditions. for (ItemInstance equipped : inventory.getPaperdollItems()) { + if (!equipped.getItem().hasSkills()) + { + continue; + } + final List otherEnchantSkills = equipped.getItem().getSkills(ItemSkillType.ON_ENCHANT); if (otherEnchantSkills == null) { @@ -593,8 +677,18 @@ public abstract class Inventory extends ItemContainer { continue; } - player.addSkill(skill, false); - update = true; + + if (addedSkills.containsKey(holder.getSkill().getId())) + { + if (addedSkills.get(holder.getSkill().getId()).getLevel() < holder.getSkill().getLevel()) + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + } + else + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } } } } @@ -605,10 +699,16 @@ public abstract class Inventory extends ItemContainer item.getItem().forEachSkill(ItemSkillType.ON_EQUIP, holder -> holder.getSkill().activateSkill(player, player)); } - if (update) + if (!addedSkills.isEmpty()) { + for (Skill skill : addedSkills.values()) + { + player.addSkill(skill, false); + } + player.sendSkillList(); } + if (updateTimestamp) { player.sendPacket(new SkillCoolTime(player)); diff --git a/L2J_Mobius_7.0_PreludeOfWar/java/org/l2jmobius/gameserver/model/items/Item.java b/L2J_Mobius_7.0_PreludeOfWar/java/org/l2jmobius/gameserver/model/items/Item.java index 58fd46ecb2..7a1819fabf 100644 --- a/L2J_Mobius_7.0_PreludeOfWar/java/org/l2jmobius/gameserver/model/items/Item.java +++ b/L2J_Mobius_7.0_PreludeOfWar/java/org/l2jmobius/gameserver/model/items/Item.java @@ -754,6 +754,11 @@ public abstract class Item extends ListenersContainer implements IIdentifiable return _preConditions; } + public boolean hasSkills() + { + return _skills != null; + } + /** * Method to retrieve skills linked to this item armor and weapon: passive skills etcitem: skills used on item use <-- ??? * @return Skills linked to this item as SkillHolder[] diff --git a/L2J_Mobius_8.0_Homunculus/java/org/l2jmobius/gameserver/model/itemcontainer/Inventory.java b/L2J_Mobius_8.0_Homunculus/java/org/l2jmobius/gameserver/model/itemcontainer/Inventory.java index 3716800a0f..042309385d 100644 --- a/L2J_Mobius_8.0_Homunculus/java/org/l2jmobius/gameserver/model/itemcontainer/Inventory.java +++ b/L2J_Mobius_8.0_Homunculus/java/org/l2jmobius/gameserver/model/itemcontainer/Inventory.java @@ -21,7 +21,9 @@ import java.sql.PreparedStatement; import java.sql.ResultSet; import java.util.ArrayList; import java.util.Collection; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.Objects; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; @@ -324,6 +326,8 @@ public abstract class Inventory extends ItemContainer final PlayerInstance player = (PlayerInstance) inventory.getOwner(); final Item it = item.getItem(); + final Map addedSkills = new HashMap<>(1); + final Map removedSkills = new HashMap<>(1); boolean update = false; boolean updateTimestamp = false; @@ -336,81 +340,111 @@ public abstract class Inventory extends ItemContainer // Recalculate all stats player.getStat().recalculateStats(true); - final List onEnchantSkills = it.getSkills(ItemSkillType.ON_ENCHANT); - if (onEnchantSkills != null) - { - for (ItemSkillHolder holder : onEnchantSkills) - { - // Remove skills bestowed from +4 armor - if (item.getEnchantLevel() >= holder.getValue()) - { - player.removeSkill(holder.getSkill(), false, holder.getSkill().isPassive()); - update = true; - } - } - } - // Clear enchant bonus item.clearEnchantStats(); // Clear SA Bonus item.clearSpecialAbilities(); - final List normalSkills = it.getSkills(ItemSkillType.NORMAL); - if (normalSkills != null) + if (it.hasSkills()) { - for (ItemSkillHolder holder : normalSkills) + final List onEnchantSkills = it.getSkills(ItemSkillType.ON_ENCHANT); + if (onEnchantSkills != null) { - final Skill skill = holder.getSkill(); - if (skill != null) + for (ItemSkillHolder holder : onEnchantSkills) { - player.removeSkill(skill, false, skill.isPassive()); - update = true; - } - else - { - LOGGER.warning("Inventory.ItemSkillsListener.Weapon: Incorrect skill: " + holder); + // Remove skills bestowed from +4 armor + if (item.getEnchantLevel() >= holder.getValue()) + { + if (removedSkills.containsKey(holder.getSkill().getId())) + { + if (removedSkills.get(holder.getSkill().getId()).getLevel() < holder.getSkill().getLevel()) + { + removedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + } + else + { + removedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + update = true; + } } } - } - - if (item.isArmor()) - { - for (ItemInstance itm : inventory.getItems()) + + final List normalSkills = it.getSkills(ItemSkillType.NORMAL); + if (normalSkills != null) { - if (!itm.isEquipped() || itm.equals(item)) + for (ItemSkillHolder holder : normalSkills) { - continue; + final Skill skill = holder.getSkill(); + if (skill != null) + { + if (removedSkills.containsKey(holder.getSkill().getId())) + { + if (removedSkills.get(holder.getSkill().getId()).getLevel() < holder.getSkill().getLevel()) + { + removedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + } + else + { + removedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + update = true; + } } - - final List otherNormalSkills = itm.getItem().getSkills(ItemSkillType.NORMAL); - if (otherNormalSkills == null) + } + + if (item.isArmor()) + { + for (ItemInstance itm : inventory.getItems()) { - continue; - } - - for (ItemSkillHolder holder : otherNormalSkills) - { - if (player.getSkillLevel(holder.getSkillId()) != 0) + if (!itm.isEquipped() || itm.equals(item)) { continue; } - final Skill skill = holder.getSkill(); - if (skill != null) + final List otherNormalSkills = itm.getItem().getSkills(ItemSkillType.NORMAL); + if (otherNormalSkills == null) { - player.addSkill(skill, false); - if (skill.isActive() && !player.hasSkillReuse(skill.getReuseHashCode())) + continue; + } + + for (ItemSkillHolder holder : otherNormalSkills) + { + if (player.getSkillLevel(holder.getSkillId()) != 0) { - final int equipDelay = item.getEquipReuseDelay(); - if (equipDelay > 0) - { - player.addTimeStamp(skill, equipDelay); - player.disableSkill(skill, equipDelay); - } - updateTimestamp = true; + continue; + } + + final Skill skill = holder.getSkill(); + if (skill != null) + { + if (addedSkills.containsKey(holder.getSkill().getId())) + { + if (addedSkills.get(holder.getSkill().getId()).getLevel() < holder.getSkill().getLevel()) + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + } + else + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + + if (skill.isActive() && !player.hasSkillReuse(skill.getReuseHashCode())) + { + final int equipDelay = item.getEquipReuseDelay(); + if (equipDelay > 0) + { + player.addTimeStamp(skill, equipDelay); + player.disableSkill(skill, equipDelay); + } + updateTimestamp = true; + } + update = true; } - update = true; } } } @@ -419,6 +453,11 @@ public abstract class Inventory extends ItemContainer // Must check all equipped items for enchant conditions. for (ItemInstance equipped : inventory.getPaperdollItems()) { + if (!equipped.getItem().hasSkills()) + { + continue; + } + final List otherEnchantSkills = equipped.getItem().getSkills(ItemSkillType.ON_ENCHANT); if (otherEnchantSkills == null) { @@ -434,7 +473,17 @@ public abstract class Inventory extends ItemContainer // Check passive skill conditions. if (skill.isPassive() && !skill.checkConditions(SkillConditionScope.PASSIVE, player, player)) { - player.removeSkill(holder.getSkill(), false, holder.getSkill().isPassive()); + if (removedSkills.containsKey(holder.getSkill().getId())) + { + if (removedSkills.get(holder.getSkill().getId()).getLevel() < holder.getSkill().getLevel()) + { + removedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + } + else + { + removedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } update = true; } } @@ -460,8 +509,19 @@ public abstract class Inventory extends ItemContainer if (update) { + for (Skill skill : removedSkills.values()) + { + player.removeSkill(skill, false, skill.isPassive()); + } + + for (Skill skill : addedSkills.values()) + { + player.addSkill(skill, false); + } + player.sendSkillList(); } + if (updateTimestamp) { player.sendPacket(new SkillCoolTime(player)); @@ -482,7 +542,7 @@ public abstract class Inventory extends ItemContainer } final PlayerInstance player = (PlayerInstance) inventory.getOwner(); - boolean update = false; + final Map addedSkills = new HashMap<>(1); boolean updateTimestamp = false; // Apply augmentation bonuses on equip @@ -494,71 +554,90 @@ public abstract class Inventory extends ItemContainer // Recalculate all stats player.getStat().recalculateStats(true); - final List onEnchantSkills = item.getItem().getSkills(ItemSkillType.ON_ENCHANT); - if (onEnchantSkills != null) - { - for (ItemSkillHolder holder : onEnchantSkills) - { - if (player.getSkillLevel(holder.getSkillId()) >= holder.getSkillLevel()) - { - continue; - } - - // Add skills bestowed from +4 armor - if (item.getEnchantLevel() >= holder.getValue()) - { - final Skill skill = holder.getSkill(); - // Check passive skill conditions. - if (skill.isPassive() && !skill.checkConditions(SkillConditionScope.PASSIVE, player, player)) - { - continue; - } - player.addSkill(skill, false); - update = true; - } - } - } - // Apply enchant stats item.applyEnchantStats(); // Apply SA skill item.applySpecialAbilities(); - final List normalSkills = item.getItem().getSkills(ItemSkillType.NORMAL); - if (normalSkills != null) + if (item.getItem().hasSkills()) { - for (ItemSkillHolder holder : normalSkills) + final List onEnchantSkills = item.getItem().getSkills(ItemSkillType.ON_ENCHANT); + if (onEnchantSkills != null) { - if (player.getSkillLevel(holder.getSkillId()) >= holder.getSkillLevel()) + for (ItemSkillHolder holder : onEnchantSkills) { - continue; - } - - final Skill skill = holder.getSkill(); - if (skill != null) - { - if (skill.isPassive() && !skill.checkConditions(SkillConditionScope.PASSIVE, player, player)) + if (player.getSkillLevel(holder.getSkillId()) >= holder.getSkillLevel()) { continue; } - player.addSkill(skill, false); - if (skill.isActive() && !player.hasSkillReuse(skill.getReuseHashCode())) + // Add skills bestowed from +4 armor + if (item.getEnchantLevel() >= holder.getValue()) { - final int equipDelay = item.getEquipReuseDelay(); - if (equipDelay > 0) + final Skill skill = holder.getSkill(); + // Check passive skill conditions. + if (skill.isPassive() && !skill.checkConditions(SkillConditionScope.PASSIVE, player, player)) { - player.addTimeStamp(skill, equipDelay); - player.disableSkill(skill, equipDelay); + continue; + } + + if (addedSkills.containsKey(holder.getSkill().getId())) + { + if (addedSkills.get(holder.getSkill().getId()).getLevel() < holder.getSkill().getLevel()) + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + } + else + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); } - updateTimestamp = true; } - update = true; } - else + } + + final List normalSkills = item.getItem().getSkills(ItemSkillType.NORMAL); + if (normalSkills != null) + { + for (ItemSkillHolder holder : normalSkills) { - LOGGER.warning("Inventory.ItemSkillsListener.Weapon: Incorrect skill: " + holder); + if (player.getSkillLevel(holder.getSkillId()) >= holder.getSkillLevel()) + { + continue; + } + + final Skill skill = holder.getSkill(); + if (skill != null) + { + if (skill.isPassive() && !skill.checkConditions(SkillConditionScope.PASSIVE, player, player)) + { + continue; + } + + if (addedSkills.containsKey(holder.getSkill().getId())) + { + if (addedSkills.get(holder.getSkill().getId()).getLevel() < holder.getSkill().getLevel()) + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + } + else + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + + if (skill.isActive() && !player.hasSkillReuse(skill.getReuseHashCode())) + { + final int equipDelay = item.getEquipReuseDelay(); + if (equipDelay > 0) + { + player.addTimeStamp(skill, equipDelay); + player.disableSkill(skill, equipDelay); + } + updateTimestamp = true; + } + } } } } @@ -566,6 +645,11 @@ public abstract class Inventory extends ItemContainer // Must check all equipped items for enchant conditions. for (ItemInstance equipped : inventory.getPaperdollItems()) { + if (!equipped.getItem().hasSkills()) + { + continue; + } + final List otherEnchantSkills = equipped.getItem().getSkills(ItemSkillType.ON_ENCHANT); if (otherEnchantSkills == null) { @@ -588,8 +672,18 @@ public abstract class Inventory extends ItemContainer { continue; } - player.addSkill(skill, false); - update = true; + + if (addedSkills.containsKey(holder.getSkill().getId())) + { + if (addedSkills.get(holder.getSkill().getId()).getLevel() < holder.getSkill().getLevel()) + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + } + else + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } } } } @@ -600,10 +694,16 @@ public abstract class Inventory extends ItemContainer item.getItem().forEachSkill(ItemSkillType.ON_EQUIP, holder -> holder.getSkill().activateSkill(player, player)); } - if (update) + if (!addedSkills.isEmpty()) { + for (Skill skill : addedSkills.values()) + { + player.addSkill(skill, false); + } + player.sendSkillList(); } + if (updateTimestamp) { player.sendPacket(new SkillCoolTime(player)); diff --git a/L2J_Mobius_8.0_Homunculus/java/org/l2jmobius/gameserver/model/items/Item.java b/L2J_Mobius_8.0_Homunculus/java/org/l2jmobius/gameserver/model/items/Item.java index 58fd46ecb2..7a1819fabf 100644 --- a/L2J_Mobius_8.0_Homunculus/java/org/l2jmobius/gameserver/model/items/Item.java +++ b/L2J_Mobius_8.0_Homunculus/java/org/l2jmobius/gameserver/model/items/Item.java @@ -754,6 +754,11 @@ public abstract class Item extends ListenersContainer implements IIdentifiable return _preConditions; } + public boolean hasSkills() + { + return _skills != null; + } + /** * Method to retrieve skills linked to this item armor and weapon: passive skills etcitem: skills used on item use <-- ??? * @return Skills linked to this item as SkillHolder[] diff --git a/L2J_Mobius_9.0_ReturnOfTheQueenAnt/java/org/l2jmobius/gameserver/model/itemcontainer/Inventory.java b/L2J_Mobius_9.0_ReturnOfTheQueenAnt/java/org/l2jmobius/gameserver/model/itemcontainer/Inventory.java index 3716800a0f..042309385d 100644 --- a/L2J_Mobius_9.0_ReturnOfTheQueenAnt/java/org/l2jmobius/gameserver/model/itemcontainer/Inventory.java +++ b/L2J_Mobius_9.0_ReturnOfTheQueenAnt/java/org/l2jmobius/gameserver/model/itemcontainer/Inventory.java @@ -21,7 +21,9 @@ import java.sql.PreparedStatement; import java.sql.ResultSet; import java.util.ArrayList; import java.util.Collection; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.Objects; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; @@ -324,6 +326,8 @@ public abstract class Inventory extends ItemContainer final PlayerInstance player = (PlayerInstance) inventory.getOwner(); final Item it = item.getItem(); + final Map addedSkills = new HashMap<>(1); + final Map removedSkills = new HashMap<>(1); boolean update = false; boolean updateTimestamp = false; @@ -336,81 +340,111 @@ public abstract class Inventory extends ItemContainer // Recalculate all stats player.getStat().recalculateStats(true); - final List onEnchantSkills = it.getSkills(ItemSkillType.ON_ENCHANT); - if (onEnchantSkills != null) - { - for (ItemSkillHolder holder : onEnchantSkills) - { - // Remove skills bestowed from +4 armor - if (item.getEnchantLevel() >= holder.getValue()) - { - player.removeSkill(holder.getSkill(), false, holder.getSkill().isPassive()); - update = true; - } - } - } - // Clear enchant bonus item.clearEnchantStats(); // Clear SA Bonus item.clearSpecialAbilities(); - final List normalSkills = it.getSkills(ItemSkillType.NORMAL); - if (normalSkills != null) + if (it.hasSkills()) { - for (ItemSkillHolder holder : normalSkills) + final List onEnchantSkills = it.getSkills(ItemSkillType.ON_ENCHANT); + if (onEnchantSkills != null) { - final Skill skill = holder.getSkill(); - if (skill != null) + for (ItemSkillHolder holder : onEnchantSkills) { - player.removeSkill(skill, false, skill.isPassive()); - update = true; - } - else - { - LOGGER.warning("Inventory.ItemSkillsListener.Weapon: Incorrect skill: " + holder); + // Remove skills bestowed from +4 armor + if (item.getEnchantLevel() >= holder.getValue()) + { + if (removedSkills.containsKey(holder.getSkill().getId())) + { + if (removedSkills.get(holder.getSkill().getId()).getLevel() < holder.getSkill().getLevel()) + { + removedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + } + else + { + removedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + update = true; + } } } - } - - if (item.isArmor()) - { - for (ItemInstance itm : inventory.getItems()) + + final List normalSkills = it.getSkills(ItemSkillType.NORMAL); + if (normalSkills != null) { - if (!itm.isEquipped() || itm.equals(item)) + for (ItemSkillHolder holder : normalSkills) { - continue; + final Skill skill = holder.getSkill(); + if (skill != null) + { + if (removedSkills.containsKey(holder.getSkill().getId())) + { + if (removedSkills.get(holder.getSkill().getId()).getLevel() < holder.getSkill().getLevel()) + { + removedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + } + else + { + removedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + update = true; + } } - - final List otherNormalSkills = itm.getItem().getSkills(ItemSkillType.NORMAL); - if (otherNormalSkills == null) + } + + if (item.isArmor()) + { + for (ItemInstance itm : inventory.getItems()) { - continue; - } - - for (ItemSkillHolder holder : otherNormalSkills) - { - if (player.getSkillLevel(holder.getSkillId()) != 0) + if (!itm.isEquipped() || itm.equals(item)) { continue; } - final Skill skill = holder.getSkill(); - if (skill != null) + final List otherNormalSkills = itm.getItem().getSkills(ItemSkillType.NORMAL); + if (otherNormalSkills == null) { - player.addSkill(skill, false); - if (skill.isActive() && !player.hasSkillReuse(skill.getReuseHashCode())) + continue; + } + + for (ItemSkillHolder holder : otherNormalSkills) + { + if (player.getSkillLevel(holder.getSkillId()) != 0) { - final int equipDelay = item.getEquipReuseDelay(); - if (equipDelay > 0) - { - player.addTimeStamp(skill, equipDelay); - player.disableSkill(skill, equipDelay); - } - updateTimestamp = true; + continue; + } + + final Skill skill = holder.getSkill(); + if (skill != null) + { + if (addedSkills.containsKey(holder.getSkill().getId())) + { + if (addedSkills.get(holder.getSkill().getId()).getLevel() < holder.getSkill().getLevel()) + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + } + else + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + + if (skill.isActive() && !player.hasSkillReuse(skill.getReuseHashCode())) + { + final int equipDelay = item.getEquipReuseDelay(); + if (equipDelay > 0) + { + player.addTimeStamp(skill, equipDelay); + player.disableSkill(skill, equipDelay); + } + updateTimestamp = true; + } + update = true; } - update = true; } } } @@ -419,6 +453,11 @@ public abstract class Inventory extends ItemContainer // Must check all equipped items for enchant conditions. for (ItemInstance equipped : inventory.getPaperdollItems()) { + if (!equipped.getItem().hasSkills()) + { + continue; + } + final List otherEnchantSkills = equipped.getItem().getSkills(ItemSkillType.ON_ENCHANT); if (otherEnchantSkills == null) { @@ -434,7 +473,17 @@ public abstract class Inventory extends ItemContainer // Check passive skill conditions. if (skill.isPassive() && !skill.checkConditions(SkillConditionScope.PASSIVE, player, player)) { - player.removeSkill(holder.getSkill(), false, holder.getSkill().isPassive()); + if (removedSkills.containsKey(holder.getSkill().getId())) + { + if (removedSkills.get(holder.getSkill().getId()).getLevel() < holder.getSkill().getLevel()) + { + removedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + } + else + { + removedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } update = true; } } @@ -460,8 +509,19 @@ public abstract class Inventory extends ItemContainer if (update) { + for (Skill skill : removedSkills.values()) + { + player.removeSkill(skill, false, skill.isPassive()); + } + + for (Skill skill : addedSkills.values()) + { + player.addSkill(skill, false); + } + player.sendSkillList(); } + if (updateTimestamp) { player.sendPacket(new SkillCoolTime(player)); @@ -482,7 +542,7 @@ public abstract class Inventory extends ItemContainer } final PlayerInstance player = (PlayerInstance) inventory.getOwner(); - boolean update = false; + final Map addedSkills = new HashMap<>(1); boolean updateTimestamp = false; // Apply augmentation bonuses on equip @@ -494,71 +554,90 @@ public abstract class Inventory extends ItemContainer // Recalculate all stats player.getStat().recalculateStats(true); - final List onEnchantSkills = item.getItem().getSkills(ItemSkillType.ON_ENCHANT); - if (onEnchantSkills != null) - { - for (ItemSkillHolder holder : onEnchantSkills) - { - if (player.getSkillLevel(holder.getSkillId()) >= holder.getSkillLevel()) - { - continue; - } - - // Add skills bestowed from +4 armor - if (item.getEnchantLevel() >= holder.getValue()) - { - final Skill skill = holder.getSkill(); - // Check passive skill conditions. - if (skill.isPassive() && !skill.checkConditions(SkillConditionScope.PASSIVE, player, player)) - { - continue; - } - player.addSkill(skill, false); - update = true; - } - } - } - // Apply enchant stats item.applyEnchantStats(); // Apply SA skill item.applySpecialAbilities(); - final List normalSkills = item.getItem().getSkills(ItemSkillType.NORMAL); - if (normalSkills != null) + if (item.getItem().hasSkills()) { - for (ItemSkillHolder holder : normalSkills) + final List onEnchantSkills = item.getItem().getSkills(ItemSkillType.ON_ENCHANT); + if (onEnchantSkills != null) { - if (player.getSkillLevel(holder.getSkillId()) >= holder.getSkillLevel()) + for (ItemSkillHolder holder : onEnchantSkills) { - continue; - } - - final Skill skill = holder.getSkill(); - if (skill != null) - { - if (skill.isPassive() && !skill.checkConditions(SkillConditionScope.PASSIVE, player, player)) + if (player.getSkillLevel(holder.getSkillId()) >= holder.getSkillLevel()) { continue; } - player.addSkill(skill, false); - if (skill.isActive() && !player.hasSkillReuse(skill.getReuseHashCode())) + // Add skills bestowed from +4 armor + if (item.getEnchantLevel() >= holder.getValue()) { - final int equipDelay = item.getEquipReuseDelay(); - if (equipDelay > 0) + final Skill skill = holder.getSkill(); + // Check passive skill conditions. + if (skill.isPassive() && !skill.checkConditions(SkillConditionScope.PASSIVE, player, player)) { - player.addTimeStamp(skill, equipDelay); - player.disableSkill(skill, equipDelay); + continue; + } + + if (addedSkills.containsKey(holder.getSkill().getId())) + { + if (addedSkills.get(holder.getSkill().getId()).getLevel() < holder.getSkill().getLevel()) + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + } + else + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); } - updateTimestamp = true; } - update = true; } - else + } + + final List normalSkills = item.getItem().getSkills(ItemSkillType.NORMAL); + if (normalSkills != null) + { + for (ItemSkillHolder holder : normalSkills) { - LOGGER.warning("Inventory.ItemSkillsListener.Weapon: Incorrect skill: " + holder); + if (player.getSkillLevel(holder.getSkillId()) >= holder.getSkillLevel()) + { + continue; + } + + final Skill skill = holder.getSkill(); + if (skill != null) + { + if (skill.isPassive() && !skill.checkConditions(SkillConditionScope.PASSIVE, player, player)) + { + continue; + } + + if (addedSkills.containsKey(holder.getSkill().getId())) + { + if (addedSkills.get(holder.getSkill().getId()).getLevel() < holder.getSkill().getLevel()) + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + } + else + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + + if (skill.isActive() && !player.hasSkillReuse(skill.getReuseHashCode())) + { + final int equipDelay = item.getEquipReuseDelay(); + if (equipDelay > 0) + { + player.addTimeStamp(skill, equipDelay); + player.disableSkill(skill, equipDelay); + } + updateTimestamp = true; + } + } } } } @@ -566,6 +645,11 @@ public abstract class Inventory extends ItemContainer // Must check all equipped items for enchant conditions. for (ItemInstance equipped : inventory.getPaperdollItems()) { + if (!equipped.getItem().hasSkills()) + { + continue; + } + final List otherEnchantSkills = equipped.getItem().getSkills(ItemSkillType.ON_ENCHANT); if (otherEnchantSkills == null) { @@ -588,8 +672,18 @@ public abstract class Inventory extends ItemContainer { continue; } - player.addSkill(skill, false); - update = true; + + if (addedSkills.containsKey(holder.getSkill().getId())) + { + if (addedSkills.get(holder.getSkill().getId()).getLevel() < holder.getSkill().getLevel()) + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + } + else + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } } } } @@ -600,10 +694,16 @@ public abstract class Inventory extends ItemContainer item.getItem().forEachSkill(ItemSkillType.ON_EQUIP, holder -> holder.getSkill().activateSkill(player, player)); } - if (update) + if (!addedSkills.isEmpty()) { + for (Skill skill : addedSkills.values()) + { + player.addSkill(skill, false); + } + player.sendSkillList(); } + if (updateTimestamp) { player.sendPacket(new SkillCoolTime(player)); diff --git a/L2J_Mobius_9.0_ReturnOfTheQueenAnt/java/org/l2jmobius/gameserver/model/items/Item.java b/L2J_Mobius_9.0_ReturnOfTheQueenAnt/java/org/l2jmobius/gameserver/model/items/Item.java index 58fd46ecb2..7a1819fabf 100644 --- a/L2J_Mobius_9.0_ReturnOfTheQueenAnt/java/org/l2jmobius/gameserver/model/items/Item.java +++ b/L2J_Mobius_9.0_ReturnOfTheQueenAnt/java/org/l2jmobius/gameserver/model/items/Item.java @@ -754,6 +754,11 @@ public abstract class Item extends ListenersContainer implements IIdentifiable return _preConditions; } + public boolean hasSkills() + { + return _skills != null; + } + /** * Method to retrieve skills linked to this item armor and weapon: passive skills etcitem: skills used on item use <-- ??? * @return Skills linked to this item as SkillHolder[] diff --git a/L2J_Mobius_Classic_2.0_Saviors/java/org/l2jmobius/gameserver/model/itemcontainer/Inventory.java b/L2J_Mobius_Classic_2.0_Saviors/java/org/l2jmobius/gameserver/model/itemcontainer/Inventory.java index 372a79c0ed..eece76abfc 100644 --- a/L2J_Mobius_Classic_2.0_Saviors/java/org/l2jmobius/gameserver/model/itemcontainer/Inventory.java +++ b/L2J_Mobius_Classic_2.0_Saviors/java/org/l2jmobius/gameserver/model/itemcontainer/Inventory.java @@ -21,7 +21,9 @@ import java.sql.PreparedStatement; import java.sql.ResultSet; import java.util.ArrayList; import java.util.Collection; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.Objects; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; @@ -298,6 +300,8 @@ public abstract class Inventory extends ItemContainer final PlayerInstance player = (PlayerInstance) inventory.getOwner(); final Item it = item.getItem(); + final Map addedSkills = new HashMap<>(1); + final Map removedSkills = new HashMap<>(1); boolean update = false; boolean updateTimestamp = false; @@ -310,81 +314,111 @@ public abstract class Inventory extends ItemContainer // Recalculate all stats player.getStat().recalculateStats(true); - final List onEnchantSkills = it.getSkills(ItemSkillType.ON_ENCHANT); - if (onEnchantSkills != null) - { - for (ItemSkillHolder holder : onEnchantSkills) - { - // Remove skills bestowed from +4 armor - if (item.getEnchantLevel() >= holder.getValue()) - { - player.removeSkill(holder.getSkill(), false, holder.getSkill().isPassive()); - update = true; - } - } - } - // Clear enchant bonus item.clearEnchantStats(); // Clear SA Bonus item.clearSpecialAbilities(); - final List normalSkills = it.getSkills(ItemSkillType.NORMAL); - if (normalSkills != null) + if (it.hasSkills()) { - for (ItemSkillHolder holder : normalSkills) + final List onEnchantSkills = it.getSkills(ItemSkillType.ON_ENCHANT); + if (onEnchantSkills != null) { - final Skill skill = holder.getSkill(); - if (skill != null) + for (ItemSkillHolder holder : onEnchantSkills) { - player.removeSkill(skill, false, skill.isPassive()); - update = true; - } - else - { - LOGGER.warning("Inventory.ItemSkillsListener.Weapon: Incorrect skill: " + holder); + // Remove skills bestowed from +4 armor + if (item.getEnchantLevel() >= holder.getValue()) + { + if (removedSkills.containsKey(holder.getSkill().getId())) + { + if (removedSkills.get(holder.getSkill().getId()).getLevel() < holder.getSkill().getLevel()) + { + removedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + } + else + { + removedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + update = true; + } } } - } - - if (item.isArmor()) - { - for (ItemInstance itm : inventory.getItems()) + + final List normalSkills = it.getSkills(ItemSkillType.NORMAL); + if (normalSkills != null) { - if (!itm.isEquipped() || itm.equals(item)) + for (ItemSkillHolder holder : normalSkills) { - continue; + final Skill skill = holder.getSkill(); + if (skill != null) + { + if (removedSkills.containsKey(holder.getSkill().getId())) + { + if (removedSkills.get(holder.getSkill().getId()).getLevel() < holder.getSkill().getLevel()) + { + removedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + } + else + { + removedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + update = true; + } } - - final List otherNormalSkills = itm.getItem().getSkills(ItemSkillType.NORMAL); - if (otherNormalSkills == null) + } + + if (item.isArmor()) + { + for (ItemInstance itm : inventory.getItems()) { - continue; - } - - for (ItemSkillHolder holder : otherNormalSkills) - { - if (player.getSkillLevel(holder.getSkillId()) != 0) + if (!itm.isEquipped() || itm.equals(item)) { continue; } - final Skill skill = holder.getSkill(); - if (skill != null) + final List otherNormalSkills = itm.getItem().getSkills(ItemSkillType.NORMAL); + if (otherNormalSkills == null) { - player.addSkill(skill, false); - if (skill.isActive() && !player.hasSkillReuse(skill.getReuseHashCode())) + continue; + } + + for (ItemSkillHolder holder : otherNormalSkills) + { + if (player.getSkillLevel(holder.getSkillId()) != 0) { - final int equipDelay = item.getEquipReuseDelay(); - if (equipDelay > 0) - { - player.addTimeStamp(skill, equipDelay); - player.disableSkill(skill, equipDelay); - } - updateTimestamp = true; + continue; + } + + final Skill skill = holder.getSkill(); + if (skill != null) + { + if (addedSkills.containsKey(holder.getSkill().getId())) + { + if (addedSkills.get(holder.getSkill().getId()).getLevel() < holder.getSkill().getLevel()) + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + } + else + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + + if (skill.isActive() && !player.hasSkillReuse(skill.getReuseHashCode())) + { + final int equipDelay = item.getEquipReuseDelay(); + if (equipDelay > 0) + { + player.addTimeStamp(skill, equipDelay); + player.disableSkill(skill, equipDelay); + } + updateTimestamp = true; + } + update = true; } - update = true; } } } @@ -393,6 +427,11 @@ public abstract class Inventory extends ItemContainer // Must check all equipped items for enchant conditions. for (ItemInstance equipped : inventory.getPaperdollItems()) { + if (!equipped.getItem().hasSkills()) + { + continue; + } + final List otherEnchantSkills = equipped.getItem().getSkills(ItemSkillType.ON_ENCHANT); if (otherEnchantSkills == null) { @@ -408,7 +447,17 @@ public abstract class Inventory extends ItemContainer // Check passive skill conditions. if (skill.isPassive() && !skill.checkConditions(SkillConditionScope.PASSIVE, player, player)) { - player.removeSkill(holder.getSkill(), false, holder.getSkill().isPassive()); + if (removedSkills.containsKey(holder.getSkill().getId())) + { + if (removedSkills.get(holder.getSkill().getId()).getLevel() < holder.getSkill().getLevel()) + { + removedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + } + else + { + removedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } update = true; } } @@ -428,10 +477,22 @@ public abstract class Inventory extends ItemContainer // Apply skill, if weapon have "skills on unequip" it.forEachSkill(ItemSkillType.ON_UNEQUIP, holder -> holder.getSkill().activateSkill(player, player)); + if (update) { + for (Skill skill : removedSkills.values()) + { + player.removeSkill(skill, false, skill.isPassive()); + } + + for (Skill skill : addedSkills.values()) + { + player.addSkill(skill, false); + } + player.sendSkillList(); } + if (updateTimestamp) { player.sendPacket(new SkillCoolTime(player)); @@ -452,14 +513,13 @@ public abstract class Inventory extends ItemContainer } final PlayerInstance player = (PlayerInstance) inventory.getOwner(); - // Any items equipped that result in expertise penalty do not give any skills at all. if (item.getItem().getCrystalType().getLevel() > player.getExpertiseLevel()) { return; } - boolean update = false; + final Map addedSkills = new HashMap<>(1); boolean updateTimestamp = false; // Apply augmentation bonuses on equip @@ -471,71 +531,90 @@ public abstract class Inventory extends ItemContainer // Recalculate all stats player.getStat().recalculateStats(true); - final List onEnchantSkills = item.getItem().getSkills(ItemSkillType.ON_ENCHANT); - if (onEnchantSkills != null) - { - for (ItemSkillHolder holder : onEnchantSkills) - { - if (player.getSkillLevel(holder.getSkillId()) >= holder.getSkillLevel()) - { - continue; - } - - // Add skills bestowed from +4 armor - if (item.getEnchantLevel() >= holder.getValue()) - { - final Skill skill = holder.getSkill(); - // Check passive skill conditions. - if (skill.isPassive() && !skill.checkConditions(SkillConditionScope.PASSIVE, player, player)) - { - continue; - } - player.addSkill(skill, false); - update = true; - } - } - } - // Apply enchant stats item.applyEnchantStats(); // Apply SA skill item.applySpecialAbilities(); - final List normalSkills = item.getItem().getSkills(ItemSkillType.NORMAL); - if (normalSkills != null) + if (item.getItem().hasSkills()) { - for (ItemSkillHolder holder : normalSkills) + final List onEnchantSkills = item.getItem().getSkills(ItemSkillType.ON_ENCHANT); + if (onEnchantSkills != null) { - if (player.getSkillLevel(holder.getSkillId()) >= holder.getSkillLevel()) + for (ItemSkillHolder holder : onEnchantSkills) { - continue; - } - - final Skill skill = holder.getSkill(); - if (skill != null) - { - if (skill.isPassive() && !skill.checkConditions(SkillConditionScope.PASSIVE, player, player)) + if (player.getSkillLevel(holder.getSkillId()) >= holder.getSkillLevel()) { continue; } - player.addSkill(skill, false); - if (skill.isActive() && !player.hasSkillReuse(skill.getReuseHashCode())) + // Add skills bestowed from +4 armor + if (item.getEnchantLevel() >= holder.getValue()) { - final int equipDelay = item.getEquipReuseDelay(); - if (equipDelay > 0) + final Skill skill = holder.getSkill(); + // Check passive skill conditions. + if (skill.isPassive() && !skill.checkConditions(SkillConditionScope.PASSIVE, player, player)) { - player.addTimeStamp(skill, equipDelay); - player.disableSkill(skill, equipDelay); + continue; + } + + if (addedSkills.containsKey(holder.getSkill().getId())) + { + if (addedSkills.get(holder.getSkill().getId()).getLevel() < holder.getSkill().getLevel()) + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + } + else + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); } - updateTimestamp = true; } - update = true; } - else + } + + final List normalSkills = item.getItem().getSkills(ItemSkillType.NORMAL); + if (normalSkills != null) + { + for (ItemSkillHolder holder : normalSkills) { - LOGGER.warning("Inventory.ItemSkillsListener.Weapon: Incorrect skill: " + holder); + if (player.getSkillLevel(holder.getSkillId()) >= holder.getSkillLevel()) + { + continue; + } + + final Skill skill = holder.getSkill(); + if (skill != null) + { + if (skill.isPassive() && !skill.checkConditions(SkillConditionScope.PASSIVE, player, player)) + { + continue; + } + + if (addedSkills.containsKey(holder.getSkill().getId())) + { + if (addedSkills.get(holder.getSkill().getId()).getLevel() < holder.getSkill().getLevel()) + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + } + else + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + + if (skill.isActive() && !player.hasSkillReuse(skill.getReuseHashCode())) + { + final int equipDelay = item.getEquipReuseDelay(); + if (equipDelay > 0) + { + player.addTimeStamp(skill, equipDelay); + player.disableSkill(skill, equipDelay); + } + updateTimestamp = true; + } + } } } } @@ -543,6 +622,11 @@ public abstract class Inventory extends ItemContainer // Must check all equipped items for enchant conditions. for (ItemInstance equipped : inventory.getPaperdollItems()) { + if (!equipped.getItem().hasSkills()) + { + continue; + } + final List otherEnchantSkills = equipped.getItem().getSkills(ItemSkillType.ON_ENCHANT); if (otherEnchantSkills == null) { @@ -565,18 +649,35 @@ public abstract class Inventory extends ItemContainer { continue; } - player.addSkill(skill, false); - update = true; + + if (addedSkills.containsKey(holder.getSkill().getId())) + { + if (addedSkills.get(holder.getSkill().getId()).getLevel() < holder.getSkill().getLevel()) + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + } + else + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } } } } // Apply skill, if weapon have "skills on equip" item.getItem().forEachSkill(ItemSkillType.ON_EQUIP, holder -> holder.getSkill().activateSkill(player, player)); - if (update) + + if (!addedSkills.isEmpty()) { + for (Skill skill : addedSkills.values()) + { + player.addSkill(skill, false); + } + player.sendSkillList(); } + if (updateTimestamp) { player.sendPacket(new SkillCoolTime(player)); diff --git a/L2J_Mobius_Classic_2.0_Saviors/java/org/l2jmobius/gameserver/model/items/Item.java b/L2J_Mobius_Classic_2.0_Saviors/java/org/l2jmobius/gameserver/model/items/Item.java index 7008fc788d..e6b83064de 100644 --- a/L2J_Mobius_Classic_2.0_Saviors/java/org/l2jmobius/gameserver/model/items/Item.java +++ b/L2J_Mobius_Classic_2.0_Saviors/java/org/l2jmobius/gameserver/model/items/Item.java @@ -747,6 +747,11 @@ public abstract class Item extends ListenersContainer implements IIdentifiable return _preConditions; } + public boolean hasSkills() + { + return _skills != null; + } + /** * Method to retrieve skills linked to this item armor and weapon: passive skills etcitem: skills used on item use <-- ??? * @return Skills linked to this item as SkillHolder[] diff --git a/L2J_Mobius_Classic_2.1_Zaken/java/org/l2jmobius/gameserver/model/itemcontainer/Inventory.java b/L2J_Mobius_Classic_2.1_Zaken/java/org/l2jmobius/gameserver/model/itemcontainer/Inventory.java index 372a79c0ed..eece76abfc 100644 --- a/L2J_Mobius_Classic_2.1_Zaken/java/org/l2jmobius/gameserver/model/itemcontainer/Inventory.java +++ b/L2J_Mobius_Classic_2.1_Zaken/java/org/l2jmobius/gameserver/model/itemcontainer/Inventory.java @@ -21,7 +21,9 @@ import java.sql.PreparedStatement; import java.sql.ResultSet; import java.util.ArrayList; import java.util.Collection; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.Objects; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; @@ -298,6 +300,8 @@ public abstract class Inventory extends ItemContainer final PlayerInstance player = (PlayerInstance) inventory.getOwner(); final Item it = item.getItem(); + final Map addedSkills = new HashMap<>(1); + final Map removedSkills = new HashMap<>(1); boolean update = false; boolean updateTimestamp = false; @@ -310,81 +314,111 @@ public abstract class Inventory extends ItemContainer // Recalculate all stats player.getStat().recalculateStats(true); - final List onEnchantSkills = it.getSkills(ItemSkillType.ON_ENCHANT); - if (onEnchantSkills != null) - { - for (ItemSkillHolder holder : onEnchantSkills) - { - // Remove skills bestowed from +4 armor - if (item.getEnchantLevel() >= holder.getValue()) - { - player.removeSkill(holder.getSkill(), false, holder.getSkill().isPassive()); - update = true; - } - } - } - // Clear enchant bonus item.clearEnchantStats(); // Clear SA Bonus item.clearSpecialAbilities(); - final List normalSkills = it.getSkills(ItemSkillType.NORMAL); - if (normalSkills != null) + if (it.hasSkills()) { - for (ItemSkillHolder holder : normalSkills) + final List onEnchantSkills = it.getSkills(ItemSkillType.ON_ENCHANT); + if (onEnchantSkills != null) { - final Skill skill = holder.getSkill(); - if (skill != null) + for (ItemSkillHolder holder : onEnchantSkills) { - player.removeSkill(skill, false, skill.isPassive()); - update = true; - } - else - { - LOGGER.warning("Inventory.ItemSkillsListener.Weapon: Incorrect skill: " + holder); + // Remove skills bestowed from +4 armor + if (item.getEnchantLevel() >= holder.getValue()) + { + if (removedSkills.containsKey(holder.getSkill().getId())) + { + if (removedSkills.get(holder.getSkill().getId()).getLevel() < holder.getSkill().getLevel()) + { + removedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + } + else + { + removedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + update = true; + } } } - } - - if (item.isArmor()) - { - for (ItemInstance itm : inventory.getItems()) + + final List normalSkills = it.getSkills(ItemSkillType.NORMAL); + if (normalSkills != null) { - if (!itm.isEquipped() || itm.equals(item)) + for (ItemSkillHolder holder : normalSkills) { - continue; + final Skill skill = holder.getSkill(); + if (skill != null) + { + if (removedSkills.containsKey(holder.getSkill().getId())) + { + if (removedSkills.get(holder.getSkill().getId()).getLevel() < holder.getSkill().getLevel()) + { + removedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + } + else + { + removedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + update = true; + } } - - final List otherNormalSkills = itm.getItem().getSkills(ItemSkillType.NORMAL); - if (otherNormalSkills == null) + } + + if (item.isArmor()) + { + for (ItemInstance itm : inventory.getItems()) { - continue; - } - - for (ItemSkillHolder holder : otherNormalSkills) - { - if (player.getSkillLevel(holder.getSkillId()) != 0) + if (!itm.isEquipped() || itm.equals(item)) { continue; } - final Skill skill = holder.getSkill(); - if (skill != null) + final List otherNormalSkills = itm.getItem().getSkills(ItemSkillType.NORMAL); + if (otherNormalSkills == null) { - player.addSkill(skill, false); - if (skill.isActive() && !player.hasSkillReuse(skill.getReuseHashCode())) + continue; + } + + for (ItemSkillHolder holder : otherNormalSkills) + { + if (player.getSkillLevel(holder.getSkillId()) != 0) { - final int equipDelay = item.getEquipReuseDelay(); - if (equipDelay > 0) - { - player.addTimeStamp(skill, equipDelay); - player.disableSkill(skill, equipDelay); - } - updateTimestamp = true; + continue; + } + + final Skill skill = holder.getSkill(); + if (skill != null) + { + if (addedSkills.containsKey(holder.getSkill().getId())) + { + if (addedSkills.get(holder.getSkill().getId()).getLevel() < holder.getSkill().getLevel()) + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + } + else + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + + if (skill.isActive() && !player.hasSkillReuse(skill.getReuseHashCode())) + { + final int equipDelay = item.getEquipReuseDelay(); + if (equipDelay > 0) + { + player.addTimeStamp(skill, equipDelay); + player.disableSkill(skill, equipDelay); + } + updateTimestamp = true; + } + update = true; } - update = true; } } } @@ -393,6 +427,11 @@ public abstract class Inventory extends ItemContainer // Must check all equipped items for enchant conditions. for (ItemInstance equipped : inventory.getPaperdollItems()) { + if (!equipped.getItem().hasSkills()) + { + continue; + } + final List otherEnchantSkills = equipped.getItem().getSkills(ItemSkillType.ON_ENCHANT); if (otherEnchantSkills == null) { @@ -408,7 +447,17 @@ public abstract class Inventory extends ItemContainer // Check passive skill conditions. if (skill.isPassive() && !skill.checkConditions(SkillConditionScope.PASSIVE, player, player)) { - player.removeSkill(holder.getSkill(), false, holder.getSkill().isPassive()); + if (removedSkills.containsKey(holder.getSkill().getId())) + { + if (removedSkills.get(holder.getSkill().getId()).getLevel() < holder.getSkill().getLevel()) + { + removedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + } + else + { + removedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } update = true; } } @@ -428,10 +477,22 @@ public abstract class Inventory extends ItemContainer // Apply skill, if weapon have "skills on unequip" it.forEachSkill(ItemSkillType.ON_UNEQUIP, holder -> holder.getSkill().activateSkill(player, player)); + if (update) { + for (Skill skill : removedSkills.values()) + { + player.removeSkill(skill, false, skill.isPassive()); + } + + for (Skill skill : addedSkills.values()) + { + player.addSkill(skill, false); + } + player.sendSkillList(); } + if (updateTimestamp) { player.sendPacket(new SkillCoolTime(player)); @@ -452,14 +513,13 @@ public abstract class Inventory extends ItemContainer } final PlayerInstance player = (PlayerInstance) inventory.getOwner(); - // Any items equipped that result in expertise penalty do not give any skills at all. if (item.getItem().getCrystalType().getLevel() > player.getExpertiseLevel()) { return; } - boolean update = false; + final Map addedSkills = new HashMap<>(1); boolean updateTimestamp = false; // Apply augmentation bonuses on equip @@ -471,71 +531,90 @@ public abstract class Inventory extends ItemContainer // Recalculate all stats player.getStat().recalculateStats(true); - final List onEnchantSkills = item.getItem().getSkills(ItemSkillType.ON_ENCHANT); - if (onEnchantSkills != null) - { - for (ItemSkillHolder holder : onEnchantSkills) - { - if (player.getSkillLevel(holder.getSkillId()) >= holder.getSkillLevel()) - { - continue; - } - - // Add skills bestowed from +4 armor - if (item.getEnchantLevel() >= holder.getValue()) - { - final Skill skill = holder.getSkill(); - // Check passive skill conditions. - if (skill.isPassive() && !skill.checkConditions(SkillConditionScope.PASSIVE, player, player)) - { - continue; - } - player.addSkill(skill, false); - update = true; - } - } - } - // Apply enchant stats item.applyEnchantStats(); // Apply SA skill item.applySpecialAbilities(); - final List normalSkills = item.getItem().getSkills(ItemSkillType.NORMAL); - if (normalSkills != null) + if (item.getItem().hasSkills()) { - for (ItemSkillHolder holder : normalSkills) + final List onEnchantSkills = item.getItem().getSkills(ItemSkillType.ON_ENCHANT); + if (onEnchantSkills != null) { - if (player.getSkillLevel(holder.getSkillId()) >= holder.getSkillLevel()) + for (ItemSkillHolder holder : onEnchantSkills) { - continue; - } - - final Skill skill = holder.getSkill(); - if (skill != null) - { - if (skill.isPassive() && !skill.checkConditions(SkillConditionScope.PASSIVE, player, player)) + if (player.getSkillLevel(holder.getSkillId()) >= holder.getSkillLevel()) { continue; } - player.addSkill(skill, false); - if (skill.isActive() && !player.hasSkillReuse(skill.getReuseHashCode())) + // Add skills bestowed from +4 armor + if (item.getEnchantLevel() >= holder.getValue()) { - final int equipDelay = item.getEquipReuseDelay(); - if (equipDelay > 0) + final Skill skill = holder.getSkill(); + // Check passive skill conditions. + if (skill.isPassive() && !skill.checkConditions(SkillConditionScope.PASSIVE, player, player)) { - player.addTimeStamp(skill, equipDelay); - player.disableSkill(skill, equipDelay); + continue; + } + + if (addedSkills.containsKey(holder.getSkill().getId())) + { + if (addedSkills.get(holder.getSkill().getId()).getLevel() < holder.getSkill().getLevel()) + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + } + else + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); } - updateTimestamp = true; } - update = true; } - else + } + + final List normalSkills = item.getItem().getSkills(ItemSkillType.NORMAL); + if (normalSkills != null) + { + for (ItemSkillHolder holder : normalSkills) { - LOGGER.warning("Inventory.ItemSkillsListener.Weapon: Incorrect skill: " + holder); + if (player.getSkillLevel(holder.getSkillId()) >= holder.getSkillLevel()) + { + continue; + } + + final Skill skill = holder.getSkill(); + if (skill != null) + { + if (skill.isPassive() && !skill.checkConditions(SkillConditionScope.PASSIVE, player, player)) + { + continue; + } + + if (addedSkills.containsKey(holder.getSkill().getId())) + { + if (addedSkills.get(holder.getSkill().getId()).getLevel() < holder.getSkill().getLevel()) + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + } + else + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + + if (skill.isActive() && !player.hasSkillReuse(skill.getReuseHashCode())) + { + final int equipDelay = item.getEquipReuseDelay(); + if (equipDelay > 0) + { + player.addTimeStamp(skill, equipDelay); + player.disableSkill(skill, equipDelay); + } + updateTimestamp = true; + } + } } } } @@ -543,6 +622,11 @@ public abstract class Inventory extends ItemContainer // Must check all equipped items for enchant conditions. for (ItemInstance equipped : inventory.getPaperdollItems()) { + if (!equipped.getItem().hasSkills()) + { + continue; + } + final List otherEnchantSkills = equipped.getItem().getSkills(ItemSkillType.ON_ENCHANT); if (otherEnchantSkills == null) { @@ -565,18 +649,35 @@ public abstract class Inventory extends ItemContainer { continue; } - player.addSkill(skill, false); - update = true; + + if (addedSkills.containsKey(holder.getSkill().getId())) + { + if (addedSkills.get(holder.getSkill().getId()).getLevel() < holder.getSkill().getLevel()) + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + } + else + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } } } } // Apply skill, if weapon have "skills on equip" item.getItem().forEachSkill(ItemSkillType.ON_EQUIP, holder -> holder.getSkill().activateSkill(player, player)); - if (update) + + if (!addedSkills.isEmpty()) { + for (Skill skill : addedSkills.values()) + { + player.addSkill(skill, false); + } + player.sendSkillList(); } + if (updateTimestamp) { player.sendPacket(new SkillCoolTime(player)); diff --git a/L2J_Mobius_Classic_2.1_Zaken/java/org/l2jmobius/gameserver/model/items/Item.java b/L2J_Mobius_Classic_2.1_Zaken/java/org/l2jmobius/gameserver/model/items/Item.java index 7008fc788d..e6b83064de 100644 --- a/L2J_Mobius_Classic_2.1_Zaken/java/org/l2jmobius/gameserver/model/items/Item.java +++ b/L2J_Mobius_Classic_2.1_Zaken/java/org/l2jmobius/gameserver/model/items/Item.java @@ -747,6 +747,11 @@ public abstract class Item extends ListenersContainer implements IIdentifiable return _preConditions; } + public boolean hasSkills() + { + return _skills != null; + } + /** * Method to retrieve skills linked to this item armor and weapon: passive skills etcitem: skills used on item use <-- ??? * @return Skills linked to this item as SkillHolder[] diff --git a/L2J_Mobius_Classic_2.2_Antharas/java/org/l2jmobius/gameserver/model/itemcontainer/Inventory.java b/L2J_Mobius_Classic_2.2_Antharas/java/org/l2jmobius/gameserver/model/itemcontainer/Inventory.java index bd92002f8c..6beada1a5d 100644 --- a/L2J_Mobius_Classic_2.2_Antharas/java/org/l2jmobius/gameserver/model/itemcontainer/Inventory.java +++ b/L2J_Mobius_Classic_2.2_Antharas/java/org/l2jmobius/gameserver/model/itemcontainer/Inventory.java @@ -21,7 +21,9 @@ import java.sql.PreparedStatement; import java.sql.ResultSet; import java.util.ArrayList; import java.util.Collection; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.Objects; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; @@ -306,6 +308,8 @@ public abstract class Inventory extends ItemContainer final PlayerInstance player = (PlayerInstance) inventory.getOwner(); final Item it = item.getItem(); + final Map addedSkills = new HashMap<>(1); + final Map removedSkills = new HashMap<>(1); boolean update = false; boolean updateTimestamp = false; @@ -318,81 +322,111 @@ public abstract class Inventory extends ItemContainer // Recalculate all stats player.getStat().recalculateStats(true); - final List onEnchantSkills = it.getSkills(ItemSkillType.ON_ENCHANT); - if (onEnchantSkills != null) - { - for (ItemSkillHolder holder : onEnchantSkills) - { - // Remove skills bestowed from +4 armor - if (item.getEnchantLevel() >= holder.getValue()) - { - player.removeSkill(holder.getSkill(), false, holder.getSkill().isPassive()); - update = true; - } - } - } - // Clear enchant bonus item.clearEnchantStats(); // Clear SA Bonus item.clearSpecialAbilities(); - final List normalSkills = it.getSkills(ItemSkillType.NORMAL); - if (normalSkills != null) + if (it.hasSkills()) { - for (ItemSkillHolder holder : normalSkills) + final List onEnchantSkills = it.getSkills(ItemSkillType.ON_ENCHANT); + if (onEnchantSkills != null) { - final Skill skill = holder.getSkill(); - if (skill != null) + for (ItemSkillHolder holder : onEnchantSkills) { - player.removeSkill(skill, false, skill.isPassive()); - update = true; - } - else - { - LOGGER.warning("Inventory.ItemSkillsListener.Weapon: Incorrect skill: " + holder); + // Remove skills bestowed from +4 armor + if (item.getEnchantLevel() >= holder.getValue()) + { + if (removedSkills.containsKey(holder.getSkill().getId())) + { + if (removedSkills.get(holder.getSkill().getId()).getLevel() < holder.getSkill().getLevel()) + { + removedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + } + else + { + removedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + update = true; + } } } - } - - if (item.isArmor()) - { - for (ItemInstance itm : inventory.getItems()) + + final List normalSkills = it.getSkills(ItemSkillType.NORMAL); + if (normalSkills != null) { - if (!itm.isEquipped() || itm.equals(item)) + for (ItemSkillHolder holder : normalSkills) { - continue; + final Skill skill = holder.getSkill(); + if (skill != null) + { + if (removedSkills.containsKey(holder.getSkill().getId())) + { + if (removedSkills.get(holder.getSkill().getId()).getLevel() < holder.getSkill().getLevel()) + { + removedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + } + else + { + removedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + update = true; + } } - - final List otherNormalSkills = itm.getItem().getSkills(ItemSkillType.NORMAL); - if (otherNormalSkills == null) + } + + if (item.isArmor()) + { + for (ItemInstance itm : inventory.getItems()) { - continue; - } - - for (ItemSkillHolder holder : otherNormalSkills) - { - if (player.getSkillLevel(holder.getSkillId()) != 0) + if (!itm.isEquipped() || itm.equals(item)) { continue; } - final Skill skill = holder.getSkill(); - if (skill != null) + final List otherNormalSkills = itm.getItem().getSkills(ItemSkillType.NORMAL); + if (otherNormalSkills == null) { - player.addSkill(skill, false); - if (skill.isActive() && !player.hasSkillReuse(skill.getReuseHashCode())) + continue; + } + + for (ItemSkillHolder holder : otherNormalSkills) + { + if (player.getSkillLevel(holder.getSkillId()) != 0) { - final int equipDelay = item.getEquipReuseDelay(); - if (equipDelay > 0) - { - player.addTimeStamp(skill, equipDelay); - player.disableSkill(skill, equipDelay); - } - updateTimestamp = true; + continue; + } + + final Skill skill = holder.getSkill(); + if (skill != null) + { + if (addedSkills.containsKey(holder.getSkill().getId())) + { + if (addedSkills.get(holder.getSkill().getId()).getLevel() < holder.getSkill().getLevel()) + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + } + else + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + + if (skill.isActive() && !player.hasSkillReuse(skill.getReuseHashCode())) + { + final int equipDelay = item.getEquipReuseDelay(); + if (equipDelay > 0) + { + player.addTimeStamp(skill, equipDelay); + player.disableSkill(skill, equipDelay); + } + updateTimestamp = true; + } + update = true; } - update = true; } } } @@ -401,6 +435,11 @@ public abstract class Inventory extends ItemContainer // Must check all equipped items for enchant conditions. for (ItemInstance equipped : inventory.getPaperdollItems()) { + if (!equipped.getItem().hasSkills()) + { + continue; + } + final List otherEnchantSkills = equipped.getItem().getSkills(ItemSkillType.ON_ENCHANT); if (otherEnchantSkills == null) { @@ -416,7 +455,17 @@ public abstract class Inventory extends ItemContainer // Check passive skill conditions. if (skill.isPassive() && !skill.checkConditions(SkillConditionScope.PASSIVE, player, player)) { - player.removeSkill(holder.getSkill(), false, holder.getSkill().isPassive()); + if (removedSkills.containsKey(holder.getSkill().getId())) + { + if (removedSkills.get(holder.getSkill().getId()).getLevel() < holder.getSkill().getLevel()) + { + removedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + } + else + { + removedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } update = true; } } @@ -442,8 +491,19 @@ public abstract class Inventory extends ItemContainer if (update) { + for (Skill skill : removedSkills.values()) + { + player.removeSkill(skill, false, skill.isPassive()); + } + + for (Skill skill : addedSkills.values()) + { + player.addSkill(skill, false); + } + player.sendSkillList(); } + if (updateTimestamp) { player.sendPacket(new SkillCoolTime(player)); @@ -464,14 +524,13 @@ public abstract class Inventory extends ItemContainer } final PlayerInstance player = (PlayerInstance) inventory.getOwner(); - // Any items equipped that result in expertise penalty do not give any skills at all. if (item.getItem().getCrystalType().getLevel() > player.getExpertiseLevel()) { return; } - boolean update = false; + final Map addedSkills = new HashMap<>(1); boolean updateTimestamp = false; // Apply augmentation bonuses on equip @@ -483,71 +542,90 @@ public abstract class Inventory extends ItemContainer // Recalculate all stats player.getStat().recalculateStats(true); - final List onEnchantSkills = item.getItem().getSkills(ItemSkillType.ON_ENCHANT); - if (onEnchantSkills != null) - { - for (ItemSkillHolder holder : onEnchantSkills) - { - if (player.getSkillLevel(holder.getSkillId()) >= holder.getSkillLevel()) - { - continue; - } - - // Add skills bestowed from +4 armor - if (item.getEnchantLevel() >= holder.getValue()) - { - final Skill skill = holder.getSkill(); - // Check passive skill conditions. - if (skill.isPassive() && !skill.checkConditions(SkillConditionScope.PASSIVE, player, player)) - { - continue; - } - player.addSkill(skill, false); - update = true; - } - } - } - // Apply enchant stats item.applyEnchantStats(); // Apply SA skill item.applySpecialAbilities(); - final List normalSkills = item.getItem().getSkills(ItemSkillType.NORMAL); - if (normalSkills != null) + if (item.getItem().hasSkills()) { - for (ItemSkillHolder holder : normalSkills) + final List onEnchantSkills = item.getItem().getSkills(ItemSkillType.ON_ENCHANT); + if (onEnchantSkills != null) { - if (player.getSkillLevel(holder.getSkillId()) >= holder.getSkillLevel()) + for (ItemSkillHolder holder : onEnchantSkills) { - continue; - } - - final Skill skill = holder.getSkill(); - if (skill != null) - { - if (skill.isPassive() && !skill.checkConditions(SkillConditionScope.PASSIVE, player, player)) + if (player.getSkillLevel(holder.getSkillId()) >= holder.getSkillLevel()) { continue; } - player.addSkill(skill, false); - if (skill.isActive() && !player.hasSkillReuse(skill.getReuseHashCode())) + // Add skills bestowed from +4 armor + if (item.getEnchantLevel() >= holder.getValue()) { - final int equipDelay = item.getEquipReuseDelay(); - if (equipDelay > 0) + final Skill skill = holder.getSkill(); + // Check passive skill conditions. + if (skill.isPassive() && !skill.checkConditions(SkillConditionScope.PASSIVE, player, player)) { - player.addTimeStamp(skill, equipDelay); - player.disableSkill(skill, equipDelay); + continue; + } + + if (addedSkills.containsKey(holder.getSkill().getId())) + { + if (addedSkills.get(holder.getSkill().getId()).getLevel() < holder.getSkill().getLevel()) + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + } + else + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); } - updateTimestamp = true; } - update = true; } - else + } + + final List normalSkills = item.getItem().getSkills(ItemSkillType.NORMAL); + if (normalSkills != null) + { + for (ItemSkillHolder holder : normalSkills) { - LOGGER.warning("Inventory.ItemSkillsListener.Weapon: Incorrect skill: " + holder); + if (player.getSkillLevel(holder.getSkillId()) >= holder.getSkillLevel()) + { + continue; + } + + final Skill skill = holder.getSkill(); + if (skill != null) + { + if (skill.isPassive() && !skill.checkConditions(SkillConditionScope.PASSIVE, player, player)) + { + continue; + } + + if (addedSkills.containsKey(holder.getSkill().getId())) + { + if (addedSkills.get(holder.getSkill().getId()).getLevel() < holder.getSkill().getLevel()) + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + } + else + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + + if (skill.isActive() && !player.hasSkillReuse(skill.getReuseHashCode())) + { + final int equipDelay = item.getEquipReuseDelay(); + if (equipDelay > 0) + { + player.addTimeStamp(skill, equipDelay); + player.disableSkill(skill, equipDelay); + } + updateTimestamp = true; + } + } } } } @@ -555,6 +633,11 @@ public abstract class Inventory extends ItemContainer // Must check all equipped items for enchant conditions. for (ItemInstance equipped : inventory.getPaperdollItems()) { + if (!equipped.getItem().hasSkills()) + { + continue; + } + final List otherEnchantSkills = equipped.getItem().getSkills(ItemSkillType.ON_ENCHANT); if (otherEnchantSkills == null) { @@ -577,8 +660,18 @@ public abstract class Inventory extends ItemContainer { continue; } - player.addSkill(skill, false); - update = true; + + if (addedSkills.containsKey(holder.getSkill().getId())) + { + if (addedSkills.get(holder.getSkill().getId()).getLevel() < holder.getSkill().getLevel()) + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + } + else + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } } } } @@ -589,10 +682,16 @@ public abstract class Inventory extends ItemContainer item.getItem().forEachSkill(ItemSkillType.ON_EQUIP, holder -> holder.getSkill().activateSkill(player, player)); } - if (update) + if (!addedSkills.isEmpty()) { + for (Skill skill : addedSkills.values()) + { + player.addSkill(skill, false); + } + player.sendSkillList(); } + if (updateTimestamp) { player.sendPacket(new SkillCoolTime(player)); diff --git a/L2J_Mobius_Classic_2.2_Antharas/java/org/l2jmobius/gameserver/model/items/Item.java b/L2J_Mobius_Classic_2.2_Antharas/java/org/l2jmobius/gameserver/model/items/Item.java index f259063d4b..7e07a96727 100644 --- a/L2J_Mobius_Classic_2.2_Antharas/java/org/l2jmobius/gameserver/model/items/Item.java +++ b/L2J_Mobius_Classic_2.2_Antharas/java/org/l2jmobius/gameserver/model/items/Item.java @@ -748,6 +748,11 @@ public abstract class Item extends ListenersContainer implements IIdentifiable return _preConditions; } + public boolean hasSkills() + { + return _skills != null; + } + /** * Method to retrieve skills linked to this item armor and weapon: passive skills etcitem: skills used on item use <-- ??? * @return Skills linked to this item as SkillHolder[] diff --git a/L2J_Mobius_Classic_2.3_SevenSigns/java/org/l2jmobius/gameserver/model/itemcontainer/Inventory.java b/L2J_Mobius_Classic_2.3_SevenSigns/java/org/l2jmobius/gameserver/model/itemcontainer/Inventory.java index 53c4fcfae3..af0999de2b 100644 --- a/L2J_Mobius_Classic_2.3_SevenSigns/java/org/l2jmobius/gameserver/model/itemcontainer/Inventory.java +++ b/L2J_Mobius_Classic_2.3_SevenSigns/java/org/l2jmobius/gameserver/model/itemcontainer/Inventory.java @@ -21,7 +21,9 @@ import java.sql.PreparedStatement; import java.sql.ResultSet; import java.util.ArrayList; import java.util.Collection; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.Objects; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; @@ -329,6 +331,8 @@ public abstract class Inventory extends ItemContainer final PlayerInstance player = (PlayerInstance) inventory.getOwner(); final Item it = item.getItem(); + final Map addedSkills = new HashMap<>(1); + final Map removedSkills = new HashMap<>(1); boolean update = false; boolean updateTimestamp = false; @@ -341,81 +345,111 @@ public abstract class Inventory extends ItemContainer // Recalculate all stats player.getStat().recalculateStats(true); - final List onEnchantSkills = it.getSkills(ItemSkillType.ON_ENCHANT); - if (onEnchantSkills != null) - { - for (ItemSkillHolder holder : onEnchantSkills) - { - // Remove skills bestowed from +4 armor - if (item.getEnchantLevel() >= holder.getValue()) - { - player.removeSkill(holder.getSkill(), false, holder.getSkill().isPassive()); - update = true; - } - } - } - // Clear enchant bonus item.clearEnchantStats(); // Clear SA Bonus item.clearSpecialAbilities(); - final List normalSkills = it.getSkills(ItemSkillType.NORMAL); - if (normalSkills != null) + if (it.hasSkills()) { - for (ItemSkillHolder holder : normalSkills) + final List onEnchantSkills = it.getSkills(ItemSkillType.ON_ENCHANT); + if (onEnchantSkills != null) { - final Skill skill = holder.getSkill(); - if (skill != null) + for (ItemSkillHolder holder : onEnchantSkills) { - player.removeSkill(skill, false, skill.isPassive()); - update = true; - } - else - { - LOGGER.warning("Inventory.ItemSkillsListener.Weapon: Incorrect skill: " + holder); + // Remove skills bestowed from +4 armor + if (item.getEnchantLevel() >= holder.getValue()) + { + if (removedSkills.containsKey(holder.getSkill().getId())) + { + if (removedSkills.get(holder.getSkill().getId()).getLevel() < holder.getSkill().getLevel()) + { + removedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + } + else + { + removedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + update = true; + } } } - } - - if (item.isArmor()) - { - for (ItemInstance itm : inventory.getItems()) + + final List normalSkills = it.getSkills(ItemSkillType.NORMAL); + if (normalSkills != null) { - if (!itm.isEquipped() || itm.equals(item)) + for (ItemSkillHolder holder : normalSkills) { - continue; + final Skill skill = holder.getSkill(); + if (skill != null) + { + if (removedSkills.containsKey(holder.getSkill().getId())) + { + if (removedSkills.get(holder.getSkill().getId()).getLevel() < holder.getSkill().getLevel()) + { + removedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + } + else + { + removedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + update = true; + } } - - final List otherNormalSkills = itm.getItem().getSkills(ItemSkillType.NORMAL); - if (otherNormalSkills == null) + } + + if (item.isArmor()) + { + for (ItemInstance itm : inventory.getItems()) { - continue; - } - - for (ItemSkillHolder holder : otherNormalSkills) - { - if (player.getSkillLevel(holder.getSkillId()) != 0) + if (!itm.isEquipped() || itm.equals(item)) { continue; } - final Skill skill = holder.getSkill(); - if (skill != null) + final List otherNormalSkills = itm.getItem().getSkills(ItemSkillType.NORMAL); + if (otherNormalSkills == null) { - player.addSkill(skill, false); - if (skill.isActive() && !player.hasSkillReuse(skill.getReuseHashCode())) + continue; + } + + for (ItemSkillHolder holder : otherNormalSkills) + { + if (player.getSkillLevel(holder.getSkillId()) != 0) { - final int equipDelay = item.getEquipReuseDelay(); - if (equipDelay > 0) - { - player.addTimeStamp(skill, equipDelay); - player.disableSkill(skill, equipDelay); - } - updateTimestamp = true; + continue; + } + + final Skill skill = holder.getSkill(); + if (skill != null) + { + if (addedSkills.containsKey(holder.getSkill().getId())) + { + if (addedSkills.get(holder.getSkill().getId()).getLevel() < holder.getSkill().getLevel()) + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + } + else + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + + if (skill.isActive() && !player.hasSkillReuse(skill.getReuseHashCode())) + { + final int equipDelay = item.getEquipReuseDelay(); + if (equipDelay > 0) + { + player.addTimeStamp(skill, equipDelay); + player.disableSkill(skill, equipDelay); + } + updateTimestamp = true; + } + update = true; } - update = true; } } } @@ -424,6 +458,11 @@ public abstract class Inventory extends ItemContainer // Must check all equipped items for enchant conditions. for (ItemInstance equipped : inventory.getPaperdollItems()) { + if (!equipped.getItem().hasSkills()) + { + continue; + } + final List otherEnchantSkills = equipped.getItem().getSkills(ItemSkillType.ON_ENCHANT); if (otherEnchantSkills == null) { @@ -439,7 +478,17 @@ public abstract class Inventory extends ItemContainer // Check passive skill conditions. if (skill.isPassive() && !skill.checkConditions(SkillConditionScope.PASSIVE, player, player)) { - player.removeSkill(holder.getSkill(), false, holder.getSkill().isPassive()); + if (removedSkills.containsKey(holder.getSkill().getId())) + { + if (removedSkills.get(holder.getSkill().getId()).getLevel() < holder.getSkill().getLevel()) + { + removedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + } + else + { + removedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } update = true; } } @@ -465,8 +514,19 @@ public abstract class Inventory extends ItemContainer if (update) { + for (Skill skill : removedSkills.values()) + { + player.removeSkill(skill, false, skill.isPassive()); + } + + for (Skill skill : addedSkills.values()) + { + player.addSkill(skill, false); + } + player.sendSkillList(); } + if (updateTimestamp) { player.sendPacket(new SkillCoolTime(player)); @@ -487,14 +547,13 @@ public abstract class Inventory extends ItemContainer } final PlayerInstance player = (PlayerInstance) inventory.getOwner(); - // Any items equipped that result in expertise penalty do not give any skills at all. if (item.getItem().getCrystalType().getLevel() > player.getExpertiseLevel()) { return; } - boolean update = false; + final Map addedSkills = new HashMap<>(1); boolean updateTimestamp = false; // Apply augmentation bonuses on equip @@ -506,71 +565,90 @@ public abstract class Inventory extends ItemContainer // Recalculate all stats player.getStat().recalculateStats(true); - final List onEnchantSkills = item.getItem().getSkills(ItemSkillType.ON_ENCHANT); - if (onEnchantSkills != null) - { - for (ItemSkillHolder holder : onEnchantSkills) - { - if (player.getSkillLevel(holder.getSkillId()) >= holder.getSkillLevel()) - { - continue; - } - - // Add skills bestowed from +4 armor - if (item.getEnchantLevel() >= holder.getValue()) - { - final Skill skill = holder.getSkill(); - // Check passive skill conditions. - if (skill.isPassive() && !skill.checkConditions(SkillConditionScope.PASSIVE, player, player)) - { - continue; - } - player.addSkill(skill, false); - update = true; - } - } - } - // Apply enchant stats item.applyEnchantStats(); // Apply SA skill item.applySpecialAbilities(); - final List normalSkills = item.getItem().getSkills(ItemSkillType.NORMAL); - if (normalSkills != null) + if (item.getItem().hasSkills()) { - for (ItemSkillHolder holder : normalSkills) + final List onEnchantSkills = item.getItem().getSkills(ItemSkillType.ON_ENCHANT); + if (onEnchantSkills != null) { - if (player.getSkillLevel(holder.getSkillId()) >= holder.getSkillLevel()) + for (ItemSkillHolder holder : onEnchantSkills) { - continue; - } - - final Skill skill = holder.getSkill(); - if (skill != null) - { - if (skill.isPassive() && !skill.checkConditions(SkillConditionScope.PASSIVE, player, player)) + if (player.getSkillLevel(holder.getSkillId()) >= holder.getSkillLevel()) { continue; } - player.addSkill(skill, false); - if (skill.isActive() && !player.hasSkillReuse(skill.getReuseHashCode())) + // Add skills bestowed from +4 armor + if (item.getEnchantLevel() >= holder.getValue()) { - final int equipDelay = item.getEquipReuseDelay(); - if (equipDelay > 0) + final Skill skill = holder.getSkill(); + // Check passive skill conditions. + if (skill.isPassive() && !skill.checkConditions(SkillConditionScope.PASSIVE, player, player)) { - player.addTimeStamp(skill, equipDelay); - player.disableSkill(skill, equipDelay); + continue; + } + + if (addedSkills.containsKey(holder.getSkill().getId())) + { + if (addedSkills.get(holder.getSkill().getId()).getLevel() < holder.getSkill().getLevel()) + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + } + else + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); } - updateTimestamp = true; } - update = true; } - else + } + + final List normalSkills = item.getItem().getSkills(ItemSkillType.NORMAL); + if (normalSkills != null) + { + for (ItemSkillHolder holder : normalSkills) { - LOGGER.warning("Inventory.ItemSkillsListener.Weapon: Incorrect skill: " + holder); + if (player.getSkillLevel(holder.getSkillId()) >= holder.getSkillLevel()) + { + continue; + } + + final Skill skill = holder.getSkill(); + if (skill != null) + { + if (skill.isPassive() && !skill.checkConditions(SkillConditionScope.PASSIVE, player, player)) + { + continue; + } + + if (addedSkills.containsKey(holder.getSkill().getId())) + { + if (addedSkills.get(holder.getSkill().getId()).getLevel() < holder.getSkill().getLevel()) + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + } + else + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + + if (skill.isActive() && !player.hasSkillReuse(skill.getReuseHashCode())) + { + final int equipDelay = item.getEquipReuseDelay(); + if (equipDelay > 0) + { + player.addTimeStamp(skill, equipDelay); + player.disableSkill(skill, equipDelay); + } + updateTimestamp = true; + } + } } } } @@ -578,6 +656,11 @@ public abstract class Inventory extends ItemContainer // Must check all equipped items for enchant conditions. for (ItemInstance equipped : inventory.getPaperdollItems()) { + if (!equipped.getItem().hasSkills()) + { + continue; + } + final List otherEnchantSkills = equipped.getItem().getSkills(ItemSkillType.ON_ENCHANT); if (otherEnchantSkills == null) { @@ -600,8 +683,18 @@ public abstract class Inventory extends ItemContainer { continue; } - player.addSkill(skill, false); - update = true; + + if (addedSkills.containsKey(holder.getSkill().getId())) + { + if (addedSkills.get(holder.getSkill().getId()).getLevel() < holder.getSkill().getLevel()) + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + } + else + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } } } } @@ -612,10 +705,16 @@ public abstract class Inventory extends ItemContainer item.getItem().forEachSkill(ItemSkillType.ON_EQUIP, holder -> holder.getSkill().activateSkill(player, player)); } - if (update) + if (!addedSkills.isEmpty()) { + for (Skill skill : addedSkills.values()) + { + player.addSkill(skill, false); + } + player.sendSkillList(); } + if (updateTimestamp) { player.sendPacket(new SkillCoolTime(player)); diff --git a/L2J_Mobius_Classic_2.3_SevenSigns/java/org/l2jmobius/gameserver/model/items/Item.java b/L2J_Mobius_Classic_2.3_SevenSigns/java/org/l2jmobius/gameserver/model/items/Item.java index a7493cf689..6de5a49241 100644 --- a/L2J_Mobius_Classic_2.3_SevenSigns/java/org/l2jmobius/gameserver/model/items/Item.java +++ b/L2J_Mobius_Classic_2.3_SevenSigns/java/org/l2jmobius/gameserver/model/items/Item.java @@ -753,6 +753,11 @@ public abstract class Item extends ListenersContainer implements IIdentifiable return _preConditions; } + public boolean hasSkills() + { + return _skills != null; + } + /** * Method to retrieve skills linked to this item armor and weapon: passive skills etcitem: skills used on item use <-- ??? * @return Skills linked to this item as SkillHolder[] diff --git a/L2J_Mobius_Classic_2.4_SecretOfEmpire/java/org/l2jmobius/gameserver/model/itemcontainer/Inventory.java b/L2J_Mobius_Classic_2.4_SecretOfEmpire/java/org/l2jmobius/gameserver/model/itemcontainer/Inventory.java index 53c4fcfae3..af0999de2b 100644 --- a/L2J_Mobius_Classic_2.4_SecretOfEmpire/java/org/l2jmobius/gameserver/model/itemcontainer/Inventory.java +++ b/L2J_Mobius_Classic_2.4_SecretOfEmpire/java/org/l2jmobius/gameserver/model/itemcontainer/Inventory.java @@ -21,7 +21,9 @@ import java.sql.PreparedStatement; import java.sql.ResultSet; import java.util.ArrayList; import java.util.Collection; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.Objects; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; @@ -329,6 +331,8 @@ public abstract class Inventory extends ItemContainer final PlayerInstance player = (PlayerInstance) inventory.getOwner(); final Item it = item.getItem(); + final Map addedSkills = new HashMap<>(1); + final Map removedSkills = new HashMap<>(1); boolean update = false; boolean updateTimestamp = false; @@ -341,81 +345,111 @@ public abstract class Inventory extends ItemContainer // Recalculate all stats player.getStat().recalculateStats(true); - final List onEnchantSkills = it.getSkills(ItemSkillType.ON_ENCHANT); - if (onEnchantSkills != null) - { - for (ItemSkillHolder holder : onEnchantSkills) - { - // Remove skills bestowed from +4 armor - if (item.getEnchantLevel() >= holder.getValue()) - { - player.removeSkill(holder.getSkill(), false, holder.getSkill().isPassive()); - update = true; - } - } - } - // Clear enchant bonus item.clearEnchantStats(); // Clear SA Bonus item.clearSpecialAbilities(); - final List normalSkills = it.getSkills(ItemSkillType.NORMAL); - if (normalSkills != null) + if (it.hasSkills()) { - for (ItemSkillHolder holder : normalSkills) + final List onEnchantSkills = it.getSkills(ItemSkillType.ON_ENCHANT); + if (onEnchantSkills != null) { - final Skill skill = holder.getSkill(); - if (skill != null) + for (ItemSkillHolder holder : onEnchantSkills) { - player.removeSkill(skill, false, skill.isPassive()); - update = true; - } - else - { - LOGGER.warning("Inventory.ItemSkillsListener.Weapon: Incorrect skill: " + holder); + // Remove skills bestowed from +4 armor + if (item.getEnchantLevel() >= holder.getValue()) + { + if (removedSkills.containsKey(holder.getSkill().getId())) + { + if (removedSkills.get(holder.getSkill().getId()).getLevel() < holder.getSkill().getLevel()) + { + removedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + } + else + { + removedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + update = true; + } } } - } - - if (item.isArmor()) - { - for (ItemInstance itm : inventory.getItems()) + + final List normalSkills = it.getSkills(ItemSkillType.NORMAL); + if (normalSkills != null) { - if (!itm.isEquipped() || itm.equals(item)) + for (ItemSkillHolder holder : normalSkills) { - continue; + final Skill skill = holder.getSkill(); + if (skill != null) + { + if (removedSkills.containsKey(holder.getSkill().getId())) + { + if (removedSkills.get(holder.getSkill().getId()).getLevel() < holder.getSkill().getLevel()) + { + removedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + } + else + { + removedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + update = true; + } } - - final List otherNormalSkills = itm.getItem().getSkills(ItemSkillType.NORMAL); - if (otherNormalSkills == null) + } + + if (item.isArmor()) + { + for (ItemInstance itm : inventory.getItems()) { - continue; - } - - for (ItemSkillHolder holder : otherNormalSkills) - { - if (player.getSkillLevel(holder.getSkillId()) != 0) + if (!itm.isEquipped() || itm.equals(item)) { continue; } - final Skill skill = holder.getSkill(); - if (skill != null) + final List otherNormalSkills = itm.getItem().getSkills(ItemSkillType.NORMAL); + if (otherNormalSkills == null) { - player.addSkill(skill, false); - if (skill.isActive() && !player.hasSkillReuse(skill.getReuseHashCode())) + continue; + } + + for (ItemSkillHolder holder : otherNormalSkills) + { + if (player.getSkillLevel(holder.getSkillId()) != 0) { - final int equipDelay = item.getEquipReuseDelay(); - if (equipDelay > 0) - { - player.addTimeStamp(skill, equipDelay); - player.disableSkill(skill, equipDelay); - } - updateTimestamp = true; + continue; + } + + final Skill skill = holder.getSkill(); + if (skill != null) + { + if (addedSkills.containsKey(holder.getSkill().getId())) + { + if (addedSkills.get(holder.getSkill().getId()).getLevel() < holder.getSkill().getLevel()) + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + } + else + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + + if (skill.isActive() && !player.hasSkillReuse(skill.getReuseHashCode())) + { + final int equipDelay = item.getEquipReuseDelay(); + if (equipDelay > 0) + { + player.addTimeStamp(skill, equipDelay); + player.disableSkill(skill, equipDelay); + } + updateTimestamp = true; + } + update = true; } - update = true; } } } @@ -424,6 +458,11 @@ public abstract class Inventory extends ItemContainer // Must check all equipped items for enchant conditions. for (ItemInstance equipped : inventory.getPaperdollItems()) { + if (!equipped.getItem().hasSkills()) + { + continue; + } + final List otherEnchantSkills = equipped.getItem().getSkills(ItemSkillType.ON_ENCHANT); if (otherEnchantSkills == null) { @@ -439,7 +478,17 @@ public abstract class Inventory extends ItemContainer // Check passive skill conditions. if (skill.isPassive() && !skill.checkConditions(SkillConditionScope.PASSIVE, player, player)) { - player.removeSkill(holder.getSkill(), false, holder.getSkill().isPassive()); + if (removedSkills.containsKey(holder.getSkill().getId())) + { + if (removedSkills.get(holder.getSkill().getId()).getLevel() < holder.getSkill().getLevel()) + { + removedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + } + else + { + removedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } update = true; } } @@ -465,8 +514,19 @@ public abstract class Inventory extends ItemContainer if (update) { + for (Skill skill : removedSkills.values()) + { + player.removeSkill(skill, false, skill.isPassive()); + } + + for (Skill skill : addedSkills.values()) + { + player.addSkill(skill, false); + } + player.sendSkillList(); } + if (updateTimestamp) { player.sendPacket(new SkillCoolTime(player)); @@ -487,14 +547,13 @@ public abstract class Inventory extends ItemContainer } final PlayerInstance player = (PlayerInstance) inventory.getOwner(); - // Any items equipped that result in expertise penalty do not give any skills at all. if (item.getItem().getCrystalType().getLevel() > player.getExpertiseLevel()) { return; } - boolean update = false; + final Map addedSkills = new HashMap<>(1); boolean updateTimestamp = false; // Apply augmentation bonuses on equip @@ -506,71 +565,90 @@ public abstract class Inventory extends ItemContainer // Recalculate all stats player.getStat().recalculateStats(true); - final List onEnchantSkills = item.getItem().getSkills(ItemSkillType.ON_ENCHANT); - if (onEnchantSkills != null) - { - for (ItemSkillHolder holder : onEnchantSkills) - { - if (player.getSkillLevel(holder.getSkillId()) >= holder.getSkillLevel()) - { - continue; - } - - // Add skills bestowed from +4 armor - if (item.getEnchantLevel() >= holder.getValue()) - { - final Skill skill = holder.getSkill(); - // Check passive skill conditions. - if (skill.isPassive() && !skill.checkConditions(SkillConditionScope.PASSIVE, player, player)) - { - continue; - } - player.addSkill(skill, false); - update = true; - } - } - } - // Apply enchant stats item.applyEnchantStats(); // Apply SA skill item.applySpecialAbilities(); - final List normalSkills = item.getItem().getSkills(ItemSkillType.NORMAL); - if (normalSkills != null) + if (item.getItem().hasSkills()) { - for (ItemSkillHolder holder : normalSkills) + final List onEnchantSkills = item.getItem().getSkills(ItemSkillType.ON_ENCHANT); + if (onEnchantSkills != null) { - if (player.getSkillLevel(holder.getSkillId()) >= holder.getSkillLevel()) + for (ItemSkillHolder holder : onEnchantSkills) { - continue; - } - - final Skill skill = holder.getSkill(); - if (skill != null) - { - if (skill.isPassive() && !skill.checkConditions(SkillConditionScope.PASSIVE, player, player)) + if (player.getSkillLevel(holder.getSkillId()) >= holder.getSkillLevel()) { continue; } - player.addSkill(skill, false); - if (skill.isActive() && !player.hasSkillReuse(skill.getReuseHashCode())) + // Add skills bestowed from +4 armor + if (item.getEnchantLevel() >= holder.getValue()) { - final int equipDelay = item.getEquipReuseDelay(); - if (equipDelay > 0) + final Skill skill = holder.getSkill(); + // Check passive skill conditions. + if (skill.isPassive() && !skill.checkConditions(SkillConditionScope.PASSIVE, player, player)) { - player.addTimeStamp(skill, equipDelay); - player.disableSkill(skill, equipDelay); + continue; + } + + if (addedSkills.containsKey(holder.getSkill().getId())) + { + if (addedSkills.get(holder.getSkill().getId()).getLevel() < holder.getSkill().getLevel()) + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + } + else + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); } - updateTimestamp = true; } - update = true; } - else + } + + final List normalSkills = item.getItem().getSkills(ItemSkillType.NORMAL); + if (normalSkills != null) + { + for (ItemSkillHolder holder : normalSkills) { - LOGGER.warning("Inventory.ItemSkillsListener.Weapon: Incorrect skill: " + holder); + if (player.getSkillLevel(holder.getSkillId()) >= holder.getSkillLevel()) + { + continue; + } + + final Skill skill = holder.getSkill(); + if (skill != null) + { + if (skill.isPassive() && !skill.checkConditions(SkillConditionScope.PASSIVE, player, player)) + { + continue; + } + + if (addedSkills.containsKey(holder.getSkill().getId())) + { + if (addedSkills.get(holder.getSkill().getId()).getLevel() < holder.getSkill().getLevel()) + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + } + else + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + + if (skill.isActive() && !player.hasSkillReuse(skill.getReuseHashCode())) + { + final int equipDelay = item.getEquipReuseDelay(); + if (equipDelay > 0) + { + player.addTimeStamp(skill, equipDelay); + player.disableSkill(skill, equipDelay); + } + updateTimestamp = true; + } + } } } } @@ -578,6 +656,11 @@ public abstract class Inventory extends ItemContainer // Must check all equipped items for enchant conditions. for (ItemInstance equipped : inventory.getPaperdollItems()) { + if (!equipped.getItem().hasSkills()) + { + continue; + } + final List otherEnchantSkills = equipped.getItem().getSkills(ItemSkillType.ON_ENCHANT); if (otherEnchantSkills == null) { @@ -600,8 +683,18 @@ public abstract class Inventory extends ItemContainer { continue; } - player.addSkill(skill, false); - update = true; + + if (addedSkills.containsKey(holder.getSkill().getId())) + { + if (addedSkills.get(holder.getSkill().getId()).getLevel() < holder.getSkill().getLevel()) + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + } + else + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } } } } @@ -612,10 +705,16 @@ public abstract class Inventory extends ItemContainer item.getItem().forEachSkill(ItemSkillType.ON_EQUIP, holder -> holder.getSkill().activateSkill(player, player)); } - if (update) + if (!addedSkills.isEmpty()) { + for (Skill skill : addedSkills.values()) + { + player.addSkill(skill, false); + } + player.sendSkillList(); } + if (updateTimestamp) { player.sendPacket(new SkillCoolTime(player)); diff --git a/L2J_Mobius_Classic_2.4_SecretOfEmpire/java/org/l2jmobius/gameserver/model/items/Item.java b/L2J_Mobius_Classic_2.4_SecretOfEmpire/java/org/l2jmobius/gameserver/model/items/Item.java index a7493cf689..6de5a49241 100644 --- a/L2J_Mobius_Classic_2.4_SecretOfEmpire/java/org/l2jmobius/gameserver/model/items/Item.java +++ b/L2J_Mobius_Classic_2.4_SecretOfEmpire/java/org/l2jmobius/gameserver/model/items/Item.java @@ -753,6 +753,11 @@ public abstract class Item extends ListenersContainer implements IIdentifiable return _preConditions; } + public boolean hasSkills() + { + return _skills != null; + } + /** * Method to retrieve skills linked to this item armor and weapon: passive skills etcitem: skills used on item use <-- ??? * @return Skills linked to this item as SkillHolder[] diff --git a/L2J_Mobius_Classic_3.0_TheKamael/java/org/l2jmobius/gameserver/model/itemcontainer/Inventory.java b/L2J_Mobius_Classic_3.0_TheKamael/java/org/l2jmobius/gameserver/model/itemcontainer/Inventory.java index 65c6a450a3..affda3e80e 100644 --- a/L2J_Mobius_Classic_3.0_TheKamael/java/org/l2jmobius/gameserver/model/itemcontainer/Inventory.java +++ b/L2J_Mobius_Classic_3.0_TheKamael/java/org/l2jmobius/gameserver/model/itemcontainer/Inventory.java @@ -21,7 +21,9 @@ import java.sql.PreparedStatement; import java.sql.ResultSet; import java.util.ArrayList; import java.util.Collection; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.Objects; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; @@ -329,6 +331,8 @@ public abstract class Inventory extends ItemContainer final PlayerInstance player = (PlayerInstance) inventory.getOwner(); final Item it = item.getItem(); + final Map addedSkills = new HashMap<>(1); + final Map removedSkills = new HashMap<>(1); boolean update = false; boolean updateTimestamp = false; @@ -341,81 +345,111 @@ public abstract class Inventory extends ItemContainer // Recalculate all stats player.getStat().recalculateStats(true); - final List onEnchantSkills = it.getSkills(ItemSkillType.ON_ENCHANT); - if (onEnchantSkills != null) - { - for (ItemSkillHolder holder : onEnchantSkills) - { - // Remove skills bestowed from +4 armor - if (item.getEnchantLevel() >= holder.getValue()) - { - player.removeSkill(holder.getSkill(), false, holder.getSkill().isPassive()); - update = true; - } - } - } - // Clear enchant bonus item.clearEnchantStats(); // Clear SA Bonus item.clearSpecialAbilities(); - final List normalSkills = it.getSkills(ItemSkillType.NORMAL); - if (normalSkills != null) + if (it.hasSkills()) { - for (ItemSkillHolder holder : normalSkills) + final List onEnchantSkills = it.getSkills(ItemSkillType.ON_ENCHANT); + if (onEnchantSkills != null) { - final Skill skill = holder.getSkill(); - if (skill != null) + for (ItemSkillHolder holder : onEnchantSkills) { - player.removeSkill(skill, false, skill.isPassive()); - update = true; - } - else - { - LOGGER.warning("Inventory.ItemSkillsListener.Weapon: Incorrect skill: " + holder); + // Remove skills bestowed from +4 armor + if (item.getEnchantLevel() >= holder.getValue()) + { + if (removedSkills.containsKey(holder.getSkill().getId())) + { + if (removedSkills.get(holder.getSkill().getId()).getLevel() < holder.getSkill().getLevel()) + { + removedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + } + else + { + removedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + update = true; + } } } - } - - if (item.isArmor()) - { - for (ItemInstance itm : inventory.getItems()) + + final List normalSkills = it.getSkills(ItemSkillType.NORMAL); + if (normalSkills != null) { - if (!itm.isEquipped() || itm.equals(item)) + for (ItemSkillHolder holder : normalSkills) { - continue; + final Skill skill = holder.getSkill(); + if (skill != null) + { + if (removedSkills.containsKey(holder.getSkill().getId())) + { + if (removedSkills.get(holder.getSkill().getId()).getLevel() < holder.getSkill().getLevel()) + { + removedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + } + else + { + removedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + update = true; + } } - - final List otherNormalSkills = itm.getItem().getSkills(ItemSkillType.NORMAL); - if (otherNormalSkills == null) + } + + if (item.isArmor()) + { + for (ItemInstance itm : inventory.getItems()) { - continue; - } - - for (ItemSkillHolder holder : otherNormalSkills) - { - if (player.getSkillLevel(holder.getSkillId()) != 0) + if (!itm.isEquipped() || itm.equals(item)) { continue; } - final Skill skill = holder.getSkill(); - if (skill != null) + final List otherNormalSkills = itm.getItem().getSkills(ItemSkillType.NORMAL); + if (otherNormalSkills == null) { - player.addSkill(skill, false); - if (skill.isActive() && !player.hasSkillReuse(skill.getReuseHashCode())) + continue; + } + + for (ItemSkillHolder holder : otherNormalSkills) + { + if (player.getSkillLevel(holder.getSkillId()) != 0) { - final int equipDelay = item.getEquipReuseDelay(); - if (equipDelay > 0) - { - player.addTimeStamp(skill, equipDelay); - player.disableSkill(skill, equipDelay); - } - updateTimestamp = true; + continue; + } + + final Skill skill = holder.getSkill(); + if (skill != null) + { + if (addedSkills.containsKey(holder.getSkill().getId())) + { + if (addedSkills.get(holder.getSkill().getId()).getLevel() < holder.getSkill().getLevel()) + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + } + else + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + + if (skill.isActive() && !player.hasSkillReuse(skill.getReuseHashCode())) + { + final int equipDelay = item.getEquipReuseDelay(); + if (equipDelay > 0) + { + player.addTimeStamp(skill, equipDelay); + player.disableSkill(skill, equipDelay); + } + updateTimestamp = true; + } + update = true; } - update = true; } } } @@ -424,6 +458,11 @@ public abstract class Inventory extends ItemContainer // Must check all equipped items for enchant conditions. for (ItemInstance equipped : inventory.getPaperdollItems()) { + if (!equipped.getItem().hasSkills()) + { + continue; + } + final List otherEnchantSkills = equipped.getItem().getSkills(ItemSkillType.ON_ENCHANT); if (otherEnchantSkills == null) { @@ -439,7 +478,17 @@ public abstract class Inventory extends ItemContainer // Check passive skill conditions. if (skill.isPassive() && !skill.checkConditions(SkillConditionScope.PASSIVE, player, player)) { - player.removeSkill(holder.getSkill(), false, holder.getSkill().isPassive()); + if (removedSkills.containsKey(holder.getSkill().getId())) + { + if (removedSkills.get(holder.getSkill().getId()).getLevel() < holder.getSkill().getLevel()) + { + removedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + } + else + { + removedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } update = true; } } @@ -465,8 +514,19 @@ public abstract class Inventory extends ItemContainer if (update) { + for (Skill skill : removedSkills.values()) + { + player.removeSkill(skill, false, skill.isPassive()); + } + + for (Skill skill : addedSkills.values()) + { + player.addSkill(skill, false); + } + player.sendSkillList(); } + if (updateTimestamp) { player.sendPacket(new SkillCoolTime(player)); @@ -487,7 +547,7 @@ public abstract class Inventory extends ItemContainer } final PlayerInstance player = (PlayerInstance) inventory.getOwner(); - boolean update = false; + final Map addedSkills = new HashMap<>(1); boolean updateTimestamp = false; // Apply augmentation bonuses on equip @@ -499,71 +559,90 @@ public abstract class Inventory extends ItemContainer // Recalculate all stats player.getStat().recalculateStats(true); - final List onEnchantSkills = item.getItem().getSkills(ItemSkillType.ON_ENCHANT); - if (onEnchantSkills != null) - { - for (ItemSkillHolder holder : onEnchantSkills) - { - if (player.getSkillLevel(holder.getSkillId()) >= holder.getSkillLevel()) - { - continue; - } - - // Add skills bestowed from +4 armor - if (item.getEnchantLevel() >= holder.getValue()) - { - final Skill skill = holder.getSkill(); - // Check passive skill conditions. - if (skill.isPassive() && !skill.checkConditions(SkillConditionScope.PASSIVE, player, player)) - { - continue; - } - player.addSkill(skill, false); - update = true; - } - } - } - // Apply enchant stats item.applyEnchantStats(); // Apply SA skill item.applySpecialAbilities(); - final List normalSkills = item.getItem().getSkills(ItemSkillType.NORMAL); - if (normalSkills != null) + if (item.getItem().hasSkills()) { - for (ItemSkillHolder holder : normalSkills) + final List onEnchantSkills = item.getItem().getSkills(ItemSkillType.ON_ENCHANT); + if (onEnchantSkills != null) { - if (player.getSkillLevel(holder.getSkillId()) >= holder.getSkillLevel()) + for (ItemSkillHolder holder : onEnchantSkills) { - continue; - } - - final Skill skill = holder.getSkill(); - if (skill != null) - { - if (skill.isPassive() && !skill.checkConditions(SkillConditionScope.PASSIVE, player, player)) + if (player.getSkillLevel(holder.getSkillId()) >= holder.getSkillLevel()) { continue; } - player.addSkill(skill, false); - if (skill.isActive() && !player.hasSkillReuse(skill.getReuseHashCode())) + // Add skills bestowed from +4 armor + if (item.getEnchantLevel() >= holder.getValue()) { - final int equipDelay = item.getEquipReuseDelay(); - if (equipDelay > 0) + final Skill skill = holder.getSkill(); + // Check passive skill conditions. + if (skill.isPassive() && !skill.checkConditions(SkillConditionScope.PASSIVE, player, player)) { - player.addTimeStamp(skill, equipDelay); - player.disableSkill(skill, equipDelay); + continue; + } + + if (addedSkills.containsKey(holder.getSkill().getId())) + { + if (addedSkills.get(holder.getSkill().getId()).getLevel() < holder.getSkill().getLevel()) + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + } + else + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); } - updateTimestamp = true; } - update = true; } - else + } + + final List normalSkills = item.getItem().getSkills(ItemSkillType.NORMAL); + if (normalSkills != null) + { + for (ItemSkillHolder holder : normalSkills) { - LOGGER.warning("Inventory.ItemSkillsListener.Weapon: Incorrect skill: " + holder); + if (player.getSkillLevel(holder.getSkillId()) >= holder.getSkillLevel()) + { + continue; + } + + final Skill skill = holder.getSkill(); + if (skill != null) + { + if (skill.isPassive() && !skill.checkConditions(SkillConditionScope.PASSIVE, player, player)) + { + continue; + } + + if (addedSkills.containsKey(holder.getSkill().getId())) + { + if (addedSkills.get(holder.getSkill().getId()).getLevel() < holder.getSkill().getLevel()) + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + } + else + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + + if (skill.isActive() && !player.hasSkillReuse(skill.getReuseHashCode())) + { + final int equipDelay = item.getEquipReuseDelay(); + if (equipDelay > 0) + { + player.addTimeStamp(skill, equipDelay); + player.disableSkill(skill, equipDelay); + } + updateTimestamp = true; + } + } } } } @@ -571,6 +650,11 @@ public abstract class Inventory extends ItemContainer // Must check all equipped items for enchant conditions. for (ItemInstance equipped : inventory.getPaperdollItems()) { + if (!equipped.getItem().hasSkills()) + { + continue; + } + final List otherEnchantSkills = equipped.getItem().getSkills(ItemSkillType.ON_ENCHANT); if (otherEnchantSkills == null) { @@ -593,8 +677,18 @@ public abstract class Inventory extends ItemContainer { continue; } - player.addSkill(skill, false); - update = true; + + if (addedSkills.containsKey(holder.getSkill().getId())) + { + if (addedSkills.get(holder.getSkill().getId()).getLevel() < holder.getSkill().getLevel()) + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + } + else + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } } } } @@ -605,10 +699,16 @@ public abstract class Inventory extends ItemContainer item.getItem().forEachSkill(ItemSkillType.ON_EQUIP, holder -> holder.getSkill().activateSkill(player, player)); } - if (update) + if (!addedSkills.isEmpty()) { + for (Skill skill : addedSkills.values()) + { + player.addSkill(skill, false); + } + player.sendSkillList(); } + if (updateTimestamp) { player.sendPacket(new SkillCoolTime(player)); diff --git a/L2J_Mobius_Classic_3.0_TheKamael/java/org/l2jmobius/gameserver/model/items/Item.java b/L2J_Mobius_Classic_3.0_TheKamael/java/org/l2jmobius/gameserver/model/items/Item.java index a7493cf689..6de5a49241 100644 --- a/L2J_Mobius_Classic_3.0_TheKamael/java/org/l2jmobius/gameserver/model/items/Item.java +++ b/L2J_Mobius_Classic_3.0_TheKamael/java/org/l2jmobius/gameserver/model/items/Item.java @@ -753,6 +753,11 @@ public abstract class Item extends ListenersContainer implements IIdentifiable return _preConditions; } + public boolean hasSkills() + { + return _skills != null; + } + /** * Method to retrieve skills linked to this item armor and weapon: passive skills etcitem: skills used on item use <-- ??? * @return Skills linked to this item as SkillHolder[] diff --git a/L2J_Mobius_Classic_Interlude/java/org/l2jmobius/gameserver/model/itemcontainer/Inventory.java b/L2J_Mobius_Classic_Interlude/java/org/l2jmobius/gameserver/model/itemcontainer/Inventory.java index 3017ab91d8..86fd39d1c2 100644 --- a/L2J_Mobius_Classic_Interlude/java/org/l2jmobius/gameserver/model/itemcontainer/Inventory.java +++ b/L2J_Mobius_Classic_Interlude/java/org/l2jmobius/gameserver/model/itemcontainer/Inventory.java @@ -21,7 +21,9 @@ import java.sql.PreparedStatement; import java.sql.ResultSet; import java.util.ArrayList; import java.util.Collection; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.Objects; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; @@ -298,6 +300,8 @@ public abstract class Inventory extends ItemContainer final PlayerInstance player = (PlayerInstance) inventory.getOwner(); final Item it = item.getItem(); + final Map addedSkills = new HashMap<>(1); + final Map removedSkills = new HashMap<>(1); boolean update = false; boolean updateTimestamp = false; @@ -310,78 +314,108 @@ public abstract class Inventory extends ItemContainer // Recalculate all stats player.getStat().recalculateStats(true); - final List onEnchantSkills = it.getSkills(ItemSkillType.ON_ENCHANT); - if (onEnchantSkills != null) - { - for (ItemSkillHolder holder : onEnchantSkills) - { - // Remove skills bestowed from +4 armor - if (item.getEnchantLevel() >= holder.getValue()) - { - player.removeSkill(holder.getSkill(), false, holder.getSkill().isPassive()); - update = true; - } - } - } - // Clear enchant bonus item.clearEnchantStats(); - final List normalSkills = it.getSkills(ItemSkillType.NORMAL); - if (normalSkills != null) + if (it.hasSkills()) { - for (ItemSkillHolder holder : normalSkills) + final List onEnchantSkills = it.getSkills(ItemSkillType.ON_ENCHANT); + if (onEnchantSkills != null) { - final Skill skill = holder.getSkill(); - if (skill != null) + for (ItemSkillHolder holder : onEnchantSkills) { - player.removeSkill(skill, false, skill.isPassive()); - update = true; - } - else - { - LOGGER.warning("Inventory.ItemSkillsListener.Weapon: Incorrect skill: " + holder); + // Remove skills bestowed from +4 armor + if (item.getEnchantLevel() >= holder.getValue()) + { + if (removedSkills.containsKey(holder.getSkill().getId())) + { + if (removedSkills.get(holder.getSkill().getId()).getLevel() < holder.getSkill().getLevel()) + { + removedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + } + else + { + removedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + update = true; + } } } - } - - if (item.isArmor()) - { - for (ItemInstance itm : inventory.getItems()) + + final List normalSkills = it.getSkills(ItemSkillType.NORMAL); + if (normalSkills != null) { - if (!itm.isEquipped() || itm.equals(item)) + for (ItemSkillHolder holder : normalSkills) { - continue; + final Skill skill = holder.getSkill(); + if (skill != null) + { + if (removedSkills.containsKey(holder.getSkill().getId())) + { + if (removedSkills.get(holder.getSkill().getId()).getLevel() < holder.getSkill().getLevel()) + { + removedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + } + else + { + removedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + update = true; + } } - - final List otherNormalSkills = itm.getItem().getSkills(ItemSkillType.NORMAL); - if (otherNormalSkills == null) + } + + if (item.isArmor()) + { + for (ItemInstance itm : inventory.getItems()) { - continue; - } - - for (ItemSkillHolder holder : otherNormalSkills) - { - if (player.getSkillLevel(holder.getSkillId()) != 0) + if (!itm.isEquipped() || itm.equals(item)) { continue; } - final Skill skill = holder.getSkill(); - if (skill != null) + final List otherNormalSkills = itm.getItem().getSkills(ItemSkillType.NORMAL); + if (otherNormalSkills == null) { - player.addSkill(skill, false); - if (skill.isActive() && !player.hasSkillReuse(skill.getReuseHashCode())) + continue; + } + + for (ItemSkillHolder holder : otherNormalSkills) + { + if (player.getSkillLevel(holder.getSkillId()) != 0) { - final int equipDelay = item.getEquipReuseDelay(); - if (equipDelay > 0) - { - player.addTimeStamp(skill, equipDelay); - player.disableSkill(skill, equipDelay); - } - updateTimestamp = true; + continue; + } + + final Skill skill = holder.getSkill(); + if (skill != null) + { + if (addedSkills.containsKey(holder.getSkill().getId())) + { + if (addedSkills.get(holder.getSkill().getId()).getLevel() < holder.getSkill().getLevel()) + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + } + else + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + + if (skill.isActive() && !player.hasSkillReuse(skill.getReuseHashCode())) + { + final int equipDelay = item.getEquipReuseDelay(); + if (equipDelay > 0) + { + player.addTimeStamp(skill, equipDelay); + player.disableSkill(skill, equipDelay); + } + updateTimestamp = true; + } + update = true; } - update = true; } } } @@ -390,6 +424,11 @@ public abstract class Inventory extends ItemContainer // Must check all equipped items for enchant conditions. for (ItemInstance equipped : inventory.getPaperdollItems()) { + if (!equipped.getItem().hasSkills()) + { + continue; + } + final List otherEnchantSkills = equipped.getItem().getSkills(ItemSkillType.ON_ENCHANT); if (otherEnchantSkills == null) { @@ -405,7 +444,17 @@ public abstract class Inventory extends ItemContainer // Check passive skill conditions. if (skill.isPassive() && !skill.checkConditions(SkillConditionScope.PASSIVE, player, player)) { - player.removeSkill(holder.getSkill(), false, holder.getSkill().isPassive()); + if (removedSkills.containsKey(holder.getSkill().getId())) + { + if (removedSkills.get(holder.getSkill().getId()).getLevel() < holder.getSkill().getLevel()) + { + removedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + } + else + { + removedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } update = true; } } @@ -425,10 +474,22 @@ public abstract class Inventory extends ItemContainer // Apply skill, if weapon have "skills on unequip" it.forEachSkill(ItemSkillType.ON_UNEQUIP, holder -> holder.getSkill().activateSkill(player, player)); + if (update) { + for (Skill skill : removedSkills.values()) + { + player.removeSkill(skill, false, skill.isPassive()); + } + + for (Skill skill : addedSkills.values()) + { + player.addSkill(skill, false); + } + player.sendSkillList(); } + if (updateTimestamp) { player.sendPacket(new SkillCoolTime(player)); @@ -449,14 +510,13 @@ public abstract class Inventory extends ItemContainer } final PlayerInstance player = (PlayerInstance) inventory.getOwner(); - // Any items equipped that result in expertise penalty do not give any skills at all. if (item.getItem().getCrystalType().getLevel() > player.getExpertiseLevel()) { return; } - boolean update = false; + final Map addedSkills = new HashMap<>(1); boolean updateTimestamp = false; // Apply augmentation bonuses on equip @@ -468,68 +528,87 @@ public abstract class Inventory extends ItemContainer // Recalculate all stats player.getStat().recalculateStats(true); - final List onEnchantSkills = item.getItem().getSkills(ItemSkillType.ON_ENCHANT); - if (onEnchantSkills != null) - { - for (ItemSkillHolder holder : onEnchantSkills) - { - if (player.getSkillLevel(holder.getSkillId()) >= holder.getSkillLevel()) - { - continue; - } - - // Add skills bestowed from +4 armor - if (item.getEnchantLevel() >= holder.getValue()) - { - final Skill skill = holder.getSkill(); - // Check passive skill conditions. - if (skill.isPassive() && !skill.checkConditions(SkillConditionScope.PASSIVE, player, player)) - { - continue; - } - player.addSkill(skill, false); - update = true; - } - } - } - // Apply enchant stats item.applyEnchantStats(); - final List normalSkills = item.getItem().getSkills(ItemSkillType.NORMAL); - if (normalSkills != null) + if (item.getItem().hasSkills()) { - for (ItemSkillHolder holder : normalSkills) + final List onEnchantSkills = item.getItem().getSkills(ItemSkillType.ON_ENCHANT); + if (onEnchantSkills != null) { - if (player.getSkillLevel(holder.getSkillId()) >= holder.getSkillLevel()) + for (ItemSkillHolder holder : onEnchantSkills) { - continue; - } - - final Skill skill = holder.getSkill(); - if (skill != null) - { - if (skill.isPassive() && !skill.checkConditions(SkillConditionScope.PASSIVE, player, player)) + if (player.getSkillLevel(holder.getSkillId()) >= holder.getSkillLevel()) { continue; } - player.addSkill(skill, false); - if (skill.isActive() && !player.hasSkillReuse(skill.getReuseHashCode())) + // Add skills bestowed from +4 armor + if (item.getEnchantLevel() >= holder.getValue()) { - final int equipDelay = item.getEquipReuseDelay(); - if (equipDelay > 0) + final Skill skill = holder.getSkill(); + // Check passive skill conditions. + if (skill.isPassive() && !skill.checkConditions(SkillConditionScope.PASSIVE, player, player)) { - player.addTimeStamp(skill, equipDelay); - player.disableSkill(skill, equipDelay); + continue; + } + + if (addedSkills.containsKey(holder.getSkill().getId())) + { + if (addedSkills.get(holder.getSkill().getId()).getLevel() < holder.getSkill().getLevel()) + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + } + else + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); } - updateTimestamp = true; } - update = true; } - else + } + + final List normalSkills = item.getItem().getSkills(ItemSkillType.NORMAL); + if (normalSkills != null) + { + for (ItemSkillHolder holder : normalSkills) { - LOGGER.warning("Inventory.ItemSkillsListener.Weapon: Incorrect skill: " + holder); + if (player.getSkillLevel(holder.getSkillId()) >= holder.getSkillLevel()) + { + continue; + } + + final Skill skill = holder.getSkill(); + if (skill != null) + { + if (skill.isPassive() && !skill.checkConditions(SkillConditionScope.PASSIVE, player, player)) + { + continue; + } + + if (addedSkills.containsKey(holder.getSkill().getId())) + { + if (addedSkills.get(holder.getSkill().getId()).getLevel() < holder.getSkill().getLevel()) + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + } + else + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + + if (skill.isActive() && !player.hasSkillReuse(skill.getReuseHashCode())) + { + final int equipDelay = item.getEquipReuseDelay(); + if (equipDelay > 0) + { + player.addTimeStamp(skill, equipDelay); + player.disableSkill(skill, equipDelay); + } + updateTimestamp = true; + } + } } } } @@ -537,6 +616,11 @@ public abstract class Inventory extends ItemContainer // Must check all equipped items for enchant conditions. for (ItemInstance equipped : inventory.getPaperdollItems()) { + if (!equipped.getItem().hasSkills()) + { + continue; + } + final List otherEnchantSkills = equipped.getItem().getSkills(ItemSkillType.ON_ENCHANT); if (otherEnchantSkills == null) { @@ -559,18 +643,35 @@ public abstract class Inventory extends ItemContainer { continue; } - player.addSkill(skill, false); - update = true; + + if (addedSkills.containsKey(holder.getSkill().getId())) + { + if (addedSkills.get(holder.getSkill().getId()).getLevel() < holder.getSkill().getLevel()) + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + } + else + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } } } } // Apply skill, if weapon have "skills on equip" item.getItem().forEachSkill(ItemSkillType.ON_EQUIP, holder -> holder.getSkill().activateSkill(player, player)); - if (update) + + if (!addedSkills.isEmpty()) { + for (Skill skill : addedSkills.values()) + { + player.addSkill(skill, false); + } + player.sendSkillList(); } + if (updateTimestamp) { player.sendPacket(new SkillCoolTime(player)); diff --git a/L2J_Mobius_Classic_Interlude/java/org/l2jmobius/gameserver/model/items/Item.java b/L2J_Mobius_Classic_Interlude/java/org/l2jmobius/gameserver/model/items/Item.java index e2255f8244..5556524f8d 100644 --- a/L2J_Mobius_Classic_Interlude/java/org/l2jmobius/gameserver/model/items/Item.java +++ b/L2J_Mobius_Classic_Interlude/java/org/l2jmobius/gameserver/model/items/Item.java @@ -747,6 +747,11 @@ public abstract class Item extends ListenersContainer implements IIdentifiable return _preConditions; } + public boolean hasSkills() + { + return _skills != null; + } + /** * Method to retrieve skills linked to this item armor and weapon: passive skills etcitem: skills used on item use <-- ??? * @return Skills linked to this item as SkillHolder[] diff --git a/L2J_Mobius_Essence_4.0_DwellingOfSpirits/java/org/l2jmobius/gameserver/model/itemcontainer/Inventory.java b/L2J_Mobius_Essence_4.0_DwellingOfSpirits/java/org/l2jmobius/gameserver/model/itemcontainer/Inventory.java index 2c6530ab26..c9a38b4aff 100644 --- a/L2J_Mobius_Essence_4.0_DwellingOfSpirits/java/org/l2jmobius/gameserver/model/itemcontainer/Inventory.java +++ b/L2J_Mobius_Essence_4.0_DwellingOfSpirits/java/org/l2jmobius/gameserver/model/itemcontainer/Inventory.java @@ -21,7 +21,9 @@ import java.sql.PreparedStatement; import java.sql.ResultSet; import java.util.ArrayList; import java.util.Collection; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.Objects; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; @@ -324,6 +326,8 @@ public abstract class Inventory extends ItemContainer final PlayerInstance player = (PlayerInstance) inventory.getOwner(); final Item it = item.getItem(); + final Map addedSkills = new HashMap<>(1); + final Map removedSkills = new HashMap<>(1); boolean update = false; boolean updateTimestamp = false; @@ -336,81 +340,111 @@ public abstract class Inventory extends ItemContainer // Recalculate all stats player.getStat().recalculateStats(true); - final List onEnchantSkills = it.getSkills(ItemSkillType.ON_ENCHANT); - if (onEnchantSkills != null) - { - for (ItemSkillHolder holder : onEnchantSkills) - { - // Remove skills bestowed from +4 armor - if (item.getEnchantLevel() >= holder.getValue()) - { - player.removeSkill(holder.getSkill(), false, holder.getSkill().isPassive()); - update = true; - } - } - } - // Clear enchant bonus item.clearEnchantStats(); // Clear SA Bonus item.clearSpecialAbilities(); - final List normalSkills = it.getSkills(ItemSkillType.NORMAL); - if (normalSkills != null) + if (it.hasSkills()) { - for (ItemSkillHolder holder : normalSkills) + final List onEnchantSkills = it.getSkills(ItemSkillType.ON_ENCHANT); + if (onEnchantSkills != null) { - final Skill skill = holder.getSkill(); - if (skill != null) + for (ItemSkillHolder holder : onEnchantSkills) { - player.removeSkill(skill, false, skill.isPassive()); - update = true; - } - else - { - LOGGER.warning("Inventory.ItemSkillsListener.Weapon: Incorrect skill: " + holder); + // Remove skills bestowed from +4 armor + if (item.getEnchantLevel() >= holder.getValue()) + { + if (removedSkills.containsKey(holder.getSkill().getId())) + { + if (removedSkills.get(holder.getSkill().getId()).getLevel() < holder.getSkill().getLevel()) + { + removedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + } + else + { + removedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + update = true; + } } } - } - - if (item.isArmor()) - { - for (ItemInstance itm : inventory.getItems()) + + final List normalSkills = it.getSkills(ItemSkillType.NORMAL); + if (normalSkills != null) { - if (!itm.isEquipped() || itm.equals(item)) + for (ItemSkillHolder holder : normalSkills) { - continue; + final Skill skill = holder.getSkill(); + if (skill != null) + { + if (removedSkills.containsKey(holder.getSkill().getId())) + { + if (removedSkills.get(holder.getSkill().getId()).getLevel() < holder.getSkill().getLevel()) + { + removedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + } + else + { + removedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + update = true; + } } - - final List otherNormalSkills = itm.getItem().getSkills(ItemSkillType.NORMAL); - if (otherNormalSkills == null) + } + + if (item.isArmor()) + { + for (ItemInstance itm : inventory.getItems()) { - continue; - } - - for (ItemSkillHolder holder : otherNormalSkills) - { - if (player.getSkillLevel(holder.getSkillId()) != 0) + if (!itm.isEquipped() || itm.equals(item)) { continue; } - final Skill skill = holder.getSkill(); - if (skill != null) + final List otherNormalSkills = itm.getItem().getSkills(ItemSkillType.NORMAL); + if (otherNormalSkills == null) { - player.addSkill(skill, false); - if (skill.isActive() && !player.hasSkillReuse(skill.getReuseHashCode())) + continue; + } + + for (ItemSkillHolder holder : otherNormalSkills) + { + if (player.getSkillLevel(holder.getSkillId()) != 0) { - final int equipDelay = item.getEquipReuseDelay(); - if (equipDelay > 0) - { - player.addTimeStamp(skill, equipDelay); - player.disableSkill(skill, equipDelay); - } - updateTimestamp = true; + continue; + } + + final Skill skill = holder.getSkill(); + if (skill != null) + { + if (addedSkills.containsKey(holder.getSkill().getId())) + { + if (addedSkills.get(holder.getSkill().getId()).getLevel() < holder.getSkill().getLevel()) + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + } + else + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + + if (skill.isActive() && !player.hasSkillReuse(skill.getReuseHashCode())) + { + final int equipDelay = item.getEquipReuseDelay(); + if (equipDelay > 0) + { + player.addTimeStamp(skill, equipDelay); + player.disableSkill(skill, equipDelay); + } + updateTimestamp = true; + } + update = true; } - update = true; } } } @@ -419,6 +453,11 @@ public abstract class Inventory extends ItemContainer // Must check all equipped items for enchant conditions. for (ItemInstance equipped : inventory.getPaperdollItems()) { + if (!equipped.getItem().hasSkills()) + { + continue; + } + final List otherEnchantSkills = equipped.getItem().getSkills(ItemSkillType.ON_ENCHANT); if (otherEnchantSkills == null) { @@ -434,7 +473,17 @@ public abstract class Inventory extends ItemContainer // Check passive skill conditions. if (skill.isPassive() && !skill.checkConditions(SkillConditionScope.PASSIVE, player, player)) { - player.removeSkill(holder.getSkill(), false, holder.getSkill().isPassive()); + if (removedSkills.containsKey(holder.getSkill().getId())) + { + if (removedSkills.get(holder.getSkill().getId()).getLevel() < holder.getSkill().getLevel()) + { + removedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + } + else + { + removedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } update = true; } } @@ -460,8 +509,19 @@ public abstract class Inventory extends ItemContainer if (update) { + for (Skill skill : removedSkills.values()) + { + player.removeSkill(skill, false, skill.isPassive()); + } + + for (Skill skill : addedSkills.values()) + { + player.addSkill(skill, false); + } + player.sendSkillList(); } + if (updateTimestamp) { player.sendPacket(new SkillCoolTime(player)); @@ -482,7 +542,7 @@ public abstract class Inventory extends ItemContainer } final PlayerInstance player = (PlayerInstance) inventory.getOwner(); - boolean update = false; + final Map addedSkills = new HashMap<>(1); boolean updateTimestamp = false; // Apply augmentation bonuses on equip @@ -494,71 +554,90 @@ public abstract class Inventory extends ItemContainer // Recalculate all stats player.getStat().recalculateStats(true); - final List onEnchantSkills = item.getItem().getSkills(ItemSkillType.ON_ENCHANT); - if (onEnchantSkills != null) - { - for (ItemSkillHolder holder : onEnchantSkills) - { - if (player.getSkillLevel(holder.getSkillId()) >= holder.getSkillLevel()) - { - continue; - } - - // Add skills bestowed from +4 armor - if (item.getEnchantLevel() >= holder.getValue()) - { - final Skill skill = holder.getSkill(); - // Check passive skill conditions. - if (skill.isPassive() && !skill.checkConditions(SkillConditionScope.PASSIVE, player, player)) - { - continue; - } - player.addSkill(skill, false); - update = true; - } - } - } - // Apply enchant stats item.applyEnchantStats(); // Apply SA skill item.applySpecialAbilities(); - final List normalSkills = item.getItem().getSkills(ItemSkillType.NORMAL); - if (normalSkills != null) + if (item.getItem().hasSkills()) { - for (ItemSkillHolder holder : normalSkills) + final List onEnchantSkills = item.getItem().getSkills(ItemSkillType.ON_ENCHANT); + if (onEnchantSkills != null) { - if (player.getSkillLevel(holder.getSkillId()) >= holder.getSkillLevel()) + for (ItemSkillHolder holder : onEnchantSkills) { - continue; - } - - final Skill skill = holder.getSkill(); - if (skill != null) - { - if (skill.isPassive() && !skill.checkConditions(SkillConditionScope.PASSIVE, player, player)) + if (player.getSkillLevel(holder.getSkillId()) >= holder.getSkillLevel()) { continue; } - player.addSkill(skill, false); - if (skill.isActive() && !player.hasSkillReuse(skill.getReuseHashCode())) + // Add skills bestowed from +4 armor + if (item.getEnchantLevel() >= holder.getValue()) { - final int equipDelay = item.getEquipReuseDelay(); - if (equipDelay > 0) + final Skill skill = holder.getSkill(); + // Check passive skill conditions. + if (skill.isPassive() && !skill.checkConditions(SkillConditionScope.PASSIVE, player, player)) { - player.addTimeStamp(skill, equipDelay); - player.disableSkill(skill, equipDelay); + continue; + } + + if (addedSkills.containsKey(holder.getSkill().getId())) + { + if (addedSkills.get(holder.getSkill().getId()).getLevel() < holder.getSkill().getLevel()) + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + } + else + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); } - updateTimestamp = true; } - update = true; } - else + } + + final List normalSkills = item.getItem().getSkills(ItemSkillType.NORMAL); + if (normalSkills != null) + { + for (ItemSkillHolder holder : normalSkills) { - LOGGER.warning("Inventory.ItemSkillsListener.Weapon: Incorrect skill: " + holder); + if (player.getSkillLevel(holder.getSkillId()) >= holder.getSkillLevel()) + { + continue; + } + + final Skill skill = holder.getSkill(); + if (skill != null) + { + if (skill.isPassive() && !skill.checkConditions(SkillConditionScope.PASSIVE, player, player)) + { + continue; + } + + if (addedSkills.containsKey(holder.getSkill().getId())) + { + if (addedSkills.get(holder.getSkill().getId()).getLevel() < holder.getSkill().getLevel()) + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + } + else + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + + if (skill.isActive() && !player.hasSkillReuse(skill.getReuseHashCode())) + { + final int equipDelay = item.getEquipReuseDelay(); + if (equipDelay > 0) + { + player.addTimeStamp(skill, equipDelay); + player.disableSkill(skill, equipDelay); + } + updateTimestamp = true; + } + } } } } @@ -566,6 +645,11 @@ public abstract class Inventory extends ItemContainer // Must check all equipped items for enchant conditions. for (ItemInstance equipped : inventory.getPaperdollItems()) { + if (!equipped.getItem().hasSkills()) + { + continue; + } + final List otherEnchantSkills = equipped.getItem().getSkills(ItemSkillType.ON_ENCHANT); if (otherEnchantSkills == null) { @@ -588,8 +672,18 @@ public abstract class Inventory extends ItemContainer { continue; } - player.addSkill(skill, false); - update = true; + + if (addedSkills.containsKey(holder.getSkill().getId())) + { + if (addedSkills.get(holder.getSkill().getId()).getLevel() < holder.getSkill().getLevel()) + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + } + else + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } } } } @@ -600,10 +694,16 @@ public abstract class Inventory extends ItemContainer item.getItem().forEachSkill(ItemSkillType.ON_EQUIP, holder -> holder.getSkill().activateSkill(player, player)); } - if (update) + if (!addedSkills.isEmpty()) { + for (Skill skill : addedSkills.values()) + { + player.addSkill(skill, false); + } + player.sendSkillList(); } + if (updateTimestamp) { player.sendPacket(new SkillCoolTime(player)); diff --git a/L2J_Mobius_Essence_4.0_DwellingOfSpirits/java/org/l2jmobius/gameserver/model/items/Item.java b/L2J_Mobius_Essence_4.0_DwellingOfSpirits/java/org/l2jmobius/gameserver/model/items/Item.java index c86d0a5a41..10cd6a106a 100644 --- a/L2J_Mobius_Essence_4.0_DwellingOfSpirits/java/org/l2jmobius/gameserver/model/items/Item.java +++ b/L2J_Mobius_Essence_4.0_DwellingOfSpirits/java/org/l2jmobius/gameserver/model/items/Item.java @@ -753,6 +753,11 @@ public abstract class Item extends ListenersContainer implements IIdentifiable return _preConditions; } + public boolean hasSkills() + { + return _skills != null; + } + /** * Method to retrieve skills linked to this item armor and weapon: passive skills etcitem: skills used on item use <-- ??? * @return Skills linked to this item as SkillHolder[] diff --git a/L2J_Mobius_Essence_5.0_Sylph/java/org/l2jmobius/gameserver/model/itemcontainer/Inventory.java b/L2J_Mobius_Essence_5.0_Sylph/java/org/l2jmobius/gameserver/model/itemcontainer/Inventory.java index 38fbcf47f7..d0594966b1 100644 --- a/L2J_Mobius_Essence_5.0_Sylph/java/org/l2jmobius/gameserver/model/itemcontainer/Inventory.java +++ b/L2J_Mobius_Essence_5.0_Sylph/java/org/l2jmobius/gameserver/model/itemcontainer/Inventory.java @@ -21,7 +21,9 @@ import java.sql.PreparedStatement; import java.sql.ResultSet; import java.util.ArrayList; import java.util.Collection; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.Objects; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; @@ -333,6 +335,8 @@ public abstract class Inventory extends ItemContainer final PlayerInstance player = (PlayerInstance) inventory.getOwner(); final Item it = item.getItem(); + final Map addedSkills = new HashMap<>(1); + final Map removedSkills = new HashMap<>(1); boolean update = false; boolean updateTimestamp = false; @@ -345,94 +349,134 @@ public abstract class Inventory extends ItemContainer // Recalculate all stats player.getStat().recalculateStats(true); - final List onEnchantSkills = it.getSkills(ItemSkillType.ON_ENCHANT); - if (onEnchantSkills != null) - { - for (ItemSkillHolder holder : onEnchantSkills) - { - // Remove skills bestowed from +4 armor - if (item.getEnchantLevel() >= holder.getValue()) - { - player.removeSkill(holder.getSkill(), false, holder.getSkill().isPassive()); - update = true; - } - } - } - - final List onBlessingSkills = it.getSkills(ItemSkillType.ON_BLESSING); - if (onBlessingSkills != null) - { - for (ItemSkillHolder holder : onBlessingSkills) - { - if (item.isBlessed()) - { - player.removeSkill(holder.getSkill(), false, holder.getSkill().isPassive()); - update = true; - } - } - } - // Clear enchant bonus item.clearEnchantStats(); // Clear SA Bonus item.clearSpecialAbilities(); - final List normalSkills = it.getSkills(ItemSkillType.NORMAL); - if (normalSkills != null) + if (it.hasSkills()) { - for (ItemSkillHolder holder : normalSkills) + final List onEnchantSkills = it.getSkills(ItemSkillType.ON_ENCHANT); + if (onEnchantSkills != null) { - final Skill skill = holder.getSkill(); - if (skill != null) + for (ItemSkillHolder holder : onEnchantSkills) { - player.removeSkill(skill, false, skill.isPassive()); - update = true; - } - else - { - LOGGER.warning("Inventory.ItemSkillsListener.Weapon: Incorrect skill: " + holder); + // Remove skills bestowed from +4 armor + if (item.getEnchantLevel() >= holder.getValue()) + { + if (removedSkills.containsKey(holder.getSkill().getId())) + { + if (removedSkills.get(holder.getSkill().getId()).getLevel() < holder.getSkill().getLevel()) + { + removedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + } + else + { + removedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + update = true; + } } } - } - - if (item.isArmor()) - { - for (ItemInstance itm : inventory.getItems()) + + if (item.isBlessed()) { - if (!itm.isEquipped() || itm.equals(item)) + final List onBlessingSkills = it.getSkills(ItemSkillType.ON_BLESSING); + if (onBlessingSkills != null) { - continue; + for (ItemSkillHolder holder : onBlessingSkills) + { + if (removedSkills.containsKey(holder.getSkill().getId())) + { + if (removedSkills.get(holder.getSkill().getId()).getLevel() < holder.getSkill().getLevel()) + { + removedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + } + else + { + removedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + update = true; + } } - - final List otherNormalSkills = itm.getItem().getSkills(ItemSkillType.NORMAL); - if (otherNormalSkills == null) + } + + final List normalSkills = it.getSkills(ItemSkillType.NORMAL); + if (normalSkills != null) + { + for (ItemSkillHolder holder : normalSkills) { - continue; + final Skill skill = holder.getSkill(); + if (skill != null) + { + if (removedSkills.containsKey(holder.getSkill().getId())) + { + if (removedSkills.get(holder.getSkill().getId()).getLevel() < holder.getSkill().getLevel()) + { + removedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + } + else + { + removedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + update = true; + } } - - for (ItemSkillHolder holder : otherNormalSkills) + } + + if (item.isArmor()) + { + for (ItemInstance itm : inventory.getItems()) { - if (player.getSkillLevel(holder.getSkillId()) != 0) + if (!itm.isEquipped() || itm.equals(item)) { continue; } - final Skill skill = holder.getSkill(); - if (skill != null) + final List otherNormalSkills = itm.getItem().getSkills(ItemSkillType.NORMAL); + if (otherNormalSkills == null) { - player.addSkill(skill, false); - if (skill.isActive() && !player.hasSkillReuse(skill.getReuseHashCode())) + continue; + } + + for (ItemSkillHolder holder : otherNormalSkills) + { + if (player.getSkillLevel(holder.getSkillId()) != 0) { - final int equipDelay = item.getEquipReuseDelay(); - if (equipDelay > 0) - { - player.addTimeStamp(skill, equipDelay); - player.disableSkill(skill, equipDelay); - } - updateTimestamp = true; + continue; + } + + final Skill skill = holder.getSkill(); + if (skill != null) + { + if (addedSkills.containsKey(holder.getSkill().getId())) + { + if (addedSkills.get(holder.getSkill().getId()).getLevel() < holder.getSkill().getLevel()) + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + } + else + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + + if (skill.isActive() && !player.hasSkillReuse(skill.getReuseHashCode())) + { + final int equipDelay = item.getEquipReuseDelay(); + if (equipDelay > 0) + { + player.addTimeStamp(skill, equipDelay); + player.disableSkill(skill, equipDelay); + } + updateTimestamp = true; + } + update = true; } - update = true; } } } @@ -441,6 +485,11 @@ public abstract class Inventory extends ItemContainer // Must check all equipped items for enchant conditions. for (ItemInstance equipped : inventory.getPaperdollItems()) { + if (!equipped.getItem().hasSkills()) + { + continue; + } + final List otherEnchantSkills = equipped.getItem().getSkills(ItemSkillType.ON_ENCHANT); final List otherBlessingSkills = equipped.getItem().getSkills(ItemSkillType.ON_BLESSING); if ((otherEnchantSkills == null) && (otherBlessingSkills == null)) @@ -448,23 +497,6 @@ public abstract class Inventory extends ItemContainer continue; } - if (onBlessingSkills != null) - { - for (ItemSkillHolder holder : otherBlessingSkills) - { - // Add skills bestowed from +4 armor - if (equipped.isBlessed()) - { - final Skill skill = holder.getSkill(); - // Check passive skill conditions. - if (skill.isPassive() && !skill.checkConditions(SkillConditionScope.PASSIVE, player, player)) - { - player.removeSkill(holder.getSkill(), false, holder.getSkill().isPassive()); - update = true; - } - } - } - } if (otherEnchantSkills != null) { for (ItemSkillHolder holder : otherEnchantSkills) @@ -476,12 +508,47 @@ public abstract class Inventory extends ItemContainer // Check passive skill conditions. if (skill.isPassive() && !skill.checkConditions(SkillConditionScope.PASSIVE, player, player)) { - player.removeSkill(holder.getSkill(), false, holder.getSkill().isPassive()); + if (removedSkills.containsKey(holder.getSkill().getId())) + { + if (removedSkills.get(holder.getSkill().getId()).getLevel() < holder.getSkill().getLevel()) + { + removedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + } + else + { + removedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } update = true; } } } } + + if ((otherBlessingSkills != null) && equipped.isBlessed()) + { + for (ItemSkillHolder holder : otherBlessingSkills) + { + // Add skills bestowed from +4 armor + final Skill skill = holder.getSkill(); + // Check passive skill conditions. + if (skill.isPassive() && !skill.checkConditions(SkillConditionScope.PASSIVE, player, player)) + { + if (removedSkills.containsKey(holder.getSkill().getId())) + { + if (removedSkills.get(holder.getSkill().getId()).getLevel() < holder.getSkill().getLevel()) + { + removedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + } + else + { + removedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + update = true; + } + } + } } // Must check for toggle and isRemovedOnUnequipWeapon skill item conditions. @@ -503,8 +570,19 @@ public abstract class Inventory extends ItemContainer if (update) { + for (Skill skill : removedSkills.values()) + { + player.removeSkill(skill, false, skill.isPassive()); + } + + for (Skill skill : addedSkills.values()) + { + player.addSkill(skill, false); + } + player.sendSkillList(); } + if (updateTimestamp) { player.sendPacket(new SkillCoolTime(player)); @@ -525,7 +603,7 @@ public abstract class Inventory extends ItemContainer } final PlayerInstance player = (PlayerInstance) inventory.getOwner(); - boolean update = false; + final Map addedSkills = new HashMap<>(1); boolean updateTimestamp = false; // Apply augmentation bonuses on equip @@ -537,113 +615,18 @@ public abstract class Inventory extends ItemContainer // Recalculate all stats player.getStat().recalculateStats(true); - final List onEnchantSkills = item.getItem().getSkills(ItemSkillType.ON_ENCHANT); - final List onBlessingSkills = item.getItem().getSkills(ItemSkillType.ON_BLESSING); - if (onEnchantSkills != null) - { - for (ItemSkillHolder holder : onEnchantSkills) - { - if (player.getSkillLevel(holder.getSkillId()) >= holder.getSkillLevel()) - { - continue; - } - - // Add skills bestowed from +4 armor - if (item.getEnchantLevel() >= holder.getValue()) - { - final Skill skill = holder.getSkill(); - // Check passive skill conditions. - if (skill.isPassive() && !skill.checkConditions(SkillConditionScope.PASSIVE, player, player)) - { - continue; - } - player.addSkill(skill, false); - update = true; - } - } - } - if (onBlessingSkills != null) - { - for (ItemSkillHolder holder : onBlessingSkills) - { - if (player.getSkillLevel(holder.getSkillId()) >= holder.getSkillLevel()) - { - continue; - } - - // Add skills bestowed from +4 armor - if (item.isBlessed()) - { - final Skill skill = holder.getSkill(); - // Check passive skill conditions. - if (skill.isPassive() && !skill.checkConditions(SkillConditionScope.PASSIVE, player, player)) - { - continue; - } - player.addSkill(skill, false); - update = true; - } - } - } - // Apply enchant stats item.applyEnchantStats(); // Apply SA skill item.applySpecialAbilities(); - final List normalSkills = item.getItem().getSkills(ItemSkillType.NORMAL); - if (normalSkills != null) + if (item.getItem().hasSkills()) { - for (ItemSkillHolder holder : normalSkills) + final List onEnchantSkills = item.getItem().getSkills(ItemSkillType.ON_ENCHANT); + if (onEnchantSkills != null) { - if (player.getSkillLevel(holder.getSkillId()) >= holder.getSkillLevel()) - { - continue; - } - - final Skill skill = holder.getSkill(); - if (skill != null) - { - if (skill.isPassive() && !skill.checkConditions(SkillConditionScope.PASSIVE, player, player)) - { - continue; - } - - player.addSkill(skill, false); - if (skill.isActive() && !player.hasSkillReuse(skill.getReuseHashCode())) - { - final int equipDelay = item.getEquipReuseDelay(); - if (equipDelay > 0) - { - player.addTimeStamp(skill, equipDelay); - player.disableSkill(skill, equipDelay); - } - updateTimestamp = true; - } - update = true; - } - else - { - LOGGER.warning("Inventory.ItemSkillsListener.Weapon: Incorrect skill: " + holder); - } - } - } - - // Must check all equipped items for enchant conditions. - for (ItemInstance equipped : inventory.getPaperdollItems()) - { - final List otherEnchantSkills = equipped.getItem().getSkills(ItemSkillType.ON_ENCHANT); - final List otherBlessingSkills = equipped.getItem().getSkills(ItemSkillType.ON_BLESSING); - - if ((otherEnchantSkills == null) && (otherBlessingSkills == null)) - { - continue; - } - - if (otherBlessingSkills != null) - { - for (ItemSkillHolder holder : otherBlessingSkills) + for (ItemSkillHolder holder : onEnchantSkills) { if (player.getSkillLevel(holder.getSkillId()) >= holder.getSkillLevel()) { @@ -651,7 +634,7 @@ public abstract class Inventory extends ItemContainer } // Add skills bestowed from +4 armor - if (equipped.isBlessed()) + if (item.getEnchantLevel() >= holder.getValue()) { final Skill skill = holder.getSkill(); // Check passive skill conditions. @@ -659,12 +642,117 @@ public abstract class Inventory extends ItemContainer { continue; } - player.addSkill(skill, false); - update = true; + + if (addedSkills.containsKey(holder.getSkill().getId())) + { + if (addedSkills.get(holder.getSkill().getId()).getLevel() < holder.getSkill().getLevel()) + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + } + else + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } } } } + if (item.isBlessed()) + { + final List onBlessingSkills = item.getItem().getSkills(ItemSkillType.ON_BLESSING); + if (onBlessingSkills != null) + { + for (ItemSkillHolder holder : onBlessingSkills) + { + if (player.getSkillLevel(holder.getSkillId()) >= holder.getSkillLevel()) + { + continue; + } + + // Add skills bestowed from +4 armor + final Skill skill = holder.getSkill(); + // Check passive skill conditions. + if (skill.isPassive() && !skill.checkConditions(SkillConditionScope.PASSIVE, player, player)) + { + continue; + } + + if (addedSkills.containsKey(holder.getSkill().getId())) + { + if (addedSkills.get(holder.getSkill().getId()).getLevel() < holder.getSkill().getLevel()) + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + } + else + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + } + } + } + + final List normalSkills = item.getItem().getSkills(ItemSkillType.NORMAL); + if (normalSkills != null) + { + for (ItemSkillHolder holder : normalSkills) + { + if (player.getSkillLevel(holder.getSkillId()) >= holder.getSkillLevel()) + { + continue; + } + + final Skill skill = holder.getSkill(); + if (skill != null) + { + if (skill.isPassive() && !skill.checkConditions(SkillConditionScope.PASSIVE, player, player)) + { + continue; + } + + if (addedSkills.containsKey(holder.getSkill().getId())) + { + if (addedSkills.get(holder.getSkill().getId()).getLevel() < holder.getSkill().getLevel()) + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + } + else + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + + if (skill.isActive() && !player.hasSkillReuse(skill.getReuseHashCode())) + { + final int equipDelay = item.getEquipReuseDelay(); + if (equipDelay > 0) + { + player.addTimeStamp(skill, equipDelay); + player.disableSkill(skill, equipDelay); + } + updateTimestamp = true; + } + } + } + } + } + + // Must check all equipped items for enchant conditions. + for (ItemInstance equipped : inventory.getPaperdollItems()) + { + if (!equipped.getItem().hasSkills()) + { + continue; + } + + final List otherEnchantSkills = equipped.getItem().getSkills(ItemSkillType.ON_ENCHANT); + final List otherBlessingSkills = equipped.getItem().getSkills(ItemSkillType.ON_BLESSING); + if ((otherEnchantSkills == null) && (otherBlessingSkills == null)) + { + continue; + } + if (otherEnchantSkills != null) { for (ItemSkillHolder holder : otherEnchantSkills) @@ -683,8 +771,52 @@ public abstract class Inventory extends ItemContainer { continue; } - player.addSkill(skill, false); - update = true; + + if (addedSkills.containsKey(holder.getSkill().getId())) + { + if (addedSkills.get(holder.getSkill().getId()).getLevel() < holder.getSkill().getLevel()) + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + } + else + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + } + } + } + + if (otherBlessingSkills != null) + { + for (ItemSkillHolder holder : otherBlessingSkills) + { + if (player.getSkillLevel(holder.getSkillId()) >= holder.getSkillLevel()) + { + continue; + } + + // Add skills bestowed from +4 armor + if (equipped.isBlessed()) + { + final Skill skill = holder.getSkill(); + // Check passive skill conditions. + if (skill.isPassive() && !skill.checkConditions(SkillConditionScope.PASSIVE, player, player)) + { + continue; + } + + if (addedSkills.containsKey(holder.getSkill().getId())) + { + if (addedSkills.get(holder.getSkill().getId()).getLevel() < holder.getSkill().getLevel()) + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } + } + else + { + addedSkills.put(holder.getSkill().getId(), holder.getSkill()); + } } } } @@ -696,10 +828,16 @@ public abstract class Inventory extends ItemContainer item.getItem().forEachSkill(ItemSkillType.ON_EQUIP, holder -> holder.getSkill().activateSkill(player, player)); } - if (update) + if (!addedSkills.isEmpty()) { + for (Skill skill : addedSkills.values()) + { + player.addSkill(skill, false); + } + player.sendSkillList(); } + if (updateTimestamp) { player.sendPacket(new SkillCoolTime(player)); diff --git a/L2J_Mobius_Essence_5.0_Sylph/java/org/l2jmobius/gameserver/model/items/Item.java b/L2J_Mobius_Essence_5.0_Sylph/java/org/l2jmobius/gameserver/model/items/Item.java index c86d0a5a41..10cd6a106a 100644 --- a/L2J_Mobius_Essence_5.0_Sylph/java/org/l2jmobius/gameserver/model/items/Item.java +++ b/L2J_Mobius_Essence_5.0_Sylph/java/org/l2jmobius/gameserver/model/items/Item.java @@ -753,6 +753,11 @@ public abstract class Item extends ListenersContainer implements IIdentifiable return _preConditions; } + public boolean hasSkills() + { + return _skills != null; + } + /** * Method to retrieve skills linked to this item armor and weapon: passive skills etcitem: skills used on item use <-- ??? * @return Skills linked to this item as SkillHolder[]