Effect list broadcast issue fix.

Contributed by Liamxroy.
This commit is contained in:
MobiusDev 2017-09-26 15:41:55 +00:00
parent 9816651177
commit ebc4a789e6
47 changed files with 443 additions and 383 deletions

View File

@ -95,7 +95,7 @@ public final class DispelBySlot extends AbstractEffect
final Short abnormalLevel = _dispelAbnormals.get(info.getSkill().getAbnormalType()); final Short abnormalLevel = _dispelAbnormals.get(info.getSkill().getAbnormalType());
return (abnormalLevel != null) && ((abnormalLevel < 0) || (abnormalLevel >= info.getSkill().getAbnormalLvl())); return (abnormalLevel != null) && ((abnormalLevel < 0) || (abnormalLevel >= info.getSkill().getAbnormalLvl()));
}, true); }, true, true);
} }
} }
} }

View File

@ -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. // 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);
} }
} }

View File

@ -98,6 +98,6 @@ public final class DispelBySlotProbability extends AbstractEffect
final Short abnormalLevel = (Rnd.get(100) < _rate) ? _dispelAbnormals.get(info.getSkill().getAbnormalType()) : null; final Short abnormalLevel = (Rnd.get(100) < _rate) ? _dispelAbnormals.get(info.getSkill().getAbnormalType()) : null;
return (abnormalLevel != null) && ((abnormalLevel < 0) || (abnormalLevel >= info.getSkill().getAbnormalLvl())); return (abnormalLevel != null) && ((abnormalLevel < 0) || (abnormalLevel >= info.getSkill().getAbnormalLvl()));
}, true); }, true, true);
} }
} }

View File

@ -76,7 +76,7 @@ public final class StealAbnormal extends AbstractEffect
stolen.setAbnormalTime(infoToSteal.getTime()); // Copy the remaining time. 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. // 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); 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); effector.getEffectList().add(stolen);
} }
} }

View File

