Abnormal improvements.
This commit is contained in:
@@ -16,6 +16,8 @@
|
|||||||
*/
|
*/
|
||||||
package handlers.effecthandlers;
|
package handlers.effecthandlers;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
|
||||||
import com.l2jmobius.gameserver.model.L2Object;
|
import com.l2jmobius.gameserver.model.L2Object;
|
||||||
import com.l2jmobius.gameserver.model.L2World;
|
import com.l2jmobius.gameserver.model.L2World;
|
||||||
import com.l2jmobius.gameserver.model.StatsSet;
|
import com.l2jmobius.gameserver.model.StatsSet;
|
||||||
@@ -38,6 +40,19 @@ public final class CallSkillOnActionTime extends AbstractEffect
|
|||||||
setTicks(params.getInt("ticks"));
|
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
|
@Override
|
||||||
public boolean onActionTime(L2Character effector, L2Character effected, Skill skill)
|
public boolean onActionTime(L2Character effector, L2Character effected, Skill skill)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -136,6 +136,5 @@ public final class Disarmor extends AbstractEffect
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
super.onExit(effector, effected, skill);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -84,6 +84,5 @@ public final class DoubleCast extends AbstractEffect
|
|||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
super.onExit(effector, effected, skill);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -65,15 +65,15 @@ public final class CharEffectList
|
|||||||
{
|
{
|
||||||
private static final Logger LOGGER = Logger.getLogger(CharEffectList.class.getName());
|
private static final Logger LOGGER = Logger.getLogger(CharEffectList.class.getName());
|
||||||
/** Queue containing all effects from buffs for this effect list. */
|
/** 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. */
|
/** 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. */
|
/** 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}. */
|
/** Map containing the all stacked effect in progress for each {@code AbnormalType}. */
|
||||||
private volatile Set<AbnormalType> _stackedEffects = EnumSet.noneOf(AbnormalType.class);
|
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. */
|
/** 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. */
|
/** Set containing all abnormal visual effects this creature currently displays. */
|
||||||
private volatile Set<AbnormalVisualEffect> _abnormalVisualEffects = EnumSet.noneOf(AbnormalVisualEffect.class);
|
private volatile Set<AbnormalVisualEffect> _abnormalVisualEffects = EnumSet.noneOf(AbnormalVisualEffect.class);
|
||||||
/** Short buff skill ID. */
|
/** Short buff skill ID. */
|
||||||
@@ -110,7 +110,7 @@ public final class CharEffectList
|
|||||||
*/
|
*/
|
||||||
public Set<BuffInfo> getPassives()
|
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()
|
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()
|
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()
|
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()
|
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)
|
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)
|
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)
|
public void addBlockedAbnormalTypes(Set<AbnormalType> blockedAbnormalTypes)
|
||||||
{
|
{
|
||||||
// Initialize
|
|
||||||
if (_blockedAbnormalTypes == null)
|
|
||||||
{
|
|
||||||
synchronized (this)
|
|
||||||
{
|
|
||||||
if (_blockedAbnormalTypes == null)
|
|
||||||
{
|
|
||||||
_blockedAbnormalTypes = EnumSet.copyOf(blockedAbnormalTypes);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_blockedAbnormalTypes.addAll(blockedAbnormalTypes);
|
_blockedAbnormalTypes.addAll(blockedAbnormalTypes);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -238,7 +226,7 @@ public final class CharEffectList
|
|||||||
*/
|
*/
|
||||||
public boolean removeBlockedAbnormalTypes(Set<AbnormalType> blockedBuffSlots)
|
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()
|
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()
|
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)
|
public void stopAllPassives(boolean update, boolean broadcast)
|
||||||
{
|
{
|
||||||
if (_passives != null)
|
if (!_passives.isEmpty())
|
||||||
{
|
{
|
||||||
_passives.forEach(this::remove);
|
_passives.forEach(this::remove);
|
||||||
// Update stats, effect flags and icons.
|
// Update stats, effect flags and icons.
|
||||||
@@ -392,7 +380,7 @@ public final class CharEffectList
|
|||||||
*/
|
*/
|
||||||
public void stopAllOptions(boolean update, boolean broadcast)
|
public void stopAllOptions(boolean update, boolean broadcast)
|
||||||
{
|
{
|
||||||
if (_options != null)
|
if (!_options.isEmpty())
|
||||||
{
|
{
|
||||||
_options.forEach(this::remove);
|
_options.forEach(this::remove);
|
||||||
// Update stats, effect flags and icons.
|
// Update stats, effect flags and icons.
|
||||||
@@ -490,7 +478,7 @@ public final class CharEffectList
|
|||||||
*/
|
*/
|
||||||
public void stopEffects(Predicate<BuffInfo> filter, boolean update, boolean broadcast)
|
public void stopEffects(Predicate<BuffInfo> filter, boolean update, boolean broadcast)
|
||||||
{
|
{
|
||||||
if (_actives != null)
|
if (!_actives.isEmpty())
|
||||||
{
|
{
|
||||||
_actives.stream().filter(filter).forEach(this::remove);
|
_actives.stream().filter(filter).forEach(this::remove);
|
||||||
|
|
||||||
@@ -678,6 +666,10 @@ public final class CharEffectList
|
|||||||
{
|
{
|
||||||
// Remove active effect.
|
// Remove active effect.
|
||||||
removeActive(info, removed);
|
removeActive(info, removed);
|
||||||
|
if (_owner.isNpc()) // Fix for all NPC debuff animations removed.
|
||||||
|
{
|
||||||
|
updateEffectList(broadcast);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update stats, effect flags and icons.
|
// Update stats, effect flags and icons.
|
||||||
@@ -693,7 +685,7 @@ public final class CharEffectList
|
|||||||
*/
|
*/
|
||||||
private synchronized void removeActive(BuffInfo info, boolean removed)
|
private synchronized void removeActive(BuffInfo info, boolean removed)
|
||||||
{
|
{
|
||||||
if (_actives != null)
|
if (!_actives.isEmpty())
|
||||||
{
|
{
|
||||||
// Removes the buff from the given effect list.
|
// Removes the buff from the given effect list.
|
||||||
_actives.remove(info);
|
_actives.remove(info);
|
||||||
@@ -716,7 +708,7 @@ public final class CharEffectList
|
|||||||
|
|
||||||
private void removePassive(BuffInfo info, boolean removed)
|
private void removePassive(BuffInfo info, boolean removed)
|
||||||
{
|
{
|
||||||
if (_passives != null)
|
if (!_passives.isEmpty())
|
||||||
{
|
{
|
||||||
_passives.remove(info);
|
_passives.remove(info);
|
||||||
info.stopAllEffects(removed);
|
info.stopAllEffects(removed);
|
||||||
@@ -725,7 +717,7 @@ public final class CharEffectList
|
|||||||
|
|
||||||
private void removeOption(BuffInfo info, boolean removed)
|
private void removeOption(BuffInfo info, boolean removed)
|
||||||
{
|
{
|
||||||
if (_options != null)
|
if (!_options.isEmpty())
|
||||||
{
|
{
|
||||||
_options.remove(info);
|
_options.remove(info);
|
||||||
info.stopAllEffects(removed);
|
info.stopAllEffects(removed);
|
||||||
@@ -821,12 +813,6 @@ public final class CharEffectList
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize
|
|
||||||
if (_actives == null)
|
|
||||||
{
|
|
||||||
_actives = new ConcurrentLinkedQueue<>();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Manage effect stacking.
|
// Manage effect stacking.
|
||||||
if (hasAbnormalType(skill.getAbnormalType()))
|
if (hasAbnormalType(skill.getAbnormalType()))
|
||||||
{
|
{
|
||||||
@@ -857,7 +843,7 @@ public final class CharEffectList
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Remove effect that gets overriden.
|
// Remove effect that gets overridden.
|
||||||
remove(existingInfo);
|
remove(existingInfo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -865,7 +851,7 @@ public final class CharEffectList
|
|||||||
{
|
{
|
||||||
info.setInUse(false);
|
info.setInUse(false);
|
||||||
}
|
}
|
||||||
else // The effect we try to add should be overriden.
|
else // The effect we try to add should be overridden.
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -918,18 +904,6 @@ public final class CharEffectList
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize
|
|
||||||
if (_passives == null)
|
|
||||||
{
|
|
||||||
synchronized (this)
|
|
||||||
{
|
|
||||||
if (_passives == null)
|
|
||||||
{
|
|
||||||
_passives = ConcurrentHashMap.newKeySet();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove previous passives of this id.
|
// Remove previous passives of this id.
|
||||||
_passives.stream().filter(Objects::nonNull).filter(b -> b.getSkill().getId() == skill.getId()).forEach(b ->
|
_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)
|
if (info.getOption() != null)
|
||||||
{
|
{
|
||||||
// Initialize
|
|
||||||
if (_options == null)
|
|
||||||
{
|
|
||||||
synchronized (this)
|
|
||||||
{
|
|
||||||
if (_options == null)
|
|
||||||
{
|
|
||||||
_options = ConcurrentHashMap.newKeySet();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove previous options of this id.
|
// Remove previous options of this id.
|
||||||
_options.stream().filter(Objects::nonNull).filter(b -> b.getOption().getId() == info.getOption().getId()).forEach(b ->
|
_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<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();
|
final Optional<ExOlympiadSpelledInfo> os = (player.isInOlympiadMode() && player.isOlympiadStart()) ? Optional.of(new ExOlympiadSpelledInfo(player)) : Optional.empty();
|
||||||
|
|
||||||
if (_actives != null)
|
if (!_actives.isEmpty())
|
||||||
{
|
{
|
||||||
//@formatter:off
|
//@formatter:off
|
||||||
_actives.stream()
|
_actives.stream()
|
||||||
@@ -1109,42 +1071,47 @@ public final class CharEffectList
|
|||||||
final Set<BuffInfo> unhideBuffs = new HashSet<>();
|
final Set<BuffInfo> unhideBuffs = new HashSet<>();
|
||||||
|
|
||||||
// Recalculate new flags
|
// Recalculate new flags
|
||||||
if (_actives != null)
|
for (BuffInfo info : _actives)
|
||||||
{
|
{
|
||||||
for (BuffInfo info : _actives)
|
if (info != null)
|
||||||
{
|
{
|
||||||
if (info != null)
|
final Skill skill = info.getSkill();
|
||||||
|
|
||||||
|
// Handle hidden buffs. Check if there was such abnormal before so we can continue.
|
||||||
|
if ((_hiddenBuffs.get() > 0) && _stackedEffects.contains(skill.getAbnormalType()))
|
||||||
{
|
{
|
||||||
final Skill skill = info.getSkill();
|
// If incoming buff isnt hidden, remove any hidden buffs with its abnormal type.
|
||||||
|
if (info.isInUse())
|
||||||
// Handle hidden buffs. Check if there was such abnormal before so we can continue.
|
|
||||||
if ((_hiddenBuffs.get() > 0) && _stackedEffects.contains(skill.getAbnormalType()))
|
|
||||||
{
|
{
|
||||||
// If incoming buff isnt hidden, remove any hidden buffs with its abnormal type.
|
unhideBuffs.removeIf(b -> b.isAbnormalType(skill.getAbnormalType()));
|
||||||
if (info.isInUse())
|
|
||||||
{
|
|
||||||
unhideBuffs.removeIf(b -> b.isAbnormalType(skill.getAbnormalType()));
|
|
||||||
}
|
|
||||||
// If this incoming buff is hidden and its first of its abnormal, or it removes any previous hidden buff with the same or lower abnormal level and add this instead.
|
|
||||||
else if (!abnormalTypeFlags.contains(skill.getAbnormalType()) || unhideBuffs.removeIf(b -> (b.isAbnormalType(skill.getAbnormalType())) && (b.getSkill().getAbnormalLvl() <= skill.getAbnormalLvl())))
|
|
||||||
{
|
|
||||||
unhideBuffs.add(info);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
// If this incoming buff is hidden and its first of its abnormal, or it removes any previous hidden buff with the same or lower abnormal level and add this instead.
|
||||||
// Add the EffectType flag.
|
else if (!abnormalTypeFlags.contains(skill.getAbnormalType()) || unhideBuffs.removeIf(b -> (b.isAbnormalType(skill.getAbnormalType())) && (b.getSkill().getAbnormalLvl() <= skill.getAbnormalLvl())))
|
||||||
for (AbstractEffect e : info.getEffects())
|
|
||||||
{
|
{
|
||||||
flags |= e.getEffectFlags();
|
unhideBuffs.add(info);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Add the AbnormalType flag.
|
// Add the EffectType flag.
|
||||||
abnormalTypeFlags.add(skill.getAbnormalType());
|
for (AbstractEffect e : info.getEffects())
|
||||||
|
{
|
||||||
|
flags |= e.getEffectFlags();
|
||||||
|
}
|
||||||
|
|
||||||
// Add AbnormalVisualEffect flag.
|
// Add the AbnormalType flag.
|
||||||
if (skill.hasAbnormalVisualEffects())
|
abnormalTypeFlags.add(skill.getAbnormalType());
|
||||||
|
|
||||||
|
// Add AbnormalVisualEffect flag.
|
||||||
|
if (skill.hasAbnormalVisualEffects())
|
||||||
|
{
|
||||||
|
for (AbnormalVisualEffect ave : skill.getAbnormalVisualEffects())
|
||||||
{
|
{
|
||||||
abnormalVisualEffectFlags.addAll(skill.getAbnormalVisualEffects());
|
abnormalVisualEffectFlags.add(ave);
|
||||||
|
_abnormalVisualEffects.add(ave);
|
||||||
|
}
|
||||||
|
if (broadcast)
|
||||||
|
{
|
||||||
|
_owner.updateAbnormalVisualEffects();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1167,7 +1134,7 @@ public final class CharEffectList
|
|||||||
if (broadcast)
|
if (broadcast)
|
||||||
{
|
{
|
||||||
// Check if there is change in AbnormalVisualEffect
|
// Check if there is change in AbnormalVisualEffect
|
||||||
if ((abnormalVisualEffectFlags.size() != _abnormalVisualEffects.size()) || !abnormalVisualEffectFlags.containsAll(_abnormalVisualEffects))
|
if (!abnormalVisualEffectFlags.containsAll(_abnormalVisualEffects))
|
||||||
{
|
{
|
||||||
_abnormalVisualEffects = abnormalVisualEffectFlags;
|
_abnormalVisualEffects = abnormalVisualEffectFlags;
|
||||||
_owner.updateAbnormalVisualEffects();
|
_owner.updateAbnormalVisualEffects();
|
||||||
|
|||||||
@@ -77,7 +77,6 @@ public class DoppelgangerInstance extends L2Npc
|
|||||||
info.setAbnormalTime(summonerInfo.getAbnormalTime());
|
info.setAbnormalTime(summonerInfo.getAbnormalTime());
|
||||||
getEffectList().add(info);
|
getEffectList().add(info);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -786,7 +786,7 @@ public class CharStat
|
|||||||
final CharEffectList effectList = _activeChar.getEffectList();
|
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> 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> 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
|
// Call pump to each effect
|
||||||
//@formatter:off
|
//@formatter:off
|
||||||
|
|||||||
@@ -389,10 +389,10 @@ public final class BuffInfo
|
|||||||
for (AbstractEffect effect : _effects)
|
for (AbstractEffect effect : _effects)
|
||||||
{
|
{
|
||||||
// Instant effects shouldn't call onExit(..).
|
// Instant effects shouldn't call onExit(..).
|
||||||
if (!effect.isInstant())
|
// if (!effect.isInstant())
|
||||||
{
|
// {
|
||||||
effect.onExit(_effector, _effected, _skill);
|
effect.onExit(_effector, _effected, _skill);
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set the proper system message.
|
// Set the proper system message.
|
||||||
|
|||||||
@@ -21,13 +21,11 @@ import java.util.List;
|
|||||||
|
|
||||||
import com.l2jmobius.commons.network.PacketWriter;
|
import com.l2jmobius.commons.network.PacketWriter;
|
||||||
import com.l2jmobius.gameserver.model.skills.BuffInfo;
|
import com.l2jmobius.gameserver.model.skills.BuffInfo;
|
||||||
import com.l2jmobius.gameserver.model.skills.Skill;
|
|
||||||
import com.l2jmobius.gameserver.network.OutgoingPackets;
|
import com.l2jmobius.gameserver.network.OutgoingPackets;
|
||||||
|
|
||||||
public class AbnormalStatusUpdate implements IClientOutgoingPacket
|
public class AbnormalStatusUpdate implements IClientOutgoingPacket
|
||||||
{
|
{
|
||||||
private final List<BuffInfo> _effects = new ArrayList<>();
|
private final List<BuffInfo> _effects = new ArrayList<>();
|
||||||
private final List<Skill> _effects2 = new ArrayList<>();
|
|
||||||
|
|
||||||
public void addSkill(BuffInfo info)
|
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
|
@Override
|
||||||
public boolean write(PacketWriter packet)
|
public boolean write(PacketWriter packet)
|
||||||
{
|
{
|
||||||
OutgoingPackets.ABNORMAL_STATUS_UPDATE.writeId(packet);
|
OutgoingPackets.ABNORMAL_STATUS_UPDATE.writeId(packet);
|
||||||
|
|
||||||
packet.writeH(_effects.size() + _effects2.size());
|
packet.writeH(_effects.size());
|
||||||
for (BuffInfo info : _effects)
|
for (BuffInfo info : _effects)
|
||||||
{
|
{
|
||||||
if ((info != null) && info.isInUse())
|
if ((info != null) && info.isInUse())
|
||||||
@@ -62,17 +52,6 @@ public class AbnormalStatusUpdate implements IClientOutgoingPacket
|
|||||||
writeOptionalD(packet, info.getSkill().isAura() ? -1 : info.getTime());
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,6 @@
|
|||||||
*/
|
*/
|
||||||
package com.l2jmobius.gameserver.network.serverpackets;
|
package com.l2jmobius.gameserver.network.serverpackets;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
@@ -24,40 +23,12 @@ import java.util.stream.Collectors;
|
|||||||
import com.l2jmobius.commons.network.PacketWriter;
|
import com.l2jmobius.commons.network.PacketWriter;
|
||||||
import com.l2jmobius.gameserver.model.actor.L2Character;
|
import com.l2jmobius.gameserver.model.actor.L2Character;
|
||||||
import com.l2jmobius.gameserver.model.skills.BuffInfo;
|
import com.l2jmobius.gameserver.model.skills.BuffInfo;
|
||||||
import com.l2jmobius.gameserver.model.skills.Skill;
|
|
||||||
import com.l2jmobius.gameserver.network.OutgoingPackets;
|
import com.l2jmobius.gameserver.network.OutgoingPackets;
|
||||||
|
|
||||||
public class ExAbnormalStatusUpdateFromTarget implements IClientOutgoingPacket
|
public class ExAbnormalStatusUpdateFromTarget implements IClientOutgoingPacket
|
||||||
{
|
{
|
||||||
private final L2Character _character;
|
private final L2Character _character;
|
||||||
private List<Effect> _effects = new ArrayList<>();
|
private final List<BuffInfo> _effects;
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public ExAbnormalStatusUpdateFromTarget(L2Character character)
|
public ExAbnormalStatusUpdateFromTarget(L2Character character)
|
||||||
{
|
{
|
||||||
@@ -68,7 +39,6 @@ public class ExAbnormalStatusUpdateFromTarget implements IClientOutgoingPacket
|
|||||||
.filter(Objects::nonNull)
|
.filter(Objects::nonNull)
|
||||||
.filter(BuffInfo::isInUse)
|
.filter(BuffInfo::isInUse)
|
||||||
.filter(b -> !b.getSkill().isToggle())
|
.filter(b -> !b.getSkill().isToggle())
|
||||||
.map(Effect::new)
|
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
//@formatter:on
|
//@formatter:on
|
||||||
}
|
}
|
||||||
@@ -81,13 +51,15 @@ public class ExAbnormalStatusUpdateFromTarget implements IClientOutgoingPacket
|
|||||||
packet.writeD(_character.getObjectId());
|
packet.writeD(_character.getObjectId());
|
||||||
packet.writeH(_effects.size());
|
packet.writeH(_effects.size());
|
||||||
|
|
||||||
for (Effect info : _effects)
|
for (BuffInfo info : _effects)
|
||||||
{
|
{
|
||||||
packet.writeD(info._skillId);
|
packet.writeD(info.getSkill().getDisplayId());
|
||||||
packet.writeH(info._level);
|
packet.writeH(info.getSkill().getDisplayLevel());
|
||||||
packet.writeH(info._abnormalType);
|
// packet.writeH(info.getSkill().getSubLevel());
|
||||||
packet.writeH(info._duration);
|
packet.writeH(info.getSkill().getAbnormalType().getClientId());
|
||||||
packet.writeD(info._caster);
|
// writeOptionalD(packet, info.getSkill().isAura() ? -1 : info.getTime());
|
||||||
|
packet.writeH(info.getSkill().isAura() ? -1 : info.getTime());
|
||||||
|
packet.writeD(info.getEffectorObjectId());
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,6 +16,8 @@
|
|||||||
*/
|
*/
|
||||||
package handlers.effecthandlers;
|
package handlers.effecthandlers;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
|
||||||
import com.l2jmobius.gameserver.model.L2Object;
|
import com.l2jmobius.gameserver.model.L2Object;
|
||||||
import com.l2jmobius.gameserver.model.L2World;
|
import com.l2jmobius.gameserver.model.L2World;
|
||||||
import com.l2jmobius.gameserver.model.StatsSet;
|
import com.l2jmobius.gameserver.model.StatsSet;
|
||||||
@@ -38,6 +40,19 @@ public final class CallSkillOnActionTime extends AbstractEffect
|
|||||||
setTicks(params.getInt("ticks"));
|
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
|
@Override
|
||||||
public boolean onActionTime(L2Character effector, L2Character effected, Skill skill)
|
public boolean onActionTime(L2Character effector, L2Character effected, Skill skill)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -136,6 +136,5 @@ public final class Disarmor extends AbstractEffect
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
super.onExit(effector, effected, skill);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -84,6 +84,5 @@ public final class DoubleCast extends AbstractEffect
|
|||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
super.onExit(effector, effected, skill);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -65,15 +65,15 @@ public final class CharEffectList
|
|||||||
{
|
{
|
||||||
private static final Logger LOGGER = Logger.getLogger(CharEffectList.class.getName());
|
private static final Logger LOGGER = Logger.getLogger(CharEffectList.class.getName());
|
||||||
/** Queue containing all effects from buffs for this effect list. */
|
/** 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. */
|
/** 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. */
|
/** 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}. */
|
/** Map containing the all stacked effect in progress for each {@code AbnormalType}. */
|
||||||
private volatile Set<AbnormalType> _stackedEffects = EnumSet.noneOf(AbnormalType.class);
|
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. */
|
/** 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. */
|
/** Set containing all abnormal visual effects this creature currently displays. */
|
||||||
private volatile Set<AbnormalVisualEffect> _abnormalVisualEffects = EnumSet.noneOf(AbnormalVisualEffect.class);
|
private volatile Set<AbnormalVisualEffect> _abnormalVisualEffects = EnumSet.noneOf(AbnormalVisualEffect.class);
|
||||||
/** Short buff skill ID. */
|
/** Short buff skill ID. */
|
||||||
@@ -110,7 +110,7 @@ public final class CharEffectList
|
|||||||
*/
|
*/
|
||||||
public Set<BuffInfo> getPassives()
|
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()
|
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()
|
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()
|
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()
|
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)
|
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)
|
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)
|
public void addBlockedAbnormalTypes(Set<AbnormalType> blockedAbnormalTypes)
|
||||||
{
|
{
|
||||||
// Initialize
|
|
||||||
if (_blockedAbnormalTypes == null)
|
|
||||||
{
|
|
||||||
synchronized (this)
|
|
||||||
{
|
|
||||||
if (_blockedAbnormalTypes == null)
|
|
||||||
{
|
|
||||||
_blockedAbnormalTypes = EnumSet.copyOf(blockedAbnormalTypes);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_blockedAbnormalTypes.addAll(blockedAbnormalTypes);
|
_blockedAbnormalTypes.addAll(blockedAbnormalTypes);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -238,7 +226,7 @@ public final class CharEffectList
|
|||||||
*/
|
*/
|
||||||
public boolean removeBlockedAbnormalTypes(Set<AbnormalType> blockedBuffSlots)
|
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()
|
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()
|
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)
|
public void stopAllPassives(boolean update, boolean broadcast)
|
||||||
{
|
{
|
||||||
if (_passives != null)
|
if (!_passives.isEmpty())
|
||||||
{
|
{
|
||||||
_passives.forEach(this::remove);
|
_passives.forEach(this::remove);
|
||||||
// Update stats, effect flags and icons.
|
// Update stats, effect flags and icons.
|
||||||
@@ -392,7 +380,7 @@ public final class CharEffectList
|
|||||||
*/
|
*/
|
||||||
public void stopAllOptions(boolean update, boolean broadcast)
|
public void stopAllOptions(boolean update, boolean broadcast)
|
||||||
{
|
{
|
||||||
if (_options != null)
|
if (!_options.isEmpty())
|
||||||
{
|
{
|
||||||
_options.forEach(this::remove);
|
_options.forEach(this::remove);
|
||||||
// Update stats, effect flags and icons.
|
// Update stats, effect flags and icons.
|
||||||
@@ -490,7 +478,7 @@ public final class CharEffectList
|
|||||||
*/
|
*/
|
||||||
public void stopEffects(Predicate<BuffInfo> filter, boolean update, boolean broadcast)
|
public void stopEffects(Predicate<BuffInfo> filter, boolean update, boolean broadcast)
|
||||||
{
|
{
|
||||||
if (_actives != null)
|
if (!_actives.isEmpty())
|
||||||
{
|
{
|
||||||
_actives.stream().filter(filter).forEach(this::remove);
|
_actives.stream().filter(filter).forEach(this::remove);
|
||||||
|
|
||||||
@@ -678,6 +666,10 @@ public final class CharEffectList
|
|||||||
{
|
{
|
||||||
// Remove active effect.
|
// Remove active effect.
|
||||||
removeActive(info, removed);
|
removeActive(info, removed);
|
||||||
|
if (_owner.isNpc()) // Fix for all NPC debuff animations removed.
|
||||||
|
{
|
||||||
|
updateEffectList(broadcast);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update stats, effect flags and icons.
|
// Update stats, effect flags and icons.
|
||||||
@@ -693,7 +685,7 @@ public final class CharEffectList
|
|||||||
*/
|
*/
|
||||||
private synchronized void removeActive(BuffInfo info, boolean removed)
|
private synchronized void removeActive(BuffInfo info, boolean removed)
|
||||||
{
|
{
|
||||||
if (_actives != null)
|
if (!_actives.isEmpty())
|
||||||
{
|
{
|
||||||
// Removes the buff from the given effect list.
|
// Removes the buff from the given effect list.
|
||||||
_actives.remove(info);
|
_actives.remove(info);
|
||||||
@@ -716,7 +708,7 @@ public final class CharEffectList
|
|||||||
|
|
||||||
private void removePassive(BuffInfo info, boolean removed)
|
private void removePassive(BuffInfo info, boolean removed)
|
||||||
{
|
{
|
||||||
if (_passives != null)
|
if (!_passives.isEmpty())
|
||||||
{
|
{
|
||||||
_passives.remove(info);
|
_passives.remove(info);
|
||||||
info.stopAllEffects(removed);
|
info.stopAllEffects(removed);
|
||||||
@@ -725,7 +717,7 @@ public final class CharEffectList
|
|||||||
|
|
||||||
private void removeOption(BuffInfo info, boolean removed)
|
private void removeOption(BuffInfo info, boolean removed)
|
||||||
{
|
{
|
||||||
if (_options != null)
|
if (!_options.isEmpty())
|
||||||
{
|
{
|
||||||
_options.remove(info);
|
_options.remove(info);
|
||||||
info.stopAllEffects(removed);
|
info.stopAllEffects(removed);
|
||||||
@@ -821,12 +813,6 @@ public final class CharEffectList
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize
|
|
||||||
if (_actives == null)
|
|
||||||
{
|
|
||||||
_actives = new ConcurrentLinkedQueue<>();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Manage effect stacking.
|
// Manage effect stacking.
|
||||||
if (hasAbnormalType(skill.getAbnormalType()))
|
if (hasAbnormalType(skill.getAbnormalType()))
|
||||||
{
|
{
|
||||||
@@ -857,7 +843,7 @@ public final class CharEffectList
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Remove effect that gets overriden.
|
// Remove effect that gets overridden.
|
||||||
remove(existingInfo);
|
remove(existingInfo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -865,7 +851,7 @@ public final class CharEffectList
|
|||||||
{
|
{
|
||||||
info.setInUse(false);
|
info.setInUse(false);
|
||||||
}
|
}
|
||||||
else // The effect we try to add should be overriden.
|
else // The effect we try to add should be overridden.
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -918,18 +904,6 @@ public final class CharEffectList
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize
|
|
||||||
if (_passives == null)
|
|
||||||
{
|
|
||||||
synchronized (this)
|
|
||||||
{
|
|
||||||
if (_passives == null)
|
|
||||||
{
|
|
||||||
_passives = ConcurrentHashMap.newKeySet();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove previous passives of this id.
|
// Remove previous passives of this id.
|
||||||
_passives.stream().filter(Objects::nonNull).filter(b -> b.getSkill().getId() == skill.getId()).forEach(b ->
|
_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)
|
if (info.getOption() != null)
|
||||||
{
|
{
|
||||||
// Initialize
|
|
||||||
if (_options == null)
|
|
||||||
{
|
|
||||||
synchronized (this)
|
|
||||||
{
|
|
||||||
if (_options == null)
|
|
||||||
{
|
|
||||||
_options = ConcurrentHashMap.newKeySet();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove previous options of this id.
|
// Remove previous options of this id.
|
||||||
_options.stream().filter(Objects::nonNull).filter(b -> b.getOption().getId() == info.getOption().getId()).forEach(b ->
|
_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<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();
|
final Optional<ExOlympiadSpelledInfo> os = (player.isInOlympiadMode() && player.isOlympiadStart()) ? Optional.of(new ExOlympiadSpelledInfo(player)) : Optional.empty();
|
||||||
|
|
||||||
if (_actives != null)
|
if (!_actives.isEmpty())
|
||||||
{
|
{
|
||||||
//@formatter:off
|
//@formatter:off
|
||||||
_actives.stream()
|
_actives.stream()
|
||||||
@@ -1109,42 +1071,47 @@ public final class CharEffectList
|
|||||||
final Set<BuffInfo> unhideBuffs = new HashSet<>();
|
final Set<BuffInfo> unhideBuffs = new HashSet<>();
|
||||||
|
|
||||||
// Recalculate new flags
|
// Recalculate new flags
|
||||||
if (_actives != null)
|
for (BuffInfo info : _actives)
|
||||||
{
|
{
|
||||||
for (BuffInfo info : _actives)
|
if (info != null)
|
||||||
{
|
{
|
||||||
if (info != null)
|
final Skill skill = info.getSkill();
|
||||||
|
|
||||||
|
// Handle hidden buffs. Check if there was such abnormal before so we can continue.
|
||||||
|
if ((_hiddenBuffs.get() > 0) && _stackedEffects.contains(skill.getAbnormalType()))
|
||||||
{
|
{
|
||||||
final Skill skill = info.getSkill();
|
// If incoming buff isnt hidden, remove any hidden buffs with its abnormal type.
|
||||||
|
if (info.isInUse())
|
||||||
// Handle hidden buffs. Check if there was such abnormal before so we can continue.
|
|
||||||
if ((_hiddenBuffs.get() > 0) && _stackedEffects.contains(skill.getAbnormalType()))
|
|
||||||
{
|
{
|
||||||
// If incoming buff isnt hidden, remove any hidden buffs with its abnormal type.
|
unhideBuffs.removeIf(b -> b.isAbnormalType(skill.getAbnormalType()));
|
||||||
if (info.isInUse())
|
|
||||||
{
|
|
||||||
unhideBuffs.removeIf(b -> b.isAbnormalType(skill.getAbnormalType()));
|
|
||||||
}
|
|
||||||
// If this incoming buff is hidden and its first of its abnormal, or it removes any previous hidden buff with the same or lower abnormal level and add this instead.
|
|
||||||
else if (!abnormalTypeFlags.contains(skill.getAbnormalType()) || unhideBuffs.removeIf(b -> (b.isAbnormalType(skill.getAbnormalType())) && (b.getSkill().getAbnormalLvl() <= skill.getAbnormalLvl())))
|
|
||||||
{
|
|
||||||
unhideBuffs.add(info);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
// If this incoming buff is hidden and its first of its abnormal, or it removes any previous hidden buff with the same or lower abnormal level and add this instead.
|
||||||
// Add the EffectType flag.
|
else if (!abnormalTypeFlags.contains(skill.getAbnormalType()) || unhideBuffs.removeIf(b -> (b.isAbnormalType(skill.getAbnormalType())) && (b.getSkill().getAbnormalLvl() <= skill.getAbnormalLvl())))
|
||||||
for (AbstractEffect e : info.getEffects())
|
|
||||||
{
|
{
|
||||||
flags |= e.getEffectFlags();
|
unhideBuffs.add(info);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Add the AbnormalType flag.
|
// Add the EffectType flag.
|
||||||
abnormalTypeFlags.add(skill.getAbnormalType());
|
for (AbstractEffect e : info.getEffects())
|
||||||
|
{
|
||||||
|
flags |= e.getEffectFlags();
|
||||||
|
}
|
||||||
|
|
||||||
// Add AbnormalVisualEffect flag.
|
// Add the AbnormalType flag.
|
||||||
if (skill.hasAbnormalVisualEffects())
|
abnormalTypeFlags.add(skill.getAbnormalType());
|
||||||
|
|
||||||
|
// Add AbnormalVisualEffect flag.
|
||||||
|
if (skill.hasAbnormalVisualEffects())
|
||||||
|
{
|
||||||
|
for (AbnormalVisualEffect ave : skill.getAbnormalVisualEffects())
|
||||||
{
|
{
|
||||||
abnormalVisualEffectFlags.addAll(skill.getAbnormalVisualEffects());
|
abnormalVisualEffectFlags.add(ave);
|
||||||
|
_abnormalVisualEffects.add(ave);
|
||||||
|
}
|
||||||
|
if (broadcast)
|
||||||
|
{
|
||||||
|
_owner.updateAbnormalVisualEffects();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1167,7 +1134,7 @@ public final class CharEffectList
|
|||||||
if (broadcast)
|
if (broadcast)
|
||||||
{
|
{
|
||||||
// Check if there is change in AbnormalVisualEffect
|
// Check if there is change in AbnormalVisualEffect
|
||||||
if ((abnormalVisualEffectFlags.size() != _abnormalVisualEffects.size()) || !abnormalVisualEffectFlags.containsAll(_abnormalVisualEffects))
|
if (!abnormalVisualEffectFlags.containsAll(_abnormalVisualEffects))
|
||||||
{
|
{
|
||||||
_abnormalVisualEffects = abnormalVisualEffectFlags;
|
_abnormalVisualEffects = abnormalVisualEffectFlags;
|
||||||
_owner.updateAbnormalVisualEffects();
|
_owner.updateAbnormalVisualEffects();
|
||||||
|
|||||||
@@ -77,7 +77,6 @@ public class DoppelgangerInstance extends L2Npc
|
|||||||
info.setAbnormalTime(summonerInfo.getAbnormalTime());
|
info.setAbnormalTime(summonerInfo.getAbnormalTime());
|
||||||
getEffectList().add(info);
|
getEffectList().add(info);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -786,7 +786,7 @@ public class CharStat
|
|||||||
final CharEffectList effectList = _activeChar.getEffectList();
|
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> 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> 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
|
// Call pump to each effect
|
||||||
//@formatter:off
|
//@formatter:off
|
||||||
|
|||||||
@@ -389,10 +389,10 @@ public final class BuffInfo
|
|||||||
for (AbstractEffect effect : _effects)
|
for (AbstractEffect effect : _effects)
|
||||||
{
|
{
|
||||||
// Instant effects shouldn't call onExit(..).
|
// Instant effects shouldn't call onExit(..).
|
||||||
if (!effect.isInstant())
|
// if (!effect.isInstant())
|
||||||
{
|
// {
|
||||||
effect.onExit(_effector, _effected, _skill);
|
effect.onExit(_effector, _effected, _skill);
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set the proper system message.
|
// Set the proper system message.
|
||||||
|
|||||||
@@ -21,13 +21,11 @@ import java.util.List;
|
|||||||
|
|
||||||
import com.l2jmobius.commons.network.PacketWriter;
|
import com.l2jmobius.commons.network.PacketWriter;
|
||||||
import com.l2jmobius.gameserver.model.skills.BuffInfo;
|
import com.l2jmobius.gameserver.model.skills.BuffInfo;
|
||||||
import com.l2jmobius.gameserver.model.skills.Skill;
|
|
||||||
import com.l2jmobius.gameserver.network.OutgoingPackets;
|
import com.l2jmobius.gameserver.network.OutgoingPackets;
|
||||||
|
|
||||||
public class AbnormalStatusUpdate implements IClientOutgoingPacket
|
public class AbnormalStatusUpdate implements IClientOutgoingPacket
|
||||||
{
|
{
|
||||||
private final List<BuffInfo> _effects = new ArrayList<>();
|
private final List<BuffInfo> _effects = new ArrayList<>();
|
||||||
private final List<Skill> _effects2 = new ArrayList<>();
|
|
||||||
|
|
||||||
public void addSkill(BuffInfo info)
|
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
|
@Override
|
||||||
public boolean write(PacketWriter packet)
|
public boolean write(PacketWriter packet)
|
||||||
{
|
{
|
||||||
OutgoingPackets.ABNORMAL_STATUS_UPDATE.writeId(packet);
|
OutgoingPackets.ABNORMAL_STATUS_UPDATE.writeId(packet);
|
||||||
|
|
||||||
packet.writeH(_effects.size() + _effects2.size());
|
packet.writeH(_effects.size());
|
||||||
for (BuffInfo info : _effects)
|
for (BuffInfo info : _effects)
|
||||||
{
|
{
|
||||||
if ((info != null) && info.isInUse())
|
if ((info != null) && info.isInUse())
|
||||||
@@ -62,17 +52,6 @@ public class AbnormalStatusUpdate implements IClientOutgoingPacket
|
|||||||
writeOptionalD(packet, info.getSkill().isAura() ? -1 : info.getTime());
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,6 @@
|
|||||||
*/
|
*/
|
||||||
package com.l2jmobius.gameserver.network.serverpackets;
|
package com.l2jmobius.gameserver.network.serverpackets;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
@@ -24,41 +23,12 @@ import java.util.stream.Collectors;
|
|||||||
import com.l2jmobius.commons.network.PacketWriter;
|
import com.l2jmobius.commons.network.PacketWriter;
|
||||||
import com.l2jmobius.gameserver.model.actor.L2Character;
|
import com.l2jmobius.gameserver.model.actor.L2Character;
|
||||||
import com.l2jmobius.gameserver.model.skills.BuffInfo;
|
import com.l2jmobius.gameserver.model.skills.BuffInfo;
|
||||||
import com.l2jmobius.gameserver.model.skills.Skill;
|
|
||||||
import com.l2jmobius.gameserver.network.OutgoingPackets;
|
import com.l2jmobius.gameserver.network.OutgoingPackets;
|
||||||
|
|
||||||
public class ExAbnormalStatusUpdateFromTarget implements IClientOutgoingPacket
|
public class ExAbnormalStatusUpdateFromTarget implements IClientOutgoingPacket
|
||||||
{
|
{
|
||||||
private final L2Character _character;
|
private final L2Character _character;
|
||||||
private List<Effect> _effects = new ArrayList<>();
|
private final List<BuffInfo> _effects;
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public ExAbnormalStatusUpdateFromTarget(L2Character character)
|
public ExAbnormalStatusUpdateFromTarget(L2Character character)
|
||||||
{
|
{
|
||||||
@@ -69,7 +39,6 @@ public class ExAbnormalStatusUpdateFromTarget implements IClientOutgoingPacket
|
|||||||
.filter(Objects::nonNull)
|
.filter(Objects::nonNull)
|
||||||
.filter(BuffInfo::isInUse)
|
.filter(BuffInfo::isInUse)
|
||||||
.filter(b -> !b.getSkill().isToggle())
|
.filter(b -> !b.getSkill().isToggle())
|
||||||
.map(Effect::new)
|
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
//@formatter:on
|
//@formatter:on
|
||||||
}
|
}
|
||||||
@@ -82,14 +51,14 @@ public class ExAbnormalStatusUpdateFromTarget implements IClientOutgoingPacket
|
|||||||
packet.writeD(_character.getObjectId());
|
packet.writeD(_character.getObjectId());
|
||||||
packet.writeH(_effects.size());
|
packet.writeH(_effects.size());
|
||||||
|
|
||||||
for (Effect info : _effects)
|
for (BuffInfo info : _effects)
|
||||||
{
|
{
|
||||||
packet.writeD(info._skillId);
|
packet.writeD(info.getSkill().getDisplayId());
|
||||||
packet.writeH(info._level);
|
packet.writeH(info.getSkill().getDisplayLevel());
|
||||||
packet.writeH(info._subLevel);
|
packet.writeH(info.getSkill().getSubLevel());
|
||||||
packet.writeH(info._abnormalType);
|
packet.writeH(info.getSkill().getAbnormalType().getClientId());
|
||||||
writeOptionalD(packet, info._duration);
|
writeOptionalD(packet, info.getSkill().isAura() ? -1 : info.getTime());
|
||||||
packet.writeD(info._caster);
|
packet.writeD(info.getEffectorObjectId());
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,6 +16,8 @@
|
|||||||
*/
|
*/
|
||||||
package handlers.effecthandlers;
|
package handlers.effecthandlers;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
|
||||||
import com.l2jmobius.gameserver.model.L2Object;
|
import com.l2jmobius.gameserver.model.L2Object;
|
||||||
import com.l2jmobius.gameserver.model.L2World;
|
import com.l2jmobius.gameserver.model.L2World;
|
||||||
import com.l2jmobius.gameserver.model.StatsSet;
|
import com.l2jmobius.gameserver.model.StatsSet;
|
||||||
@@ -38,6 +40,19 @@ public final class CallSkillOnActionTime extends AbstractEffect
|
|||||||
setTicks(params.getInt("ticks"));
|
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
|
@Override
|
||||||
public boolean onActionTime(L2Character effector, L2Character effected, Skill skill)
|
public boolean onActionTime(L2Character effector, L2Character effected, Skill skill)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -136,6 +136,5 @@ public final class Disarmor extends AbstractEffect
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
super.onExit(effector, effected, skill);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -84,6 +84,5 @@ public final class DoubleCast extends AbstractEffect
|
|||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
super.onExit(effector, effected, skill);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -65,15 +65,15 @@ public final class CharEffectList
|
|||||||
{
|
{
|
||||||
private static final Logger LOGGER = Logger.getLogger(CharEffectList.class.getName());
|
private static final Logger LOGGER = Logger.getLogger(CharEffectList.class.getName());
|
||||||
/** Queue containing all effects from buffs for this effect list. */
|
/** 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. */
|
/** 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. */
|
/** 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}. */
|
/** Map containing the all stacked effect in progress for each {@code AbnormalType}. */
|
||||||
private volatile Set<AbnormalType> _stackedEffects = EnumSet.noneOf(AbnormalType.class);
|
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. */
|
/** 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. */
|
/** Set containing all abnormal visual effects this creature currently displays. */
|
||||||
private volatile Set<AbnormalVisualEffect> _abnormalVisualEffects = EnumSet.noneOf(AbnormalVisualEffect.class);
|
private volatile Set<AbnormalVisualEffect> _abnormalVisualEffects = EnumSet.noneOf(AbnormalVisualEffect.class);
|
||||||
/** Short buff skill ID. */
|
/** Short buff skill ID. */
|
||||||
@@ -110,7 +110,7 @@ public final class CharEffectList
|
|||||||
*/
|
*/
|
||||||
public Set<BuffInfo> getPassives()
|
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()
|
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()
|
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()
|
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()
|
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)
|
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)
|
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)
|
public void addBlockedAbnormalTypes(Set<AbnormalType> blockedAbnormalTypes)
|
||||||
{
|
{
|
||||||
// Initialize
|
|
||||||
if (_blockedAbnormalTypes == null)
|
|
||||||
{
|
|
||||||
synchronized (this)
|
|
||||||
{
|
|
||||||
if (_blockedAbnormalTypes == null)
|
|
||||||
{
|
|
||||||
_blockedAbnormalTypes = EnumSet.copyOf(blockedAbnormalTypes);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_blockedAbnormalTypes.addAll(blockedAbnormalTypes);
|
_blockedAbnormalTypes.addAll(blockedAbnormalTypes);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -238,7 +226,7 @@ public final class CharEffectList
|
|||||||
*/
|
*/
|
||||||
public boolean removeBlockedAbnormalTypes(Set<AbnormalType> blockedBuffSlots)
|
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()
|
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()
|
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)
|
public void stopAllPassives(boolean update, boolean broadcast)
|
||||||
{
|
{
|
||||||
if (_passives != null)
|
if (!_passives.isEmpty())
|
||||||
{
|
{
|
||||||
_passives.forEach(this::remove);
|
_passives.forEach(this::remove);
|
||||||
// Update stats, effect flags and icons.
|
// Update stats, effect flags and icons.
|
||||||
@@ -392,7 +380,7 @@ public final class CharEffectList
|
|||||||
*/
|
*/
|
||||||
public void stopAllOptions(boolean update, boolean broadcast)
|
public void stopAllOptions(boolean update, boolean broadcast)
|
||||||
{
|
{
|
||||||
if (_options != null)
|
if (!_options.isEmpty())
|
||||||
{
|
{
|
||||||
_options.forEach(this::remove);
|
_options.forEach(this::remove);
|
||||||
// Update stats, effect flags and icons.
|
// Update stats, effect flags and icons.
|
||||||
@@ -490,7 +478,7 @@ public final class CharEffectList
|
|||||||
*/
|
*/
|
||||||
public void stopEffects(Predicate<BuffInfo> filter, boolean update, boolean broadcast)
|
public void stopEffects(Predicate<BuffInfo> filter, boolean update, boolean broadcast)
|
||||||
{
|
{
|
||||||
if (_actives != null)
|
if (!_actives.isEmpty())
|
||||||
{
|
{
|
||||||
_actives.stream().filter(filter).forEach(this::remove);
|
_actives.stream().filter(filter).forEach(this::remove);
|
||||||
|
|
||||||
@@ -678,6 +666,10 @@ public final class CharEffectList
|
|||||||
{
|
{
|
||||||
// Remove active effect.
|
// Remove active effect.
|
||||||
removeActive(info, removed);
|
removeActive(info, removed);
|
||||||
|
if (_owner.isNpc()) // Fix for all NPC debuff animations removed.
|
||||||
|
{
|
||||||
|
updateEffectList(broadcast);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update stats, effect flags and icons.
|
// Update stats, effect flags and icons.
|
||||||
@@ -693,7 +685,7 @@ public final class CharEffectList
|
|||||||
*/
|
*/
|
||||||
private synchronized void removeActive(BuffInfo info, boolean removed)
|
private synchronized void removeActive(BuffInfo info, boolean removed)
|
||||||
{
|
{
|
||||||
if (_actives != null)
|
if (!_actives.isEmpty())
|
||||||
{
|
{
|
||||||
// Removes the buff from the given effect list.
|
// Removes the buff from the given effect list.
|
||||||
_actives.remove(info);
|
_actives.remove(info);
|
||||||
@@ -716,7 +708,7 @@ public final class CharEffectList
|
|||||||
|
|
||||||
private void removePassive(BuffInfo info, boolean removed)
|
private void removePassive(BuffInfo info, boolean removed)
|
||||||
{
|
{
|
||||||
if (_passives != null)
|
if (!_passives.isEmpty())
|
||||||
{
|
{
|
||||||
_passives.remove(info);
|
_passives.remove(info);
|
||||||
info.stopAllEffects(removed);
|
info.stopAllEffects(removed);
|
||||||
@@ -725,7 +717,7 @@ public final class CharEffectList
|
|||||||
|
|
||||||
private void removeOption(BuffInfo info, boolean removed)
|
private void removeOption(BuffInfo info, boolean removed)
|
||||||
{
|
{
|
||||||
if (_options != null)
|
if (!_options.isEmpty())
|
||||||
{
|
{
|
||||||
_options.remove(info);
|
_options.remove(info);
|
||||||
info.stopAllEffects(removed);
|
info.stopAllEffects(removed);
|
||||||
@@ -821,12 +813,6 @@ public final class CharEffectList
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize
|
|
||||||
if (_actives == null)
|
|
||||||
{
|
|
||||||
_actives = new ConcurrentLinkedQueue<>();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Manage effect stacking.
|
// Manage effect stacking.
|
||||||
if (hasAbnormalType(skill.getAbnormalType()))
|
if (hasAbnormalType(skill.getAbnormalType()))
|
||||||
{
|
{
|
||||||
@@ -857,7 +843,7 @@ public final class CharEffectList
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Remove effect that gets overriden.
|
// Remove effect that gets overridden.
|
||||||
remove(existingInfo);
|
remove(existingInfo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -865,7 +851,7 @@ public final class CharEffectList
|
|||||||
{
|
{
|
||||||
info.setInUse(false);
|
info.setInUse(false);
|
||||||
}
|
}
|
||||||
else // The effect we try to add should be overriden.
|
else // The effect we try to add should be overridden.
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -918,18 +904,6 @@ public final class CharEffectList
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize
|
|
||||||
if (_passives == null)
|
|
||||||
{
|
|
||||||
synchronized (this)
|
|
||||||
{
|
|
||||||
if (_passives == null)
|
|
||||||
{
|
|
||||||
_passives = ConcurrentHashMap.newKeySet();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove previous passives of this id.
|
// Remove previous passives of this id.
|
||||||
_passives.stream().filter(Objects::nonNull).filter(b -> b.getSkill().getId() == skill.getId()).forEach(b ->
|
_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)
|
if (info.getOption() != null)
|
||||||
{
|
{
|
||||||
// Initialize
|
|
||||||
if (_options == null)
|
|
||||||
{
|
|
||||||
synchronized (this)
|
|
||||||
{
|
|
||||||
if (_options == null)
|
|
||||||
{
|
|
||||||
_options = ConcurrentHashMap.newKeySet();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove previous options of this id.
|
// Remove previous options of this id.
|
||||||
_options.stream().filter(Objects::nonNull).filter(b -> b.getOption().getId() == info.getOption().getId()).forEach(b ->
|
_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<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();
|
final Optional<ExOlympiadSpelledInfo> os = (player.isInOlympiadMode() && player.isOlympiadStart()) ? Optional.of(new ExOlympiadSpelledInfo(player)) : Optional.empty();
|
||||||
|
|
||||||
if (_actives != null)
|
if (!_actives.isEmpty())
|
||||||
{
|
{
|
||||||
//@formatter:off
|
//@formatter:off
|
||||||
_actives.stream()
|
_actives.stream()
|
||||||
@@ -1109,42 +1071,47 @@ public final class CharEffectList
|
|||||||
final Set<BuffInfo> unhideBuffs = new HashSet<>();
|
final Set<BuffInfo> unhideBuffs = new HashSet<>();
|
||||||
|
|
||||||
// Recalculate new flags
|
// Recalculate new flags
|
||||||
if (_actives != null)
|
for (BuffInfo info : _actives)
|
||||||
{
|
{
|
||||||
for (BuffInfo info : _actives)
|
if (info != null)
|
||||||
{
|
{
|
||||||
if (info != null)
|
final Skill skill = info.getSkill();
|
||||||
|
|
||||||
|
// Handle hidden buffs. Check if there was such abnormal before so we can continue.
|
||||||
|
if ((_hiddenBuffs.get() > 0) && _stackedEffects.contains(skill.getAbnormalType()))
|
||||||
{
|
{
|
||||||
final Skill skill = info.getSkill();
|
// If incoming buff isnt hidden, remove any hidden buffs with its abnormal type.
|
||||||
|
if (info.isInUse())
|
||||||
// Handle hidden buffs. Check if there was such abnormal before so we can continue.
|
|
||||||
if ((_hiddenBuffs.get() > 0) && _stackedEffects.contains(skill.getAbnormalType()))
|
|
||||||
{
|
{
|
||||||
// If incoming buff isnt hidden, remove any hidden buffs with its abnormal type.
|
unhideBuffs.removeIf(b -> b.isAbnormalType(skill.getAbnormalType()));
|
||||||
if (info.isInUse())
|
|
||||||
{
|
|
||||||
unhideBuffs.removeIf(b -> b.isAbnormalType(skill.getAbnormalType()));
|
|
||||||
}
|
|
||||||
// If this incoming buff is hidden and its first of its abnormal, or it removes any previous hidden buff with the same or lower abnormal level and add this instead.
|
|
||||||
else if (!abnormalTypeFlags.contains(skill.getAbnormalType()) || unhideBuffs.removeIf(b -> (b.isAbnormalType(skill.getAbnormalType())) && (b.getSkill().getAbnormalLvl() <= skill.getAbnormalLvl())))
|
|
||||||
{
|
|
||||||
unhideBuffs.add(info);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
// If this incoming buff is hidden and its first of its abnormal, or it removes any previous hidden buff with the same or lower abnormal level and add this instead.
|
||||||
// Add the EffectType flag.
|
else if (!abnormalTypeFlags.contains(skill.getAbnormalType()) || unhideBuffs.removeIf(b -> (b.isAbnormalType(skill.getAbnormalType())) && (b.getSkill().getAbnormalLvl() <= skill.getAbnormalLvl())))
|
||||||
for (AbstractEffect e : info.getEffects())
|
|
||||||
{
|
{
|
||||||
flags |= e.getEffectFlags();
|
unhideBuffs.add(info);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Add the AbnormalType flag.
|
// Add the EffectType flag.
|
||||||
abnormalTypeFlags.add(skill.getAbnormalType());
|
for (AbstractEffect e : info.getEffects())
|
||||||
|
{
|
||||||
|
flags |= e.getEffectFlags();
|
||||||
|
}
|
||||||
|
|
||||||
// Add AbnormalVisualEffect flag.
|
// Add the AbnormalType flag.
|
||||||
if (skill.hasAbnormalVisualEffects())
|
abnormalTypeFlags.add(skill.getAbnormalType());
|
||||||
|
|
||||||
|
// Add AbnormalVisualEffect flag.
|
||||||
|
if (skill.hasAbnormalVisualEffects())
|
||||||
|
{
|
||||||
|
for (AbnormalVisualEffect ave : skill.getAbnormalVisualEffects())
|
||||||
{
|
{
|
||||||
abnormalVisualEffectFlags.addAll(skill.getAbnormalVisualEffects());
|
abnormalVisualEffectFlags.add(ave);
|
||||||
|
_abnormalVisualEffects.add(ave);
|
||||||
|
}
|
||||||
|
if (broadcast)
|
||||||
|
{
|
||||||
|
_owner.updateAbnormalVisualEffects();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1167,7 +1134,7 @@ public final class CharEffectList
|
|||||||
if (broadcast)
|
if (broadcast)
|
||||||
{
|
{
|
||||||
// Check if there is change in AbnormalVisualEffect
|
// Check if there is change in AbnormalVisualEffect
|
||||||
if ((abnormalVisualEffectFlags.size() != _abnormalVisualEffects.size()) || !abnormalVisualEffectFlags.containsAll(_abnormalVisualEffects))
|
if (!abnormalVisualEffectFlags.containsAll(_abnormalVisualEffects))
|
||||||
{
|
{
|
||||||
_abnormalVisualEffects = abnormalVisualEffectFlags;
|
_abnormalVisualEffects = abnormalVisualEffectFlags;
|
||||||
_owner.updateAbnormalVisualEffects();
|
_owner.updateAbnormalVisualEffects();
|
||||||
|
|||||||
@@ -77,7 +77,6 @@ public class DoppelgangerInstance extends L2Npc
|
|||||||
info.setAbnormalTime(summonerInfo.getAbnormalTime());
|
info.setAbnormalTime(summonerInfo.getAbnormalTime());
|
||||||
getEffectList().add(info);
|
getEffectList().add(info);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -786,7 +786,7 @@ public class CharStat
|
|||||||
final CharEffectList effectList = _activeChar.getEffectList();
|
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> 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> 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
|
// Call pump to each effect
|
||||||
//@formatter:off
|
//@formatter:off
|
||||||
|
|||||||
@@ -389,10 +389,10 @@ public final class BuffInfo
|
|||||||
for (AbstractEffect effect : _effects)
|
for (AbstractEffect effect : _effects)
|
||||||
{
|
{
|
||||||
// Instant effects shouldn't call onExit(..).
|
// Instant effects shouldn't call onExit(..).
|
||||||
if (!effect.isInstant())
|
// if (!effect.isInstant())
|
||||||
{
|
// {
|
||||||
effect.onExit(_effector, _effected, _skill);
|
effect.onExit(_effector, _effected, _skill);
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set the proper system message.
|
// Set the proper system message.
|
||||||
|
|||||||
@@ -21,13 +21,11 @@ import java.util.List;
|
|||||||
|
|
||||||
import com.l2jmobius.commons.network.PacketWriter;
|
import com.l2jmobius.commons.network.PacketWriter;
|
||||||
import com.l2jmobius.gameserver.model.skills.BuffInfo;
|
import com.l2jmobius.gameserver.model.skills.BuffInfo;
|
||||||
import com.l2jmobius.gameserver.model.skills.Skill;
|
|
||||||
import com.l2jmobius.gameserver.network.OutgoingPackets;
|
import com.l2jmobius.gameserver.network.OutgoingPackets;
|
||||||
|
|
||||||
public class AbnormalStatusUpdate implements IClientOutgoingPacket
|
public class AbnormalStatusUpdate implements IClientOutgoingPacket
|
||||||
{
|
{
|
||||||
private final List<BuffInfo> _effects = new ArrayList<>();
|
private final List<BuffInfo> _effects = new ArrayList<>();
|
||||||
private final List<Skill> _effects2 = new ArrayList<>();
|
|
||||||
|
|
||||||
public void addSkill(BuffInfo info)
|
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
|
@Override
|
||||||
public boolean write(PacketWriter packet)
|
public boolean write(PacketWriter packet)
|
||||||
{
|
{
|
||||||
OutgoingPackets.ABNORMAL_STATUS_UPDATE.writeId(packet);
|
OutgoingPackets.ABNORMAL_STATUS_UPDATE.writeId(packet);
|
||||||
|
|
||||||
packet.writeH(_effects.size() + _effects2.size());
|
packet.writeH(_effects.size());
|
||||||
for (BuffInfo info : _effects)
|
for (BuffInfo info : _effects)
|
||||||
{
|
{
|
||||||
if ((info != null) && info.isInUse())
|
if ((info != null) && info.isInUse())
|
||||||
@@ -62,17 +52,6 @@ public class AbnormalStatusUpdate implements IClientOutgoingPacket
|
|||||||
writeOptionalD(packet, info.getSkill().isAura() ? -1 : info.getTime());
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,6 @@
|
|||||||
*/
|
*/
|
||||||
package com.l2jmobius.gameserver.network.serverpackets;
|
package com.l2jmobius.gameserver.network.serverpackets;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
@@ -24,41 +23,12 @@ import java.util.stream.Collectors;
|
|||||||
import com.l2jmobius.commons.network.PacketWriter;
|
import com.l2jmobius.commons.network.PacketWriter;
|
||||||
import com.l2jmobius.gameserver.model.actor.L2Character;
|
import com.l2jmobius.gameserver.model.actor.L2Character;
|
||||||
import com.l2jmobius.gameserver.model.skills.BuffInfo;
|
import com.l2jmobius.gameserver.model.skills.BuffInfo;
|
||||||
import com.l2jmobius.gameserver.model.skills.Skill;
|
|
||||||
import com.l2jmobius.gameserver.network.OutgoingPackets;
|
import com.l2jmobius.gameserver.network.OutgoingPackets;
|
||||||
|
|
||||||
public class ExAbnormalStatusUpdateFromTarget implements IClientOutgoingPacket
|
public class ExAbnormalStatusUpdateFromTarget implements IClientOutgoingPacket
|
||||||
{
|
{
|
||||||
private final L2Character _character;
|
private final L2Character _character;
|
||||||
private List<Effect> _effects = new ArrayList<>();
|
private final List<BuffInfo> _effects;
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public ExAbnormalStatusUpdateFromTarget(L2Character character)
|
public ExAbnormalStatusUpdateFromTarget(L2Character character)
|
||||||
{
|
{
|
||||||
@@ -69,7 +39,6 @@ public class ExAbnormalStatusUpdateFromTarget implements IClientOutgoingPacket
|
|||||||
.filter(Objects::nonNull)
|
.filter(Objects::nonNull)
|
||||||
.filter(BuffInfo::isInUse)
|
.filter(BuffInfo::isInUse)
|
||||||
.filter(b -> !b.getSkill().isToggle())
|
.filter(b -> !b.getSkill().isToggle())
|
||||||
.map(Effect::new)
|
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
//@formatter:on
|
//@formatter:on
|
||||||
}
|
}
|
||||||
@@ -82,14 +51,14 @@ public class ExAbnormalStatusUpdateFromTarget implements IClientOutgoingPacket
|
|||||||
packet.writeD(_character.getObjectId());
|
packet.writeD(_character.getObjectId());
|
||||||
packet.writeH(_effects.size());
|
packet.writeH(_effects.size());
|
||||||
|
|
||||||
for (Effect info : _effects)
|
for (BuffInfo info : _effects)
|
||||||
{
|
{
|
||||||
packet.writeD(info._skillId);
|
packet.writeD(info.getSkill().getDisplayId());
|
||||||
packet.writeH(info._level);
|
packet.writeH(info.getSkill().getDisplayLevel());
|
||||||
packet.writeH(info._subLevel);
|
packet.writeH(info.getSkill().getSubLevel());
|
||||||
packet.writeH(info._abnormalType);
|
packet.writeH(info.getSkill().getAbnormalType().getClientId());
|
||||||
writeOptionalD(packet, info._duration);
|
writeOptionalD(packet, info.getSkill().isAura() ? -1 : info.getTime());
|
||||||
packet.writeD(info._caster);
|
packet.writeD(info.getEffectorObjectId());
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,6 +16,8 @@
|
|||||||
*/
|
*/
|
||||||
package handlers.effecthandlers;
|
package handlers.effecthandlers;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
|
||||||
import com.l2jmobius.gameserver.model.L2Object;
|
import com.l2jmobius.gameserver.model.L2Object;
|
||||||
import com.l2jmobius.gameserver.model.L2World;
|
import com.l2jmobius.gameserver.model.L2World;
|
||||||
import com.l2jmobius.gameserver.model.StatsSet;
|
import com.l2jmobius.gameserver.model.StatsSet;
|
||||||
@@ -38,6 +40,19 @@ public final class CallSkillOnActionTime extends AbstractEffect
|
|||||||
setTicks(params.getInt("ticks"));
|
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
|
@Override
|
||||||
public boolean onActionTime(L2Character effector, L2Character effected, Skill skill)
|
public boolean onActionTime(L2Character effector, L2Character effected, Skill skill)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -136,6 +136,5 @@ public final class Disarmor extends AbstractEffect
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
super.onExit(effector, effected, skill);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -84,6 +84,5 @@ public final class DoubleCast extends AbstractEffect
|
|||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
super.onExit(effector, effected, skill);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -65,15 +65,15 @@ public final class CharEffectList
|
|||||||
{
|
{
|
||||||
private static final Logger LOGGER = Logger.getLogger(CharEffectList.class.getName());
|
private static final Logger LOGGER = Logger.getLogger(CharEffectList.class.getName());
|
||||||
/** Queue containing all effects from buffs for this effect list. */
|
/** 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. */
|
/** 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. */
|
/** 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}. */
|
/** Map containing the all stacked effect in progress for each {@code AbnormalType}. */
|
||||||
private volatile Set<AbnormalType> _stackedEffects = EnumSet.noneOf(AbnormalType.class);
|
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. */
|
/** 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. */
|
/** Set containing all abnormal visual effects this creature currently displays. */
|
||||||
private volatile Set<AbnormalVisualEffect> _abnormalVisualEffects = EnumSet.noneOf(AbnormalVisualEffect.class);
|
private volatile Set<AbnormalVisualEffect> _abnormalVisualEffects = EnumSet.noneOf(AbnormalVisualEffect.class);
|
||||||
/** Short buff skill ID. */
|
/** Short buff skill ID. */
|
||||||
@@ -110,7 +110,7 @@ public final class CharEffectList
|
|||||||
*/
|
*/
|
||||||
public Set<BuffInfo> getPassives()
|
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()
|
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()
|
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()
|
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()
|
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)
|
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)
|
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)
|
public void addBlockedAbnormalTypes(Set<AbnormalType> blockedAbnormalTypes)
|
||||||
{
|
{
|
||||||
// Initialize
|
|
||||||
if (_blockedAbnormalTypes == null)
|
|
||||||
{
|
|
||||||
synchronized (this)
|
|
||||||
{
|
|
||||||
if (_blockedAbnormalTypes == null)
|
|
||||||
{
|
|
||||||
_blockedAbnormalTypes = EnumSet.copyOf(blockedAbnormalTypes);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_blockedAbnormalTypes.addAll(blockedAbnormalTypes);
|
_blockedAbnormalTypes.addAll(blockedAbnormalTypes);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -238,7 +226,7 @@ public final class CharEffectList
|
|||||||
*/
|
*/
|
||||||
public boolean removeBlockedAbnormalTypes(Set<AbnormalType> blockedBuffSlots)
|
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()
|
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()
|
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)
|
public void stopAllPassives(boolean update, boolean broadcast)
|
||||||
{
|
{
|
||||||
if (_passives != null)
|
if (!_passives.isEmpty())
|
||||||
{
|
{
|
||||||
_passives.forEach(this::remove);
|
_passives.forEach(this::remove);
|
||||||
// Update stats, effect flags and icons.
|
// Update stats, effect flags and icons.
|
||||||
@@ -392,7 +380,7 @@ public final class CharEffectList
|
|||||||
*/
|
*/
|
||||||
public void stopAllOptions(boolean update, boolean broadcast)
|
public void stopAllOptions(boolean update, boolean broadcast)
|
||||||
{
|
{
|
||||||
if (_options != null)
|
if (!_options.isEmpty())
|
||||||
{
|
{
|
||||||
_options.forEach(this::remove);
|
_options.forEach(this::remove);
|
||||||
// Update stats, effect flags and icons.
|
// Update stats, effect flags and icons.
|
||||||
@@ -490,7 +478,7 @@ public final class CharEffectList
|
|||||||
*/
|
*/
|
||||||
public void stopEffects(Predicate<BuffInfo> filter, boolean update, boolean broadcast)
|
public void stopEffects(Predicate<BuffInfo> filter, boolean update, boolean broadcast)
|
||||||
{
|
{
|
||||||
if (_actives != null)
|
if (!_actives.isEmpty())
|
||||||
{
|
{
|
||||||
_actives.stream().filter(filter).forEach(this::remove);
|
_actives.stream().filter(filter).forEach(this::remove);
|
||||||
|
|
||||||
@@ -678,6 +666,10 @@ public final class CharEffectList
|
|||||||
{
|
{
|
||||||
// Remove active effect.
|
// Remove active effect.
|
||||||
removeActive(info, removed);
|
removeActive(info, removed);
|
||||||
|
if (_owner.isNpc()) // Fix for all NPC debuff animations removed.
|
||||||
|
{
|
||||||
|
updateEffectList(broadcast);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update stats, effect flags and icons.
|
// Update stats, effect flags and icons.
|
||||||
@@ -693,7 +685,7 @@ public final class CharEffectList
|
|||||||
*/
|
*/
|
||||||
private synchronized void removeActive(BuffInfo info, boolean removed)
|
private synchronized void removeActive(BuffInfo info, boolean removed)
|
||||||
{
|
{
|
||||||
if (_actives != null)
|
if (!_actives.isEmpty())
|
||||||
{
|
{
|
||||||
// Removes the buff from the given effect list.
|
// Removes the buff from the given effect list.
|
||||||
_actives.remove(info);
|
_actives.remove(info);
|
||||||
@@ -716,7 +708,7 @@ public final class CharEffectList
|
|||||||
|
|
||||||
private void removePassive(BuffInfo info, boolean removed)
|
private void removePassive(BuffInfo info, boolean removed)
|
||||||
{
|
{
|
||||||
if (_passives != null)
|
if (!_passives.isEmpty())
|
||||||
{
|
{
|
||||||
_passives.remove(info);
|
_passives.remove(info);
|
||||||
info.stopAllEffects(removed);
|
info.stopAllEffects(removed);
|
||||||
@@ -725,7 +717,7 @@ public final class CharEffectList
|
|||||||
|
|
||||||
private void removeOption(BuffInfo info, boolean removed)
|
private void removeOption(BuffInfo info, boolean removed)
|
||||||
{
|
{
|
||||||
if (_options != null)
|
if (!_options.isEmpty())
|
||||||
{
|
{
|
||||||
_options.remove(info);
|
_options.remove(info);
|
||||||
info.stopAllEffects(removed);
|
info.stopAllEffects(removed);
|
||||||
@@ -821,12 +813,6 @@ public final class CharEffectList
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize
|
|
||||||
if (_actives == null)
|
|
||||||
{
|
|
||||||
_actives = new ConcurrentLinkedQueue<>();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Manage effect stacking.
|
// Manage effect stacking.
|
||||||
if (hasAbnormalType(skill.getAbnormalType()))
|
if (hasAbnormalType(skill.getAbnormalType()))
|
||||||
{
|
{
|
||||||
@@ -857,7 +843,7 @@ public final class CharEffectList
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Remove effect that gets overriden.
|
// Remove effect that gets overridden.
|
||||||
remove(existingInfo);
|
remove(existingInfo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -865,7 +851,7 @@ public final class CharEffectList
|
|||||||
{
|
{
|
||||||
info.setInUse(false);
|
info.setInUse(false);
|
||||||
}
|
}
|
||||||
else // The effect we try to add should be overriden.
|
else // The effect we try to add should be overridden.
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -918,18 +904,6 @@ public final class CharEffectList
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize
|
|
||||||
if (_passives == null)
|
|
||||||
{
|
|
||||||
synchronized (this)
|
|
||||||
{
|
|
||||||
if (_passives == null)
|
|
||||||
{
|
|
||||||
_passives = ConcurrentHashMap.newKeySet();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove previous passives of this id.
|
// Remove previous passives of this id.
|
||||||
_passives.stream().filter(Objects::nonNull).filter(b -> b.getSkill().getId() == skill.getId()).forEach(b ->
|
_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)
|
if (info.getOption() != null)
|
||||||
{
|
{
|
||||||
// Initialize
|
|
||||||
if (_options == null)
|
|
||||||
{
|
|
||||||
synchronized (this)
|
|
||||||
{
|
|
||||||
if (_options == null)
|
|
||||||
{
|
|
||||||
_options = ConcurrentHashMap.newKeySet();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove previous options of this id.
|
// Remove previous options of this id.
|
||||||
_options.stream().filter(Objects::nonNull).filter(b -> b.getOption().getId() == info.getOption().getId()).forEach(b ->
|
_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<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();
|
final Optional<ExOlympiadSpelledInfo> os = (player.isInOlympiadMode() && player.isOlympiadStart()) ? Optional.of(new ExOlympiadSpelledInfo(player)) : Optional.empty();
|
||||||
|
|
||||||
if (_actives != null)
|
if (!_actives.isEmpty())
|
||||||
{
|
{
|
||||||
//@formatter:off
|
//@formatter:off
|
||||||
_actives.stream()
|
_actives.stream()
|
||||||
@@ -1109,42 +1071,47 @@ public final class CharEffectList
|
|||||||
final Set<BuffInfo> unhideBuffs = new HashSet<>();
|
final Set<BuffInfo> unhideBuffs = new HashSet<>();
|
||||||
|
|
||||||
// Recalculate new flags
|
// Recalculate new flags
|
||||||
if (_actives != null)
|
for (BuffInfo info : _actives)
|
||||||
{
|
{
|
||||||
for (BuffInfo info : _actives)
|
if (info != null)
|
||||||
{
|
{
|
||||||
if (info != null)
|
final Skill skill = info.getSkill();
|
||||||
|
|
||||||
|
// Handle hidden buffs. Check if there was such abnormal before so we can continue.
|
||||||
|
if ((_hiddenBuffs.get() > 0) && _stackedEffects.contains(skill.getAbnormalType()))
|
||||||
{
|
{
|
||||||
final Skill skill = info.getSkill();
|
// If incoming buff isnt hidden, remove any hidden buffs with its abnormal type.
|
||||||
|
if (info.isInUse())
|
||||||
// Handle hidden buffs. Check if there was such abnormal before so we can continue.
|
|
||||||
if ((_hiddenBuffs.get() > 0) && _stackedEffects.contains(skill.getAbnormalType()))
|
|
||||||
{
|
{
|
||||||
// If incoming buff isnt hidden, remove any hidden buffs with its abnormal type.
|
unhideBuffs.removeIf(b -> b.isAbnormalType(skill.getAbnormalType()));
|
||||||
if (info.isInUse())
|
|
||||||
{
|
|
||||||
unhideBuffs.removeIf(b -> b.isAbnormalType(skill.getAbnormalType()));
|
|
||||||
}
|
|
||||||
// If this incoming buff is hidden and its first of its abnormal, or it removes any previous hidden buff with the same or lower abnormal level and add this instead.
|
|
||||||
else if (!abnormalTypeFlags.contains(skill.getAbnormalType()) || unhideBuffs.removeIf(b -> (b.isAbnormalType(skill.getAbnormalType())) && (b.getSkill().getAbnormalLvl() <= skill.getAbnormalLvl())))
|
|
||||||
{
|
|
||||||
unhideBuffs.add(info);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
// If this incoming buff is hidden and its first of its abnormal, or it removes any previous hidden buff with the same or lower abnormal level and add this instead.
|
||||||
// Add the EffectType flag.
|
else if (!abnormalTypeFlags.contains(skill.getAbnormalType()) || unhideBuffs.removeIf(b -> (b.isAbnormalType(skill.getAbnormalType())) && (b.getSkill().getAbnormalLvl() <= skill.getAbnormalLvl())))
|
||||||
for (AbstractEffect e : info.getEffects())
|
|
||||||
{
|
{
|
||||||
flags |= e.getEffectFlags();
|
unhideBuffs.add(info);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Add the AbnormalType flag.
|
// Add the EffectType flag.
|
||||||
abnormalTypeFlags.add(skill.getAbnormalType());
|
for (AbstractEffect e : info.getEffects())
|
||||||
|
{
|
||||||
|
flags |= e.getEffectFlags();
|
||||||
|
}
|
||||||
|
|
||||||
// Add AbnormalVisualEffect flag.
|
// Add the AbnormalType flag.
|
||||||
if (skill.hasAbnormalVisualEffects())
|
abnormalTypeFlags.add(skill.getAbnormalType());
|
||||||
|
|
||||||
|
// Add AbnormalVisualEffect flag.
|
||||||
|
if (skill.hasAbnormalVisualEffects())
|
||||||
|
{
|
||||||
|
for (AbnormalVisualEffect ave : skill.getAbnormalVisualEffects())
|
||||||
{
|
{
|
||||||
abnormalVisualEffectFlags.addAll(skill.getAbnormalVisualEffects());
|
abnormalVisualEffectFlags.add(ave);
|
||||||
|
_abnormalVisualEffects.add(ave);
|
||||||
|
}
|
||||||
|
if (broadcast)
|
||||||
|
{
|
||||||
|
_owner.updateAbnormalVisualEffects();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1167,7 +1134,7 @@ public final class CharEffectList
|
|||||||
if (broadcast)
|
if (broadcast)
|
||||||
{
|
{
|
||||||
// Check if there is change in AbnormalVisualEffect
|
// Check if there is change in AbnormalVisualEffect
|
||||||
if ((abnormalVisualEffectFlags.size() != _abnormalVisualEffects.size()) || !abnormalVisualEffectFlags.containsAll(_abnormalVisualEffects))
|
if (!abnormalVisualEffectFlags.containsAll(_abnormalVisualEffects))
|
||||||
{
|
{
|
||||||
_abnormalVisualEffects = abnormalVisualEffectFlags;
|
_abnormalVisualEffects = abnormalVisualEffectFlags;
|
||||||
_owner.updateAbnormalVisualEffects();
|
_owner.updateAbnormalVisualEffects();
|
||||||
|
|||||||
@@ -77,7 +77,6 @@ public class DoppelgangerInstance extends L2Npc
|
|||||||
info.setAbnormalTime(summonerInfo.getAbnormalTime());
|
info.setAbnormalTime(summonerInfo.getAbnormalTime());
|
||||||
getEffectList().add(info);
|
getEffectList().add(info);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -786,7 +786,7 @@ public class CharStat
|
|||||||
final CharEffectList effectList = _activeChar.getEffectList();
|
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> 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> 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
|
// Call pump to each effect
|
||||||
//@formatter:off
|
//@formatter:off
|
||||||
|
|||||||
@@ -389,10 +389,10 @@ public final class BuffInfo
|
|||||||
for (AbstractEffect effect : _effects)
|
for (AbstractEffect effect : _effects)
|
||||||
{
|
{
|
||||||
// Instant effects shouldn't call onExit(..).
|
// Instant effects shouldn't call onExit(..).
|
||||||
if (!effect.isInstant())
|
// if (!effect.isInstant())
|
||||||
{
|
// {
|
||||||
effect.onExit(_effector, _effected, _skill);
|
effect.onExit(_effector, _effected, _skill);
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set the proper system message.
|
// Set the proper system message.
|
||||||
|
|||||||
@@ -21,13 +21,11 @@ import java.util.List;
|
|||||||
|
|
||||||
import com.l2jmobius.commons.network.PacketWriter;
|
import com.l2jmobius.commons.network.PacketWriter;
|
||||||
import com.l2jmobius.gameserver.model.skills.BuffInfo;
|
import com.l2jmobius.gameserver.model.skills.BuffInfo;
|
||||||
import com.l2jmobius.gameserver.model.skills.Skill;
|
|
||||||
import com.l2jmobius.gameserver.network.OutgoingPackets;
|
import com.l2jmobius.gameserver.network.OutgoingPackets;
|
||||||
|
|
||||||
public class AbnormalStatusUpdate implements IClientOutgoingPacket
|
public class AbnormalStatusUpdate implements IClientOutgoingPacket
|
||||||
{
|
{
|
||||||
private final List<BuffInfo> _effects = new ArrayList<>();
|
private final List<BuffInfo> _effects = new ArrayList<>();
|
||||||
private final List<Skill> _effects2 = new ArrayList<>();
|
|
||||||
|
|
||||||
public void addSkill(BuffInfo info)
|
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
|
@Override
|
||||||
public boolean write(PacketWriter packet)
|
public boolean write(PacketWriter packet)
|
||||||
{
|
{
|
||||||
OutgoingPackets.ABNORMAL_STATUS_UPDATE.writeId(packet);
|
OutgoingPackets.ABNORMAL_STATUS_UPDATE.writeId(packet);
|
||||||
|
|
||||||
packet.writeH(_effects.size() + _effects2.size());
|
packet.writeH(_effects.size());
|
||||||
for (BuffInfo info : _effects)
|
for (BuffInfo info : _effects)
|
||||||
{
|
{
|
||||||
if ((info != null) && info.isInUse())
|
if ((info != null) && info.isInUse())
|
||||||
@@ -62,17 +52,6 @@ public class AbnormalStatusUpdate implements IClientOutgoingPacket
|
|||||||
writeOptionalD(packet, info.getSkill().isAura() ? -1 : info.getTime());
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,6 @@
|
|||||||
*/
|
*/
|
||||||
package com.l2jmobius.gameserver.network.serverpackets;
|
package com.l2jmobius.gameserver.network.serverpackets;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
@@ -24,41 +23,12 @@ import java.util.stream.Collectors;
|
|||||||
import com.l2jmobius.commons.network.PacketWriter;
|
import com.l2jmobius.commons.network.PacketWriter;
|
||||||
import com.l2jmobius.gameserver.model.actor.L2Character;
|
import com.l2jmobius.gameserver.model.actor.L2Character;
|
||||||
import com.l2jmobius.gameserver.model.skills.BuffInfo;
|
import com.l2jmobius.gameserver.model.skills.BuffInfo;
|
||||||
import com.l2jmobius.gameserver.model.skills.Skill;
|
|
||||||
import com.l2jmobius.gameserver.network.OutgoingPackets;
|
import com.l2jmobius.gameserver.network.OutgoingPackets;
|
||||||
|
|
||||||
public class ExAbnormalStatusUpdateFromTarget implements IClientOutgoingPacket
|
public class ExAbnormalStatusUpdateFromTarget implements IClientOutgoingPacket
|
||||||
{
|
{
|
||||||
private final L2Character _character;
|
private final L2Character _character;
|
||||||
private List<Effect> _effects = new ArrayList<>();
|
private final List<BuffInfo> _effects;
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public ExAbnormalStatusUpdateFromTarget(L2Character character)
|
public ExAbnormalStatusUpdateFromTarget(L2Character character)
|
||||||
{
|
{
|
||||||
@@ -69,7 +39,6 @@ public class ExAbnormalStatusUpdateFromTarget implements IClientOutgoingPacket
|
|||||||
.filter(Objects::nonNull)
|
.filter(Objects::nonNull)
|
||||||
.filter(BuffInfo::isInUse)
|
.filter(BuffInfo::isInUse)
|
||||||
.filter(b -> !b.getSkill().isToggle())
|
.filter(b -> !b.getSkill().isToggle())
|
||||||
.map(Effect::new)
|
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
//@formatter:on
|
//@formatter:on
|
||||||
}
|
}
|
||||||
@@ -82,14 +51,14 @@ public class ExAbnormalStatusUpdateFromTarget implements IClientOutgoingPacket
|
|||||||
packet.writeD(_character.getObjectId());
|
packet.writeD(_character.getObjectId());
|
||||||
packet.writeH(_effects.size());
|
packet.writeH(_effects.size());
|
||||||
|
|
||||||
for (Effect info : _effects)
|
for (BuffInfo info : _effects)
|
||||||
{
|
{
|
||||||
packet.writeD(info._skillId);
|
packet.writeD(info.getSkill().getDisplayId());
|
||||||
packet.writeH(info._level);
|
packet.writeH(info.getSkill().getDisplayLevel());
|
||||||
packet.writeH(info._subLevel);
|
packet.writeH(info.getSkill().getSubLevel());
|
||||||
packet.writeH(info._abnormalType);
|
packet.writeH(info.getSkill().getAbnormalType().getClientId());
|
||||||
writeOptionalD(packet, info._duration);
|
writeOptionalD(packet, info.getSkill().isAura() ? -1 : info.getTime());
|
||||||
packet.writeD(info._caster);
|
packet.writeD(info.getEffectorObjectId());
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,6 +16,8 @@
|
|||||||
*/
|
*/
|
||||||
package handlers.effecthandlers;
|
package handlers.effecthandlers;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
|
||||||
import com.l2jmobius.gameserver.model.L2Object;
|
import com.l2jmobius.gameserver.model.L2Object;
|
||||||
import com.l2jmobius.gameserver.model.L2World;
|
import com.l2jmobius.gameserver.model.L2World;
|
||||||
import com.l2jmobius.gameserver.model.StatsSet;
|
import com.l2jmobius.gameserver.model.StatsSet;
|
||||||
@@ -38,6 +40,19 @@ public final class CallSkillOnActionTime extends AbstractEffect
|
|||||||
setTicks(params.getInt("ticks"));
|
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
|
@Override
|
||||||
public boolean onActionTime(L2Character effector, L2Character effected, Skill skill)
|
public boolean onActionTime(L2Character effector, L2Character effected, Skill skill)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -136,6 +136,5 @@ public final class Disarmor extends AbstractEffect
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
super.onExit(effector, effected, skill);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -84,6 +84,5 @@ public final class DoubleCast extends AbstractEffect
|
|||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
super.onExit(effector, effected, skill);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -65,15 +65,15 @@ public final class CharEffectList
|
|||||||
{
|
{
|
||||||
private static final Logger LOGGER = Logger.getLogger(CharEffectList.class.getName());
|
private static final Logger LOGGER = Logger.getLogger(CharEffectList.class.getName());
|
||||||
/** Queue containing all effects from buffs for this effect list. */
|
/** 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. */
|
/** 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. */
|
/** 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}. */
|
/** Map containing the all stacked effect in progress for each {@code AbnormalType}. */
|
||||||
private volatile Set<AbnormalType> _stackedEffects = EnumSet.noneOf(AbnormalType.class);
|
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. */
|
/** 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. */
|
/** Set containing all abnormal visual effects this creature currently displays. */
|
||||||
private volatile Set<AbnormalVisualEffect> _abnormalVisualEffects = EnumSet.noneOf(AbnormalVisualEffect.class);
|
private volatile Set<AbnormalVisualEffect> _abnormalVisualEffects = EnumSet.noneOf(AbnormalVisualEffect.class);
|
||||||
/** Short buff skill ID. */
|
/** Short buff skill ID. */
|
||||||
@@ -110,7 +110,7 @@ public final class CharEffectList
|
|||||||
*/
|
*/
|
||||||
public Set<BuffInfo> getPassives()
|
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()
|
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()
|
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()
|
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()
|
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)
|
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)
|
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)
|
public void addBlockedAbnormalTypes(Set<AbnormalType> blockedAbnormalTypes)
|
||||||
{
|
{
|
||||||
// Initialize
|
|
||||||
if (_blockedAbnormalTypes == null)
|
|
||||||
{
|
|
||||||
synchronized (this)
|
|
||||||
{
|
|
||||||
if (_blockedAbnormalTypes == null)
|
|
||||||
{
|
|
||||||
_blockedAbnormalTypes = EnumSet.copyOf(blockedAbnormalTypes);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_blockedAbnormalTypes.addAll(blockedAbnormalTypes);
|
_blockedAbnormalTypes.addAll(blockedAbnormalTypes);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -238,7 +226,7 @@ public final class CharEffectList
|
|||||||
*/
|
*/
|
||||||
public boolean removeBlockedAbnormalTypes(Set<AbnormalType> blockedBuffSlots)
|
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()
|
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()
|
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)
|
public void stopAllPassives(boolean update, boolean broadcast)
|
||||||
{
|
{
|
||||||
if (_passives != null)
|
if (!_passives.isEmpty())
|
||||||
{
|
{
|
||||||
_passives.forEach(this::remove);
|
_passives.forEach(this::remove);
|
||||||
// Update stats, effect flags and icons.
|
// Update stats, effect flags and icons.
|
||||||
@@ -392,7 +380,7 @@ public final class CharEffectList
|
|||||||
*/
|
*/
|
||||||
public void stopAllOptions(boolean update, boolean broadcast)
|
public void stopAllOptions(boolean update, boolean broadcast)
|
||||||
{
|
{
|
||||||
if (_options != null)
|
if (!_options.isEmpty())
|
||||||
{
|
{
|
||||||
_options.forEach(this::remove);
|
_options.forEach(this::remove);
|
||||||
// Update stats, effect flags and icons.
|
// Update stats, effect flags and icons.
|
||||||
@@ -490,7 +478,7 @@ public final class CharEffectList
|
|||||||
*/
|
*/
|
||||||
public void stopEffects(Predicate<BuffInfo> filter, boolean update, boolean broadcast)
|
public void stopEffects(Predicate<BuffInfo> filter, boolean update, boolean broadcast)
|
||||||
{
|
{
|
||||||
if (_actives != null)
|
if (!_actives.isEmpty())
|
||||||
{
|
{
|
||||||
_actives.stream().filter(filter).forEach(this::remove);
|
_actives.stream().filter(filter).forEach(this::remove);
|
||||||
|
|
||||||
@@ -678,6 +666,10 @@ public final class CharEffectList
|
|||||||
{
|
{
|
||||||
// Remove active effect.
|
// Remove active effect.
|
||||||
removeActive(info, removed);
|
removeActive(info, removed);
|
||||||
|
if (_owner.isNpc()) // Fix for all NPC debuff animations removed.
|
||||||
|
{
|
||||||
|
updateEffectList(broadcast);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update stats, effect flags and icons.
|
// Update stats, effect flags and icons.
|
||||||
@@ -693,7 +685,7 @@ public final class CharEffectList
|
|||||||
*/
|
*/
|
||||||
private synchronized void removeActive(BuffInfo info, boolean removed)
|
private synchronized void removeActive(BuffInfo info, boolean removed)
|
||||||
{
|
{
|
||||||
if (_actives != null)
|
if (!_actives.isEmpty())
|
||||||
{
|
{
|
||||||
// Removes the buff from the given effect list.
|
// Removes the buff from the given effect list.
|
||||||
_actives.remove(info);
|
_actives.remove(info);
|
||||||
@@ -716,7 +708,7 @@ public final class CharEffectList
|
|||||||
|
|
||||||
private void removePassive(BuffInfo info, boolean removed)
|
private void removePassive(BuffInfo info, boolean removed)
|
||||||
{
|
{
|
||||||
if (_passives != null)
|
if (!_passives.isEmpty())
|
||||||
{
|
{
|
||||||
_passives.remove(info);
|
_passives.remove(info);
|
||||||
info.stopAllEffects(removed);
|
info.stopAllEffects(removed);
|
||||||
@@ -725,7 +717,7 @@ public final class CharEffectList
|
|||||||
|
|
||||||
private void removeOption(BuffInfo info, boolean removed)
|
private void removeOption(BuffInfo info, boolean removed)
|
||||||
{
|
{
|
||||||
if (_options != null)
|
if (!_options.isEmpty())
|
||||||
{
|
{
|
||||||
_options.remove(info);
|
_options.remove(info);
|
||||||
info.stopAllEffects(removed);
|
info.stopAllEffects(removed);
|
||||||
@@ -821,12 +813,6 @@ public final class CharEffectList
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize
|
|
||||||
if (_actives == null)
|
|
||||||
{
|
|
||||||
_actives = new ConcurrentLinkedQueue<>();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Manage effect stacking.
|
// Manage effect stacking.
|
||||||
if (hasAbnormalType(skill.getAbnormalType()))
|
if (hasAbnormalType(skill.getAbnormalType()))
|
||||||
{
|
{
|
||||||
@@ -857,7 +843,7 @@ public final class CharEffectList
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Remove effect that gets overriden.
|
// Remove effect that gets overridden.
|
||||||
remove(existingInfo);
|
remove(existingInfo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -865,7 +851,7 @@ public final class CharEffectList
|
|||||||
{
|
{
|
||||||
info.setInUse(false);
|
info.setInUse(false);
|
||||||
}
|
}
|
||||||
else // The effect we try to add should be overriden.
|
else // The effect we try to add should be overridden.
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -918,18 +904,6 @@ public final class CharEffectList
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize
|
|
||||||
if (_passives == null)
|
|
||||||
{
|
|
||||||
synchronized (this)
|
|
||||||
{
|
|
||||||
if (_passives == null)
|
|
||||||
{
|
|
||||||
_passives = ConcurrentHashMap.newKeySet();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove previous passives of this id.
|
// Remove previous passives of this id.
|
||||||
_passives.stream().filter(Objects::nonNull).filter(b -> b.getSkill().getId() == skill.getId()).forEach(b ->
|
_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)
|
if (info.getOption() != null)
|
||||||
{
|
{
|
||||||
// Initialize
|
|
||||||
if (_options == null)
|
|
||||||
{
|
|
||||||
synchronized (this)
|
|
||||||
{
|
|
||||||
if (_options == null)
|
|
||||||
{
|
|
||||||
_options = ConcurrentHashMap.newKeySet();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove previous options of this id.
|
// Remove previous options of this id.
|
||||||
_options.stream().filter(Objects::nonNull).filter(b -> b.getOption().getId() == info.getOption().getId()).forEach(b ->
|
_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<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();
|
final Optional<ExOlympiadSpelledInfo> os = (player.isInOlympiadMode() && player.isOlympiadStart()) ? Optional.of(new ExOlympiadSpelledInfo(player)) : Optional.empty();
|
||||||
|
|
||||||
if (_actives != null)
|
if (!_actives.isEmpty())
|
||||||
{
|
{
|
||||||
//@formatter:off
|
//@formatter:off
|
||||||
_actives.stream()
|
_actives.stream()
|
||||||
@@ -1109,42 +1071,47 @@ public final class CharEffectList
|
|||||||
final Set<BuffInfo> unhideBuffs = new HashSet<>();
|
final Set<BuffInfo> unhideBuffs = new HashSet<>();
|
||||||
|
|
||||||
// Recalculate new flags
|
// Recalculate new flags
|
||||||
if (_actives != null)
|
for (BuffInfo info : _actives)
|
||||||
{
|
{
|
||||||
for (BuffInfo info : _actives)
|
if (info != null)
|
||||||
{
|
{
|
||||||
if (info != null)
|
final Skill skill = info.getSkill();
|
||||||
|
|
||||||
|
// Handle hidden buffs. Check if there was such abnormal before so we can continue.
|
||||||
|
if ((_hiddenBuffs.get() > 0) && _stackedEffects.contains(skill.getAbnormalType()))
|
||||||
{
|
{
|
||||||
final Skill skill = info.getSkill();
|
// If incoming buff isnt hidden, remove any hidden buffs with its abnormal type.
|
||||||
|
if (info.isInUse())
|
||||||
// Handle hidden buffs. Check if there was such abnormal before so we can continue.
|
|
||||||
if ((_hiddenBuffs.get() > 0) && _stackedEffects.contains(skill.getAbnormalType()))
|
|
||||||
{
|
{
|
||||||
// If incoming buff isnt hidden, remove any hidden buffs with its abnormal type.
|
unhideBuffs.removeIf(b -> b.isAbnormalType(skill.getAbnormalType()));
|
||||||
if (info.isInUse())
|
|
||||||
{
|
|
||||||
unhideBuffs.removeIf(b -> b.isAbnormalType(skill.getAbnormalType()));
|
|
||||||
}
|
|
||||||
// If this incoming buff is hidden and its first of its abnormal, or it removes any previous hidden buff with the same or lower abnormal level and add this instead.
|
|
||||||
else if (!abnormalTypeFlags.contains(skill.getAbnormalType()) || unhideBuffs.removeIf(b -> (b.isAbnormalType(skill.getAbnormalType())) && (b.getSkill().getAbnormalLvl() <= skill.getAbnormalLvl())))
|
|
||||||
{
|
|
||||||
unhideBuffs.add(info);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
// If this incoming buff is hidden and its first of its abnormal, or it removes any previous hidden buff with the same or lower abnormal level and add this instead.
|
||||||
// Add the EffectType flag.
|
else if (!abnormalTypeFlags.contains(skill.getAbnormalType()) || unhideBuffs.removeIf(b -> (b.isAbnormalType(skill.getAbnormalType())) && (b.getSkill().getAbnormalLvl() <= skill.getAbnormalLvl())))
|
||||||
for (AbstractEffect e : info.getEffects())
|
|
||||||
{
|
{
|
||||||
flags |= e.getEffectFlags();
|
unhideBuffs.add(info);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Add the AbnormalType flag.
|
// Add the EffectType flag.
|
||||||
abnormalTypeFlags.add(skill.getAbnormalType());
|
for (AbstractEffect e : info.getEffects())
|
||||||
|
{
|
||||||
|
flags |= e.getEffectFlags();
|
||||||
|
}
|
||||||
|
|
||||||
// Add AbnormalVisualEffect flag.
|
// Add the AbnormalType flag.
|
||||||
if (skill.hasAbnormalVisualEffects())
|
abnormalTypeFlags.add(skill.getAbnormalType());
|
||||||
|
|
||||||
|
// Add AbnormalVisualEffect flag.
|
||||||
|
if (skill.hasAbnormalVisualEffects())
|
||||||
|
{
|
||||||
|
for (AbnormalVisualEffect ave : skill.getAbnormalVisualEffects())
|
||||||
{
|
{
|
||||||
abnormalVisualEffectFlags.addAll(skill.getAbnormalVisualEffects());
|
abnormalVisualEffectFlags.add(ave);
|
||||||
|
_abnormalVisualEffects.add(ave);
|
||||||
|
}
|
||||||
|
if (broadcast)
|
||||||
|
{
|
||||||
|
_owner.updateAbnormalVisualEffects();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1167,7 +1134,7 @@ public final class CharEffectList
|
|||||||
if (broadcast)
|
if (broadcast)
|
||||||
{
|
{
|
||||||
// Check if there is change in AbnormalVisualEffect
|
// Check if there is change in AbnormalVisualEffect
|
||||||
if ((abnormalVisualEffectFlags.size() != _abnormalVisualEffects.size()) || !abnormalVisualEffectFlags.containsAll(_abnormalVisualEffects))
|
if (!abnormalVisualEffectFlags.containsAll(_abnormalVisualEffects))
|
||||||
{
|
{
|
||||||
_abnormalVisualEffects = abnormalVisualEffectFlags;
|
_abnormalVisualEffects = abnormalVisualEffectFlags;
|
||||||
_owner.updateAbnormalVisualEffects();
|
_owner.updateAbnormalVisualEffects();
|
||||||
|
|||||||
@@ -77,7 +77,6 @@ public class DoppelgangerInstance extends L2Npc
|
|||||||
info.setAbnormalTime(summonerInfo.getAbnormalTime());
|
info.setAbnormalTime(summonerInfo.getAbnormalTime());
|
||||||
getEffectList().add(info);
|
getEffectList().add(info);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -786,7 +786,7 @@ public class CharStat
|
|||||||
final CharEffectList effectList = _activeChar.getEffectList();
|
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> 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> 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
|
// Call pump to each effect
|
||||||
//@formatter:off
|
//@formatter:off
|
||||||
|
|||||||
@@ -389,10 +389,10 @@ public final class BuffInfo
|
|||||||
for (AbstractEffect effect : _effects)
|
for (AbstractEffect effect : _effects)
|
||||||
{
|
{
|
||||||
// Instant effects shouldn't call onExit(..).
|
// Instant effects shouldn't call onExit(..).
|
||||||
if (!effect.isInstant())
|
// if (!effect.isInstant())
|
||||||
{
|
// {
|
||||||
effect.onExit(_effector, _effected, _skill);
|
effect.onExit(_effector, _effected, _skill);
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set the proper system message.
|
// Set the proper system message.
|
||||||
|
|||||||
@@ -21,13 +21,11 @@ import java.util.List;
|
|||||||
|
|
||||||
import com.l2jmobius.commons.network.PacketWriter;
|
import com.l2jmobius.commons.network.PacketWriter;
|
||||||
import com.l2jmobius.gameserver.model.skills.BuffInfo;
|
import com.l2jmobius.gameserver.model.skills.BuffInfo;
|
||||||
import com.l2jmobius.gameserver.model.skills.Skill;
|
|
||||||
import com.l2jmobius.gameserver.network.OutgoingPackets;
|
import com.l2jmobius.gameserver.network.OutgoingPackets;
|
||||||
|
|
||||||
public class AbnormalStatusUpdate implements IClientOutgoingPacket
|
public class AbnormalStatusUpdate implements IClientOutgoingPacket
|
||||||
{
|
{
|
||||||
private final List<BuffInfo> _effects = new ArrayList<>();
|
private final List<BuffInfo> _effects = new ArrayList<>();
|
||||||
private final List<Skill> _effects2 = new ArrayList<>();
|
|
||||||
|
|
||||||
public void addSkill(BuffInfo info)
|
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
|
@Override
|
||||||
public boolean write(PacketWriter packet)
|
public boolean write(PacketWriter packet)
|
||||||
{
|
{
|
||||||
OutgoingPackets.ABNORMAL_STATUS_UPDATE.writeId(packet);
|
OutgoingPackets.ABNORMAL_STATUS_UPDATE.writeId(packet);
|
||||||
|
|
||||||
packet.writeH(_effects.size() + _effects2.size());
|
packet.writeH(_effects.size());
|
||||||
for (BuffInfo info : _effects)
|
for (BuffInfo info : _effects)
|
||||||
{
|
{
|
||||||
if ((info != null) && info.isInUse())
|
if ((info != null) && info.isInUse())
|
||||||
@@ -62,17 +52,6 @@ public class AbnormalStatusUpdate implements IClientOutgoingPacket
|
|||||||
writeOptionalD(packet, info.getSkill().isAura() ? -1 : info.getTime());
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,6 @@
|
|||||||
*/
|
*/
|
||||||
package com.l2jmobius.gameserver.network.serverpackets;
|
package com.l2jmobius.gameserver.network.serverpackets;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
@@ -24,41 +23,12 @@ import java.util.stream.Collectors;
|
|||||||
import com.l2jmobius.commons.network.PacketWriter;
|
import com.l2jmobius.commons.network.PacketWriter;
|
||||||
import com.l2jmobius.gameserver.model.actor.L2Character;
|
import com.l2jmobius.gameserver.model.actor.L2Character;
|
||||||
import com.l2jmobius.gameserver.model.skills.BuffInfo;
|
import com.l2jmobius.gameserver.model.skills.BuffInfo;
|
||||||
import com.l2jmobius.gameserver.model.skills.Skill;
|
|
||||||
import com.l2jmobius.gameserver.network.OutgoingPackets;
|
import com.l2jmobius.gameserver.network.OutgoingPackets;
|
||||||
|
|
||||||
public class ExAbnormalStatusUpdateFromTarget implements IClientOutgoingPacket
|
public class ExAbnormalStatusUpdateFromTarget implements IClientOutgoingPacket
|
||||||
{
|
{
|
||||||
private final L2Character _character;
|
private final L2Character _character;
|
||||||
private List<Effect> _effects = new ArrayList<>();
|
private final List<BuffInfo> _effects;
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public ExAbnormalStatusUpdateFromTarget(L2Character character)
|
public ExAbnormalStatusUpdateFromTarget(L2Character character)
|
||||||
{
|
{
|
||||||
@@ -69,7 +39,6 @@ public class ExAbnormalStatusUpdateFromTarget implements IClientOutgoingPacket
|
|||||||
.filter(Objects::nonNull)
|
.filter(Objects::nonNull)
|
||||||
.filter(BuffInfo::isInUse)
|
.filter(BuffInfo::isInUse)
|
||||||
.filter(b -> !b.getSkill().isToggle())
|
.filter(b -> !b.getSkill().isToggle())
|
||||||
.map(Effect::new)
|
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
//@formatter:on
|
//@formatter:on
|
||||||
}
|
}
|
||||||
@@ -82,14 +51,14 @@ public class ExAbnormalStatusUpdateFromTarget implements IClientOutgoingPacket
|
|||||||
packet.writeD(_character.getObjectId());
|
packet.writeD(_character.getObjectId());
|
||||||
packet.writeH(_effects.size());
|
packet.writeH(_effects.size());
|
||||||
|
|
||||||
for (Effect info : _effects)
|
for (BuffInfo info : _effects)
|
||||||
{
|
{
|
||||||
packet.writeD(info._skillId);
|
packet.writeD(info.getSkill().getDisplayId());
|
||||||
packet.writeH(info._level);
|
packet.writeH(info.getSkill().getDisplayLevel());
|
||||||
packet.writeH(info._subLevel);
|
packet.writeH(info.getSkill().getSubLevel());
|
||||||
packet.writeH(info._abnormalType);
|
packet.writeH(info.getSkill().getAbnormalType().getClientId());
|
||||||
writeOptionalD(packet, info._duration);
|
writeOptionalD(packet, info.getSkill().isAura() ? -1 : info.getTime());
|
||||||
packet.writeD(info._caster);
|
packet.writeD(info.getEffectorObjectId());
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,6 +16,8 @@
|
|||||||
*/
|
*/
|
||||||
package handlers.effecthandlers;
|
package handlers.effecthandlers;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
|
||||||
import com.l2jmobius.gameserver.model.L2Object;
|
import com.l2jmobius.gameserver.model.L2Object;
|
||||||
import com.l2jmobius.gameserver.model.L2World;
|
import com.l2jmobius.gameserver.model.L2World;
|
||||||
import com.l2jmobius.gameserver.model.StatsSet;
|
import com.l2jmobius.gameserver.model.StatsSet;
|
||||||
@@ -38,6 +40,19 @@ public final class CallSkillOnActionTime extends AbstractEffect
|
|||||||
setTicks(params.getInt("ticks"));
|
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
|
@Override
|
||||||
public boolean onActionTime(L2Character effector, L2Character effected, Skill skill)
|
public boolean onActionTime(L2Character effector, L2Character effected, Skill skill)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -136,6 +136,5 @@ public final class Disarmor extends AbstractEffect
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
super.onExit(effector, effected, skill);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -84,6 +84,5 @@ public final class DoubleCast extends AbstractEffect
|
|||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
super.onExit(effector, effected, skill);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -65,15 +65,15 @@ public final class CharEffectList
|
|||||||
{
|
{
|
||||||
private static final Logger LOGGER = Logger.getLogger(CharEffectList.class.getName());
|
private static final Logger LOGGER = Logger.getLogger(CharEffectList.class.getName());
|
||||||
/** Queue containing all effects from buffs for this effect list. */
|
/** 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. */
|
/** 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. */
|
/** 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}. */
|
/** Map containing the all stacked effect in progress for each {@code AbnormalType}. */
|
||||||
private volatile Set<AbnormalType> _stackedEffects = EnumSet.noneOf(AbnormalType.class);
|
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. */
|
/** 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. */
|
/** Set containing all abnormal visual effects this creature currently displays. */
|
||||||
private volatile Set<AbnormalVisualEffect> _abnormalVisualEffects = EnumSet.noneOf(AbnormalVisualEffect.class);
|
private volatile Set<AbnormalVisualEffect> _abnormalVisualEffects = EnumSet.noneOf(AbnormalVisualEffect.class);
|
||||||
/** Short buff skill ID. */
|
/** Short buff skill ID. */
|
||||||
@@ -110,7 +110,7 @@ public final class CharEffectList
|
|||||||
*/
|
*/
|
||||||
public Set<BuffInfo> getPassives()
|
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()
|
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()
|
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()
|
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()
|
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)
|
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)
|
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)
|
public void addBlockedAbnormalTypes(Set<AbnormalType> blockedAbnormalTypes)
|
||||||
{
|
{
|
||||||
// Initialize
|
|
||||||
if (_blockedAbnormalTypes == null)
|
|
||||||
{
|
|
||||||
synchronized (this)
|
|
||||||
{
|
|
||||||
if (_blockedAbnormalTypes == null)
|
|
||||||
{
|
|
||||||
_blockedAbnormalTypes = EnumSet.copyOf(blockedAbnormalTypes);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_blockedAbnormalTypes.addAll(blockedAbnormalTypes);
|
_blockedAbnormalTypes.addAll(blockedAbnormalTypes);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -238,7 +226,7 @@ public final class CharEffectList
|
|||||||
*/
|
*/
|
||||||
public boolean removeBlockedAbnormalTypes(Set<AbnormalType> blockedBuffSlots)
|
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()
|
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()
|
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)
|
public void stopAllPassives(boolean update, boolean broadcast)
|
||||||
{
|
{
|
||||||
if (_passives != null)
|
if (!_passives.isEmpty())
|
||||||
{
|
{
|
||||||
_passives.forEach(this::remove);
|
_passives.forEach(this::remove);
|
||||||
// Update stats, effect flags and icons.
|
// Update stats, effect flags and icons.
|
||||||
@@ -392,7 +380,7 @@ public final class CharEffectList
|
|||||||
*/
|
*/
|
||||||
public void stopAllOptions(boolean update, boolean broadcast)
|
public void stopAllOptions(boolean update, boolean broadcast)
|
||||||
{
|
{
|
||||||
if (_options != null)
|
if (!_options.isEmpty())
|
||||||
{
|
{
|
||||||
_options.forEach(this::remove);
|
_options.forEach(this::remove);
|
||||||
// Update stats, effect flags and icons.
|
// Update stats, effect flags and icons.
|
||||||
@@ -490,7 +478,7 @@ public final class CharEffectList
|
|||||||
*/
|
*/
|
||||||
public void stopEffects(Predicate<BuffInfo> filter, boolean update, boolean broadcast)
|
public void stopEffects(Predicate<BuffInfo> filter, boolean update, boolean broadcast)
|
||||||
{
|
{
|
||||||
if (_actives != null)
|
if (!_actives.isEmpty())
|
||||||
{
|
{
|
||||||
_actives.stream().filter(filter).forEach(this::remove);
|
_actives.stream().filter(filter).forEach(this::remove);
|
||||||
|
|
||||||
@@ -678,6 +666,10 @@ public final class CharEffectList
|
|||||||
{
|
{
|
||||||
// Remove active effect.
|
// Remove active effect.
|
||||||
removeActive(info, removed);
|
removeActive(info, removed);
|
||||||
|
if (_owner.isNpc()) // Fix for all NPC debuff animations removed.
|
||||||
|
{
|
||||||
|
updateEffectList(broadcast);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update stats, effect flags and icons.
|
// Update stats, effect flags and icons.
|
||||||
@@ -693,7 +685,7 @@ public final class CharEffectList
|
|||||||
*/
|
*/
|
||||||
private synchronized void removeActive(BuffInfo info, boolean removed)
|
private synchronized void removeActive(BuffInfo info, boolean removed)
|
||||||
{
|
{
|
||||||
if (_actives != null)
|
if (!_actives.isEmpty())
|
||||||
{
|
{
|
||||||
// Removes the buff from the given effect list.
|
// Removes the buff from the given effect list.
|
||||||
_actives.remove(info);
|
_actives.remove(info);
|
||||||
@@ -716,7 +708,7 @@ public final class CharEffectList
|
|||||||
|
|
||||||
private void removePassive(BuffInfo info, boolean removed)
|
private void removePassive(BuffInfo info, boolean removed)
|
||||||
{
|
{
|
||||||
if (_passives != null)
|
if (!_passives.isEmpty())
|
||||||
{
|
{
|
||||||
_passives.remove(info);
|
_passives.remove(info);
|
||||||
info.stopAllEffects(removed);
|
info.stopAllEffects(removed);
|
||||||
@@ -725,7 +717,7 @@ public final class CharEffectList
|
|||||||
|
|
||||||
private void removeOption(BuffInfo info, boolean removed)
|
private void removeOption(BuffInfo info, boolean removed)
|
||||||
{
|
{
|
||||||
if (_options != null)
|
if (!_options.isEmpty())
|
||||||
{
|
{
|
||||||
_options.remove(info);
|
_options.remove(info);
|
||||||
info.stopAllEffects(removed);
|
info.stopAllEffects(removed);
|
||||||
@@ -821,12 +813,6 @@ public final class CharEffectList
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize
|
|
||||||
if (_actives == null)
|
|
||||||
{
|
|
||||||
_actives = new ConcurrentLinkedQueue<>();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Manage effect stacking.
|
// Manage effect stacking.
|
||||||
if (hasAbnormalType(skill.getAbnormalType()))
|
if (hasAbnormalType(skill.getAbnormalType()))
|
||||||
{
|
{
|
||||||
@@ -857,7 +843,7 @@ public final class CharEffectList
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Remove effect that gets overriden.
|
// Remove effect that gets overridden.
|
||||||
remove(existingInfo);
|
remove(existingInfo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -865,7 +851,7 @@ public final class CharEffectList
|
|||||||
{
|
{
|
||||||
info.setInUse(false);
|
info.setInUse(false);
|
||||||
}
|
}
|
||||||
else // The effect we try to add should be overriden.
|
else // The effect we try to add should be overridden.
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -918,18 +904,6 @@ public final class CharEffectList
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize
|
|
||||||
if (_passives == null)
|
|
||||||
{
|
|
||||||
synchronized (this)
|
|
||||||
{
|
|
||||||
if (_passives == null)
|
|
||||||
{
|
|
||||||
_passives = ConcurrentHashMap.newKeySet();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove previous passives of this id.
|
// Remove previous passives of this id.
|
||||||
_passives.stream().filter(Objects::nonNull).filter(b -> b.getSkill().getId() == skill.getId()).forEach(b ->
|
_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)
|
if (info.getOption() != null)
|
||||||
{
|
{
|
||||||
// Initialize
|
|
||||||
if (_options == null)
|
|
||||||
{
|
|
||||||
synchronized (this)
|
|
||||||
{
|
|
||||||
if (_options == null)
|
|
||||||
{
|
|
||||||
_options = ConcurrentHashMap.newKeySet();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove previous options of this id.
|
// Remove previous options of this id.
|
||||||
_options.stream().filter(Objects::nonNull).filter(b -> b.getOption().getId() == info.getOption().getId()).forEach(b ->
|
_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<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();
|
final Optional<ExOlympiadSpelledInfo> os = (player.isInOlympiadMode() && player.isOlympiadStart()) ? Optional.of(new ExOlympiadSpelledInfo(player)) : Optional.empty();
|
||||||
|
|
||||||
if (_actives != null)
|
if (!_actives.isEmpty())
|
||||||
{
|
{
|
||||||
//@formatter:off
|
//@formatter:off
|
||||||
_actives.stream()
|
_actives.stream()
|
||||||
@@ -1109,42 +1071,47 @@ public final class CharEffectList
|
|||||||
final Set<BuffInfo> unhideBuffs = new HashSet<>();
|
final Set<BuffInfo> unhideBuffs = new HashSet<>();
|
||||||
|
|
||||||
// Recalculate new flags
|
// Recalculate new flags
|
||||||
if (_actives != null)
|
for (BuffInfo info : _actives)
|
||||||
{
|
{
|
||||||
for (BuffInfo info : _actives)
|
if (info != null)
|
||||||
{
|
{
|
||||||
if (info != null)
|
final Skill skill = info.getSkill();
|
||||||
|
|
||||||
|
// Handle hidden buffs. Check if there was such abnormal before so we can continue.
|
||||||
|
if ((_hiddenBuffs.get() > 0) && _stackedEffects.contains(skill.getAbnormalType()))
|
||||||
{
|
{
|
||||||
final Skill skill = info.getSkill();
|
// If incoming buff isnt hidden, remove any hidden buffs with its abnormal type.
|
||||||
|
if (info.isInUse())
|
||||||
// Handle hidden buffs. Check if there was such abnormal before so we can continue.
|
|
||||||
if ((_hiddenBuffs.get() > 0) && _stackedEffects.contains(skill.getAbnormalType()))
|
|
||||||
{
|
{
|
||||||
// If incoming buff isnt hidden, remove any hidden buffs with its abnormal type.
|
unhideBuffs.removeIf(b -> b.isAbnormalType(skill.getAbnormalType()));
|
||||||
if (info.isInUse())
|
|
||||||
{
|
|
||||||
unhideBuffs.removeIf(b -> b.isAbnormalType(skill.getAbnormalType()));
|
|
||||||
}
|
|
||||||
// If this incoming buff is hidden and its first of its abnormal, or it removes any previous hidden buff with the same or lower abnormal level and add this instead.
|
|
||||||
else if (!abnormalTypeFlags.contains(skill.getAbnormalType()) || unhideBuffs.removeIf(b -> (b.isAbnormalType(skill.getAbnormalType())) && (b.getSkill().getAbnormalLvl() <= skill.getAbnormalLvl())))
|
|
||||||
{
|
|
||||||
unhideBuffs.add(info);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
// If this incoming buff is hidden and its first of its abnormal, or it removes any previous hidden buff with the same or lower abnormal level and add this instead.
|
||||||
// Add the EffectType flag.
|
else if (!abnormalTypeFlags.contains(skill.getAbnormalType()) || unhideBuffs.removeIf(b -> (b.isAbnormalType(skill.getAbnormalType())) && (b.getSkill().getAbnormalLvl() <= skill.getAbnormalLvl())))
|
||||||
for (AbstractEffect e : info.getEffects())
|
|
||||||
{
|
{
|
||||||
flags |= e.getEffectFlags();
|
unhideBuffs.add(info);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Add the AbnormalType flag.
|
// Add the EffectType flag.
|
||||||
abnormalTypeFlags.add(skill.getAbnormalType());
|
for (AbstractEffect e : info.getEffects())
|
||||||
|
{
|
||||||
|
flags |= e.getEffectFlags();
|
||||||
|
}
|
||||||
|
|
||||||
// Add AbnormalVisualEffect flag.
|
// Add the AbnormalType flag.
|
||||||
if (skill.hasAbnormalVisualEffects())
|
abnormalTypeFlags.add(skill.getAbnormalType());
|
||||||
|
|
||||||
|
// Add AbnormalVisualEffect flag.
|
||||||
|
if (skill.hasAbnormalVisualEffects())
|
||||||
|
{
|
||||||
|
for (AbnormalVisualEffect ave : skill.getAbnormalVisualEffects())
|
||||||
{
|
{
|
||||||
abnormalVisualEffectFlags.addAll(skill.getAbnormalVisualEffects());
|
abnormalVisualEffectFlags.add(ave);
|
||||||
|
_abnormalVisualEffects.add(ave);
|
||||||
|
}
|
||||||
|
if (broadcast)
|
||||||
|
{
|
||||||
|
_owner.updateAbnormalVisualEffects();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1167,7 +1134,7 @@ public final class CharEffectList
|
|||||||
if (broadcast)
|
if (broadcast)
|
||||||
{
|
{
|
||||||
// Check if there is change in AbnormalVisualEffect
|
// Check if there is change in AbnormalVisualEffect
|
||||||
if ((abnormalVisualEffectFlags.size() != _abnormalVisualEffects.size()) || !abnormalVisualEffectFlags.containsAll(_abnormalVisualEffects))
|
if (!abnormalVisualEffectFlags.containsAll(_abnormalVisualEffects))
|
||||||
{
|
{
|
||||||
_abnormalVisualEffects = abnormalVisualEffectFlags;
|
_abnormalVisualEffects = abnormalVisualEffectFlags;
|
||||||
_owner.updateAbnormalVisualEffects();
|
_owner.updateAbnormalVisualEffects();
|
||||||
|
|||||||
@@ -77,7 +77,6 @@ public class DoppelgangerInstance extends L2Npc
|
|||||||
info.setAbnormalTime(summonerInfo.getAbnormalTime());
|
info.setAbnormalTime(summonerInfo.getAbnormalTime());
|
||||||
getEffectList().add(info);
|
getEffectList().add(info);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -786,7 +786,7 @@ public class CharStat
|
|||||||
final CharEffectList effectList = _activeChar.getEffectList();
|
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> 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> 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
|
// Call pump to each effect
|
||||||
//@formatter:off
|
//@formatter:off
|
||||||
|
|||||||
@@ -389,10 +389,10 @@ public final class BuffInfo
|
|||||||
for (AbstractEffect effect : _effects)
|
for (AbstractEffect effect : _effects)
|
||||||
{
|
{
|
||||||
// Instant effects shouldn't call onExit(..).
|
// Instant effects shouldn't call onExit(..).
|
||||||
if (!effect.isInstant())
|
// if (!effect.isInstant())
|
||||||
{
|
// {
|
||||||
effect.onExit(_effector, _effected, _skill);
|
effect.onExit(_effector, _effected, _skill);
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set the proper system message.
|
// Set the proper system message.
|
||||||
|
|||||||
@@ -21,13 +21,11 @@ import java.util.List;
|
|||||||
|
|
||||||
import com.l2jmobius.commons.network.PacketWriter;
|
import com.l2jmobius.commons.network.PacketWriter;
|
||||||
import com.l2jmobius.gameserver.model.skills.BuffInfo;
|
import com.l2jmobius.gameserver.model.skills.BuffInfo;
|
||||||
import com.l2jmobius.gameserver.model.skills.Skill;
|
|
||||||
import com.l2jmobius.gameserver.network.OutgoingPackets;
|
import com.l2jmobius.gameserver.network.OutgoingPackets;
|
||||||
|
|
||||||
public class AbnormalStatusUpdate implements IClientOutgoingPacket
|
public class AbnormalStatusUpdate implements IClientOutgoingPacket
|
||||||
{
|
{
|
||||||
private final List<BuffInfo> _effects = new ArrayList<>();
|
private final List<BuffInfo> _effects = new ArrayList<>();
|
||||||
private final List<Skill> _effects2 = new ArrayList<>();
|
|
||||||
|
|
||||||
public void addSkill(BuffInfo info)
|
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
|
@Override
|
||||||
public boolean write(PacketWriter packet)
|
public boolean write(PacketWriter packet)
|
||||||
{
|
{
|
||||||
OutgoingPackets.ABNORMAL_STATUS_UPDATE.writeId(packet);
|
OutgoingPackets.ABNORMAL_STATUS_UPDATE.writeId(packet);
|
||||||
|
|
||||||
packet.writeH(_effects.size() + _effects2.size());
|
packet.writeH(_effects.size());
|
||||||
for (BuffInfo info : _effects)
|
for (BuffInfo info : _effects)
|
||||||
{
|
{
|
||||||
if ((info != null) && info.isInUse())
|
if ((info != null) && info.isInUse())
|
||||||
@@ -62,17 +52,6 @@ public class AbnormalStatusUpdate implements IClientOutgoingPacket
|
|||||||
writeOptionalD(packet, info.getSkill().isAura() ? -1 : info.getTime());
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,6 @@
|
|||||||
*/
|
*/
|
||||||
package com.l2jmobius.gameserver.network.serverpackets;
|
package com.l2jmobius.gameserver.network.serverpackets;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
@@ -24,41 +23,12 @@ import java.util.stream.Collectors;
|
|||||||
import com.l2jmobius.commons.network.PacketWriter;
|
import com.l2jmobius.commons.network.PacketWriter;
|
||||||
import com.l2jmobius.gameserver.model.actor.L2Character;
|
import com.l2jmobius.gameserver.model.actor.L2Character;
|
||||||
import com.l2jmobius.gameserver.model.skills.BuffInfo;
|
import com.l2jmobius.gameserver.model.skills.BuffInfo;
|
||||||
import com.l2jmobius.gameserver.model.skills.Skill;
|
|
||||||
import com.l2jmobius.gameserver.network.OutgoingPackets;
|
import com.l2jmobius.gameserver.network.OutgoingPackets;
|
||||||
|
|
||||||
public class ExAbnormalStatusUpdateFromTarget implements IClientOutgoingPacket
|
public class ExAbnormalStatusUpdateFromTarget implements IClientOutgoingPacket
|
||||||
{
|
{
|
||||||
private final L2Character _character;
|
private final L2Character _character;
|
||||||
private List<Effect> _effects = new ArrayList<>();
|
private final List<BuffInfo> _effects;
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public ExAbnormalStatusUpdateFromTarget(L2Character character)
|
public ExAbnormalStatusUpdateFromTarget(L2Character character)
|
||||||
{
|
{
|
||||||
@@ -69,7 +39,6 @@ public class ExAbnormalStatusUpdateFromTarget implements IClientOutgoingPacket
|
|||||||
.filter(Objects::nonNull)
|
.filter(Objects::nonNull)
|
||||||
.filter(BuffInfo::isInUse)
|
.filter(BuffInfo::isInUse)
|
||||||
.filter(b -> !b.getSkill().isToggle())
|
.filter(b -> !b.getSkill().isToggle())
|
||||||
.map(Effect::new)
|
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
//@formatter:on
|
//@formatter:on
|
||||||
}
|
}
|
||||||
@@ -82,14 +51,14 @@ public class ExAbnormalStatusUpdateFromTarget implements IClientOutgoingPacket
|
|||||||
packet.writeD(_character.getObjectId());
|
packet.writeD(_character.getObjectId());
|
||||||
packet.writeH(_effects.size());
|
packet.writeH(_effects.size());
|
||||||
|
|
||||||
for (Effect info : _effects)
|
for (BuffInfo info : _effects)
|
||||||
{
|
{
|
||||||
packet.writeD(info._skillId);
|
packet.writeD(info.getSkill().getDisplayId());
|
||||||
packet.writeH(info._level);
|
packet.writeH(info.getSkill().getDisplayLevel());
|
||||||
packet.writeH(info._subLevel);
|
packet.writeH(info.getSkill().getSubLevel());
|
||||||
packet.writeH(info._abnormalType);
|
packet.writeH(info.getSkill().getAbnormalType().getClientId());
|
||||||
writeOptionalD(packet, info._duration);
|
writeOptionalD(packet, info.getSkill().isAura() ? -1 : info.getTime());
|
||||||
packet.writeD(info._caster);
|
packet.writeD(info.getEffectorObjectId());
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,6 +16,8 @@
|
|||||||
*/
|
*/
|
||||||
package handlers.effecthandlers;
|
package handlers.effecthandlers;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
|
||||||
import com.l2jmobius.gameserver.model.L2Object;
|
import com.l2jmobius.gameserver.model.L2Object;
|
||||||
import com.l2jmobius.gameserver.model.L2World;
|
import com.l2jmobius.gameserver.model.L2World;
|
||||||
import com.l2jmobius.gameserver.model.StatsSet;
|
import com.l2jmobius.gameserver.model.StatsSet;
|
||||||
@@ -38,6 +40,19 @@ public final class CallSkillOnActionTime extends AbstractEffect
|
|||||||
setTicks(params.getInt("ticks"));
|
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
|
@Override
|
||||||
public boolean onActionTime(L2Character effector, L2Character effected, Skill skill)
|
public boolean onActionTime(L2Character effector, L2Character effected, Skill skill)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -136,6 +136,5 @@ public final class Disarmor extends AbstractEffect
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
super.onExit(effector, effected, skill);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -84,6 +84,5 @@ public final class DoubleCast extends AbstractEffect
|
|||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
super.onExit(effector, effected, skill);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -65,15 +65,15 @@ public final class CharEffectList
|
|||||||
{
|
{
|
||||||
private static final Logger LOGGER = Logger.getLogger(CharEffectList.class.getName());
|
private static final Logger LOGGER = Logger.getLogger(CharEffectList.class.getName());
|
||||||
/** Queue containing all effects from buffs for this effect list. */
|
/** 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. */
|
/** 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. */
|
/** 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}. */
|
/** Map containing the all stacked effect in progress for each {@code AbnormalType}. */
|
||||||
private volatile Set<AbnormalType> _stackedEffects = EnumSet.noneOf(AbnormalType.class);
|
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. */
|
/** 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. */
|
/** Set containing all abnormal visual effects this creature currently displays. */
|
||||||
private volatile Set<AbnormalVisualEffect> _abnormalVisualEffects = EnumSet.noneOf(AbnormalVisualEffect.class);
|
private volatile Set<AbnormalVisualEffect> _abnormalVisualEffects = EnumSet.noneOf(AbnormalVisualEffect.class);
|
||||||
/** Short buff skill ID. */
|
/** Short buff skill ID. */
|
||||||
@@ -110,7 +110,7 @@ public final class CharEffectList
|
|||||||
*/
|
*/
|
||||||
public Set<BuffInfo> getPassives()
|
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()
|
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()
|
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()
|
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()
|
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)
|
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)
|
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)
|
public void addBlockedAbnormalTypes(Set<AbnormalType> blockedAbnormalTypes)
|
||||||
{
|
{
|
||||||
// Initialize
|
|
||||||
if (_blockedAbnormalTypes == null)
|
|
||||||
{
|
|
||||||
synchronized (this)
|
|
||||||
{
|
|
||||||
if (_blockedAbnormalTypes == null)
|
|
||||||
{
|
|
||||||
_blockedAbnormalTypes = EnumSet.copyOf(blockedAbnormalTypes);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_blockedAbnormalTypes.addAll(blockedAbnormalTypes);
|
_blockedAbnormalTypes.addAll(blockedAbnormalTypes);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -238,7 +226,7 @@ public final class CharEffectList
|
|||||||
*/
|
*/
|
||||||
public boolean removeBlockedAbnormalTypes(Set<AbnormalType> blockedBuffSlots)
|
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()
|
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()
|
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)
|
public void stopAllPassives(boolean update, boolean broadcast)
|
||||||
{
|
{
|
||||||
if (_passives != null)
|
if (!_passives.isEmpty())
|
||||||
{
|
{
|
||||||
_passives.forEach(this::remove);
|
_passives.forEach(this::remove);
|
||||||
// Update stats, effect flags and icons.
|
// Update stats, effect flags and icons.
|
||||||
@@ -392,7 +380,7 @@ public final class CharEffectList
|
|||||||
*/
|
*/
|
||||||
public void stopAllOptions(boolean update, boolean broadcast)
|
public void stopAllOptions(boolean update, boolean broadcast)
|
||||||
{
|
{
|
||||||
if (_options != null)
|
if (!_options.isEmpty())
|
||||||
{
|
{
|
||||||
_options.forEach(this::remove);
|
_options.forEach(this::remove);
|
||||||
// Update stats, effect flags and icons.
|
// Update stats, effect flags and icons.
|
||||||
@@ -490,7 +478,7 @@ public final class CharEffectList
|
|||||||
*/
|
*/
|
||||||
public void stopEffects(Predicate<BuffInfo> filter, boolean update, boolean broadcast)
|
public void stopEffects(Predicate<BuffInfo> filter, boolean update, boolean broadcast)
|
||||||
{
|
{
|
||||||
if (_actives != null)
|
if (!_actives.isEmpty())
|
||||||
{
|
{
|
||||||
_actives.stream().filter(filter).forEach(this::remove);
|
_actives.stream().filter(filter).forEach(this::remove);
|
||||||
|
|
||||||
@@ -678,6 +666,10 @@ public final class CharEffectList
|
|||||||
{
|
{
|
||||||
// Remove active effect.
|
// Remove active effect.
|
||||||
removeActive(info, removed);
|
removeActive(info, removed);
|
||||||
|
if (_owner.isNpc()) // Fix for all NPC debuff animations removed.
|
||||||
|
{
|
||||||
|
updateEffectList(broadcast);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update stats, effect flags and icons.
|
// Update stats, effect flags and icons.
|
||||||
@@ -693,7 +685,7 @@ public final class CharEffectList
|
|||||||
*/
|
*/
|
||||||
private synchronized void removeActive(BuffInfo info, boolean removed)
|
private synchronized void removeActive(BuffInfo info, boolean removed)
|
||||||
{
|
{
|
||||||
if (_actives != null)
|
if (!_actives.isEmpty())
|
||||||
{
|
{
|
||||||
// Removes the buff from the given effect list.
|
// Removes the buff from the given effect list.
|
||||||
_actives.remove(info);
|
_actives.remove(info);
|
||||||
@@ -716,7 +708,7 @@ public final class CharEffectList
|
|||||||
|
|
||||||
private void removePassive(BuffInfo info, boolean removed)
|
private void removePassive(BuffInfo info, boolean removed)
|
||||||
{
|
{
|
||||||
if (_passives != null)
|
if (!_passives.isEmpty())
|
||||||
{
|
{
|
||||||
_passives.remove(info);
|
_passives.remove(info);
|
||||||
info.stopAllEffects(removed);
|
info.stopAllEffects(removed);
|
||||||
@@ -725,7 +717,7 @@ public final class CharEffectList
|
|||||||
|
|
||||||
private void removeOption(BuffInfo info, boolean removed)
|
private void removeOption(BuffInfo info, boolean removed)
|
||||||
{
|
{
|
||||||
if (_options != null)
|
if (!_options.isEmpty())
|
||||||
{
|
{
|
||||||
_options.remove(info);
|
_options.remove(info);
|
||||||
info.stopAllEffects(removed);
|
info.stopAllEffects(removed);
|
||||||
@@ -821,12 +813,6 @@ public final class CharEffectList
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize
|
|
||||||
if (_actives == null)
|
|
||||||
{
|
|
||||||
_actives = new ConcurrentLinkedQueue<>();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Manage effect stacking.
|
// Manage effect stacking.
|
||||||
if (hasAbnormalType(skill.getAbnormalType()))
|
if (hasAbnormalType(skill.getAbnormalType()))
|
||||||
{
|
{
|
||||||
@@ -857,7 +843,7 @@ public final class CharEffectList
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Remove effect that gets overriden.
|
// Remove effect that gets overridden.
|
||||||
remove(existingInfo);
|
remove(existingInfo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -865,7 +851,7 @@ public final class CharEffectList
|
|||||||
{
|
{
|
||||||
info.setInUse(false);
|
info.setInUse(false);
|
||||||
}
|
}
|
||||||
else // The effect we try to add should be overriden.
|
else // The effect we try to add should be overridden.
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -918,18 +904,6 @@ public final class CharEffectList
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize
|
|
||||||
if (_passives == null)
|
|
||||||
{
|
|
||||||
synchronized (this)
|
|
||||||
{
|
|
||||||
if (_passives == null)
|
|
||||||
{
|
|
||||||
_passives = ConcurrentHashMap.newKeySet();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove previous passives of this id.
|
// Remove previous passives of this id.
|
||||||
_passives.stream().filter(Objects::nonNull).filter(b -> b.getSkill().getId() == skill.getId()).forEach(b ->
|
_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)
|
if (info.getOption() != null)
|
||||||
{
|
{
|
||||||
// Initialize
|
|
||||||
if (_options == null)
|
|
||||||
{
|
|
||||||
synchronized (this)
|
|
||||||
{
|
|
||||||
if (_options == null)
|
|
||||||
{
|
|
||||||
_options = ConcurrentHashMap.newKeySet();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove previous options of this id.
|
// Remove previous options of this id.
|
||||||
_options.stream().filter(Objects::nonNull).filter(b -> b.getOption().getId() == info.getOption().getId()).forEach(b ->
|
_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<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();
|
final Optional<ExOlympiadSpelledInfo> os = (player.isInOlympiadMode() && player.isOlympiadStart()) ? Optional.of(new ExOlympiadSpelledInfo(player)) : Optional.empty();
|
||||||
|
|
||||||
if (_actives != null)
|
if (!_actives.isEmpty())
|
||||||
{
|
{
|
||||||
//@formatter:off
|
//@formatter:off
|
||||||
_actives.stream()
|
_actives.stream()
|
||||||
@@ -1109,42 +1071,47 @@ public final class CharEffectList
|
|||||||
final Set<BuffInfo> unhideBuffs = new HashSet<>();
|
final Set<BuffInfo> unhideBuffs = new HashSet<>();
|
||||||
|
|
||||||
// Recalculate new flags
|
// Recalculate new flags
|
||||||
if (_actives != null)
|
for (BuffInfo info : _actives)
|
||||||
{
|
{
|
||||||
for (BuffInfo info : _actives)
|
if (info != null)
|
||||||
{
|
{
|
||||||
if (info != null)
|
final Skill skill = info.getSkill();
|
||||||
|
|
||||||
|
// Handle hidden buffs. Check if there was such abnormal before so we can continue.
|
||||||
|
if ((_hiddenBuffs.get() > 0) && _stackedEffects.contains(skill.getAbnormalType()))
|
||||||
{
|
{
|
||||||
final Skill skill = info.getSkill();
|
// If incoming buff isnt hidden, remove any hidden buffs with its abnormal type.
|
||||||
|
if (info.isInUse())
|
||||||
// Handle hidden buffs. Check if there was such abnormal before so we can continue.
|
|
||||||
if ((_hiddenBuffs.get() > 0) && _stackedEffects.contains(skill.getAbnormalType()))
|
|
||||||
{
|
{
|
||||||
// If incoming buff isnt hidden, remove any hidden buffs with its abnormal type.
|
unhideBuffs.removeIf(b -> b.isAbnormalType(skill.getAbnormalType()));
|
||||||
if (info.isInUse())
|
|
||||||
{
|
|
||||||
unhideBuffs.removeIf(b -> b.isAbnormalType(skill.getAbnormalType()));
|
|
||||||
}
|
|
||||||
// If this incoming buff is hidden and its first of its abnormal, or it removes any previous hidden buff with the same or lower abnormal level and add this instead.
|
|
||||||
else if (!abnormalTypeFlags.contains(skill.getAbnormalType()) || unhideBuffs.removeIf(b -> (b.isAbnormalType(skill.getAbnormalType())) && (b.getSkill().getAbnormalLvl() <= skill.getAbnormalLvl())))
|
|
||||||
{
|
|
||||||
unhideBuffs.add(info);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
// If this incoming buff is hidden and its first of its abnormal, or it removes any previous hidden buff with the same or lower abnormal level and add this instead.
|
||||||
// Add the EffectType flag.
|
else if (!abnormalTypeFlags.contains(skill.getAbnormalType()) || unhideBuffs.removeIf(b -> (b.isAbnormalType(skill.getAbnormalType())) && (b.getSkill().getAbnormalLvl() <= skill.getAbnormalLvl())))
|
||||||
for (AbstractEffect e : info.getEffects())
|
|
||||||
{
|
{
|
||||||
flags |= e.getEffectFlags();
|
unhideBuffs.add(info);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Add the AbnormalType flag.
|
// Add the EffectType flag.
|
||||||
abnormalTypeFlags.add(skill.getAbnormalType());
|
for (AbstractEffect e : info.getEffects())
|
||||||
|
{
|
||||||
|
flags |= e.getEffectFlags();
|
||||||
|
}
|
||||||
|
|
||||||
// Add AbnormalVisualEffect flag.
|
// Add the AbnormalType flag.
|
||||||
if (skill.hasAbnormalVisualEffects())
|
abnormalTypeFlags.add(skill.getAbnormalType());
|
||||||
|
|
||||||
|
// Add AbnormalVisualEffect flag.
|
||||||
|
if (skill.hasAbnormalVisualEffects())
|
||||||
|
{
|
||||||
|
for (AbnormalVisualEffect ave : skill.getAbnormalVisualEffects())
|
||||||
{
|
{
|
||||||
abnormalVisualEffectFlags.addAll(skill.getAbnormalVisualEffects());
|
abnormalVisualEffectFlags.add(ave);
|
||||||
|
_abnormalVisualEffects.add(ave);
|
||||||
|
}
|
||||||
|
if (broadcast)
|
||||||
|
{
|
||||||
|
_owner.updateAbnormalVisualEffects();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1167,7 +1134,7 @@ public final class CharEffectList
|
|||||||
if (broadcast)
|
if (broadcast)
|
||||||
{
|
{
|
||||||
// Check if there is change in AbnormalVisualEffect
|
// Check if there is change in AbnormalVisualEffect
|
||||||
if ((abnormalVisualEffectFlags.size() != _abnormalVisualEffects.size()) || !abnormalVisualEffectFlags.containsAll(_abnormalVisualEffects))
|
if (!abnormalVisualEffectFlags.containsAll(_abnormalVisualEffects))
|
||||||
{
|
{
|
||||||
_abnormalVisualEffects = abnormalVisualEffectFlags;
|
_abnormalVisualEffects = abnormalVisualEffectFlags;
|
||||||
_owner.updateAbnormalVisualEffects();
|
_owner.updateAbnormalVisualEffects();
|
||||||
|
|||||||
@@ -77,7 +77,6 @@ public class DoppelgangerInstance extends L2Npc
|
|||||||
info.setAbnormalTime(summonerInfo.getAbnormalTime());
|
info.setAbnormalTime(summonerInfo.getAbnormalTime());
|
||||||
getEffectList().add(info);
|
getEffectList().add(info);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -776,7 +776,7 @@ public class CharStat
|
|||||||
final CharEffectList effectList = _activeChar.getEffectList();
|
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> 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> 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
|
// Call pump to each effect
|
||||||
//@formatter:off
|
//@formatter:off
|
||||||
|
|||||||
@@ -389,10 +389,10 @@ public final class BuffInfo
|
|||||||
for (AbstractEffect effect : _effects)
|
for (AbstractEffect effect : _effects)
|
||||||
{
|
{
|
||||||
// Instant effects shouldn't call onExit(..).
|
// Instant effects shouldn't call onExit(..).
|
||||||
if (!effect.isInstant())
|
// if (!effect.isInstant())
|
||||||
{
|
// {
|
||||||
effect.onExit(_effector, _effected, _skill);
|
effect.onExit(_effector, _effected, _skill);
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set the proper system message.
|
// Set the proper system message.
|
||||||
|
|||||||
@@ -21,17 +21,11 @@ import java.util.List;
|
|||||||
|
|
||||||
import com.l2jmobius.commons.network.PacketWriter;
|
import com.l2jmobius.commons.network.PacketWriter;
|
||||||
import com.l2jmobius.gameserver.model.skills.BuffInfo;
|
import com.l2jmobius.gameserver.model.skills.BuffInfo;
|
||||||
import com.l2jmobius.gameserver.model.skills.Skill;
|
|
||||||
import com.l2jmobius.gameserver.network.OutgoingPackets;
|
import com.l2jmobius.gameserver.network.OutgoingPackets;
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Mobius
|
|
||||||
* @version Classic 2.0
|
|
||||||
*/
|
|
||||||
public class AbnormalStatusUpdate implements IClientOutgoingPacket
|
public class AbnormalStatusUpdate implements IClientOutgoingPacket
|
||||||
{
|
{
|
||||||
private final List<BuffInfo> _effects = new ArrayList<>();
|
private final List<BuffInfo> _effects = new ArrayList<>();
|
||||||
private final List<Skill> _effects2 = new ArrayList<>();
|
|
||||||
|
|
||||||
public void addSkill(BuffInfo info)
|
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
|
@Override
|
||||||
public boolean write(PacketWriter packet)
|
public boolean write(PacketWriter packet)
|
||||||
{
|
{
|
||||||
OutgoingPackets.ABNORMAL_STATUS_UPDATE.writeId(packet);
|
OutgoingPackets.ABNORMAL_STATUS_UPDATE.writeId(packet);
|
||||||
|
|
||||||
packet.writeH(_effects.size() + _effects2.size());
|
packet.writeH(_effects.size());
|
||||||
for (BuffInfo info : _effects)
|
for (BuffInfo info : _effects)
|
||||||
{
|
{
|
||||||
if ((info != null) && info.isInUse())
|
if ((info != null) && info.isInUse())
|
||||||
{
|
{
|
||||||
packet.writeD(info.getSkill().getDisplayId());
|
packet.writeD(info.getSkill().getDisplayId());
|
||||||
packet.writeH(info.getSkill().getDisplayLevel());
|
packet.writeH(info.getSkill().getDisplayLevel());
|
||||||
packet.writeD(0x00);
|
// packet.writeH(info.getSkill().getSubLevel());
|
||||||
packet.writeH(info.getSkill().isAura() ? -1 : info.getTime());
|
packet.writeD(info.getSkill().getAbnormalType().getClientId());
|
||||||
}
|
writeOptionalD(packet, 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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -16,8 +16,8 @@
|
|||||||
*/
|
*/
|
||||||
package com.l2jmobius.gameserver.network.serverpackets;
|
package com.l2jmobius.gameserver.network.serverpackets;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import com.l2jmobius.commons.network.PacketWriter;
|
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.model.skills.BuffInfo;
|
||||||
import com.l2jmobius.gameserver.network.OutgoingPackets;
|
import com.l2jmobius.gameserver.network.OutgoingPackets;
|
||||||
|
|
||||||
/**
|
|
||||||
* @author proGenitor <br>
|
|
||||||
* Experimental packet compatible for L2Classic 2.0.
|
|
||||||
*/
|
|
||||||
public class ExAbnormalStatusUpdateFromTarget implements IClientOutgoingPacket
|
public class ExAbnormalStatusUpdateFromTarget implements IClientOutgoingPacket
|
||||||
{
|
{
|
||||||
private final L2Character _character;
|
private final L2Character _character;
|
||||||
private List<Effect> _effects = new ArrayList<>();
|
private final List<BuffInfo> _effects;
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public ExAbnormalStatusUpdateFromTarget(L2Character character)
|
public ExAbnormalStatusUpdateFromTarget(L2Character character)
|
||||||
{
|
{
|
||||||
@@ -61,7 +36,9 @@ public class ExAbnormalStatusUpdateFromTarget implements IClientOutgoingPacket
|
|||||||
_character = character;
|
_character = character;
|
||||||
_effects = character.getEffectList().getEffects()
|
_effects = character.getEffectList().getEffects()
|
||||||
.stream()
|
.stream()
|
||||||
.map(Effect::new)
|
.filter(Objects::nonNull)
|
||||||
|
.filter(BuffInfo::isInUse)
|
||||||
|
.filter(b -> !b.getSkill().isToggle())
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
//@formatter:on
|
//@formatter:on
|
||||||
}
|
}
|
||||||
@@ -74,14 +51,14 @@ public class ExAbnormalStatusUpdateFromTarget implements IClientOutgoingPacket
|
|||||||
packet.writeD(_character.getObjectId());
|
packet.writeD(_character.getObjectId());
|
||||||
packet.writeH(_effects.size());
|
packet.writeH(_effects.size());
|
||||||
|
|
||||||
for (Effect info : _effects)
|
for (BuffInfo info : _effects)
|
||||||
{
|
{
|
||||||
packet.writeD(info._skillId);
|
packet.writeD(info.getSkill().getDisplayId());
|
||||||
packet.writeH(info._level);
|
packet.writeH(info.getSkill().getDisplayLevel());
|
||||||
packet.writeH(info._subLevel);
|
// packet.writeH(info.getSkill().getSubLevel());
|
||||||
packet.writeH(info._abnormalType);
|
packet.writeH(info.getSkill().getAbnormalType().getClientId());
|
||||||
writeOptionalD(packet, info._duration);
|
writeOptionalD(packet, info.getSkill().isAura() ? -1 : info.getTime());
|
||||||
packet.writeD(info._caster);
|
packet.writeD(info.getEffectorObjectId());
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,6 +16,8 @@
|
|||||||
*/
|
*/
|
||||||
package handlers.effecthandlers;
|
package handlers.effecthandlers;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
|
||||||
import com.l2jmobius.gameserver.model.L2Object;
|
import com.l2jmobius.gameserver.model.L2Object;
|
||||||
import com.l2jmobius.gameserver.model.L2World;
|
import com.l2jmobius.gameserver.model.L2World;
|
||||||
import com.l2jmobius.gameserver.model.StatsSet;
|
import com.l2jmobius.gameserver.model.StatsSet;
|
||||||
@@ -38,6 +40,19 @@ public final class CallSkillOnActionTime extends AbstractEffect
|
|||||||
setTicks(params.getInt("ticks"));
|
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
|
@Override
|
||||||
public boolean onActionTime(L2Character effector, L2Character effected, Skill skill)
|
public boolean onActionTime(L2Character effector, L2Character effected, Skill skill)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -136,6 +136,5 @@ public final class Disarmor extends AbstractEffect
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
super.onExit(effector, effected, skill);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -84,6 +84,5 @@ public final class DoubleCast extends AbstractEffect
|
|||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
super.onExit(effector, effected, skill);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -65,15 +65,15 @@ public final class CharEffectList
|
|||||||
{
|
{
|
||||||
private static final Logger LOGGER = Logger.getLogger(CharEffectList.class.getName());
|
private static final Logger LOGGER = Logger.getLogger(CharEffectList.class.getName());
|
||||||
/** Queue containing all effects from buffs for this effect list. */
|
/** 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. */
|
/** 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. */
|
/** 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}. */
|
/** Map containing the all stacked effect in progress for each {@code AbnormalType}. */
|
||||||
private volatile Set<AbnormalType> _stackedEffects = EnumSet.noneOf(AbnormalType.class);
|
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. */
|
/** 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. */
|
/** Set containing all abnormal visual effects this creature currently displays. */
|
||||||
private volatile Set<AbnormalVisualEffect> _abnormalVisualEffects = EnumSet.noneOf(AbnormalVisualEffect.class);
|
private volatile Set<AbnormalVisualEffect> _abnormalVisualEffects = EnumSet.noneOf(AbnormalVisualEffect.class);
|
||||||
/** Short buff skill ID. */
|
/** Short buff skill ID. */
|
||||||
@@ -110,7 +110,7 @@ public final class CharEffectList
|
|||||||
*/
|
*/
|
||||||
public Set<BuffInfo> getPassives()
|
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()
|
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()
|
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()
|
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()
|
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)
|
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)
|
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)
|
public void addBlockedAbnormalTypes(Set<AbnormalType> blockedAbnormalTypes)
|
||||||
{
|
{
|
||||||
// Initialize
|
|
||||||
if (_blockedAbnormalTypes == null)
|
|
||||||
{
|
|
||||||
synchronized (this)
|
|
||||||
{
|
|
||||||
if (_blockedAbnormalTypes == null)
|
|
||||||
{
|
|
||||||
_blockedAbnormalTypes = EnumSet.copyOf(blockedAbnormalTypes);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_blockedAbnormalTypes.addAll(blockedAbnormalTypes);
|
_blockedAbnormalTypes.addAll(blockedAbnormalTypes);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -238,7 +226,7 @@ public final class CharEffectList
|
|||||||
*/
|
*/
|
||||||
public boolean removeBlockedAbnormalTypes(Set<AbnormalType> blockedBuffSlots)
|
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()
|
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()
|
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)
|
public void stopAllPassives(boolean update, boolean broadcast)
|
||||||
{
|
{
|
||||||
if (_passives != null)
|
if (!_passives.isEmpty())
|
||||||
{
|
{
|
||||||
_passives.forEach(this::remove);
|
_passives.forEach(this::remove);
|
||||||
// Update stats, effect flags and icons.
|
// Update stats, effect flags and icons.
|
||||||
@@ -392,7 +380,7 @@ public final class CharEffectList
|
|||||||
*/
|
*/
|
||||||
public void stopAllOptions(boolean update, boolean broadcast)
|
public void stopAllOptions(boolean update, boolean broadcast)
|
||||||
{
|
{
|
||||||
if (_options != null)
|
if (!_options.isEmpty())
|
||||||
{
|
{
|
||||||
_options.forEach(this::remove);
|
_options.forEach(this::remove);
|
||||||
// Update stats, effect flags and icons.
|
// Update stats, effect flags and icons.
|
||||||
@@ -490,7 +478,7 @@ public final class CharEffectList
|
|||||||
*/
|
*/
|
||||||
public void stopEffects(Predicate<BuffInfo> filter, boolean update, boolean broadcast)
|
public void stopEffects(Predicate<BuffInfo> filter, boolean update, boolean broadcast)
|
||||||
{
|
{
|
||||||
if (_actives != null)
|
if (!_actives.isEmpty())
|
||||||
{
|
{
|
||||||
_actives.stream().filter(filter).forEach(this::remove);
|
_actives.stream().filter(filter).forEach(this::remove);
|
||||||
|
|
||||||
@@ -678,6 +666,10 @@ public final class CharEffectList
|
|||||||
{
|
{
|
||||||
// Remove active effect.
|
// Remove active effect.
|
||||||
removeActive(info, removed);
|
removeActive(info, removed);
|
||||||
|
if (_owner.isNpc()) // Fix for all NPC debuff animations removed.
|
||||||
|
{
|
||||||
|
updateEffectList(broadcast);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update stats, effect flags and icons.
|
// Update stats, effect flags and icons.
|
||||||
@@ -693,7 +685,7 @@ public final class CharEffectList
|
|||||||
*/
|
*/
|
||||||
private synchronized void removeActive(BuffInfo info, boolean removed)
|
private synchronized void removeActive(BuffInfo info, boolean removed)
|
||||||
{
|
{
|
||||||
if (_actives != null)
|
if (!_actives.isEmpty())
|
||||||
{
|
{
|
||||||
// Removes the buff from the given effect list.
|
// Removes the buff from the given effect list.
|
||||||
_actives.remove(info);
|
_actives.remove(info);
|
||||||
@@ -716,7 +708,7 @@ public final class CharEffectList
|
|||||||
|
|
||||||
private void removePassive(BuffInfo info, boolean removed)
|
private void removePassive(BuffInfo info, boolean removed)
|
||||||
{
|
{
|
||||||
if (_passives != null)
|
if (!_passives.isEmpty())
|
||||||
{
|
{
|
||||||
_passives.remove(info);
|
_passives.remove(info);
|
||||||
info.stopAllEffects(removed);
|
info.stopAllEffects(removed);
|
||||||
@@ -725,7 +717,7 @@ public final class CharEffectList
|
|||||||
|
|
||||||
private void removeOption(BuffInfo info, boolean removed)
|
private void removeOption(BuffInfo info, boolean removed)
|
||||||
{
|
{
|
||||||
if (_options != null)
|
if (!_options.isEmpty())
|
||||||
{
|
{
|
||||||
_options.remove(info);
|
_options.remove(info);
|
||||||
info.stopAllEffects(removed);
|
info.stopAllEffects(removed);
|
||||||
@@ -821,12 +813,6 @@ public final class CharEffectList
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize
|
|
||||||
if (_actives == null)
|
|
||||||
{
|
|
||||||
_actives = new ConcurrentLinkedQueue<>();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Manage effect stacking.
|
// Manage effect stacking.
|
||||||
if (hasAbnormalType(skill.getAbnormalType()))
|
if (hasAbnormalType(skill.getAbnormalType()))
|
||||||
{
|
{
|
||||||
@@ -857,7 +843,7 @@ public final class CharEffectList
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Remove effect that gets overriden.
|
// Remove effect that gets overridden.
|
||||||
remove(existingInfo);
|
remove(existingInfo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -865,7 +851,7 @@ public final class CharEffectList
|
|||||||
{
|
{
|
||||||
info.setInUse(false);
|
info.setInUse(false);
|
||||||
}
|
}
|
||||||
else // The effect we try to add should be overriden.
|
else // The effect we try to add should be overridden.
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -918,18 +904,6 @@ public final class CharEffectList
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize
|
|
||||||
if (_passives == null)
|
|
||||||
{
|
|
||||||
synchronized (this)
|
|
||||||
{
|
|
||||||
if (_passives == null)
|
|
||||||
{
|
|
||||||
_passives = ConcurrentHashMap.newKeySet();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove previous passives of this id.
|
// Remove previous passives of this id.
|
||||||
_passives.stream().filter(Objects::nonNull).filter(b -> b.getSkill().getId() == skill.getId()).forEach(b ->
|
_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)
|
if (info.getOption() != null)
|
||||||
{
|
{
|
||||||
// Initialize
|
|
||||||
if (_options == null)
|
|
||||||
{
|
|
||||||
synchronized (this)
|
|
||||||
{
|
|
||||||
if (_options == null)
|
|
||||||
{
|
|
||||||
_options = ConcurrentHashMap.newKeySet();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove previous options of this id.
|
// Remove previous options of this id.
|
||||||
_options.stream().filter(Objects::nonNull).filter(b -> b.getOption().getId() == info.getOption().getId()).forEach(b ->
|
_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<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();
|
final Optional<ExOlympiadSpelledInfo> os = (player.isInOlympiadMode() && player.isOlympiadStart()) ? Optional.of(new ExOlympiadSpelledInfo(player)) : Optional.empty();
|
||||||
|
|
||||||
if (_actives != null)
|
if (!_actives.isEmpty())
|
||||||
{
|
{
|
||||||
//@formatter:off
|
//@formatter:off
|
||||||
_actives.stream()
|
_actives.stream()
|
||||||
@@ -1109,42 +1071,47 @@ public final class CharEffectList
|
|||||||
final Set<BuffInfo> unhideBuffs = new HashSet<>();
|
final Set<BuffInfo> unhideBuffs = new HashSet<>();
|
||||||
|
|
||||||
// Recalculate new flags
|
// Recalculate new flags
|
||||||
if (_actives != null)
|
for (BuffInfo info : _actives)
|
||||||
{
|
{
|
||||||
for (BuffInfo info : _actives)
|
if (info != null)
|
||||||
{
|
{
|
||||||
if (info != null)
|
final Skill skill = info.getSkill();
|
||||||
|
|
||||||
|
// Handle hidden buffs. Check if there was such abnormal before so we can continue.
|
||||||
|
if ((_hiddenBuffs.get() > 0) && _stackedEffects.contains(skill.getAbnormalType()))
|
||||||
{
|
{
|
||||||
final Skill skill = info.getSkill();
|
// If incoming buff isnt hidden, remove any hidden buffs with its abnormal type.
|
||||||
|
if (info.isInUse())
|
||||||
// Handle hidden buffs. Check if there was such abnormal before so we can continue.
|
|
||||||
if ((_hiddenBuffs.get() > 0) && _stackedEffects.contains(skill.getAbnormalType()))
|
|
||||||
{
|
{
|
||||||
// If incoming buff isnt hidden, remove any hidden buffs with its abnormal type.
|
unhideBuffs.removeIf(b -> b.isAbnormalType(skill.getAbnormalType()));
|
||||||
if (info.isInUse())
|
|
||||||
{
|
|
||||||
unhideBuffs.removeIf(b -> b.isAbnormalType(skill.getAbnormalType()));
|
|
||||||
}
|
|
||||||
// If this incoming buff is hidden and its first of its abnormal, or it removes any previous hidden buff with the same or lower abnormal level and add this instead.
|
|
||||||
else if (!abnormalTypeFlags.contains(skill.getAbnormalType()) || unhideBuffs.removeIf(b -> (b.isAbnormalType(skill.getAbnormalType())) && (b.getSkill().getAbnormalLvl() <= skill.getAbnormalLvl())))
|
|
||||||
{
|
|
||||||
unhideBuffs.add(info);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
// If this incoming buff is hidden and its first of its abnormal, or it removes any previous hidden buff with the same or lower abnormal level and add this instead.
|
||||||
// Add the EffectType flag.
|
else if (!abnormalTypeFlags.contains(skill.getAbnormalType()) || unhideBuffs.removeIf(b -> (b.isAbnormalType(skill.getAbnormalType())) && (b.getSkill().getAbnormalLvl() <= skill.getAbnormalLvl())))
|
||||||
for (AbstractEffect e : info.getEffects())
|
|
||||||
{
|
{
|
||||||
flags |= e.getEffectFlags();
|
unhideBuffs.add(info);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Add the AbnormalType flag.
|
// Add the EffectType flag.
|
||||||
abnormalTypeFlags.add(skill.getAbnormalType());
|
for (AbstractEffect e : info.getEffects())
|
||||||
|
{
|
||||||
|
flags |= e.getEffectFlags();
|
||||||
|
}
|
||||||
|
|
||||||
// Add AbnormalVisualEffect flag.
|
// Add the AbnormalType flag.
|
||||||
if (skill.hasAbnormalVisualEffects())
|
abnormalTypeFlags.add(skill.getAbnormalType());
|
||||||
|
|
||||||
|
// Add AbnormalVisualEffect flag.
|
||||||
|
if (skill.hasAbnormalVisualEffects())
|
||||||
|
{
|
||||||
|
for (AbnormalVisualEffect ave : skill.getAbnormalVisualEffects())
|
||||||
{
|
{
|
||||||
abnormalVisualEffectFlags.addAll(skill.getAbnormalVisualEffects());
|
abnormalVisualEffectFlags.add(ave);
|
||||||
|
_abnormalVisualEffects.add(ave);
|
||||||
|
}
|
||||||
|
if (broadcast)
|
||||||
|
{
|
||||||
|
_owner.updateAbnormalVisualEffects();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1167,7 +1134,7 @@ public final class CharEffectList
|
|||||||
if (broadcast)
|
if (broadcast)
|
||||||
{
|
{
|
||||||
// Check if there is change in AbnormalVisualEffect
|
// Check if there is change in AbnormalVisualEffect
|
||||||
if ((abnormalVisualEffectFlags.size() != _abnormalVisualEffects.size()) || !abnormalVisualEffectFlags.containsAll(_abnormalVisualEffects))
|
if (!abnormalVisualEffectFlags.containsAll(_abnormalVisualEffects))
|
||||||
{
|
{
|
||||||
_abnormalVisualEffects = abnormalVisualEffectFlags;
|
_abnormalVisualEffects = abnormalVisualEffectFlags;
|
||||||
_owner.updateAbnormalVisualEffects();
|
_owner.updateAbnormalVisualEffects();
|
||||||
|
|||||||
@@ -77,7 +77,6 @@ public class DoppelgangerInstance extends L2Npc
|
|||||||
info.setAbnormalTime(summonerInfo.getAbnormalTime());
|
info.setAbnormalTime(summonerInfo.getAbnormalTime());
|
||||||
getEffectList().add(info);
|
getEffectList().add(info);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -776,7 +776,7 @@ public class CharStat
|
|||||||
final CharEffectList effectList = _activeChar.getEffectList();
|
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> 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> 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
|
// Call pump to each effect
|
||||||
//@formatter:off
|
//@formatter:off
|
||||||
|
|||||||
@@ -389,10 +389,10 @@ public final class BuffInfo
|
|||||||
for (AbstractEffect effect : _effects)
|
for (AbstractEffect effect : _effects)
|
||||||
{
|
{
|
||||||
// Instant effects shouldn't call onExit(..).
|
// Instant effects shouldn't call onExit(..).
|
||||||
if (!effect.isInstant())
|
// if (!effect.isInstant())
|
||||||
{
|
// {
|
||||||
effect.onExit(_effector, _effected, _skill);
|
effect.onExit(_effector, _effected, _skill);
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set the proper system message.
|
// Set the proper system message.
|
||||||
|
|||||||
@@ -21,17 +21,11 @@ import java.util.List;
|
|||||||
|
|
||||||
import com.l2jmobius.commons.network.PacketWriter;
|
import com.l2jmobius.commons.network.PacketWriter;
|
||||||
import com.l2jmobius.gameserver.model.skills.BuffInfo;
|
import com.l2jmobius.gameserver.model.skills.BuffInfo;
|
||||||
import com.l2jmobius.gameserver.model.skills.Skill;
|
|
||||||
import com.l2jmobius.gameserver.network.OutgoingPackets;
|
import com.l2jmobius.gameserver.network.OutgoingPackets;
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Mobius
|
|
||||||
* @version Classic 2.0
|
|
||||||
*/
|
|
||||||
public class AbnormalStatusUpdate implements IClientOutgoingPacket
|
public class AbnormalStatusUpdate implements IClientOutgoingPacket
|
||||||
{
|
{
|
||||||
private final List<BuffInfo> _effects = new ArrayList<>();
|
private final List<BuffInfo> _effects = new ArrayList<>();
|
||||||
private final List<Skill> _effects2 = new ArrayList<>();
|
|
||||||
|
|
||||||
public void addSkill(BuffInfo info)
|
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
|
@Override
|
||||||
public boolean write(PacketWriter packet)
|
public boolean write(PacketWriter packet)
|
||||||
{
|
{
|
||||||
OutgoingPackets.ABNORMAL_STATUS_UPDATE.writeId(packet);
|
OutgoingPackets.ABNORMAL_STATUS_UPDATE.writeId(packet);
|
||||||
|
|
||||||
packet.writeH(_effects.size() + _effects2.size());
|
packet.writeH(_effects.size());
|
||||||
for (BuffInfo info : _effects)
|
for (BuffInfo info : _effects)
|
||||||
{
|
{
|
||||||
if ((info != null) && info.isInUse())
|
if ((info != null) && info.isInUse())
|
||||||
{
|
{
|
||||||
packet.writeD(info.getSkill().getDisplayId());
|
packet.writeD(info.getSkill().getDisplayId());
|
||||||
packet.writeH(info.getSkill().getDisplayLevel());
|
packet.writeH(info.getSkill().getDisplayLevel());
|
||||||
packet.writeD(0x00);
|
// packet.writeH(info.getSkill().getSubLevel());
|
||||||
packet.writeH(info.getSkill().isAura() ? -1 : info.getTime());
|
packet.writeD(info.getSkill().getAbnormalType().getClientId());
|
||||||
}
|
writeOptionalD(packet, 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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -16,8 +16,8 @@
|
|||||||
*/
|
*/
|
||||||
package com.l2jmobius.gameserver.network.serverpackets;
|
package com.l2jmobius.gameserver.network.serverpackets;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import com.l2jmobius.commons.network.PacketWriter;
|
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.model.skills.BuffInfo;
|
||||||
import com.l2jmobius.gameserver.network.OutgoingPackets;
|
import com.l2jmobius.gameserver.network.OutgoingPackets;
|
||||||
|
|
||||||
/**
|
|
||||||
* @author proGenitor <br>
|
|
||||||
* Experimental packet compatible for L2Classic 2.0.
|
|
||||||
*/
|
|
||||||
public class ExAbnormalStatusUpdateFromTarget implements IClientOutgoingPacket
|
public class ExAbnormalStatusUpdateFromTarget implements IClientOutgoingPacket
|
||||||
{
|
{
|
||||||
private final L2Character _character;
|
private final L2Character _character;
|
||||||
private List<Effect> _effects = new ArrayList<>();
|
private final List<BuffInfo> _effects;
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public ExAbnormalStatusUpdateFromTarget(L2Character character)
|
public ExAbnormalStatusUpdateFromTarget(L2Character character)
|
||||||
{
|
{
|
||||||
@@ -61,7 +36,9 @@ public class ExAbnormalStatusUpdateFromTarget implements IClientOutgoingPacket
|
|||||||
_character = character;
|
_character = character;
|
||||||
_effects = character.getEffectList().getEffects()
|
_effects = character.getEffectList().getEffects()
|
||||||
.stream()
|
.stream()
|
||||||
.map(Effect::new)
|
.filter(Objects::nonNull)
|
||||||
|
.filter(BuffInfo::isInUse)
|
||||||
|
.filter(b -> !b.getSkill().isToggle())
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
//@formatter:on
|
//@formatter:on
|
||||||
}
|
}
|
||||||
@@ -74,14 +51,14 @@ public class ExAbnormalStatusUpdateFromTarget implements IClientOutgoingPacket
|
|||||||
packet.writeD(_character.getObjectId());
|
packet.writeD(_character.getObjectId());
|
||||||
packet.writeH(_effects.size());
|
packet.writeH(_effects.size());
|
||||||
|
|
||||||
for (Effect info : _effects)
|
for (BuffInfo info : _effects)
|
||||||
{
|
{
|
||||||
packet.writeD(info._skillId);
|
packet.writeD(info.getSkill().getDisplayId());
|
||||||
packet.writeH(info._level);
|
packet.writeH(info.getSkill().getDisplayLevel());
|
||||||
packet.writeH(info._subLevel);
|
// packet.writeH(info.getSkill().getSubLevel());
|
||||||
packet.writeH(info._abnormalType);
|
packet.writeH(info.getSkill().getAbnormalType().getClientId());
|
||||||
writeOptionalD(packet, info._duration);
|
writeOptionalD(packet, info.getSkill().isAura() ? -1 : info.getTime());
|
||||||
packet.writeD(info._caster);
|
packet.writeD(info.getEffectorObjectId());
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,6 +16,8 @@
|
|||||||
*/
|
*/
|
||||||
package handlers.effecthandlers;
|
package handlers.effecthandlers;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
|
||||||
import com.l2jmobius.gameserver.model.L2Object;
|
import com.l2jmobius.gameserver.model.L2Object;
|
||||||
import com.l2jmobius.gameserver.model.L2World;
|
import com.l2jmobius.gameserver.model.L2World;
|
||||||
import com.l2jmobius.gameserver.model.StatsSet;
|
import com.l2jmobius.gameserver.model.StatsSet;
|
||||||
@@ -38,6 +40,19 @@ public final class CallSkillOnActionTime extends AbstractEffect
|
|||||||
setTicks(params.getInt("ticks"));
|
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
|
@Override
|
||||||
public boolean onActionTime(L2Character effector, L2Character effected, Skill skill)
|
public boolean onActionTime(L2Character effector, L2Character effected, Skill skill)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -136,6 +136,5 @@ public final class Disarmor extends AbstractEffect
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
super.onExit(effector, effected, skill);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -84,6 +84,5 @@ public final class DoubleCast extends AbstractEffect
|
|||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
super.onExit(effector, effected, skill);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -65,15 +65,15 @@ public final class CharEffectList
|
|||||||
{
|
{
|
||||||
private static final Logger LOGGER = Logger.getLogger(CharEffectList.class.getName());
|
private static final Logger LOGGER = Logger.getLogger(CharEffectList.class.getName());
|
||||||
/** Queue containing all effects from buffs for this effect list. */
|
/** 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. */
|
/** 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. */
|
/** 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}. */
|
/** Map containing the all stacked effect in progress for each {@code AbnormalType}. */
|
||||||
private volatile Set<AbnormalType> _stackedEffects = EnumSet.noneOf(AbnormalType.class);
|
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. */
|
/** 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. */
|
/** Set containing all abnormal visual effects this creature currently displays. */
|
||||||
private volatile Set<AbnormalVisualEffect> _abnormalVisualEffects = EnumSet.noneOf(AbnormalVisualEffect.class);
|
private volatile Set<AbnormalVisualEffect> _abnormalVisualEffects = EnumSet.noneOf(AbnormalVisualEffect.class);
|
||||||
/** Short buff skill ID. */
|
/** Short buff skill ID. */
|
||||||
@@ -110,7 +110,7 @@ public final class CharEffectList
|
|||||||
*/
|
*/
|
||||||
public Set<BuffInfo> getPassives()
|
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()
|
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()
|
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()
|
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()
|
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)
|
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)
|
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)
|
public void addBlockedAbnormalTypes(Set<AbnormalType> blockedAbnormalTypes)
|
||||||
{
|
{
|
||||||
// Initialize
|
|
||||||
if (_blockedAbnormalTypes == null)
|
|
||||||
{
|
|
||||||
synchronized (this)
|
|
||||||
{
|
|
||||||
if (_blockedAbnormalTypes == null)
|
|
||||||
{
|
|
||||||
_blockedAbnormalTypes = EnumSet.copyOf(blockedAbnormalTypes);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_blockedAbnormalTypes.addAll(blockedAbnormalTypes);
|
_blockedAbnormalTypes.addAll(blockedAbnormalTypes);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -238,7 +226,7 @@ public final class CharEffectList
|
|||||||
*/
|
*/
|
||||||
public boolean removeBlockedAbnormalTypes(Set<AbnormalType> blockedBuffSlots)
|
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()
|
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()
|
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)
|
public void stopAllPassives(boolean update, boolean broadcast)
|
||||||
{
|
{
|
||||||
if (_passives != null)
|
if (!_passives.isEmpty())
|
||||||
{
|
{
|
||||||
_passives.forEach(this::remove);
|
_passives.forEach(this::remove);
|
||||||
// Update stats, effect flags and icons.
|
// Update stats, effect flags and icons.
|
||||||
@@ -392,7 +380,7 @@ public final class CharEffectList
|
|||||||
*/
|
*/
|
||||||
public void stopAllOptions(boolean update, boolean broadcast)
|
public void stopAllOptions(boolean update, boolean broadcast)
|
||||||
{
|
{
|
||||||
if (_options != null)
|
if (!_options.isEmpty())
|
||||||
{
|
{
|
||||||
_options.forEach(this::remove);
|
_options.forEach(this::remove);
|
||||||
// Update stats, effect flags and icons.
|
// Update stats, effect flags and icons.
|
||||||
@@ -490,7 +478,7 @@ public final class CharEffectList
|
|||||||
*/
|
*/
|
||||||
public void stopEffects(Predicate<BuffInfo> filter, boolean update, boolean broadcast)
|
public void stopEffects(Predicate<BuffInfo> filter, boolean update, boolean broadcast)
|
||||||
{
|
{
|
||||||
if (_actives != null)
|
if (!_actives.isEmpty())
|
||||||
{
|
{
|
||||||
_actives.stream().filter(filter).forEach(this::remove);
|
_actives.stream().filter(filter).forEach(this::remove);
|
||||||
|
|
||||||
@@ -678,6 +666,10 @@ public final class CharEffectList
|
|||||||
{
|
{
|
||||||
// Remove active effect.
|
// Remove active effect.
|
||||||
removeActive(info, removed);
|
removeActive(info, removed);
|
||||||
|
if (_owner.isNpc()) // Fix for all NPC debuff animations removed.
|
||||||
|
{
|
||||||
|
updateEffectList(broadcast);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update stats, effect flags and icons.
|
// Update stats, effect flags and icons.
|
||||||
@@ -693,7 +685,7 @@ public final class CharEffectList
|
|||||||
*/
|
*/
|
||||||
private synchronized void removeActive(BuffInfo info, boolean removed)
|
private synchronized void removeActive(BuffInfo info, boolean removed)
|
||||||
{
|
{
|
||||||
if (_actives != null)
|
if (!_actives.isEmpty())
|
||||||
{
|
{
|
||||||
// Removes the buff from the given effect list.
|
// Removes the buff from the given effect list.
|
||||||
_actives.remove(info);
|
_actives.remove(info);
|
||||||
@@ -716,7 +708,7 @@ public final class CharEffectList
|
|||||||
|
|
||||||
private void removePassive(BuffInfo info, boolean removed)
|
private void removePassive(BuffInfo info, boolean removed)
|
||||||
{
|
{
|
||||||
if (_passives != null)
|
if (!_passives.isEmpty())
|
||||||
{
|
{
|
||||||
_passives.remove(info);
|
_passives.remove(info);
|
||||||
info.stopAllEffects(removed);
|
info.stopAllEffects(removed);
|
||||||
@@ -725,7 +717,7 @@ public final class CharEffectList
|
|||||||
|
|
||||||
private void removeOption(BuffInfo info, boolean removed)
|
private void removeOption(BuffInfo info, boolean removed)
|
||||||
{
|
{
|
||||||
if (_options != null)
|
if (!_options.isEmpty())
|
||||||
{
|
{
|
||||||
_options.remove(info);
|
_options.remove(info);
|
||||||
info.stopAllEffects(removed);
|
info.stopAllEffects(removed);
|
||||||
@@ -821,12 +813,6 @@ public final class CharEffectList
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize
|
|
||||||
if (_actives == null)
|
|
||||||
{
|
|
||||||
_actives = new ConcurrentLinkedQueue<>();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Manage effect stacking.
|
// Manage effect stacking.
|
||||||
if (hasAbnormalType(skill.getAbnormalType()))
|
if (hasAbnormalType(skill.getAbnormalType()))
|
||||||
{
|
{
|
||||||
@@ -857,7 +843,7 @@ public final class CharEffectList
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Remove effect that gets overriden.
|
// Remove effect that gets overridden.
|
||||||
remove(existingInfo);
|
remove(existingInfo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -865,7 +851,7 @@ public final class CharEffectList
|
|||||||
{
|
{
|
||||||
info.setInUse(false);
|
info.setInUse(false);
|
||||||
}
|
}
|
||||||
else // The effect we try to add should be overriden.
|
else // The effect we try to add should be overridden.
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -918,18 +904,6 @@ public final class CharEffectList
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize
|
|
||||||
if (_passives == null)
|
|
||||||
{
|
|
||||||
synchronized (this)
|
|
||||||
{
|
|
||||||
if (_passives == null)
|
|
||||||
{
|
|
||||||
_passives = ConcurrentHashMap.newKeySet();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove previous passives of this id.
|
// Remove previous passives of this id.
|
||||||
_passives.stream().filter(Objects::nonNull).filter(b -> b.getSkill().getId() == skill.getId()).forEach(b ->
|
_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)
|
if (info.getOption() != null)
|
||||||
{
|
{
|
||||||
// Initialize
|
|
||||||
if (_options == null)
|
|
||||||
{
|
|
||||||
synchronized (this)
|
|
||||||
{
|
|
||||||
if (_options == null)
|
|
||||||
{
|
|
||||||
_options = ConcurrentHashMap.newKeySet();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove previous options of this id.
|
// Remove previous options of this id.
|
||||||
_options.stream().filter(Objects::nonNull).filter(b -> b.getOption().getId() == info.getOption().getId()).forEach(b ->
|
_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<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();
|
final Optional<ExOlympiadSpelledInfo> os = (player.isInOlympiadMode() && player.isOlympiadStart()) ? Optional.of(new ExOlympiadSpelledInfo(player)) : Optional.empty();
|
||||||
|
|
||||||
if (_actives != null)
|
if (!_actives.isEmpty())
|
||||||
{
|
{
|
||||||
//@formatter:off
|
//@formatter:off
|
||||||
_actives.stream()
|
_actives.stream()
|
||||||
@@ -1109,42 +1071,47 @@ public final class CharEffectList
|
|||||||
final Set<BuffInfo> unhideBuffs = new HashSet<>();
|
final Set<BuffInfo> unhideBuffs = new HashSet<>();
|
||||||
|
|
||||||
// Recalculate new flags
|
// Recalculate new flags
|
||||||
if (_actives != null)
|
for (BuffInfo info : _actives)
|
||||||
{
|
{
|
||||||
for (BuffInfo info : _actives)
|
if (info != null)
|
||||||
{
|
{
|
||||||
if (info != null)
|
final Skill skill = info.getSkill();
|
||||||
|
|
||||||
|
// Handle hidden buffs. Check if there was such abnormal before so we can continue.
|
||||||
|
if ((_hiddenBuffs.get() > 0) && _stackedEffects.contains(skill.getAbnormalType()))
|
||||||
{
|
{
|
||||||
final Skill skill = info.getSkill();
|
// If incoming buff isnt hidden, remove any hidden buffs with its abnormal type.
|
||||||
|
if (info.isInUse())
|
||||||
// Handle hidden buffs. Check if there was such abnormal before so we can continue.
|
|
||||||
if ((_hiddenBuffs.get() > 0) && _stackedEffects.contains(skill.getAbnormalType()))
|
|
||||||
{
|
{
|
||||||
// If incoming buff isnt hidden, remove any hidden buffs with its abnormal type.
|
unhideBuffs.removeIf(b -> b.isAbnormalType(skill.getAbnormalType()));
|
||||||
if (info.isInUse())
|
|
||||||
{
|
|
||||||
unhideBuffs.removeIf(b -> b.isAbnormalType(skill.getAbnormalType()));
|
|
||||||
}
|
|
||||||
// If this incoming buff is hidden and its first of its abnormal, or it removes any previous hidden buff with the same or lower abnormal level and add this instead.
|
|
||||||
else if (!abnormalTypeFlags.contains(skill.getAbnormalType()) || unhideBuffs.removeIf(b -> (b.isAbnormalType(skill.getAbnormalType())) && (b.getSkill().getAbnormalLvl() <= skill.getAbnormalLvl())))
|
|
||||||
{
|
|
||||||
unhideBuffs.add(info);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
// If this incoming buff is hidden and its first of its abnormal, or it removes any previous hidden buff with the same or lower abnormal level and add this instead.
|
||||||
// Add the EffectType flag.
|
else if (!abnormalTypeFlags.contains(skill.getAbnormalType()) || unhideBuffs.removeIf(b -> (b.isAbnormalType(skill.getAbnormalType())) && (b.getSkill().getAbnormalLvl() <= skill.getAbnormalLvl())))
|
||||||
for (AbstractEffect e : info.getEffects())
|
|
||||||
{
|
{
|
||||||
flags |= e.getEffectFlags();
|
unhideBuffs.add(info);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Add the AbnormalType flag.
|
// Add the EffectType flag.
|
||||||
abnormalTypeFlags.add(skill.getAbnormalType());
|
for (AbstractEffect e : info.getEffects())
|
||||||
|
{
|
||||||
|
flags |= e.getEffectFlags();
|
||||||
|
}
|
||||||
|
|
||||||
// Add AbnormalVisualEffect flag.
|
// Add the AbnormalType flag.
|
||||||
if (skill.hasAbnormalVisualEffects())
|
abnormalTypeFlags.add(skill.getAbnormalType());
|
||||||
|
|
||||||
|
// Add AbnormalVisualEffect flag.
|
||||||
|
if (skill.hasAbnormalVisualEffects())
|
||||||
|
{
|
||||||
|
for (AbnormalVisualEffect ave : skill.getAbnormalVisualEffects())
|
||||||
{
|
{
|
||||||
abnormalVisualEffectFlags.addAll(skill.getAbnormalVisualEffects());
|
abnormalVisualEffectFlags.add(ave);
|
||||||
|
_abnormalVisualEffects.add(ave);
|
||||||
|
}
|
||||||
|
if (broadcast)
|
||||||
|
{
|
||||||
|
_owner.updateAbnormalVisualEffects();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1167,7 +1134,7 @@ public final class CharEffectList
|
|||||||
if (broadcast)
|
if (broadcast)
|
||||||
{
|
{
|
||||||
// Check if there is change in AbnormalVisualEffect
|
// Check if there is change in AbnormalVisualEffect
|
||||||
if ((abnormalVisualEffectFlags.size() != _abnormalVisualEffects.size()) || !abnormalVisualEffectFlags.containsAll(_abnormalVisualEffects))
|
if (!abnormalVisualEffectFlags.containsAll(_abnormalVisualEffects))
|
||||||
{
|
{
|
||||||
_abnormalVisualEffects = abnormalVisualEffectFlags;
|
_abnormalVisualEffects = abnormalVisualEffectFlags;
|
||||||
_owner.updateAbnormalVisualEffects();
|
_owner.updateAbnormalVisualEffects();
|
||||||
|
|||||||
@@ -77,7 +77,6 @@ public class DoppelgangerInstance extends L2Npc
|
|||||||
info.setAbnormalTime(summonerInfo.getAbnormalTime());
|
info.setAbnormalTime(summonerInfo.getAbnormalTime());
|
||||||
getEffectList().add(info);
|
getEffectList().add(info);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -776,7 +776,7 @@ public class CharStat
|
|||||||
final CharEffectList effectList = _activeChar.getEffectList();
|
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> 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> 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
|
// Call pump to each effect
|
||||||
//@formatter:off
|
//@formatter:off
|
||||||
|
|||||||
@@ -389,10 +389,10 @@ public final class BuffInfo
|
|||||||
for (AbstractEffect effect : _effects)
|
for (AbstractEffect effect : _effects)
|
||||||
{
|
{
|
||||||
// Instant effects shouldn't call onExit(..).
|
// Instant effects shouldn't call onExit(..).
|
||||||
if (!effect.isInstant())
|
// if (!effect.isInstant())
|
||||||
{
|
// {
|
||||||
effect.onExit(_effector, _effected, _skill);
|
effect.onExit(_effector, _effected, _skill);
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set the proper system message.
|
// Set the proper system message.
|
||||||
|
|||||||
@@ -21,17 +21,11 @@ import java.util.List;
|
|||||||
|
|
||||||
import com.l2jmobius.commons.network.PacketWriter;
|
import com.l2jmobius.commons.network.PacketWriter;
|
||||||
import com.l2jmobius.gameserver.model.skills.BuffInfo;
|
import com.l2jmobius.gameserver.model.skills.BuffInfo;
|
||||||
import com.l2jmobius.gameserver.model.skills.Skill;
|
|
||||||
import com.l2jmobius.gameserver.network.OutgoingPackets;
|
import com.l2jmobius.gameserver.network.OutgoingPackets;
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Mobius
|
|
||||||
* @version Classic 2.0
|
|
||||||
*/
|
|
||||||
public class AbnormalStatusUpdate implements IClientOutgoingPacket
|
public class AbnormalStatusUpdate implements IClientOutgoingPacket
|
||||||
{
|
{
|
||||||
private final List<BuffInfo> _effects = new ArrayList<>();
|
private final List<BuffInfo> _effects = new ArrayList<>();
|
||||||
private final List<Skill> _effects2 = new ArrayList<>();
|
|
||||||
|
|
||||||
public void addSkill(BuffInfo info)
|
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
|
@Override
|
||||||
public boolean write(PacketWriter packet)
|
public boolean write(PacketWriter packet)
|
||||||
{
|
{
|
||||||
OutgoingPackets.ABNORMAL_STATUS_UPDATE.writeId(packet);
|
OutgoingPackets.ABNORMAL_STATUS_UPDATE.writeId(packet);
|
||||||
|
|
||||||
packet.writeH(_effects.size() + _effects2.size());
|
packet.writeH(_effects.size());
|
||||||
for (BuffInfo info : _effects)
|
for (BuffInfo info : _effects)
|
||||||
{
|
{
|
||||||
if ((info != null) && info.isInUse())
|
if ((info != null) && info.isInUse())
|
||||||
{
|
{
|
||||||
packet.writeD(info.getSkill().getDisplayId());
|
packet.writeD(info.getSkill().getDisplayId());
|
||||||
packet.writeH(info.getSkill().getDisplayLevel());
|
packet.writeH(info.getSkill().getDisplayLevel());
|
||||||
packet.writeD(0x00);
|
// packet.writeH(info.getSkill().getSubLevel());
|
||||||
packet.writeH(info.getSkill().isAura() ? -1 : info.getTime());
|
packet.writeD(info.getSkill().getAbnormalType().getClientId());
|
||||||
}
|
writeOptionalD(packet, 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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -16,8 +16,8 @@
|
|||||||
*/
|
*/
|
||||||
package com.l2jmobius.gameserver.network.serverpackets;
|
package com.l2jmobius.gameserver.network.serverpackets;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import com.l2jmobius.commons.network.PacketWriter;
|
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.model.skills.BuffInfo;
|
||||||
import com.l2jmobius.gameserver.network.OutgoingPackets;
|
import com.l2jmobius.gameserver.network.OutgoingPackets;
|
||||||
|
|
||||||
/**
|
|
||||||
* @author proGenitor <br>
|
|
||||||
* Experimental packet compatible for L2Classic 2.0.
|
|
||||||
*/
|
|
||||||
public class ExAbnormalStatusUpdateFromTarget implements IClientOutgoingPacket
|
public class ExAbnormalStatusUpdateFromTarget implements IClientOutgoingPacket
|
||||||
{
|
{
|
||||||
private final L2Character _character;
|
private final L2Character _character;
|
||||||
private List<Effect> _effects = new ArrayList<>();
|
private final List<BuffInfo> _effects;
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public ExAbnormalStatusUpdateFromTarget(L2Character character)
|
public ExAbnormalStatusUpdateFromTarget(L2Character character)
|
||||||
{
|
{
|
||||||
@@ -61,7 +36,9 @@ public class ExAbnormalStatusUpdateFromTarget implements IClientOutgoingPacket
|
|||||||
_character = character;
|
_character = character;
|
||||||
_effects = character.getEffectList().getEffects()
|
_effects = character.getEffectList().getEffects()
|
||||||
.stream()
|
.stream()
|
||||||
.map(Effect::new)
|
.filter(Objects::nonNull)
|
||||||
|
.filter(BuffInfo::isInUse)
|
||||||
|
.filter(b -> !b.getSkill().isToggle())
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
//@formatter:on
|
//@formatter:on
|
||||||
}
|
}
|
||||||
@@ -74,14 +51,14 @@ public class ExAbnormalStatusUpdateFromTarget implements IClientOutgoingPacket
|
|||||||
packet.writeD(_character.getObjectId());
|
packet.writeD(_character.getObjectId());
|
||||||
packet.writeH(_effects.size());
|
packet.writeH(_effects.size());
|
||||||
|
|
||||||
for (Effect info : _effects)
|
for (BuffInfo info : _effects)
|
||||||
{
|
{
|
||||||
packet.writeD(info._skillId);
|
packet.writeD(info.getSkill().getDisplayId());
|
||||||
packet.writeH(info._level);
|
packet.writeH(info.getSkill().getDisplayLevel());
|
||||||
packet.writeH(info._subLevel);
|
// packet.writeH(info.getSkill().getSubLevel());
|
||||||
packet.writeH(info._abnormalType);
|
packet.writeH(info.getSkill().getAbnormalType().getClientId());
|
||||||
writeOptionalD(packet, info._duration);
|
writeOptionalD(packet, info.getSkill().isAura() ? -1 : info.getTime());
|
||||||
packet.writeD(info._caster);
|
packet.writeD(info.getEffectorObjectId());
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,6 +16,8 @@
|
|||||||
*/
|
*/
|
||||||
package handlers.effecthandlers;
|
package handlers.effecthandlers;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
|
||||||
import com.l2jmobius.gameserver.model.L2Object;
|
import com.l2jmobius.gameserver.model.L2Object;
|
||||||
import com.l2jmobius.gameserver.model.L2World;
|
import com.l2jmobius.gameserver.model.L2World;
|
||||||
import com.l2jmobius.gameserver.model.StatsSet;
|
import com.l2jmobius.gameserver.model.StatsSet;
|
||||||
@@ -38,6 +40,19 @@ public final class CallSkillOnActionTime extends AbstractEffect
|
|||||||
setTicks(params.getInt("ticks"));
|
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
|
@Override
|
||||||
public boolean onActionTime(L2Character effector, L2Character effected, Skill skill)
|
public boolean onActionTime(L2Character effector, L2Character effected, Skill skill)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -136,6 +136,5 @@ public final class Disarmor extends AbstractEffect
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
super.onExit(effector, effected, skill);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -84,6 +84,5 @@ public final class DoubleCast extends AbstractEffect
|
|||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
super.onExit(effector, effected, skill);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -65,15 +65,15 @@ public final class CharEffectList
|
|||||||
{
|
{
|
||||||
private static final Logger LOGGER = Logger.getLogger(CharEffectList.class.getName());
|
private static final Logger LOGGER = Logger.getLogger(CharEffectList.class.getName());
|
||||||
/** Queue containing all effects from buffs for this effect list. */
|
/** 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. */
|
/** 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. */
|
/** 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}. */
|
/** Map containing the all stacked effect in progress for each {@code AbnormalType}. */
|
||||||
private volatile Set<AbnormalType> _stackedEffects = EnumSet.noneOf(AbnormalType.class);
|
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. */
|
/** 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. */
|
/** Set containing all abnormal visual effects this creature currently displays. */
|
||||||
private volatile Set<AbnormalVisualEffect> _abnormalVisualEffects = EnumSet.noneOf(AbnormalVisualEffect.class);
|
private volatile Set<AbnormalVisualEffect> _abnormalVisualEffects = EnumSet.noneOf(AbnormalVisualEffect.class);
|
||||||
/** Short buff skill ID. */
|
/** Short buff skill ID. */
|
||||||
@@ -110,7 +110,7 @@ public final class CharEffectList
|
|||||||
*/
|
*/
|
||||||
public Set<BuffInfo> getPassives()
|
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()
|
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()
|
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()
|
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()
|
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)
|
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)
|
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)
|
public void addBlockedAbnormalTypes(Set<AbnormalType> blockedAbnormalTypes)
|
||||||
{
|
{
|
||||||
// Initialize
|
|
||||||
if (_blockedAbnormalTypes == null)
|
|
||||||
{
|
|
||||||
synchronized (this)
|
|
||||||
{
|
|
||||||
if (_blockedAbnormalTypes == null)
|
|
||||||
{
|
|
||||||
_blockedAbnormalTypes = EnumSet.copyOf(blockedAbnormalTypes);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_blockedAbnormalTypes.addAll(blockedAbnormalTypes);
|
_blockedAbnormalTypes.addAll(blockedAbnormalTypes);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -238,7 +226,7 @@ public final class CharEffectList
|
|||||||
*/
|
*/
|
||||||
public boolean removeBlockedAbnormalTypes(Set<AbnormalType> blockedBuffSlots)
|
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()
|
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()
|
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)
|
public void stopAllPassives(boolean update, boolean broadcast)
|
||||||
{
|
{
|
||||||
if (_passives != null)
|
if (!_passives.isEmpty())
|
||||||
{
|
{
|
||||||
_passives.forEach(this::remove);
|
_passives.forEach(this::remove);
|
||||||
// Update stats, effect flags and icons.
|
// Update stats, effect flags and icons.
|
||||||
@@ -392,7 +380,7 @@ public final class CharEffectList
|
|||||||
*/
|
*/
|
||||||
public void stopAllOptions(boolean update, boolean broadcast)
|
public void stopAllOptions(boolean update, boolean broadcast)
|
||||||
{
|
{
|
||||||
if (_options != null)
|
if (!_options.isEmpty())
|
||||||
{
|
{
|
||||||
_options.forEach(this::remove);
|
_options.forEach(this::remove);
|
||||||
// Update stats, effect flags and icons.
|
// Update stats, effect flags and icons.
|
||||||
@@ -490,7 +478,7 @@ public final class CharEffectList
|
|||||||
*/
|
*/
|
||||||
public void stopEffects(Predicate<BuffInfo> filter, boolean update, boolean broadcast)
|
public void stopEffects(Predicate<BuffInfo> filter, boolean update, boolean broadcast)
|
||||||
{
|
{
|
||||||
if (_actives != null)
|
if (!_actives.isEmpty())
|
||||||
{
|
{
|
||||||
_actives.stream().filter(filter).forEach(this::remove);
|
_actives.stream().filter(filter).forEach(this::remove);
|
||||||
|
|
||||||
@@ -678,6 +666,10 @@ public final class CharEffectList
|
|||||||
{
|
{
|
||||||
// Remove active effect.
|
// Remove active effect.
|
||||||
removeActive(info, removed);
|
removeActive(info, removed);
|
||||||
|
if (_owner.isNpc()) // Fix for all NPC debuff animations removed.
|
||||||
|
{
|
||||||
|
updateEffectList(broadcast);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update stats, effect flags and icons.
|
// Update stats, effect flags and icons.
|
||||||
@@ -693,7 +685,7 @@ public final class CharEffectList
|
|||||||
*/
|
*/
|
||||||
private synchronized void removeActive(BuffInfo info, boolean removed)
|
private synchronized void removeActive(BuffInfo info, boolean removed)
|
||||||
{
|
{
|
||||||
if (_actives != null)
|
if (!_actives.isEmpty())
|
||||||
{
|
{
|
||||||
// Removes the buff from the given effect list.
|
// Removes the buff from the given effect list.
|
||||||
_actives.remove(info);
|
_actives.remove(info);
|
||||||
@@ -716,7 +708,7 @@ public final class CharEffectList
|
|||||||
|
|
||||||
private void removePassive(BuffInfo info, boolean removed)
|
private void removePassive(BuffInfo info, boolean removed)
|
||||||
{
|
{
|
||||||
if (_passives != null)
|
if (!_passives.isEmpty())
|
||||||
{
|
{
|
||||||
_passives.remove(info);
|
_passives.remove(info);
|
||||||
info.stopAllEffects(removed);
|
info.stopAllEffects(removed);
|
||||||
@@ -725,7 +717,7 @@ public final class CharEffectList
|
|||||||
|
|
||||||
private void removeOption(BuffInfo info, boolean removed)
|
private void removeOption(BuffInfo info, boolean removed)
|
||||||
{
|
{
|
||||||
if (_options != null)
|
if (!_options.isEmpty())
|
||||||
{
|
{
|
||||||
_options.remove(info);
|
_options.remove(info);
|
||||||
info.stopAllEffects(removed);
|
info.stopAllEffects(removed);
|
||||||
@@ -821,12 +813,6 @@ public final class CharEffectList
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize
|
|
||||||
if (_actives == null)
|
|
||||||
{
|
|
||||||
_actives = new ConcurrentLinkedQueue<>();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Manage effect stacking.
|
// Manage effect stacking.
|
||||||
if (hasAbnormalType(skill.getAbnormalType()))
|
if (hasAbnormalType(skill.getAbnormalType()))
|
||||||
{
|
{
|
||||||
@@ -857,7 +843,7 @@ public final class CharEffectList
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Remove effect that gets overriden.
|
// Remove effect that gets overridden.
|
||||||
remove(existingInfo);
|
remove(existingInfo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -865,7 +851,7 @@ public final class CharEffectList
|
|||||||
{
|
{
|
||||||
info.setInUse(false);
|
info.setInUse(false);
|
||||||
}
|
}
|
||||||
else // The effect we try to add should be overriden.
|
else // The effect we try to add should be overridden.
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -918,18 +904,6 @@ public final class CharEffectList
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize
|
|
||||||
if (_passives == null)
|
|
||||||
{
|
|
||||||
synchronized (this)
|
|
||||||
{
|
|
||||||
if (_passives == null)
|
|
||||||
{
|
|
||||||
_passives = ConcurrentHashMap.newKeySet();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove previous passives of this id.
|
// Remove previous passives of this id.
|
||||||
_passives.stream().filter(Objects::nonNull).filter(b -> b.getSkill().getId() == skill.getId()).forEach(b ->
|
_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)
|
if (info.getOption() != null)
|
||||||
{
|
{
|
||||||
// Initialize
|
|
||||||
if (_options == null)
|
|
||||||
{
|
|
||||||
synchronized (this)
|
|
||||||
{
|
|
||||||
if (_options == null)
|
|
||||||
{
|
|
||||||
_options = ConcurrentHashMap.newKeySet();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove previous options of this id.
|
// Remove previous options of this id.
|
||||||
_options.stream().filter(Objects::nonNull).filter(b -> b.getOption().getId() == info.getOption().getId()).forEach(b ->
|
_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<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();
|
final Optional<ExOlympiadSpelledInfo> os = (player.isInOlympiadMode() && player.isOlympiadStart()) ? Optional.of(new ExOlympiadSpelledInfo(player)) : Optional.empty();
|
||||||
|
|
||||||
if (_actives != null)
|
if (!_actives.isEmpty())
|
||||||
{
|
{
|
||||||
//@formatter:off
|
//@formatter:off
|
||||||
_actives.stream()
|
_actives.stream()
|
||||||
@@ -1109,42 +1071,47 @@ public final class CharEffectList
|
|||||||
final Set<BuffInfo> unhideBuffs = new HashSet<>();
|
final Set<BuffInfo> unhideBuffs = new HashSet<>();
|
||||||
|
|
||||||
// Recalculate new flags
|
// Recalculate new flags
|
||||||
if (_actives != null)
|
for (BuffInfo info : _actives)
|
||||||
{
|
{
|
||||||
for (BuffInfo info : _actives)
|
if (info != null)
|
||||||
{
|
{
|
||||||
if (info != null)
|
final Skill skill = info.getSkill();
|
||||||
|
|
||||||
|
// Handle hidden buffs. Check if there was such abnormal before so we can continue.
|
||||||
|
if ((_hiddenBuffs.get() > 0) && _stackedEffects.contains(skill.getAbnormalType()))
|
||||||
{
|
{
|
||||||
final Skill skill = info.getSkill();
|
// If incoming buff isnt hidden, remove any hidden buffs with its abnormal type.
|
||||||
|
if (info.isInUse())
|
||||||
// Handle hidden buffs. Check if there was such abnormal before so we can continue.
|
|
||||||
if ((_hiddenBuffs.get() > 0) && _stackedEffects.contains(skill.getAbnormalType()))
|
|
||||||
{
|
{
|
||||||
// If incoming buff isnt hidden, remove any hidden buffs with its abnormal type.
|
unhideBuffs.removeIf(b -> b.isAbnormalType(skill.getAbnormalType()));
|
||||||
if (info.isInUse())
|
|
||||||
{
|
|
||||||
unhideBuffs.removeIf(b -> b.isAbnormalType(skill.getAbnormalType()));
|
|
||||||
}
|
|
||||||
// If this incoming buff is hidden and its first of its abnormal, or it removes any previous hidden buff with the same or lower abnormal level and add this instead.
|
|
||||||
else if (!abnormalTypeFlags.contains(skill.getAbnormalType()) || unhideBuffs.removeIf(b -> (b.isAbnormalType(skill.getAbnormalType())) && (b.getSkill().getAbnormalLvl() <= skill.getAbnormalLvl())))
|
|
||||||
{
|
|
||||||
unhideBuffs.add(info);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
// If this incoming buff is hidden and its first of its abnormal, or it removes any previous hidden buff with the same or lower abnormal level and add this instead.
|
||||||
// Add the EffectType flag.
|
else if (!abnormalTypeFlags.contains(skill.getAbnormalType()) || unhideBuffs.removeIf(b -> (b.isAbnormalType(skill.getAbnormalType())) && (b.getSkill().getAbnormalLvl() <= skill.getAbnormalLvl())))
|
||||||
for (AbstractEffect e : info.getEffects())
|
|
||||||
{
|
{
|
||||||
flags |= e.getEffectFlags();
|
unhideBuffs.add(info);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Add the AbnormalType flag.
|
// Add the EffectType flag.
|
||||||
abnormalTypeFlags.add(skill.getAbnormalType());
|
for (AbstractEffect e : info.getEffects())
|
||||||
|
{
|
||||||
|
flags |= e.getEffectFlags();
|
||||||
|
}
|
||||||
|
|
||||||
// Add AbnormalVisualEffect flag.
|
// Add the AbnormalType flag.
|
||||||
if (skill.hasAbnormalVisualEffects())
|
abnormalTypeFlags.add(skill.getAbnormalType());
|
||||||
|
|
||||||
|
// Add AbnormalVisualEffect flag.
|
||||||
|
if (skill.hasAbnormalVisualEffects())
|
||||||
|
{
|
||||||
|
for (AbnormalVisualEffect ave : skill.getAbnormalVisualEffects())
|
||||||
{
|
{
|
||||||
abnormalVisualEffectFlags.addAll(skill.getAbnormalVisualEffects());
|
abnormalVisualEffectFlags.add(ave);
|
||||||
|
_abnormalVisualEffects.add(ave);
|
||||||
|
}
|
||||||
|
if (broadcast)
|
||||||
|
{
|
||||||
|
_owner.updateAbnormalVisualEffects();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1167,7 +1134,7 @@ public final class CharEffectList
|
|||||||
if (broadcast)
|
if (broadcast)
|
||||||
{
|
{
|
||||||
// Check if there is change in AbnormalVisualEffect
|
// Check if there is change in AbnormalVisualEffect
|
||||||
if ((abnormalVisualEffectFlags.size() != _abnormalVisualEffects.size()) || !abnormalVisualEffectFlags.containsAll(_abnormalVisualEffects))
|
if (!abnormalVisualEffectFlags.containsAll(_abnormalVisualEffects))
|
||||||
{
|
{
|
||||||
_abnormalVisualEffects = abnormalVisualEffectFlags;
|
_abnormalVisualEffects = abnormalVisualEffectFlags;
|
||||||
_owner.updateAbnormalVisualEffects();
|
_owner.updateAbnormalVisualEffects();
|
||||||
|
|||||||
@@ -77,7 +77,6 @@ public class DoppelgangerInstance extends L2Npc
|
|||||||
info.setAbnormalTime(summonerInfo.getAbnormalTime());
|
info.setAbnormalTime(summonerInfo.getAbnormalTime());
|
||||||
getEffectList().add(info);
|
getEffectList().add(info);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -776,7 +776,7 @@ public class CharStat
|
|||||||
final CharEffectList effectList = _activeChar.getEffectList();
|
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> 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> 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
|
// Call pump to each effect
|
||||||
//@formatter:off
|
//@formatter:off
|
||||||
|
|||||||
@@ -389,10 +389,10 @@ public final class BuffInfo
|
|||||||
for (AbstractEffect effect : _effects)
|
for (AbstractEffect effect : _effects)
|
||||||
{
|
{
|
||||||
// Instant effects shouldn't call onExit(..).
|
// Instant effects shouldn't call onExit(..).
|
||||||
if (!effect.isInstant())
|
// if (!effect.isInstant())
|
||||||
{
|
// {
|
||||||
effect.onExit(_effector, _effected, _skill);
|
effect.onExit(_effector, _effected, _skill);
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set the proper system message.
|
// Set the proper system message.
|
||||||
|
|||||||
@@ -21,17 +21,11 @@ import java.util.List;
|
|||||||
|
|
||||||
import com.l2jmobius.commons.network.PacketWriter;
|
import com.l2jmobius.commons.network.PacketWriter;
|
||||||
import com.l2jmobius.gameserver.model.skills.BuffInfo;
|
import com.l2jmobius.gameserver.model.skills.BuffInfo;
|
||||||
import com.l2jmobius.gameserver.model.skills.Skill;
|
|
||||||
import com.l2jmobius.gameserver.network.OutgoingPackets;
|
import com.l2jmobius.gameserver.network.OutgoingPackets;
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Mobius
|
|
||||||
* @version Classic 2.0
|
|
||||||
*/
|
|
||||||
public class AbnormalStatusUpdate implements IClientOutgoingPacket
|
public class AbnormalStatusUpdate implements IClientOutgoingPacket
|
||||||
{
|
{
|
||||||
private final List<BuffInfo> _effects = new ArrayList<>();
|
private final List<BuffInfo> _effects = new ArrayList<>();
|
||||||
private final List<Skill> _effects2 = new ArrayList<>();
|
|
||||||
|
|
||||||
public void addSkill(BuffInfo info)
|
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
|
@Override
|
||||||
public boolean write(PacketWriter packet)
|
public boolean write(PacketWriter packet)
|
||||||
{
|
{
|
||||||
OutgoingPackets.ABNORMAL_STATUS_UPDATE.writeId(packet);
|
OutgoingPackets.ABNORMAL_STATUS_UPDATE.writeId(packet);
|
||||||
|
|
||||||
packet.writeH(_effects.size() + _effects2.size());
|
packet.writeH(_effects.size());
|
||||||
for (BuffInfo info : _effects)
|
for (BuffInfo info : _effects)
|
||||||
{
|
{
|
||||||
if ((info != null) && info.isInUse())
|
if ((info != null) && info.isInUse())
|
||||||
{
|
{
|
||||||
packet.writeD(info.getSkill().getDisplayId());
|
packet.writeD(info.getSkill().getDisplayId());
|
||||||
packet.writeH(info.getSkill().getDisplayLevel());
|
packet.writeH(info.getSkill().getDisplayLevel());
|
||||||
packet.writeD(0x00);
|
// packet.writeH(info.getSkill().getSubLevel());
|
||||||
packet.writeH(info.getSkill().isAura() ? -1 : info.getTime());
|
packet.writeD(info.getSkill().getAbnormalType().getClientId());
|
||||||
}
|
writeOptionalD(packet, 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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -16,8 +16,8 @@
|
|||||||
*/
|
*/
|
||||||
package com.l2jmobius.gameserver.network.serverpackets;
|
package com.l2jmobius.gameserver.network.serverpackets;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import com.l2jmobius.commons.network.PacketWriter;
|
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.model.skills.BuffInfo;
|
||||||
import com.l2jmobius.gameserver.network.OutgoingPackets;
|
import com.l2jmobius.gameserver.network.OutgoingPackets;
|
||||||
|
|
||||||
/**
|
|
||||||
* @author proGenitor <br>
|
|
||||||
* Experimental packet compatible for L2Classic 2.0.
|
|
||||||
*/
|
|
||||||
public class ExAbnormalStatusUpdateFromTarget implements IClientOutgoingPacket
|
public class ExAbnormalStatusUpdateFromTarget implements IClientOutgoingPacket
|
||||||
{
|
{
|
||||||
private final L2Character _character;
|
private final L2Character _character;
|
||||||
private List<Effect> _effects = new ArrayList<>();
|
private final List<BuffInfo> _effects;
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public ExAbnormalStatusUpdateFromTarget(L2Character character)
|
public ExAbnormalStatusUpdateFromTarget(L2Character character)
|
||||||
{
|
{
|
||||||
@@ -61,7 +36,9 @@ public class ExAbnormalStatusUpdateFromTarget implements IClientOutgoingPacket
|
|||||||
_character = character;
|
_character = character;
|
||||||
_effects = character.getEffectList().getEffects()
|
_effects = character.getEffectList().getEffects()
|
||||||
.stream()
|
.stream()
|
||||||
.map(Effect::new)
|
.filter(Objects::nonNull)
|
||||||
|
.filter(BuffInfo::isInUse)
|
||||||
|
.filter(b -> !b.getSkill().isToggle())
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
//@formatter:on
|
//@formatter:on
|
||||||
}
|
}
|
||||||
@@ -74,14 +51,14 @@ public class ExAbnormalStatusUpdateFromTarget implements IClientOutgoingPacket
|
|||||||
packet.writeD(_character.getObjectId());
|
packet.writeD(_character.getObjectId());
|
||||||
packet.writeH(_effects.size());
|
packet.writeH(_effects.size());
|
||||||
|
|
||||||
for (Effect info : _effects)
|
for (BuffInfo info : _effects)
|
||||||
{
|
{
|
||||||
packet.writeD(info._skillId);
|
packet.writeD(info.getSkill().getDisplayId());
|
||||||
packet.writeH(info._level);
|
packet.writeH(info.getSkill().getDisplayLevel());
|
||||||
packet.writeH(info._subLevel);
|
// packet.writeH(info.getSkill().getSubLevel());
|
||||||
packet.writeH(info._abnormalType);
|
packet.writeH(info.getSkill().getAbnormalType().getClientId());
|
||||||
writeOptionalD(packet, info._duration);
|
writeOptionalD(packet, info.getSkill().isAura() ? -1 : info.getTime());
|
||||||
packet.writeD(info._caster);
|
packet.writeD(info.getEffectorObjectId());
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user