From ebc4a789e6bbbb1b523b47e1c0516e0568e20027 Mon Sep 17 00:00:00 2001 From: MobiusDev <8391001+MobiusDevelopment@users.noreply.github.com> Date: Tue, 26 Sep 2017 15:41:55 +0000 Subject: [PATCH] Effect list broadcast issue fix. Contributed by Liamxroy. --- .../handlers/effecthandlers/DispelBySlot.java | 2 +- .../effecthandlers/DispelBySlotMyself.java | 2 +- .../DispelBySlotProbability.java | 2 +- .../effecthandlers/StealAbnormal.java | 2 +- .../scripts/instances/Kamaloka/Kamaloka.java | 2 +- .../gameserver/model/CharEffectList.java | 167 ++++++++++-------- .../gameserver/model/actor/L2Character.java | 6 +- .../gameserver/model/actor/L2Npc.java | 12 +- .../model/actor/instance/L2PcInstance.java | 6 +- .../model/actor/status/CharStatus.java | 2 +- .../model/instancezone/InstanceTemplate.java | 2 +- .../gameserver/model/options/Options.java | 2 +- .../handlers/effecthandlers/DispelBySlot.java | 2 +- .../effecthandlers/DispelBySlotMyself.java | 2 +- .../DispelBySlotProbability.java | 2 +- .../effecthandlers/StealAbnormal.java | 2 +- .../scripts/instances/Kamaloka/Kamaloka.java | 2 +- .../gameserver/model/CharEffectList.java | 167 ++++++++++-------- .../gameserver/model/actor/L2Character.java | 6 +- .../gameserver/model/actor/L2Npc.java | 12 +- .../model/actor/instance/L2PcInstance.java | 6 +- .../model/actor/status/CharStatus.java | 2 +- .../model/instancezone/InstanceTemplate.java | 2 +- .../gameserver/model/options/Options.java | 2 +- .../handlers/effecthandlers/DispelBySlot.java | 2 +- .../effecthandlers/DispelBySlotMyself.java | 2 +- .../DispelBySlotProbability.java | 2 +- .../effecthandlers/StealAbnormal.java | 2 +- .../scripts/instances/Kamaloka/Kamaloka.java | 2 +- .../gameserver/model/CharEffectList.java | 167 ++++++++++-------- .../gameserver/model/actor/L2Character.java | 6 +- .../gameserver/model/actor/L2Npc.java | 12 +- .../model/actor/instance/L2PcInstance.java | 6 +- .../model/actor/status/CharStatus.java | 2 +- .../model/instancezone/InstanceTemplate.java | 2 +- .../gameserver/model/options/Options.java | 2 +- .../handlers/effecthandlers/DispelBySlot.java | 2 +- .../effecthandlers/DispelBySlotMyself.java | 2 +- .../DispelBySlotProbability.java | 2 +- .../effecthandlers/StealAbnormal.java | 2 +- .../gameserver/model/CharEffectList.java | 167 ++++++++++-------- .../gameserver/model/actor/L2Character.java | 6 +- .../gameserver/model/actor/L2Npc.java | 12 +- .../model/actor/instance/L2PcInstance.java | 6 +- .../model/actor/status/CharStatus.java | 2 +- .../model/instancezone/InstanceTemplate.java | 2 +- .../gameserver/model/options/Options.java | 2 +- 47 files changed, 443 insertions(+), 383 deletions(-) diff --git a/L2J_Mobius_1.0_Ertheia/dist/game/data/scripts/handlers/effecthandlers/DispelBySlot.java b/L2J_Mobius_1.0_Ertheia/dist/game/data/scripts/handlers/effecthandlers/DispelBySlot.java index 034ed3f77a..a70de6564a 100644 --- a/L2J_Mobius_1.0_Ertheia/dist/game/data/scripts/handlers/effecthandlers/DispelBySlot.java +++ b/L2J_Mobius_1.0_Ertheia/dist/game/data/scripts/handlers/effecthandlers/DispelBySlot.java @@ -95,7 +95,7 @@ public final class DispelBySlot extends AbstractEffect final Short abnormalLevel = _dispelAbnormals.get(info.getSkill().getAbnormalType()); return (abnormalLevel != null) && ((abnormalLevel < 0) || (abnormalLevel >= info.getSkill().getAbnormalLvl())); - }, true); + }, true, true); } } } diff --git a/L2J_Mobius_1.0_Ertheia/dist/game/data/scripts/handlers/effecthandlers/DispelBySlotMyself.java b/L2J_Mobius_1.0_Ertheia/dist/game/data/scripts/handlers/effecthandlers/DispelBySlotMyself.java index 5513ebafe3..2c3234faf1 100644 --- a/L2J_Mobius_1.0_Ertheia/dist/game/data/scripts/handlers/effecthandlers/DispelBySlotMyself.java +++ b/L2J_Mobius_1.0_Ertheia/dist/game/data/scripts/handlers/effecthandlers/DispelBySlotMyself.java @@ -74,6 +74,6 @@ public final class DispelBySlotMyself extends AbstractEffect } // The effectlist should already check if it has buff with this abnormal type or not. - effected.getEffectList().stopEffects(info -> !info.getSkill().isIrreplacableBuff() && _dispelAbnormals.contains(info.getSkill().getAbnormalType()), true); + effected.getEffectList().stopEffects(info -> !info.getSkill().isIrreplacableBuff() && _dispelAbnormals.contains(info.getSkill().getAbnormalType()), true, true); } } diff --git a/L2J_Mobius_1.0_Ertheia/dist/game/data/scripts/handlers/effecthandlers/DispelBySlotProbability.java b/L2J_Mobius_1.0_Ertheia/dist/game/data/scripts/handlers/effecthandlers/DispelBySlotProbability.java index 9078f1553f..834c09acb7 100644 --- a/L2J_Mobius_1.0_Ertheia/dist/game/data/scripts/handlers/effecthandlers/DispelBySlotProbability.java +++ b/L2J_Mobius_1.0_Ertheia/dist/game/data/scripts/handlers/effecthandlers/DispelBySlotProbability.java @@ -98,6 +98,6 @@ public final class DispelBySlotProbability extends AbstractEffect final Short abnormalLevel = (Rnd.get(100) < _rate) ? _dispelAbnormals.get(info.getSkill().getAbnormalType()) : null; return (abnormalLevel != null) && ((abnormalLevel < 0) || (abnormalLevel >= info.getSkill().getAbnormalLvl())); - }, true); + }, true, true); } } diff --git a/L2J_Mobius_1.0_Ertheia/dist/game/data/scripts/handlers/effecthandlers/StealAbnormal.java b/L2J_Mobius_1.0_Ertheia/dist/game/data/scripts/handlers/effecthandlers/StealAbnormal.java index c711533bfe..580be62378 100644 --- a/L2J_Mobius_1.0_Ertheia/dist/game/data/scripts/handlers/effecthandlers/StealAbnormal.java +++ b/L2J_Mobius_1.0_Ertheia/dist/game/data/scripts/handlers/effecthandlers/StealAbnormal.java @@ -76,7 +76,7 @@ public final class StealAbnormal extends AbstractEffect stolen.setAbnormalTime(infoToSteal.getTime()); // Copy the remaining time. // To include all the effects, it's required to go through the template rather the buff info. infoToSteal.getSkill().applyEffectScope(EffectScope.GENERAL, stolen, true, true); - effected.getEffectList().remove(infoToSteal, true, true); + effected.getEffectList().remove(infoToSteal, true, true, true); effector.getEffectList().add(stolen); } } diff --git a/L2J_Mobius_1.0_Ertheia/dist/game/data/scripts/instances/Kamaloka/Kamaloka.java b/L2J_Mobius_1.0_Ertheia/dist/game/data/scripts/instances/Kamaloka/Kamaloka.java index 2a8ce3803f..cfbe5cc68d 100644 --- a/L2J_Mobius_1.0_Ertheia/dist/game/data/scripts/instances/Kamaloka/Kamaloka.java +++ b/L2J_Mobius_1.0_Ertheia/dist/game/data/scripts/instances/Kamaloka/Kamaloka.java @@ -491,7 +491,7 @@ public final class Kamaloka extends AbstractInstance private static final void removeBuffs(L2Character ch) { // Stop all buffs. - ch.getEffectList().stopEffects(info -> (info != null) && !info.getSkill().isStayAfterDeath() && (Arrays.binarySearch(BUFFS_WHITELIST, info.getSkill().getId()) < 0), true); + ch.getEffectList().stopEffects(info -> (info != null) && !info.getSkill().isStayAfterDeath() && (Arrays.binarySearch(BUFFS_WHITELIST, info.getSkill().getId()) < 0), true, true); } /** diff --git a/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/model/CharEffectList.java b/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/model/CharEffectList.java index de027352eb..f8e1cf6833 100644 --- a/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/model/CharEffectList.java +++ b/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/model/CharEffectList.java @@ -332,10 +332,11 @@ public final class CharEffectList /** * Exits all effects in this effect list.
* Stops all the effects, clear the effect lists and updates the effect flags and icons. + * @param broadcast {@code true} to broadcast update packets, {@code false} otherwise. */ - public void stopAllEffects() + public void stopAllEffects(boolean broadcast) { - stopEffects(b -> !b.getSkill().isNecessaryToggle() && !b.getSkill().isIrreplacableBuff(), true); + stopEffects(b -> !b.getSkill().isNecessaryToggle() && !b.getSkill().isIrreplacableBuff(), true, broadcast); } /** @@ -343,7 +344,7 @@ public final class CharEffectList */ public void stopAllEffectsExceptThoseThatLastThroughDeath() { - stopEffects(info -> !info.getSkill().isStayAfterDeath(), true); + stopEffects(info -> !info.getSkill().isStayAfterDeath(), true, true); } /** @@ -354,7 +355,7 @@ public final class CharEffectList if (getToggleCount() > 0) { // Ignore necessary toggles. - stopEffects(b -> b.getSkill().isToggle() && !b.getSkill().isNecessaryToggle() && !b.getSkill().isIrreplacableBuff(), true); + stopEffects(b -> b.getSkill().isToggle() && !b.getSkill().isNecessaryToggle() && !b.getSkill().isIrreplacableBuff(), true, true); } } @@ -362,35 +363,43 @@ public final class CharEffectList { if (getToggleCount() > 0) { - stopEffects(b -> b.getSkill().isToggle() && (b.getSkill().getToggleGroupId() == toggleGroup), true); + stopEffects(b -> b.getSkill().isToggle() && (b.getSkill().getToggleGroupId() == toggleGroup), true, true); } } /** * Stops all active dances/songs skills. * @param update set to true to update the effect flags and icons + * @param broadcast {@code true} to broadcast update packets if updating, {@code false} otherwise. */ - public void stopAllPassives(boolean update) + public void stopAllPassives(boolean update, boolean broadcast) { if (_passives != null) { _passives.forEach(this::remove); // Update stats, effect flags and icons. - updateEffectList(update); + if (update) + { + updateEffectList(broadcast); + } } } /** * Stops all active dances/songs skills. * @param update set to true to update the effect flags and icons + * @param broadcast {@code true} to broadcast update packets if updating, {@code false} otherwise. */ - public void stopAllOptions(boolean update) + public void stopAllOptions(boolean update, boolean broadcast) { if (_options != null) { _options.forEach(this::remove); // Update stats, effect flags and icons. - updateEffectList(update); + if (update) + { + updateEffectList(broadcast); + } } } @@ -402,7 +411,7 @@ public final class CharEffectList { if (isAffected(effectFlag)) { - stopEffects(info -> info.getEffects().stream().anyMatch(effect -> (effect != null) && ((effect.getEffectFlags() & effectFlag.getMask()) != 0)), true); + stopEffects(info -> info.getEffects().stream().anyMatch(effect -> (effect != null) && ((effect.getEffectFlags() & effectFlag.getMask()) != 0)), true, true); } } @@ -421,7 +430,7 @@ public final class CharEffectList final BuffInfo info = getBuffInfoBySkillId(skillId); if (info != null) { - remove(info, removed, true); + remove(info, removed, true, true); } } @@ -454,7 +463,7 @@ public final class CharEffectList { if (hasAbnormalType(type)) { - stopEffects(i -> i.isAbnormalType(type), true); + stopEffects(i -> i.isAbnormalType(type), true, true); return true; } @@ -470,7 +479,7 @@ public final class CharEffectList { if (hasAbnormalType(types)) { - stopEffects(i -> types.contains(i.getSkill().getAbnormalType()), true); + stopEffects(i -> types.contains(i.getSkill().getAbnormalType()), true, true); return true; } @@ -481,15 +490,19 @@ public final class CharEffectList * Exits all effects matched by a specific filter.
* @param filter any filter to apply when selecting which {@code BuffInfo}s to be removed. * @param update update effect flags and icons after the operation finishes. + * @param broadcast {@code true} to broadcast update packets if updating, {@code false} otherwise. */ - public void stopEffects(Predicate filter, boolean update) + public void stopEffects(Predicate filter, boolean update, boolean broadcast) { if (_actives != null) { _actives.stream().filter(filter).forEach(this::remove); // Update stats, effect flags and icons. - updateEffectList(update); + if (update) + { + updateEffectList(broadcast); + } } } @@ -501,7 +514,7 @@ public final class CharEffectList { if (_hasBuffsRemovedOnAnyAction.intValue() > 0) { - stopEffects(info -> info.getSkill().isRemovedOnAnyActionExceptMove(), true); + stopEffects(info -> info.getSkill().isRemovedOnAnyActionExceptMove(), true, true); } } @@ -509,7 +522,7 @@ public final class CharEffectList { if (_hasBuffsRemovedOnDamage.intValue() > 0) { - stopEffects(info -> info.getSkill().isRemovedOnDamage(), true); + stopEffects(info -> info.getSkill().isRemovedOnDamage(), true, true); } } @@ -626,7 +639,7 @@ public final class CharEffectList */ private void remove(BuffInfo info) { - remove(info, true, false); + remove(info, true, false, false); } /** @@ -634,8 +647,9 @@ public final class CharEffectList * @param info the effects to remove * @param removed {@code true} if the effect is removed, {@code false} otherwise * @param update {@code true} if effect flags and icons should be updated after this removal, {@code false} otherwise. + * @param broadcast {@code true} to broadcast update packets if updating, {@code false} otherwise. */ - public void remove(BuffInfo info, boolean removed, boolean update) + public void remove(BuffInfo info, boolean removed, boolean update, boolean broadcast) { if (info == null) { @@ -659,7 +673,10 @@ public final class CharEffectList } // Update stats, effect flags and icons. - updateEffectList(update); + if (update) + { + updateEffectList(broadcast); + } } /** @@ -1070,74 +1087,74 @@ public final class CharEffectList /** * Wrapper to update abnormal icons and effect flags. - * @param update if {@code true} performs an update + * @param broadcast {@code true} sends update packets to observing players, {@code false} doesn't send any packets. */ - private void updateEffectList(boolean update) + private void updateEffectList(boolean broadcast) { - if (update) + // Create new empty flags. + long flags = 0; + final Set abnormalTypeFlags = EnumSet.noneOf(AbnormalType.class); + final Set abnormalVisualEffectFlags = EnumSet.noneOf(AbnormalVisualEffect.class); + final Set unhideBuffs = new HashSet<>(); + + // Recalculate new flags + if (_actives != null) { - // Create new empty flags. - long flags = 0; - final Set abnormalTypeFlags = EnumSet.noneOf(AbnormalType.class); - final Set abnormalVisualEffectFlags = EnumSet.noneOf(AbnormalVisualEffect.class); - final Set unhideBuffs = new HashSet<>(); - - // Recalculate new flags - if (_actives != null) + for (BuffInfo info : _actives) { - for (BuffInfo info : _actives) + if (info != null) { - if (info != null) + final Skill skill = info.getSkill(); + + // Handle hidden buffs. Check if there was such abnormal before so we can continue. + if ((getHiddenBuffsCount() > 0) && _stackedEffects.contains(skill.getAbnormalType())) { - final Skill skill = info.getSkill(); - - // Handle hidden buffs. Check if there was such abnormal before so we can continue. - if ((getHiddenBuffsCount() > 0) && _stackedEffects.contains(skill.getAbnormalType())) + // If incoming buff isnt hidden, remove any hidden buffs with its abnormal type. + if (info.isInUse()) { - // If incoming buff isnt hidden, remove any hidden buffs with its abnormal type. - if (info.isInUse()) - { - unhideBuffs.removeIf(b -> b.isAbnormalType(skill.getAbnormalType())); - } - // If this incoming buff is hidden and its first of its abnormal, or it removes any previous hidden buff with the same or lower abnormal level and add this instead. - else if (!abnormalTypeFlags.contains(skill.getAbnormalType()) || unhideBuffs.removeIf(b -> (b.isAbnormalType(skill.getAbnormalType())) && (b.getSkill().getAbnormalLvl() <= skill.getAbnormalLvl()))) - { - unhideBuffs.add(info); - } + unhideBuffs.removeIf(b -> b.isAbnormalType(skill.getAbnormalType())); } - - // Add the EffectType flag. - for (AbstractEffect e : info.getEffects()) + // If this incoming buff is hidden and its first of its abnormal, or it removes any previous hidden buff with the same or lower abnormal level and add this instead. + else if (!abnormalTypeFlags.contains(skill.getAbnormalType()) || unhideBuffs.removeIf(b -> (b.isAbnormalType(skill.getAbnormalType())) && (b.getSkill().getAbnormalLvl() <= skill.getAbnormalLvl()))) { - flags |= e.getEffectFlags(); - } - - // Add the AbnormalType flag. - abnormalTypeFlags.add(skill.getAbnormalType()); - - // Add AbnormalVisualEffect flag. - if (skill.hasAbnormalVisualEffects()) - { - abnormalVisualEffectFlags.addAll(skill.getAbnormalVisualEffects()); + unhideBuffs.add(info); } } + + // Add the EffectType flag. + for (AbstractEffect e : info.getEffects()) + { + flags |= e.getEffectFlags(); + } + + // Add the AbnormalType flag. + abnormalTypeFlags.add(skill.getAbnormalType()); + + // Add AbnormalVisualEffect flag. + if (skill.hasAbnormalVisualEffects()) + { + abnormalVisualEffectFlags.addAll(skill.getAbnormalVisualEffects()); + } } } - - // Replace the old flags with the new flags. - _effectFlags = flags; - _stackedEffects = abnormalTypeFlags; - - // Unhide the selected buffs. - unhideBuffs.forEach(b -> - { - b.setInUse(true); - _hiddenBuffs.decrementAndGet(); - }); - - // Recalculate all stats - _owner.getStat().recalculateStats(true); - + } + + // Replace the old flags with the new flags. + _effectFlags = flags; + _stackedEffects = abnormalTypeFlags; + + // Unhide the selected buffs. + unhideBuffs.forEach(b -> + { + b.setInUse(true); + _hiddenBuffs.decrementAndGet(); + }); + + // Recalculate all stats + _owner.getStat().recalculateStats(broadcast); + + if (broadcast) + { // Check if there is change in AbnormalVisualEffect if ((abnormalVisualEffectFlags.size() != _abnormalVisualEffects.size()) || !abnormalVisualEffectFlags.containsAll(_abnormalVisualEffects)) { diff --git a/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/model/actor/L2Character.java b/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/model/actor/L2Character.java index 7ba91ec156..df8f5edede 100644 --- a/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/model/actor/L2Character.java +++ b/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/model/actor/L2Character.java @@ -1946,8 +1946,8 @@ public abstract class L2Character extends L2Object implements ISkillsHolder, IDe getSummoner().removeSummonedNpc(getObjectId()); } - // Remove all effects - _effectList.stopAllEffects(); + // Remove all effects, do not broadcast changes. + _effectList.stopAllEffects(false); // Cancel all timers related to this Creature TimersManager.getInstance().cancelTimers(getObjectId()); @@ -2550,7 +2550,7 @@ public abstract class L2Character extends L2Object implements ISkillsHolder, IDe */ public void stopAllEffects() { - _effectList.stopAllEffects(); + _effectList.stopAllEffects(true); } /** diff --git a/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/model/actor/L2Npc.java b/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/model/actor/L2Npc.java index 744af6f9da..44439e2b7e 100644 --- a/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/model/actor/L2Npc.java +++ b/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/model/actor/L2Npc.java @@ -998,8 +998,8 @@ public class L2Npc extends L2Character */ public void onRespawn() { - // Stop all effects - stopAllEffects(); + // Stop all effects and recalculate stats without broadcasting. + getEffectList().stopAllEffects(false); // Make it alive setIsDead(false); @@ -1007,11 +1007,9 @@ public class L2Npc extends L2Character // Reset decay info setDecayed(false); - // Recalculate npcs stats - getStat().recalculateStats(true); - - // Set the HP and MP of the L2NpcInstance to the max - setCurrentHpMp(getMaxHp(), getMaxMp()); + // Fully heal npc and don't broadcast packet. + setCurrentHp(getMaxHp(), false); + setCurrentMp(getMaxMp(), false); // Clear script variables if (hasVariables()) diff --git a/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/model/actor/instance/L2PcInstance.java b/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/model/actor/instance/L2PcInstance.java index 54c79d5093..b8a7996067 100644 --- a/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/model/actor/instance/L2PcInstance.java +++ b/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/model/actor/instance/L2PcInstance.java @@ -10623,9 +10623,9 @@ public final class L2PcInstance extends L2Playable cleanup(); storeMe(); - // Stop all passives and augment options - getEffectList().stopAllPassives(false); - getEffectList().stopAllOptions(false); + // Stop all passives and augment options without broadcasting changes. + getEffectList().stopAllPassives(false, false); + getEffectList().stopAllOptions(false, false); return super.deleteMe(); } diff --git a/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/model/actor/status/CharStatus.java b/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/model/actor/status/CharStatus.java index a30d9f419d..9494559d7d 100644 --- a/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/model/actor/status/CharStatus.java +++ b/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/model/actor/status/CharStatus.java @@ -331,7 +331,7 @@ public class CharStatus { if (_previousHpPercent.compareAndSet(lastHpPercent, currentHpPercent)) { - _activeChar.getStat().recalculateStats(true); + _activeChar.getStat().recalculateStats(broadcastPacket); } } diff --git a/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/model/instancezone/InstanceTemplate.java b/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/model/instancezone/InstanceTemplate.java index cfa158dfff..f4fa7592ad 100644 --- a/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/model/instancezone/InstanceTemplate.java +++ b/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/model/instancezone/InstanceTemplate.java @@ -509,7 +509,7 @@ public class InstanceTemplate extends ListenersContainer implements IIdentifiabl for (L2Playable playable : affected) { // Stop all buffs. - playable.getEffectList().stopEffects(info -> !info.getSkill().isIrreplacableBuff() && info.getSkill().getBuffType().isBuff() && hasRemoveBuffException(info.getSkill()), true); + playable.getEffectList().stopEffects(info -> !info.getSkill().isIrreplacableBuff() && info.getSkill().getBuffType().isBuff() && hasRemoveBuffException(info.getSkill()), true, true); } } } diff --git a/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/model/options/Options.java b/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/model/options/Options.java index 04dd4379fb..2c24b77b7e 100644 --- a/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/model/options/Options.java +++ b/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/model/options/Options.java @@ -204,7 +204,7 @@ public class Options if (info.getOption() == this) { player.sendDebugMessage("Removing effects: " + info.getEffects()); - player.getEffectList().remove(info, false, true); + player.getEffectList().remove(info, false, true, true); } } } diff --git a/L2J_Mobius_2.5_Underground/dist/game/data/scripts/handlers/effecthandlers/DispelBySlot.java b/L2J_Mobius_2.5_Underground/dist/game/data/scripts/handlers/effecthandlers/DispelBySlot.java index 034ed3f77a..a70de6564a 100644 --- a/L2J_Mobius_2.5_Underground/dist/game/data/scripts/handlers/effecthandlers/DispelBySlot.java +++ b/L2J_Mobius_2.5_Underground/dist/game/data/scripts/handlers/effecthandlers/DispelBySlot.java @@ -95,7 +95,7 @@ public final class DispelBySlot extends AbstractEffect final Short abnormalLevel = _dispelAbnormals.get(info.getSkill().getAbnormalType()); return (abnormalLevel != null) && ((abnormalLevel < 0) || (abnormalLevel >= info.getSkill().getAbnormalLvl())); - }, true); + }, true, true); } } } diff --git a/L2J_Mobius_2.5_Underground/dist/game/data/scripts/handlers/effecthandlers/DispelBySlotMyself.java b/L2J_Mobius_2.5_Underground/dist/game/data/scripts/handlers/effecthandlers/DispelBySlotMyself.java index 5513ebafe3..2c3234faf1 100644 --- a/L2J_Mobius_2.5_Underground/dist/game/data/scripts/handlers/effecthandlers/DispelBySlotMyself.java +++ b/L2J_Mobius_2.5_Underground/dist/game/data/scripts/handlers/effecthandlers/DispelBySlotMyself.java @@ -74,6 +74,6 @@ public final class DispelBySlotMyself extends AbstractEffect } // The effectlist should already check if it has buff with this abnormal type or not. - effected.getEffectList().stopEffects(info -> !info.getSkill().isIrreplacableBuff() && _dispelAbnormals.contains(info.getSkill().getAbnormalType()), true); + effected.getEffectList().stopEffects(info -> !info.getSkill().isIrreplacableBuff() && _dispelAbnormals.contains(info.getSkill().getAbnormalType()), true, true); } } diff --git a/L2J_Mobius_2.5_Underground/dist/game/data/scripts/handlers/effecthandlers/DispelBySlotProbability.java b/L2J_Mobius_2.5_Underground/dist/game/data/scripts/handlers/effecthandlers/DispelBySlotProbability.java index 9078f1553f..834c09acb7 100644 --- a/L2J_Mobius_2.5_Underground/dist/game/data/scripts/handlers/effecthandlers/DispelBySlotProbability.java +++ b/L2J_Mobius_2.5_Underground/dist/game/data/scripts/handlers/effecthandlers/DispelBySlotProbability.java @@ -98,6 +98,6 @@ public final class DispelBySlotProbability extends AbstractEffect final Short abnormalLevel = (Rnd.get(100) < _rate) ? _dispelAbnormals.get(info.getSkill().getAbnormalType()) : null; return (abnormalLevel != null) && ((abnormalLevel < 0) || (abnormalLevel >= info.getSkill().getAbnormalLvl())); - }, true); + }, true, true); } } diff --git a/L2J_Mobius_2.5_Underground/dist/game/data/scripts/handlers/effecthandlers/StealAbnormal.java b/L2J_Mobius_2.5_Underground/dist/game/data/scripts/handlers/effecthandlers/StealAbnormal.java index c711533bfe..580be62378 100644 --- a/L2J_Mobius_2.5_Underground/dist/game/data/scripts/handlers/effecthandlers/StealAbnormal.java +++ b/L2J_Mobius_2.5_Underground/dist/game/data/scripts/handlers/effecthandlers/StealAbnormal.java @@ -76,7 +76,7 @@ public final class StealAbnormal extends AbstractEffect stolen.setAbnormalTime(infoToSteal.getTime()); // Copy the remaining time. // To include all the effects, it's required to go through the template rather the buff info. infoToSteal.getSkill().applyEffectScope(EffectScope.GENERAL, stolen, true, true); - effected.getEffectList().remove(infoToSteal, true, true); + effected.getEffectList().remove(infoToSteal, true, true, true); effector.getEffectList().add(stolen); } } diff --git a/L2J_Mobius_2.5_Underground/dist/game/data/scripts/instances/Kamaloka/Kamaloka.java b/L2J_Mobius_2.5_Underground/dist/game/data/scripts/instances/Kamaloka/Kamaloka.java index 2a8ce3803f..cfbe5cc68d 100644 --- a/L2J_Mobius_2.5_Underground/dist/game/data/scripts/instances/Kamaloka/Kamaloka.java +++ b/L2J_Mobius_2.5_Underground/dist/game/data/scripts/instances/Kamaloka/Kamaloka.java @@ -491,7 +491,7 @@ public final class Kamaloka extends AbstractInstance private static final void removeBuffs(L2Character ch) { // Stop all buffs. - ch.getEffectList().stopEffects(info -> (info != null) && !info.getSkill().isStayAfterDeath() && (Arrays.binarySearch(BUFFS_WHITELIST, info.getSkill().getId()) < 0), true); + ch.getEffectList().stopEffects(info -> (info != null) && !info.getSkill().isStayAfterDeath() && (Arrays.binarySearch(BUFFS_WHITELIST, info.getSkill().getId()) < 0), true, true); } /** diff --git a/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/model/CharEffectList.java b/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/model/CharEffectList.java index de027352eb..f8e1cf6833 100644 --- a/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/model/CharEffectList.java +++ b/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/model/CharEffectList.java @@ -332,10 +332,11 @@ public final class CharEffectList /** * Exits all effects in this effect list.
* Stops all the effects, clear the effect lists and updates the effect flags and icons. + * @param broadcast {@code true} to broadcast update packets, {@code false} otherwise. */ - public void stopAllEffects() + public void stopAllEffects(boolean broadcast) { - stopEffects(b -> !b.getSkill().isNecessaryToggle() && !b.getSkill().isIrreplacableBuff(), true); + stopEffects(b -> !b.getSkill().isNecessaryToggle() && !b.getSkill().isIrreplacableBuff(), true, broadcast); } /** @@ -343,7 +344,7 @@ public final class CharEffectList */ public void stopAllEffectsExceptThoseThatLastThroughDeath() { - stopEffects(info -> !info.getSkill().isStayAfterDeath(), true); + stopEffects(info -> !info.getSkill().isStayAfterDeath(), true, true); } /** @@ -354,7 +355,7 @@ public final class CharEffectList if (getToggleCount() > 0) { // Ignore necessary toggles. - stopEffects(b -> b.getSkill().isToggle() && !b.getSkill().isNecessaryToggle() && !b.getSkill().isIrreplacableBuff(), true); + stopEffects(b -> b.getSkill().isToggle() && !b.getSkill().isNecessaryToggle() && !b.getSkill().isIrreplacableBuff(), true, true); } } @@ -362,35 +363,43 @@ public final class CharEffectList { if (getToggleCount() > 0) { - stopEffects(b -> b.getSkill().isToggle() && (b.getSkill().getToggleGroupId() == toggleGroup), true); + stopEffects(b -> b.getSkill().isToggle() && (b.getSkill().getToggleGroupId() == toggleGroup), true, true); } } /** * Stops all active dances/songs skills. * @param update set to true to update the effect flags and icons + * @param broadcast {@code true} to broadcast update packets if updating, {@code false} otherwise. */ - public void stopAllPassives(boolean update) + public void stopAllPassives(boolean update, boolean broadcast) { if (_passives != null) { _passives.forEach(this::remove); // Update stats, effect flags and icons. - updateEffectList(update); + if (update) + { + updateEffectList(broadcast); + } } } /** * Stops all active dances/songs skills. * @param update set to true to update the effect flags and icons + * @param broadcast {@code true} to broadcast update packets if updating, {@code false} otherwise. */ - public void stopAllOptions(boolean update) + public void stopAllOptions(boolean update, boolean broadcast) { if (_options != null) { _options.forEach(this::remove); // Update stats, effect flags and icons. - updateEffectList(update); + if (update) + { + updateEffectList(broadcast); + } } } @@ -402,7 +411,7 @@ public final class CharEffectList { if (isAffected(effectFlag)) { - stopEffects(info -> info.getEffects().stream().anyMatch(effect -> (effect != null) && ((effect.getEffectFlags() & effectFlag.getMask()) != 0)), true); + stopEffects(info -> info.getEffects().stream().anyMatch(effect -> (effect != null) && ((effect.getEffectFlags() & effectFlag.getMask()) != 0)), true, true); } } @@ -421,7 +430,7 @@ public final class CharEffectList final BuffInfo info = getBuffInfoBySkillId(skillId); if (info != null) { - remove(info, removed, true); + remove(info, removed, true, true); } } @@ -454,7 +463,7 @@ public final class CharEffectList { if (hasAbnormalType(type)) { - stopEffects(i -> i.isAbnormalType(type), true); + stopEffects(i -> i.isAbnormalType(type), true, true); return true; } @@ -470,7 +479,7 @@ public final class CharEffectList { if (hasAbnormalType(types)) { - stopEffects(i -> types.contains(i.getSkill().getAbnormalType()), true); + stopEffects(i -> types.contains(i.getSkill().getAbnormalType()), true, true); return true; } @@ -481,15 +490,19 @@ public final class CharEffectList * Exits all effects matched by a specific filter.
* @param filter any filter to apply when selecting which {@code BuffInfo}s to be removed. * @param update update effect flags and icons after the operation finishes. + * @param broadcast {@code true} to broadcast update packets if updating, {@code false} otherwise. */ - public void stopEffects(Predicate filter, boolean update) + public void stopEffects(Predicate filter, boolean update, boolean broadcast) { if (_actives != null) { _actives.stream().filter(filter).forEach(this::remove); // Update stats, effect flags and icons. - updateEffectList(update); + if (update) + { + updateEffectList(broadcast); + } } } @@ -501,7 +514,7 @@ public final class CharEffectList { if (_hasBuffsRemovedOnAnyAction.intValue() > 0) { - stopEffects(info -> info.getSkill().isRemovedOnAnyActionExceptMove(), true); + stopEffects(info -> info.getSkill().isRemovedOnAnyActionExceptMove(), true, true); } } @@ -509,7 +522,7 @@ public final class CharEffectList { if (_hasBuffsRemovedOnDamage.intValue() > 0) { - stopEffects(info -> info.getSkill().isRemovedOnDamage(), true); + stopEffects(info -> info.getSkill().isRemovedOnDamage(), true, true); } } @@ -626,7 +639,7 @@ public final class CharEffectList */ private void remove(BuffInfo info) { - remove(info, true, false); + remove(info, true, false, false); } /** @@ -634,8 +647,9 @@ public final class CharEffectList * @param info the effects to remove * @param removed {@code true} if the effect is removed, {@code false} otherwise * @param update {@code true} if effect flags and icons should be updated after this removal, {@code false} otherwise. + * @param broadcast {@code true} to broadcast update packets if updating, {@code false} otherwise. */ - public void remove(BuffInfo info, boolean removed, boolean update) + public void remove(BuffInfo info, boolean removed, boolean update, boolean broadcast) { if (info == null) { @@ -659,7 +673,10 @@ public final class CharEffectList } // Update stats, effect flags and icons. - updateEffectList(update); + if (update) + { + updateEffectList(broadcast); + } } /** @@ -1070,74 +1087,74 @@ public final class CharEffectList /** * Wrapper to update abnormal icons and effect flags. - * @param update if {@code true} performs an update + * @param broadcast {@code true} sends update packets to observing players, {@code false} doesn't send any packets. */ - private void updateEffectList(boolean update) + private void updateEffectList(boolean broadcast) { - if (update) + // Create new empty flags. + long flags = 0; + final Set abnormalTypeFlags = EnumSet.noneOf(AbnormalType.class); + final Set abnormalVisualEffectFlags = EnumSet.noneOf(AbnormalVisualEffect.class); + final Set unhideBuffs = new HashSet<>(); + + // Recalculate new flags + if (_actives != null) { - // Create new empty flags. - long flags = 0; - final Set abnormalTypeFlags = EnumSet.noneOf(AbnormalType.class); - final Set abnormalVisualEffectFlags = EnumSet.noneOf(AbnormalVisualEffect.class); - final Set unhideBuffs = new HashSet<>(); - - // Recalculate new flags - if (_actives != null) + for (BuffInfo info : _actives) { - for (BuffInfo info : _actives) + if (info != null) { - if (info != null) + final Skill skill = info.getSkill(); + + // Handle hidden buffs. Check if there was such abnormal before so we can continue. + if ((getHiddenBuffsCount() > 0) && _stackedEffects.contains(skill.getAbnormalType())) { - final Skill skill = info.getSkill(); - - // Handle hidden buffs. Check if there was such abnormal before so we can continue. - if ((getHiddenBuffsCount() > 0) && _stackedEffects.contains(skill.getAbnormalType())) + // If incoming buff isnt hidden, remove any hidden buffs with its abnormal type. + if (info.isInUse()) { - // If incoming buff isnt hidden, remove any hidden buffs with its abnormal type. - if (info.isInUse()) - { - unhideBuffs.removeIf(b -> b.isAbnormalType(skill.getAbnormalType())); - } - // If this incoming buff is hidden and its first of its abnormal, or it removes any previous hidden buff with the same or lower abnormal level and add this instead. - else if (!abnormalTypeFlags.contains(skill.getAbnormalType()) || unhideBuffs.removeIf(b -> (b.isAbnormalType(skill.getAbnormalType())) && (b.getSkill().getAbnormalLvl() <= skill.getAbnormalLvl()))) - { - unhideBuffs.add(info); - } + unhideBuffs.removeIf(b -> b.isAbnormalType(skill.getAbnormalType())); } - - // Add the EffectType flag. - for (AbstractEffect e : info.getEffects()) + // If this incoming buff is hidden and its first of its abnormal, or it removes any previous hidden buff with the same or lower abnormal level and add this instead. + else if (!abnormalTypeFlags.contains(skill.getAbnormalType()) || unhideBuffs.removeIf(b -> (b.isAbnormalType(skill.getAbnormalType())) && (b.getSkill().getAbnormalLvl() <= skill.getAbnormalLvl()))) { - flags |= e.getEffectFlags(); - } - - // Add the AbnormalType flag. - abnormalTypeFlags.add(skill.getAbnormalType()); - - // Add AbnormalVisualEffect flag. - if (skill.hasAbnormalVisualEffects()) - { - abnormalVisualEffectFlags.addAll(skill.getAbnormalVisualEffects()); + unhideBuffs.add(info); } } + + // Add the EffectType flag. + for (AbstractEffect e : info.getEffects()) + { + flags |= e.getEffectFlags(); + } + + // Add the AbnormalType flag. + abnormalTypeFlags.add(skill.getAbnormalType()); + + // Add AbnormalVisualEffect flag. + if (skill.hasAbnormalVisualEffects()) + { + abnormalVisualEffectFlags.addAll(skill.getAbnormalVisualEffects()); + } } } - - // Replace the old flags with the new flags. - _effectFlags = flags; - _stackedEffects = abnormalTypeFlags; - - // Unhide the selected buffs. - unhideBuffs.forEach(b -> - { - b.setInUse(true); - _hiddenBuffs.decrementAndGet(); - }); - - // Recalculate all stats - _owner.getStat().recalculateStats(true); - + } + + // Replace the old flags with the new flags. + _effectFlags = flags; + _stackedEffects = abnormalTypeFlags; + + // Unhide the selected buffs. + unhideBuffs.forEach(b -> + { + b.setInUse(true); + _hiddenBuffs.decrementAndGet(); + }); + + // Recalculate all stats + _owner.getStat().recalculateStats(broadcast); + + if (broadcast) + { // Check if there is change in AbnormalVisualEffect if ((abnormalVisualEffectFlags.size() != _abnormalVisualEffects.size()) || !abnormalVisualEffectFlags.containsAll(_abnormalVisualEffects)) { diff --git a/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/model/actor/L2Character.java b/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/model/actor/L2Character.java index bf268507a8..e7f6e87a65 100644 --- a/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/model/actor/L2Character.java +++ b/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/model/actor/L2Character.java @@ -1950,8 +1950,8 @@ public abstract class L2Character extends L2Object implements ISkillsHolder, IDe getSummoner().removeSummonedNpc(getObjectId()); } - // Remove all effects - _effectList.stopAllEffects(); + // Remove all effects, do not broadcast changes. + _effectList.stopAllEffects(false); // Cancel all timers related to this Creature TimersManager.getInstance().cancelTimers(getObjectId()); @@ -2554,7 +2554,7 @@ public abstract class L2Character extends L2Object implements ISkillsHolder, IDe */ public void stopAllEffects() { - _effectList.stopAllEffects(); + _effectList.stopAllEffects(true); } /** diff --git a/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/model/actor/L2Npc.java b/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/model/actor/L2Npc.java index 96801d3313..aa4830fcbe 100644 --- a/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/model/actor/L2Npc.java +++ b/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/model/actor/L2Npc.java @@ -997,8 +997,8 @@ public class L2Npc extends L2Character */ public void onRespawn() { - // Stop all effects - stopAllEffects(); + // Stop all effects and recalculate stats without broadcasting. + getEffectList().stopAllEffects(false); // Make it alive setIsDead(false); @@ -1006,11 +1006,9 @@ public class L2Npc extends L2Character // Reset decay info setDecayed(false); - // Recalculate npcs stats - getStat().recalculateStats(true); - - // Set the HP and MP of the L2NpcInstance to the max - setCurrentHpMp(getMaxHp(), getMaxMp()); + // Fully heal npc and don't broadcast packet. + setCurrentHp(getMaxHp(), false); + setCurrentMp(getMaxMp(), false); // Clear script variables if (hasVariables()) diff --git a/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/model/actor/instance/L2PcInstance.java b/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/model/actor/instance/L2PcInstance.java index a523755493..970dd6f683 100644 --- a/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/model/actor/instance/L2PcInstance.java +++ b/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/model/actor/instance/L2PcInstance.java @@ -10623,9 +10623,9 @@ public final class L2PcInstance extends L2Playable cleanup(); storeMe(); - // Stop all passives and augment options - getEffectList().stopAllPassives(false); - getEffectList().stopAllOptions(false); + // Stop all passives and augment options without broadcasting changes. + getEffectList().stopAllPassives(false, false); + getEffectList().stopAllOptions(false, false); return super.deleteMe(); } diff --git a/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/model/actor/status/CharStatus.java b/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/model/actor/status/CharStatus.java index a30d9f419d..9494559d7d 100644 --- a/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/model/actor/status/CharStatus.java +++ b/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/model/actor/status/CharStatus.java @@ -331,7 +331,7 @@ public class CharStatus { if (_previousHpPercent.compareAndSet(lastHpPercent, currentHpPercent)) { - _activeChar.getStat().recalculateStats(true); + _activeChar.getStat().recalculateStats(broadcastPacket); } } diff --git a/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/model/instancezone/InstanceTemplate.java b/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/model/instancezone/InstanceTemplate.java index cfa158dfff..f4fa7592ad 100644 --- a/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/model/instancezone/InstanceTemplate.java +++ b/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/model/instancezone/InstanceTemplate.java @@ -509,7 +509,7 @@ public class InstanceTemplate extends ListenersContainer implements IIdentifiabl for (L2Playable playable : affected) { // Stop all buffs. - playable.getEffectList().stopEffects(info -> !info.getSkill().isIrreplacableBuff() && info.getSkill().getBuffType().isBuff() && hasRemoveBuffException(info.getSkill()), true); + playable.getEffectList().stopEffects(info -> !info.getSkill().isIrreplacableBuff() && info.getSkill().getBuffType().isBuff() && hasRemoveBuffException(info.getSkill()), true, true); } } } diff --git a/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/model/options/Options.java b/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/model/options/Options.java index 04dd4379fb..2c24b77b7e 100644 --- a/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/model/options/Options.java +++ b/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/model/options/Options.java @@ -204,7 +204,7 @@ public class Options if (info.getOption() == this) { player.sendDebugMessage("Removing effects: " + info.getEffects()); - player.getEffectList().remove(info, false, true); + player.getEffectList().remove(info, false, true, true); } } } diff --git a/L2J_Mobius_3.0_Helios/dist/game/data/scripts/handlers/effecthandlers/DispelBySlot.java b/L2J_Mobius_3.0_Helios/dist/game/data/scripts/handlers/effecthandlers/DispelBySlot.java index 034ed3f77a..a70de6564a 100644 --- a/L2J_Mobius_3.0_Helios/dist/game/data/scripts/handlers/effecthandlers/DispelBySlot.java +++ b/L2J_Mobius_3.0_Helios/dist/game/data/scripts/handlers/effecthandlers/DispelBySlot.java @@ -95,7 +95,7 @@ public final class DispelBySlot extends AbstractEffect final Short abnormalLevel = _dispelAbnormals.get(info.getSkill().getAbnormalType()); return (abnormalLevel != null) && ((abnormalLevel < 0) || (abnormalLevel >= info.getSkill().getAbnormalLvl())); - }, true); + }, true, true); } } } diff --git a/L2J_Mobius_3.0_Helios/dist/game/data/scripts/handlers/effecthandlers/DispelBySlotMyself.java b/L2J_Mobius_3.0_Helios/dist/game/data/scripts/handlers/effecthandlers/DispelBySlotMyself.java index 5513ebafe3..2c3234faf1 100644 --- a/L2J_Mobius_3.0_Helios/dist/game/data/scripts/handlers/effecthandlers/DispelBySlotMyself.java +++ b/L2J_Mobius_3.0_Helios/dist/game/data/scripts/handlers/effecthandlers/DispelBySlotMyself.java @@ -74,6 +74,6 @@ public final class DispelBySlotMyself extends AbstractEffect } // The effectlist should already check if it has buff with this abnormal type or not. - effected.getEffectList().stopEffects(info -> !info.getSkill().isIrreplacableBuff() && _dispelAbnormals.contains(info.getSkill().getAbnormalType()), true); + effected.getEffectList().stopEffects(info -> !info.getSkill().isIrreplacableBuff() && _dispelAbnormals.contains(info.getSkill().getAbnormalType()), true, true); } } diff --git a/L2J_Mobius_3.0_Helios/dist/game/data/scripts/handlers/effecthandlers/DispelBySlotProbability.java b/L2J_Mobius_3.0_Helios/dist/game/data/scripts/handlers/effecthandlers/DispelBySlotProbability.java index 9078f1553f..834c09acb7 100644 --- a/L2J_Mobius_3.0_Helios/dist/game/data/scripts/handlers/effecthandlers/DispelBySlotProbability.java +++ b/L2J_Mobius_3.0_Helios/dist/game/data/scripts/handlers/effecthandlers/DispelBySlotProbability.java @@ -98,6 +98,6 @@ public final class DispelBySlotProbability extends AbstractEffect final Short abnormalLevel = (Rnd.get(100) < _rate) ? _dispelAbnormals.get(info.getSkill().getAbnormalType()) : null; return (abnormalLevel != null) && ((abnormalLevel < 0) || (abnormalLevel >= info.getSkill().getAbnormalLvl())); - }, true); + }, true, true); } } diff --git a/L2J_Mobius_3.0_Helios/dist/game/data/scripts/handlers/effecthandlers/StealAbnormal.java b/L2J_Mobius_3.0_Helios/dist/game/data/scripts/handlers/effecthandlers/StealAbnormal.java index c711533bfe..580be62378 100644 --- a/L2J_Mobius_3.0_Helios/dist/game/data/scripts/handlers/effecthandlers/StealAbnormal.java +++ b/L2J_Mobius_3.0_Helios/dist/game/data/scripts/handlers/effecthandlers/StealAbnormal.java @@ -76,7 +76,7 @@ public final class StealAbnormal extends AbstractEffect stolen.setAbnormalTime(infoToSteal.getTime()); // Copy the remaining time. // To include all the effects, it's required to go through the template rather the buff info. infoToSteal.getSkill().applyEffectScope(EffectScope.GENERAL, stolen, true, true); - effected.getEffectList().remove(infoToSteal, true, true); + effected.getEffectList().remove(infoToSteal, true, true, true); effector.getEffectList().add(stolen); } } diff --git a/L2J_Mobius_3.0_Helios/dist/game/data/scripts/instances/Kamaloka/Kamaloka.java b/L2J_Mobius_3.0_Helios/dist/game/data/scripts/instances/Kamaloka/Kamaloka.java index 2a8ce3803f..cfbe5cc68d 100644 --- a/L2J_Mobius_3.0_Helios/dist/game/data/scripts/instances/Kamaloka/Kamaloka.java +++ b/L2J_Mobius_3.0_Helios/dist/game/data/scripts/instances/Kamaloka/Kamaloka.java @@ -491,7 +491,7 @@ public final class Kamaloka extends AbstractInstance private static final void removeBuffs(L2Character ch) { // Stop all buffs. - ch.getEffectList().stopEffects(info -> (info != null) && !info.getSkill().isStayAfterDeath() && (Arrays.binarySearch(BUFFS_WHITELIST, info.getSkill().getId()) < 0), true); + ch.getEffectList().stopEffects(info -> (info != null) && !info.getSkill().isStayAfterDeath() && (Arrays.binarySearch(BUFFS_WHITELIST, info.getSkill().getId()) < 0), true, true); } /** diff --git a/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/model/CharEffectList.java b/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/model/CharEffectList.java index de027352eb..f8e1cf6833 100644 --- a/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/model/CharEffectList.java +++ b/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/model/CharEffectList.java @@ -332,10 +332,11 @@ public final class CharEffectList /** * Exits all effects in this effect list.
* Stops all the effects, clear the effect lists and updates the effect flags and icons. + * @param broadcast {@code true} to broadcast update packets, {@code false} otherwise. */ - public void stopAllEffects() + public void stopAllEffects(boolean broadcast) { - stopEffects(b -> !b.getSkill().isNecessaryToggle() && !b.getSkill().isIrreplacableBuff(), true); + stopEffects(b -> !b.getSkill().isNecessaryToggle() && !b.getSkill().isIrreplacableBuff(), true, broadcast); } /** @@ -343,7 +344,7 @@ public final class CharEffectList */ public void stopAllEffectsExceptThoseThatLastThroughDeath() { - stopEffects(info -> !info.getSkill().isStayAfterDeath(), true); + stopEffects(info -> !info.getSkill().isStayAfterDeath(), true, true); } /** @@ -354,7 +355,7 @@ public final class CharEffectList if (getToggleCount() > 0) { // Ignore necessary toggles. - stopEffects(b -> b.getSkill().isToggle() && !b.getSkill().isNecessaryToggle() && !b.getSkill().isIrreplacableBuff(), true); + stopEffects(b -> b.getSkill().isToggle() && !b.getSkill().isNecessaryToggle() && !b.getSkill().isIrreplacableBuff(), true, true); } } @@ -362,35 +363,43 @@ public final class CharEffectList { if (getToggleCount() > 0) { - stopEffects(b -> b.getSkill().isToggle() && (b.getSkill().getToggleGroupId() == toggleGroup), true); + stopEffects(b -> b.getSkill().isToggle() && (b.getSkill().getToggleGroupId() == toggleGroup), true, true); } } /** * Stops all active dances/songs skills. * @param update set to true to update the effect flags and icons + * @param broadcast {@code true} to broadcast update packets if updating, {@code false} otherwise. */ - public void stopAllPassives(boolean update) + public void stopAllPassives(boolean update, boolean broadcast) { if (_passives != null) { _passives.forEach(this::remove); // Update stats, effect flags and icons. - updateEffectList(update); + if (update) + { + updateEffectList(broadcast); + } } } /** * Stops all active dances/songs skills. * @param update set to true to update the effect flags and icons + * @param broadcast {@code true} to broadcast update packets if updating, {@code false} otherwise. */ - public void stopAllOptions(boolean update) + public void stopAllOptions(boolean update, boolean broadcast) { if (_options != null) { _options.forEach(this::remove); // Update stats, effect flags and icons. - updateEffectList(update); + if (update) + { + updateEffectList(broadcast); + } } } @@ -402,7 +411,7 @@ public final class CharEffectList { if (isAffected(effectFlag)) { - stopEffects(info -> info.getEffects().stream().anyMatch(effect -> (effect != null) && ((effect.getEffectFlags() & effectFlag.getMask()) != 0)), true); + stopEffects(info -> info.getEffects().stream().anyMatch(effect -> (effect != null) && ((effect.getEffectFlags() & effectFlag.getMask()) != 0)), true, true); } } @@ -421,7 +430,7 @@ public final class CharEffectList final BuffInfo info = getBuffInfoBySkillId(skillId); if (info != null) { - remove(info, removed, true); + remove(info, removed, true, true); } } @@ -454,7 +463,7 @@ public final class CharEffectList { if (hasAbnormalType(type)) { - stopEffects(i -> i.isAbnormalType(type), true); + stopEffects(i -> i.isAbnormalType(type), true, true); return true; } @@ -470,7 +479,7 @@ public final class CharEffectList { if (hasAbnormalType(types)) { - stopEffects(i -> types.contains(i.getSkill().getAbnormalType()), true); + stopEffects(i -> types.contains(i.getSkill().getAbnormalType()), true, true); return true; } @@ -481,15 +490,19 @@ public final class CharEffectList * Exits all effects matched by a specific filter.
* @param filter any filter to apply when selecting which {@code BuffInfo}s to be removed. * @param update update effect flags and icons after the operation finishes. + * @param broadcast {@code true} to broadcast update packets if updating, {@code false} otherwise. */ - public void stopEffects(Predicate filter, boolean update) + public void stopEffects(Predicate filter, boolean update, boolean broadcast) { if (_actives != null) { _actives.stream().filter(filter).forEach(this::remove); // Update stats, effect flags and icons. - updateEffectList(update); + if (update) + { + updateEffectList(broadcast); + } } } @@ -501,7 +514,7 @@ public final class CharEffectList { if (_hasBuffsRemovedOnAnyAction.intValue() > 0) { - stopEffects(info -> info.getSkill().isRemovedOnAnyActionExceptMove(), true); + stopEffects(info -> info.getSkill().isRemovedOnAnyActionExceptMove(), true, true); } } @@ -509,7 +522,7 @@ public final class CharEffectList { if (_hasBuffsRemovedOnDamage.intValue() > 0) { - stopEffects(info -> info.getSkill().isRemovedOnDamage(), true); + stopEffects(info -> info.getSkill().isRemovedOnDamage(), true, true); } } @@ -626,7 +639,7 @@ public final class CharEffectList */ private void remove(BuffInfo info) { - remove(info, true, false); + remove(info, true, false, false); } /** @@ -634,8 +647,9 @@ public final class CharEffectList * @param info the effects to remove * @param removed {@code true} if the effect is removed, {@code false} otherwise * @param update {@code true} if effect flags and icons should be updated after this removal, {@code false} otherwise. + * @param broadcast {@code true} to broadcast update packets if updating, {@code false} otherwise. */ - public void remove(BuffInfo info, boolean removed, boolean update) + public void remove(BuffInfo info, boolean removed, boolean update, boolean broadcast) { if (info == null) { @@ -659,7 +673,10 @@ public final class CharEffectList } // Update stats, effect flags and icons. - updateEffectList(update); + if (update) + { + updateEffectList(broadcast); + } } /** @@ -1070,74 +1087,74 @@ public final class CharEffectList /** * Wrapper to update abnormal icons and effect flags. - * @param update if {@code true} performs an update + * @param broadcast {@code true} sends update packets to observing players, {@code false} doesn't send any packets. */ - private void updateEffectList(boolean update) + private void updateEffectList(boolean broadcast) { - if (update) + // Create new empty flags. + long flags = 0; + final Set abnormalTypeFlags = EnumSet.noneOf(AbnormalType.class); + final Set abnormalVisualEffectFlags = EnumSet.noneOf(AbnormalVisualEffect.class); + final Set unhideBuffs = new HashSet<>(); + + // Recalculate new flags + if (_actives != null) { - // Create new empty flags. - long flags = 0; - final Set abnormalTypeFlags = EnumSet.noneOf(AbnormalType.class); - final Set abnormalVisualEffectFlags = EnumSet.noneOf(AbnormalVisualEffect.class); - final Set unhideBuffs = new HashSet<>(); - - // Recalculate new flags - if (_actives != null) + for (BuffInfo info : _actives) { - for (BuffInfo info : _actives) + if (info != null) { - if (info != null) + final Skill skill = info.getSkill(); + + // Handle hidden buffs. Check if there was such abnormal before so we can continue. + if ((getHiddenBuffsCount() > 0) && _stackedEffects.contains(skill.getAbnormalType())) { - final Skill skill = info.getSkill(); - - // Handle hidden buffs. Check if there was such abnormal before so we can continue. - if ((getHiddenBuffsCount() > 0) && _stackedEffects.contains(skill.getAbnormalType())) + // If incoming buff isnt hidden, remove any hidden buffs with its abnormal type. + if (info.isInUse()) { - // If incoming buff isnt hidden, remove any hidden buffs with its abnormal type. - if (info.isInUse()) - { - unhideBuffs.removeIf(b -> b.isAbnormalType(skill.getAbnormalType())); - } - // If this incoming buff is hidden and its first of its abnormal, or it removes any previous hidden buff with the same or lower abnormal level and add this instead. - else if (!abnormalTypeFlags.contains(skill.getAbnormalType()) || unhideBuffs.removeIf(b -> (b.isAbnormalType(skill.getAbnormalType())) && (b.getSkill().getAbnormalLvl() <= skill.getAbnormalLvl()))) - { - unhideBuffs.add(info); - } + unhideBuffs.removeIf(b -> b.isAbnormalType(skill.getAbnormalType())); } - - // Add the EffectType flag. - for (AbstractEffect e : info.getEffects()) + // If this incoming buff is hidden and its first of its abnormal, or it removes any previous hidden buff with the same or lower abnormal level and add this instead. + else if (!abnormalTypeFlags.contains(skill.getAbnormalType()) || unhideBuffs.removeIf(b -> (b.isAbnormalType(skill.getAbnormalType())) && (b.getSkill().getAbnormalLvl() <= skill.getAbnormalLvl()))) { - flags |= e.getEffectFlags(); - } - - // Add the AbnormalType flag. - abnormalTypeFlags.add(skill.getAbnormalType()); - - // Add AbnormalVisualEffect flag. - if (skill.hasAbnormalVisualEffects()) - { - abnormalVisualEffectFlags.addAll(skill.getAbnormalVisualEffects()); + unhideBuffs.add(info); } } + + // Add the EffectType flag. + for (AbstractEffect e : info.getEffects()) + { + flags |= e.getEffectFlags(); + } + + // Add the AbnormalType flag. + abnormalTypeFlags.add(skill.getAbnormalType()); + + // Add AbnormalVisualEffect flag. + if (skill.hasAbnormalVisualEffects()) + { + abnormalVisualEffectFlags.addAll(skill.getAbnormalVisualEffects()); + } } } - - // Replace the old flags with the new flags. - _effectFlags = flags; - _stackedEffects = abnormalTypeFlags; - - // Unhide the selected buffs. - unhideBuffs.forEach(b -> - { - b.setInUse(true); - _hiddenBuffs.decrementAndGet(); - }); - - // Recalculate all stats - _owner.getStat().recalculateStats(true); - + } + + // Replace the old flags with the new flags. + _effectFlags = flags; + _stackedEffects = abnormalTypeFlags; + + // Unhide the selected buffs. + unhideBuffs.forEach(b -> + { + b.setInUse(true); + _hiddenBuffs.decrementAndGet(); + }); + + // Recalculate all stats + _owner.getStat().recalculateStats(broadcast); + + if (broadcast) + { // Check if there is change in AbnormalVisualEffect if ((abnormalVisualEffectFlags.size() != _abnormalVisualEffects.size()) || !abnormalVisualEffectFlags.containsAll(_abnormalVisualEffects)) { diff --git a/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/model/actor/L2Character.java b/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/model/actor/L2Character.java index bf268507a8..e7f6e87a65 100644 --- a/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/model/actor/L2Character.java +++ b/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/model/actor/L2Character.java @@ -1950,8 +1950,8 @@ public abstract class L2Character extends L2Object implements ISkillsHolder, IDe getSummoner().removeSummonedNpc(getObjectId()); } - // Remove all effects - _effectList.stopAllEffects(); + // Remove all effects, do not broadcast changes. + _effectList.stopAllEffects(false); // Cancel all timers related to this Creature TimersManager.getInstance().cancelTimers(getObjectId()); @@ -2554,7 +2554,7 @@ public abstract class L2Character extends L2Object implements ISkillsHolder, IDe */ public void stopAllEffects() { - _effectList.stopAllEffects(); + _effectList.stopAllEffects(true); } /** diff --git a/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/model/actor/L2Npc.java b/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/model/actor/L2Npc.java index 96801d3313..aa4830fcbe 100644 --- a/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/model/actor/L2Npc.java +++ b/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/model/actor/L2Npc.java @@ -997,8 +997,8 @@ public class L2Npc extends L2Character */ public void onRespawn() { - // Stop all effects - stopAllEffects(); + // Stop all effects and recalculate stats without broadcasting. + getEffectList().stopAllEffects(false); // Make it alive setIsDead(false); @@ -1006,11 +1006,9 @@ public class L2Npc extends L2Character // Reset decay info setDecayed(false); - // Recalculate npcs stats - getStat().recalculateStats(true); - - // Set the HP and MP of the L2NpcInstance to the max - setCurrentHpMp(getMaxHp(), getMaxMp()); + // Fully heal npc and don't broadcast packet. + setCurrentHp(getMaxHp(), false); + setCurrentMp(getMaxMp(), false); // Clear script variables if (hasVariables()) diff --git a/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/model/actor/instance/L2PcInstance.java b/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/model/actor/instance/L2PcInstance.java index ea7e249b32..15f45cb23b 100644 --- a/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/model/actor/instance/L2PcInstance.java +++ b/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/model/actor/instance/L2PcInstance.java @@ -10634,9 +10634,9 @@ public final class L2PcInstance extends L2Playable cleanup(); storeMe(); - // Stop all passives and augment options - getEffectList().stopAllPassives(false); - getEffectList().stopAllOptions(false); + // Stop all passives and augment options without broadcasting changes. + getEffectList().stopAllPassives(false, false); + getEffectList().stopAllOptions(false, false); return super.deleteMe(); } diff --git a/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/model/actor/status/CharStatus.java b/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/model/actor/status/CharStatus.java index a30d9f419d..9494559d7d 100644 --- a/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/model/actor/status/CharStatus.java +++ b/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/model/actor/status/CharStatus.java @@ -331,7 +331,7 @@ public class CharStatus { if (_previousHpPercent.compareAndSet(lastHpPercent, currentHpPercent)) { - _activeChar.getStat().recalculateStats(true); + _activeChar.getStat().recalculateStats(broadcastPacket); } } diff --git a/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/model/instancezone/InstanceTemplate.java b/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/model/instancezone/InstanceTemplate.java index cfa158dfff..f4fa7592ad 100644 --- a/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/model/instancezone/InstanceTemplate.java +++ b/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/model/instancezone/InstanceTemplate.java @@ -509,7 +509,7 @@ public class InstanceTemplate extends ListenersContainer implements IIdentifiabl for (L2Playable playable : affected) { // Stop all buffs. - playable.getEffectList().stopEffects(info -> !info.getSkill().isIrreplacableBuff() && info.getSkill().getBuffType().isBuff() && hasRemoveBuffException(info.getSkill()), true); + playable.getEffectList().stopEffects(info -> !info.getSkill().isIrreplacableBuff() && info.getSkill().getBuffType().isBuff() && hasRemoveBuffException(info.getSkill()), true, true); } } } diff --git a/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/model/options/Options.java b/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/model/options/Options.java index 04dd4379fb..2c24b77b7e 100644 --- a/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/model/options/Options.java +++ b/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/model/options/Options.java @@ -204,7 +204,7 @@ public class Options if (info.getOption() == this) { player.sendDebugMessage("Removing effects: " + info.getEffects()); - player.getEffectList().remove(info, false, true); + player.getEffectList().remove(info, false, true, true); } } } diff --git a/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/scripts/handlers/effecthandlers/DispelBySlot.java b/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/scripts/handlers/effecthandlers/DispelBySlot.java index 034ed3f77a..a70de6564a 100644 --- a/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/scripts/handlers/effecthandlers/DispelBySlot.java +++ b/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/scripts/handlers/effecthandlers/DispelBySlot.java @@ -95,7 +95,7 @@ public final class DispelBySlot extends AbstractEffect final Short abnormalLevel = _dispelAbnormals.get(info.getSkill().getAbnormalType()); return (abnormalLevel != null) && ((abnormalLevel < 0) || (abnormalLevel >= info.getSkill().getAbnormalLvl())); - }, true); + }, true, true); } } } diff --git a/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/scripts/handlers/effecthandlers/DispelBySlotMyself.java b/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/scripts/handlers/effecthandlers/DispelBySlotMyself.java index 5513ebafe3..2c3234faf1 100644 --- a/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/scripts/handlers/effecthandlers/DispelBySlotMyself.java +++ b/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/scripts/handlers/effecthandlers/DispelBySlotMyself.java @@ -74,6 +74,6 @@ public final class DispelBySlotMyself extends AbstractEffect } // The effectlist should already check if it has buff with this abnormal type or not. - effected.getEffectList().stopEffects(info -> !info.getSkill().isIrreplacableBuff() && _dispelAbnormals.contains(info.getSkill().getAbnormalType()), true); + effected.getEffectList().stopEffects(info -> !info.getSkill().isIrreplacableBuff() && _dispelAbnormals.contains(info.getSkill().getAbnormalType()), true, true); } } diff --git a/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/scripts/handlers/effecthandlers/DispelBySlotProbability.java b/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/scripts/handlers/effecthandlers/DispelBySlotProbability.java index 9078f1553f..834c09acb7 100644 --- a/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/scripts/handlers/effecthandlers/DispelBySlotProbability.java +++ b/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/scripts/handlers/effecthandlers/DispelBySlotProbability.java @@ -98,6 +98,6 @@ public final class DispelBySlotProbability extends AbstractEffect final Short abnormalLevel = (Rnd.get(100) < _rate) ? _dispelAbnormals.get(info.getSkill().getAbnormalType()) : null; return (abnormalLevel != null) && ((abnormalLevel < 0) || (abnormalLevel >= info.getSkill().getAbnormalLvl())); - }, true); + }, true, true); } } diff --git a/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/scripts/handlers/effecthandlers/StealAbnormal.java b/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/scripts/handlers/effecthandlers/StealAbnormal.java index c711533bfe..580be62378 100644 --- a/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/scripts/handlers/effecthandlers/StealAbnormal.java +++ b/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/scripts/handlers/effecthandlers/StealAbnormal.java @@ -76,7 +76,7 @@ public final class StealAbnormal extends AbstractEffect stolen.setAbnormalTime(infoToSteal.getTime()); // Copy the remaining time. // To include all the effects, it's required to go through the template rather the buff info. infoToSteal.getSkill().applyEffectScope(EffectScope.GENERAL, stolen, true, true); - effected.getEffectList().remove(infoToSteal, true, true); + effected.getEffectList().remove(infoToSteal, true, true, true); effector.getEffectList().add(stolen); } } diff --git a/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/model/CharEffectList.java b/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/model/CharEffectList.java index de027352eb..f8e1cf6833 100644 --- a/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/model/CharEffectList.java +++ b/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/model/CharEffectList.java @@ -332,10 +332,11 @@ public final class CharEffectList /** * Exits all effects in this effect list.
* Stops all the effects, clear the effect lists and updates the effect flags and icons. + * @param broadcast {@code true} to broadcast update packets, {@code false} otherwise. */ - public void stopAllEffects() + public void stopAllEffects(boolean broadcast) { - stopEffects(b -> !b.getSkill().isNecessaryToggle() && !b.getSkill().isIrreplacableBuff(), true); + stopEffects(b -> !b.getSkill().isNecessaryToggle() && !b.getSkill().isIrreplacableBuff(), true, broadcast); } /** @@ -343,7 +344,7 @@ public final class CharEffectList */ public void stopAllEffectsExceptThoseThatLastThroughDeath() { - stopEffects(info -> !info.getSkill().isStayAfterDeath(), true); + stopEffects(info -> !info.getSkill().isStayAfterDeath(), true, true); } /** @@ -354,7 +355,7 @@ public final class CharEffectList if (getToggleCount() > 0) { // Ignore necessary toggles. - stopEffects(b -> b.getSkill().isToggle() && !b.getSkill().isNecessaryToggle() && !b.getSkill().isIrreplacableBuff(), true); + stopEffects(b -> b.getSkill().isToggle() && !b.getSkill().isNecessaryToggle() && !b.getSkill().isIrreplacableBuff(), true, true); } } @@ -362,35 +363,43 @@ public final class CharEffectList { if (getToggleCount() > 0) { - stopEffects(b -> b.getSkill().isToggle() && (b.getSkill().getToggleGroupId() == toggleGroup), true); + stopEffects(b -> b.getSkill().isToggle() && (b.getSkill().getToggleGroupId() == toggleGroup), true, true); } } /** * Stops all active dances/songs skills. * @param update set to true to update the effect flags and icons + * @param broadcast {@code true} to broadcast update packets if updating, {@code false} otherwise. */ - public void stopAllPassives(boolean update) + public void stopAllPassives(boolean update, boolean broadcast) { if (_passives != null) { _passives.forEach(this::remove); // Update stats, effect flags and icons. - updateEffectList(update); + if (update) + { + updateEffectList(broadcast); + } } } /** * Stops all active dances/songs skills. * @param update set to true to update the effect flags and icons + * @param broadcast {@code true} to broadcast update packets if updating, {@code false} otherwise. */ - public void stopAllOptions(boolean update) + public void stopAllOptions(boolean update, boolean broadcast) { if (_options != null) { _options.forEach(this::remove); // Update stats, effect flags and icons. - updateEffectList(update); + if (update) + { + updateEffectList(broadcast); + } } } @@ -402,7 +411,7 @@ public final class CharEffectList { if (isAffected(effectFlag)) { - stopEffects(info -> info.getEffects().stream().anyMatch(effect -> (effect != null) && ((effect.getEffectFlags() & effectFlag.getMask()) != 0)), true); + stopEffects(info -> info.getEffects().stream().anyMatch(effect -> (effect != null) && ((effect.getEffectFlags() & effectFlag.getMask()) != 0)), true, true); } } @@ -421,7 +430,7 @@ public final class CharEffectList final BuffInfo info = getBuffInfoBySkillId(skillId); if (info != null) { - remove(info, removed, true); + remove(info, removed, true, true); } } @@ -454,7 +463,7 @@ public final class CharEffectList { if (hasAbnormalType(type)) { - stopEffects(i -> i.isAbnormalType(type), true); + stopEffects(i -> i.isAbnormalType(type), true, true); return true; } @@ -470,7 +479,7 @@ public final class CharEffectList { if (hasAbnormalType(types)) { - stopEffects(i -> types.contains(i.getSkill().getAbnormalType()), true); + stopEffects(i -> types.contains(i.getSkill().getAbnormalType()), true, true); return true; } @@ -481,15 +490,19 @@ public final class CharEffectList * Exits all effects matched by a specific filter.
* @param filter any filter to apply when selecting which {@code BuffInfo}s to be removed. * @param update update effect flags and icons after the operation finishes. + * @param broadcast {@code true} to broadcast update packets if updating, {@code false} otherwise. */ - public void stopEffects(Predicate filter, boolean update) + public void stopEffects(Predicate filter, boolean update, boolean broadcast) { if (_actives != null) { _actives.stream().filter(filter).forEach(this::remove); // Update stats, effect flags and icons. - updateEffectList(update); + if (update) + { + updateEffectList(broadcast); + } } } @@ -501,7 +514,7 @@ public final class CharEffectList { if (_hasBuffsRemovedOnAnyAction.intValue() > 0) { - stopEffects(info -> info.getSkill().isRemovedOnAnyActionExceptMove(), true); + stopEffects(info -> info.getSkill().isRemovedOnAnyActionExceptMove(), true, true); } } @@ -509,7 +522,7 @@ public final class CharEffectList { if (_hasBuffsRemovedOnDamage.intValue() > 0) { - stopEffects(info -> info.getSkill().isRemovedOnDamage(), true); + stopEffects(info -> info.getSkill().isRemovedOnDamage(), true, true); } } @@ -626,7 +639,7 @@ public final class CharEffectList */ private void remove(BuffInfo info) { - remove(info, true, false); + remove(info, true, false, false); } /** @@ -634,8 +647,9 @@ public final class CharEffectList * @param info the effects to remove * @param removed {@code true} if the effect is removed, {@code false} otherwise * @param update {@code true} if effect flags and icons should be updated after this removal, {@code false} otherwise. + * @param broadcast {@code true} to broadcast update packets if updating, {@code false} otherwise. */ - public void remove(BuffInfo info, boolean removed, boolean update) + public void remove(BuffInfo info, boolean removed, boolean update, boolean broadcast) { if (info == null) { @@ -659,7 +673,10 @@ public final class CharEffectList } // Update stats, effect flags and icons. - updateEffectList(update); + if (update) + { + updateEffectList(broadcast); + } } /** @@ -1070,74 +1087,74 @@ public final class CharEffectList /** * Wrapper to update abnormal icons and effect flags. - * @param update if {@code true} performs an update + * @param broadcast {@code true} sends update packets to observing players, {@code false} doesn't send any packets. */ - private void updateEffectList(boolean update) + private void updateEffectList(boolean broadcast) { - if (update) + // Create new empty flags. + long flags = 0; + final Set abnormalTypeFlags = EnumSet.noneOf(AbnormalType.class); + final Set abnormalVisualEffectFlags = EnumSet.noneOf(AbnormalVisualEffect.class); + final Set unhideBuffs = new HashSet<>(); + + // Recalculate new flags + if (_actives != null) { - // Create new empty flags. - long flags = 0; - final Set abnormalTypeFlags = EnumSet.noneOf(AbnormalType.class); - final Set abnormalVisualEffectFlags = EnumSet.noneOf(AbnormalVisualEffect.class); - final Set unhideBuffs = new HashSet<>(); - - // Recalculate new flags - if (_actives != null) + for (BuffInfo info : _actives) { - for (BuffInfo info : _actives) + if (info != null) { - if (info != null) + final Skill skill = info.getSkill(); + + // Handle hidden buffs. Check if there was such abnormal before so we can continue. + if ((getHiddenBuffsCount() > 0) && _stackedEffects.contains(skill.getAbnormalType())) { - final Skill skill = info.getSkill(); - - // Handle hidden buffs. Check if there was such abnormal before so we can continue. - if ((getHiddenBuffsCount() > 0) && _stackedEffects.contains(skill.getAbnormalType())) + // If incoming buff isnt hidden, remove any hidden buffs with its abnormal type. + if (info.isInUse()) { - // If incoming buff isnt hidden, remove any hidden buffs with its abnormal type. - if (info.isInUse()) - { - unhideBuffs.removeIf(b -> b.isAbnormalType(skill.getAbnormalType())); - } - // If this incoming buff is hidden and its first of its abnormal, or it removes any previous hidden buff with the same or lower abnormal level and add this instead. - else if (!abnormalTypeFlags.contains(skill.getAbnormalType()) || unhideBuffs.removeIf(b -> (b.isAbnormalType(skill.getAbnormalType())) && (b.getSkill().getAbnormalLvl() <= skill.getAbnormalLvl()))) - { - unhideBuffs.add(info); - } + unhideBuffs.removeIf(b -> b.isAbnormalType(skill.getAbnormalType())); } - - // Add the EffectType flag. - for (AbstractEffect e : info.getEffects()) + // If this incoming buff is hidden and its first of its abnormal, or it removes any previous hidden buff with the same or lower abnormal level and add this instead. + else if (!abnormalTypeFlags.contains(skill.getAbnormalType()) || unhideBuffs.removeIf(b -> (b.isAbnormalType(skill.getAbnormalType())) && (b.getSkill().getAbnormalLvl() <= skill.getAbnormalLvl()))) { - flags |= e.getEffectFlags(); - } - - // Add the AbnormalType flag. - abnormalTypeFlags.add(skill.getAbnormalType()); - - // Add AbnormalVisualEffect flag. - if (skill.hasAbnormalVisualEffects()) - { - abnormalVisualEffectFlags.addAll(skill.getAbnormalVisualEffects()); + unhideBuffs.add(info); } } + + // Add the EffectType flag. + for (AbstractEffect e : info.getEffects()) + { + flags |= e.getEffectFlags(); + } + + // Add the AbnormalType flag. + abnormalTypeFlags.add(skill.getAbnormalType()); + + // Add AbnormalVisualEffect flag. + if (skill.hasAbnormalVisualEffects()) + { + abnormalVisualEffectFlags.addAll(skill.getAbnormalVisualEffects()); + } } } - - // Replace the old flags with the new flags. - _effectFlags = flags; - _stackedEffects = abnormalTypeFlags; - - // Unhide the selected buffs. - unhideBuffs.forEach(b -> - { - b.setInUse(true); - _hiddenBuffs.decrementAndGet(); - }); - - // Recalculate all stats - _owner.getStat().recalculateStats(true); - + } + + // Replace the old flags with the new flags. + _effectFlags = flags; + _stackedEffects = abnormalTypeFlags; + + // Unhide the selected buffs. + unhideBuffs.forEach(b -> + { + b.setInUse(true); + _hiddenBuffs.decrementAndGet(); + }); + + // Recalculate all stats + _owner.getStat().recalculateStats(broadcast); + + if (broadcast) + { // Check if there is change in AbnormalVisualEffect if ((abnormalVisualEffectFlags.size() != _abnormalVisualEffects.size()) || !abnormalVisualEffectFlags.containsAll(_abnormalVisualEffects)) { diff --git a/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/model/actor/L2Character.java b/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/model/actor/L2Character.java index bf268507a8..e7f6e87a65 100644 --- a/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/model/actor/L2Character.java +++ b/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/model/actor/L2Character.java @@ -1950,8 +1950,8 @@ public abstract class L2Character extends L2Object implements ISkillsHolder, IDe getSummoner().removeSummonedNpc(getObjectId()); } - // Remove all effects - _effectList.stopAllEffects(); + // Remove all effects, do not broadcast changes. + _effectList.stopAllEffects(false); // Cancel all timers related to this Creature TimersManager.getInstance().cancelTimers(getObjectId()); @@ -2554,7 +2554,7 @@ public abstract class L2Character extends L2Object implements ISkillsHolder, IDe */ public void stopAllEffects() { - _effectList.stopAllEffects(); + _effectList.stopAllEffects(true); } /** diff --git a/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/model/actor/L2Npc.java b/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/model/actor/L2Npc.java index 96801d3313..aa4830fcbe 100644 --- a/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/model/actor/L2Npc.java +++ b/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/model/actor/L2Npc.java @@ -997,8 +997,8 @@ public class L2Npc extends L2Character */ public void onRespawn() { - // Stop all effects - stopAllEffects(); + // Stop all effects and recalculate stats without broadcasting. + getEffectList().stopAllEffects(false); // Make it alive setIsDead(false); @@ -1006,11 +1006,9 @@ public class L2Npc extends L2Character // Reset decay info setDecayed(false); - // Recalculate npcs stats - getStat().recalculateStats(true); - - // Set the HP and MP of the L2NpcInstance to the max - setCurrentHpMp(getMaxHp(), getMaxMp()); + // Fully heal npc and don't broadcast packet. + setCurrentHp(getMaxHp(), false); + setCurrentMp(getMaxMp(), false); // Clear script variables if (hasVariables()) diff --git a/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/model/actor/instance/L2PcInstance.java b/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/model/actor/instance/L2PcInstance.java index 6c8df576c1..820361b03d 100644 --- a/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/model/actor/instance/L2PcInstance.java +++ b/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/model/actor/instance/L2PcInstance.java @@ -10596,9 +10596,9 @@ public final class L2PcInstance extends L2Playable cleanup(); storeMe(); - // Stop all passives and augment options - getEffectList().stopAllPassives(false); - getEffectList().stopAllOptions(false); + // Stop all passives and augment options without broadcasting changes. + getEffectList().stopAllPassives(false, false); + getEffectList().stopAllOptions(false, false); return super.deleteMe(); } diff --git a/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/model/actor/status/CharStatus.java b/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/model/actor/status/CharStatus.java index a30d9f419d..9494559d7d 100644 --- a/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/model/actor/status/CharStatus.java +++ b/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/model/actor/status/CharStatus.java @@ -331,7 +331,7 @@ public class CharStatus { if (_previousHpPercent.compareAndSet(lastHpPercent, currentHpPercent)) { - _activeChar.getStat().recalculateStats(true); + _activeChar.getStat().recalculateStats(broadcastPacket); } } diff --git a/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/model/instancezone/InstanceTemplate.java b/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/model/instancezone/InstanceTemplate.java index cfa158dfff..f4fa7592ad 100644 --- a/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/model/instancezone/InstanceTemplate.java +++ b/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/model/instancezone/InstanceTemplate.java @@ -509,7 +509,7 @@ public class InstanceTemplate extends ListenersContainer implements IIdentifiabl for (L2Playable playable : affected) { // Stop all buffs. - playable.getEffectList().stopEffects(info -> !info.getSkill().isIrreplacableBuff() && info.getSkill().getBuffType().isBuff() && hasRemoveBuffException(info.getSkill()), true); + playable.getEffectList().stopEffects(info -> !info.getSkill().isIrreplacableBuff() && info.getSkill().getBuffType().isBuff() && hasRemoveBuffException(info.getSkill()), true, true); } } } diff --git a/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/model/options/Options.java b/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/model/options/Options.java index 04dd4379fb..2c24b77b7e 100644 --- a/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/model/options/Options.java +++ b/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/model/options/Options.java @@ -204,7 +204,7 @@ public class Options if (info.getOption() == this) { player.sendDebugMessage("Removing effects: " + info.getEffects()); - player.getEffectList().remove(info, false, true); + player.getEffectList().remove(info, false, true, true); } } }