@ -491,7 +491,7 @@ public final class Kamaloka extends AbstractInstance
private static final void removeBuffs(L2Character ch) private static final void removeBuffs(L2Character ch)
{ {
// Stop all buffs. // 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);
} }
/** /**

View File

@ -332,10 +332,11 @@ public final class CharEffectList
/** /**
* Exits all effects in this effect list.<br> * Exits all effects in this effect list.<br>
* Stops all the effects, clear the effect lists and updates the effect flags and icons. * 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() 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) if (getToggleCount() > 0)
{ {
// Ignore necessary toggles. // 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) 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. * Stops all active dances/songs skills.
* @param update set to true to update the effect flags and icons * @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) if (_passives != null)
{ {
_passives.forEach(this::remove); _passives.forEach(this::remove);
// Update stats, effect flags and icons. // Update stats, effect flags and icons.
updateEffectList(update); if (update)
{
updateEffectList(broadcast);
}
} }
} }
/** /**
* Stops all active dances/songs skills. * Stops all active dances/songs skills.
* @param update set to true to update the effect flags and icons * @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) if (_options != null)
{ {
_options.forEach(this::remove); _options.forEach(this::remove);
// Update stats, effect flags and icons. // Update stats, effect flags and icons.
updateEffectList(update); if (update)
{
updateEffectList(broadcast);
}
} }
} }
@ -402,7 +411,7 @@ public final class CharEffectList
{ {
if (isAffected(effectFlag)) 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); final BuffInfo info = getBuffInfoBySkillId(skillId);
if (info != null) if (info != null)
{ {
remove(info, removed, true); remove(info, removed, true, true);
} }
} }
@ -454,7 +463,7 @@ public final class CharEffectList
{ {
if (hasAbnormalType(type)) if (hasAbnormalType(type))
{ {
stopEffects(i -> i.isAbnormalType(type), true); stopEffects(i -> i.isAbnormalType(type), true, true);
return true; return true;
} }
@ -470,7 +479,7 @@ public final class CharEffectList
{ {
if (hasAbnormalType(types)) if (hasAbnormalType(types))
{ {
stopEffects(i -> types.contains(i.getSkill().getAbnormalType()), true); stopEffects(i -> types.contains(i.getSkill().getAbnormalType()), true, true);
return true; return true;
} }
@ -481,15 +490,19 @@ public final class CharEffectList
* Exits all effects matched by a specific filter.<br> * Exits all effects matched by a specific filter.<br>
* @param filter any filter to apply when selecting which {@code BuffInfo}s to be removed. * @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 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<BuffInfo> filter, boolean update) public void stopEffects(Predicate<BuffInfo> filter, boolean update, boolean broadcast)
{ {
if (_actives != null) if (_actives != null)
{ {
_actives.stream().filter(filter).forEach(this::remove); _actives.stream().filter(filter).forEach(this::remove);
// Update stats, effect flags and icons. // Update stats, effect flags and icons.
updateEffectList(update); if (update)
{
updateEffectList(broadcast);
}
} }
} }
@ -501,7 +514,7 @@ public final class CharEffectList
{ {
if (_hasBuffsRemovedOnAnyAction.intValue() > 0) 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) 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) 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 info the effects to remove
* @param removed {@code true} if the effect is removed, {@code false} otherwise * @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 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) if (info == null)
{ {
@ -659,7 +673,10 @@ public final class CharEffectList
} }
// Update stats, effect flags and icons. // Update stats, effect flags and icons.
updateEffectList(update); if (update)
{
updateEffectList(broadcast);
}
} }
/** /**
@ -1070,11 +1087,9 @@ public final class CharEffectList
/** /**
* Wrapper to update abnormal icons and effect flags. * 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. // Create new empty flags.
long flags = 0; long flags = 0;
@ -1136,8 +1151,10 @@ public final class CharEffectList
}); });
// Recalculate all stats // Recalculate all stats
_owner.getStat().recalculateStats(true); _owner.getStat().recalculateStats(broadcast);
if (broadcast)
{
// Check if there is change in AbnormalVisualEffect // Check if there is change in AbnormalVisualEffect
if ((abnormalVisualEffectFlags.size() != _abnormalVisualEffects.size()) || !abnormalVisualEffectFlags.containsAll(_abnormalVisualEffects)) if ((abnormalVisualEffectFlags.size() != _abnormalVisualEffects.size()) || !abnormalVisualEffectFlags.containsAll(_abnormalVisualEffects))
{ {

View File

@ -1946,8 +1946,8 @@ public abstract class L2Character extends L2Object implements ISkillsHolder, IDe
getSummoner().removeSummonedNpc(getObjectId()); getSummoner().removeSummonedNpc(getObjectId());
} }
// Remove all effects // Remove all effects, do not broadcast changes.
_effectList.stopAllEffects(); _effectList.stopAllEffects(false);
// Cancel all timers related to this Creature // Cancel all timers related to this Creature
TimersManager.getInstance().cancelTimers(getObjectId()); TimersManager.getInstance().cancelTimers(getObjectId());
@ -2550,7 +2550,7 @@ public abstract class L2Character extends L2Object implements ISkillsHolder, IDe
*/ */
public void stopAllEffects() public void stopAllEffects()
{ {
_effectList.stopAllEffects(); _effectList.stopAllEffects(true);
} }
/** /**

View File

@ -998,8 +998,8 @@ public class L2Npc extends L2Character
*/ */
public void onRespawn() public void onRespawn()
{ {
// Stop all effects // Stop all effects and recalculate stats without broadcasting.
stopAllEffects(); getEffectList().stopAllEffects(false);
// Make it alive // Make it alive
setIsDead(false); setIsDead(false);
@ -1007,11 +1007,9 @@ public class L2Npc extends L2Character
// Reset decay info // Reset decay info
setDecayed(false); setDecayed(false);
// Recalculate npcs stats // Fully heal npc and don't broadcast packet.
getStat().recalculateStats(true); setCurrentHp(getMaxHp(), false);
setCurrentMp(getMaxMp(), false);
// Set the HP and MP of the L2NpcInstance to the max
setCurrentHpMp(getMaxHp(), getMaxMp());
// Clear script variables // Clear script variables
if (hasVariables()) if (hasVariables())

View File

@ -10623,9 +10623,9 @@ public final class L2PcInstance extends L2Playable
cleanup(); cleanup();
storeMe(); storeMe();
// Stop all passives and augment options // Stop all passives and augment options without broadcasting changes.
getEffectList().stopAllPassives(false); getEffectList().stopAllPassives(false, false);
getEffectList().stopAllOptions(false); getEffectList().stopAllOptions(false, false);
return super.deleteMe(); return super.deleteMe();
} }

View File

@ -331,7 +331,7 @@ public class CharStatus
{ {
if (_previousHpPercent.compareAndSet(lastHpPercent, currentHpPercent)) if (_previousHpPercent.compareAndSet(lastHpPercent, currentHpPercent))
{ {
_activeChar.getStat().recalculateStats(true); _activeChar.getStat().recalculateStats(broadcastPacket);
} }
} }

View File

@ -509,7 +509,7 @@ public class InstanceTemplate extends ListenersContainer implements IIdentifiabl
for (L2Playable playable : affected) for (L2Playable playable : affected)
{ {
// Stop all buffs. // 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);
} }
} }
} }

View File

