Abnormal improvements.

This commit is contained in:
MobiusDev
2018-11-01 16:51:03 +00:00
parent bd7da50452
commit d35a9d46ec
90 changed files with 929 additions and 1632 deletions

View File

@ -16,6 +16,8 @@
*/
package handlers.effecthandlers;
import java.util.Collections;
import com.l2jmobius.gameserver.model.L2Object;
import com.l2jmobius.gameserver.model.L2World;
import com.l2jmobius.gameserver.model.StatsSet;
@ -38,6 +40,19 @@ public final class CallSkillOnActionTime extends AbstractEffect
setTicks(params.getInt("ticks"));
}
@Override
public void onStart(L2Character effector, L2Character effected, Skill skill)
{
effected.getEffectList().stopEffects(Collections.singleton(_skill.getSkill().getAbnormalType()));
effected.getEffectList().addBlockedAbnormalTypes(Collections.singleton(_skill.getSkill().getAbnormalType()));
}
@Override
public void onExit(L2Character effector, L2Character effected, Skill skill)
{
effected.getEffectList().removeBlockedAbnormalTypes(Collections.singleton(_skill.getSkill().getAbnormalType()));
}
@Override
public boolean onActionTime(L2Character effector, L2Character effected, Skill skill)
{

View File

@ -136,6 +136,5 @@ public final class Disarmor extends AbstractEffect
}
}
}
super.onExit(effector, effected, skill);
}
}

View File

@ -84,6 +84,5 @@ public final class DoubleCast extends AbstractEffect
return null;
});
}
super.onExit(effector, effected, skill);
}
}

View File