@ -204,7 +204,7 @@ public class Options
if (info.getOption() == this) if (info.getOption() == this)
{ {
player.sendDebugMessage("Removing effects: " + info.getEffects()); player.sendDebugMessage("Removing effects: " + info.getEffects());
player.getEffectList().remove(info, false, true); player.getEffectList().remove(info, false, true, true);
} }
} }
} }

View File

@ -95,7 +95,7 @@ public final class DispelBySlot extends AbstractEffect
final Short abnormalLevel = _dispelAbnormals.get(info.getSkill().getAbnormalType()); final Short abnormalLevel = _dispelAbnormals.get(info.getSkill().getAbnormalType());
return (abnormalLevel != null) && ((abnormalLevel < 0) || (abnormalLevel >= info.getSkill().getAbnormalLvl())); return (abnormalLevel != null) && ((abnormalLevel < 0) || (abnormalLevel >= info.getSkill().getAbnormalLvl()));
}, true); }, true, true);
} }
} }
} }

View File

@ -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. // 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);
} }
} }

View File

@ -98,6 +98,6 @@ public final class DispelBySlotProbability extends AbstractEffect
final Short abnormalLevel = (Rnd.get(100) < _rate) ? _dispelAbnormals.get(info.getSkill().getAbnormalType()) : null; final Short abnormalLevel = (Rnd.get(100) < _rate) ? _dispelAbnormals.get(info.getSkill().getAbnormalType()) : null;
return (abnormalLevel != null) && ((abnormalLevel < 0) || (abnormalLevel >= info.getSkill().getAbnormalLvl())); return (abnormalLevel != null) && ((abnormalLevel < 0) || (abnormalLevel >= info.getSkill().getAbnormalLvl()));
}, true); }, true, true);
} }
} }

View File

@ -76,7 +76,7 @@ public final class StealAbnormal extends AbstractEffect
stolen.setAbnormalTime(infoToSteal.getTime()); // Copy the remaining time. 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. // 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); 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); effector.getEffectList().add(stolen);
} }
} }

View File

@ -491,7 +491,7 @@ public final class Kamaloka extends AbstractInstance
private static final void removeBuffs(L2Character ch) private static final void removeBuffs(L2Character ch)
{ {
// Stop all buffs. // 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);
} }
/** /**

View File

@ -332,10 +332,11 @@ public final class CharEffectList
/** /**
* Exits all effects in this effect list.<br> * Exits all effects in this effect list.<br>
* Stops all the effects, clear the effect lists and updates the effect flags and icons. * 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() 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) if (getToggleCount() > 0)
{ {
// Ignore necessary toggles. // 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) 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. * Stops all active dances/songs skills.
* @param update set to true to update the effect flags and icons * @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) if (_passives != null)
{ {
_passives.forEach(this::remove); _passives.forEach(this::remove);
// Update stats, effect flags and icons. // Update stats, effect flags and icons.
updateEffectList(update); if (update)
{
updateEffectList(broadcast);
}
} }
} }
/** /**
* Stops all active dances/songs skills. * Stops all active dances/songs skills.
* @param update set to true to update the effect flags and icons * @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) if (_options != null)
{ {
_options.forEach(this::remove); _options.forEach(this::remove);
// Update stats, effect flags and icons. // Update stats, effect flags and icons.
updateEffectList(update); if (update)
{
updateEffectList(broadcast);
}
} }
} }
@ -402,7 +411,7 @@ public final class CharEffectList
{ {
if (isAffected(effectFlag)) 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); final BuffInfo info = getBuffInfoBySkillId(skillId);
if (info != null) if (info != null)
{ {
remove(info, removed, true); remove(info, removed, true, true);
} }
} }
@ -454,7 +463,7 @@ public final class CharEffectList
{ {
if (hasAbnormalType(type)) if (hasAbnormalType(type))
{ {
stopEffects(i -> i.isAbnormalType(type), true); stopEffects(i -> i.isAbnormalType(type), true, true);
return true; return true;
} }
@ -470,7 +479,7 @@ public final class CharEffectList
{ {
if (hasAbnormalType(types)) if (hasAbnormalType(types))
{ {
stopEffects(i -> types.contains(i.getSkill().getAbnormalType()), true); stopEffects(i -> types.contains(i.getSkill().getAbnormalType()), true, true);
return true; return true;
} }
@ -481,15 +490,19 @@ public final class CharEffectList
* Exits all effects matched by a specific filter.<br> * Exits all effects matched by a specific filter.<br>
* @param filter any filter to apply when selecting which {@code BuffInfo}s to be removed. * @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 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<BuffInfo> filter, boolean update) public void stopEffects(Predicate<BuffInfo> filter, boolean update, boolean broadcast)
{ {
if (_actives != null) if (_actives != null)
{ {
_actives.stream().filter(filter).forEach(this::remove); _actives.stream().filter(filter).forEach(this::remove);
// Update stats, effect flags and icons. // Update stats, effect flags and icons.
updateEffectList(update); if (update)
{
updateEffectList(broadcast);
}
} }
} }
@ -501,7 +514,7 @@ public final class CharEffectList
{ {
if (_hasBuffsRemovedOnAnyAction.intValue() > 0) 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) 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) 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 info the effects to remove
* @param removed {@code true} if the effect is removed, {@code false} otherwise * @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 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) if (info == null)
{ {
@ -659,7 +673,10 @@ public final class CharEffectList
} }
// Update stats, effect flags and icons. // Update stats, effect flags and icons.
updateEffectList(update); if (update)
{
updateEffectList(broadcast);
}
} }
/** /**
@ -1070,11 +1087,9 @@ public final class CharEffectList
/** /**
* Wrapper to update abnormal icons and effect flags. * 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. // Create new empty flags.
long flags = 0; long flags = 0;
@ -1136,8 +1151,10 @@ public final class CharEffectList
}); });
// Recalculate all stats // Recalculate all stats
_owner.getStat().recalculateStats(true); _owner.getStat().recalculateStats(broadcast);
if (broadcast)
{
// Check if there is change in AbnormalVisualEffect // Check if there is change in AbnormalVisualEffect
if ((abnormalVisualEffectFlags.size() != _abnormalVisualEffects.size()) || !abnormalVisualEffectFlags.containsAll(_abnormalVisualEffects)) if ((abnormalVisualEffectFlags.size() != _abnormalVisualEffects.size()) || !abnormalVisualEffectFlags.containsAll(_abnormalVisualEffects))
{ {

View File

@ -1950,8 +1950,8 @@ public abstract class L2Character extends L2Object implements ISkillsHolder, IDe
getSummoner().removeSummonedNpc(getObjectId()); getSummoner().removeSummonedNpc(getObjectId());
} }
// Remove all effects // Remove all effects, do not broadcast changes.
_effectList.stopAllEffects(); _effectList.stopAllEffects(false);
// Cancel all timers related to this Creature // Cancel all timers related to this Creature
TimersManager.getInstance().cancelTimers(getObjectId()); TimersManager.getInstance().cancelTimers(getObjectId());
@ -2554,7 +2554,7 @@ public abstract class L2Character extends L2Object implements ISkillsHolder, IDe
*/ */
public void stopAllEffects() public void stopAllEffects()
{ {
_effectList.stopAllEffects(); _effectList.stopAllEffects(true);
} }
/** /**

View File

@ -997,8 +997,8 @@ public class L2Npc extends L2Character
*/ */
public void onRespawn() public void onRespawn()
{ {
// Stop all effects // Stop all effects and recalculate stats without broadcasting.
stopAllEffects(); getEffectList().stopAllEffects(false);
// Make it alive // Make it alive
setIsDead(false); setIsDead(false);
@ -1006,11 +1006,9 @@ public class L2Npc extends L2Character
// Reset decay info // Reset decay info
setDecayed(false); setDecayed(false);
// Recalculate npcs stats // Fully heal npc and don't broadcast packet.
getStat().recalculateStats(true); setCurrentHp(getMaxHp(), false);
setCurrentMp(getMaxMp(), false);
// Set the HP and MP of the L2NpcInstance to the max
setCurrentHpMp(getMaxHp(), getMaxMp());
// Clear script variables // Clear script variables
if (hasVariables()) if (hasVariables())

View File

@ -10623,9 +10623,9 @@ public final class L2PcInstance extends L2Playable
cleanup(); cleanup();
storeMe(); storeMe();
// Stop all passives and augment options // Stop all passives and augment options without broadcasting changes.
getEffectList().stopAllPassives(false); getEffectList().stopAllPassives(false, false);
getEffectList().stopAllOptions(false); getEffectList().stopAllOptions(false, false);
return super.deleteMe(); return super.deleteMe();
} }

View File

@ -331,7 +331,7 @@ public class CharStatus
{ {
if (_previousHpPercent.compareAndSet(lastHpPercent, currentHpPercent)) if (_previousHpPercent.compareAndSet(lastHpPercent, currentHpPercent))
{ {
_activeChar.getStat().recalculateStats(true); _activeChar.getStat().recalculateStats(broadcastPacket);
} }
} }

View File

@ -509,7 +509,7 @@ public class InstanceTemplate extends ListenersContainer implements IIdentifiabl
for (L2Playable playable : affected) for (L2Playable playable : affected)
{ {
// Stop all buffs. // 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);
} }
} }
} }

View File