@ -65,15 +65,15 @@ public final class CharEffectList
{
private static final Logger LOGGER = Logger.getLogger(CharEffectList.class.getName());
/** Queue containing all effects from buffs for this effect list. */
private volatile Queue<BuffInfo> _actives;
private volatile Queue<BuffInfo> _actives = new ConcurrentLinkedQueue<>();
/** List containing all passives for this effect list. They bypass most of the actions and they are not included in most operations. */
private volatile Set<BuffInfo> _passives;
private volatile Set<BuffInfo> _passives = ConcurrentHashMap.newKeySet();
/** List containing all options for this effect list. They bypass most of the actions and they are not included in most operations. */
private volatile Set<BuffInfo> _options;
private volatile Set<BuffInfo> _options = ConcurrentHashMap.newKeySet();
/** Map containing the all stacked effect in progress for each {@code AbnormalType}. */
private volatile Set<AbnormalType> _stackedEffects = EnumSet.noneOf(AbnormalType.class);
/** Set containing all {@code AbnormalType}s that shouldn't be added to this creature effect list. */
private volatile Set<AbnormalType> _blockedAbnormalTypes = null;
private volatile Set<AbnormalType> _blockedAbnormalTypes = EnumSet.noneOf(AbnormalType.class);
/** Set containing all abnormal visual effects this creature currently displays. */
private volatile Set<AbnormalVisualEffect> _abnormalVisualEffects = EnumSet.noneOf(AbnormalVisualEffect.class);
/** Short buff skill ID. */
@ -110,7 +110,7 @@ public final class CharEffectList
*/
public Set<BuffInfo> getPassives()
{
return _passives != null ? Collections.unmodifiableSet(_passives) : Collections.emptySet();
return Collections.unmodifiableSet(_passives);
}
/**
@ -119,7 +119,7 @@ public final class CharEffectList
*/
public Set<BuffInfo> getOptions()
{
return _options != null ? Collections.unmodifiableSet(_options) : Collections.emptySet();
return Collections.unmodifiableSet(_options);
}
/**
@ -128,7 +128,7 @@ public final class CharEffectList
*/
public Collection<BuffInfo> getEffects()
{
return _actives != null ? Collections.unmodifiableCollection(_actives) : Collections.emptyList();
return Collections.unmodifiableCollection(_actives);
}
/**
@ -137,7 +137,7 @@ public final class CharEffectList
*/
public List<BuffInfo> getBuffs()
{
return _actives != null ? _actives.stream().filter(b -> !b.getSkill().getBuffType().isBuff()).collect(Collectors.toList()) : Collections.emptyList();
return _actives.stream().filter(b -> !b.getSkill().getBuffType().isBuff()).collect(Collectors.toList());
}
/**
@ -146,7 +146,7 @@ public final class CharEffectList
*/
public List<BuffInfo> getDebuffs()
{
return _actives != null ? _actives.stream().filter(b -> b.getSkill().isDebuff()).collect(Collectors.toList()) : Collections.emptyList();
return _actives.stream().filter(b -> b.getSkill().isDebuff()).collect(Collectors.toList());
}
/**
@ -156,7 +156,7 @@ public final class CharEffectList
*/
public boolean isAffectedBySkill(int skillId)
{
return ((_actives != null) && _actives.stream().anyMatch(i -> i.getSkill().getId() == skillId)) || ((_passives != null) && _passives.stream().anyMatch(i -> i.getSkill().getId() == skillId));
return (_actives.stream().anyMatch(i -> i.getSkill().getId() == skillId)) || (_passives.stream().anyMatch(i -> i.getSkill().getId() == skillId));
}
/**
@ -166,7 +166,7 @@ public final class CharEffectList
*/
public BuffInfo getBuffInfoBySkillId(int skillId)
{
return Stream.concat(_actives != null ? _actives.stream() : Stream.empty(), _passives != null ? _passives.stream() : Stream.empty()).filter(b -> b.getSkill().getId() == skillId).findFirst().orElse(null);
return Stream.concat(_actives.stream(), _passives.stream()).filter(b -> b.getSkill().getId() == skillId).findFirst().orElse(null);
}
/**
@ -216,18 +216,6 @@ public final class CharEffectList
*/
public void addBlockedAbnormalTypes(Set<AbnormalType> blockedAbnormalTypes)
{
// Initialize
if (_blockedAbnormalTypes == null)
{
synchronized (this)
{
if (_blockedAbnormalTypes == null)
{
_blockedAbnormalTypes = EnumSet.copyOf(blockedAbnormalTypes);
}
}
}
_blockedAbnormalTypes.addAll(blockedAbnormalTypes);
}
@ -238,7 +226,7 @@ public final class CharEffectList
*/
public boolean removeBlockedAbnormalTypes(Set<AbnormalType> blockedBuffSlots)
{
return (_blockedAbnormalTypes != null) && _blockedAbnormalTypes.removeAll(blockedBuffSlots);
return _blockedAbnormalTypes.removeAll(blockedBuffSlots);
}
/**
@ -247,7 +235,7 @@ public final class CharEffectList
*/
public Set<AbnormalType> getBlockedAbnormalTypes()
{
return _blockedAbnormalTypes != null ? Collections.unmodifiableSet(_blockedAbnormalTypes) : Collections.emptySet();
return Collections.unmodifiableSet(_blockedAbnormalTypes);
}
/**
@ -277,7 +265,7 @@ public final class CharEffectList
*/
public int getBuffCount()
{
return _actives != null ? (_buffCount.get() - _hiddenBuffs.get()) : 0;
return !_actives.isEmpty() ? (_buffCount.get() - _hiddenBuffs.get()) : 0;
}
/**
@ -374,7 +362,7 @@ public final class CharEffectList
*/
public void stopAllPassives(boolean update, boolean broadcast)
{
if (_passives != null)
if (!_passives.isEmpty())
{
_passives.forEach(this::remove);
// Update stats, effect flags and icons.
@ -392,7 +380,7 @@ public final class CharEffectList
*/
public void stopAllOptions(boolean update, boolean broadcast)
{
if (_options != null)
if (!_options.isEmpty())
{
_options.forEach(this::remove);
// Update stats, effect flags and icons.
@ -490,7 +478,7 @@ public final class CharEffectList
*/
public void stopEffects(Predicate<BuffInfo> filter, boolean update, boolean broadcast)
{
if (_actives != null)
if (!_actives.isEmpty())
{
_actives.stream().filter(filter).forEach(this::remove);
@ -678,6 +666,10 @@ public final class CharEffectList
{
// Remove active effect.
removeActive(info, removed);
if (_owner.isNpc()) // Fix for all NPC debuff animations removed.
{
updateEffectList(broadcast);
}
}
// Update stats, effect flags and icons.
@ -693,7 +685,7 @@ public final class CharEffectList
*/
private synchronized void removeActive(BuffInfo info, boolean removed)
{
if (_actives != null)
if (!_actives.isEmpty())
{
// Removes the buff from the given effect list.
_actives.remove(info);
@ -716,7 +708,7 @@ public final class CharEffectList
private void removePassive(BuffInfo info, boolean removed)
{
if (_passives != null)
if (!_passives.isEmpty())
{
_passives.remove(info);
info.stopAllEffects(removed);
@ -725,7 +717,7 @@ public final class CharEffectList
private void removeOption(BuffInfo info, boolean removed)
{
if (_options != null)
if (!_options.isEmpty())
{
_options.remove(info);
info.stopAllEffects(removed);
@ -821,12 +813,6 @@ public final class CharEffectList
}
}
// Initialize
if (_actives == null)
{
_actives = new ConcurrentLinkedQueue<>();
}
// Manage effect stacking.
if (hasAbnormalType(skill.getAbnormalType()))
{
@ -857,7 +843,7 @@ public final class CharEffectList
}
else
{
// Remove effect that gets overriden.
// Remove effect that gets overridden.
remove(existingInfo);
}
}
@ -865,7 +851,7 @@ public final class CharEffectList
{
info.setInUse(false);
}
else // The effect we try to add should be overriden.
else // The effect we try to add should be overridden.
{
return;
}
@ -918,18 +904,6 @@ public final class CharEffectList
return;
}
// Initialize
if (_passives == null)
{
synchronized (this)
{
if (_passives == null)
{
_passives = ConcurrentHashMap.newKeySet();
}
}
}
// Remove previous passives of this id.
_passives.stream().filter(Objects::nonNull).filter(b -> b.getSkill().getId() == skill.getId()).forEach(b ->
{
@ -947,18 +921,6 @@ public final class CharEffectList
{
if (info.getOption() != null)
{
// Initialize
if (_options == null)
{
synchronized (this)
{
if (_options == null)
{
_options = ConcurrentHashMap.newKeySet();
}
}
}
// Remove previous options of this id.
_options.stream().filter(Objects::nonNull).filter(b -> b.getOption().getId() == info.getOption().getId()).forEach(b ->
{
@ -988,7 +950,7 @@ public final class CharEffectList
final Optional<PartySpelled> ps = ((party != null) || _owner.isSummon()) ? Optional.of(new PartySpelled(_owner)) : Optional.empty();
final Optional<ExOlympiadSpelledInfo> os = (player.isInOlympiadMode() && player.isOlympiadStart()) ? Optional.of(new ExOlympiadSpelledInfo(player)) : Optional.empty();
if (_actives != null)
if (!_actives.isEmpty())
{
//@formatter:off
_actives.stream()
@ -1109,8 +1071,6 @@ public final class CharEffectList
final Set<BuffInfo> unhideBuffs = new HashSet<>();
// Recalculate new flags
if (_actives != null)
{
for (BuffInfo info : _actives)
{
if (info != null)
@ -1144,7 +1104,14 @@ public final class CharEffectList
// Add AbnormalVisualEffect flag.
if (skill.hasAbnormalVisualEffects())
{
abnormalVisualEffectFlags.addAll(skill.getAbnormalVisualEffects());
for (AbnormalVisualEffect ave : skill.getAbnormalVisualEffects())
{
abnormalVisualEffectFlags.add(ave);
_abnormalVisualEffects.add(ave);
}
if (broadcast)
{
_owner.updateAbnormalVisualEffects();
}
}
}
@ -1167,7 +1134,7 @@ public final class CharEffectList
if (broadcast)
{
// Check if there is change in AbnormalVisualEffect
if ((abnormalVisualEffectFlags.size() != _abnormalVisualEffects.size()) || !abnormalVisualEffectFlags.containsAll(_abnormalVisualEffects))
if (!abnormalVisualEffectFlags.containsAll(_abnormalVisualEffects))
{
_abnormalVisualEffects = abnormalVisualEffectFlags;
_owner.updateAbnormalVisualEffects();

View File

@ -77,7 +77,6 @@ public class DoppelgangerInstance extends L2Npc
info.setAbnormalTime(summonerInfo.getAbnormalTime());
getEffectList().add(info);
}
}
}
}

View File

@ -786,7 +786,7 @@ public class CharStat
final CharEffectList effectList = _activeChar.getEffectList();
final Stream<BuffInfo> passives = effectList.getPassives().stream().filter(BuffInfo::isInUse).filter(info -> info.getSkill().checkConditions(SkillConditionScope.PASSIVE, _activeChar, _activeChar));
final Stream<BuffInfo> options = effectList.getOptions().stream().filter(BuffInfo::isInUse);
final Stream<BuffInfo> effectsStream = Stream.concat(effectList.getEffects().stream().filter(BuffInfo::isInUse), Stream.concat(passives != null ? passives : Stream.empty(), options != null ? options : Stream.empty()));
final Stream<BuffInfo> effectsStream = Stream.concat(effectList.getEffects().stream().filter(BuffInfo::isInUse), Stream.concat(passives, options));
// Call pump to each effect
//@formatter:off

View File

@ -389,10 +389,10 @@ public final class BuffInfo
for (AbstractEffect effect : _effects)
{
// Instant effects shouldn't call onExit(..).
if (!effect.isInstant())
{
// if (!effect.isInstant())
// {
effect.onExit(_effector, _effected, _skill);
}
// }
}
// Set the proper system message.

View File

@ -21,13 +21,11 @@ import java.util.List;
import com.l2jmobius.commons.network.PacketWriter;
import com.l2jmobius.gameserver.model.skills.BuffInfo;
import com.l2jmobius.gameserver.model.skills.Skill;
import com.l2jmobius.gameserver.network.OutgoingPackets;
public class AbnormalStatusUpdate implements IClientOutgoingPacket
{
private final List<BuffInfo> _effects = new ArrayList<>();
private final List<Skill> _effects2 = new ArrayList<>();
public void addSkill(BuffInfo info)
{
@ -37,20 +35,12 @@ public class AbnormalStatusUpdate implements IClientOutgoingPacket
}
}
public void addSkill(Skill skill)
{
if (!skill.isHealingPotionSkill())
{
_effects2.add(skill);
}
}
@Override
public boolean write(PacketWriter packet)
{
OutgoingPackets.ABNORMAL_STATUS_UPDATE.writeId(packet);
packet.writeH(_effects.size() + _effects2.size());
packet.writeH(_effects.size());
for (BuffInfo info : _effects)
{
if ((info != null) && info.isInUse())
@ -62,17 +52,6 @@ public class AbnormalStatusUpdate implements IClientOutgoingPacket
writeOptionalD(packet, info.getSkill().isAura() ? -1 : info.getTime());
}
}
for (Skill skill : _effects2)
{
if (skill != null)
{
packet.writeD(skill.getDisplayId());
packet.writeH(skill.getDisplayLevel());
// packet.writeH(0x00); // Sub level
packet.writeD(skill.getAbnormalType().getClientId());
packet.writeH(-1);
}
}
return true;
}
}

View File

@ -16,7 +16,6 @@
*/
package com.l2jmobius.gameserver.network.serverpackets;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
@ -24,40 +23,12 @@ import java.util.stream.Collectors;
import com.l2jmobius.commons.network.PacketWriter;
import com.l2jmobius.gameserver.model.actor.L2Character;
import com.l2jmobius.gameserver.model.skills.BuffInfo;
import com.l2jmobius.gameserver.model.skills.Skill;
import com.l2jmobius.gameserver.network.OutgoingPackets;
public class ExAbnormalStatusUpdateFromTarget implements IClientOutgoingPacket
{
private final L2Character _character;
private List<Effect> _effects = new ArrayList<>();
private static class Effect
{
protected int _skillId;
protected int _level;
protected int _abnormalType;
protected int _duration;
protected int _caster;
public Effect(BuffInfo info)
{
final Skill skill = info.getSkill();
final L2Character caster = info.getEffector();
int casterId = 0;
if (caster != null)
{
casterId = caster.getObjectId();
}
_skillId = skill.getDisplayId();
_level = skill.getDisplayLevel();
// _subLevel = skill.getSubLevel();
_abnormalType = skill.getAbnormalType().getClientId();
_duration = skill.isAura() ? -1 : info.getTime();
_caster = casterId;
}
}
private final List<BuffInfo> _effects;
public ExAbnormalStatusUpdateFromTarget(L2Character character)
{
@ -68,7 +39,6 @@ public class ExAbnormalStatusUpdateFromTarget implements IClientOutgoingPacket
.filter(Objects::nonNull)
.filter(BuffInfo::isInUse)
.filter(b -> !b.getSkill().isToggle())
.map(Effect::new)
.collect(Collectors.toList());
//@formatter:on
}
@ -81,13 +51,15 @@ public class ExAbnormalStatusUpdateFromTarget implements IClientOutgoingPacket
packet.writeD(_character.getObjectId());
packet.writeH(_effects.size());
for (Effect info : _effects)
for (BuffInfo info : _effects)
{
packet.writeD(info._skillId);
packet.writeH(info._level);
packet.writeH(info._abnormalType);
packet.writeH(info._duration);
packet.writeD(info._caster);
packet.writeD(info.getSkill().getDisplayId());
packet.writeH(info.getSkill().getDisplayLevel());
// packet.writeH(info.getSkill().getSubLevel());
packet.writeH(info.getSkill().getAbnormalType().getClientId());
// writeOptionalD(packet, info.getSkill().isAura() ? -1 : info.getTime());
packet.writeH(info.getSkill().isAura() ? -1 : info.getTime());
packet.writeD(info.getEffectorObjectId());
}
return true;
}

View File

@ -16,6 +16,8 @@
*/
package handlers.effecthandlers;
import java.util.Collections;
import com.l2jmobius.gameserver.model.L2Object;
import com.l2jmobius.gameserver.model.L2World;
import com.l2jmobius.gameserver.model.StatsSet;
@ -38,6 +40,19 @@ public final class CallSkillOnActionTime extends AbstractEffect
setTicks(params.getInt("ticks"));
}
@Override
public void onStart(L2Character effector, L2Character effected, Skill skill)
{
effected.getEffectList().stopEffects(Collections.singleton(_skill.getSkill().getAbnormalType()));
effected.getEffectList().addBlockedAbnormalTypes(Collections.singleton(_skill.getSkill().getAbnormalType()));
}
@Override
public void onExit(L2Character effector, L2Character effected, Skill skill)
{
effected.getEffectList().removeBlockedAbnormalTypes(Collections.singleton(_skill.getSkill().getAbnormalType()));
}
@Override
public boolean onActionTime(L2Character effector, L2Character effected, Skill skill)
{

View File

@ -136,6 +136,5 @@ public final class Disarmor extends AbstractEffect
}
}
}
super.onExit(effector, effected, skill);
}
}

View File

@ -84,6 +84,5 @@ public final class DoubleCast extends AbstractEffect
return null;
});
}
super.onExit(effector, effected, skill);
}
}

View File

@ -65,15 +65,15 @@ public final class CharEffectList
{
private static final Logger LOGGER = Logger.getLogger(CharEffectList.class.getName());
/** Queue containing all effects from buffs for this effect list. */
private volatile Queue<BuffInfo> _actives;
private volatile Queue<BuffInfo> _actives = new ConcurrentLinkedQueue<>();
/** List containing all passives for this effect list. They bypass most of the actions and they are not included in most operations. */
private volatile Set<BuffInfo> _passives;
private volatile Set<BuffInfo> _passives = ConcurrentHashMap.newKeySet();
/** List containing all options for this effect list. They bypass most of the actions and they are not included in most operations. */
private volatile Set<BuffInfo> _options;
private volatile Set<BuffInfo> _options = ConcurrentHashMap.newKeySet();
/** Map containing the all stacked effect in progress for each {@code AbnormalType}. */
private volatile Set<AbnormalType> _stackedEffects = EnumSet.noneOf(AbnormalType.class);
/** Set containing all {@code AbnormalType}s that shouldn't be added to this creature effect list. */
private volatile Set<AbnormalType> _blockedAbnormalTypes = null;
private volatile Set<AbnormalType> _blockedAbnormalTypes = EnumSet.noneOf(AbnormalType.class);
/** Set containing all abnormal visual effects this creature currently displays. */
private volatile Set<AbnormalVisualEffect> _abnormalVisualEffects = EnumSet.noneOf(AbnormalVisualEffect.class);
/** Short buff skill ID. */
@ -110,7 +110,7 @@ public final class CharEffectList
*/
public Set<BuffInfo> getPassives()
{
return _passives != null ? Collections.unmodifiableSet(_passives) : Collections.emptySet();
return Collections.unmodifiableSet(_passives);
}
/**
@ -119,7 +119,7 @@ public final class CharEffectList
*/
public Set<BuffInfo> getOptions()
{
return _options != null ? Collections.unmodifiableSet(_options) : Collections.emptySet();
return Collections.unmodifiableSet(_options);
}
/**
@ -128,7 +128,7 @@ public final class CharEffectList
*/
public Collection<BuffInfo> getEffects()
{
return _actives != null ? Collections.unmodifiableCollection(_actives) : Collections.emptyList();
return Collections.unmodifiableCollection(_actives);
}
/**
@ -137,7 +137,7 @@ public final class CharEffectList
*/
public List<BuffInfo> getBuffs()
{
return _actives != null ? _actives.stream().filter(b -> !b.getSkill().getBuffType().isBuff()).collect(Collectors.toList()) : Collections.emptyList();
return _actives.stream().filter(b -> !b.getSkill().getBuffType().isBuff()).collect(Collectors.toList());
}
/**
@ -146,7 +146,7 @@ public final class CharEffectList
*/
public List<BuffInfo> getDebuffs()
{
return _actives != null ? _actives.stream().filter(b -> b.getSkill().isDebuff()).collect(Collectors.toList()) : Collections.emptyList();
return _actives.stream().filter(b -> b.getSkill().isDebuff()).collect(Collectors.toList());
}
/**
@ -156,7 +156,7 @@ public final class CharEffectList
*/
public boolean isAffectedBySkill(int skillId)
{
return ((_actives != null) && _actives.stream().anyMatch(i -> i.getSkill().getId() == skillId)) || ((_passives != null) && _passives.stream().anyMatch(i -> i.getSkill().getId() == skillId));
return (_actives.stream().anyMatch(i -> i.getSkill().getId() == skillId)) || (_passives.stream().anyMatch(i -> i.getSkill().getId() == skillId));
}
/**
@ -166,7 +166,7 @@ public final class CharEffectList
*/
public BuffInfo getBuffInfoBySkillId(int skillId)
{
return Stream.concat(_actives != null ? _actives.stream() : Stream.empty(), _passives != null ? _passives.stream() : Stream.empty()).filter(b -> b.getSkill().getId() == skillId).findFirst().orElse(null);
return Stream.concat(_actives.stream(), _passives.stream()).filter(b -> b.getSkill().getId() == skillId).findFirst().orElse(null);
}
/**
@ -216,18 +216,6 @@ public final class CharEffectList
*/
public void addBlockedAbnormalTypes(Set<AbnormalType> blockedAbnormalTypes)
{
// Initialize
if (_blockedAbnormalTypes == null)
{
synchronized (this)
{
if (_blockedAbnormalTypes == null)
{
_blockedAbnormalTypes = EnumSet.copyOf(blockedAbnormalTypes);
}
}
}
_blockedAbnormalTypes.addAll(blockedAbnormalTypes);
}
@ -238,7 +226,7 @@ public final class CharEffectList
*/
public boolean removeBlockedAbnormalTypes(Set<AbnormalType> blockedBuffSlots)
{
return (_blockedAbnormalTypes != null) && _blockedAbnormalTypes.removeAll(blockedBuffSlots);
return _blockedAbnormalTypes.removeAll(blockedBuffSlots);
}
/**
@ -247,7 +235,7 @@ public final class CharEffectList
*/
public Set<AbnormalType> getBlockedAbnormalTypes()
{
return _blockedAbnormalTypes != null ? Collections.unmodifiableSet(_blockedAbnormalTypes) : Collections.emptySet();
return Collections.unmodifiableSet(_blockedAbnormalTypes);
}
/**
@ -277,7 +265,7 @@ public final class CharEffectList
*/
public int getBuffCount()
{
return _actives != null ? (_buffCount.get() - _hiddenBuffs.get()) : 0;
return !_actives.isEmpty() ? (_buffCount.get() - _hiddenBuffs.get()) : 0;
}
/**
@ -374,7 +362,7 @@ public final class CharEffectList
*/
public void stopAllPassives(boolean update, boolean broadcast)
{
if (_passives != null)
if (!_passives.isEmpty())
{
_passives.forEach(this::remove);
// Update stats, effect flags and icons.
@ -392,7 +380,7 @@ public final class CharEffectList
*/
public void stopAllOptions(boolean update, boolean broadcast)
{
if (_options != null)
if (!_options.isEmpty())
{
_options.forEach(this::remove);
// Update stats, effect flags and icons.
@ -490,7 +478,7 @@ public final class CharEffectList
*/
public void stopEffects(Predicate<BuffInfo> filter, boolean update, boolean broadcast)
{
if (_actives != null)
if (!_actives.isEmpty())
{
_actives.stream().filter(filter).forEach(this::remove);
@ -678,6 +666,10 @@ public final class CharEffectList
{
// Remove active effect.
removeActive(info, removed);
if (_owner.isNpc()) // Fix for all NPC debuff animations removed.
{
updateEffectList(broadcast);
}
}
// Update stats, effect flags and icons.
@ -693,7 +685,7 @@ public final class CharEffectList
*/
private synchronized void removeActive(BuffInfo info, boolean removed)
{
if (_actives != null)
if (!_actives.isEmpty())
{
// Removes the buff from the given effect list.
_actives.remove(info);
@ -716,7 +708,7 @@ public final class CharEffectList
private void removePassive(BuffInfo info, boolean removed)
{
if (_passives != null)
if (!_passives.isEmpty())
{
_passives.remove(info);
info.stopAllEffects(removed);
@ -725,7 +717,7 @@ public final class CharEffectList
private void removeOption(BuffInfo info, boolean removed)
{
if (_options != null)
if (!_options.isEmpty())
{
_options.remove(info);
info.stopAllEffects(removed);
@ -821,12 +813,6 @@ public final class CharEffectList
}
}
// Initialize
if (_actives == null)
{
_actives = new ConcurrentLinkedQueue<>();
}
// Manage effect stacking.
if (hasAbnormalType(skill.getAbnormalType()))
{
@ -857,7 +843,7 @@ public final class CharEffectList
}
else
{
// Remove effect that gets overriden.
// Remove effect that gets overridden.
remove(existingInfo);
}
}
@ -865,7 +851,7 @@ public final class CharEffectList
{
info.setInUse(false);
}
else // The effect we try to add should be overriden.
else // The effect we try to add should be overridden.
{
return;
}
@ -918,18 +904,6 @@ public final class CharEffectList
return;
}
// Initialize
if (_passives == null)
{
synchronized (this)
{
if (_passives == null)
{
_passives = ConcurrentHashMap.newKeySet();
}
}
}
// Remove previous passives of this id.
_passives.stream().filter(Objects::nonNull).filter(b -> b.getSkill().getId() == skill.getId()).forEach(b ->
{
@ -947,18 +921,6 @@ public final class CharEffectList
{
if (info.getOption() != null)
{
// Initialize
if (_options == null)
{
synchronized (this)
{
if (_options == null)
{
_options = ConcurrentHashMap.newKeySet();
}
}
}
// Remove previous options of this id.
_options.stream().filter(Objects::nonNull).filter(b -> b.getOption().getId() == info.getOption().getId()).forEach(b ->
{
@ -988,7 +950,7 @@ public final class CharEffectList
final Optional<PartySpelled> ps = ((party != null) || _owner.isSummon()) ? Optional.of(new PartySpelled(_owner)) : Optional.empty();
final Optional<ExOlympiadSpelledInfo> os = (player.isInOlympiadMode() && player.isOlympiadStart()) ? Optional.of(new ExOlympiadSpelledInfo(player)) : Optional.empty();
if (_actives != null)
if (!_actives.isEmpty())
{
//@formatter:off
_actives.stream()
@ -1109,8 +1071,6 @@ public final class CharEffectList
final Set<BuffInfo> unhideBuffs = new HashSet<>();
// Recalculate new flags
if (_actives != null)
{
for (BuffInfo info : _actives)
{
if (info != null)
@ -1144,7 +1104,14 @@ public final class CharEffectList
// Add AbnormalVisualEffect flag.
if (skill.hasAbnormalVisualEffects())
{
abnormalVisualEffectFlags.addAll(skill.getAbnormalVisualEffects());
for (AbnormalVisualEffect ave : skill.getAbnormalVisualEffects())
{
abnormalVisualEffectFlags.add(ave);
_abnormalVisualEffects.add(ave);
}
if (broadcast)
{
_owner.updateAbnormalVisualEffects();
}
}
}
@ -1167,7 +1134,7 @@ public final class CharEffectList
if (broadcast)
{
// Check if there is change in AbnormalVisualEffect
if ((abnormalVisualEffectFlags.size() != _abnormalVisualEffects.size()) || !abnormalVisualEffectFlags.containsAll(_abnormalVisualEffects))
if (!abnormalVisualEffectFlags.containsAll(_abnormalVisualEffects))
{
_abnormalVisualEffects = abnormalVisualEffectFlags;
_owner.updateAbnormalVisualEffects();

View File

@ -77,7 +77,6 @@ public class DoppelgangerInstance extends L2Npc
info.setAbnormalTime(summonerInfo.getAbnormalTime());
getEffectList().add(info);
}
}
}
}

View File

@ -786,7 +786,7 @@ public class CharStat
final CharEffectList effectList = _activeChar.getEffectList();
final Stream<BuffInfo> passives = effectList.getPassives().stream().filter(BuffInfo::isInUse).filter(info -> info.getSkill().checkConditions(SkillConditionScope.PASSIVE, _activeChar, _activeChar));
final Stream<BuffInfo> options = effectList.getOptions().stream().filter(BuffInfo::isInUse);
final Stream<BuffInfo> effectsStream = Stream.concat(effectList.getEffects().stream().filter(BuffInfo::isInUse), Stream.concat(passives != null ? passives : Stream.empty(), options != null ? options : Stream.empty()));
final Stream<BuffInfo> effectsStream = Stream.concat(effectList.getEffects().stream().filter(BuffInfo::isInUse), Stream.concat(passives, options));
// Call pump to each effect
//@formatter:off

View File

@ -389,10 +389,10 @@ public final class BuffInfo
for (AbstractEffect effect : _effects)
{
// Instant effects shouldn't call onExit(..).
if (!effect.isInstant())
{
// if (!effect.isInstant())
// {
effect.onExit(_effector, _effected, _skill);
}
// }
}
// Set the proper system message.

View File

@ -21,13 +21,11 @@ import java.util.List;
import com.l2jmobius.commons.network.PacketWriter;
import com.l2jmobius.gameserver.model.skills.BuffInfo;
import com.l2jmobius.gameserver.model.skills.Skill;
import com.l2jmobius.gameserver.network.OutgoingPackets;
public class AbnormalStatusUpdate implements IClientOutgoingPacket
{
private final List<BuffInfo> _effects = new ArrayList<>();
private final List<Skill> _effects2 = new ArrayList<>();
public void addSkill(BuffInfo info)
{
@ -37,20 +35,12 @@ public class AbnormalStatusUpdate implements IClientOutgoingPacket
}
}
public void addSkill(Skill skill)
{
if (!skill.isHealingPotionSkill())
{
_effects2.add(skill);
}
}
@Override
public boolean write(PacketWriter packet)
{
OutgoingPackets.ABNORMAL_STATUS_UPDATE.writeId(packet);
packet.writeH(_effects.size() + _effects2.size());
packet.writeH(_effects.size());
for (BuffInfo info : _effects)
{
if ((info != null) && info.isInUse())
@ -62,17 +52,6 @@ public class AbnormalStatusUpdate implements IClientOutgoingPacket
writeOptionalD(packet, info.getSkill().isAura() ? -1 : info.getTime());
}
}
for (Skill skill : _effects2)
{
if (skill != null)
{
packet.writeD(skill.getDisplayId());
packet.writeH(skill.getDisplayLevel());
packet.writeH(0x00); // Sub level
packet.writeD(skill.getAbnormalType().getClientId());
packet.writeH(-1);
}
}
return true;
}
}

View File

@ -16,7 +16,6 @@
*/
package com.l2jmobius.gameserver.network.serverpackets;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
@ -24,41 +23,12 @@ import java.util.stream.Collectors;
import com.l2jmobius.commons.network.PacketWriter;
import com.l2jmobius.gameserver.model.actor.L2Character;
import com.l2jmobius.gameserver.model.skills.BuffInfo;
import com.l2jmobius.gameserver.model.skills.Skill;
import com.l2jmobius.gameserver.network.OutgoingPackets;
public class ExAbnormalStatusUpdateFromTarget implements IClientOutgoingPacket
{
private final L2Character _character;
private List<Effect> _effects = new ArrayList<>();
private static class Effect
{
protected int _skillId;
protected int _level;
protected int _subLevel;
protected int _abnormalType;
protected int _duration;
protected int _caster;
public Effect(BuffInfo info)
{
final Skill skill = info.getSkill();
final L2Character caster = info.getEffector();
int casterId = 0;
if (caster != null)
{
casterId = caster.getObjectId();
}
_skillId = skill.getDisplayId();
_level = skill.getDisplayLevel();
_subLevel = skill.getSubLevel();
_abnormalType = skill.getAbnormalType().getClientId();
_duration = skill.isAura() ? -1 : info.getTime();
_caster = casterId;
}
}
private final List<BuffInfo> _effects;
public ExAbnormalStatusUpdateFromTarget(L2Character character)
{
@ -69,7 +39,6 @@ public class ExAbnormalStatusUpdateFromTarget implements IClientOutgoingPacket
.filter(Objects::nonNull)
.filter(BuffInfo::isInUse)
.filter(b -> !b.getSkill().isToggle())
.map(Effect::new)
.collect(Collectors.toList());
//@formatter:on
}
@ -82,14 +51,14 @@ public class ExAbnormalStatusUpdateFromTarget implements IClientOutgoingPacket
packet.writeD(_character.getObjectId());
packet.writeH(_effects.size());
for (Effect info : _effects)
for (BuffInfo info : _effects)
{
packet.writeD(info._skillId);
packet.writeH(info._level);
packet.writeH(info._subLevel);
packet.writeH(info._abnormalType);
writeOptionalD(packet, info._duration);
packet.writeD(info._caster);
packet.writeD(info.getSkill().getDisplayId());
packet.writeH(info.getSkill().getDisplayLevel());
packet.writeH(info.getSkill().getSubLevel());
packet.writeH(info.getSkill().getAbnormalType().getClientId());
writeOptionalD(packet, info.getSkill().isAura() ? -1 : info.getTime());
packet.writeD(info.getEffectorObjectId());
}
return true;
}

View File

@ -16,6 +16,8 @@
*/
package handlers.effecthandlers;
import java.util.Collections;
import com.l2jmobius.gameserver.model.L2Object;
import com.l2jmobius.gameserver.model.L2World;
import com.l2jmobius.gameserver.model.StatsSet;
@ -38,6 +40,19 @@ public final class CallSkillOnActionTime extends AbstractEffect
setTicks(params.getInt("ticks"));
}
@Override
public void onStart(L2Character effector, L2Character effected, Skill skill)
{
effected.getEffectList().stopEffects(Collections.singleton(_skill.getSkill().getAbnormalType()));
effected.getEffectList().addBlockedAbnormalTypes(Collections.singleton(_skill.getSkill().getAbnormalType()));
}
@Override
public void onExit(L2Character effector, L2Character effected, Skill skill)
{
effected.getEffectList().removeBlockedAbnormalTypes(Collections.singleton(_skill.getSkill().getAbnormalType()));
}
@Override
public boolean onActionTime(L2Character effector, L2Character effected, Skill skill)
{

View File

@ -136,6 +136,5 @@ public final class Disarmor extends AbstractEffect
}
}
}
super.onExit(effector, effected, skill);
}
}

View File

@ -84,6 +84,5 @@ public final class DoubleCast extends AbstractEffect
return null;
});
}
super.onExit(effector, effected, skill);
}
}

View File

@ -65,15 +65,15 @@ public final class CharEffectList
{
private static final Logger LOGGER = Logger.getLogger(CharEffectList.class.getName());
/** Queue containing all effects from buffs for this effect list. */
private volatile Queue<BuffInfo> _actives;
private volatile Queue<BuffInfo> _actives = new ConcurrentLinkedQueue<>();
/** List containing all passives for this effect list. They bypass most of the actions and they are not included in most operations. */
private volatile Set<BuffInfo> _passives;
private volatile Set<BuffInfo> _passives = ConcurrentHashMap.newKeySet();
/** List containing all options for this effect list. They bypass most of the actions and they are not included in most operations. */
private volatile Set<BuffInfo> _options;
private volatile Set<BuffInfo> _options = ConcurrentHashMap.newKeySet();
/** Map containing the all stacked effect in progress for each {@code AbnormalType}. */
private volatile Set<AbnormalType> _stackedEffects = EnumSet.noneOf(AbnormalType.class);
/** Set containing all {@code AbnormalType}s that shouldn't be added to this creature effect list. */
private volatile Set<AbnormalType> _blockedAbnormalTypes = null;
private volatile Set<AbnormalType> _blockedAbnormalTypes = EnumSet.noneOf(AbnormalType.class);
/** Set containing all abnormal visual effects this creature currently displays. */
private volatile Set<AbnormalVisualEffect> _abnormalVisualEffects = EnumSet.noneOf(AbnormalVisualEffect.class);
/** Short buff skill ID. */
@ -110,7 +110,7 @@ public final class CharEffectList
*/
public Set<BuffInfo> getPassives()
{
return _passives != null ? Collections.unmodifiableSet(_passives) : Collections.emptySet();
return Collections.unmodifiableSet(_passives);
}
/**
@ -119,7 +119,7 @@ public final class CharEffectList
*/
public Set<BuffInfo> getOptions()
{
return _options != null ? Collections.unmodifiableSet(_options) : Collections.emptySet();
return Collections.unmodifiableSet(_options);
}
/**
@ -128,7 +128,7 @@ public final class CharEffectList
*/
public Collection<BuffInfo> getEffects()
{
return _actives != null ? Collections.unmodifiableCollection(_actives) : Collections.emptyList();
return Collections.unmodifiableCollection(_actives);
}
/**
@ -137,7 +137,7 @@ public final class CharEffectList
*/
public List<BuffInfo> getBuffs()
{
return _actives != null ? _actives.stream().filter(b -> !b.getSkill().getBuffType().isBuff()).collect(Collectors.toList()) : Collections.emptyList();
return _actives.stream().filter(b -> !b.getSkill().getBuffType().isBuff()).collect(Collectors.toList());
}
/**
@ -146,7 +146,7 @@ public final class CharEffectList
*/
public List<BuffInfo> getDebuffs()
{
return _actives != null ? _actives.stream().filter(b -> b.getSkill().isDebuff()).collect(Collectors.toList()) : Collections.emptyList();
return _actives.stream().filter(b -> b.getSkill().isDebuff()).collect(Collectors.toList());
}
/**
@ -156,7 +156,7 @@ public final class CharEffectList
*/
public boolean isAffectedBySkill(int skillId)
{
return ((_actives != null) && _actives.stream().anyMatch(i -> i.getSkill().getId() == skillId)) || ((_passives != null) && _passives.stream().anyMatch(i -> i.getSkill().getId() == skillId));
return (_actives.stream().anyMatch(i -> i.getSkill().getId() == skillId)) || (_passives.stream().anyMatch(i -> i.getSkill().getId() == skillId));
}
/**
@ -166,7 +166,7 @@ public final class CharEffectList
*/
public BuffInfo getBuffInfoBySkillId(int skillId)
{
return Stream.concat(_actives != null ? _actives.stream() : Stream.empty(), _passives != null ? _passives.stream() : Stream.empty()).filter(b -> b.getSkill().getId() == skillId).findFirst().orElse(null);
return Stream.concat(_actives.stream(), _passives.stream()).filter(b -> b.getSkill().getId() == skillId).findFirst().orElse(null);
}
/**
@ -216,18 +216,6 @@ public final class CharEffectList
*/
public void addBlockedAbnormalTypes(Set<AbnormalType> blockedAbnormalTypes)
{
// Initialize
if (_blockedAbnormalTypes == null)
{
synchronized (this)
{
if (_blockedAbnormalTypes == null)
{
_blockedAbnormalTypes = EnumSet.copyOf(blockedAbnormalTypes);
}
}
}
_blockedAbnormalTypes.addAll(blockedAbnormalTypes);
}
@ -238,7 +226,7 @@ public final class CharEffectList
*/
public boolean removeBlockedAbnormalTypes(Set<AbnormalType> blockedBuffSlots)
{
return (_blockedAbnormalTypes != null) && _blockedAbnormalTypes.removeAll(blockedBuffSlots);
return _blockedAbnormalTypes.removeAll(blockedBuffSlots);
}
/**
@ -247,7 +235,7 @@ public final class CharEffectList
*/
public Set<AbnormalType> getBlockedAbnormalTypes()
{
return _blockedAbnormalTypes != null ? Collections.unmodifiableSet(_blockedAbnormalTypes) : Collections.emptySet();
return Collections.unmodifiableSet(_blockedAbnormalTypes);
}
/**
@ -277,7 +265,7 @@ public final class CharEffectList
*/
public int getBuffCount()
{
return _actives != null ? (_buffCount.get() - _hiddenBuffs.get()) : 0;
return !_actives.isEmpty() ? (_buffCount.get() - _hiddenBuffs.get()) : 0;
}
/**
@ -374,7 +362,7 @@ public final class CharEffectList
*/
public void stopAllPassives(boolean update, boolean broadcast)
{
if (_passives != null)
if (!_passives.isEmpty())
{
_passives.forEach(this::remove);
// Update stats, effect flags and icons.
@ -392,7 +380,7 @@ public final class CharEffectList
*/
public void stopAllOptions(boolean update, boolean broadcast)
{
if (_options != null)
if (!_options.isEmpty())
{
_options.forEach(this::remove);
// Update stats, effect flags and icons.
@ -490,7 +478,7 @@ public final class CharEffectList
*/
public void stopEffects(Predicate<BuffInfo> filter, boolean update, boolean broadcast)
{
if (_actives != null)
if (!_actives.isEmpty())
{
_actives.stream().filter(filter).forEach(this::remove);
@ -678,6 +666,10 @@ public final class CharEffectList
{
// Remove active effect.
removeActive(info, removed);
if (_owner.isNpc()) // Fix for all NPC debuff animations removed.
{
updateEffectList(broadcast);
}
}
// Update stats, effect flags and icons.
@ -693,7 +685,7 @@ public final class CharEffectList
*/
private synchronized void removeActive(BuffInfo info, boolean removed)
{
if (_actives != null)
if (!_actives.isEmpty())
{
// Removes the buff from the given effect list.
_actives.remove(info);
@ -716,7 +708,7 @@ public final class CharEffectList
private void removePassive(BuffInfo info, boolean removed)
{
if (_passives != null)
if (!_passives.isEmpty())
{
_passives.remove(info);
info.stopAllEffects(removed);
@ -725,7 +717,7 @@ public final class CharEffectList
private void removeOption(BuffInfo info, boolean removed)
{
if (_options != null)
if (!_options.isEmpty())
{
_options.remove(info);
info.stopAllEffects(removed);
@ -821,12 +813,6 @@ public final class CharEffectList
}
}
// Initialize
if (_actives == null)
{
_actives = new ConcurrentLinkedQueue<>();
}
// Manage effect stacking.
if (hasAbnormalType(skill.getAbnormalType()))
{
@ -857,7 +843,7 @@ public final class CharEffectList
}
else
{
// Remove effect that gets overriden.
// Remove effect that gets overridden.
remove(existingInfo);
}
}
@ -865,7 +851,7 @@ public final class CharEffectList
{
info.setInUse(false);
}
else // The effect we try to add should be overriden.
else // The effect we try to add should be overridden.
{
return;
}
@ -918,18 +904,6 @@ public final class CharEffectList
return;
}
// Initialize
if (_passives == null)
{
synchronized (this)
{
if (_passives == null)
{
_passives = ConcurrentHashMap.newKeySet();
}
}
}
// Remove previous passives of this id.
_passives.stream().filter(Objects::nonNull).filter(b -> b.getSkill().getId() == skill.getId()).forEach(b ->
{
@ -947,18 +921,6 @@ public final class CharEffectList
{
if (info.getOption() != null)
{
// Initialize
if (_options == null)
{
synchronized (this)
{
if (_options == null)
{
_options = ConcurrentHashMap.newKeySet();
}
}
}
// Remove previous options of this id.
_options.stream().filter(Objects::nonNull).filter(b -> b.getOption().getId() == info.getOption().getId()).forEach(b ->
{
@ -988,7 +950,7 @@ public final class CharEffectList
final Optional<PartySpelled> ps = ((party != null) || _owner.isSummon()) ? Optional.of(new PartySpelled(_owner)) : Optional.empty();
final Optional<ExOlympiadSpelledInfo> os = (player.isInOlympiadMode() && player.isOlympiadStart()) ? Optional.of(new ExOlympiadSpelledInfo(player)) : Optional.empty();
if (_actives != null)
if (!_actives.isEmpty())
{
//@formatter:off
_actives.stream()
@ -1109,8 +1071,6 @@ public final class CharEffectList
final Set<BuffInfo> unhideBuffs = new HashSet<>();
// Recalculate new flags
if (_actives != null)
{
for (BuffInfo info : _actives)
{
if (info != null)
@ -1144,7 +1104,14 @@ public final class CharEffectList
// Add AbnormalVisualEffect flag.
if (skill.hasAbnormalVisualEffects())
{
abnormalVisualEffectFlags.addAll(skill.getAbnormalVisualEffects());
for (AbnormalVisualEffect ave : skill.getAbnormalVisualEffects())
{
abnormalVisualEffectFlags.add(ave);
_abnormalVisualEffects.add(ave);
}
if (broadcast)
{
_owner.updateAbnormalVisualEffects();
}
}
}
@ -1167,7 +1134,7 @@ public final class CharEffectList
if (broadcast)
{
// Check if there is change in AbnormalVisualEffect
if ((abnormalVisualEffectFlags.size() != _abnormalVisualEffects.size()) || !abnormalVisualEffectFlags.containsAll(_abnormalVisualEffects))
if (!abnormalVisualEffectFlags.containsAll(_abnormalVisualEffects))
{
_abnormalVisualEffects = abnormalVisualEffectFlags;
_owner.updateAbnormalVisualEffects();

View File

@ -77,7 +77,6 @@ public class DoppelgangerInstance extends L2Npc
info.setAbnormalTime(summonerInfo.getAbnormalTime());
getEffectList().add(info);
}
}
}
}

View File

@ -786,7 +786,7 @@ public class CharStat
final CharEffectList effectList = _activeChar.getEffectList();
final Stream<BuffInfo> passives = effectList.getPassives().stream().filter(BuffInfo::isInUse).filter(info -> info.getSkill().checkConditions(SkillConditionScope.PASSIVE, _activeChar, _activeChar));
final Stream<BuffInfo> options = effectList.getOptions().stream().filter(BuffInfo::isInUse);
final Stream<BuffInfo> effectsStream = Stream.concat(effectList.getEffects().stream().filter(BuffInfo::isInUse), Stream.concat(passives != null ? passives : Stream.empty(), options != null ? options : Stream.empty()));
final Stream<BuffInfo> effectsStream = Stream.concat(effectList.getEffects().stream().filter(BuffInfo::isInUse), Stream.concat(passives, options));
// Call pump to each effect
//@formatter:off

View File

@ -389,10 +389,10 @@ public final class BuffInfo
for (AbstractEffect effect : _effects)
{
// Instant effects shouldn't call onExit(..).
if (!effect.isInstant())
{
// if (!effect.isInstant())
// {
effect.onExit(_effector, _effected, _skill);
}
// }
}
// Set the proper system message.

View File

@ -21,13 +21,11 @@ import java.util.List;
import com.l2jmobius.commons.network.PacketWriter;
import com.l2jmobius.gameserver.model.skills.BuffInfo;
import com.l2jmobius.gameserver.model.skills.Skill;
import com.l2jmobius.gameserver.network.OutgoingPackets;
public class AbnormalStatusUpdate implements IClientOutgoingPacket
{
private final List<BuffInfo> _effects = new ArrayList<>();
private final List<Skill> _effects2 = new ArrayList<>();
public void addSkill(BuffInfo info)
{
@ -37,20 +35,12 @@ public class AbnormalStatusUpdate implements IClientOutgoingPacket
}
}
public void addSkill(Skill skill)
{
if (!skill.isHealingPotionSkill())
{
_effects2.add(skill);
}
}
@Override
public boolean write(PacketWriter packet)
{
OutgoingPackets.ABNORMAL_STATUS_UPDATE.writeId(packet);
packet.writeH(_effects.size() + _effects2.size());
packet.writeH(_effects.size());
for (BuffInfo info : _effects)
{
if ((info != null) && info.isInUse())
@ -62,17 +52,6 @@ public class AbnormalStatusUpdate implements IClientOutgoingPacket
writeOptionalD(packet, info.getSkill().isAura() ? -1 : info.getTime());
}
}
for (Skill skill : _effects2)
{
if (skill != null)
{
packet.writeD(skill.getDisplayId());
packet.writeH(skill.getDisplayLevel());
packet.writeH(0x00); // Sub level
packet.writeD(skill.getAbnormalType().getClientId());
packet.writeH(-1);
}
}
return true;
}
}

View File

@ -16,7 +16,6 @@
*/
package com.l2jmobius.gameserver.network.serverpackets;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
@ -24,41 +23,12 @@ import java.util.stream.Collectors;
import com.l2jmobius.commons.network.PacketWriter;
import com.l2jmobius.gameserver.model.actor.L2Character;
import com.l2jmobius.gameserver.model.skills.BuffInfo;
import com.l2jmobius.gameserver.model.skills.Skill;
import com.l2jmobius.gameserver.network.OutgoingPackets;
public class ExAbnormalStatusUpdateFromTarget implements IClientOutgoingPacket
{
private final L2Character _character;
private List<Effect> _effects = new ArrayList<>();
private static class Effect
{
protected int _skillId;
protected int _level;
protected int _subLevel;
protected int _abnormalType;
protected int _duration;
protected int _caster;
public Effect(BuffInfo info)
{
final Skill skill = info.getSkill();
final L2Character caster = info.getEffector();
int casterId = 0;
if (caster != null)
{
casterId = caster.getObjectId();
}
_skillId = skill.getDisplayId();
_level = skill.getDisplayLevel();
_subLevel = skill.getSubLevel();
_abnormalType = skill.getAbnormalType().getClientId();
_duration = skill.isAura() ? -1 : info.getTime();
_caster = casterId;
}
}
private final List<BuffInfo> _effects;
public ExAbnormalStatusUpdateFromTarget(L2Character character)
{
@ -69,7 +39,6 @@ public class ExAbnormalStatusUpdateFromTarget implements IClientOutgoingPacket
.filter(Objects::nonNull)
.filter(BuffInfo::isInUse)
.filter(b -> !b.getSkill().isToggle())
.map(Effect::new)
.collect(Collectors.toList());
//@formatter:on
}
@ -82,14 +51,14 @@ public class ExAbnormalStatusUpdateFromTarget implements IClientOutgoingPacket
packet.writeD(_character.getObjectId());
packet.writeH(_effects.size());
for (Effect info : _effects)
for (BuffInfo info : _effects)
{
packet.writeD(info._skillId);
packet.writeH(info._level);
packet.writeH(info._subLevel);
packet.writeH(info._abnormalType);
writeOptionalD(packet, info._duration);
packet.writeD(info._caster);
packet.writeD(info.getSkill().getDisplayId());
packet.writeH(info.getSkill().getDisplayLevel());
packet.writeH(info.getSkill().getSubLevel());
packet.writeH(info.getSkill().getAbnormalType().getClientId());
writeOptionalD(packet, info.getSkill().isAura() ? -1 : info.getTime());
packet.writeD(info.getEffectorObjectId());
}
return true;
}

View File

@ -16,6 +16,8 @@
*/
package handlers.effecthandlers;
import java.util.Collections;
import com.l2jmobius.gameserver.model.L2Object;
import com.l2jmobius.gameserver.model.L2World;
import com.l2jmobius.gameserver.model.StatsSet;
@ -38,6 +40,19 @@ public final class CallSkillOnActionTime extends AbstractEffect
setTicks(params.getInt("ticks"));
}
@Override
public void onStart(L2Character effector, L2Character effected, Skill skill)
{
effected.getEffectList().stopEffects(Collections.singleton(_skill.getSkill().getAbnormalType()));
effected.getEffectList().addBlockedAbnormalTypes(Collections.singleton(_skill.getSkill().getAbnormalType()));
}
@Override
public void onExit(L2Character effector, L2Character effected, Skill skill)
{
effected.getEffectList().removeBlockedAbnormalTypes(Collections.singleton(_skill.getSkill().getAbnormalType()));
}
@Override
public boolean onActionTime(L2Character effector, L2Character effected, Skill skill)
{

View File

@ -136,6 +136,5 @@ public final class Disarmor extends AbstractEffect
}
}
}
super.onExit(effector, effected, skill);
}
}

View File

@ -84,6 +84,5 @@ public final class DoubleCast extends AbstractEffect
return null;
});
}
super.onExit(effector, effected, skill);
}
}

View File

@ -65,15 +65,15 @@ public final class CharEffectList
{
private static final Logger LOGGER = Logger.getLogger(CharEffectList.class.getName());
/** Queue containing all effects from buffs for this effect list. */
private volatile Queue<BuffInfo> _actives;
private volatile Queue<BuffInfo> _actives = new ConcurrentLinkedQueue<>();
/** List containing all passives for this effect list. They bypass most of the actions and they are not included in most operations. */
private volatile Set<BuffInfo> _passives;
private volatile Set<BuffInfo> _passives = ConcurrentHashMap.newKeySet();
/** List containing all options for this effect list. They bypass most of the actions and they are not included in most operations. */
private volatile Set<BuffInfo> _options;
private volatile Set<BuffInfo> _options = ConcurrentHashMap.newKeySet();
/** Map containing the all stacked effect in progress for each {@code AbnormalType}. */
private volatile Set<AbnormalType> _stackedEffects = EnumSet.noneOf(AbnormalType.class);
/** Set containing all {@code AbnormalType}s that shouldn't be added to this creature effect list. */
private volatile Set<AbnormalType> _blockedAbnormalTypes = null;
private volatile Set<AbnormalType> _blockedAbnormalTypes = EnumSet.noneOf(AbnormalType.class);
/** Set containing all abnormal visual effects this creature currently displays. */
private volatile Set<AbnormalVisualEffect> _abnormalVisualEffects = EnumSet.noneOf(AbnormalVisualEffect.class);
/** Short buff skill ID. */
@ -110,7 +110,7 @@ public final class CharEffectList
*/
public Set<BuffInfo> getPassives()
{
return _passives != null ? Collections.unmodifiableSet(_passives) : Collections.emptySet();
return Collections.unmodifiableSet(_passives);
}
/**
@ -119,7 +119,7 @@ public final class CharEffectList
*/
public Set<BuffInfo> getOptions()
{
return _options != null ? Collections.unmodifiableSet(_options) : Collections.emptySet();
return Collections.unmodifiableSet(_options);
}
/**
@ -128,7 +128,7 @@ public final class CharEffectList
*/
public Collection<BuffInfo> getEffects()
{
return _actives != null ? Collections.unmodifiableCollection(_actives) : Collections.emptyList();
return Collections.unmodifiableCollection(_actives);
}
/**
@ -137,7 +137,7 @@ public final class CharEffectList
*/
public List<BuffInfo> getBuffs()
{
return _actives != null ? _actives.stream().filter(b -> !b.getSkill().getBuffType().isBuff()).collect(Collectors.toList()) : Collections.emptyList();
return _actives.stream().filter(b -> !b.getSkill().getBuffType().isBuff()).collect(Collectors.toList());
}
/**
@ -146,7 +146,7 @@ public final class CharEffectList
*/
public List<BuffInfo> getDebuffs()
{
return _actives != null ? _actives.stream().filter(b -> b.getSkill().isDebuff()).collect(Collectors.toList()) : Collections.emptyList();
return _actives.stream().filter(b -> b.getSkill().isDebuff()).collect(Collectors.toList());
}
/**
@ -156,7 +156,7 @@ public final class CharEffectList
*/
public boolean isAffectedBySkill(int skillId)
{
return ((_actives != null) && _actives.stream().anyMatch(i -> i.getSkill().getId() == skillId)) || ((_passives != null) && _passives.stream().anyMatch(i -> i.getSkill().getId() == skillId));
return (_actives.stream().anyMatch(i -> i.getSkill().getId() == skillId)) || (_passives.stream().anyMatch(i -> i.getSkill().getId() == skillId));
}
/**
@ -166,7 +166,7 @@ public final class CharEffectList
*/
public BuffInfo getBuffInfoBySkillId(int skillId)
{
return Stream.concat(_actives != null ? _actives.stream() : Stream.empty(), _passives != null ? _passives.stream() : Stream.empty()).filter(b -> b.getSkill().getId() == skillId).findFirst().orElse(null);
return Stream.concat(_actives.stream(), _passives.stream()).filter(b -> b.getSkill().getId() == skillId).findFirst().orElse(null);
}
/**
@ -216,18 +216,6 @@ public final class CharEffectList
*/
public void addBlockedAbnormalTypes(Set<AbnormalType> blockedAbnormalTypes)
{
// Initialize
if (_blockedAbnormalTypes == null)
{
synchronized (this)
{
if (_blockedAbnormalTypes == null)
{
_blockedAbnormalTypes = EnumSet.copyOf(blockedAbnormalTypes);
}
}
}
_blockedAbnormalTypes.addAll(blockedAbnormalTypes);
}
@ -238,7 +226,7 @@ public final class CharEffectList
*/
public boolean removeBlockedAbnormalTypes(Set<AbnormalType> blockedBuffSlots)
{
return (_blockedAbnormalTypes != null) && _blockedAbnormalTypes.removeAll(blockedBuffSlots);
return _blockedAbnormalTypes.removeAll(blockedBuffSlots);
}
/**
@ -247,7 +235,7 @@ public final class CharEffectList
*/
public Set<AbnormalType> getBlockedAbnormalTypes()
{
return _blockedAbnormalTypes != null ? Collections.unmodifiableSet(_blockedAbnormalTypes) : Collections.emptySet();
return Collections.unmodifiableSet(_blockedAbnormalTypes);
}
/**
@ -277,7 +265,7 @@ public final class CharEffectList
*/
public int getBuffCount()
{
return _actives != null ? (_buffCount.get() - _hiddenBuffs.get()) : 0;
return !_actives.isEmpty() ? (_buffCount.get() - _hiddenBuffs.get()) : 0;
}
/**
@ -374,7 +362,7 @@ public final class CharEffectList
*/
public void stopAllPassives(boolean update, boolean broadcast)
{
if (_passives != null)
if (!_passives.isEmpty())
{
_passives.forEach(this::remove);
// Update stats, effect flags and icons.
@ -392,7 +380,7 @@ public final class CharEffectList
*/
public void stopAllOptions(boolean update, boolean broadcast)
{
if (_options != null)
if (!_options.isEmpty())
{
_options.forEach(this::remove);
// Update stats, effect flags and icons.
@ -490,7 +478,7 @@ public final class CharEffectList
*/
public void stopEffects(Predicate<BuffInfo> filter, boolean update, boolean broadcast)
{
if (_actives != null)
if (!_actives.isEmpty())
{
_actives.stream().filter(filter).forEach(this::remove);
@ -678,6 +666,10 @@ public final class CharEffectList
{
// Remove active effect.
removeActive(info, removed);
if (_owner.isNpc()) // Fix for all NPC debuff animations removed.
{
updateEffectList(broadcast);
}
}
// Update stats, effect flags and icons.
@ -693,7 +685,7 @@ public final class CharEffectList
*/
private synchronized void removeActive(BuffInfo info, boolean removed)
{
if (_actives != null)
if (!_actives.isEmpty())
{
// Removes the buff from the given effect list.
_actives.remove(info);
@ -716,7 +708,7 @@ public final class CharEffectList
private void removePassive(BuffInfo info, boolean removed)
{
if (_passives != null)
if (!_passives.isEmpty())
{
_passives.remove(info);
info.stopAllEffects(removed);
@ -725,7 +717,7 @@ public final class CharEffectList
private void removeOption(BuffInfo info, boolean removed)
{
if (_options != null)
if (!_options.isEmpty())
{
_options.remove(info);
info.stopAllEffects(removed);
@ -821,12 +813,6 @@ public final class CharEffectList
}
}
// Initialize
if (_actives == null)
{
_actives = new ConcurrentLinkedQueue<>();
}
// Manage effect stacking.
if (hasAbnormalType(skill.getAbnormalType()))
{
@ -857,7 +843,7 @@ public final class CharEffectList
}
else
{
// Remove effect that gets overriden.
// Remove effect that gets overridden.
remove(existingInfo);
}
}
@ -865,7 +851,7 @@ public final class CharEffectList
{
info.setInUse(false);
}
else // The effect we try to add should be overriden.
else // The effect we try to add should be overridden.
{
return;
}
@ -918,18 +904,6 @@ public final class CharEffectList
return;
}
// Initialize
if (_passives == null)
{
synchronized (this)
{
if (_passives == null)
{
_passives = ConcurrentHashMap.newKeySet();
}
}
}
// Remove previous passives of this id.
_passives.stream().filter(Objects::nonNull).filter(b -> b.getSkill().getId() == skill.getId()).forEach(b ->
{
@ -947,18 +921,6 @@ public final class CharEffectList
{
if (info.getOption() != null)
{
// Initialize
if (_options == null)
{
synchronized (this)
{
if (_options == null)
{
_options = ConcurrentHashMap.newKeySet();
}
}
}
// Remove previous options of this id.
_options.stream().filter(Objects::nonNull).filter(b -> b.getOption().getId() == info.getOption().getId()).forEach(b ->
{
@ -988,7 +950,7 @@ public final class CharEffectList
final Optional<PartySpelled> ps = ((party != null) || _owner.isSummon()) ? Optional.of(new PartySpelled(_owner)) : Optional.empty();
final Optional<ExOlympiadSpelledInfo> os = (player.isInOlympiadMode() && player.isOlympiadStart()) ? Optional.of(new ExOlympiadSpelledInfo(player)) : Optional.empty();
if (_actives != null)
if (!_actives.isEmpty())
{
//@formatter:off
_actives.stream()
@ -1109,8 +1071,6 @@ public final class CharEffectList
final Set<BuffInfo> unhideBuffs = new HashSet<>();
// Recalculate new flags
if (_actives != null)
{
for (BuffInfo info : _actives)
{
if (info != null)
@ -1144,7 +1104,14 @@ public final class CharEffectList
// Add AbnormalVisualEffect flag.
if (skill.hasAbnormalVisualEffects())
{
abnormalVisualEffectFlags.addAll(skill.getAbnormalVisualEffects());
for (AbnormalVisualEffect ave : skill.getAbnormalVisualEffects())
{
abnormalVisualEffectFlags.add(ave);
_abnormalVisualEffects.add(ave);
}
if (broadcast)
{
_owner.updateAbnormalVisualEffects();
}
}
}
@ -1167,7 +1134,7 @@ public final class CharEffectList
if (broadcast)
{
// Check if there is change in AbnormalVisualEffect
if ((abnormalVisualEffectFlags.size() != _abnormalVisualEffects.size()) || !abnormalVisualEffectFlags.containsAll(_abnormalVisualEffects))
if (!abnormalVisualEffectFlags.containsAll(_abnormalVisualEffects))
{
_abnormalVisualEffects = abnormalVisualEffectFlags;
_owner.updateAbnormalVisualEffects();

View File

@ -77,7 +77,6 @@ public class DoppelgangerInstance extends L2Npc
info.setAbnormalTime(summonerInfo.getAbnormalTime());
getEffectList().add(info);
}
}
}
}

View File

@ -786,7 +786,7 @@ public class CharStat
final CharEffectList effectList = _activeChar.getEffectList();
final Stream<BuffInfo> passives = effectList.getPassives().stream().filter(BuffInfo::isInUse).filter(info -> info.getSkill().checkConditions(SkillConditionScope.PASSIVE, _activeChar, _activeChar));
final Stream<BuffInfo> options = effectList.getOptions().stream().filter(BuffInfo::isInUse);
final Stream<BuffInfo> effectsStream = Stream.concat(effectList.getEffects().stream().filter(BuffInfo::isInUse), Stream.concat(passives != null ? passives : Stream.empty(), options != null ? options : Stream.empty()));
final Stream<BuffInfo> effectsStream = Stream.concat(effectList.getEffects().stream().filter(BuffInfo::isInUse), Stream.concat(passives, options));
// Call pump to each effect
//@formatter:off

View File

@ -389,10 +389,10 @@ public final class BuffInfo
for (AbstractEffect effect : _effects)
{
// Instant effects shouldn't call onExit(..).
if (!effect.isInstant())
{
// if (!effect.isInstant())
// {
effect.onExit(_effector, _effected, _skill);
}
// }
}
// Set the proper system message.

View File

@ -21,13 +21,11 @@ import java.util.List;
import com.l2jmobius.commons.network.PacketWriter;
import com.l2jmobius.gameserver.model.skills.BuffInfo;
import com.l2jmobius.gameserver.model.skills.Skill;
import com.l2jmobius.gameserver.network.OutgoingPackets;
public class AbnormalStatusUpdate implements IClientOutgoingPacket
{
private final List<BuffInfo> _effects = new ArrayList<>();
private final List<Skill> _effects2 = new ArrayList<>();
public void addSkill(BuffInfo info)
{
@ -37,20 +35,12 @@ public class AbnormalStatusUpdate implements IClientOutgoingPacket
}
}
public void addSkill(Skill skill)
{
if (!skill.isHealingPotionSkill())
{
_effects2.add(skill);
}
}
@Override
public boolean write(PacketWriter packet)
{
OutgoingPackets.ABNORMAL_STATUS_UPDATE.writeId(packet);
packet.writeH(_effects.size() + _effects2.size());
packet.writeH(_effects.size());
for (BuffInfo info : _effects)
{
if ((info != null) && info.isInUse())
@ -62,17 +52,6 @@ public class AbnormalStatusUpdate implements IClientOutgoingPacket
writeOptionalD(packet, info.getSkill().isAura() ? -1 : info.getTime());
}
}
for (Skill skill : _effects2)
{
if (skill != null)
{
packet.writeD(skill.getDisplayId());
packet.writeH(skill.getDisplayLevel());
packet.writeH(0x00); // Sub level
packet.writeD(skill.getAbnormalType().getClientId());
packet.writeH(-1);
}
}
return true;
}
}

View File

@ -16,7 +16,6 @@
*/
package com.l2jmobius.gameserver.network.serverpackets;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
@ -24,41 +23,12 @@ import java.util.stream.Collectors;
import com.l2jmobius.commons.network.PacketWriter;
import com.l2jmobius.gameserver.model.actor.L2Character;
import com.l2jmobius.gameserver.model.skills.BuffInfo;
import com.l2jmobius.gameserver.model.skills.Skill;
import com.l2jmobius.gameserver.network.OutgoingPackets;
public class ExAbnormalStatusUpdateFromTarget implements IClientOutgoingPacket
{
private final L2Character _character;
private List<Effect> _effects = new ArrayList<>();
private static class Effect
{
protected int _skillId;
protected int _level;
protected int _subLevel;
protected int _abnormalType;
protected int _duration;
protected int _caster;
public Effect(BuffInfo info)
{
final Skill skill = info.getSkill();
final L2Character caster = info.getEffector();
int casterId = 0;
if (caster != null)
{
casterId = caster.getObjectId();
}
_skillId = skill.getDisplayId();
_level = skill.getDisplayLevel();
_subLevel = skill.getSubLevel();
_abnormalType = skill.getAbnormalType().getClientId();
_duration = skill.isAura() ? -1 : info.getTime();
_caster = casterId;
}
}
private final List<BuffInfo> _effects;
public ExAbnormalStatusUpdateFromTarget(L2Character character)
{
@ -69,7 +39,6 @@ public class ExAbnormalStatusUpdateFromTarget implements IClientOutgoingPacket
.filter(Objects::nonNull)
.filter(BuffInfo::isInUse)
.filter(b -> !b.getSkill().isToggle())
.map(Effect::new)
.collect(Collectors.toList());
//@formatter:on
}
@ -82,14 +51,14 @@ public class ExAbnormalStatusUpdateFromTarget implements IClientOutgoingPacket
packet.writeD(_character.getObjectId());
packet.writeH(_effects.size());
for (Effect info : _effects)
for (BuffInfo info : _effects)
{
packet.writeD(info._skillId);
packet.writeH(info._level);
packet.writeH(info._subLevel);
packet.writeH(info._abnormalType);
writeOptionalD(packet, info._duration);
packet.writeD(info._caster);
packet.writeD(info.getSkill().getDisplayId());
packet.writeH(info.getSkill().getDisplayLevel());
packet.writeH(info.getSkill().getSubLevel());
packet.writeH(info.getSkill().getAbnormalType().getClientId());
writeOptionalD(packet, info.getSkill().isAura() ? -1 : info.getTime());
packet.writeD(info.getEffectorObjectId());
}
return true;
}

View File

@ -16,6 +16,8 @@
*/
package handlers.effecthandlers;
import java.util.Collections;
import com.l2jmobius.gameserver.model.L2Object;
import com.l2jmobius.gameserver.model.L2World;
import com.l2jmobius.gameserver.model.StatsSet;
@ -38,6 +40,19 @@ public final class CallSkillOnActionTime extends AbstractEffect
setTicks(params.getInt("ticks"));
}
@Override
public void onStart(L2Character effector, L2Character effected, Skill skill)
{
effected.getEffectList().stopEffects(Collections.singleton(_skill.getSkill().getAbnormalType()));
effected.getEffectList().addBlockedAbnormalTypes(Collections.singleton(_skill.getSkill().getAbnormalType()));
}
@Override
public void onExit(L2Character effector, L2Character effected, Skill skill)
{
effected.getEffectList().removeBlockedAbnormalTypes(Collections.singleton(_skill.getSkill().getAbnormalType()));
}
@Override
public boolean onActionTime(L2Character effector, L2Character effected, Skill skill)
{

View File

@ -136,6 +136,5 @@ public final class Disarmor extends AbstractEffect
}
}
}
super.onExit(effector, effected, skill);
}
}

View File

@ -84,6 +84,5 @@ public final class DoubleCast extends AbstractEffect
return null;
});
}
super.onExit(effector, effected, skill);
}
}

View File

@ -65,15 +65,15 @@ public final class CharEffectList
{
private static final Logger LOGGER = Logger.getLogger(CharEffectList.class.getName());
/** Queue containing all effects from buffs for this effect list. */
private volatile Queue<BuffInfo> _actives;
private volatile Queue<BuffInfo> _actives = new ConcurrentLinkedQueue<>();
/** List containing all passives for this effect list. They bypass most of the actions and they are not included in most operations. */
private volatile Set<BuffInfo> _passives;
private volatile Set<BuffInfo> _passives = ConcurrentHashMap.newKeySet();
/** List containing all options for this effect list. They bypass most of the actions and they are not included in most operations. */
private volatile Set<BuffInfo> _options;
private volatile Set<BuffInfo> _options = ConcurrentHashMap.newKeySet();
/** Map containing the all stacked effect in progress for each {@code AbnormalType}. */
private volatile Set<AbnormalType> _stackedEffects = EnumSet.noneOf(AbnormalType.class);
/** Set containing all {@code AbnormalType}s that shouldn't be added to this creature effect list. */
private volatile Set<AbnormalType> _blockedAbnormalTypes = null;
private volatile Set<AbnormalType> _blockedAbnormalTypes = EnumSet.noneOf(AbnormalType.class);
/** Set containing all abnormal visual effects this creature currently displays. */
private volatile Set<AbnormalVisualEffect> _abnormalVisualEffects = EnumSet.noneOf(AbnormalVisualEffect.class);
/** Short buff skill ID. */
@ -110,7 +110,7 @@ public final class CharEffectList
*/
public Set<BuffInfo> getPassives()
{
return _passives != null ? Collections.unmodifiableSet(_passives) : Collections.emptySet();
return Collections.unmodifiableSet(_passives);
}
/**
@ -119,7 +119,7 @@ public final class CharEffectList
*/
public Set<BuffInfo> getOptions()
{
return _options != null ? Collections.unmodifiableSet(_options) : Collections.emptySet();
return Collections.unmodifiableSet(_options);
}
/**
@ -128,7 +128,7 @@ public final class CharEffectList
*/
public Collection<BuffInfo> getEffects()
{
return _actives != null ? Collections.unmodifiableCollection(_actives) : Collections.emptyList();
return Collections.unmodifiableCollection(_actives);
}
/**
@ -137,7 +137,7 @@ public final class CharEffectList
*/
public List<BuffInfo> getBuffs()
{
return _actives != null ? _actives.stream().filter(b -> !b.getSkill().getBuffType().isBuff()).collect(Collectors.toList()) : Collections.emptyList();
return _actives.stream().filter(b -> !b.getSkill().getBuffType().isBuff()).collect(Collectors.toList());
}
/**
@ -146,7 +146,7 @@ public final class CharEffectList
*/
public List<BuffInfo> getDebuffs()
{
return _actives != null ? _actives.stream().filter(b -> b.getSkill().isDebuff()).collect(Collectors.toList()) : Collections.emptyList();
return _actives.stream().filter(b -> b.getSkill().isDebuff()).collect(Collectors.toList());
}
/**
@ -156,7 +156,7 @@ public final class CharEffectList
*/
public boolean isAffectedBySkill(int skillId)
{
return ((_actives != null) && _actives.stream().anyMatch(i -> i.getSkill().getId() == skillId)) || ((_passives != null) && _passives.stream().anyMatch(i -> i.getSkill().getId() == skillId));
return (_actives.stream().anyMatch(i -> i.getSkill().getId() == skillId)) || (_passives.stream().anyMatch(i -> i.getSkill().getId() == skillId));
}
/**
@ -166,7 +166,7 @@ public final class CharEffectList
*/
public BuffInfo getBuffInfoBySkillId(int skillId)
{
return Stream.concat(_actives != null ? _actives.stream() : Stream.empty(), _passives != null ? _passives.stream() : Stream.empty()).filter(b -> b.getSkill().getId() == skillId).findFirst().orElse(null);
return Stream.concat(_actives.stream(), _passives.stream()).filter(b -> b.getSkill().getId() == skillId).findFirst().orElse(null);
}
/**
@ -216,18 +216,6 @@ public final class CharEffectList
*/
public void addBlockedAbnormalTypes(Set<AbnormalType> blockedAbnormalTypes)
{
// Initialize
if (_blockedAbnormalTypes == null)
{
synchronized (this)
{
if (_blockedAbnormalTypes == null)
{
_blockedAbnormalTypes = EnumSet.copyOf(blockedAbnormalTypes);
}
}
}
_blockedAbnormalTypes.addAll(blockedAbnormalTypes);
}
@ -238,7 +226,7 @@ public final class CharEffectList
*/
public boolean removeBlockedAbnormalTypes(Set<AbnormalType> blockedBuffSlots)
{
return (_blockedAbnormalTypes != null) && _blockedAbnormalTypes.removeAll(blockedBuffSlots);
return _blockedAbnormalTypes.removeAll(blockedBuffSlots);
}
/**
@ -247,7 +235,7 @@ public final class CharEffectList
*/
public Set<AbnormalType> getBlockedAbnormalTypes()
{
return _blockedAbnormalTypes != null ? Collections.unmodifiableSet(_blockedAbnormalTypes) : Collections.emptySet();
return Collections.unmodifiableSet(_blockedAbnormalTypes);
}
/**
@ -277,7 +265,7 @@ public final class CharEffectList
*/
public int getBuffCount()
{
return _actives != null ? (_buffCount.get() - _hiddenBuffs.get()) : 0;
return !_actives.isEmpty() ? (_buffCount.get() - _hiddenBuffs.get()) : 0;
}
/**
@ -374,7 +362,7 @@ public final class CharEffectList
*/
public void stopAllPassives(boolean update, boolean broadcast)
{
if (_passives != null)
if (!_passives.isEmpty())
{
_passives.forEach(this::remove);
// Update stats, effect flags and icons.
@ -392,7 +380,7 @@ public final class CharEffectList
*/
public void stopAllOptions(boolean update, boolean broadcast)
{
if (_options != null)
if (!_options.isEmpty())
{
_options.forEach(this::remove);
// Update stats, effect flags and icons.
@ -490,7 +478,7 @@ public final class CharEffectList
*/
public void stopEffects(Predicate<BuffInfo> filter, boolean update, boolean broadcast)
{
if (_actives != null)
if (!_actives.isEmpty())
{
_actives.stream().filter(filter).forEach(this::remove);
@ -678,6 +666,10 @@ public final class CharEffectList
{
// Remove active effect.
removeActive(info, removed);
if (_owner.isNpc()) // Fix for all NPC debuff animations removed.
{
updateEffectList(broadcast);
}
}
// Update stats, effect flags and icons.
@ -693,7 +685,7 @@ public final class CharEffectList
*/
private synchronized void removeActive(BuffInfo info, boolean removed)
{
if (_actives != null)
if (!_actives.isEmpty())
{
// Removes the buff from the given effect list.
_actives.remove(info);
@ -716,7 +708,7 @@ public final class CharEffectList
private void removePassive(BuffInfo info, boolean removed)
{
if (_passives != null)
if (!_passives.isEmpty())
{
_passives.remove(info);
info.stopAllEffects(removed);
@ -725,7 +717,7 @@ public final class CharEffectList
private void removeOption(BuffInfo info, boolean removed)
{
if (_options != null)
if (!_options.isEmpty())
{
_options.remove(info);
info.stopAllEffects(removed);
@ -821,12 +813,6 @@ public final class CharEffectList
}
}
// Initialize
if (_actives == null)
{
_actives = new ConcurrentLinkedQueue<>();
}
// Manage effect stacking.
if (hasAbnormalType(skill.getAbnormalType()))
{
@ -857,7 +843,7 @@ public final class CharEffectList
}
else
{
// Remove effect that gets overriden.
// Remove effect that gets overridden.
remove(existingInfo);
}
}
@ -865,7 +851,7 @@ public final class CharEffectList
{
info.setInUse(false);
}
else // The effect we try to add should be overriden.
else // The effect we try to add should be overridden.
{
return;
}
@ -918,18 +904,6 @@ public final class CharEffectList
return;
}
// Initialize
if (_passives == null)
{
synchronized (this)
{
if (_passives == null)
{
_passives = ConcurrentHashMap.newKeySet();
}
}
}
// Remove previous passives of this id.
_passives.stream().filter(Objects::nonNull).filter(b -> b.getSkill().getId() == skill.getId()).forEach(b ->
{
@ -947,18 +921,6 @@ public final class CharEffectList
{
if (info.getOption() != null)
{
// Initialize
if (_options == null)
{
synchronized (this)
{
if (_options == null)
{
_options = ConcurrentHashMap.newKeySet();
}
}
}
// Remove previous options of this id.
_options.stream().filter(Objects::nonNull).filter(b -> b.getOption().getId() == info.getOption().getId()).forEach(b ->
{
@ -988,7 +950,7 @@ public final class CharEffectList
final Optional<PartySpelled> ps = ((party != null) || _owner.isSummon()) ? Optional.of(new PartySpelled(_owner)) : Optional.empty();
final Optional<ExOlympiadSpelledInfo> os = (player.isInOlympiadMode() && player.isOlympiadStart()) ? Optional.of(new ExOlympiadSpelledInfo(player)) : Optional.empty();
if (_actives != null)
if (!_actives.isEmpty())
{
//@formatter:off
_actives.stream()
@ -1109,8 +1071,6 @@ public final class CharEffectList
final Set<BuffInfo> unhideBuffs = new HashSet<>();
// Recalculate new flags
if (_actives != null)
{
for (BuffInfo info : _actives)
{
if (info != null)
@ -1144,7 +1104,14 @@ public final class CharEffectList
// Add AbnormalVisualEffect flag.
if (skill.hasAbnormalVisualEffects())
{
abnormalVisualEffectFlags.addAll(skill.getAbnormalVisualEffects());
for (AbnormalVisualEffect ave : skill.getAbnormalVisualEffects())
{
abnormalVisualEffectFlags.add(ave);
_abnormalVisualEffects.add(ave);
}
if (broadcast)
{
_owner.updateAbnormalVisualEffects();
}
}
}
@ -1167,7 +1134,7 @@ public final class CharEffectList
if (broadcast)
{
// Check if there is change in AbnormalVisualEffect
if ((abnormalVisualEffectFlags.size() != _abnormalVisualEffects.size()) || !abnormalVisualEffectFlags.containsAll(_abnormalVisualEffects))
if (!abnormalVisualEffectFlags.containsAll(_abnormalVisualEffects))
{
_abnormalVisualEffects = abnormalVisualEffectFlags;
_owner.updateAbnormalVisualEffects();

View File

@ -77,7 +77,6 @@ public class DoppelgangerInstance extends L2Npc
info.setAbnormalTime(summonerInfo.getAbnormalTime());
getEffectList().add(info);
}
}
}
}

View File

@ -786,7 +786,7 @@ public class CharStat
final CharEffectList effectList = _activeChar.getEffectList();
final Stream<BuffInfo> passives = effectList.getPassives().stream().filter(BuffInfo::isInUse).filter(info -> info.getSkill().checkConditions(SkillConditionScope.PASSIVE, _activeChar, _activeChar));
final Stream<BuffInfo> options = effectList.getOptions().stream().filter(BuffInfo::isInUse);
final Stream<BuffInfo> effectsStream = Stream.concat(effectList.getEffects().stream().filter(BuffInfo::isInUse), Stream.concat(passives != null ? passives : Stream.empty(), options != null ? options : Stream.empty()));
final Stream<BuffInfo> effectsStream = Stream.concat(effectList.getEffects().stream().filter(BuffInfo::isInUse), Stream.concat(passives, options));
// Call pump to each effect
//@formatter:off

View File

@ -389,10 +389,10 @@ public final class BuffInfo
for (AbstractEffect effect : _effects)
{
// Instant effects shouldn't call onExit(..).
if (!effect.isInstant())
{
// if (!effect.isInstant())
// {
effect.onExit(_effector, _effected, _skill);
}
// }
}
// Set the proper system message.

View File

@ -21,13 +21,11 @@ import java.util.List;
import com.l2jmobius.commons.network.PacketWriter;
import com.l2jmobius.gameserver.model.skills.BuffInfo;
import com.l2jmobius.gameserver.model.skills.Skill;
import com.l2jmobius.gameserver.network.OutgoingPackets;
public class AbnormalStatusUpdate implements IClientOutgoingPacket
{
private final List<BuffInfo> _effects = new ArrayList<>();
private final List<Skill> _effects2 = new ArrayList<>();
public void addSkill(BuffInfo info)
{
@ -37,20 +35,12 @@ public class AbnormalStatusUpdate implements IClientOutgoingPacket
}
}
public void addSkill(Skill skill)
{
if (!skill.isHealingPotionSkill())
{
_effects2.add(skill);
}
}
@Override
public boolean write(PacketWriter packet)
{
OutgoingPackets.ABNORMAL_STATUS_UPDATE.writeId(packet);
packet.writeH(_effects.size() + _effects2.size());
packet.writeH(_effects.size());
for (BuffInfo info : _effects)
{
if ((info != null) && info.isInUse())
@ -62,17 +52,6 @@ public class AbnormalStatusUpdate implements IClientOutgoingPacket
writeOptionalD(packet, info.getSkill().isAura() ? -1 : info.getTime());
}
}
for (Skill skill : _effects2)
{
if (skill != null)
{
packet.writeD(skill.getDisplayId());
packet.writeH(skill.getDisplayLevel());
packet.writeH(0x00); // Sub level
packet.writeD(skill.getAbnormalType().getClientId());
packet.writeH(-1);
}
}
return true;
}
}

View File

@ -16,7 +16,6 @@
*/
package com.l2jmobius.gameserver.network.serverpackets;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
@ -24,41 +23,12 @@ import java.util.stream.Collectors;
import com.l2jmobius.commons.network.PacketWriter;
import com.l2jmobius.gameserver.model.actor.L2Character;
import com.l2jmobius.gameserver.model.skills.BuffInfo;
import com.l2jmobius.gameserver.model.skills.Skill;
import com.l2jmobius.gameserver.network.OutgoingPackets;
public class ExAbnormalStatusUpdateFromTarget implements IClientOutgoingPacket
{
private final L2Character _character;
private List<Effect> _effects = new ArrayList<>();
private static class Effect
{
protected int _skillId;
protected int _level;
protected int _subLevel;
protected int _abnormalType;
protected int _duration;
protected int _caster;
public Effect(BuffInfo info)
{
final Skill skill = info.getSkill();
final L2Character caster = info.getEffector();
int casterId = 0;
if (caster != null)
{
casterId = caster.getObjectId();
}
_skillId = skill.getDisplayId();
_level = skill.getDisplayLevel();
_subLevel = skill.getSubLevel();
_abnormalType = skill.getAbnormalType().getClientId();
_duration = skill.isAura() ? -1 : info.getTime();
_caster = casterId;
}
}
private final List<BuffInfo> _effects;
public ExAbnormalStatusUpdateFromTarget(L2Character character)
{
@ -69,7 +39,6 @@ public class ExAbnormalStatusUpdateFromTarget implements IClientOutgoingPacket
.filter(Objects::nonNull)
.filter(BuffInfo::isInUse)
.filter(b -> !b.getSkill().isToggle())
.map(Effect::new)
.collect(Collectors.toList());
//@formatter:on
}
@ -82,14 +51,14 @@ public class ExAbnormalStatusUpdateFromTarget implements IClientOutgoingPacket
packet.writeD(_character.getObjectId());
packet.writeH(_effects.size());
for (Effect info : _effects)
for (BuffInfo info : _effects)
{
packet.writeD(info._skillId);
packet.writeH(info._level);
packet.writeH(info._subLevel);
packet.writeH(info._abnormalType);
writeOptionalD(packet, info._duration);
packet.writeD(info._caster);
packet.writeD(info.getSkill().getDisplayId());
packet.writeH(info.getSkill().getDisplayLevel());
packet.writeH(info.getSkill().getSubLevel());
packet.writeH(info.getSkill().getAbnormalType().getClientId());
writeOptionalD(packet, info.getSkill().isAura() ? -1 : info.getTime());
packet.writeD(info.getEffectorObjectId());
}
return true;
}

View File

@ -16,6 +16,8 @@
*/
package handlers.effecthandlers;
import java.util.Collections;
import com.l2jmobius.gameserver.model.L2Object;
import com.l2jmobius.gameserver.model.L2World;
import com.l2jmobius.gameserver.model.StatsSet;
@ -38,6 +40,19 @@ public final class CallSkillOnActionTime extends AbstractEffect
setTicks(params.getInt("ticks"));
}
@Override
public void onStart(L2Character effector, L2Character effected, Skill skill)
{
effected.getEffectList().stopEffects(Collections.singleton(_skill.getSkill().getAbnormalType()));
effected.getEffectList().addBlockedAbnormalTypes(Collections.singleton(_skill.getSkill().getAbnormalType()));
}
@Override
public void onExit(L2Character effector, L2Character effected, Skill skill)
{
effected.getEffectList().removeBlockedAbnormalTypes(Collections.singleton(_skill.getSkill().getAbnormalType()));
}
@Override
public boolean onActionTime(L2Character effector, L2Character effected, Skill skill)
{

View File

@ -136,6 +136,5 @@ public final class Disarmor extends AbstractEffect
}
}
}
super.onExit(effector, effected, skill);
}
}

View File

@ -84,6 +84,5 @@ public final class DoubleCast extends AbstractEffect
return null;
});
}
super.onExit(effector, effected, skill);
}
}

View File

@ -65,15 +65,15 @@ public final class CharEffectList
{
private static final Logger LOGGER = Logger.getLogger(CharEffectList.class.getName());
/** Queue containing all effects from buffs for this effect list. */
private volatile Queue<BuffInfo> _actives;
private volatile Queue<BuffInfo> _actives = new ConcurrentLinkedQueue<>();
/** List containing all passives for this effect list. They bypass most of the actions and they are not included in most operations. */
private volatile Set<BuffInfo> _passives;
private volatile Set<BuffInfo> _passives = ConcurrentHashMap.newKeySet();
/** List containing all options for this effect list. They bypass most of the actions and they are not included in most operations. */
private volatile Set<BuffInfo> _options;
private volatile Set<BuffInfo> _options = ConcurrentHashMap.newKeySet();
/** Map containing the all stacked effect in progress for each {@code AbnormalType}. */
private volatile Set<AbnormalType> _stackedEffects = EnumSet.noneOf(AbnormalType.class);
/** Set containing all {@code AbnormalType}s that shouldn't be added to this creature effect list. */
private volatile Set<AbnormalType> _blockedAbnormalTypes = null;
private volatile Set<AbnormalType> _blockedAbnormalTypes = EnumSet.noneOf(AbnormalType.class);
/** Set containing all abnormal visual effects this creature currently displays. */
private volatile Set<AbnormalVisualEffect> _abnormalVisualEffects = EnumSet.noneOf(AbnormalVisualEffect.class);
/** Short buff skill ID. */
@ -110,7 +110,7 @@ public final class CharEffectList
*/
public Set<BuffInfo> getPassives()
{
return _passives != null ? Collections.unmodifiableSet(_passives) : Collections.emptySet();
return Collections.unmodifiableSet(_passives);
}
/**
@ -119,7 +119,7 @@ public final class CharEffectList
*/
public Set<BuffInfo> getOptions()
{
return _options != null ? Collections.unmodifiableSet(_options) : Collections.emptySet();
return Collections.unmodifiableSet(_options);
}
/**
@ -128,7 +128,7 @@ public final class CharEffectList
*/
public Collection<BuffInfo> getEffects()
{
return _actives != null ? Collections.unmodifiableCollection(_actives) : Collections.emptyList();
return Collections.unmodifiableCollection(_actives);
}
/**
@ -137,7 +137,7 @@ public final class CharEffectList
*/
public List<BuffInfo> getBuffs()
{
return _actives != null ? _actives.stream().filter(b -> !b.getSkill().getBuffType().isBuff()).collect(Collectors.toList()) : Collections.emptyList();
return _actives.stream().filter(b -> !b.getSkill().getBuffType().isBuff()).collect(Collectors.toList());
}
/**
@ -146,7 +146,7 @@ public final class CharEffectList
*/
public List<BuffInfo> getDebuffs()
{
return _actives != null ? _actives.stream().filter(b -> b.getSkill().isDebuff()).collect(Collectors.toList()) : Collections.emptyList();
return _actives.stream().filter(b -> b.getSkill().isDebuff()).collect(Collectors.toList());
}
/**
@ -156,7 +156,7 @@ public final class CharEffectList
*/
public boolean isAffectedBySkill(int skillId)
{
return ((_actives != null) && _actives.stream().anyMatch(i -> i.getSkill().getId() == skillId)) || ((_passives != null) && _passives.stream().anyMatch(i -> i.getSkill().getId() == skillId));
return (_actives.stream().anyMatch(i -> i.getSkill().getId() == skillId)) || (_passives.stream().anyMatch(i -> i.getSkill().getId() == skillId));
}
/**
@ -166,7 +166,7 @@ public final class CharEffectList
*/
public BuffInfo getBuffInfoBySkillId(int skillId)
{
return Stream.concat(_actives != null ? _actives.stream() : Stream.empty(), _passives != null ? _passives.stream() : Stream.empty()).filter(b -> b.getSkill().getId() == skillId).findFirst().orElse(null);
return Stream.concat(_actives.stream(), _passives.stream()).filter(b -> b.getSkill().getId() == skillId).findFirst().orElse(null);
}
/**
@ -216,18 +216,6 @@ public final class CharEffectList
*/
public void addBlockedAbnormalTypes(Set<AbnormalType> blockedAbnormalTypes)
{
// Initialize
if (_blockedAbnormalTypes == null)
{
synchronized (this)
{
if (_blockedAbnormalTypes == null)
{
_blockedAbnormalTypes = EnumSet.copyOf(blockedAbnormalTypes);
}
}
}
_blockedAbnormalTypes.addAll(blockedAbnormalTypes);
}
@ -238,7 +226,7 @@ public final class CharEffectList
*/
public boolean removeBlockedAbnormalTypes(Set<AbnormalType> blockedBuffSlots)
{
return (_blockedAbnormalTypes != null) && _blockedAbnormalTypes.removeAll(blockedBuffSlots);
return _blockedAbnormalTypes.removeAll(blockedBuffSlots);
}
/**
@ -247,7 +235,7 @@ public final class CharEffectList
*/
public Set<AbnormalType> getBlockedAbnormalTypes()
{
return _blockedAbnormalTypes != null ? Collections.unmodifiableSet(_blockedAbnormalTypes) : Collections.emptySet();
return Collections.unmodifiableSet(_blockedAbnormalTypes);
}
/**
@ -277,7 +265,7 @@ public final class CharEffectList
*/
public int getBuffCount()
{
return _actives != null ? (_buffCount.get() - _hiddenBuffs.get()) : 0;
return !_actives.isEmpty() ? (_buffCount.get() - _hiddenBuffs.get()) : 0;
}
/**
@ -374,7 +362,7 @@ public final class CharEffectList
*/
public void stopAllPassives(boolean update, boolean broadcast)
{
if (_passives != null)
if (!_passives.isEmpty())
{
_passives.forEach(this::remove);
// Update stats, effect flags and icons.
@ -392,7 +380,7 @@ public final class CharEffectList
*/
public void stopAllOptions(boolean update, boolean broadcast)
{
if (_options != null)
if (!_options.isEmpty())
{
_options.forEach(this::remove);
// Update stats, effect flags and icons.
@ -490,7 +478,7 @@ public final class CharEffectList
*/
public void stopEffects(Predicate<BuffInfo> filter, boolean update, boolean broadcast)
{
if (_actives != null)
if (!_actives.isEmpty())
{
_actives.stream().filter(filter).forEach(this::remove);
@ -678,6 +666,10 @@ public final class CharEffectList
{
// Remove active effect.
removeActive(info, removed);
if (_owner.isNpc()) // Fix for all NPC debuff animations removed.
{
updateEffectList(broadcast);
}
}
// Update stats, effect flags and icons.
@ -693,7 +685,7 @@ public final class CharEffectList
*/
private synchronized void removeActive(BuffInfo info, boolean removed)
{
if (_actives != null)
if (!_actives.isEmpty())
{
// Removes the buff from the given effect list.
_actives.remove(info);
@ -716,7 +708,7 @@ public final class CharEffectList
private void removePassive(BuffInfo info, boolean removed)
{
if (_passives != null)
if (!_passives.isEmpty())
{
_passives.remove(info);
info.stopAllEffects(removed);
@ -725,7 +717,7 @@ public final class CharEffectList
private void removeOption(BuffInfo info, boolean removed)
{
if (_options != null)
if (!_options.isEmpty())
{
_options.remove(info);
info.stopAllEffects(removed);
@ -821,12 +813,6 @@ public final class CharEffectList
}
}
// Initialize
if (_actives == null)
{
_actives = new ConcurrentLinkedQueue<>();
}
// Manage effect stacking.
if (hasAbnormalType(skill.getAbnormalType()))
{
@ -857,7 +843,7 @@ public final class CharEffectList
}
else
{
// Remove effect that gets overriden.
// Remove effect that gets overridden.
remove(existingInfo);
}
}
@ -865,7 +851,7 @@ public final class CharEffectList
{
info.setInUse(false);
}
else // The effect we try to add should be overriden.
else // The effect we try to add should be overridden.
{
return;
}
@ -918,18 +904,6 @@ public final class CharEffectList
return;
}
// Initialize
if (_passives == null)
{
synchronized (this)
{
if (_passives == null)
{
_passives = ConcurrentHashMap.newKeySet();
}
}
}
// Remove previous passives of this id.
_passives.stream().filter(Objects::nonNull).filter(b -> b.getSkill().getId() == skill.getId()).forEach(b ->
{
@ -947,18 +921,6 @@ public final class CharEffectList
{
if (info.getOption() != null)
{
// Initialize
if (_options == null)
{
synchronized (this)
{
if (_options == null)
{
_options = ConcurrentHashMap.newKeySet();
}
}
}
// Remove previous options of this id.
_options.stream().filter(Objects::nonNull).filter(b -> b.getOption().getId() == info.getOption().getId()).forEach(b ->
{
@ -988,7 +950,7 @@ public final class CharEffectList
final Optional<PartySpelled> ps = ((party != null) || _owner.isSummon()) ? Optional.of(new PartySpelled(_owner)) : Optional.empty();
final Optional<ExOlympiadSpelledInfo> os = (player.isInOlympiadMode() && player.isOlympiadStart()) ? Optional.of(new ExOlympiadSpelledInfo(player)) : Optional.empty();
if (_actives != null)
if (!_actives.isEmpty())
{
//@formatter:off
_actives.stream()
@ -1109,8 +1071,6 @@ public final class CharEffectList
final Set<BuffInfo> unhideBuffs = new HashSet<>();
// Recalculate new flags
if (_actives != null)
{
for (BuffInfo info : _actives)
{
if (info != null)
@ -1144,7 +1104,14 @@ public final class CharEffectList
// Add AbnormalVisualEffect flag.
if (skill.hasAbnormalVisualEffects())
{
abnormalVisualEffectFlags.addAll(skill.getAbnormalVisualEffects());
for (AbnormalVisualEffect ave : skill.getAbnormalVisualEffects())
{
abnormalVisualEffectFlags.add(ave);
_abnormalVisualEffects.add(ave);
}
if (broadcast)
{
_owner.updateAbnormalVisualEffects();
}
}
}
@ -1167,7 +1134,7 @@ public final class CharEffectList
if (broadcast)
{
// Check if there is change in AbnormalVisualEffect
if ((abnormalVisualEffectFlags.size() != _abnormalVisualEffects.size()) || !abnormalVisualEffectFlags.containsAll(_abnormalVisualEffects))
if (!abnormalVisualEffectFlags.containsAll(_abnormalVisualEffects))
{
_abnormalVisualEffects = abnormalVisualEffectFlags;
_owner.updateAbnormalVisualEffects();

View File

@ -77,7 +77,6 @@ public class DoppelgangerInstance extends L2Npc
info.setAbnormalTime(summonerInfo.getAbnormalTime());
getEffectList().add(info);
}
}
}
}

View File

@ -786,7 +786,7 @@ public class CharStat
final CharEffectList effectList = _activeChar.getEffectList();
final Stream<BuffInfo> passives = effectList.getPassives().stream().filter(BuffInfo::isInUse).filter(info -> info.getSkill().checkConditions(SkillConditionScope.PASSIVE, _activeChar, _activeChar));
final Stream<BuffInfo> options = effectList.getOptions().stream().filter(BuffInfo::isInUse);
final Stream<BuffInfo> effectsStream = Stream.concat(effectList.getEffects().stream().filter(BuffInfo::isInUse), Stream.concat(passives != null ? passives : Stream.empty(), options != null ? options : Stream.empty()));
final Stream<BuffInfo> effectsStream = Stream.concat(effectList.getEffects().stream().filter(BuffInfo::isInUse), Stream.concat(passives, options));
// Call pump to each effect
//@formatter:off

View File

@ -389,10 +389,10 @@ public final class BuffInfo
for (AbstractEffect effect : _effects)
{
// Instant effects shouldn't call onExit(..).
if (!effect.isInstant())
{
// if (!effect.isInstant())
// {
effect.onExit(_effector, _effected, _skill);
}
// }
}
// Set the proper system message.

View File

@ -21,13 +21,11 @@ import java.util.List;
import com.l2jmobius.commons.network.PacketWriter;
import com.l2jmobius.gameserver.model.skills.BuffInfo;
import com.l2jmobius.gameserver.model.skills.Skill;
import com.l2jmobius.gameserver.network.OutgoingPackets;
public class AbnormalStatusUpdate implements IClientOutgoingPacket
{
private final List<BuffInfo> _effects = new ArrayList<>();
private final List<Skill> _effects2 = new ArrayList<>();
public void addSkill(BuffInfo info)
{
@ -37,20 +35,12 @@ public class AbnormalStatusUpdate implements IClientOutgoingPacket
}
}
public void addSkill(Skill skill)
{
if (!skill.isHealingPotionSkill())
{
_effects2.add(skill);
}
}
@Override
public boolean write(PacketWriter packet)
{
OutgoingPackets.ABNORMAL_STATUS_UPDATE.writeId(packet);
packet.writeH(_effects.size() + _effects2.size());
packet.writeH(_effects.size());
for (BuffInfo info : _effects)
{
if ((info != null) && info.isInUse())
@ -62,17 +52,6 @@ public class AbnormalStatusUpdate implements IClientOutgoingPacket
writeOptionalD(packet, info.getSkill().isAura() ? -1 : info.getTime());
}
}
for (Skill skill : _effects2)
{
if (skill != null)
{
packet.writeD(skill.getDisplayId());
packet.writeH(skill.getDisplayLevel());
packet.writeH(0x00); // Sub level
packet.writeD(skill.getAbnormalType().getClientId());
packet.writeH(-1);
}
}
return true;
}
}

View File

@ -16,7 +16,6 @@
*/
package com.l2jmobius.gameserver.network.serverpackets;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
@ -24,41 +23,12 @@ import java.util.stream.Collectors;
import com.l2jmobius.commons.network.PacketWriter;
import com.l2jmobius.gameserver.model.actor.L2Character;
import com.l2jmobius.gameserver.model.skills.BuffInfo;
import com.l2jmobius.gameserver.model.skills.Skill;
import com.l2jmobius.gameserver.network.OutgoingPackets;
public class ExAbnormalStatusUpdateFromTarget implements IClientOutgoingPacket
{
private final L2Character _character;
private List<Effect> _effects = new ArrayList<>();
private static class Effect
{
protected int _skillId;
protected int _level;
protected int _subLevel;
protected int _abnormalType;
protected int _duration;
protected int _caster;
public Effect(BuffInfo info)
{
final Skill skill = info.getSkill();
final L2Character caster = info.getEffector();
int casterId = 0;
if (caster != null)
{
casterId = caster.getObjectId();
}
_skillId = skill.getDisplayId();
_level = skill.getDisplayLevel();
_subLevel = skill.getSubLevel();
_abnormalType = skill.getAbnormalType().getClientId();
_duration = skill.isAura() ? -1 : info.getTime();
_caster = casterId;
}
}
private final List<BuffInfo> _effects;
public ExAbnormalStatusUpdateFromTarget(L2Character character)
{
@ -69,7 +39,6 @@ public class ExAbnormalStatusUpdateFromTarget implements IClientOutgoingPacket
.filter(Objects::nonNull)
.filter(BuffInfo::isInUse)
.filter(b -> !b.getSkill().isToggle())
.map(Effect::new)
.collect(Collectors.toList());
//@formatter:on
}
@ -82,14 +51,14 @@ public class ExAbnormalStatusUpdateFromTarget implements IClientOutgoingPacket
packet.writeD(_character.getObjectId());
packet.writeH(_effects.size());
for (Effect info : _effects)
for (BuffInfo info : _effects)
{
packet.writeD(info._skillId);
packet.writeH(info._level);
packet.writeH(info._subLevel);
packet.writeH(info._abnormalType);
writeOptionalD(packet, info._duration);
packet.writeD(info._caster);
packet.writeD(info.getSkill().getDisplayId());
packet.writeH(info.getSkill().getDisplayLevel());
packet.writeH(info.getSkill().getSubLevel());
packet.writeH(info.getSkill().getAbnormalType().getClientId());
writeOptionalD(packet, info.getSkill().isAura() ? -1 : info.getTime());
packet.writeD(info.getEffectorObjectId());
}
return true;
}

View File

@ -16,6 +16,8 @@
*/
package handlers.effecthandlers;
import java.util.Collections;
import com.l2jmobius.gameserver.model.L2Object;
import com.l2jmobius.gameserver.model.L2World;
import com.l2jmobius.gameserver.model.StatsSet;
@ -38,6 +40,19 @@ public final class CallSkillOnActionTime extends AbstractEffect
setTicks(params.getInt("ticks"));
}
@Override
public void onStart(L2Character effector, L2Character effected, Skill skill)
{
effected.getEffectList().stopEffects(Collections.singleton(_skill.getSkill().getAbnormalType()));
effected.getEffectList().addBlockedAbnormalTypes(Collections.singleton(_skill.getSkill().getAbnormalType()));
}
@Override
public void onExit(L2Character effector, L2Character effected, Skill skill)
{
effected.getEffectList().removeBlockedAbnormalTypes(Collections.singleton(_skill.getSkill().getAbnormalType()));
}
@Override
public boolean onActionTime(L2Character effector, L2Character effected, Skill skill)
{

View File

@ -136,6 +136,5 @@ public final class Disarmor extends AbstractEffect
}
}
}
super.onExit(effector, effected, skill);
}
}

View File

@ -84,6 +84,5 @@ public final class DoubleCast extends AbstractEffect
return null;
});
}
super.onExit(effector, effected, skill);
}
}

View File

@ -65,15 +65,15 @@ public final class CharEffectList
{
private static final Logger LOGGER = Logger.getLogger(CharEffectList.class.getName());
/** Queue containing all effects from buffs for this effect list. */
private volatile Queue<BuffInfo> _actives;
private volatile Queue<BuffInfo> _actives = new ConcurrentLinkedQueue<>();
/** List containing all passives for this effect list. They bypass most of the actions and they are not included in most operations. */
private volatile Set<BuffInfo> _passives;
private volatile Set<BuffInfo> _passives = ConcurrentHashMap.newKeySet();
/** List containing all options for this effect list. They bypass most of the actions and they are not included in most operations. */
private volatile Set<BuffInfo> _options;
private volatile Set<BuffInfo> _options = ConcurrentHashMap.newKeySet();
/** Map containing the all stacked effect in progress for each {@code AbnormalType}. */
private volatile Set<AbnormalType> _stackedEffects = EnumSet.noneOf(AbnormalType.class);
/** Set containing all {@code AbnormalType}s that shouldn't be added to this creature effect list. */
private volatile Set<AbnormalType> _blockedAbnormalTypes = null;
private volatile Set<AbnormalType> _blockedAbnormalTypes = EnumSet.noneOf(AbnormalType.class);
/** Set containing all abnormal visual effects this creature currently displays. */
private volatile Set<AbnormalVisualEffect> _abnormalVisualEffects = EnumSet.noneOf(AbnormalVisualEffect.class);
/** Short buff skill ID. */
@ -110,7 +110,7 @@ public final class CharEffectList
*/
public Set<BuffInfo> getPassives()
{
return _passives != null ? Collections.unmodifiableSet(_passives) : Collections.emptySet();
return Collections.unmodifiableSet(_passives);
}
/**
@ -119,7 +119,7 @@ public final class CharEffectList
*/
public Set<BuffInfo> getOptions()
{
return _options != null ? Collections.unmodifiableSet(_options) : Collections.emptySet();
return Collections.unmodifiableSet(_options);
}
/**
@ -128,7 +128,7 @@ public final class CharEffectList
*/
public Collection<BuffInfo> getEffects()
{
return _actives != null ? Collections.unmodifiableCollection(_actives) : Collections.emptyList();
return Collections.unmodifiableCollection(_actives);
}
/**
@ -137,7 +137,7 @@ public final class CharEffectList
*/
public List<BuffInfo> getBuffs()
{
return _actives != null ? _actives.stream().filter(b -> !b.getSkill().getBuffType().isBuff()).collect(Collectors.toList()) : Collections.emptyList();
return _actives.stream().filter(b -> !b.getSkill().getBuffType().isBuff()).collect(Collectors.toList());
}
/**
@ -146,7 +146,7 @@ public final class CharEffectList
*/
public List<BuffInfo> getDebuffs()
{
return _actives != null ? _actives.stream().filter(b -> b.getSkill().isDebuff()).collect(Collectors.toList()) : Collections.emptyList();
return _actives.stream().filter(b -> b.getSkill().isDebuff()).collect(Collectors.toList());
}
/**
@ -156,7 +156,7 @@ public final class CharEffectList
*/
public boolean isAffectedBySkill(int skillId)
{
return ((_actives != null) && _actives.stream().anyMatch(i -> i.getSkill().getId() == skillId)) || ((_passives != null) && _passives.stream().anyMatch(i -> i.getSkill().getId() == skillId));
return (_actives.stream().anyMatch(i -> i.getSkill().getId() == skillId)) || (_passives.stream().anyMatch(i -> i.getSkill().getId() == skillId));
}
/**
@ -166,7 +166,7 @@ public final class CharEffectList
*/
public BuffInfo getBuffInfoBySkillId(int skillId)
{
return Stream.concat(_actives != null ? _actives.stream() : Stream.empty(), _passives != null ? _passives.stream() : Stream.empty()).filter(b -> b.getSkill().getId() == skillId).findFirst().orElse(null);
return Stream.concat(_actives.stream(), _passives.stream()).filter(b -> b.getSkill().getId() == skillId).findFirst().orElse(null);
}
/**
@ -216,18 +216,6 @@ public final class CharEffectList
*/
public void addBlockedAbnormalTypes(Set<AbnormalType> blockedAbnormalTypes)
{
// Initialize
if (_blockedAbnormalTypes == null)
{
synchronized (this)
{
if (_blockedAbnormalTypes == null)
{
_blockedAbnormalTypes = EnumSet.copyOf(blockedAbnormalTypes);
}
}
}
_blockedAbnormalTypes.addAll(blockedAbnormalTypes);
}
@ -238,7 +226,7 @@ public final class CharEffectList
*/
public boolean removeBlockedAbnormalTypes(Set<AbnormalType> blockedBuffSlots)
{
return (_blockedAbnormalTypes != null) && _blockedAbnormalTypes.removeAll(blockedBuffSlots);
return _blockedAbnormalTypes.removeAll(blockedBuffSlots);
}
/**
@ -247,7 +235,7 @@ public final class CharEffectList
*/
public Set<AbnormalType> getBlockedAbnormalTypes()
{
return _blockedAbnormalTypes != null ? Collections.unmodifiableSet(_blockedAbnormalTypes) : Collections.emptySet();
return Collections.unmodifiableSet(_blockedAbnormalTypes);
}
/**
@ -277,7 +265,7 @@ public final class CharEffectList
*/
public int getBuffCount()
{
return _actives != null ? (_buffCount.get() - _hiddenBuffs.get()) : 0;
return !_actives.isEmpty() ? (_buffCount.get() - _hiddenBuffs.get()) : 0;
}
/**
@ -374,7 +362,7 @@ public final class CharEffectList
*/
public void stopAllPassives(boolean update, boolean broadcast)
{
if (_passives != null)
if (!_passives.isEmpty())
{
_passives.forEach(this::remove);
// Update stats, effect flags and icons.
@ -392,7 +380,7 @@ public final class CharEffectList
*/
public void stopAllOptions(boolean update, boolean broadcast)
{
if (_options != null)
if (!_options.isEmpty())
{
_options.forEach(this::remove);
// Update stats, effect flags and icons.
@ -490,7 +478,7 @@ public final class CharEffectList
*/
public void stopEffects(Predicate<BuffInfo> filter, boolean update, boolean broadcast)
{
if (_actives != null)
if (!_actives.isEmpty())
{
_actives.stream().filter(filter).forEach(this::remove);
@ -678,6 +666,10 @@ public final class CharEffectList
{
// Remove active effect.
removeActive(info, removed);
if (_owner.isNpc()) // Fix for all NPC debuff animations removed.
{
updateEffectList(broadcast);
}
}
// Update stats, effect flags and icons.
@ -693,7 +685,7 @@ public final class CharEffectList
*/
private synchronized void removeActive(BuffInfo info, boolean removed)
{
if (_actives != null)
if (!_actives.isEmpty())
{
// Removes the buff from the given effect list.
_actives.remove(info);
@ -716,7 +708,7 @@ public final class CharEffectList
private void removePassive(BuffInfo info, boolean removed)
{
if (_passives != null)
if (!_passives.isEmpty())
{
_passives.remove(info);
info.stopAllEffects(removed);
@ -725,7 +717,7 @@ public final class CharEffectList
private void removeOption(BuffInfo info, boolean removed)
{
if (_options != null)
if (!_options.isEmpty())
{
_options.remove(info);
info.stopAllEffects(removed);
@ -821,12 +813,6 @@ public final class CharEffectList
}
}
// Initialize
if (_actives == null)
{
_actives = new ConcurrentLinkedQueue<>();
}
// Manage effect stacking.
if (hasAbnormalType(skill.getAbnormalType()))
{
@ -857,7 +843,7 @@ public final class CharEffectList
}
else
{
// Remove effect that gets overriden.
// Remove effect that gets overridden.
remove(existingInfo);
}
}
@ -865,7 +851,7 @@ public final class CharEffectList
{
info.setInUse(false);
}
else // The effect we try to add should be overriden.
else // The effect we try to add should be overridden.
{
return;
}
@ -918,18 +904,6 @@ public final class CharEffectList
return;
}
// Initialize
if (_passives == null)
{
synchronized (this)
{
if (_passives == null)
{
_passives = ConcurrentHashMap.newKeySet();
}
}
}
// Remove previous passives of this id.
_passives.stream().filter(Objects::nonNull).filter(b -> b.getSkill().getId() == skill.getId()).forEach(b ->
{
@ -947,18 +921,6 @@ public final class CharEffectList
{
if (info.getOption() != null)
{
// Initialize
if (_options == null)
{
synchronized (this)
{
if (_options == null)
{
_options = ConcurrentHashMap.newKeySet();
}
}
}
// Remove previous options of this id.
_options.stream().filter(Objects::nonNull).filter(b -> b.getOption().getId() == info.getOption().getId()).forEach(b ->
{
@ -988,7 +950,7 @@ public final class CharEffectList
final Optional<PartySpelled> ps = ((party != null) || _owner.isSummon()) ? Optional.of(new PartySpelled(_owner)) : Optional.empty();
final Optional<ExOlympiadSpelledInfo> os = (player.isInOlympiadMode() && player.isOlympiadStart()) ? Optional.of(new ExOlympiadSpelledInfo(player)) : Optional.empty();
if (_actives != null)
if (!_actives.isEmpty())
{
//@formatter:off
_actives.stream()
@ -1109,8 +1071,6 @@ public final class CharEffectList
final Set<BuffInfo> unhideBuffs = new HashSet<>();
// Recalculate new flags
if (_actives != null)
{
for (BuffInfo info : _actives)
{
if (info != null)
@ -1144,7 +1104,14 @@ public final class CharEffectList
// Add AbnormalVisualEffect flag.
if (skill.hasAbnormalVisualEffects())
{
abnormalVisualEffectFlags.addAll(skill.getAbnormalVisualEffects());
for (AbnormalVisualEffect ave : skill.getAbnormalVisualEffects())
{
abnormalVisualEffectFlags.add(ave);
_abnormalVisualEffects.add(ave);
}
if (broadcast)
{
_owner.updateAbnormalVisualEffects();
}
}
}
@ -1167,7 +1134,7 @@ public final class CharEffectList
if (broadcast)
{
// Check if there is change in AbnormalVisualEffect
if ((abnormalVisualEffectFlags.size() != _abnormalVisualEffects.size()) || !abnormalVisualEffectFlags.containsAll(_abnormalVisualEffects))
if (!abnormalVisualEffectFlags.containsAll(_abnormalVisualEffects))
{
_abnormalVisualEffects = abnormalVisualEffectFlags;
_owner.updateAbnormalVisualEffects();

View File

@ -77,7 +77,6 @@ public class DoppelgangerInstance extends L2Npc
info.setAbnormalTime(summonerInfo.getAbnormalTime());
getEffectList().add(info);
}
}
}
}

View File

@ -776,7 +776,7 @@ public class CharStat
final CharEffectList effectList = _activeChar.getEffectList();
final Stream<BuffInfo> passives = effectList.getPassives().stream().filter(BuffInfo::isInUse).filter(info -> info.getSkill().checkConditions(SkillConditionScope.PASSIVE, _activeChar, _activeChar));
final Stream<BuffInfo> options = effectList.getOptions().stream().filter(BuffInfo::isInUse);
final Stream<BuffInfo> effectsStream = Stream.concat(effectList.getEffects().stream().filter(BuffInfo::isInUse), Stream.concat(passives != null ? passives : Stream.empty(), options != null ? options : Stream.empty()));
final Stream<BuffInfo> effectsStream = Stream.concat(effectList.getEffects().stream().filter(BuffInfo::isInUse), Stream.concat(passives, options));
// Call pump to each effect
//@formatter:off

View File

@ -389,10 +389,10 @@ public final class BuffInfo
for (AbstractEffect effect : _effects)
{
// Instant effects shouldn't call onExit(..).
if (!effect.isInstant())
{
// if (!effect.isInstant())
// {
effect.onExit(_effector, _effected, _skill);
}
// }
}
// Set the proper system message.

View File

@ -21,17 +21,11 @@ import java.util.List;
import com.l2jmobius.commons.network.PacketWriter;
import com.l2jmobius.gameserver.model.skills.BuffInfo;
import com.l2jmobius.gameserver.model.skills.Skill;
import com.l2jmobius.gameserver.network.OutgoingPackets;
/**
* @author Mobius
* @version Classic 2.0
*/
public class AbnormalStatusUpdate implements IClientOutgoingPacket
{
private final List<BuffInfo> _effects = new ArrayList<>();
private final List<Skill> _effects2 = new ArrayList<>();
public void addSkill(BuffInfo info)
{
@ -41,38 +35,21 @@ public class AbnormalStatusUpdate implements IClientOutgoingPacket
}
}
public void addSkill(Skill skill)
{
if (!skill.isHealingPotionSkill())
{
_effects2.add(skill);
}
}
@Override
public boolean write(PacketWriter packet)
{
OutgoingPackets.ABNORMAL_STATUS_UPDATE.writeId(packet);
packet.writeH(_effects.size() + _effects2.size());
packet.writeH(_effects.size());
for (BuffInfo info : _effects)
{
if ((info != null) && info.isInUse())
{
packet.writeD(info.getSkill().getDisplayId());
packet.writeH(info.getSkill().getDisplayLevel());
packet.writeD(0x00);
packet.writeH(info.getSkill().isAura() ? -1 : info.getTime());
}
}
for (Skill skill : _effects2)
{
if (skill != null)
{
packet.writeD(skill.getDisplayId());
packet.writeH(skill.getDisplayLevel());
packet.writeD(skill.getAbnormalType().getClientId());
packet.writeH(-1);
// packet.writeH(info.getSkill().getSubLevel());
packet.writeD(info.getSkill().getAbnormalType().getClientId());
writeOptionalD(packet, info.getSkill().isAura() ? -1 : info.getTime());
}
}
return true;

View File

@ -16,8 +16,8 @@
*/
package com.l2jmobius.gameserver.network.serverpackets;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
import com.l2jmobius.commons.network.PacketWriter;
@ -25,35 +25,10 @@ import com.l2jmobius.gameserver.model.actor.L2Character;
import com.l2jmobius.gameserver.model.skills.BuffInfo;
import com.l2jmobius.gameserver.network.OutgoingPackets;
/**
* @author proGenitor <br>
* Experimental packet compatible for L2Classic 2.0.
*/
public class ExAbnormalStatusUpdateFromTarget implements IClientOutgoingPacket
{
private final L2Character _character;
private List<Effect> _effects = new ArrayList<>();
private static class Effect
{
protected int _skillId;
protected int _level;
protected int _subLevel;
protected int _abnormalType;
protected int _duration;
protected int _caster;
public Effect(BuffInfo info)
{
final L2Character caster = info.getEffector();
int casterId = 0;
if (caster != null)
{
casterId = caster.getObjectId();
}
_caster = casterId;
}
}
private final List<BuffInfo> _effects;
public ExAbnormalStatusUpdateFromTarget(L2Character character)
{
@ -61,7 +36,9 @@ public class ExAbnormalStatusUpdateFromTarget implements IClientOutgoingPacket
_character = character;
_effects = character.getEffectList().getEffects()
.stream()
.map(Effect::new)
.filter(Objects::nonNull)
.filter(BuffInfo::isInUse)
.filter(b -> !b.getSkill().isToggle())
.collect(Collectors.toList());
//@formatter:on
}
@ -74,14 +51,14 @@ public class ExAbnormalStatusUpdateFromTarget implements IClientOutgoingPacket
packet.writeD(_character.getObjectId());
packet.writeH(_effects.size());
for (Effect info : _effects)
for (BuffInfo info : _effects)
{
packet.writeD(info._skillId);
packet.writeH(info._level);
packet.writeH(info._subLevel);
packet.writeH(info._abnormalType);
writeOptionalD(packet, info._duration);
packet.writeD(info._caster);
packet.writeD(info.getSkill().getDisplayId());
packet.writeH(info.getSkill().getDisplayLevel());
// packet.writeH(info.getSkill().getSubLevel());
packet.writeH(info.getSkill().getAbnormalType().getClientId());
writeOptionalD(packet, info.getSkill().isAura() ? -1 : info.getTime());
packet.writeD(info.getEffectorObjectId());
}
return true;
}

View File

@ -16,6 +16,8 @@
*/
package handlers.effecthandlers;
import java.util.Collections;
import com.l2jmobius.gameserver.model.L2Object;
import com.l2jmobius.gameserver.model.L2World;
import com.l2jmobius.gameserver.model.StatsSet;
@ -38,6 +40,19 @@ public final class CallSkillOnActionTime extends AbstractEffect
setTicks(params.getInt("ticks"));
}
@Override
public void onStart(L2Character effector, L2Character effected, Skill skill)
{
effected.getEffectList().stopEffects(Collections.singleton(_skill.getSkill().getAbnormalType()));
effected.getEffectList().addBlockedAbnormalTypes(Collections.singleton(_skill.getSkill().getAbnormalType()));
}
@Override
public void onExit(L2Character effector, L2Character effected, Skill skill)
{
effected.getEffectList().removeBlockedAbnormalTypes(Collections.singleton(_skill.getSkill().getAbnormalType()));
}
@Override
public boolean onActionTime(L2Character effector, L2Character effected, Skill skill)
{

View File

@ -136,6 +136,5 @@ public final class Disarmor extends AbstractEffect
}
}
}
super.onExit(effector, effected, skill);
}
}

View File

@ -84,6 +84,5 @@ public final class DoubleCast extends AbstractEffect
return null;
});
}
super.onExit(effector, effected, skill);
}
}

View File

@ -65,15 +65,15 @@ public final class CharEffectList
{
private static final Logger LOGGER = Logger.getLogger(CharEffectList.class.getName());
/** Queue containing all effects from buffs for this effect list. */
private volatile Queue<BuffInfo> _actives;
private volatile Queue<BuffInfo> _actives = new ConcurrentLinkedQueue<>();
/** List containing all passives for this effect list. They bypass most of the actions and they are not included in most operations. */
private volatile Set<BuffInfo> _passives;
private volatile Set<BuffInfo> _passives = ConcurrentHashMap.newKeySet();
/** List containing all options for this effect list. They bypass most of the actions and they are not included in most operations. */
private volatile Set<BuffInfo> _options;
private volatile Set<BuffInfo> _options = ConcurrentHashMap.newKeySet();
/** Map containing the all stacked effect in progress for each {@code AbnormalType}. */
private volatile Set<AbnormalType> _stackedEffects = EnumSet.noneOf(AbnormalType.class);
/** Set containing all {@code AbnormalType}s that shouldn't be added to this creature effect list. */
private volatile Set<AbnormalType> _blockedAbnormalTypes = null;
private volatile Set<AbnormalType> _blockedAbnormalTypes = EnumSet.noneOf(AbnormalType.class);
/** Set containing all abnormal visual effects this creature currently displays. */
private volatile Set<AbnormalVisualEffect> _abnormalVisualEffects = EnumSet.noneOf(AbnormalVisualEffect.class);
/** Short buff skill ID. */
@ -110,7 +110,7 @@ public final class CharEffectList
*/
public Set<BuffInfo> getPassives()
{
return _passives != null ? Collections.unmodifiableSet(_passives) : Collections.emptySet();
return Collections.unmodifiableSet(_passives);
}
/**
@ -119,7 +119,7 @@ public final class CharEffectList
*/
public Set<BuffInfo> getOptions()
{
return _options != null ? Collections.unmodifiableSet(_options) : Collections.emptySet();
return Collections.unmodifiableSet(_options);
}
/**
@ -128,7 +128,7 @@ public final class CharEffectList
*/
public Collection<BuffInfo> getEffects()
{
return _actives != null ? Collections.unmodifiableCollection(_actives) : Collections.emptyList();
return Collections.unmodifiableCollection(_actives);
}
/**
@ -137,7 +137,7 @@ public final class CharEffectList
*/
public List<BuffInfo> getBuffs()
{
return _actives != null ? _actives.stream().filter(b -> !b.getSkill().getBuffType().isBuff()).collect(Collectors.toList()) : Collections.emptyList();
return _actives.stream().filter(b -> !b.getSkill().getBuffType().isBuff()).collect(Collectors.toList());
}
/**
@ -146,7 +146,7 @@ public final class CharEffectList
*/
public List<BuffInfo> getDebuffs()
{
return _actives != null ? _actives.stream().filter(b -> b.getSkill().isDebuff()).collect(Collectors.toList()) : Collections.emptyList();
return _actives.stream().filter(b -> b.getSkill().isDebuff()).collect(Collectors.toList());
}
/**
@ -156,7 +156,7 @@ public final class CharEffectList
*/
public boolean isAffectedBySkill(int skillId)
{
return ((_actives != null) && _actives.stream().anyMatch(i -> i.getSkill().getId() == skillId)) || ((_passives != null) && _passives.stream().anyMatch(i -> i.getSkill().getId() == skillId));
return (_actives.stream().anyMatch(i -> i.getSkill().getId() == skillId)) || (_passives.stream().anyMatch(i -> i.getSkill().getId() == skillId));
}
/**
@ -166,7 +166,7 @@ public final class CharEffectList
*/
public BuffInfo getBuffInfoBySkillId(int skillId)
{
return Stream.concat(_actives != null ? _actives.stream() : Stream.empty(), _passives != null ? _passives.stream() : Stream.empty()).filter(b -> b.getSkill().getId() == skillId).findFirst().orElse(null);
return Stream.concat(_actives.stream(), _passives.stream()).filter(b -> b.getSkill().getId() == skillId).findFirst().orElse(null);
}
/**
@ -216,18 +216,6 @@ public final class CharEffectList
*/
public void addBlockedAbnormalTypes(Set<AbnormalType> blockedAbnormalTypes)
{
// Initialize
if (_blockedAbnormalTypes == null)
{
synchronized (this)
{
if (_blockedAbnormalTypes == null)
{
_blockedAbnormalTypes = EnumSet.copyOf(blockedAbnormalTypes);
}
}
}
_blockedAbnormalTypes.addAll(blockedAbnormalTypes);
}
@ -238,7 +226,7 @@ public final class CharEffectList
*/
public boolean removeBlockedAbnormalTypes(Set<AbnormalType> blockedBuffSlots)
{
return (_blockedAbnormalTypes != null) && _blockedAbnormalTypes.removeAll(blockedBuffSlots);
return _blockedAbnormalTypes.removeAll(blockedBuffSlots);
}
/**
@ -247,7 +235,7 @@ public final class CharEffectList
*/
public Set<AbnormalType> getBlockedAbnormalTypes()
{
return _blockedAbnormalTypes != null ? Collections.unmodifiableSet(_blockedAbnormalTypes) : Collections.emptySet();
return Collections.unmodifiableSet(_blockedAbnormalTypes);
}
/**
@ -277,7 +265,7 @@ public final class CharEffectList
*/
public int getBuffCount()
{
return _actives != null ? (_buffCount.get() - _hiddenBuffs.get()) : 0;
return !_actives.isEmpty() ? (_buffCount.get() - _hiddenBuffs.get()) : 0;
}
/**
@ -374,7 +362,7 @@ public final class CharEffectList
*/
public void stopAllPassives(boolean update, boolean broadcast)
{
if (_passives != null)
if (!_passives.isEmpty())
{
_passives.forEach(this::remove);
// Update stats, effect flags and icons.
@ -392,7 +380,7 @@ public final class CharEffectList
*/
public void stopAllOptions(boolean update, boolean broadcast)
{
if (_options != null)
if (!_options.isEmpty())
{
_options.forEach(this::remove);
// Update stats, effect flags and icons.
@ -490,7 +478,7 @@ public final class CharEffectList
*/
public void stopEffects(Predicate<BuffInfo> filter, boolean update, boolean broadcast)
{
if (_actives != null)
if (!_actives.isEmpty())
{
_actives.stream().filter(filter).forEach(this::remove);
@ -678,6 +666,10 @@ public final class CharEffectList
{
// Remove active effect.
removeActive(info, removed);
if (_owner.isNpc()) // Fix for all NPC debuff animations removed.
{
updateEffectList(broadcast);
}
}
// Update stats, effect flags and icons.
@ -693,7 +685,7 @@ public final class CharEffectList
*/
private synchronized void removeActive(BuffInfo info, boolean removed)
{
if (_actives != null)
if (!_actives.isEmpty())
{
// Removes the buff from the given effect list.
_actives.remove(info);
@ -716,7 +708,7 @@ public final class CharEffectList
private void removePassive(BuffInfo info, boolean removed)
{
if (_passives != null)
if (!_passives.isEmpty())
{
_passives.remove(info);
info.stopAllEffects(removed);
@ -725,7 +717,7 @@ public final class CharEffectList
private void removeOption(BuffInfo info, boolean removed)
{
if (_options != null)
if (!_options.isEmpty())
{
_options.remove(info);
info.stopAllEffects(removed);
@ -821,12 +813,6 @@ public final class CharEffectList
}
}
// Initialize
if (_actives == null)
{
_actives = new ConcurrentLinkedQueue<>();
}
// Manage effect stacking.
if (hasAbnormalType(skill.getAbnormalType()))
{
@ -857,7 +843,7 @@ public final class CharEffectList
}
else
{
// Remove effect that gets overriden.
// Remove effect that gets overridden.
remove(existingInfo);
}
}
@ -865,7 +851,7 @@ public final class CharEffectList
{
info.setInUse(false);
}
else // The effect we try to add should be overriden.
else // The effect we try to add should be overridden.
{
return;
}
@ -918,18 +904,6 @@ public final class CharEffectList
return;
}
// Initialize
if (_passives == null)
{
synchronized (this)
{
if (_passives == null)
{
_passives = ConcurrentHashMap.newKeySet();
}
}
}
// Remove previous passives of this id.
_passives.stream().filter(Objects::nonNull).filter(b -> b.getSkill().getId() == skill.getId()).forEach(b ->
{
@ -947,18 +921,6 @@ public final class CharEffectList
{
if (info.getOption() != null)
{
// Initialize
if (_options == null)
{
synchronized (this)
{
if (_options == null)
{
_options = ConcurrentHashMap.newKeySet();
}
}
}
// Remove previous options of this id.
_options.stream().filter(Objects::nonNull).filter(b -> b.getOption().getId() == info.getOption().getId()).forEach(b ->
{
@ -988,7 +950,7 @@ public final class CharEffectList
final Optional<PartySpelled> ps = ((party != null) || _owner.isSummon()) ? Optional.of(new PartySpelled(_owner)) : Optional.empty();
final Optional<ExOlympiadSpelledInfo> os = (player.isInOlympiadMode() && player.isOlympiadStart()) ? Optional.of(new ExOlympiadSpelledInfo(player)) : Optional.empty();
if (_actives != null)
if (!_actives.isEmpty())
{
//@formatter:off
_actives.stream()
@ -1109,8 +1071,6 @@ public final class CharEffectList
final Set<BuffInfo> unhideBuffs = new HashSet<>();
// Recalculate new flags
if (_actives != null)
{
for (BuffInfo info : _actives)
{
if (info != null)
@ -1144,7 +1104,14 @@ public final class CharEffectList
// Add AbnormalVisualEffect flag.
if (skill.hasAbnormalVisualEffects())
{
abnormalVisualEffectFlags.addAll(skill.getAbnormalVisualEffects());
for (AbnormalVisualEffect ave : skill.getAbnormalVisualEffects())
{
abnormalVisualEffectFlags.add(ave);
_abnormalVisualEffects.add(ave);
}
if (broadcast)
{
_owner.updateAbnormalVisualEffects();
}
}
}
@ -1167,7 +1134,7 @@ public final class CharEffectList
if (broadcast)
{
// Check if there is change in AbnormalVisualEffect
if ((abnormalVisualEffectFlags.size() != _abnormalVisualEffects.size()) || !abnormalVisualEffectFlags.containsAll(_abnormalVisualEffects))
if (!abnormalVisualEffectFlags.containsAll(_abnormalVisualEffects))
{
_abnormalVisualEffects = abnormalVisualEffectFlags;
_owner.updateAbnormalVisualEffects();

View File

@ -77,7 +77,6 @@ public class DoppelgangerInstance extends L2Npc
info.setAbnormalTime(summonerInfo.getAbnormalTime());
getEffectList().add(info);
}
}
}
}

View File

@ -776,7 +776,7 @@ public class CharStat
final CharEffectList effectList = _activeChar.getEffectList();
final Stream<BuffInfo> passives = effectList.getPassives().stream().filter(BuffInfo::isInUse).filter(info -> info.getSkill().checkConditions(SkillConditionScope.PASSIVE, _activeChar, _activeChar));
final Stream<BuffInfo> options = effectList.getOptions().stream().filter(BuffInfo::isInUse);
final Stream<BuffInfo> effectsStream = Stream.concat(effectList.getEffects().stream().filter(BuffInfo::isInUse), Stream.concat(passives != null ? passives : Stream.empty(), options != null ? options : Stream.empty()));
final Stream<BuffInfo> effectsStream = Stream.concat(effectList.getEffects().stream().filter(BuffInfo::isInUse), Stream.concat(passives, options));
// Call pump to each effect
//@formatter:off

View File

@ -389,10 +389,10 @@ public final class BuffInfo
for (AbstractEffect effect : _effects)
{
// Instant effects shouldn't call onExit(..).
if (!effect.isInstant())
{
// if (!effect.isInstant())
// {
effect.onExit(_effector, _effected, _skill);
}
// }
}
// Set the proper system message.

View File

@ -21,17 +21,11 @@ import java.util.List;
import com.l2jmobius.commons.network.PacketWriter;
import com.l2jmobius.gameserver.model.skills.BuffInfo;
import com.l2jmobius.gameserver.model.skills.Skill;
import com.l2jmobius.gameserver.network.OutgoingPackets;
/**
* @author Mobius
* @version Classic 2.0
*/
public class AbnormalStatusUpdate implements IClientOutgoingPacket
{
private final List<BuffInfo> _effects = new ArrayList<>();
private final List<Skill> _effects2 = new ArrayList<>();
public void addSkill(BuffInfo info)
{
@ -41,38 +35,21 @@ public class AbnormalStatusUpdate implements IClientOutgoingPacket
}
}
public void addSkill(Skill skill)
{
if (!skill.isHealingPotionSkill())
{
_effects2.add(skill);
}
}
@Override
public boolean write(PacketWriter packet)
{
OutgoingPackets.ABNORMAL_STATUS_UPDATE.writeId(packet);
packet.writeH(_effects.size() + _effects2.size());
packet.writeH(_effects.size());
for (BuffInfo info : _effects)
{
if ((info != null) && info.isInUse())
{
packet.writeD(info.getSkill().getDisplayId());
packet.writeH(info.getSkill().getDisplayLevel());
packet.writeD(0x00);
packet.writeH(info.getSkill().isAura() ? -1 : info.getTime());
}
}
for (Skill skill : _effects2)
{
if (skill != null)
{
packet.writeD(skill.getDisplayId());
packet.writeH(skill.getDisplayLevel());
packet.writeD(skill.getAbnormalType().getClientId());
packet.writeH(-1);
// packet.writeH(info.getSkill().getSubLevel());
packet.writeD(info.getSkill().getAbnormalType().getClientId());
writeOptionalD(packet, info.getSkill().isAura() ? -1 : info.getTime());
}
}
return true;

View File

@ -16,8 +16,8 @@
*/
package com.l2jmobius.gameserver.network.serverpackets;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
import com.l2jmobius.commons.network.PacketWriter;
@ -25,35 +25,10 @@ import com.l2jmobius.gameserver.model.actor.L2Character;
import com.l2jmobius.gameserver.model.skills.BuffInfo;
import com.l2jmobius.gameserver.network.OutgoingPackets;
/**
* @author proGenitor <br>
* Experimental packet compatible for L2Classic 2.0.
*/
public class ExAbnormalStatusUpdateFromTarget implements IClientOutgoingPacket
{
private final L2Character _character;
private List<Effect> _effects = new ArrayList<>();
private static class Effect
{
protected int _skillId;
protected int _level;
protected int _subLevel;
protected int _abnormalType;
protected int _duration;
protected int _caster;
public Effect(BuffInfo info)
{
final L2Character caster = info.getEffector();
int casterId = 0;
if (caster != null)
{
casterId = caster.getObjectId();
}
_caster = casterId;
}
}
private final List<BuffInfo> _effects;
public ExAbnormalStatusUpdateFromTarget(L2Character character)
{
@ -61,7 +36,9 @@ public class ExAbnormalStatusUpdateFromTarget implements IClientOutgoingPacket
_character = character;
_effects = character.getEffectList().getEffects()
.stream()
.map(Effect::new)
.filter(Objects::nonNull)
.filter(BuffInfo::isInUse)
.filter(b -> !b.getSkill().isToggle())
.collect(Collectors.toList());
//@formatter:on
}
@ -74,14 +51,14 @@ public class ExAbnormalStatusUpdateFromTarget implements IClientOutgoingPacket
packet.writeD(_character.getObjectId());
packet.writeH(_effects.size());
for (Effect info : _effects)
for (BuffInfo info : _effects)
{
packet.writeD(info._skillId);
packet.writeH(info._level);
packet.writeH(info._subLevel);
packet.writeH(info._abnormalType);
writeOptionalD(packet, info._duration);
packet.writeD(info._caster);
packet.writeD(info.getSkill().getDisplayId());
packet.writeH(info.getSkill().getDisplayLevel());
// packet.writeH(info.getSkill().getSubLevel());
packet.writeH(info.getSkill().getAbnormalType().getClientId());
writeOptionalD(packet, info.getSkill().isAura() ? -1 : info.getTime());
packet.writeD(info.getEffectorObjectId());
}
return true;
}

View File

@ -16,6 +16,8 @@
*/
package handlers.effecthandlers;
import java.util.Collections;
import com.l2jmobius.gameserver.model.L2Object;
import com.l2jmobius.gameserver.model.L2World;
import com.l2jmobius.gameserver.model.StatsSet;
@ -38,6 +40,19 @@ public final class CallSkillOnActionTime extends AbstractEffect
setTicks(params.getInt("ticks"));
}
@Override
public void onStart(L2Character effector, L2Character effected, Skill skill)
{
effected.getEffectList().stopEffects(Collections.singleton(_skill.getSkill().getAbnormalType()));
effected.getEffectList().addBlockedAbnormalTypes(Collections.singleton(_skill.getSkill().getAbnormalType()));
}
@Override
public void onExit(L2Character effector, L2Character effected, Skill skill)
{
effected.getEffectList().removeBlockedAbnormalTypes(Collections.singleton(_skill.getSkill().getAbnormalType()));
}
@Override
public boolean onActionTime(L2Character effector, L2Character effected, Skill skill)
{

View File

@ -136,6 +136,5 @@ public final class Disarmor extends AbstractEffect
}
}
}
super.onExit(effector, effected, skill);
}
}

View File

@ -84,6 +84,5 @@ public final class DoubleCast extends AbstractEffect
return null;
});
}
super.onExit(effector, effected, skill);
}
}

View File

@ -65,15 +65,15 @@ public final class CharEffectList
{
private static final Logger LOGGER = Logger.getLogger(CharEffectList.class.getName());
/** Queue containing all effects from buffs for this effect list. */
private volatile Queue<BuffInfo> _actives;
private volatile Queue<BuffInfo> _actives = new ConcurrentLinkedQueue<>();
/** List containing all passives for this effect list. They bypass most of the actions and they are not included in most operations. */
private volatile Set<BuffInfo> _passives;
private volatile Set<BuffInfo> _passives = ConcurrentHashMap.newKeySet();
/** List containing all options for this effect list. They bypass most of the actions and they are not included in most operations. */
private volatile Set<BuffInfo> _options;
private volatile Set<BuffInfo> _options = ConcurrentHashMap.newKeySet();
/** Map containing the all stacked effect in progress for each {@code AbnormalType}. */
private volatile Set<AbnormalType> _stackedEffects = EnumSet.noneOf(AbnormalType.class);
/** Set containing all {@code AbnormalType}s that shouldn't be added to this creature effect list. */
private volatile Set<AbnormalType> _blockedAbnormalTypes = null;
private volatile Set<AbnormalType> _blockedAbnormalTypes = EnumSet.noneOf(AbnormalType.class);
/** Set containing all abnormal visual effects this creature currently displays. */
private volatile Set<AbnormalVisualEffect> _abnormalVisualEffects = EnumSet.noneOf(AbnormalVisualEffect.class);
/** Short buff skill ID. */
@ -110,7 +110,7 @@ public final class CharEffectList
*/
public Set<BuffInfo> getPassives()
{
return _passives != null ? Collections.unmodifiableSet(_passives) : Collections.emptySet();
return Collections.unmodifiableSet(_passives);
}
/**
@ -119,7 +119,7 @@ public final class CharEffectList
*/
public Set<BuffInfo> getOptions()
{
return _options != null ? Collections.unmodifiableSet(_options) : Collections.emptySet();
return Collections.unmodifiableSet(_options);
}
/**
@ -128,7 +128,7 @@ public final class CharEffectList
*/
public Collection<BuffInfo> getEffects()
{
return _actives != null ? Collections.unmodifiableCollection(_actives) : Collections.emptyList();
return Collections.unmodifiableCollection(_actives);
}
/**
@ -137,7 +137,7 @@ public final class CharEffectList
*/
public List<BuffInfo> getBuffs()
{
return _actives != null ? _actives.stream().filter(b -> !b.getSkill().getBuffType().isBuff()).collect(Collectors.toList()) : Collections.emptyList();
return _actives.stream().filter(b -> !b.getSkill().getBuffType().isBuff()).collect(Collectors.toList());
}
/**
@ -146,7 +146,7 @@ public final class CharEffectList
*/
public List<BuffInfo> getDebuffs()
{
return _actives != null ? _actives.stream().filter(b -> b.getSkill().isDebuff()).collect(Collectors.toList()) : Collections.emptyList();
return _actives.stream().filter(b -> b.getSkill().isDebuff()).collect(Collectors.toList());
}
/**
@ -156,7 +156,7 @@ public final class CharEffectList
*/
public boolean isAffectedBySkill(int skillId)
{
return ((_actives != null) && _actives.stream().anyMatch(i -> i.getSkill().getId() == skillId)) || ((_passives != null) && _passives.stream().anyMatch(i -> i.getSkill().getId() == skillId));
return (_actives.stream().anyMatch(i -> i.getSkill().getId() == skillId)) || (_passives.stream().anyMatch(i -> i.getSkill().getId() == skillId));
}
/**
@ -166,7 +166,7 @@ public final class CharEffectList
*/
public BuffInfo getBuffInfoBySkillId(int skillId)
{
return Stream.concat(_actives != null ? _actives.stream() : Stream.empty(), _passives != null ? _passives.stream() : Stream.empty()).filter(b -> b.getSkill().getId() == skillId).findFirst().orElse(null);
return Stream.concat(_actives.stream(), _passives.stream()).filter(b -> b.getSkill().getId() == skillId).findFirst().orElse(null);
}
/**
@ -216,18 +216,6 @@ public final class CharEffectList
*/
public void addBlockedAbnormalTypes(Set<AbnormalType> blockedAbnormalTypes)
{
// Initialize
if (_blockedAbnormalTypes == null)
{
synchronized (this)
{
if (_blockedAbnormalTypes == null)
{
_blockedAbnormalTypes = EnumSet.copyOf(blockedAbnormalTypes);
}
}
}
_blockedAbnormalTypes.addAll(blockedAbnormalTypes);
}
@ -238,7 +226,7 @@ public final class CharEffectList
*/
public boolean removeBlockedAbnormalTypes(Set<AbnormalType> blockedBuffSlots)
{
return (_blockedAbnormalTypes != null) && _blockedAbnormalTypes.removeAll(blockedBuffSlots);
return _blockedAbnormalTypes.removeAll(blockedBuffSlots);
}
/**
@ -247,7 +235,7 @@ public final class CharEffectList
*/
public Set<AbnormalType> getBlockedAbnormalTypes()
{
return _blockedAbnormalTypes != null ? Collections.unmodifiableSet(_blockedAbnormalTypes) : Collections.emptySet();
return Collections.unmodifiableSet(_blockedAbnormalTypes);
}
/**
@ -277,7 +265,7 @@ public final class CharEffectList
*/
public int getBuffCount()
{
return _actives != null ? (_buffCount.get() - _hiddenBuffs.get()) : 0;
return !_actives.isEmpty() ? (_buffCount.get() - _hiddenBuffs.get()) : 0;
}
/**
@ -374,7 +362,7 @@ public final class CharEffectList
*/
public void stopAllPassives(boolean update, boolean broadcast)
{
if (_passives != null)
if (!_passives.isEmpty())
{
_passives.forEach(this::remove);
// Update stats, effect flags and icons.
@ -392,7 +380,7 @@ public final class CharEffectList
*/
public void stopAllOptions(boolean update, boolean broadcast)
{
if (_options != null)
if (!_options.isEmpty())
{
_options.forEach(this::remove);
// Update stats, effect flags and icons.
@ -490,7 +478,7 @@ public final class CharEffectList
*/
public void stopEffects(Predicate<BuffInfo> filter, boolean update, boolean broadcast)
{
if (_actives != null)
if (!_actives.isEmpty())
{
_actives.stream().filter(filter).forEach(this::remove);
@ -678,6 +666,10 @@ public final class CharEffectList
{
// Remove active effect.
removeActive(info, removed);
if (_owner.isNpc()) // Fix for all NPC debuff animations removed.
{
updateEffectList(broadcast);
}
}
// Update stats, effect flags and icons.
@ -693,7 +685,7 @@ public final class CharEffectList
*/
private synchronized void removeActive(BuffInfo info, boolean removed)
{
if (_actives != null)
if (!_actives.isEmpty())
{
// Removes the buff from the given effect list.
_actives.remove(info);
@ -716,7 +708,7 @@ public final class CharEffectList
private void removePassive(BuffInfo info, boolean removed)
{
if (_passives != null)
if (!_passives.isEmpty())
{
_passives.remove(info);
info.stopAllEffects(removed);
@ -725,7 +717,7 @@ public final class CharEffectList
private void removeOption(BuffInfo info, boolean removed)
{
if (_options != null)
if (!_options.isEmpty())
{
_options.remove(info);
info.stopAllEffects(removed);
@ -821,12 +813,6 @@ public final class CharEffectList
}
}
// Initialize
if (_actives == null)
{
_actives = new ConcurrentLinkedQueue<>();
}
// Manage effect stacking.
if (hasAbnormalType(skill.getAbnormalType()))
{
@ -857,7 +843,7 @@ public final class CharEffectList
}
else
{
// Remove effect that gets overriden.
// Remove effect that gets overridden.
remove(existingInfo);
}
}
@ -865,7 +851,7 @@ public final class CharEffectList
{
info.setInUse(false);
}
else // The effect we try to add should be overriden.
else // The effect we try to add should be overridden.
{
return;
}
@ -918,18 +904,6 @@ public final class CharEffectList
return;
}
// Initialize
if (_passives == null)
{
synchronized (this)
{
if (_passives == null)
{
_passives = ConcurrentHashMap.newKeySet();
}
}
}
// Remove previous passives of this id.
_passives.stream().filter(Objects::nonNull).filter(b -> b.getSkill().getId() == skill.getId()).forEach(b ->
{
@ -947,18 +921,6 @@ public final class CharEffectList
{
if (info.getOption() != null)
{
// Initialize
if (_options == null)
{
synchronized (this)
{
if (_options == null)
{
_options = ConcurrentHashMap.newKeySet();
}
}
}
// Remove previous options of this id.
_options.stream().filter(Objects::nonNull).filter(b -> b.getOption().getId() == info.getOption().getId()).forEach(b ->
{
@ -988,7 +950,7 @@ public final class CharEffectList
final Optional<PartySpelled> ps = ((party != null) || _owner.isSummon()) ? Optional.of(new PartySpelled(_owner)) : Optional.empty();
final Optional<ExOlympiadSpelledInfo> os = (player.isInOlympiadMode() && player.isOlympiadStart()) ? Optional.of(new ExOlympiadSpelledInfo(player)) : Optional.empty();
if (_actives != null)
if (!_actives.isEmpty())
{
//@formatter:off
_actives.stream()
@ -1109,8 +1071,6 @@ public final class CharEffectList
final Set<BuffInfo> unhideBuffs = new HashSet<>();
// Recalculate new flags
if (_actives != null)
{
for (BuffInfo info : _actives)
{
if (info != null)
@ -1144,7 +1104,14 @@ public final class CharEffectList
// Add AbnormalVisualEffect flag.
if (skill.hasAbnormalVisualEffects())
{
abnormalVisualEffectFlags.addAll(skill.getAbnormalVisualEffects());
for (AbnormalVisualEffect ave : skill.getAbnormalVisualEffects())
{
abnormalVisualEffectFlags.add(ave);
_abnormalVisualEffects.add(ave);
}
if (broadcast)
{
_owner.updateAbnormalVisualEffects();
}
}
}
@ -1167,7 +1134,7 @@ public final class CharEffectList
if (broadcast)
{
// Check if there is change in AbnormalVisualEffect
if ((abnormalVisualEffectFlags.size() != _abnormalVisualEffects.size()) || !abnormalVisualEffectFlags.containsAll(_abnormalVisualEffects))
if (!abnormalVisualEffectFlags.containsAll(_abnormalVisualEffects))
{
_abnormalVisualEffects = abnormalVisualEffectFlags;
_owner.updateAbnormalVisualEffects();

View File

@ -77,7 +77,6 @@ public class DoppelgangerInstance extends L2Npc
info.setAbnormalTime(summonerInfo.getAbnormalTime());
getEffectList().add(info);
}
}
}
}

View File

@ -776,7 +776,7 @@ public class CharStat
final CharEffectList effectList = _activeChar.getEffectList();
final Stream<BuffInfo> passives = effectList.getPassives().stream().filter(BuffInfo::isInUse).filter(info -> info.getSkill().checkConditions(SkillConditionScope.PASSIVE, _activeChar, _activeChar));
final Stream<BuffInfo> options = effectList.getOptions().stream().filter(BuffInfo::isInUse);
final Stream<BuffInfo> effectsStream = Stream.concat(effectList.getEffects().stream().filter(BuffInfo::isInUse), Stream.concat(passives != null ? passives : Stream.empty(), options != null ? options : Stream.empty()));
final Stream<BuffInfo> effectsStream = Stream.concat(effectList.getEffects().stream().filter(BuffInfo::isInUse), Stream.concat(passives, options));
// Call pump to each effect
//@formatter:off

View File

@ -389,10 +389,10 @@ public final class BuffInfo
for (AbstractEffect effect : _effects)
{
// Instant effects shouldn't call onExit(..).
if (!effect.isInstant())
{
// if (!effect.isInstant())
// {
effect.onExit(_effector, _effected, _skill);
}
// }
}
// Set the proper system message.

View File

@ -21,17 +21,11 @@ import java.util.List;
import com.l2jmobius.commons.network.PacketWriter;
import com.l2jmobius.gameserver.model.skills.BuffInfo;
import com.l2jmobius.gameserver.model.skills.Skill;
import com.l2jmobius.gameserver.network.OutgoingPackets;
/**
* @author Mobius
* @version Classic 2.0
*/
public class AbnormalStatusUpdate implements IClientOutgoingPacket
{
private final List<BuffInfo> _effects = new ArrayList<>();
private final List<Skill> _effects2 = new ArrayList<>();
public void addSkill(BuffInfo info)
{
@ -41,38 +35,21 @@ public class AbnormalStatusUpdate implements IClientOutgoingPacket
}
}
public void addSkill(Skill skill)
{
if (!skill.isHealingPotionSkill())
{
_effects2.add(skill);
}
}
@Override
public boolean write(PacketWriter packet)
{
OutgoingPackets.ABNORMAL_STATUS_UPDATE.writeId(packet);
packet.writeH(_effects.size() + _effects2.size());
packet.writeH(_effects.size());
for (BuffInfo info : _effects)
{
if ((info != null) && info.isInUse())
{
packet.writeD(info.getSkill().getDisplayId());
packet.writeH(info.getSkill().getDisplayLevel());
packet.writeD(0x00);
packet.writeH(info.getSkill().isAura() ? -1 : info.getTime());
}
}
for (Skill skill : _effects2)
{
if (skill != null)
{
packet.writeD(skill.getDisplayId());
packet.writeH(skill.getDisplayLevel());
packet.writeD(skill.getAbnormalType().getClientId());
packet.writeH(-1);
// packet.writeH(info.getSkill().getSubLevel());
packet.writeD(info.getSkill().getAbnormalType().getClientId());
writeOptionalD(packet, info.getSkill().isAura() ? -1 : info.getTime());
}
}
return true;

View File

@ -16,8 +16,8 @@
*/
package com.l2jmobius.gameserver.network.serverpackets;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
import com.l2jmobius.commons.network.PacketWriter;
@ -25,35 +25,10 @@ import com.l2jmobius.gameserver.model.actor.L2Character;
import com.l2jmobius.gameserver.model.skills.BuffInfo;
import com.l2jmobius.gameserver.network.OutgoingPackets;
/**
* @author proGenitor <br>
* Experimental packet compatible for L2Classic 2.0.
*/
public class ExAbnormalStatusUpdateFromTarget implements IClientOutgoingPacket
{
private final L2Character _character;
private List<Effect> _effects = new ArrayList<>();
private static class Effect
{
protected int _skillId;
protected int _level;
protected int _subLevel;
protected int _abnormalType;
protected int _duration;
protected int _caster;
public Effect(BuffInfo info)
{
final L2Character caster = info.getEffector();
int casterId = 0;
if (caster != null)
{
casterId = caster.getObjectId();
}
_caster = casterId;
}
}
private final List<BuffInfo> _effects;
public ExAbnormalStatusUpdateFromTarget(L2Character character)
{
@ -61,7 +36,9 @@ public class ExAbnormalStatusUpdateFromTarget implements IClientOutgoingPacket
_character = character;
_effects = character.getEffectList().getEffects()
.stream()
.map(Effect::new)
.filter(Objects::nonNull)
.filter(BuffInfo::isInUse)
.filter(b -> !b.getSkill().isToggle())
.collect(Collectors.toList());
//@formatter:on
}
@ -74,14 +51,14 @@ public class ExAbnormalStatusUpdateFromTarget implements IClientOutgoingPacket
packet.writeD(_character.getObjectId());
packet.writeH(_effects.size());
for (Effect info : _effects)
for (BuffInfo info : _effects)
{
packet.writeD(info._skillId);
packet.writeH(info._level);
packet.writeH(info._subLevel);
packet.writeH(info._abnormalType);
writeOptionalD(packet, info._duration);
packet.writeD(info._caster);
packet.writeD(info.getSkill().getDisplayId());
packet.writeH(info.getSkill().getDisplayLevel());
// packet.writeH(info.getSkill().getSubLevel());
packet.writeH(info.getSkill().getAbnormalType().getClientId());
writeOptionalD(packet, info.getSkill().isAura() ? -1 : info.getTime());
packet.writeD(info.getEffectorObjectId());
}
return true;
}

View File

@ -16,6 +16,8 @@
*/
package handlers.effecthandlers;
import java.util.Collections;
import com.l2jmobius.gameserver.model.L2Object;
import com.l2jmobius.gameserver.model.L2World;
import com.l2jmobius.gameserver.model.StatsSet;
@ -38,6 +40,19 @@ public final class CallSkillOnActionTime extends AbstractEffect
setTicks(params.getInt("ticks"));
}
@Override
public void onStart(L2Character effector, L2Character effected, Skill skill)
{
effected.getEffectList().stopEffects(Collections.singleton(_skill.getSkill().getAbnormalType()));
effected.getEffectList().addBlockedAbnormalTypes(Collections.singleton(_skill.getSkill().getAbnormalType()));
}
@Override
public void onExit(L2Character effector, L2Character effected, Skill skill)
{
effected.getEffectList().removeBlockedAbnormalTypes(Collections.singleton(_skill.getSkill().getAbnormalType()));
}
@Override
public boolean onActionTime(L2Character effector, L2Character effected, Skill skill)
{

View File

@ -136,6 +136,5 @@ public final class Disarmor extends AbstractEffect
}
}
}
super.onExit(effector, effected, skill);
}
}

View File

@ -84,6 +84,5 @@ public final class DoubleCast extends AbstractEffect
return null;
});
}
super.onExit(effector, effected, skill);
}
}

View File

@ -65,15 +65,15 @@ public final class CharEffectList
{
private static final Logger LOGGER = Logger.getLogger(CharEffectList.class.getName());
/** Queue containing all effects from buffs for this effect list. */
private volatile Queue<BuffInfo> _actives;
private volatile Queue<BuffInfo> _actives = new ConcurrentLinkedQueue<>();
/** List containing all passives for this effect list. They bypass most of the actions and they are not included in most operations. */
private volatile Set<BuffInfo> _passives;
private volatile Set<BuffInfo> _passives = ConcurrentHashMap.newKeySet();
/** List containing all options for this effect list. They bypass most of the actions and they are not included in most operations. */
private volatile Set<BuffInfo> _options;
private volatile Set<BuffInfo> _options = ConcurrentHashMap.newKeySet();
/** Map containing the all stacked effect in progress for each {@code AbnormalType}. */
private volatile Set<AbnormalType> _stackedEffects = EnumSet.noneOf(AbnormalType.class);
/** Set containing all {@code AbnormalType}s that shouldn't be added to this creature effect list. */
private volatile Set<AbnormalType> _blockedAbnormalTypes = null;
private volatile Set<AbnormalType> _blockedAbnormalTypes = EnumSet.noneOf(AbnormalType.class);
/** Set containing all abnormal visual effects this creature currently displays. */
private volatile Set<AbnormalVisualEffect> _abnormalVisualEffects = EnumSet.noneOf(AbnormalVisualEffect.class);
/** Short buff skill ID. */
@ -110,7 +110,7 @@ public final class CharEffectList
*/
public Set<BuffInfo> getPassives()
{
return _passives != null ? Collections.unmodifiableSet(_passives) : Collections.emptySet();
return Collections.unmodifiableSet(_passives);
}
/**
@ -119,7 +119,7 @@ public final class CharEffectList
*/
public Set<BuffInfo> getOptions()
{
return _options != null ? Collections.unmodifiableSet(_options) : Collections.emptySet();
return Collections.unmodifiableSet(_options);
}
/**
@ -128,7 +128,7 @@ public final class CharEffectList
*/
public Collection<BuffInfo> getEffects()
{
return _actives != null ? Collections.unmodifiableCollection(_actives) : Collections.emptyList();
return Collections.unmodifiableCollection(_actives);
}
/**
@ -137,7 +137,7 @@ public final class CharEffectList
*/
public List<BuffInfo> getBuffs()
{
return _actives != null ? _actives.stream().filter(b -> !b.getSkill().getBuffType().isBuff()).collect(Collectors.toList()) : Collections.emptyList();
return _actives.stream().filter(b -> !b.getSkill().getBuffType().isBuff()).collect(Collectors.toList());
}
/**
@ -146,7 +146,7 @@ public final class CharEffectList
*/
public List<BuffInfo> getDebuffs()
{
return _actives != null ? _actives.stream().filter(b -> b.getSkill().isDebuff()).collect(Collectors.toList()) : Collections.emptyList();
return _actives.stream().filter(b -> b.getSkill().isDebuff()).collect(Collectors.toList());
}
/**
@ -156,7 +156,7 @@ public final class CharEffectList
*/
public boolean isAffectedBySkill(int skillId)
{
return ((_actives != null) && _actives.stream().anyMatch(i -> i.getSkill().getId() == skillId)) || ((_passives != null) && _passives.stream().anyMatch(i -> i.getSkill().getId() == skillId));
return (_actives.stream().anyMatch(i -> i.getSkill().getId() == skillId)) || (_passives.stream().anyMatch(i -> i.getSkill().getId() == skillId));
}
/**
@ -166,7 +166,7 @@ public final class CharEffectList
*/
public BuffInfo getBuffInfoBySkillId(int skillId)
{
return Stream.concat(_actives != null ? _actives.stream() : Stream.empty(), _passives != null ? _passives.stream() : Stream.empty()).filter(b -> b.getSkill().getId() == skillId).findFirst().orElse(null);
return Stream.concat(_actives.stream(), _passives.stream()).filter(b -> b.getSkill().getId() == skillId).findFirst().orElse(null);
}
/**
@ -216,18 +216,6 @@ public final class CharEffectList
*/
public void addBlockedAbnormalTypes(Set<AbnormalType> blockedAbnormalTypes)
{
// Initialize
if (_blockedAbnormalTypes == null)
{
synchronized (this)
{
if (_blockedAbnormalTypes == null)
{
_blockedAbnormalTypes = EnumSet.copyOf(blockedAbnormalTypes);
}
}
}
_blockedAbnormalTypes.addAll(blockedAbnormalTypes);
}
@ -238,7 +226,7 @@ public final class CharEffectList
*/
public boolean removeBlockedAbnormalTypes(Set<AbnormalType> blockedBuffSlots)
{
return (_blockedAbnormalTypes != null) && _blockedAbnormalTypes.removeAll(blockedBuffSlots);
return _blockedAbnormalTypes.removeAll(blockedBuffSlots);
}
/**
@ -247,7 +235,7 @@ public final class CharEffectList
*/
public Set<AbnormalType> getBlockedAbnormalTypes()
{
return _blockedAbnormalTypes != null ? Collections.unmodifiableSet(_blockedAbnormalTypes) : Collections.emptySet();
return Collections.unmodifiableSet(_blockedAbnormalTypes);
}
/**
@ -277,7 +265,7 @@ public final class CharEffectList
*/
public int getBuffCount()
{
return _actives != null ? (_buffCount.get() - _hiddenBuffs.get()) : 0;
return !_actives.isEmpty() ? (_buffCount.get() - _hiddenBuffs.get()) : 0;
}
/**
@ -374,7 +362,7 @@ public final class CharEffectList
*/
public void stopAllPassives(boolean update, boolean broadcast)
{
if (_passives != null)
if (!_passives.isEmpty())
{
_passives.forEach(this::remove);
// Update stats, effect flags and icons.
@ -392,7 +380,7 @@ public final class CharEffectList
*/
public void stopAllOptions(boolean update, boolean broadcast)
{
if (_options != null)
if (!_options.isEmpty())
{
_options.forEach(this::remove);
// Update stats, effect flags and icons.
@ -490,7 +478,7 @@ public final class CharEffectList
*/
public void stopEffects(Predicate<BuffInfo> filter, boolean update, boolean broadcast)
{
if (_actives != null)
if (!_actives.isEmpty())
{
_actives.stream().filter(filter).forEach(this::remove);
@ -678,6 +666,10 @@ public final class CharEffectList
{
// Remove active effect.
removeActive(info, removed);
if (_owner.isNpc()) // Fix for all NPC debuff animations removed.
{
updateEffectList(broadcast);
}
}
// Update stats, effect flags and icons.
@ -693,7 +685,7 @@ public final class CharEffectList
*/
private synchronized void removeActive(BuffInfo info, boolean removed)
{
if (_actives != null)
if (!_actives.isEmpty())
{
// Removes the buff from the given effect list.
_actives.remove(info);
@ -716,7 +708,7 @@ public final class CharEffectList
private void removePassive(BuffInfo info, boolean removed)
{
if (_passives != null)
if (!_passives.isEmpty())
{
_passives.remove(info);
info.stopAllEffects(removed);
@ -725,7 +717,7 @@ public final class CharEffectList
private void removeOption(BuffInfo info, boolean removed)
{
if (_options != null)
if (!_options.isEmpty())
{
_options.remove(info);
info.stopAllEffects(removed);
@ -821,12 +813,6 @@ public final class CharEffectList
}
}
// Initialize
if (_actives == null)
{
_actives = new ConcurrentLinkedQueue<>();
}
// Manage effect stacking.
if (hasAbnormalType(skill.getAbnormalType()))
{
@ -857,7 +843,7 @@ public final class CharEffectList
}
else
{
// Remove effect that gets overriden.
// Remove effect that gets overridden.
remove(existingInfo);
}
}
@ -865,7 +851,7 @@ public final class CharEffectList
{
info.setInUse(false);
}
else // The effect we try to add should be overriden.
else // The effect we try to add should be overridden.
{
return;
}
@ -918,18 +904,6 @@ public final class CharEffectList
return;
}
// Initialize
if (_passives == null)
{
synchronized (this)
{
if (_passives == null)
{
_passives = ConcurrentHashMap.newKeySet();
}
}
}
// Remove previous passives of this id.
_passives.stream().filter(Objects::nonNull).filter(b -> b.getSkill().getId() == skill.getId()).forEach(b ->
{
@ -947,18 +921,6 @@ public final class CharEffectList
{
if (info.getOption() != null)
{
// Initialize
if (_options == null)
{
synchronized (this)
{
if (_options == null)
{
_options = ConcurrentHashMap.newKeySet();
}
}
}
// Remove previous options of this id.
_options.stream().filter(Objects::nonNull).filter(b -> b.getOption().getId() == info.getOption().getId()).forEach(b ->
{
@ -988,7 +950,7 @@ public final class CharEffectList
final Optional<PartySpelled> ps = ((party != null) || _owner.isSummon()) ? Optional.of(new PartySpelled(_owner)) : Optional.empty();
final Optional<ExOlympiadSpelledInfo> os = (player.isInOlympiadMode() && player.isOlympiadStart()) ? Optional.of(new ExOlympiadSpelledInfo(player)) : Optional.empty();
if (_actives != null)
if (!_actives.isEmpty())
{
//@formatter:off
_actives.stream()
@ -1109,8 +1071,6 @@ public final class CharEffectList
final Set<BuffInfo> unhideBuffs = new HashSet<>();
// Recalculate new flags
if (_actives != null)
{
for (BuffInfo info : _actives)
{
if (info != null)
@ -1144,7 +1104,14 @@ public final class CharEffectList
// Add AbnormalVisualEffect flag.
if (skill.hasAbnormalVisualEffects())
{
abnormalVisualEffectFlags.addAll(skill.getAbnormalVisualEffects());
for (AbnormalVisualEffect ave : skill.getAbnormalVisualEffects())
{
abnormalVisualEffectFlags.add(ave);
_abnormalVisualEffects.add(ave);
}
if (broadcast)
{
_owner.updateAbnormalVisualEffects();
}
}
}
@ -1167,7 +1134,7 @@ public final class CharEffectList
if (broadcast)
{
// Check if there is change in AbnormalVisualEffect
if ((abnormalVisualEffectFlags.size() != _abnormalVisualEffects.size()) || !abnormalVisualEffectFlags.containsAll(_abnormalVisualEffects))
if (!abnormalVisualEffectFlags.containsAll(_abnormalVisualEffects))
{
_abnormalVisualEffects = abnormalVisualEffectFlags;
_owner.updateAbnormalVisualEffects();

View File

@ -77,7 +77,6 @@ public class DoppelgangerInstance extends L2Npc
info.setAbnormalTime(summonerInfo.getAbnormalTime());
getEffectList().add(info);
}
}
}
}

View File

@ -776,7 +776,7 @@ public class CharStat
final CharEffectList effectList = _activeChar.getEffectList();
final Stream<BuffInfo> passives = effectList.getPassives().stream().filter(BuffInfo::isInUse).filter(info -> info.getSkill().checkConditions(SkillConditionScope.PASSIVE, _activeChar, _activeChar));
final Stream<BuffInfo> options = effectList.getOptions().stream().filter(BuffInfo::isInUse);
final Stream<BuffInfo> effectsStream = Stream.concat(effectList.getEffects().stream().filter(BuffInfo::isInUse), Stream.concat(passives != null ? passives : Stream.empty(), options != null ? options : Stream.empty()));
final Stream<BuffInfo> effectsStream = Stream.concat(effectList.getEffects().stream().filter(BuffInfo::isInUse), Stream.concat(passives, options));
// Call pump to each effect
//@formatter:off

View File

@ -389,10 +389,10 @@ public final class BuffInfo
for (AbstractEffect effect : _effects)
{
// Instant effects shouldn't call onExit(..).
if (!effect.isInstant())
{
// if (!effect.isInstant())
// {
effect.onExit(_effector, _effected, _skill);
}
// }
}
// Set the proper system message.

View File

@ -21,17 +21,11 @@ import java.util.List;
import com.l2jmobius.commons.network.PacketWriter;
import com.l2jmobius.gameserver.model.skills.BuffInfo;
import com.l2jmobius.gameserver.model.skills.Skill;
import com.l2jmobius.gameserver.network.OutgoingPackets;
/**
* @author Mobius
* @version Classic 2.0
*/
public class AbnormalStatusUpdate implements IClientOutgoingPacket
{
private final List<BuffInfo> _effects = new ArrayList<>();
private final List<Skill> _effects2 = new ArrayList<>();
public void addSkill(BuffInfo info)
{
@ -41,38 +35,21 @@ public class AbnormalStatusUpdate implements IClientOutgoingPacket
}
}
public void addSkill(Skill skill)
{
if (!skill.isHealingPotionSkill())
{
_effects2.add(skill);
}
}
@Override
public boolean write(PacketWriter packet)
{
OutgoingPackets.ABNORMAL_STATUS_UPDATE.writeId(packet);
packet.writeH(_effects.size() + _effects2.size());
packet.writeH(_effects.size());
for (BuffInfo info : _effects)
{
if ((info != null) && info.isInUse())
{
packet.writeD(info.getSkill().getDisplayId());
packet.writeH(info.getSkill().getDisplayLevel());
packet.writeD(0x00);
packet.writeH(info.getSkill().isAura() ? -1 : info.getTime());
}
}
for (Skill skill : _effects2)
{
if (skill != null)
{
packet.writeD(skill.getDisplayId());
packet.writeH(skill.getDisplayLevel());
packet.writeD(skill.getAbnormalType().getClientId());
packet.writeH(-1);
// packet.writeH(info.getSkill().getSubLevel());
packet.writeD(info.getSkill().getAbnormalType().getClientId());
writeOptionalD(packet, info.getSkill().isAura() ? -1 : info.getTime());
}
}
return true;

View File

@ -16,8 +16,8 @@
*/
package com.l2jmobius.gameserver.network.serverpackets;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
import com.l2jmobius.commons.network.PacketWriter;
@ -25,35 +25,10 @@ import com.l2jmobius.gameserver.model.actor.L2Character;
import com.l2jmobius.gameserver.model.skills.BuffInfo;
import com.l2jmobius.gameserver.network.OutgoingPackets;
/**
* @author proGenitor <br>
* Experimental packet compatible for L2Classic 2.0.
*/
public class ExAbnormalStatusUpdateFromTarget implements IClientOutgoingPacket
{
private final L2Character _character;
private List<Effect> _effects = new ArrayList<>();
private static class Effect
{
protected int _skillId;
protected int _level;
protected int _subLevel;
protected int _abnormalType;
protected int _duration;
protected int _caster;
public Effect(BuffInfo info)
{
final L2Character caster = info.getEffector();
int casterId = 0;
if (caster != null)
{
casterId = caster.getObjectId();
}
_caster = casterId;
}
}
private final List<BuffInfo> _effects;
public ExAbnormalStatusUpdateFromTarget(L2Character character)
{
@ -61,7 +36,9 @@ public class ExAbnormalStatusUpdateFromTarget implements IClientOutgoingPacket
_character = character;
_effects = character.getEffectList().getEffects()
.stream()
.map(Effect::new)
.filter(Objects::nonNull)
.filter(BuffInfo::isInUse)
.filter(b -> !b.getSkill().isToggle())
.collect(Collectors.toList());
//@formatter:on
}
@ -74,14 +51,14 @@ public class ExAbnormalStatusUpdateFromTarget implements IClientOutgoingPacket
packet.writeD(_character.getObjectId());
packet.writeH(_effects.size());
for (Effect info : _effects)
for (BuffInfo info : _effects)
{
packet.writeD(info._skillId);
packet.writeH(info._level);
packet.writeH(info._subLevel);
packet.writeH(info._abnormalType);
writeOptionalD(packet, info._duration);
packet.writeD(info._caster);
packet.writeD(info.getSkill().getDisplayId());
packet.writeH(info.getSkill().getDisplayLevel());
// packet.writeH(info.getSkill().getSubLevel());
packet.writeH(info.getSkill().getAbnormalType().getClientId());
writeOptionalD(packet, info.getSkill().isAura() ? -1 : info.getTime());
packet.writeD(info.getEffectorObjectId());
}
return true;
}