@ -204,7 +204,7 @@ public class Options
if (info.getOption() == this) if (info.getOption() == this)
{ {
player.sendDebugMessage("Removing effects: " + info.getEffects()); player.sendDebugMessage("Removing effects: " + info.getEffects());
player.getEffectList().remove(info, false, true); player.getEffectList().remove(info, false, true, true);
} }
} }
} }

View File

@ -95,7 +95,7 @@ public final class DispelBySlot extends AbstractEffect
final Short abnormalLevel = _dispelAbnormals.get(info.getSkill().getAbnormalType()); final Short abnormalLevel = _dispelAbnormals.get(info.getSkill().getAbnormalType());
return (abnormalLevel != null) && ((abnormalLevel < 0) || (abnormalLevel >= info.getSkill().getAbnormalLvl())); return (abnormalLevel != null) && ((abnormalLevel < 0) || (abnormalLevel >= info.getSkill().getAbnormalLvl()));
}, true); }, true, true);
} }
} }
} }

View File

@ -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. // 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);
} }
} }

View File

@ -98,6 +98,6 @@ public final class DispelBySlotProbability extends AbstractEffect
final Short abnormalLevel = (Rnd.get(100) < _rate) ? _dispelAbnormals.get(info.getSkill().getAbnormalType()) : null; final Short abnormalLevel = (Rnd.get(100) < _rate) ? _dispelAbnormals.get(info.getSkill().getAbnormalType()) : null;
return (abnormalLevel != null) && ((abnormalLevel < 0) || (abnormalLevel >= info.getSkill().getAbnormalLvl())); return (abnormalLevel != null) && ((abnormalLevel < 0) || (abnormalLevel >= info.getSkill().getAbnormalLvl()));
}, true); }, true, true);
} }
} }

View File

@ -76,7 +76,7 @@ public final class StealAbnormal extends AbstractEffect
stolen.setAbnormalTime(infoToSteal.getTime()); // Copy the remaining time. 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. // 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); 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); effector.getEffectList().add(stolen);
} }
} }

View File

@ -491,7 +491,7 @@ public final class Kamaloka extends AbstractInstance
private static final void removeBuffs(L2Character ch) private static final void removeBuffs(L2Character ch)
{ {
// Stop all buffs. // 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);
} }
/** /**

View File

@ -332,10 +332,11 @@ public final class CharEffectList
/** /**
* Exits all effects in this effect list.<br> * Exits all effects in this effect list.<br>
* Stops all the effects, clear the effect lists and updates the effect flags and icons. * 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() 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) if (getToggleCount() > 0)
{ {
// Ignore necessary toggles. // 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) 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. * Stops all active dances/songs skills.
* @param update set to true to update the effect flags and icons * @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) if (_passives != null)
{ {
_passives.forEach(this::remove); _passives.forEach(this::remove);
// Update stats, effect flags and icons. // Update stats, effect flags and icons.
updateEffectList(update); if (update)
{
updateEffectList(broadcast);
}
} }
} }
/** /**
* Stops all active dances/songs skills. * Stops all active dances/songs skills.
* @param update set to true to update the effect flags and icons * @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) if (_options != null)
{ {
_options.forEach(this::remove); _options.forEach(this::remove);
// Update stats, effect flags and icons. // Update stats, effect flags and icons.
updateEffectList(update); if (update)
{
updateEffectList(broadcast);
}
} }
} }
@ -402,7 +411,7 @@ public final class CharEffectList
{ {
if (isAffected(effectFlag)) 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); final BuffInfo info = getBuffInfoBySkillId(skillId);
if (info != null) if (info != null)
{ {
remove(info, removed, true); remove(info, removed, true, true);
} }
} }
@ -454,7 +463,7 @@ public final class CharEffectList
{ {
if (hasAbnormalType(type)) if (hasAbnormalType(type))
{ {
stopEffects(i -> i.isAbnormalType(type), true); stopEffects(i -> i.isAbnormalType(type), true, true);
return true; return true;
} }
@ -470,7 +479,7 @@ public final class CharEffectList
{ {
if (hasAbnormalType(types)) if (hasAbnormalType(types))
{ {
stopEffects(i -> types.contains(i.getSkill().getAbnormalType()), true); stopEffects(i -> types.contains(i.getSkill().getAbnormalType()), true, true);
return true; return true;
} }
@ -481,15 +490,19 @@ public final class CharEffectList
* Exits all effects matched by a specific filter.<br> * Exits all effects matched by a specific filter.<br>
* @param filter any filter to apply when selecting which {@code BuffInfo}s to be removed. * @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 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<BuffInfo> filter, boolean update) public void stopEffects(Predicate<BuffInfo> filter, boolean update, boolean broadcast)
{ {
if (_actives != null) if (_actives != null)
{ {
_actives.stream().filter(filter).forEach(this::remove); _actives.stream().filter(filter).forEach(this::remove);
// Update stats, effect flags and icons. // Update stats, effect flags and icons.
updateEffectList(update); if (update)
{
updateEffectList(broadcast);
}
} }
} }
@ -501,7 +514,7 @@ public final class CharEffectList
{ {
if (_hasBuffsRemovedOnAnyAction.intValue() > 0) 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) 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) 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 info the effects to remove
* @param removed {@code true} if the effect is removed, {@code false} otherwise * @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 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) if (info == null)
{ {
@ -659,7 +673,10 @@ public final class CharEffectList
} }
// Update stats, effect flags and icons. // Update stats, effect flags and icons.
updateEffectList(update); if (update)
{
updateEffectList(broadcast);
}
} }
/** /**
@ -1070,11 +1087,9 @@ public final class CharEffectList
/** /**
* Wrapper to update abnormal icons and effect flags. * 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. // Create new empty flags.
long flags = 0; long flags = 0;
@ -1136,8 +1151,10 @@ public final class CharEffectList
}); });
// Recalculate all stats // Recalculate all stats
_owner.getStat().recalculateStats(true); _owner.getStat().recalculateStats(broadcast);
if (broadcast)
{
// Check if there is change in AbnormalVisualEffect // Check if there is change in AbnormalVisualEffect
if ((abnormalVisualEffectFlags.size() != _abnormalVisualEffects.size()) || !abnormalVisualEffectFlags.containsAll(_abnormalVisualEffects)) if ((abnormalVisualEffectFlags.size() != _abnormalVisualEffects.size()) || !abnormalVisualEffectFlags.containsAll(_abnormalVisualEffects))
{ {

View File

@ -1950,8 +1950,8 @@ public abstract class L2Character extends L2Object implements ISkillsHolder, IDe
getSummoner().removeSummonedNpc(getObjectId()); getSummoner().removeSummonedNpc(getObjectId());
} }
// Remove all effects // Remove all effects, do not broadcast changes.
_effectList.stopAllEffects(); _effectList.stopAllEffects(false);
// Cancel all timers related to this Creature // Cancel all timers related to this Creature
TimersManager.getInstance().cancelTimers(getObjectId()); TimersManager.getInstance().cancelTimers(getObjectId());
@ -2554,7 +2554,7 @@ public abstract class L2Character extends L2Object implements ISkillsHolder, IDe
*/ */
public void stopAllEffects() public void stopAllEffects()
{ {
_effectList.stopAllEffects(); _effectList.stopAllEffects(true);
} }
/** /**

View File

@ -997,8 +997,8 @@ public class L2Npc extends L2Character
*/ */
public void onRespawn() public void onRespawn()
{ {
// Stop all effects // Stop all effects and recalculate stats without broadcasting.
stopAllEffects(); getEffectList().stopAllEffects(false);
// Make it alive // Make it alive
setIsDead(false); setIsDead(false);
@ -1006,11 +1006,9 @@ public class L2Npc extends L2Character
// Reset decay info // Reset decay info
setDecayed(false); setDecayed(false);
// Recalculate npcs stats // Fully heal npc and don't broadcast packet.
getStat().recalculateStats(true); setCurrentHp(getMaxHp(), false);
setCurrentMp(getMaxMp(), false);
// Set the HP and MP of the L2NpcInstance to the max
setCurrentHpMp(getMaxHp(), getMaxMp());
// Clear script variables // Clear script variables
if (hasVariables()) if (hasVariables())

View File

@ -10634,9 +10634,9 @@ public final class L2PcInstance extends L2Playable
cleanup(); cleanup();
storeMe(); storeMe();
// Stop all passives and augment options // Stop all passives and augment options without broadcasting changes.
getEffectList().stopAllPassives(false); getEffectList().stopAllPassives(false, false);
getEffectList().stopAllOptions(false); getEffectList().stopAllOptions(false, false);
return super.deleteMe(); return super.deleteMe();
} }

View File

@ -331,7 +331,7 @@ public class CharStatus
{ {
if (_previousHpPercent.compareAndSet(lastHpPercent, currentHpPercent)) if (_previousHpPercent.compareAndSet(lastHpPercent, currentHpPercent))
{ {
_activeChar.getStat().recalculateStats(true); _activeChar.getStat().recalculateStats(broadcastPacket);
} }
} }

View File

@ -509,7 +509,7 @@ public class InstanceTemplate extends ListenersContainer implements IIdentifiabl
for (L2Playable playable : affected) for (L2Playable playable : affected)
{ {
// Stop all buffs. // 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);
} }
} }
} }

View File

@ -204,7 +204,7 @@ public class Options
if (info.getOption() == this) if (info.getOption() == this)
{ {
player.sendDebugMessage("Removing effects: " + info.getEffects()); player.sendDebugMessage("Removing effects: " + info.getEffects());
player.getEffectList().remove(info, false, true); player.getEffectList().remove(info, false, true, true);
} }
} }
} }

View File

@ -95,7 +95,7 @@ public final class DispelBySlot extends AbstractEffect
final Short abnormalLevel = _dispelAbnormals.get(info.getSkill().getAbnormalType()); final Short abnormalLevel = _dispelAbnormals.get(info.getSkill().getAbnormalType());
return (abnormalLevel != null) && ((abnormalLevel < 0) || (abnormalLevel >= info.getSkill().getAbnormalLvl())); return (abnormalLevel != null) && ((abnormalLevel < 0) || (abnormalLevel >= info.getSkill().getAbnormalLvl()));
}, true); }, true, true);
} }
} }
} }

View File

@ -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. // 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);
} }
} }

View File

@ -98,6 +98,6 @@ public final class DispelBySlotProbability extends AbstractEffect
final Short abnormalLevel = (Rnd.get(100) < _rate) ? _dispelAbnormals.get(info.getSkill().getAbnormalType()) : null; final Short abnormalLevel = (Rnd.get(100) < _rate) ? _dispelAbnormals.get(info.getSkill().getAbnormalType()) : null;
return (abnormalLevel != null) && ((abnormalLevel < 0) || (abnormalLevel >= info.getSkill().getAbnormalLvl())); return (abnormalLevel != null) && ((abnormalLevel < 0) || (abnormalLevel >= info.getSkill().getAbnormalLvl()));
}, true); }, true, true);
} }
} }

View File

@ -76,7 +76,7 @@ public final class StealAbnormal extends AbstractEffect
stolen.setAbnormalTime(infoToSteal.getTime()); // Copy the remaining time. 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. // 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); 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); effector.getEffectList().add(stolen);
} }
} }

View File

@ -332,10 +332,11 @@ public final class CharEffectList
/** /**
* Exits all effects in this effect list.<br> * Exits all effects in this effect list.<br>
* Stops all the effects, clear the effect lists and updates the effect flags and icons. * 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() 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) if (getToggleCount() > 0)
{ {
// Ignore necessary toggles. // 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) 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. * Stops all active dances/songs skills.
* @param update set to true to update the effect flags and icons * @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) if (_passives != null)
{ {
_passives.forEach(this::remove); _passives.forEach(this::remove);
// Update stats, effect flags and icons. // Update stats, effect flags and icons.
updateEffectList(update); if (update)
{
updateEffectList(broadcast);
}
} }
} }
/** /**
* Stops all active dances/songs skills. * Stops all active dances/songs skills.
* @param update set to true to update the effect flags and icons * @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) if (_options != null)
{ {
_options.forEach(this::remove); _options.forEach(this::remove);
// Update stats, effect flags and icons. // Update stats, effect flags and icons.
updateEffectList(update); if (update)
{
updateEffectList(broadcast);
}
} }
} }
@ -402,7 +411,7 @@ public final class CharEffectList
{ {
if (isAffected(effectFlag)) 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); final BuffInfo info = getBuffInfoBySkillId(skillId);
if (info != null) if (info != null)
{ {
remove(info, removed, true); remove(info, removed, true, true);
} }
} }
@ -454,7 +463,7 @@ public final class CharEffectList
{ {
if (hasAbnormalType(type)) if (hasAbnormalType(type))
{ {
stopEffects(i -> i.isAbnormalType(type), true); stopEffects(i -> i.isAbnormalType(type), true, true);
return true; return true;
} }
@ -470,7 +479,7 @@ public final class CharEffectList
{ {
if (hasAbnormalType(types)) if (hasAbnormalType(types))
{ {
stopEffects(i -> types.contains(i.getSkill().getAbnormalType()), true); stopEffects(i -> types.contains(i.getSkill().getAbnormalType()), true, true);
return true; return true;
} }
@ -481,15 +490,19 @@ public final class CharEffectList
* Exits all effects matched by a specific filter.<br> * Exits all effects matched by a specific filter.<br>
* @param filter any filter to apply when selecting which {@code BuffInfo}s to be removed. * @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 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<BuffInfo> filter, boolean update) public void stopEffects(Predicate<BuffInfo> filter, boolean update, boolean broadcast)
{ {
if (_actives != null) if (_actives != null)
{ {
_actives.stream().filter(filter).forEach(this::remove); _actives.stream().filter(filter).forEach(this::remove);
// Update stats, effect flags and icons. // Update stats, effect flags and icons.
updateEffectList(update); if (update)
{
updateEffectList(broadcast);
}
} }
} }
@ -501,7 +514,7 @@ public final class CharEffectList
{ {
if (_hasBuffsRemovedOnAnyAction.intValue() > 0) 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) 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) 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 info the effects to remove
* @param removed {@code true} if the effect is removed, {@code false} otherwise * @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 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) if (info == null)
{ {
@ -659,7 +673,10 @@ public final class CharEffectList
} }
// Update stats, effect flags and icons. // Update stats, effect flags and icons.
updateEffectList(update); if (update)
{
updateEffectList(broadcast);
}
} }
/** /**
@ -1070,11 +1087,9 @@ public final class CharEffectList
/** /**
* Wrapper to update abnormal icons and effect flags. * 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. // Create new empty flags.
long flags = 0; long flags = 0;
@ -1136,8 +1151,10 @@ public final class CharEffectList
}); });
// Recalculate all stats // Recalculate all stats
_owner.getStat().recalculateStats(true); _owner.getStat().recalculateStats(broadcast);
if (broadcast)
{
// Check if there is change in AbnormalVisualEffect // Check if there is change in AbnormalVisualEffect
if ((abnormalVisualEffectFlags.size() != _abnormalVisualEffects.size()) || !abnormalVisualEffectFlags.containsAll(_abnormalVisualEffects)) if ((abnormalVisualEffectFlags.size() != _abnormalVisualEffects.size()) || !abnormalVisualEffectFlags.containsAll(_abnormalVisualEffects))
{ {

View File

@ -1950,8 +1950,8 @@ public abstract class L2Character extends L2Object implements ISkillsHolder, IDe
getSummoner().removeSummonedNpc(getObjectId()); getSummoner().removeSummonedNpc(getObjectId());
} }
// Remove all effects // Remove all effects, do not broadcast changes.
_effectList.stopAllEffects(); _effectList.stopAllEffects(false);
// Cancel all timers related to this Creature // Cancel all timers related to this Creature
TimersManager.getInstance().cancelTimers(getObjectId()); TimersManager.getInstance().cancelTimers(getObjectId());
@ -2554,7 +2554,7 @@ public abstract class L2Character extends L2Object implements ISkillsHolder, IDe
*/ */
public void stopAllEffects() public void stopAllEffects()
{ {
_effectList.stopAllEffects(); _effectList.stopAllEffects(true);
} }
/** /**

View File

@ -997,8 +997,8 @@ public class L2Npc extends L2Character
*/ */
public void onRespawn() public void onRespawn()
{ {
// Stop all effects // Stop all effects and recalculate stats without broadcasting.
stopAllEffects(); getEffectList().stopAllEffects(false);
// Make it alive // Make it alive
setIsDead(false); setIsDead(false);
@ -1006,11 +1006,9 @@ public class L2Npc extends L2Character
// Reset decay info // Reset decay info
setDecayed(false); setDecayed(false);
// Recalculate npcs stats // Fully heal npc and don't broadcast packet.
getStat().recalculateStats(true); setCurrentHp(getMaxHp(), false);
setCurrentMp(getMaxMp(), false);
// Set the HP and MP of the L2NpcInstance to the max
setCurrentHpMp(getMaxHp(), getMaxMp());
// Clear script variables // Clear script variables
if (hasVariables()) if (hasVariables())

View File

@ -10596,9 +10596,9 @@ public final class L2PcInstance extends L2Playable
cleanup(); cleanup();
storeMe(); storeMe();
// Stop all passives and augment options // Stop all passives and augment options without broadcasting changes.
getEffectList().stopAllPassives(false); getEffectList().stopAllPassives(false, false);
getEffectList().stopAllOptions(false); getEffectList().stopAllOptions(false, false);
return super.deleteMe(); return super.deleteMe();
} }

View File

@ -331,7 +331,7 @@ public class CharStatus
{ {
if (_previousHpPercent.compareAndSet(lastHpPercent, currentHpPercent)) if (_previousHpPercent.compareAndSet(lastHpPercent, currentHpPercent))
{ {
_activeChar.getStat().recalculateStats(true); _activeChar.getStat().recalculateStats(broadcastPacket);
} }
} }

View File

@ -509,7 +509,7 @@ public class InstanceTemplate extends ListenersContainer implements IIdentifiabl
for (L2Playable playable : affected) for (L2Playable playable : affected)
{ {
// Stop all buffs. // 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);
} }
} }
} }

View File

@ -204,7 +204,7 @@ public class Options
if (info.getOption() == this) if (info.getOption() == this)
{ {
player.sendDebugMessage("Removing effects: " + info.getEffects()); player.sendDebugMessage("Removing effects: " + info.getEffects());
player.getEffectList().remove(info, false, true); player.getEffectList().remove(info, false, true, true);
} }
} }
} }