Use EnumSet instead or Arrays for traits.
Adapted from: L2jUnity free files.
This commit is contained in:
@@ -22,9 +22,7 @@ import java.util.Map.Entry;
|
|||||||
|
|
||||||
import org.l2jmobius.gameserver.model.StatsSet;
|
import org.l2jmobius.gameserver.model.StatsSet;
|
||||||
import org.l2jmobius.gameserver.model.actor.Creature;
|
import org.l2jmobius.gameserver.model.actor.Creature;
|
||||||
import org.l2jmobius.gameserver.model.actor.stat.CreatureStat;
|
|
||||||
import org.l2jmobius.gameserver.model.effects.AbstractEffect;
|
import org.l2jmobius.gameserver.model.effects.AbstractEffect;
|
||||||
import org.l2jmobius.gameserver.model.items.instance.ItemInstance;
|
|
||||||
import org.l2jmobius.gameserver.model.skills.Skill;
|
import org.l2jmobius.gameserver.model.skills.Skill;
|
||||||
import org.l2jmobius.gameserver.model.stats.TraitType;
|
import org.l2jmobius.gameserver.model.stats.TraitType;
|
||||||
|
|
||||||
@@ -51,35 +49,11 @@ public final class AttackTrait extends AbstractEffect
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onExit(Creature effector, Creature effected, Skill skill)
|
public void pump(Creature effected, Skill skill)
|
||||||
{
|
{
|
||||||
final CreatureStat charStat = effected.getStat();
|
for (Entry<TraitType, Float> trait : _attackTraits.entrySet())
|
||||||
synchronized (charStat.getAttackTraits())
|
|
||||||
{
|
{
|
||||||
for (Entry<TraitType, Float> trait : _attackTraits.entrySet())
|
effected.getStat().mergeAttackTrait(trait.getKey(), trait.getValue());
|
||||||
{
|
|
||||||
if (charStat.getAttackTraitsCount()[trait.getKey().ordinal()] == 0)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
charStat.getAttackTraits()[trait.getKey().ordinal()] /= trait.getValue();
|
|
||||||
charStat.getAttackTraitsCount()[trait.getKey().ordinal()]--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onStart(Creature effector, Creature effected, Skill skill, ItemInstance item)
|
|
||||||
{
|
|
||||||
final CreatureStat charStat = effected.getStat();
|
|
||||||
synchronized (charStat.getAttackTraits())
|
|
||||||
{
|
|
||||||
for (Entry<TraitType, Float> trait : _attackTraits.entrySet())
|
|
||||||
{
|
|
||||||
charStat.getAttackTraits()[trait.getKey().ordinal()] *= trait.getValue();
|
|
||||||
charStat.getAttackTraitsCount()[trait.getKey().ordinal()]++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,9 +22,7 @@ import java.util.Map.Entry;
|
|||||||
|
|
||||||
import org.l2jmobius.gameserver.model.StatsSet;
|
import org.l2jmobius.gameserver.model.StatsSet;
|
||||||
import org.l2jmobius.gameserver.model.actor.Creature;
|
import org.l2jmobius.gameserver.model.actor.Creature;
|
||||||
import org.l2jmobius.gameserver.model.actor.stat.CreatureStat;
|
|
||||||
import org.l2jmobius.gameserver.model.effects.AbstractEffect;
|
import org.l2jmobius.gameserver.model.effects.AbstractEffect;
|
||||||
import org.l2jmobius.gameserver.model.items.instance.ItemInstance;
|
|
||||||
import org.l2jmobius.gameserver.model.skills.Skill;
|
import org.l2jmobius.gameserver.model.skills.Skill;
|
||||||
import org.l2jmobius.gameserver.model.stats.TraitType;
|
import org.l2jmobius.gameserver.model.stats.TraitType;
|
||||||
|
|
||||||
@@ -46,75 +44,22 @@ public final class DefenceTrait extends AbstractEffect
|
|||||||
|
|
||||||
for (Entry<String, Object> param : params.getSet().entrySet())
|
for (Entry<String, Object> param : params.getSet().entrySet())
|
||||||
{
|
{
|
||||||
try
|
_defenceTraits.put(TraitType.valueOf(param.getKey()), (Float.parseFloat((String) param.getValue()) + 100) / 100);
|
||||||
{
|
|
||||||
final TraitType traitType = TraitType.valueOf(param.getKey());
|
|
||||||
final float value = Float.parseFloat((String) param.getValue());
|
|
||||||
if (value == 0)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
_defenceTraits.put(traitType, (value + 100) / 100);
|
|
||||||
}
|
|
||||||
catch (NumberFormatException e)
|
|
||||||
{
|
|
||||||
LOGGER.warning(getClass().getSimpleName() + ": value of " + param.getKey() + " must be float value " + param.getValue() + " found.");
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
LOGGER.warning(getClass().getSimpleName() + ": value of TraitType enum required but found: " + param.getKey());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onExit(Creature effector, Creature effected, Skill skill)
|
public void pump(Creature effected, Skill skill)
|
||||||
{
|
{
|
||||||
final CreatureStat charStat = effected.getStat();
|
for (Entry<TraitType, Float> trait : _defenceTraits.entrySet())
|
||||||
synchronized (charStat.getDefenceTraits())
|
|
||||||
{
|
{
|
||||||
for (Entry<TraitType, Float> trait : _defenceTraits.entrySet())
|
if (trait.getValue() < 2.0f)
|
||||||
{
|
{
|
||||||
if (trait.getValue() < 2.0f)
|
effected.getStat().mergeDefenceTrait(trait.getKey(), trait.getValue());
|
||||||
{
|
|
||||||
if (charStat.getDefenceTraitsCount()[trait.getKey().ordinal()] == 0)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
charStat.getDefenceTraits()[trait.getKey().ordinal()] /= trait.getValue();
|
|
||||||
charStat.getDefenceTraitsCount()[trait.getKey().ordinal()]--;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (charStat.getTraitsInvul()[trait.getKey().ordinal()] == 0)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
charStat.getTraitsInvul()[trait.getKey().ordinal()]--;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
else
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onStart(Creature effector, Creature effected, Skill skill, ItemInstance item)
|
|
||||||
{
|
|
||||||
final CreatureStat charStat = effected.getStat();
|
|
||||||
synchronized (charStat.getDefenceTraits())
|
|
||||||
{
|
|
||||||
for (Entry<TraitType, Float> trait : _defenceTraits.entrySet())
|
|
||||||
{
|
{
|
||||||
if (trait.getValue() < 2.0f)
|
effected.getStat().mergeInvulnerableTrait(trait.getKey());
|
||||||
{
|
|
||||||
charStat.getDefenceTraits()[trait.getKey().ordinal()] *= trait.getValue();
|
|
||||||
charStat.getDefenceTraitsCount()[trait.getKey().ordinal()]++;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
charStat.getTraitsInvul()[trait.getKey().ordinal()]++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,10 +16,10 @@
|
|||||||
*/
|
*/
|
||||||
package org.l2jmobius.gameserver.model.actor.stat;
|
package org.l2jmobius.gameserver.model.actor.stat;
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Deque;
|
import java.util.Deque;
|
||||||
import java.util.EnumMap;
|
import java.util.EnumMap;
|
||||||
|
import java.util.EnumSet;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
@@ -72,11 +72,11 @@ public class CreatureStat
|
|||||||
private final Deque<StatsHolder> _additionalMul = new ConcurrentLinkedDeque<>();
|
private final Deque<StatsHolder> _additionalMul = new ConcurrentLinkedDeque<>();
|
||||||
private final Map<Stats, Double> _fixedValue = new ConcurrentHashMap<>();
|
private final Map<Stats, Double> _fixedValue = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
private final float[] _attackTraits = new float[TraitType.values().length];
|
private final float[] _attackTraitValues = new float[TraitType.values().length];
|
||||||
private final float[] _defenceTraits = new float[TraitType.values().length];
|
private final float[] _defenceTraitValues = new float[TraitType.values().length];
|
||||||
private final int[] _attackTraitsCount = new int[TraitType.values().length];
|
private final Set<TraitType> _attackTraits = EnumSet.noneOf(TraitType.class);
|
||||||
private final int[] _defenceTraitsCount = new int[TraitType.values().length];
|
private final Set<TraitType> _defenceTraits = EnumSet.noneOf(TraitType.class);
|
||||||
private final int[] _traitsInvul = new int[TraitType.values().length];
|
private final Set<TraitType> _invulnerableTraits = EnumSet.noneOf(TraitType.class);
|
||||||
|
|
||||||
/** Values to be recalculated after every stat update */
|
/** Values to be recalculated after every stat update */
|
||||||
private double _attackSpeedMultiplier = 1;
|
private double _attackSpeedMultiplier = 1;
|
||||||
@@ -87,8 +87,6 @@ public class CreatureStat
|
|||||||
public CreatureStat(Creature creature)
|
public CreatureStat(Creature creature)
|
||||||
{
|
{
|
||||||
_creature = creature;
|
_creature = creature;
|
||||||
Arrays.fill(_attackTraits, 1.0f);
|
|
||||||
Arrays.fill(_defenceTraits, 1.0f);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -583,54 +581,86 @@ public class CreatureStat
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public float getAttackTrait(TraitType traitType)
|
public void mergeAttackTrait(TraitType traitType, float value)
|
||||||
{
|
{
|
||||||
return _attackTraits[traitType.ordinal()];
|
_attackTraitValues[traitType.ordinal()] *= value;
|
||||||
|
_attackTraits.add(traitType);
|
||||||
}
|
}
|
||||||
|
|
||||||
public float[] getAttackTraits()
|
public float getAttackTrait(TraitType traitType)
|
||||||
{
|
{
|
||||||
return _attackTraits;
|
_lock.readLock().lock();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return _attackTraitValues[traitType.ordinal()];
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
_lock.readLock().unlock();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasAttackTrait(TraitType traitType)
|
public boolean hasAttackTrait(TraitType traitType)
|
||||||
{
|
{
|
||||||
return _attackTraitsCount[traitType.ordinal()] > 0;
|
_lock.readLock().lock();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return _attackTraits.contains(traitType);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
_lock.readLock().unlock();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public int[] getAttackTraitsCount()
|
public void mergeDefenceTrait(TraitType traitType, float value)
|
||||||
{
|
{
|
||||||
return _attackTraitsCount;
|
_defenceTraitValues[traitType.ordinal()] *= value;
|
||||||
|
_defenceTraits.add(traitType);
|
||||||
}
|
}
|
||||||
|
|
||||||
public float getDefenceTrait(TraitType traitType)
|
public float getDefenceTrait(TraitType traitType)
|
||||||
{
|
{
|
||||||
return _defenceTraits[traitType.ordinal()];
|
_lock.readLock().lock();
|
||||||
}
|
try
|
||||||
|
{
|
||||||
public float[] getDefenceTraits()
|
return _defenceTraitValues[traitType.ordinal()];
|
||||||
{
|
}
|
||||||
return _defenceTraits;
|
finally
|
||||||
|
{
|
||||||
|
_lock.readLock().unlock();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasDefenceTrait(TraitType traitType)
|
public boolean hasDefenceTrait(TraitType traitType)
|
||||||
{
|
{
|
||||||
return _defenceTraitsCount[traitType.ordinal()] > 0;
|
_lock.readLock().lock();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return _defenceTraits.contains(traitType);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
_lock.readLock().unlock();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public int[] getDefenceTraitsCount()
|
public void mergeInvulnerableTrait(TraitType traitType)
|
||||||
{
|
{
|
||||||
return _defenceTraitsCount;
|
_invulnerableTraits.add(traitType);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isTraitInvul(TraitType traitType)
|
public boolean isInvulnerableTrait(TraitType traitType)
|
||||||
{
|
{
|
||||||
return _traitsInvul[traitType.ordinal()] > 0;
|
_lock.readLock().lock();
|
||||||
}
|
try
|
||||||
|
{
|
||||||
public int[] getTraitsInvul()
|
return _invulnerableTraits.contains(traitType);
|
||||||
{
|
}
|
||||||
return _traitsInvul;
|
finally
|
||||||
|
{
|
||||||
|
_lock.readLock().unlock();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1241,7 +1241,7 @@ public final class Formulas
|
|||||||
return 1.0;
|
return 1.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (target.getStat().isTraitInvul(traitType))
|
if (target.getStat().isInvulnerableTrait(traitType))
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -63,6 +63,14 @@ public enum TraitType
|
|||||||
PHYSICAL_WEAKNESS(3),
|
PHYSICAL_WEAKNESS(3),
|
||||||
MAGICAL_WEAKNESS(3),
|
MAGICAL_WEAKNESS(3),
|
||||||
DUALDAGGER(1),
|
DUALDAGGER(1),
|
||||||
|
DEMONIC_WEAKNESS(2), // CT26_P4
|
||||||
|
DIVINE_WEAKNESS(2),
|
||||||
|
ELEMENTAL_WEAKNESS(2),
|
||||||
|
FAIRY_WEAKNESS(2),
|
||||||
|
HUMAN_WEAKNESS(2),
|
||||||
|
HUMANOID_WEAKNESS(2),
|
||||||
|
UNDEAD_WEAKNESS(2),
|
||||||
|
// The values from below are custom.
|
||||||
DUALBLUNT(1),
|
DUALBLUNT(1),
|
||||||
KNOCKBACK(3),
|
KNOCKBACK(3),
|
||||||
KNOCKDOWN(3),
|
KNOCKDOWN(3),
|
||||||
@@ -75,7 +83,9 @@ public enum TraitType
|
|||||||
CHANGEBODY(3),
|
CHANGEBODY(3),
|
||||||
TWOHANDCROSSBOW(1),
|
TWOHANDCROSSBOW(1),
|
||||||
ZONE(3),
|
ZONE(3),
|
||||||
PSYCHIC(3);
|
PSYCHIC(3),
|
||||||
|
EMBRYO_WEAKNESS(2),
|
||||||
|
SPIRIT_WEAKNESS(2);
|
||||||
|
|
||||||
private final int _type; // 1 = weapon, 2 = weakness, 3 = resistance
|
private final int _type; // 1 = weapon, 2 = weakness, 3 = resistance
|
||||||
|
|
||||||
|
|||||||
@@ -22,9 +22,7 @@ import java.util.Map.Entry;
|
|||||||
|
|
||||||
import org.l2jmobius.gameserver.model.StatsSet;
|
import org.l2jmobius.gameserver.model.StatsSet;
|
||||||
import org.l2jmobius.gameserver.model.actor.Creature;
|
import org.l2jmobius.gameserver.model.actor.Creature;
|
||||||
import org.l2jmobius.gameserver.model.actor.stat.CreatureStat;
|
|
||||||
import org.l2jmobius.gameserver.model.effects.AbstractEffect;
|
import org.l2jmobius.gameserver.model.effects.AbstractEffect;
|
||||||
import org.l2jmobius.gameserver.model.items.instance.ItemInstance;
|
|
||||||
import org.l2jmobius.gameserver.model.skills.Skill;
|
import org.l2jmobius.gameserver.model.skills.Skill;
|
||||||
import org.l2jmobius.gameserver.model.stats.TraitType;
|
import org.l2jmobius.gameserver.model.stats.TraitType;
|
||||||
|
|
||||||
@@ -51,35 +49,11 @@ public final class AttackTrait extends AbstractEffect
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onExit(Creature effector, Creature effected, Skill skill)
|
public void pump(Creature effected, Skill skill)
|
||||||
{
|
{
|
||||||
final CreatureStat charStat = effected.getStat();
|
for (Entry<TraitType, Float> trait : _attackTraits.entrySet())
|
||||||
synchronized (charStat.getAttackTraits())
|
|
||||||
{
|
{
|
||||||
for (Entry<TraitType, Float> trait : _attackTraits.entrySet())
|
effected.getStat().mergeAttackTrait(trait.getKey(), trait.getValue());
|
||||||
{
|
|
||||||
if (charStat.getAttackTraitsCount()[trait.getKey().ordinal()] == 0)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
charStat.getAttackTraits()[trait.getKey().ordinal()] /= trait.getValue();
|
|
||||||
charStat.getAttackTraitsCount()[trait.getKey().ordinal()]--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onStart(Creature effector, Creature effected, Skill skill, ItemInstance item)
|
|
||||||
{
|
|
||||||
final CreatureStat charStat = effected.getStat();
|
|
||||||
synchronized (charStat.getAttackTraits())
|
|
||||||
{
|
|
||||||
for (Entry<TraitType, Float> trait : _attackTraits.entrySet())
|
|
||||||
{
|
|
||||||
charStat.getAttackTraits()[trait.getKey().ordinal()] *= trait.getValue();
|
|
||||||
charStat.getAttackTraitsCount()[trait.getKey().ordinal()]++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,9 +22,7 @@ import java.util.Map.Entry;
|
|||||||
|
|
||||||
import org.l2jmobius.gameserver.model.StatsSet;
|
import org.l2jmobius.gameserver.model.StatsSet;
|
||||||
import org.l2jmobius.gameserver.model.actor.Creature;
|
import org.l2jmobius.gameserver.model.actor.Creature;
|
||||||
import org.l2jmobius.gameserver.model.actor.stat.CreatureStat;
|
|
||||||
import org.l2jmobius.gameserver.model.effects.AbstractEffect;
|
import org.l2jmobius.gameserver.model.effects.AbstractEffect;
|
||||||
import org.l2jmobius.gameserver.model.items.instance.ItemInstance;
|
|
||||||
import org.l2jmobius.gameserver.model.skills.Skill;
|
import org.l2jmobius.gameserver.model.skills.Skill;
|
||||||
import org.l2jmobius.gameserver.model.stats.TraitType;
|
import org.l2jmobius.gameserver.model.stats.TraitType;
|
||||||
|
|
||||||
@@ -46,75 +44,22 @@ public final class DefenceTrait extends AbstractEffect
|
|||||||
|
|
||||||
for (Entry<String, Object> param : params.getSet().entrySet())
|
for (Entry<String, Object> param : params.getSet().entrySet())
|
||||||
{
|
{
|
||||||
try
|
_defenceTraits.put(TraitType.valueOf(param.getKey()), (Float.parseFloat((String) param.getValue()) + 100) / 100);
|
||||||
{
|
|
||||||
final TraitType traitType = TraitType.valueOf(param.getKey());
|
|
||||||
final float value = Float.parseFloat((String) param.getValue());
|
|
||||||
if (value == 0)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
_defenceTraits.put(traitType, (value + 100) / 100);
|
|
||||||
}
|
|
||||||
catch (NumberFormatException e)
|
|
||||||
{
|
|
||||||
LOGGER.warning(getClass().getSimpleName() + ": value of " + param.getKey() + " must be float value " + param.getValue() + " found.");
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
LOGGER.warning(getClass().getSimpleName() + ": value of TraitType enum required but found: " + param.getKey());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onExit(Creature effector, Creature effected, Skill skill)
|
public void pump(Creature effected, Skill skill)
|
||||||
{
|
{
|
||||||
final CreatureStat charStat = effected.getStat();
|
for (Entry<TraitType, Float> trait : _defenceTraits.entrySet())
|
||||||
synchronized (charStat.getDefenceTraits())
|
|
||||||
{
|
{
|
||||||
for (Entry<TraitType, Float> trait : _defenceTraits.entrySet())
|
if (trait.getValue() < 2.0f)
|
||||||
{
|
{
|
||||||
if (trait.getValue() < 2.0f)
|
effected.getStat().mergeDefenceTrait(trait.getKey(), trait.getValue());
|
||||||
{
|
|
||||||
if (charStat.getDefenceTraitsCount()[trait.getKey().ordinal()] == 0)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
charStat.getDefenceTraits()[trait.getKey().ordinal()] /= trait.getValue();
|
|
||||||
charStat.getDefenceTraitsCount()[trait.getKey().ordinal()]--;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (charStat.getTraitsInvul()[trait.getKey().ordinal()] == 0)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
charStat.getTraitsInvul()[trait.getKey().ordinal()]--;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
else
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onStart(Creature effector, Creature effected, Skill skill, ItemInstance item)
|
|
||||||
{
|
|
||||||
final CreatureStat charStat = effected.getStat();
|
|
||||||
synchronized (charStat.getDefenceTraits())
|
|
||||||
{
|
|
||||||
for (Entry<TraitType, Float> trait : _defenceTraits.entrySet())
|
|
||||||
{
|
{
|
||||||
if (trait.getValue() < 2.0f)
|
effected.getStat().mergeInvulnerableTrait(trait.getKey());
|
||||||
{
|
|
||||||
charStat.getDefenceTraits()[trait.getKey().ordinal()] *= trait.getValue();
|
|
||||||
charStat.getDefenceTraitsCount()[trait.getKey().ordinal()]++;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
charStat.getTraitsInvul()[trait.getKey().ordinal()]++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,10 +16,10 @@
|
|||||||
*/
|
*/
|
||||||
package org.l2jmobius.gameserver.model.actor.stat;
|
package org.l2jmobius.gameserver.model.actor.stat;
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Deque;
|
import java.util.Deque;
|
||||||
import java.util.EnumMap;
|
import java.util.EnumMap;
|
||||||
|
import java.util.EnumSet;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
@@ -72,11 +72,11 @@ public class CreatureStat
|
|||||||
private final Deque<StatsHolder> _additionalMul = new ConcurrentLinkedDeque<>();
|
private final Deque<StatsHolder> _additionalMul = new ConcurrentLinkedDeque<>();
|
||||||
private final Map<Stats, Double> _fixedValue = new ConcurrentHashMap<>();
|
private final Map<Stats, Double> _fixedValue = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
private final float[] _attackTraits = new float[TraitType.values().length];
|
private final float[] _attackTraitValues = new float[TraitType.values().length];
|
||||||
private final float[] _defenceTraits = new float[TraitType.values().length];
|
private final float[] _defenceTraitValues = new float[TraitType.values().length];
|
||||||
private final int[] _attackTraitsCount = new int[TraitType.values().length];
|
private final Set<TraitType> _attackTraits = EnumSet.noneOf(TraitType.class);
|
||||||
private final int[] _defenceTraitsCount = new int[TraitType.values().length];
|
private final Set<TraitType> _defenceTraits = EnumSet.noneOf(TraitType.class);
|
||||||
private final int[] _traitsInvul = new int[TraitType.values().length];
|
private final Set<TraitType> _invulnerableTraits = EnumSet.noneOf(TraitType.class);
|
||||||
|
|
||||||
/** Values to be recalculated after every stat update */
|
/** Values to be recalculated after every stat update */
|
||||||
private double _attackSpeedMultiplier = 1;
|
private double _attackSpeedMultiplier = 1;
|
||||||
@@ -87,8 +87,6 @@ public class CreatureStat
|
|||||||
public CreatureStat(Creature creature)
|
public CreatureStat(Creature creature)
|
||||||
{
|
{
|
||||||
_creature = creature;
|
_creature = creature;
|
||||||
Arrays.fill(_attackTraits, 1.0f);
|
|
||||||
Arrays.fill(_defenceTraits, 1.0f);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -583,54 +581,86 @@ public class CreatureStat
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public float getAttackTrait(TraitType traitType)
|
public void mergeAttackTrait(TraitType traitType, float value)
|
||||||
{
|
{
|
||||||
return _attackTraits[traitType.ordinal()];
|
_attackTraitValues[traitType.ordinal()] *= value;
|
||||||
|
_attackTraits.add(traitType);
|
||||||
}
|
}
|
||||||
|
|
||||||
public float[] getAttackTraits()
|
public float getAttackTrait(TraitType traitType)
|
||||||
{
|
{
|
||||||
return _attackTraits;
|
_lock.readLock().lock();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return _attackTraitValues[traitType.ordinal()];
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
_lock.readLock().unlock();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasAttackTrait(TraitType traitType)
|
public boolean hasAttackTrait(TraitType traitType)
|
||||||
{
|
{
|
||||||
return _attackTraitsCount[traitType.ordinal()] > 0;
|
_lock.readLock().lock();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return _attackTraits.contains(traitType);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
_lock.readLock().unlock();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public int[] getAttackTraitsCount()
|
public void mergeDefenceTrait(TraitType traitType, float value)
|
||||||
{
|
{
|
||||||
return _attackTraitsCount;
|
_defenceTraitValues[traitType.ordinal()] *= value;
|
||||||
|
_defenceTraits.add(traitType);
|
||||||
}
|
}
|
||||||
|
|
||||||
public float getDefenceTrait(TraitType traitType)
|
public float getDefenceTrait(TraitType traitType)
|
||||||
{
|
{
|
||||||
return _defenceTraits[traitType.ordinal()];
|
_lock.readLock().lock();
|
||||||
}
|
try
|
||||||
|
{
|
||||||
public float[] getDefenceTraits()
|
return _defenceTraitValues[traitType.ordinal()];
|
||||||
{
|
}
|
||||||
return _defenceTraits;
|
finally
|
||||||
|
{
|
||||||
|
_lock.readLock().unlock();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasDefenceTrait(TraitType traitType)
|
public boolean hasDefenceTrait(TraitType traitType)
|
||||||
{
|
{
|
||||||
return _defenceTraitsCount[traitType.ordinal()] > 0;
|
_lock.readLock().lock();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return _defenceTraits.contains(traitType);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
_lock.readLock().unlock();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public int[] getDefenceTraitsCount()
|
public void mergeInvulnerableTrait(TraitType traitType)
|
||||||
{
|
{
|
||||||
return _defenceTraitsCount;
|
_invulnerableTraits.add(traitType);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isTraitInvul(TraitType traitType)
|
public boolean isInvulnerableTrait(TraitType traitType)
|
||||||
{
|
{
|
||||||
return _traitsInvul[traitType.ordinal()] > 0;
|
_lock.readLock().lock();
|
||||||
}
|
try
|
||||||
|
{
|
||||||
public int[] getTraitsInvul()
|
return _invulnerableTraits.contains(traitType);
|
||||||
{
|
}
|
||||||
return _traitsInvul;
|
finally
|
||||||
|
{
|
||||||
|
_lock.readLock().unlock();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1241,7 +1241,7 @@ public final class Formulas
|
|||||||
return 1.0;
|
return 1.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (target.getStat().isTraitInvul(traitType))
|
if (target.getStat().isInvulnerableTrait(traitType))
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -63,6 +63,14 @@ public enum TraitType
|
|||||||
PHYSICAL_WEAKNESS(3),
|
PHYSICAL_WEAKNESS(3),
|
||||||
MAGICAL_WEAKNESS(3),
|
MAGICAL_WEAKNESS(3),
|
||||||
DUALDAGGER(1),
|
DUALDAGGER(1),
|
||||||
|
DEMONIC_WEAKNESS(2), // CT26_P4
|
||||||
|
DIVINE_WEAKNESS(2),
|
||||||
|
ELEMENTAL_WEAKNESS(2),
|
||||||
|
FAIRY_WEAKNESS(2),
|
||||||
|
HUMAN_WEAKNESS(2),
|
||||||
|
HUMANOID_WEAKNESS(2),
|
||||||
|
UNDEAD_WEAKNESS(2),
|
||||||
|
// The values from below are custom.
|
||||||
DUALBLUNT(1),
|
DUALBLUNT(1),
|
||||||
KNOCKBACK(3),
|
KNOCKBACK(3),
|
||||||
KNOCKDOWN(3),
|
KNOCKDOWN(3),
|
||||||
@@ -75,7 +83,9 @@ public enum TraitType
|
|||||||
CHANGEBODY(3),
|
CHANGEBODY(3),
|
||||||
TWOHANDCROSSBOW(1),
|
TWOHANDCROSSBOW(1),
|
||||||
ZONE(3),
|
ZONE(3),
|
||||||
PSYCHIC(3);
|
PSYCHIC(3),
|
||||||
|
EMBRYO_WEAKNESS(2),
|
||||||
|
SPIRIT_WEAKNESS(2);
|
||||||
|
|
||||||
private final int _type; // 1 = weapon, 2 = weakness, 3 = resistance
|
private final int _type; // 1 = weapon, 2 = weakness, 3 = resistance
|
||||||
|
|
||||||
|
|||||||
@@ -22,9 +22,7 @@ import java.util.Map.Entry;
|
|||||||
|
|
||||||
import org.l2jmobius.gameserver.model.StatsSet;
|
import org.l2jmobius.gameserver.model.StatsSet;
|
||||||
import org.l2jmobius.gameserver.model.actor.Creature;
|
import org.l2jmobius.gameserver.model.actor.Creature;
|
||||||
import org.l2jmobius.gameserver.model.actor.stat.CreatureStat;
|
|
||||||
import org.l2jmobius.gameserver.model.effects.AbstractEffect;
|
import org.l2jmobius.gameserver.model.effects.AbstractEffect;
|
||||||
import org.l2jmobius.gameserver.model.items.instance.ItemInstance;
|
|
||||||
import org.l2jmobius.gameserver.model.skills.Skill;
|
import org.l2jmobius.gameserver.model.skills.Skill;
|
||||||
import org.l2jmobius.gameserver.model.stats.TraitType;
|
import org.l2jmobius.gameserver.model.stats.TraitType;
|
||||||
|
|
||||||
@@ -51,35 +49,11 @@ public final class AttackTrait extends AbstractEffect
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onExit(Creature effector, Creature effected, Skill skill)
|
public void pump(Creature effected, Skill skill)
|
||||||
{
|
{
|
||||||
final CreatureStat charStat = effected.getStat();
|
for (Entry<TraitType, Float> trait : _attackTraits.entrySet())
|
||||||
synchronized (charStat.getAttackTraits())
|
|
||||||
{
|
{
|
||||||
for (Entry<TraitType, Float> trait : _attackTraits.entrySet())
|
effected.getStat().mergeAttackTrait(trait.getKey(), trait.getValue());
|
||||||
{
|
|
||||||
if (charStat.getAttackTraitsCount()[trait.getKey().ordinal()] == 0)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
charStat.getAttackTraits()[trait.getKey().ordinal()] /= trait.getValue();
|
|
||||||
charStat.getAttackTraitsCount()[trait.getKey().ordinal()]--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onStart(Creature effector, Creature effected, Skill skill, ItemInstance item)
|
|
||||||
{
|
|
||||||
final CreatureStat charStat = effected.getStat();
|
|
||||||
synchronized (charStat.getAttackTraits())
|
|
||||||
{
|
|
||||||
for (Entry<TraitType, Float> trait : _attackTraits.entrySet())
|
|
||||||
{
|
|
||||||
charStat.getAttackTraits()[trait.getKey().ordinal()] *= trait.getValue();
|
|
||||||
charStat.getAttackTraitsCount()[trait.getKey().ordinal()]++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,9 +22,7 @@ import java.util.Map.Entry;
|
|||||||
|
|
||||||
import org.l2jmobius.gameserver.model.StatsSet;
|
import org.l2jmobius.gameserver.model.StatsSet;
|
||||||
import org.l2jmobius.gameserver.model.actor.Creature;
|
import org.l2jmobius.gameserver.model.actor.Creature;
|
||||||
import org.l2jmobius.gameserver.model.actor.stat.CreatureStat;
|
|
||||||
import org.l2jmobius.gameserver.model.effects.AbstractEffect;
|
import org.l2jmobius.gameserver.model.effects.AbstractEffect;
|
||||||
import org.l2jmobius.gameserver.model.items.instance.ItemInstance;
|
|
||||||
import org.l2jmobius.gameserver.model.skills.Skill;
|
import org.l2jmobius.gameserver.model.skills.Skill;
|
||||||
import org.l2jmobius.gameserver.model.stats.TraitType;
|
import org.l2jmobius.gameserver.model.stats.TraitType;
|
||||||
|
|
||||||
@@ -46,75 +44,22 @@ public final class DefenceTrait extends AbstractEffect
|
|||||||
|
|
||||||
for (Entry<String, Object> param : params.getSet().entrySet())
|
for (Entry<String, Object> param : params.getSet().entrySet())
|
||||||
{
|
{
|
||||||
try
|
_defenceTraits.put(TraitType.valueOf(param.getKey()), (Float.parseFloat((String) param.getValue()) + 100) / 100);
|
||||||
{
|
|
||||||
final TraitType traitType = TraitType.valueOf(param.getKey());
|
|
||||||
final float value = Float.parseFloat((String) param.getValue());
|
|
||||||
if (value == 0)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
_defenceTraits.put(traitType, (value + 100) / 100);
|
|
||||||
}
|
|
||||||
catch (NumberFormatException e)
|
|
||||||
{
|
|
||||||
LOGGER.warning(getClass().getSimpleName() + ": value of " + param.getKey() + " must be float value " + param.getValue() + " found.");
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
LOGGER.warning(getClass().getSimpleName() + ": value of TraitType enum required but found: " + param.getKey());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onExit(Creature effector, Creature effected, Skill skill)
|
public void pump(Creature effected, Skill skill)
|
||||||
{
|
{
|
||||||
final CreatureStat charStat = effected.getStat();
|
for (Entry<TraitType, Float> trait : _defenceTraits.entrySet())
|
||||||
synchronized (charStat.getDefenceTraits())
|
|
||||||
{
|
{
|
||||||
for (Entry<TraitType, Float> trait : _defenceTraits.entrySet())
|
if (trait.getValue() < 2.0f)
|
||||||
{
|
{
|
||||||
if (trait.getValue() < 2.0f)
|
effected.getStat().mergeDefenceTrait(trait.getKey(), trait.getValue());
|
||||||
{
|
|
||||||
if (charStat.getDefenceTraitsCount()[trait.getKey().ordinal()] == 0)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
charStat.getDefenceTraits()[trait.getKey().ordinal()] /= trait.getValue();
|
|
||||||
charStat.getDefenceTraitsCount()[trait.getKey().ordinal()]--;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (charStat.getTraitsInvul()[trait.getKey().ordinal()] == 0)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
charStat.getTraitsInvul()[trait.getKey().ordinal()]--;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
else
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onStart(Creature effector, Creature effected, Skill skill, ItemInstance item)
|
|
||||||
{
|
|
||||||
final CreatureStat charStat = effected.getStat();
|
|
||||||
synchronized (charStat.getDefenceTraits())
|
|
||||||
{
|
|
||||||
for (Entry<TraitType, Float> trait : _defenceTraits.entrySet())
|
|
||||||
{
|
{
|
||||||
if (trait.getValue() < 2.0f)
|
effected.getStat().mergeInvulnerableTrait(trait.getKey());
|
||||||
{
|
|
||||||
charStat.getDefenceTraits()[trait.getKey().ordinal()] *= trait.getValue();
|
|
||||||
charStat.getDefenceTraitsCount()[trait.getKey().ordinal()]++;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
charStat.getTraitsInvul()[trait.getKey().ordinal()]++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,10 +16,10 @@
|
|||||||
*/
|
*/
|
||||||
package org.l2jmobius.gameserver.model.actor.stat;
|
package org.l2jmobius.gameserver.model.actor.stat;
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Deque;
|
import java.util.Deque;
|
||||||
import java.util.EnumMap;
|
import java.util.EnumMap;
|
||||||
|
import java.util.EnumSet;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
@@ -72,11 +72,11 @@ public class CreatureStat
|
|||||||
private final Deque<StatsHolder> _additionalMul = new ConcurrentLinkedDeque<>();
|
private final Deque<StatsHolder> _additionalMul = new ConcurrentLinkedDeque<>();
|
||||||
private final Map<Stats, Double> _fixedValue = new ConcurrentHashMap<>();
|
private final Map<Stats, Double> _fixedValue = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
private final float[] _attackTraits = new float[TraitType.values().length];
|
private final float[] _attackTraitValues = new float[TraitType.values().length];
|
||||||
private final float[] _defenceTraits = new float[TraitType.values().length];
|
private final float[] _defenceTraitValues = new float[TraitType.values().length];
|
||||||
private final int[] _attackTraitsCount = new int[TraitType.values().length];
|
private final Set<TraitType> _attackTraits = EnumSet.noneOf(TraitType.class);
|
||||||
private final int[] _defenceTraitsCount = new int[TraitType.values().length];
|
private final Set<TraitType> _defenceTraits = EnumSet.noneOf(TraitType.class);
|
||||||
private final int[] _traitsInvul = new int[TraitType.values().length];
|
private final Set<TraitType> _invulnerableTraits = EnumSet.noneOf(TraitType.class);
|
||||||
|
|
||||||
/** Values to be recalculated after every stat update */
|
/** Values to be recalculated after every stat update */
|
||||||
private double _attackSpeedMultiplier = 1;
|
private double _attackSpeedMultiplier = 1;
|
||||||
@@ -87,8 +87,6 @@ public class CreatureStat
|
|||||||
public CreatureStat(Creature creature)
|
public CreatureStat(Creature creature)
|
||||||
{
|
{
|
||||||
_creature = creature;
|
_creature = creature;
|
||||||
Arrays.fill(_attackTraits, 1.0f);
|
|
||||||
Arrays.fill(_defenceTraits, 1.0f);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -583,54 +581,86 @@ public class CreatureStat
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public float getAttackTrait(TraitType traitType)
|
public void mergeAttackTrait(TraitType traitType, float value)
|
||||||
{
|
{
|
||||||
return _attackTraits[traitType.ordinal()];
|
_attackTraitValues[traitType.ordinal()] *= value;
|
||||||
|
_attackTraits.add(traitType);
|
||||||
}
|
}
|
||||||
|
|
||||||
public float[] getAttackTraits()
|
public float getAttackTrait(TraitType traitType)
|
||||||
{
|
{
|
||||||
return _attackTraits;
|
_lock.readLock().lock();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return _attackTraitValues[traitType.ordinal()];
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
_lock.readLock().unlock();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasAttackTrait(TraitType traitType)
|
public boolean hasAttackTrait(TraitType traitType)
|
||||||
{
|
{
|
||||||
return _attackTraitsCount[traitType.ordinal()] > 0;
|
_lock.readLock().lock();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return _attackTraits.contains(traitType);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
_lock.readLock().unlock();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public int[] getAttackTraitsCount()
|
public void mergeDefenceTrait(TraitType traitType, float value)
|
||||||
{
|
{
|
||||||
return _attackTraitsCount;
|
_defenceTraitValues[traitType.ordinal()] *= value;
|
||||||
|
_defenceTraits.add(traitType);
|
||||||
}
|
}
|
||||||
|
|
||||||
public float getDefenceTrait(TraitType traitType)
|
public float getDefenceTrait(TraitType traitType)
|
||||||
{
|
{
|
||||||
return _defenceTraits[traitType.ordinal()];
|
_lock.readLock().lock();
|
||||||
}
|
try
|
||||||
|
{
|
||||||
public float[] getDefenceTraits()
|
return _defenceTraitValues[traitType.ordinal()];
|
||||||
{
|
}
|
||||||
return _defenceTraits;
|
finally
|
||||||
|
{
|
||||||
|
_lock.readLock().unlock();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasDefenceTrait(TraitType traitType)
|
public boolean hasDefenceTrait(TraitType traitType)
|
||||||
{
|
{
|
||||||
return _defenceTraitsCount[traitType.ordinal()] > 0;
|
_lock.readLock().lock();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return _defenceTraits.contains(traitType);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
_lock.readLock().unlock();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public int[] getDefenceTraitsCount()
|
public void mergeInvulnerableTrait(TraitType traitType)
|
||||||
{
|
{
|
||||||
return _defenceTraitsCount;
|
_invulnerableTraits.add(traitType);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isTraitInvul(TraitType traitType)
|
public boolean isInvulnerableTrait(TraitType traitType)
|
||||||
{
|
{
|
||||||
return _traitsInvul[traitType.ordinal()] > 0;
|
_lock.readLock().lock();
|
||||||
}
|
try
|
||||||
|
{
|
||||||
public int[] getTraitsInvul()
|
return _invulnerableTraits.contains(traitType);
|
||||||
{
|
}
|
||||||
return _traitsInvul;
|
finally
|
||||||
|
{
|
||||||
|
_lock.readLock().unlock();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1241,7 +1241,7 @@ public final class Formulas
|
|||||||
return 1.0;
|
return 1.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (target.getStat().isTraitInvul(traitType))
|
if (target.getStat().isInvulnerableTrait(traitType))
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -63,6 +63,14 @@ public enum TraitType
|
|||||||
PHYSICAL_WEAKNESS(3),
|
PHYSICAL_WEAKNESS(3),
|
||||||
MAGICAL_WEAKNESS(3),
|
MAGICAL_WEAKNESS(3),
|
||||||
DUALDAGGER(1),
|
DUALDAGGER(1),
|
||||||
|
DEMONIC_WEAKNESS(2), // CT26_P4
|
||||||
|
DIVINE_WEAKNESS(2),
|
||||||
|
ELEMENTAL_WEAKNESS(2),
|
||||||
|
FAIRY_WEAKNESS(2),
|
||||||
|
HUMAN_WEAKNESS(2),
|
||||||
|
HUMANOID_WEAKNESS(2),
|
||||||
|
UNDEAD_WEAKNESS(2),
|
||||||
|
// The values from below are custom.
|
||||||
DUALBLUNT(1),
|
DUALBLUNT(1),
|
||||||
KNOCKBACK(3),
|
KNOCKBACK(3),
|
||||||
KNOCKDOWN(3),
|
KNOCKDOWN(3),
|
||||||
@@ -75,7 +83,9 @@ public enum TraitType
|
|||||||
CHANGEBODY(3),
|
CHANGEBODY(3),
|
||||||
TWOHANDCROSSBOW(1),
|
TWOHANDCROSSBOW(1),
|
||||||
ZONE(3),
|
ZONE(3),
|
||||||
PSYCHIC(3);
|
PSYCHIC(3),
|
||||||
|
EMBRYO_WEAKNESS(2),
|
||||||
|
SPIRIT_WEAKNESS(2);
|
||||||
|
|
||||||
private final int _type; // 1 = weapon, 2 = weakness, 3 = resistance
|
private final int _type; // 1 = weapon, 2 = weakness, 3 = resistance
|
||||||
|
|
||||||
|
|||||||
@@ -22,9 +22,7 @@ import java.util.Map.Entry;
|
|||||||
|
|
||||||
import org.l2jmobius.gameserver.model.StatsSet;
|
import org.l2jmobius.gameserver.model.StatsSet;
|
||||||
import org.l2jmobius.gameserver.model.actor.Creature;
|
import org.l2jmobius.gameserver.model.actor.Creature;
|
||||||
import org.l2jmobius.gameserver.model.actor.stat.CreatureStat;
|
|
||||||
import org.l2jmobius.gameserver.model.effects.AbstractEffect;
|
import org.l2jmobius.gameserver.model.effects.AbstractEffect;
|
||||||
import org.l2jmobius.gameserver.model.items.instance.ItemInstance;
|
|
||||||
import org.l2jmobius.gameserver.model.skills.Skill;
|
import org.l2jmobius.gameserver.model.skills.Skill;
|
||||||
import org.l2jmobius.gameserver.model.stats.TraitType;
|
import org.l2jmobius.gameserver.model.stats.TraitType;
|
||||||
|
|
||||||
@@ -51,35 +49,11 @@ public final class AttackTrait extends AbstractEffect
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onExit(Creature effector, Creature effected, Skill skill)
|
public void pump(Creature effected, Skill skill)
|
||||||
{
|
{
|
||||||
final CreatureStat charStat = effected.getStat();
|
for (Entry<TraitType, Float> trait : _attackTraits.entrySet())
|
||||||
synchronized (charStat.getAttackTraits())
|
|
||||||
{
|
{
|
||||||
for (Entry<TraitType, Float> trait : _attackTraits.entrySet())
|
effected.getStat().mergeAttackTrait(trait.getKey(), trait.getValue());
|
||||||
{
|
|
||||||
if (charStat.getAttackTraitsCount()[trait.getKey().ordinal()] == 0)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
charStat.getAttackTraits()[trait.getKey().ordinal()] /= trait.getValue();
|
|
||||||
charStat.getAttackTraitsCount()[trait.getKey().ordinal()]--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onStart(Creature effector, Creature effected, Skill skill, ItemInstance item)
|
|
||||||
{
|
|
||||||
final CreatureStat charStat = effected.getStat();
|
|
||||||
synchronized (charStat.getAttackTraits())
|
|
||||||
{
|
|
||||||
for (Entry<TraitType, Float> trait : _attackTraits.entrySet())
|
|
||||||
{
|
|
||||||
charStat.getAttackTraits()[trait.getKey().ordinal()] *= trait.getValue();
|
|
||||||
charStat.getAttackTraitsCount()[trait.getKey().ordinal()]++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,9 +22,7 @@ import java.util.Map.Entry;
|
|||||||
|
|
||||||
import org.l2jmobius.gameserver.model.StatsSet;
|
import org.l2jmobius.gameserver.model.StatsSet;
|
||||||
import org.l2jmobius.gameserver.model.actor.Creature;
|
import org.l2jmobius.gameserver.model.actor.Creature;
|
||||||
import org.l2jmobius.gameserver.model.actor.stat.CreatureStat;
|
|
||||||
import org.l2jmobius.gameserver.model.effects.AbstractEffect;
|
import org.l2jmobius.gameserver.model.effects.AbstractEffect;
|
||||||
import org.l2jmobius.gameserver.model.items.instance.ItemInstance;
|
|
||||||
import org.l2jmobius.gameserver.model.skills.Skill;
|
import org.l2jmobius.gameserver.model.skills.Skill;
|
||||||
import org.l2jmobius.gameserver.model.stats.TraitType;
|
import org.l2jmobius.gameserver.model.stats.TraitType;
|
||||||
|
|
||||||
@@ -46,75 +44,22 @@ public final class DefenceTrait extends AbstractEffect
|
|||||||
|
|
||||||
for (Entry<String, Object> param : params.getSet().entrySet())
|
for (Entry<String, Object> param : params.getSet().entrySet())
|
||||||
{
|
{
|
||||||
try
|
_defenceTraits.put(TraitType.valueOf(param.getKey()), (Float.parseFloat((String) param.getValue()) + 100) / 100);
|
||||||
{
|
|
||||||
final TraitType traitType = TraitType.valueOf(param.getKey());
|
|
||||||
final float value = Float.parseFloat((String) param.getValue());
|
|
||||||
if (value == 0)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
_defenceTraits.put(traitType, (value + 100) / 100);
|
|
||||||
}
|
|
||||||
catch (NumberFormatException e)
|
|
||||||
{
|
|
||||||
LOGGER.warning(getClass().getSimpleName() + ": value of " + param.getKey() + " must be float value " + param.getValue() + " found.");
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
LOGGER.warning(getClass().getSimpleName() + ": value of TraitType enum required but found: " + param.getKey());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onExit(Creature effector, Creature effected, Skill skill)
|
public void pump(Creature effected, Skill skill)
|
||||||
{
|
{
|
||||||
final CreatureStat charStat = effected.getStat();
|
for (Entry<TraitType, Float> trait : _defenceTraits.entrySet())
|
||||||
synchronized (charStat.getDefenceTraits())
|
|
||||||
{
|
{
|
||||||
for (Entry<TraitType, Float> trait : _defenceTraits.entrySet())
|
if (trait.getValue() < 2.0f)
|
||||||
{
|
{
|
||||||
if (trait.getValue() < 2.0f)
|
effected.getStat().mergeDefenceTrait(trait.getKey(), trait.getValue());
|
||||||
{
|
|
||||||
if (charStat.getDefenceTraitsCount()[trait.getKey().ordinal()] == 0)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
charStat.getDefenceTraits()[trait.getKey().ordinal()] /= trait.getValue();
|
|
||||||
charStat.getDefenceTraitsCount()[trait.getKey().ordinal()]--;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (charStat.getTraitsInvul()[trait.getKey().ordinal()] == 0)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
charStat.getTraitsInvul()[trait.getKey().ordinal()]--;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
else
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onStart(Creature effector, Creature effected, Skill skill, ItemInstance item)
|
|
||||||
{
|
|
||||||
final CreatureStat charStat = effected.getStat();
|
|
||||||
synchronized (charStat.getDefenceTraits())
|
|
||||||
{
|
|
||||||
for (Entry<TraitType, Float> trait : _defenceTraits.entrySet())
|
|
||||||
{
|
{
|
||||||
if (trait.getValue() < 2.0f)
|
effected.getStat().mergeInvulnerableTrait(trait.getKey());
|
||||||
{
|
|
||||||
charStat.getDefenceTraits()[trait.getKey().ordinal()] *= trait.getValue();
|
|
||||||
charStat.getDefenceTraitsCount()[trait.getKey().ordinal()]++;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
charStat.getTraitsInvul()[trait.getKey().ordinal()]++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,10 +16,10 @@
|
|||||||
*/
|
*/
|
||||||
package org.l2jmobius.gameserver.model.actor.stat;
|
package org.l2jmobius.gameserver.model.actor.stat;
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Deque;
|
import java.util.Deque;
|
||||||
import java.util.EnumMap;
|
import java.util.EnumMap;
|
||||||
|
import java.util.EnumSet;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
@@ -72,11 +72,11 @@ public class CreatureStat
|
|||||||
private final Deque<StatsHolder> _additionalMul = new ConcurrentLinkedDeque<>();
|
private final Deque<StatsHolder> _additionalMul = new ConcurrentLinkedDeque<>();
|
||||||
private final Map<Stats, Double> _fixedValue = new ConcurrentHashMap<>();
|
private final Map<Stats, Double> _fixedValue = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
private final float[] _attackTraits = new float[TraitType.values().length];
|
private final float[] _attackTraitValues = new float[TraitType.values().length];
|
||||||
private final float[] _defenceTraits = new float[TraitType.values().length];
|
private final float[] _defenceTraitValues = new float[TraitType.values().length];
|
||||||
private final int[] _attackTraitsCount = new int[TraitType.values().length];
|
private final Set<TraitType> _attackTraits = EnumSet.noneOf(TraitType.class);
|
||||||
private final int[] _defenceTraitsCount = new int[TraitType.values().length];
|
private final Set<TraitType> _defenceTraits = EnumSet.noneOf(TraitType.class);
|
||||||
private final int[] _traitsInvul = new int[TraitType.values().length];
|
private final Set<TraitType> _invulnerableTraits = EnumSet.noneOf(TraitType.class);
|
||||||
|
|
||||||
/** Values to be recalculated after every stat update */
|
/** Values to be recalculated after every stat update */
|
||||||
private double _attackSpeedMultiplier = 1;
|
private double _attackSpeedMultiplier = 1;
|
||||||
@@ -87,8 +87,6 @@ public class CreatureStat
|
|||||||
public CreatureStat(Creature creature)
|
public CreatureStat(Creature creature)
|
||||||
{
|
{
|
||||||
_creature = creature;
|
_creature = creature;
|
||||||
Arrays.fill(_attackTraits, 1.0f);
|
|
||||||
Arrays.fill(_defenceTraits, 1.0f);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -583,54 +581,86 @@ public class CreatureStat
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public float getAttackTrait(TraitType traitType)
|
public void mergeAttackTrait(TraitType traitType, float value)
|
||||||
{
|
{
|
||||||
return _attackTraits[traitType.ordinal()];
|
_attackTraitValues[traitType.ordinal()] *= value;
|
||||||
|
_attackTraits.add(traitType);
|
||||||
}
|
}
|
||||||
|
|
||||||
public float[] getAttackTraits()
|
public float getAttackTrait(TraitType traitType)
|
||||||
{
|
{
|
||||||
return _attackTraits;
|
_lock.readLock().lock();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return _attackTraitValues[traitType.ordinal()];
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
_lock.readLock().unlock();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasAttackTrait(TraitType traitType)
|
public boolean hasAttackTrait(TraitType traitType)
|
||||||
{
|
{
|
||||||
return _attackTraitsCount[traitType.ordinal()] > 0;
|
_lock.readLock().lock();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return _attackTraits.contains(traitType);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
_lock.readLock().unlock();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public int[] getAttackTraitsCount()
|
public void mergeDefenceTrait(TraitType traitType, float value)
|
||||||
{
|
{
|
||||||
return _attackTraitsCount;
|
_defenceTraitValues[traitType.ordinal()] *= value;
|
||||||
|
_defenceTraits.add(traitType);
|
||||||
}
|
}
|
||||||
|
|
||||||
public float getDefenceTrait(TraitType traitType)
|
public float getDefenceTrait(TraitType traitType)
|
||||||
{
|
{
|
||||||
return _defenceTraits[traitType.ordinal()];
|
_lock.readLock().lock();
|
||||||
}
|
try
|
||||||
|
{
|
||||||
public float[] getDefenceTraits()
|
return _defenceTraitValues[traitType.ordinal()];
|
||||||
{
|
}
|
||||||
return _defenceTraits;
|
finally
|
||||||
|
{
|
||||||
|
_lock.readLock().unlock();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasDefenceTrait(TraitType traitType)
|
public boolean hasDefenceTrait(TraitType traitType)
|
||||||
{
|
{
|
||||||
return _defenceTraitsCount[traitType.ordinal()] > 0;
|
_lock.readLock().lock();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return _defenceTraits.contains(traitType);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
_lock.readLock().unlock();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public int[] getDefenceTraitsCount()
|
public void mergeInvulnerableTrait(TraitType traitType)
|
||||||
{
|
{
|
||||||
return _defenceTraitsCount;
|
_invulnerableTraits.add(traitType);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isTraitInvul(TraitType traitType)
|
public boolean isInvulnerableTrait(TraitType traitType)
|
||||||
{
|
{
|
||||||
return _traitsInvul[traitType.ordinal()] > 0;
|
_lock.readLock().lock();
|
||||||
}
|
try
|
||||||
|
{
|
||||||
public int[] getTraitsInvul()
|
return _invulnerableTraits.contains(traitType);
|
||||||
{
|
}
|
||||||
return _traitsInvul;
|
finally
|
||||||
|
{
|
||||||
|
_lock.readLock().unlock();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1241,7 +1241,7 @@ public final class Formulas
|
|||||||
return 1.0;
|
return 1.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (target.getStat().isTraitInvul(traitType))
|
if (target.getStat().isInvulnerableTrait(traitType))
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -63,6 +63,14 @@ public enum TraitType
|
|||||||
PHYSICAL_WEAKNESS(3),
|
PHYSICAL_WEAKNESS(3),
|
||||||
MAGICAL_WEAKNESS(3),
|
MAGICAL_WEAKNESS(3),
|
||||||
DUALDAGGER(1),
|
DUALDAGGER(1),
|
||||||
|
DEMONIC_WEAKNESS(2), // CT26_P4
|
||||||
|
DIVINE_WEAKNESS(2),
|
||||||
|
ELEMENTAL_WEAKNESS(2),
|
||||||
|
FAIRY_WEAKNESS(2),
|
||||||
|
HUMAN_WEAKNESS(2),
|
||||||
|
HUMANOID_WEAKNESS(2),
|
||||||
|
UNDEAD_WEAKNESS(2),
|
||||||
|
// The values from below are custom.
|
||||||
DUALBLUNT(1),
|
DUALBLUNT(1),
|
||||||
KNOCKBACK(3),
|
KNOCKBACK(3),
|
||||||
KNOCKDOWN(3),
|
KNOCKDOWN(3),
|
||||||
@@ -75,7 +83,9 @@ public enum TraitType
|
|||||||
CHANGEBODY(3),
|
CHANGEBODY(3),
|
||||||
TWOHANDCROSSBOW(1),
|
TWOHANDCROSSBOW(1),
|
||||||
ZONE(3),
|
ZONE(3),
|
||||||
PSYCHIC(3);
|
PSYCHIC(3),
|
||||||
|
EMBRYO_WEAKNESS(2),
|
||||||
|
SPIRIT_WEAKNESS(2);
|
||||||
|
|
||||||
private final int _type; // 1 = weapon, 2 = weakness, 3 = resistance
|
private final int _type; // 1 = weapon, 2 = weakness, 3 = resistance
|
||||||
|
|
||||||
|
|||||||
@@ -22,9 +22,7 @@ import java.util.Map.Entry;
|
|||||||
|
|
||||||
import org.l2jmobius.gameserver.model.StatsSet;
|
import org.l2jmobius.gameserver.model.StatsSet;
|
||||||
import org.l2jmobius.gameserver.model.actor.Creature;
|
import org.l2jmobius.gameserver.model.actor.Creature;
|
||||||
import org.l2jmobius.gameserver.model.actor.stat.CreatureStat;
|
|
||||||
import org.l2jmobius.gameserver.model.effects.AbstractEffect;
|
import org.l2jmobius.gameserver.model.effects.AbstractEffect;
|
||||||
import org.l2jmobius.gameserver.model.items.instance.ItemInstance;
|
|
||||||
import org.l2jmobius.gameserver.model.skills.Skill;
|
import org.l2jmobius.gameserver.model.skills.Skill;
|
||||||
import org.l2jmobius.gameserver.model.stats.TraitType;
|
import org.l2jmobius.gameserver.model.stats.TraitType;
|
||||||
|
|
||||||
@@ -51,35 +49,11 @@ public final class AttackTrait extends AbstractEffect
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onExit(Creature effector, Creature effected, Skill skill)
|
public void pump(Creature effected, Skill skill)
|
||||||
{
|
{
|
||||||
final CreatureStat charStat = effected.getStat();
|
for (Entry<TraitType, Float> trait : _attackTraits.entrySet())
|
||||||
synchronized (charStat.getAttackTraits())
|
|
||||||
{
|
{
|
||||||
for (Entry<TraitType, Float> trait : _attackTraits.entrySet())
|
effected.getStat().mergeAttackTrait(trait.getKey(), trait.getValue());
|
||||||
{
|
|
||||||
if (charStat.getAttackTraitsCount()[trait.getKey().ordinal()] == 0)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
charStat.getAttackTraits()[trait.getKey().ordinal()] /= trait.getValue();
|
|
||||||
charStat.getAttackTraitsCount()[trait.getKey().ordinal()]--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onStart(Creature effector, Creature effected, Skill skill, ItemInstance item)
|
|
||||||
{
|
|
||||||
final CreatureStat charStat = effected.getStat();
|
|
||||||
synchronized (charStat.getAttackTraits())
|
|
||||||
{
|
|
||||||
for (Entry<TraitType, Float> trait : _attackTraits.entrySet())
|
|
||||||
{
|
|
||||||
charStat.getAttackTraits()[trait.getKey().ordinal()] *= trait.getValue();
|
|
||||||
charStat.getAttackTraitsCount()[trait.getKey().ordinal()]++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,9 +22,7 @@ import java.util.Map.Entry;
|
|||||||
|
|
||||||
import org.l2jmobius.gameserver.model.StatsSet;
|
import org.l2jmobius.gameserver.model.StatsSet;
|
||||||
import org.l2jmobius.gameserver.model.actor.Creature;
|
import org.l2jmobius.gameserver.model.actor.Creature;
|
||||||
import org.l2jmobius.gameserver.model.actor.stat.CreatureStat;
|
|
||||||
import org.l2jmobius.gameserver.model.effects.AbstractEffect;
|
import org.l2jmobius.gameserver.model.effects.AbstractEffect;
|
||||||
import org.l2jmobius.gameserver.model.items.instance.ItemInstance;
|
|
||||||
import org.l2jmobius.gameserver.model.skills.Skill;
|
import org.l2jmobius.gameserver.model.skills.Skill;
|
||||||
import org.l2jmobius.gameserver.model.stats.TraitType;
|
import org.l2jmobius.gameserver.model.stats.TraitType;
|
||||||
|
|
||||||
@@ -46,75 +44,22 @@ public final class DefenceTrait extends AbstractEffect
|
|||||||
|
|
||||||
for (Entry<String, Object> param : params.getSet().entrySet())
|
for (Entry<String, Object> param : params.getSet().entrySet())
|
||||||
{
|
{
|
||||||
try
|
_defenceTraits.put(TraitType.valueOf(param.getKey()), (Float.parseFloat((String) param.getValue()) + 100) / 100);
|
||||||
{
|
|
||||||
final TraitType traitType = TraitType.valueOf(param.getKey());
|
|
||||||
final float value = Float.parseFloat((String) param.getValue());
|
|
||||||
if (value == 0)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
_defenceTraits.put(traitType, (value + 100) / 100);
|
|
||||||
}
|
|
||||||
catch (NumberFormatException e)
|
|
||||||
{
|
|
||||||
LOGGER.warning(getClass().getSimpleName() + ": value of " + param.getKey() + " must be float value " + param.getValue() + " found.");
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
LOGGER.warning(getClass().getSimpleName() + ": value of TraitType enum required but found: " + param.getKey());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onExit(Creature effector, Creature effected, Skill skill)
|
public void pump(Creature effected, Skill skill)
|
||||||
{
|
{
|
||||||
final CreatureStat charStat = effected.getStat();
|
for (Entry<TraitType, Float> trait : _defenceTraits.entrySet())
|
||||||
synchronized (charStat.getDefenceTraits())
|
|
||||||
{
|
{
|
||||||
for (Entry<TraitType, Float> trait : _defenceTraits.entrySet())
|
if (trait.getValue() < 2.0f)
|
||||||
{
|
{
|
||||||
if (trait.getValue() < 2.0f)
|
effected.getStat().mergeDefenceTrait(trait.getKey(), trait.getValue());
|
||||||
{
|
|
||||||
if (charStat.getDefenceTraitsCount()[trait.getKey().ordinal()] == 0)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
charStat.getDefenceTraits()[trait.getKey().ordinal()] /= trait.getValue();
|
|
||||||
charStat.getDefenceTraitsCount()[trait.getKey().ordinal()]--;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (charStat.getTraitsInvul()[trait.getKey().ordinal()] == 0)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
charStat.getTraitsInvul()[trait.getKey().ordinal()]--;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
else
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onStart(Creature effector, Creature effected, Skill skill, ItemInstance item)
|
|
||||||
{
|
|
||||||
final CreatureStat charStat = effected.getStat();
|
|
||||||
synchronized (charStat.getDefenceTraits())
|
|
||||||
{
|
|
||||||
for (Entry<TraitType, Float> trait : _defenceTraits.entrySet())
|
|
||||||
{
|
{
|
||||||
if (trait.getValue() < 2.0f)
|
effected.getStat().mergeInvulnerableTrait(trait.getKey());
|
||||||
{
|
|
||||||
charStat.getDefenceTraits()[trait.getKey().ordinal()] *= trait.getValue();
|
|
||||||
charStat.getDefenceTraitsCount()[trait.getKey().ordinal()]++;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
charStat.getTraitsInvul()[trait.getKey().ordinal()]++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,10 +16,10 @@
|
|||||||
*/
|
*/
|
||||||
package org.l2jmobius.gameserver.model.actor.stat;
|
package org.l2jmobius.gameserver.model.actor.stat;
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Deque;
|
import java.util.Deque;
|
||||||
import java.util.EnumMap;
|
import java.util.EnumMap;
|
||||||
|
import java.util.EnumSet;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
@@ -72,11 +72,11 @@ public class CreatureStat
|
|||||||
private final Deque<StatsHolder> _additionalMul = new ConcurrentLinkedDeque<>();
|
private final Deque<StatsHolder> _additionalMul = new ConcurrentLinkedDeque<>();
|
||||||
private final Map<Stats, Double> _fixedValue = new ConcurrentHashMap<>();
|
private final Map<Stats, Double> _fixedValue = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
private final float[] _attackTraits = new float[TraitType.values().length];
|
private final float[] _attackTraitValues = new float[TraitType.values().length];
|
||||||
private final float[] _defenceTraits = new float[TraitType.values().length];
|
private final float[] _defenceTraitValues = new float[TraitType.values().length];
|
||||||
private final int[] _attackTraitsCount = new int[TraitType.values().length];
|
private final Set<TraitType> _attackTraits = EnumSet.noneOf(TraitType.class);
|
||||||
private final int[] _defenceTraitsCount = new int[TraitType.values().length];
|
private final Set<TraitType> _defenceTraits = EnumSet.noneOf(TraitType.class);
|
||||||
private final int[] _traitsInvul = new int[TraitType.values().length];
|
private final Set<TraitType> _invulnerableTraits = EnumSet.noneOf(TraitType.class);
|
||||||
|
|
||||||
/** Values to be recalculated after every stat update */
|
/** Values to be recalculated after every stat update */
|
||||||
private double _attackSpeedMultiplier = 1;
|
private double _attackSpeedMultiplier = 1;
|
||||||
@@ -87,8 +87,6 @@ public class CreatureStat
|
|||||||
public CreatureStat(Creature creature)
|
public CreatureStat(Creature creature)
|
||||||
{
|
{
|
||||||
_creature = creature;
|
_creature = creature;
|
||||||
Arrays.fill(_attackTraits, 1.0f);
|
|
||||||
Arrays.fill(_defenceTraits, 1.0f);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -583,54 +581,86 @@ public class CreatureStat
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public float getAttackTrait(TraitType traitType)
|
public void mergeAttackTrait(TraitType traitType, float value)
|
||||||
{
|
{
|
||||||
return _attackTraits[traitType.ordinal()];
|
_attackTraitValues[traitType.ordinal()] *= value;
|
||||||
|
_attackTraits.add(traitType);
|
||||||
}
|
}
|
||||||
|
|
||||||
public float[] getAttackTraits()
|
public float getAttackTrait(TraitType traitType)
|
||||||
{
|
{
|
||||||
return _attackTraits;
|
_lock.readLock().lock();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return _attackTraitValues[traitType.ordinal()];
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
_lock.readLock().unlock();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasAttackTrait(TraitType traitType)
|
public boolean hasAttackTrait(TraitType traitType)
|
||||||
{
|
{
|
||||||
return _attackTraitsCount[traitType.ordinal()] > 0;
|
_lock.readLock().lock();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return _attackTraits.contains(traitType);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
_lock.readLock().unlock();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public int[] getAttackTraitsCount()
|
public void mergeDefenceTrait(TraitType traitType, float value)
|
||||||
{
|
{
|
||||||
return _attackTraitsCount;
|
_defenceTraitValues[traitType.ordinal()] *= value;
|
||||||
|
_defenceTraits.add(traitType);
|
||||||
}
|
}
|
||||||
|
|
||||||
public float getDefenceTrait(TraitType traitType)
|
public float getDefenceTrait(TraitType traitType)
|
||||||
{
|
{
|
||||||
return _defenceTraits[traitType.ordinal()];
|
_lock.readLock().lock();
|
||||||
}
|
try
|
||||||
|
{
|
||||||
public float[] getDefenceTraits()
|
return _defenceTraitValues[traitType.ordinal()];
|
||||||
{
|
}
|
||||||
return _defenceTraits;
|
finally
|
||||||
|
{
|
||||||
|
_lock.readLock().unlock();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasDefenceTrait(TraitType traitType)
|
public boolean hasDefenceTrait(TraitType traitType)
|
||||||
{
|
{
|
||||||
return _defenceTraitsCount[traitType.ordinal()] > 0;
|
_lock.readLock().lock();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return _defenceTraits.contains(traitType);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
_lock.readLock().unlock();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public int[] getDefenceTraitsCount()
|
public void mergeInvulnerableTrait(TraitType traitType)
|
||||||
{
|
{
|
||||||
return _defenceTraitsCount;
|
_invulnerableTraits.add(traitType);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isTraitInvul(TraitType traitType)
|
public boolean isInvulnerableTrait(TraitType traitType)
|
||||||
{
|
{
|
||||||
return _traitsInvul[traitType.ordinal()] > 0;
|
_lock.readLock().lock();
|
||||||
}
|
try
|
||||||
|
{
|
||||||
public int[] getTraitsInvul()
|
return _invulnerableTraits.contains(traitType);
|
||||||
{
|
}
|
||||||
return _traitsInvul;
|
finally
|
||||||
|
{
|
||||||
|
_lock.readLock().unlock();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1241,7 +1241,7 @@ public final class Formulas
|
|||||||
return 1.0;
|
return 1.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (target.getStat().isTraitInvul(traitType))
|
if (target.getStat().isInvulnerableTrait(traitType))
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -63,6 +63,14 @@ public enum TraitType
|
|||||||
PHYSICAL_WEAKNESS(3),
|
PHYSICAL_WEAKNESS(3),
|
||||||
MAGICAL_WEAKNESS(3),
|
MAGICAL_WEAKNESS(3),
|
||||||
DUALDAGGER(1),
|
DUALDAGGER(1),
|
||||||
|
DEMONIC_WEAKNESS(2), // CT26_P4
|
||||||
|
DIVINE_WEAKNESS(2),
|
||||||
|
ELEMENTAL_WEAKNESS(2),
|
||||||
|
FAIRY_WEAKNESS(2),
|
||||||
|
HUMAN_WEAKNESS(2),
|
||||||
|
HUMANOID_WEAKNESS(2),
|
||||||
|
UNDEAD_WEAKNESS(2),
|
||||||
|
// The values from below are custom.
|
||||||
DUALBLUNT(1),
|
DUALBLUNT(1),
|
||||||
KNOCKBACK(3),
|
KNOCKBACK(3),
|
||||||
KNOCKDOWN(3),
|
KNOCKDOWN(3),
|
||||||
@@ -75,7 +83,9 @@ public enum TraitType
|
|||||||
CHANGEBODY(3),
|
CHANGEBODY(3),
|
||||||
TWOHANDCROSSBOW(1),
|
TWOHANDCROSSBOW(1),
|
||||||
ZONE(3),
|
ZONE(3),
|
||||||
PSYCHIC(3);
|
PSYCHIC(3),
|
||||||
|
EMBRYO_WEAKNESS(2),
|
||||||
|
SPIRIT_WEAKNESS(2);
|
||||||
|
|
||||||
private final int _type; // 1 = weapon, 2 = weakness, 3 = resistance
|
private final int _type; // 1 = weapon, 2 = weakness, 3 = resistance
|
||||||
|
|
||||||
|
|||||||
@@ -22,9 +22,7 @@ import java.util.Map.Entry;
|
|||||||
|
|
||||||
import org.l2jmobius.gameserver.model.StatsSet;
|
import org.l2jmobius.gameserver.model.StatsSet;
|
||||||
import org.l2jmobius.gameserver.model.actor.Creature;
|
import org.l2jmobius.gameserver.model.actor.Creature;
|
||||||
import org.l2jmobius.gameserver.model.actor.stat.CreatureStat;
|
|
||||||
import org.l2jmobius.gameserver.model.effects.AbstractEffect;
|
import org.l2jmobius.gameserver.model.effects.AbstractEffect;
|
||||||
import org.l2jmobius.gameserver.model.items.instance.ItemInstance;
|
|
||||||
import org.l2jmobius.gameserver.model.skills.Skill;
|
import org.l2jmobius.gameserver.model.skills.Skill;
|
||||||
import org.l2jmobius.gameserver.model.stats.TraitType;
|
import org.l2jmobius.gameserver.model.stats.TraitType;
|
||||||
|
|
||||||
@@ -51,35 +49,11 @@ public final class AttackTrait extends AbstractEffect
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onExit(Creature effector, Creature effected, Skill skill)
|
public void pump(Creature effected, Skill skill)
|
||||||
{
|
{
|
||||||
final CreatureStat charStat = effected.getStat();
|
for (Entry<TraitType, Float> trait : _attackTraits.entrySet())
|
||||||
synchronized (charStat.getAttackTraits())
|
|
||||||
{
|
{
|
||||||
for (Entry<TraitType, Float> trait : _attackTraits.entrySet())
|
effected.getStat().mergeAttackTrait(trait.getKey(), trait.getValue());
|
||||||
{
|
|
||||||
if (charStat.getAttackTraitsCount()[trait.getKey().ordinal()] == 0)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
charStat.getAttackTraits()[trait.getKey().ordinal()] /= trait.getValue();
|
|
||||||
charStat.getAttackTraitsCount()[trait.getKey().ordinal()]--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onStart(Creature effector, Creature effected, Skill skill, ItemInstance item)
|
|
||||||
{
|
|
||||||
final CreatureStat charStat = effected.getStat();
|
|
||||||
synchronized (charStat.getAttackTraits())
|
|
||||||
{
|
|
||||||
for (Entry<TraitType, Float> trait : _attackTraits.entrySet())
|
|
||||||
{
|
|
||||||
charStat.getAttackTraits()[trait.getKey().ordinal()] *= trait.getValue();
|
|
||||||
charStat.getAttackTraitsCount()[trait.getKey().ordinal()]++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,9 +22,7 @@ import java.util.Map.Entry;
|
|||||||
|
|
||||||
import org.l2jmobius.gameserver.model.StatsSet;
|
import org.l2jmobius.gameserver.model.StatsSet;
|
||||||
import org.l2jmobius.gameserver.model.actor.Creature;
|
import org.l2jmobius.gameserver.model.actor.Creature;
|
||||||
import org.l2jmobius.gameserver.model.actor.stat.CreatureStat;
|
|
||||||
import org.l2jmobius.gameserver.model.effects.AbstractEffect;
|
import org.l2jmobius.gameserver.model.effects.AbstractEffect;
|
||||||
import org.l2jmobius.gameserver.model.items.instance.ItemInstance;
|
|
||||||
import org.l2jmobius.gameserver.model.skills.Skill;
|
import org.l2jmobius.gameserver.model.skills.Skill;
|
||||||
import org.l2jmobius.gameserver.model.stats.TraitType;
|
import org.l2jmobius.gameserver.model.stats.TraitType;
|
||||||
|
|
||||||
@@ -46,75 +44,22 @@ public final class DefenceTrait extends AbstractEffect
|
|||||||
|
|
||||||
for (Entry<String, Object> param : params.getSet().entrySet())
|
for (Entry<String, Object> param : params.getSet().entrySet())
|
||||||
{
|
{
|
||||||
try
|
_defenceTraits.put(TraitType.valueOf(param.getKey()), (Float.parseFloat((String) param.getValue()) + 100) / 100);
|
||||||
{
|
|
||||||
final TraitType traitType = TraitType.valueOf(param.getKey());
|
|
||||||
final float value = Float.parseFloat((String) param.getValue());
|
|
||||||
if (value == 0)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
_defenceTraits.put(traitType, (value + 100) / 100);
|
|
||||||
}
|
|
||||||
catch (NumberFormatException e)
|
|
||||||
{
|
|
||||||
LOGGER.warning(getClass().getSimpleName() + ": value of " + param.getKey() + " must be float value " + param.getValue() + " found.");
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
LOGGER.warning(getClass().getSimpleName() + ": value of TraitType enum required but found: " + param.getKey());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onExit(Creature effector, Creature effected, Skill skill)
|
public void pump(Creature effected, Skill skill)
|
||||||
{
|
{
|
||||||
final CreatureStat charStat = effected.getStat();
|
for (Entry<TraitType, Float> trait : _defenceTraits.entrySet())
|
||||||
synchronized (charStat.getDefenceTraits())
|
|
||||||
{
|
{
|
||||||
for (Entry<TraitType, Float> trait : _defenceTraits.entrySet())
|
if (trait.getValue() < 2.0f)
|
||||||
{
|
{
|
||||||
if (trait.getValue() < 2.0f)
|
effected.getStat().mergeDefenceTrait(trait.getKey(), trait.getValue());
|
||||||
{
|
|
||||||
if (charStat.getDefenceTraitsCount()[trait.getKey().ordinal()] == 0)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
charStat.getDefenceTraits()[trait.getKey().ordinal()] /= trait.getValue();
|
|
||||||
charStat.getDefenceTraitsCount()[trait.getKey().ordinal()]--;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (charStat.getTraitsInvul()[trait.getKey().ordinal()] == 0)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
charStat.getTraitsInvul()[trait.getKey().ordinal()]--;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
else
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onStart(Creature effector, Creature effected, Skill skill, ItemInstance item)
|
|
||||||
{
|
|
||||||
final CreatureStat charStat = effected.getStat();
|
|
||||||
synchronized (charStat.getDefenceTraits())
|
|
||||||
{
|
|
||||||
for (Entry<TraitType, Float> trait : _defenceTraits.entrySet())
|
|
||||||
{
|
{
|
||||||
if (trait.getValue() < 2.0f)
|
effected.getStat().mergeInvulnerableTrait(trait.getKey());
|
||||||
{
|
|
||||||
charStat.getDefenceTraits()[trait.getKey().ordinal()] *= trait.getValue();
|
|
||||||
charStat.getDefenceTraitsCount()[trait.getKey().ordinal()]++;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
charStat.getTraitsInvul()[trait.getKey().ordinal()]++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,10 +16,10 @@
|
|||||||
*/
|
*/
|
||||||
package org.l2jmobius.gameserver.model.actor.stat;
|
package org.l2jmobius.gameserver.model.actor.stat;
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Deque;
|
import java.util.Deque;
|
||||||
import java.util.EnumMap;
|
import java.util.EnumMap;
|
||||||
|
import java.util.EnumSet;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
@@ -72,11 +72,11 @@ public class CreatureStat
|
|||||||
private final Deque<StatsHolder> _additionalMul = new ConcurrentLinkedDeque<>();
|
private final Deque<StatsHolder> _additionalMul = new ConcurrentLinkedDeque<>();
|
||||||
private final Map<Stats, Double> _fixedValue = new ConcurrentHashMap<>();
|
private final Map<Stats, Double> _fixedValue = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
private final float[] _attackTraits = new float[TraitType.values().length];
|
private final float[] _attackTraitValues = new float[TraitType.values().length];
|
||||||
private final float[] _defenceTraits = new float[TraitType.values().length];
|
private final float[] _defenceTraitValues = new float[TraitType.values().length];
|
||||||
private final int[] _attackTraitsCount = new int[TraitType.values().length];
|
private final Set<TraitType> _attackTraits = EnumSet.noneOf(TraitType.class);
|
||||||
private final int[] _defenceTraitsCount = new int[TraitType.values().length];
|
private final Set<TraitType> _defenceTraits = EnumSet.noneOf(TraitType.class);
|
||||||
private final int[] _traitsInvul = new int[TraitType.values().length];
|
private final Set<TraitType> _invulnerableTraits = EnumSet.noneOf(TraitType.class);
|
||||||
|
|
||||||
/** Values to be recalculated after every stat update */
|
/** Values to be recalculated after every stat update */
|
||||||
private double _attackSpeedMultiplier = 1;
|
private double _attackSpeedMultiplier = 1;
|
||||||
@@ -87,8 +87,6 @@ public class CreatureStat
|
|||||||
public CreatureStat(Creature creature)
|
public CreatureStat(Creature creature)
|
||||||
{
|
{
|
||||||
_creature = creature;
|
_creature = creature;
|
||||||
Arrays.fill(_attackTraits, 1.0f);
|
|
||||||
Arrays.fill(_defenceTraits, 1.0f);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -583,54 +581,86 @@ public class CreatureStat
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public float getAttackTrait(TraitType traitType)
|
public void mergeAttackTrait(TraitType traitType, float value)
|
||||||
{
|
{
|
||||||
return _attackTraits[traitType.ordinal()];
|
_attackTraitValues[traitType.ordinal()] *= value;
|
||||||
|
_attackTraits.add(traitType);
|
||||||
}
|
}
|
||||||
|
|
||||||
public float[] getAttackTraits()
|
public float getAttackTrait(TraitType traitType)
|
||||||
{
|
{
|
||||||
return _attackTraits;
|
_lock.readLock().lock();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return _attackTraitValues[traitType.ordinal()];
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
_lock.readLock().unlock();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasAttackTrait(TraitType traitType)
|
public boolean hasAttackTrait(TraitType traitType)
|
||||||
{
|
{
|
||||||
return _attackTraitsCount[traitType.ordinal()] > 0;
|
_lock.readLock().lock();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return _attackTraits.contains(traitType);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
_lock.readLock().unlock();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public int[] getAttackTraitsCount()
|
public void mergeDefenceTrait(TraitType traitType, float value)
|
||||||
{
|
{
|
||||||
return _attackTraitsCount;
|
_defenceTraitValues[traitType.ordinal()] *= value;
|
||||||
|
_defenceTraits.add(traitType);
|
||||||
}
|
}
|
||||||
|
|
||||||
public float getDefenceTrait(TraitType traitType)
|
public float getDefenceTrait(TraitType traitType)
|
||||||
{
|
{
|
||||||
return _defenceTraits[traitType.ordinal()];
|
_lock.readLock().lock();
|
||||||
}
|
try
|
||||||
|
{
|
||||||
public float[] getDefenceTraits()
|
return _defenceTraitValues[traitType.ordinal()];
|
||||||
{
|
}
|
||||||
return _defenceTraits;
|
finally
|
||||||
|
{
|
||||||
|
_lock.readLock().unlock();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasDefenceTrait(TraitType traitType)
|
public boolean hasDefenceTrait(TraitType traitType)
|
||||||
{
|
{
|
||||||
return _defenceTraitsCount[traitType.ordinal()] > 0;
|
_lock.readLock().lock();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return _defenceTraits.contains(traitType);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
_lock.readLock().unlock();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public int[] getDefenceTraitsCount()
|
public void mergeInvulnerableTrait(TraitType traitType)
|
||||||
{
|
{
|
||||||
return _defenceTraitsCount;
|
_invulnerableTraits.add(traitType);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isTraitInvul(TraitType traitType)
|
public boolean isInvulnerableTrait(TraitType traitType)
|
||||||
{
|
{
|
||||||
return _traitsInvul[traitType.ordinal()] > 0;
|
_lock.readLock().lock();
|
||||||
}
|
try
|
||||||
|
{
|
||||||
public int[] getTraitsInvul()
|
return _invulnerableTraits.contains(traitType);
|
||||||
{
|
}
|
||||||
return _traitsInvul;
|
finally
|
||||||
|
{
|
||||||
|
_lock.readLock().unlock();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1241,7 +1241,7 @@ public final class Formulas
|
|||||||
return 1.0;
|
return 1.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (target.getStat().isTraitInvul(traitType))
|
if (target.getStat().isInvulnerableTrait(traitType))
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -63,6 +63,14 @@ public enum TraitType
|
|||||||
PHYSICAL_WEAKNESS(3),
|
PHYSICAL_WEAKNESS(3),
|
||||||
MAGICAL_WEAKNESS(3),
|
MAGICAL_WEAKNESS(3),
|
||||||
DUALDAGGER(1),
|
DUALDAGGER(1),
|
||||||
|
DEMONIC_WEAKNESS(2), // CT26_P4
|
||||||
|
DIVINE_WEAKNESS(2),
|
||||||
|
ELEMENTAL_WEAKNESS(2),
|
||||||
|
FAIRY_WEAKNESS(2),
|
||||||
|
HUMAN_WEAKNESS(2),
|
||||||
|
HUMANOID_WEAKNESS(2),
|
||||||
|
UNDEAD_WEAKNESS(2),
|
||||||
|
// The values from below are custom.
|
||||||
DUALBLUNT(1),
|
DUALBLUNT(1),
|
||||||
KNOCKBACK(3),
|
KNOCKBACK(3),
|
||||||
KNOCKDOWN(3),
|
KNOCKDOWN(3),
|
||||||
@@ -75,7 +83,9 @@ public enum TraitType
|
|||||||
CHANGEBODY(3),
|
CHANGEBODY(3),
|
||||||
TWOHANDCROSSBOW(1),
|
TWOHANDCROSSBOW(1),
|
||||||
ZONE(3),
|
ZONE(3),
|
||||||
PSYCHIC(3);
|
PSYCHIC(3),
|
||||||
|
EMBRYO_WEAKNESS(2),
|
||||||
|
SPIRIT_WEAKNESS(2);
|
||||||
|
|
||||||
private final int _type; // 1 = weapon, 2 = weakness, 3 = resistance
|
private final int _type; // 1 = weapon, 2 = weakness, 3 = resistance
|
||||||
|
|
||||||
|
|||||||
@@ -22,9 +22,7 @@ import java.util.Map.Entry;
|
|||||||
|
|
||||||
import org.l2jmobius.gameserver.model.StatsSet;
|
import org.l2jmobius.gameserver.model.StatsSet;
|
||||||
import org.l2jmobius.gameserver.model.actor.Creature;
|
import org.l2jmobius.gameserver.model.actor.Creature;
|
||||||
import org.l2jmobius.gameserver.model.actor.stat.CreatureStat;
|
|
||||||
import org.l2jmobius.gameserver.model.effects.AbstractEffect;
|
import org.l2jmobius.gameserver.model.effects.AbstractEffect;
|
||||||
import org.l2jmobius.gameserver.model.items.instance.ItemInstance;
|
|
||||||
import org.l2jmobius.gameserver.model.skills.Skill;
|
import org.l2jmobius.gameserver.model.skills.Skill;
|
||||||
import org.l2jmobius.gameserver.model.stats.TraitType;
|
import org.l2jmobius.gameserver.model.stats.TraitType;
|
||||||
|
|
||||||
@@ -51,35 +49,11 @@ public final class AttackTrait extends AbstractEffect
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onExit(Creature effector, Creature effected, Skill skill)
|
public void pump(Creature effected, Skill skill)
|
||||||
{
|
{
|
||||||
final CreatureStat charStat = effected.getStat();
|
for (Entry<TraitType, Float> trait : _attackTraits.entrySet())
|
||||||
synchronized (charStat.getAttackTraits())
|
|
||||||
{
|
{
|
||||||
for (Entry<TraitType, Float> trait : _attackTraits.entrySet())
|
effected.getStat().mergeAttackTrait(trait.getKey(), trait.getValue());
|
||||||
{
|
|
||||||
if (charStat.getAttackTraitsCount()[trait.getKey().ordinal()] == 0)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
charStat.getAttackTraits()[trait.getKey().ordinal()] /= trait.getValue();
|
|
||||||
charStat.getAttackTraitsCount()[trait.getKey().ordinal()]--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onStart(Creature effector, Creature effected, Skill skill, ItemInstance item)
|
|
||||||
{
|
|
||||||
final CreatureStat charStat = effected.getStat();
|
|
||||||
synchronized (charStat.getAttackTraits())
|
|
||||||
{
|
|
||||||
for (Entry<TraitType, Float> trait : _attackTraits.entrySet())
|
|
||||||
{
|
|
||||||
charStat.getAttackTraits()[trait.getKey().ordinal()] *= trait.getValue();
|
|
||||||
charStat.getAttackTraitsCount()[trait.getKey().ordinal()]++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,9 +22,7 @@ import java.util.Map.Entry;
|
|||||||
|
|
||||||
import org.l2jmobius.gameserver.model.StatsSet;
|
import org.l2jmobius.gameserver.model.StatsSet;
|
||||||
import org.l2jmobius.gameserver.model.actor.Creature;
|
import org.l2jmobius.gameserver.model.actor.Creature;
|
||||||
import org.l2jmobius.gameserver.model.actor.stat.CreatureStat;
|
|
||||||
import org.l2jmobius.gameserver.model.effects.AbstractEffect;
|
import org.l2jmobius.gameserver.model.effects.AbstractEffect;
|
||||||
import org.l2jmobius.gameserver.model.items.instance.ItemInstance;
|
|
||||||
import org.l2jmobius.gameserver.model.skills.Skill;
|
import org.l2jmobius.gameserver.model.skills.Skill;
|
||||||
import org.l2jmobius.gameserver.model.stats.TraitType;
|
import org.l2jmobius.gameserver.model.stats.TraitType;
|
||||||
|
|
||||||
@@ -46,75 +44,22 @@ public final class DefenceTrait extends AbstractEffect
|
|||||||
|
|
||||||
for (Entry<String, Object> param : params.getSet().entrySet())
|
for (Entry<String, Object> param : params.getSet().entrySet())
|
||||||
{
|
{
|
||||||
try
|
_defenceTraits.put(TraitType.valueOf(param.getKey()), (Float.parseFloat((String) param.getValue()) + 100) / 100);
|
||||||
{
|
|
||||||
final TraitType traitType = TraitType.valueOf(param.getKey());
|
|
||||||
final float value = Float.parseFloat((String) param.getValue());
|
|
||||||
if (value == 0)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
_defenceTraits.put(traitType, (value + 100) / 100);
|
|
||||||
}
|
|
||||||
catch (NumberFormatException e)
|
|
||||||
{
|
|
||||||
LOGGER.warning(getClass().getSimpleName() + ": value of " + param.getKey() + " must be float value " + param.getValue() + " found.");
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
LOGGER.warning(getClass().getSimpleName() + ": value of TraitType enum required but found: " + param.getKey());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onExit(Creature effector, Creature effected, Skill skill)
|
public void pump(Creature effected, Skill skill)
|
||||||
{
|
{
|
||||||
final CreatureStat charStat = effected.getStat();
|
for (Entry<TraitType, Float> trait : _defenceTraits.entrySet())
|
||||||
synchronized (charStat.getDefenceTraits())
|
|
||||||
{
|
{
|
||||||
for (Entry<TraitType, Float> trait : _defenceTraits.entrySet())
|
if (trait.getValue() < 2.0f)
|
||||||
{
|
{
|
||||||
if (trait.getValue() < 2.0f)
|
effected.getStat().mergeDefenceTrait(trait.getKey(), trait.getValue());
|
||||||
{
|
|
||||||
if (charStat.getDefenceTraitsCount()[trait.getKey().ordinal()] == 0)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
charStat.getDefenceTraits()[trait.getKey().ordinal()] /= trait.getValue();
|
|
||||||
charStat.getDefenceTraitsCount()[trait.getKey().ordinal()]--;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (charStat.getTraitsInvul()[trait.getKey().ordinal()] == 0)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
charStat.getTraitsInvul()[trait.getKey().ordinal()]--;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
else
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onStart(Creature effector, Creature effected, Skill skill, ItemInstance item)
|
|
||||||
{
|
|
||||||
final CreatureStat charStat = effected.getStat();
|
|
||||||
synchronized (charStat.getDefenceTraits())
|
|
||||||
{
|
|
||||||
for (Entry<TraitType, Float> trait : _defenceTraits.entrySet())
|
|
||||||
{
|
{
|
||||||
if (trait.getValue() < 2.0f)
|
effected.getStat().mergeInvulnerableTrait(trait.getKey());
|
||||||
{
|
|
||||||
charStat.getDefenceTraits()[trait.getKey().ordinal()] *= trait.getValue();
|
|
||||||
charStat.getDefenceTraitsCount()[trait.getKey().ordinal()]++;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
charStat.getTraitsInvul()[trait.getKey().ordinal()]++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,10 +16,10 @@
|
|||||||
*/
|
*/
|
||||||
package org.l2jmobius.gameserver.model.actor.stat;
|
package org.l2jmobius.gameserver.model.actor.stat;
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Deque;
|
import java.util.Deque;
|
||||||
import java.util.EnumMap;
|
import java.util.EnumMap;
|
||||||
|
import java.util.EnumSet;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
@@ -72,11 +72,11 @@ public class CreatureStat
|
|||||||
private final Deque<StatsHolder> _additionalMul = new ConcurrentLinkedDeque<>();
|
private final Deque<StatsHolder> _additionalMul = new ConcurrentLinkedDeque<>();
|
||||||
private final Map<Stats, Double> _fixedValue = new ConcurrentHashMap<>();
|
private final Map<Stats, Double> _fixedValue = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
private final float[] _attackTraits = new float[TraitType.values().length];
|
private final float[] _attackTraitValues = new float[TraitType.values().length];
|
||||||
private final float[] _defenceTraits = new float[TraitType.values().length];
|
private final float[] _defenceTraitValues = new float[TraitType.values().length];
|
||||||
private final int[] _attackTraitsCount = new int[TraitType.values().length];
|
private final Set<TraitType> _attackTraits = EnumSet.noneOf(TraitType.class);
|
||||||
private final int[] _defenceTraitsCount = new int[TraitType.values().length];
|
private final Set<TraitType> _defenceTraits = EnumSet.noneOf(TraitType.class);
|
||||||
private final int[] _traitsInvul = new int[TraitType.values().length];
|
private final Set<TraitType> _invulnerableTraits = EnumSet.noneOf(TraitType.class);
|
||||||
|
|
||||||
/** Values to be recalculated after every stat update */
|
/** Values to be recalculated after every stat update */
|
||||||
private double _attackSpeedMultiplier = 1;
|
private double _attackSpeedMultiplier = 1;
|
||||||
@@ -87,8 +87,6 @@ public class CreatureStat
|
|||||||
public CreatureStat(Creature creature)
|
public CreatureStat(Creature creature)
|
||||||
{
|
{
|
||||||
_creature = creature;
|
_creature = creature;
|
||||||
Arrays.fill(_attackTraits, 1.0f);
|
|
||||||
Arrays.fill(_defenceTraits, 1.0f);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -583,54 +581,86 @@ public class CreatureStat
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public float getAttackTrait(TraitType traitType)
|
public void mergeAttackTrait(TraitType traitType, float value)
|
||||||
{
|
{
|
||||||
return _attackTraits[traitType.ordinal()];
|
_attackTraitValues[traitType.ordinal()] *= value;
|
||||||
|
_attackTraits.add(traitType);
|
||||||
}
|
}
|
||||||
|
|
||||||
public float[] getAttackTraits()
|
public float getAttackTrait(TraitType traitType)
|
||||||
{
|
{
|
||||||
return _attackTraits;
|
_lock.readLock().lock();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return _attackTraitValues[traitType.ordinal()];
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
_lock.readLock().unlock();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasAttackTrait(TraitType traitType)
|
public boolean hasAttackTrait(TraitType traitType)
|
||||||
{
|
{
|
||||||
return _attackTraitsCount[traitType.ordinal()] > 0;
|
_lock.readLock().lock();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return _attackTraits.contains(traitType);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
_lock.readLock().unlock();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public int[] getAttackTraitsCount()
|
public void mergeDefenceTrait(TraitType traitType, float value)
|
||||||
{
|
{
|
||||||
return _attackTraitsCount;
|
_defenceTraitValues[traitType.ordinal()] *= value;
|
||||||
|
_defenceTraits.add(traitType);
|
||||||
}
|
}
|
||||||
|
|
||||||
public float getDefenceTrait(TraitType traitType)
|
public float getDefenceTrait(TraitType traitType)
|
||||||
{
|
{
|
||||||
return _defenceTraits[traitType.ordinal()];
|
_lock.readLock().lock();
|
||||||
}
|
try
|
||||||
|
{
|
||||||
public float[] getDefenceTraits()
|
return _defenceTraitValues[traitType.ordinal()];
|
||||||
{
|
}
|
||||||
return _defenceTraits;
|
finally
|
||||||
|
{
|
||||||
|
_lock.readLock().unlock();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasDefenceTrait(TraitType traitType)
|
public boolean hasDefenceTrait(TraitType traitType)
|
||||||
{
|
{
|
||||||
return _defenceTraitsCount[traitType.ordinal()] > 0;
|
_lock.readLock().lock();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return _defenceTraits.contains(traitType);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
_lock.readLock().unlock();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public int[] getDefenceTraitsCount()
|
public void mergeInvulnerableTrait(TraitType traitType)
|
||||||
{
|
{
|
||||||
return _defenceTraitsCount;
|
_invulnerableTraits.add(traitType);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isTraitInvul(TraitType traitType)
|
public boolean isInvulnerableTrait(TraitType traitType)
|
||||||
{
|
{
|
||||||
return _traitsInvul[traitType.ordinal()] > 0;
|
_lock.readLock().lock();
|
||||||
}
|
try
|
||||||
|
{
|
||||||
public int[] getTraitsInvul()
|
return _invulnerableTraits.contains(traitType);
|
||||||
{
|
}
|
||||||
return _traitsInvul;
|
finally
|
||||||
|
{
|
||||||
|
_lock.readLock().unlock();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1241,7 +1241,7 @@ public final class Formulas
|
|||||||
return 1.0;
|
return 1.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (target.getStat().isTraitInvul(traitType))
|
if (target.getStat().isInvulnerableTrait(traitType))
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,91 +1,101 @@
|
|||||||
/*
|
/*
|
||||||
* This file is part of the L2J Mobius project.
|
* This file is part of the L2J Mobius project.
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
* General Public License for more details.
|
* General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package org.l2jmobius.gameserver.model.stats;
|
package org.l2jmobius.gameserver.model.stats;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author UnAfraid, NosBit
|
* @author UnAfraid, NosBit
|
||||||
*/
|
*/
|
||||||
public enum TraitType
|
public enum TraitType
|
||||||
{
|
{
|
||||||
NONE(0),
|
NONE(0),
|
||||||
SWORD(1),
|
SWORD(1),
|
||||||
BLUNT(1),
|
BLUNT(1),
|
||||||
DAGGER(1),
|
DAGGER(1),
|
||||||
POLE(1),
|
POLE(1),
|
||||||
FIST(1),
|
FIST(1),
|
||||||
BOW(1),
|
BOW(1),
|
||||||
ETC(1),
|
ETC(1),
|
||||||
UNK_8(0),
|
UNK_8(0),
|
||||||
POISON(3),
|
POISON(3),
|
||||||
HOLD(3),
|
HOLD(3),
|
||||||
BLEED(3),
|
BLEED(3),
|
||||||
SLEEP(3),
|
SLEEP(3),
|
||||||
SHOCK(3),
|
SHOCK(3),
|
||||||
DERANGEMENT(3),
|
DERANGEMENT(3),
|
||||||
BUG_WEAKNESS(2),
|
BUG_WEAKNESS(2),
|
||||||
ANIMAL_WEAKNESS(2),
|
ANIMAL_WEAKNESS(2),
|
||||||
PLANT_WEAKNESS(2),
|
PLANT_WEAKNESS(2),
|
||||||
BEAST_WEAKNESS(2),
|
BEAST_WEAKNESS(2),
|
||||||
DRAGON_WEAKNESS(2),
|
DRAGON_WEAKNESS(2),
|
||||||
PARALYZE(3),
|
PARALYZE(3),
|
||||||
DUAL(1),
|
DUAL(1),
|
||||||
DUALFIST(1),
|
DUALFIST(1),
|
||||||
BOSS(3),
|
BOSS(3),
|
||||||
GIANT_WEAKNESS(2),
|
GIANT_WEAKNESS(2),
|
||||||
CONSTRUCT_WEAKNESS(2),
|
CONSTRUCT_WEAKNESS(2),
|
||||||
DEATH(3),
|
DEATH(3),
|
||||||
VALAKAS(2),
|
VALAKAS(2),
|
||||||
ANESTHESIA(2),
|
ANESTHESIA(2),
|
||||||
CRITICAL_POISON(3),
|
CRITICAL_POISON(3),
|
||||||
ROOT_PHYSICALLY(3),
|
ROOT_PHYSICALLY(3),
|
||||||
ROOT_MAGICALLY(3),
|
ROOT_MAGICALLY(3),
|
||||||
RAPIER(1),
|
RAPIER(1),
|
||||||
CROSSBOW(1),
|
CROSSBOW(1),
|
||||||
ANCIENTSWORD(1),
|
ANCIENTSWORD(1),
|
||||||
TURN_STONE(3),
|
TURN_STONE(3),
|
||||||
GUST(3),
|
GUST(3),
|
||||||
PHYSICAL_BLOCKADE(3),
|
PHYSICAL_BLOCKADE(3),
|
||||||
TARGET(3),
|
TARGET(3),
|
||||||
PHYSICAL_WEAKNESS(3),
|
PHYSICAL_WEAKNESS(3),
|
||||||
MAGICAL_WEAKNESS(3),
|
MAGICAL_WEAKNESS(3),
|
||||||
DUALDAGGER(1),
|
DUALDAGGER(1),
|
||||||
DUALBLUNT(1),
|
DEMONIC_WEAKNESS(2), // CT26_P4
|
||||||
KNOCKBACK(3),
|
DIVINE_WEAKNESS(2),
|
||||||
KNOCKDOWN(3),
|
ELEMENTAL_WEAKNESS(2),
|
||||||
PULL(3),
|
FAIRY_WEAKNESS(2),
|
||||||
HATE(3),
|
HUMAN_WEAKNESS(2),
|
||||||
AGGRESSION(3),
|
HUMANOID_WEAKNESS(2),
|
||||||
AIRBIND(3),
|
UNDEAD_WEAKNESS(2),
|
||||||
DISARM(3),
|
// The values from below are custom.
|
||||||
DEPORT(3),
|
DUALBLUNT(1),
|
||||||
CHANGEBODY(3),
|
KNOCKBACK(3),
|
||||||
TWOHANDCROSSBOW(1),
|
KNOCKDOWN(3),
|
||||||
ZONE(3),
|
PULL(3),
|
||||||
PSYCHIC(3);
|
HATE(3),
|
||||||
|
AGGRESSION(3),
|
||||||
private final int _type; // 1 = weapon, 2 = weakness, 3 = resistance
|
AIRBIND(3),
|
||||||
|
DISARM(3),
|
||||||
TraitType(int type)
|
DEPORT(3),
|
||||||
{
|
CHANGEBODY(3),
|
||||||
_type = type;
|
TWOHANDCROSSBOW(1),
|
||||||
}
|
ZONE(3),
|
||||||
|
PSYCHIC(3),
|
||||||
public int getType()
|
EMBRYO_WEAKNESS(2),
|
||||||
{
|
SPIRIT_WEAKNESS(2);
|
||||||
return _type;
|
|
||||||
}
|
private final int _type; // 1 = weapon, 2 = weakness, 3 = resistance
|
||||||
}
|
|
||||||
|
TraitType(int type)
|
||||||
|
{
|
||||||
|
_type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getType()
|
||||||
|
{
|
||||||
|
return _type;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -22,9 +22,7 @@ import java.util.Map.Entry;
|
|||||||
|
|
||||||
import org.l2jmobius.gameserver.model.StatsSet;
|
import org.l2jmobius.gameserver.model.StatsSet;
|
||||||
import org.l2jmobius.gameserver.model.actor.Creature;
|
import org.l2jmobius.gameserver.model.actor.Creature;
|
||||||
import org.l2jmobius.gameserver.model.actor.stat.CreatureStat;
|
|
||||||
import org.l2jmobius.gameserver.model.effects.AbstractEffect;
|
import org.l2jmobius.gameserver.model.effects.AbstractEffect;
|
||||||
import org.l2jmobius.gameserver.model.items.instance.ItemInstance;
|
|
||||||
import org.l2jmobius.gameserver.model.skills.Skill;
|
import org.l2jmobius.gameserver.model.skills.Skill;
|
||||||
import org.l2jmobius.gameserver.model.stats.TraitType;
|
import org.l2jmobius.gameserver.model.stats.TraitType;
|
||||||
|
|
||||||
@@ -51,35 +49,11 @@ public final class AttackTrait extends AbstractEffect
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onExit(Creature effector, Creature effected, Skill skill)
|
public void pump(Creature effected, Skill skill)
|
||||||
{
|
{
|
||||||
final CreatureStat charStat = effected.getStat();
|
for (Entry<TraitType, Float> trait : _attackTraits.entrySet())
|
||||||
synchronized (charStat.getAttackTraits())
|
|
||||||
{
|
{
|
||||||
for (Entry<TraitType, Float> trait : _attackTraits.entrySet())
|
effected.getStat().mergeAttackTrait(trait.getKey(), trait.getValue());
|
||||||
{
|
|
||||||
if (charStat.getAttackTraitsCount()[trait.getKey().ordinal()] == 0)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
charStat.getAttackTraits()[trait.getKey().ordinal()] /= trait.getValue();
|
|
||||||
charStat.getAttackTraitsCount()[trait.getKey().ordinal()]--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onStart(Creature effector, Creature effected, Skill skill, ItemInstance item)
|
|
||||||
{
|
|
||||||
final CreatureStat charStat = effected.getStat();
|
|
||||||
synchronized (charStat.getAttackTraits())
|
|
||||||
{
|
|
||||||
for (Entry<TraitType, Float> trait : _attackTraits.entrySet())
|
|
||||||
{
|
|
||||||
charStat.getAttackTraits()[trait.getKey().ordinal()] *= trait.getValue();
|
|
||||||
charStat.getAttackTraitsCount()[trait.getKey().ordinal()]++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,9 +22,7 @@ import java.util.Map.Entry;
|
|||||||
|
|
||||||
import org.l2jmobius.gameserver.model.StatsSet;
|
import org.l2jmobius.gameserver.model.StatsSet;
|
||||||
import org.l2jmobius.gameserver.model.actor.Creature;
|
import org.l2jmobius.gameserver.model.actor.Creature;
|
||||||
import org.l2jmobius.gameserver.model.actor.stat.CreatureStat;
|
|
||||||
import org.l2jmobius.gameserver.model.effects.AbstractEffect;
|
import org.l2jmobius.gameserver.model.effects.AbstractEffect;
|
||||||
import org.l2jmobius.gameserver.model.items.instance.ItemInstance;
|
|
||||||
import org.l2jmobius.gameserver.model.skills.Skill;
|
import org.l2jmobius.gameserver.model.skills.Skill;
|
||||||
import org.l2jmobius.gameserver.model.stats.TraitType;
|
import org.l2jmobius.gameserver.model.stats.TraitType;
|
||||||
|
|
||||||
@@ -46,75 +44,22 @@ public final class DefenceTrait extends AbstractEffect
|
|||||||
|
|
||||||
for (Entry<String, Object> param : params.getSet().entrySet())
|
for (Entry<String, Object> param : params.getSet().entrySet())
|
||||||
{
|
{
|
||||||
try
|
_defenceTraits.put(TraitType.valueOf(param.getKey()), (Float.parseFloat((String) param.getValue()) + 100) / 100);
|
||||||
{
|
|
||||||
final TraitType traitType = TraitType.valueOf(param.getKey());
|
|
||||||
final float value = Float.parseFloat((String) param.getValue());
|
|
||||||
if (value == 0)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
_defenceTraits.put(traitType, (value + 100) / 100);
|
|
||||||
}
|
|
||||||
catch (NumberFormatException e)
|
|
||||||
{
|
|
||||||
LOGGER.warning(getClass().getSimpleName() + ": value of " + param.getKey() + " must be float value " + param.getValue() + " found.");
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
LOGGER.warning(getClass().getSimpleName() + ": value of TraitType enum required but found: " + param.getKey());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onExit(Creature effector, Creature effected, Skill skill)
|
public void pump(Creature effected, Skill skill)
|
||||||
{
|
{
|
||||||
final CreatureStat charStat = effected.getStat();
|
for (Entry<TraitType, Float> trait : _defenceTraits.entrySet())
|
||||||
synchronized (charStat.getDefenceTraits())
|
|
||||||
{
|
{
|
||||||
for (Entry<TraitType, Float> trait : _defenceTraits.entrySet())
|
if (trait.getValue() < 2.0f)
|
||||||
{
|
{
|
||||||
if (trait.getValue() < 2.0f)
|
effected.getStat().mergeDefenceTrait(trait.getKey(), trait.getValue());
|
||||||
{
|
|
||||||
if (charStat.getDefenceTraitsCount()[trait.getKey().ordinal()] == 0)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
charStat.getDefenceTraits()[trait.getKey().ordinal()] /= trait.getValue();
|
|
||||||
charStat.getDefenceTraitsCount()[trait.getKey().ordinal()]--;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (charStat.getTraitsInvul()[trait.getKey().ordinal()] == 0)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
charStat.getTraitsInvul()[trait.getKey().ordinal()]--;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
else
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onStart(Creature effector, Creature effected, Skill skill, ItemInstance item)
|
|
||||||
{
|
|
||||||
final CreatureStat charStat = effected.getStat();
|
|
||||||
synchronized (charStat.getDefenceTraits())
|
|
||||||
{
|
|
||||||
for (Entry<TraitType, Float> trait : _defenceTraits.entrySet())
|
|
||||||
{
|
{
|
||||||
if (trait.getValue() < 2.0f)
|
effected.getStat().mergeInvulnerableTrait(trait.getKey());
|
||||||
{
|
|
||||||
charStat.getDefenceTraits()[trait.getKey().ordinal()] *= trait.getValue();
|
|
||||||
charStat.getDefenceTraitsCount()[trait.getKey().ordinal()]++;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
charStat.getTraitsInvul()[trait.getKey().ordinal()]++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,10 +16,10 @@
|
|||||||
*/
|
*/
|
||||||
package org.l2jmobius.gameserver.model.actor.stat;
|
package org.l2jmobius.gameserver.model.actor.stat;
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Deque;
|
import java.util.Deque;
|
||||||
import java.util.EnumMap;
|
import java.util.EnumMap;
|
||||||
|
import java.util.EnumSet;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
@@ -72,11 +72,11 @@ public class CreatureStat
|
|||||||
private final Deque<StatsHolder> _additionalMul = new ConcurrentLinkedDeque<>();
|
private final Deque<StatsHolder> _additionalMul = new ConcurrentLinkedDeque<>();
|
||||||
private final Map<Stats, Double> _fixedValue = new ConcurrentHashMap<>();
|
private final Map<Stats, Double> _fixedValue = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
private final float[] _attackTraits = new float[TraitType.values().length];
|
private final float[] _attackTraitValues = new float[TraitType.values().length];
|
||||||
private final float[] _defenceTraits = new float[TraitType.values().length];
|
private final float[] _defenceTraitValues = new float[TraitType.values().length];
|
||||||
private final int[] _attackTraitsCount = new int[TraitType.values().length];
|
private final Set<TraitType> _attackTraits = EnumSet.noneOf(TraitType.class);
|
||||||
private final int[] _defenceTraitsCount = new int[TraitType.values().length];
|
private final Set<TraitType> _defenceTraits = EnumSet.noneOf(TraitType.class);
|
||||||
private final int[] _traitsInvul = new int[TraitType.values().length];
|
private final Set<TraitType> _invulnerableTraits = EnumSet.noneOf(TraitType.class);
|
||||||
|
|
||||||
/** Values to be recalculated after every stat update */
|
/** Values to be recalculated after every stat update */
|
||||||
private double _attackSpeedMultiplier = 1;
|
private double _attackSpeedMultiplier = 1;
|
||||||
@@ -87,8 +87,6 @@ public class CreatureStat
|
|||||||
public CreatureStat(Creature creature)
|
public CreatureStat(Creature creature)
|
||||||
{
|
{
|
||||||
_creature = creature;
|
_creature = creature;
|
||||||
Arrays.fill(_attackTraits, 1.0f);
|
|
||||||
Arrays.fill(_defenceTraits, 1.0f);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -573,54 +571,86 @@ public class CreatureStat
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public float getAttackTrait(TraitType traitType)
|
public void mergeAttackTrait(TraitType traitType, float value)
|
||||||
{
|
{
|
||||||
return _attackTraits[traitType.ordinal()];
|
_attackTraitValues[traitType.ordinal()] *= value;
|
||||||
|
_attackTraits.add(traitType);
|
||||||
}
|
}
|
||||||
|
|
||||||
public float[] getAttackTraits()
|
public float getAttackTrait(TraitType traitType)
|
||||||
{
|
{
|
||||||
return _attackTraits;
|
_lock.readLock().lock();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return _attackTraitValues[traitType.ordinal()];
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
_lock.readLock().unlock();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasAttackTrait(TraitType traitType)
|
public boolean hasAttackTrait(TraitType traitType)
|
||||||
{
|
{
|
||||||
return _attackTraitsCount[traitType.ordinal()] > 0;
|
_lock.readLock().lock();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return _attackTraits.contains(traitType);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
_lock.readLock().unlock();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public int[] getAttackTraitsCount()
|
public void mergeDefenceTrait(TraitType traitType, float value)
|
||||||
{
|
{
|
||||||
return _attackTraitsCount;
|
_defenceTraitValues[traitType.ordinal()] *= value;
|
||||||
|
_defenceTraits.add(traitType);
|
||||||
}
|
}
|
||||||
|
|
||||||
public float getDefenceTrait(TraitType traitType)
|
public float getDefenceTrait(TraitType traitType)
|
||||||
{
|
{
|
||||||
return _defenceTraits[traitType.ordinal()];
|
_lock.readLock().lock();
|
||||||
}
|
try
|
||||||
|
{
|
||||||
public float[] getDefenceTraits()
|
return _defenceTraitValues[traitType.ordinal()];
|
||||||
{
|
}
|
||||||
return _defenceTraits;
|
finally
|
||||||
|
{
|
||||||
|
_lock.readLock().unlock();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasDefenceTrait(TraitType traitType)
|
public boolean hasDefenceTrait(TraitType traitType)
|
||||||
{
|
{
|
||||||
return _defenceTraitsCount[traitType.ordinal()] > 0;
|
_lock.readLock().lock();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return _defenceTraits.contains(traitType);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
_lock.readLock().unlock();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public int[] getDefenceTraitsCount()
|
public void mergeInvulnerableTrait(TraitType traitType)
|
||||||
{
|
{
|
||||||
return _defenceTraitsCount;
|
_invulnerableTraits.add(traitType);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isTraitInvul(TraitType traitType)
|
public boolean isInvulnerableTrait(TraitType traitType)
|
||||||
{
|
{
|
||||||
return _traitsInvul[traitType.ordinal()] > 0;
|
_lock.readLock().lock();
|
||||||
}
|
try
|
||||||
|
{
|
||||||
public int[] getTraitsInvul()
|
return _invulnerableTraits.contains(traitType);
|
||||||
{
|
}
|
||||||
return _traitsInvul;
|
finally
|
||||||
|
{
|
||||||
|
_lock.readLock().unlock();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1241,7 +1241,7 @@ public final class Formulas
|
|||||||
return 1.0;
|
return 1.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (target.getStat().isTraitInvul(traitType))
|
if (target.getStat().isInvulnerableTrait(traitType))
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -63,6 +63,14 @@ public enum TraitType
|
|||||||
PHYSICAL_WEAKNESS(3),
|
PHYSICAL_WEAKNESS(3),
|
||||||
MAGICAL_WEAKNESS(3),
|
MAGICAL_WEAKNESS(3),
|
||||||
DUALDAGGER(1),
|
DUALDAGGER(1),
|
||||||
|
DEMONIC_WEAKNESS(2), // CT26_P4
|
||||||
|
DIVINE_WEAKNESS(2),
|
||||||
|
ELEMENTAL_WEAKNESS(2),
|
||||||
|
FAIRY_WEAKNESS(2),
|
||||||
|
HUMAN_WEAKNESS(2),
|
||||||
|
HUMANOID_WEAKNESS(2),
|
||||||
|
UNDEAD_WEAKNESS(2),
|
||||||
|
// The values from below are custom.
|
||||||
DUALBLUNT(1),
|
DUALBLUNT(1),
|
||||||
KNOCKBACK(3),
|
KNOCKBACK(3),
|
||||||
KNOCKDOWN(3),
|
KNOCKDOWN(3),
|
||||||
@@ -75,7 +83,9 @@ public enum TraitType
|
|||||||
CHANGEBODY(3),
|
CHANGEBODY(3),
|
||||||
TWOHANDCROSSBOW(1),
|
TWOHANDCROSSBOW(1),
|
||||||
ZONE(3),
|
ZONE(3),
|
||||||
PSYCHIC(3);
|
PSYCHIC(3),
|
||||||
|
EMBRYO_WEAKNESS(2),
|
||||||
|
SPIRIT_WEAKNESS(2);
|
||||||
|
|
||||||
private final int _type; // 1 = weapon, 2 = weakness, 3 = resistance
|
private final int _type; // 1 = weapon, 2 = weakness, 3 = resistance
|
||||||
|
|
||||||
|
|||||||
@@ -22,9 +22,7 @@ import java.util.Map.Entry;
|
|||||||
|
|
||||||
import org.l2jmobius.gameserver.model.StatsSet;
|
import org.l2jmobius.gameserver.model.StatsSet;
|
||||||
import org.l2jmobius.gameserver.model.actor.Creature;
|
import org.l2jmobius.gameserver.model.actor.Creature;
|
||||||
import org.l2jmobius.gameserver.model.actor.stat.CreatureStat;
|
|
||||||
import org.l2jmobius.gameserver.model.effects.AbstractEffect;
|
import org.l2jmobius.gameserver.model.effects.AbstractEffect;
|
||||||
import org.l2jmobius.gameserver.model.items.instance.ItemInstance;
|
|
||||||
import org.l2jmobius.gameserver.model.skills.Skill;
|
import org.l2jmobius.gameserver.model.skills.Skill;
|
||||||
import org.l2jmobius.gameserver.model.stats.TraitType;
|
import org.l2jmobius.gameserver.model.stats.TraitType;
|
||||||
|
|
||||||
@@ -51,35 +49,11 @@ public final class AttackTrait extends AbstractEffect
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onExit(Creature effector, Creature effected, Skill skill)
|
public void pump(Creature effected, Skill skill)
|
||||||
{
|
{
|
||||||
final CreatureStat charStat = effected.getStat();
|
for (Entry<TraitType, Float> trait : _attackTraits.entrySet())
|
||||||
synchronized (charStat.getAttackTraits())
|
|
||||||
{
|
{
|
||||||
for (Entry<TraitType, Float> trait : _attackTraits.entrySet())
|
effected.getStat().mergeAttackTrait(trait.getKey(), trait.getValue());
|
||||||
{
|
|
||||||
if (charStat.getAttackTraitsCount()[trait.getKey().ordinal()] == 0)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
charStat.getAttackTraits()[trait.getKey().ordinal()] /= trait.getValue();
|
|
||||||
charStat.getAttackTraitsCount()[trait.getKey().ordinal()]--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onStart(Creature effector, Creature effected, Skill skill, ItemInstance item)
|
|
||||||
{
|
|
||||||
final CreatureStat charStat = effected.getStat();
|
|
||||||
synchronized (charStat.getAttackTraits())
|
|
||||||
{
|
|
||||||
for (Entry<TraitType, Float> trait : _attackTraits.entrySet())
|
|
||||||
{
|
|
||||||
charStat.getAttackTraits()[trait.getKey().ordinal()] *= trait.getValue();
|
|
||||||
charStat.getAttackTraitsCount()[trait.getKey().ordinal()]++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,9 +22,7 @@ import java.util.Map.Entry;
|
|||||||
|
|
||||||
import org.l2jmobius.gameserver.model.StatsSet;
|
import org.l2jmobius.gameserver.model.StatsSet;
|
||||||
import org.l2jmobius.gameserver.model.actor.Creature;
|
import org.l2jmobius.gameserver.model.actor.Creature;
|
||||||
import org.l2jmobius.gameserver.model.actor.stat.CreatureStat;
|
|
||||||
import org.l2jmobius.gameserver.model.effects.AbstractEffect;
|
import org.l2jmobius.gameserver.model.effects.AbstractEffect;
|
||||||
import org.l2jmobius.gameserver.model.items.instance.ItemInstance;
|
|
||||||
import org.l2jmobius.gameserver.model.skills.Skill;
|
import org.l2jmobius.gameserver.model.skills.Skill;
|
||||||
import org.l2jmobius.gameserver.model.stats.TraitType;
|
import org.l2jmobius.gameserver.model.stats.TraitType;
|
||||||
|
|
||||||
@@ -46,75 +44,22 @@ public final class DefenceTrait extends AbstractEffect
|
|||||||
|
|
||||||
for (Entry<String, Object> param : params.getSet().entrySet())
|
for (Entry<String, Object> param : params.getSet().entrySet())
|
||||||
{
|
{
|
||||||
try
|
_defenceTraits.put(TraitType.valueOf(param.getKey()), (Float.parseFloat((String) param.getValue()) + 100) / 100);
|
||||||
{
|
|
||||||
final TraitType traitType = TraitType.valueOf(param.getKey());
|
|
||||||
final float value = Float.parseFloat((String) param.getValue());
|
|
||||||
if (value == 0)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
_defenceTraits.put(traitType, (value + 100) / 100);
|
|
||||||
}
|
|
||||||
catch (NumberFormatException e)
|
|
||||||
{
|
|
||||||
LOGGER.warning(getClass().getSimpleName() + ": value of " + param.getKey() + " must be float value " + param.getValue() + " found.");
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
LOGGER.warning(getClass().getSimpleName() + ": value of TraitType enum required but found: " + param.getKey());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onExit(Creature effector, Creature effected, Skill skill)
|
public void pump(Creature effected, Skill skill)
|
||||||
{
|
{
|
||||||
final CreatureStat charStat = effected.getStat();
|
for (Entry<TraitType, Float> trait : _defenceTraits.entrySet())
|
||||||
synchronized (charStat.getDefenceTraits())
|
|
||||||
{
|
{
|
||||||
for (Entry<TraitType, Float> trait : _defenceTraits.entrySet())
|
if (trait.getValue() < 2.0f)
|
||||||
{
|
{
|
||||||
if (trait.getValue() < 2.0f)
|
effected.getStat().mergeDefenceTrait(trait.getKey(), trait.getValue());
|
||||||
{
|
|
||||||
if (charStat.getDefenceTraitsCount()[trait.getKey().ordinal()] == 0)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
charStat.getDefenceTraits()[trait.getKey().ordinal()] /= trait.getValue();
|
|
||||||
charStat.getDefenceTraitsCount()[trait.getKey().ordinal()]--;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (charStat.getTraitsInvul()[trait.getKey().ordinal()] == 0)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
charStat.getTraitsInvul()[trait.getKey().ordinal()]--;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
else
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onStart(Creature effector, Creature effected, Skill skill, ItemInstance item)
|
|
||||||
{
|
|
||||||
final CreatureStat charStat = effected.getStat();
|
|
||||||
synchronized (charStat.getDefenceTraits())
|
|
||||||
{
|
|
||||||
for (Entry<TraitType, Float> trait : _defenceTraits.entrySet())
|
|
||||||
{
|
{
|
||||||
if (trait.getValue() < 2.0f)
|
effected.getStat().mergeInvulnerableTrait(trait.getKey());
|
||||||
{
|
|
||||||
charStat.getDefenceTraits()[trait.getKey().ordinal()] *= trait.getValue();
|
|
||||||
charStat.getDefenceTraitsCount()[trait.getKey().ordinal()]++;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
charStat.getTraitsInvul()[trait.getKey().ordinal()]++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,10 +16,10 @@
|
|||||||
*/
|
*/
|
||||||
package org.l2jmobius.gameserver.model.actor.stat;
|
package org.l2jmobius.gameserver.model.actor.stat;
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Deque;
|
import java.util.Deque;
|
||||||
import java.util.EnumMap;
|
import java.util.EnumMap;
|
||||||
|
import java.util.EnumSet;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
@@ -72,11 +72,11 @@ public class CreatureStat
|
|||||||
private final Deque<StatsHolder> _additionalMul = new ConcurrentLinkedDeque<>();
|
private final Deque<StatsHolder> _additionalMul = new ConcurrentLinkedDeque<>();
|
||||||
private final Map<Stats, Double> _fixedValue = new ConcurrentHashMap<>();
|
private final Map<Stats, Double> _fixedValue = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
private final float[] _attackTraits = new float[TraitType.values().length];
|
private final float[] _attackTraitValues = new float[TraitType.values().length];
|
||||||
private final float[] _defenceTraits = new float[TraitType.values().length];
|
private final float[] _defenceTraitValues = new float[TraitType.values().length];
|
||||||
private final int[] _attackTraitsCount = new int[TraitType.values().length];
|
private final Set<TraitType> _attackTraits = EnumSet.noneOf(TraitType.class);
|
||||||
private final int[] _defenceTraitsCount = new int[TraitType.values().length];
|
private final Set<TraitType> _defenceTraits = EnumSet.noneOf(TraitType.class);
|
||||||
private final int[] _traitsInvul = new int[TraitType.values().length];
|
private final Set<TraitType> _invulnerableTraits = EnumSet.noneOf(TraitType.class);
|
||||||
|
|
||||||
/** Values to be recalculated after every stat update */
|
/** Values to be recalculated after every stat update */
|
||||||
private double _attackSpeedMultiplier = 1;
|
private double _attackSpeedMultiplier = 1;
|
||||||
@@ -87,8 +87,6 @@ public class CreatureStat
|
|||||||
public CreatureStat(Creature creature)
|
public CreatureStat(Creature creature)
|
||||||
{
|
{
|
||||||
_creature = creature;
|
_creature = creature;
|
||||||
Arrays.fill(_attackTraits, 1.0f);
|
|
||||||
Arrays.fill(_defenceTraits, 1.0f);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -573,54 +571,86 @@ public class CreatureStat
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public float getAttackTrait(TraitType traitType)
|
public void mergeAttackTrait(TraitType traitType, float value)
|
||||||
{
|
{
|
||||||
return _attackTraits[traitType.ordinal()];
|
_attackTraitValues[traitType.ordinal()] *= value;
|
||||||
|
_attackTraits.add(traitType);
|
||||||
}
|
}
|
||||||
|
|
||||||
public float[] getAttackTraits()
|
public float getAttackTrait(TraitType traitType)
|
||||||
{
|
{
|
||||||
return _attackTraits;
|
_lock.readLock().lock();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return _attackTraitValues[traitType.ordinal()];
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
_lock.readLock().unlock();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasAttackTrait(TraitType traitType)
|
public boolean hasAttackTrait(TraitType traitType)
|
||||||
{
|
{
|
||||||
return _attackTraitsCount[traitType.ordinal()] > 0;
|
_lock.readLock().lock();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return _attackTraits.contains(traitType);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
_lock.readLock().unlock();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public int[] getAttackTraitsCount()
|
public void mergeDefenceTrait(TraitType traitType, float value)
|
||||||
{
|
{
|
||||||
return _attackTraitsCount;
|
_defenceTraitValues[traitType.ordinal()] *= value;
|
||||||
|
_defenceTraits.add(traitType);
|
||||||
}
|
}
|
||||||
|
|
||||||
public float getDefenceTrait(TraitType traitType)
|
public float getDefenceTrait(TraitType traitType)
|
||||||
{
|
{
|
||||||
return _defenceTraits[traitType.ordinal()];
|
_lock.readLock().lock();
|
||||||
}
|
try
|
||||||
|
{
|
||||||
public float[] getDefenceTraits()
|
return _defenceTraitValues[traitType.ordinal()];
|
||||||
{
|
}
|
||||||
return _defenceTraits;
|
finally
|
||||||
|
{
|
||||||
|
_lock.readLock().unlock();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasDefenceTrait(TraitType traitType)
|
public boolean hasDefenceTrait(TraitType traitType)
|
||||||
{
|
{
|
||||||
return _defenceTraitsCount[traitType.ordinal()] > 0;
|
_lock.readLock().lock();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return _defenceTraits.contains(traitType);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
_lock.readLock().unlock();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public int[] getDefenceTraitsCount()
|
public void mergeInvulnerableTrait(TraitType traitType)
|
||||||
{
|
{
|
||||||
return _defenceTraitsCount;
|
_invulnerableTraits.add(traitType);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isTraitInvul(TraitType traitType)
|
public boolean isInvulnerableTrait(TraitType traitType)
|
||||||
{
|
{
|
||||||
return _traitsInvul[traitType.ordinal()] > 0;
|
_lock.readLock().lock();
|
||||||
}
|
try
|
||||||
|
{
|
||||||
public int[] getTraitsInvul()
|
return _invulnerableTraits.contains(traitType);
|
||||||
{
|
}
|
||||||
return _traitsInvul;
|
finally
|
||||||
|
{
|
||||||
|
_lock.readLock().unlock();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1241,7 +1241,7 @@ public final class Formulas
|
|||||||
return 1.0;
|
return 1.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (target.getStat().isTraitInvul(traitType))
|
if (target.getStat().isInvulnerableTrait(traitType))
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -63,6 +63,14 @@ public enum TraitType
|
|||||||
PHYSICAL_WEAKNESS(3),
|
PHYSICAL_WEAKNESS(3),
|
||||||
MAGICAL_WEAKNESS(3),
|
MAGICAL_WEAKNESS(3),
|
||||||
DUALDAGGER(1),
|
DUALDAGGER(1),
|
||||||
|
DEMONIC_WEAKNESS(2), // CT26_P4
|
||||||
|
DIVINE_WEAKNESS(2),
|
||||||
|
ELEMENTAL_WEAKNESS(2),
|
||||||
|
FAIRY_WEAKNESS(2),
|
||||||
|
HUMAN_WEAKNESS(2),
|
||||||
|
HUMANOID_WEAKNESS(2),
|
||||||
|
UNDEAD_WEAKNESS(2),
|
||||||
|
// The values from below are custom.
|
||||||
DUALBLUNT(1),
|
DUALBLUNT(1),
|
||||||
KNOCKBACK(3),
|
KNOCKBACK(3),
|
||||||
KNOCKDOWN(3),
|
KNOCKDOWN(3),
|
||||||
@@ -75,7 +83,9 @@ public enum TraitType
|
|||||||
CHANGEBODY(3),
|
CHANGEBODY(3),
|
||||||
TWOHANDCROSSBOW(1),
|
TWOHANDCROSSBOW(1),
|
||||||
ZONE(3),
|
ZONE(3),
|
||||||
PSYCHIC(3);
|
PSYCHIC(3),
|
||||||
|
EMBRYO_WEAKNESS(2),
|
||||||
|
SPIRIT_WEAKNESS(2);
|
||||||
|
|
||||||
private final int _type; // 1 = weapon, 2 = weakness, 3 = resistance
|
private final int _type; // 1 = weapon, 2 = weakness, 3 = resistance
|
||||||
|
|
||||||
|
|||||||
@@ -22,9 +22,7 @@ import java.util.Map.Entry;
|
|||||||
|
|
||||||
import org.l2jmobius.gameserver.model.StatsSet;
|
import org.l2jmobius.gameserver.model.StatsSet;
|
||||||
import org.l2jmobius.gameserver.model.actor.Creature;
|
import org.l2jmobius.gameserver.model.actor.Creature;
|
||||||
import org.l2jmobius.gameserver.model.actor.stat.CreatureStat;
|
|
||||||
import org.l2jmobius.gameserver.model.effects.AbstractEffect;
|
import org.l2jmobius.gameserver.model.effects.AbstractEffect;
|
||||||
import org.l2jmobius.gameserver.model.items.instance.ItemInstance;
|
|
||||||
import org.l2jmobius.gameserver.model.skills.Skill;
|
import org.l2jmobius.gameserver.model.skills.Skill;
|
||||||
import org.l2jmobius.gameserver.model.stats.TraitType;
|
import org.l2jmobius.gameserver.model.stats.TraitType;
|
||||||
|
|
||||||
@@ -51,35 +49,11 @@ public final class AttackTrait extends AbstractEffect
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onExit(Creature effector, Creature effected, Skill skill)
|
public void pump(Creature effected, Skill skill)
|
||||||
{
|
{
|
||||||
final CreatureStat charStat = effected.getStat();
|
for (Entry<TraitType, Float> trait : _attackTraits.entrySet())
|
||||||
synchronized (charStat.getAttackTraits())
|
|
||||||
{
|
{
|
||||||
for (Entry<TraitType, Float> trait : _attackTraits.entrySet())
|
effected.getStat().mergeAttackTrait(trait.getKey(), trait.getValue());
|
||||||
{
|
|
||||||
if (charStat.getAttackTraitsCount()[trait.getKey().ordinal()] == 0)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
charStat.getAttackTraits()[trait.getKey().ordinal()] /= trait.getValue();
|
|
||||||
charStat.getAttackTraitsCount()[trait.getKey().ordinal()]--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onStart(Creature effector, Creature effected, Skill skill, ItemInstance item)
|
|
||||||
{
|
|
||||||
final CreatureStat charStat = effected.getStat();
|
|
||||||
synchronized (charStat.getAttackTraits())
|
|
||||||
{
|
|
||||||
for (Entry<TraitType, Float> trait : _attackTraits.entrySet())
|
|
||||||
{
|
|
||||||
charStat.getAttackTraits()[trait.getKey().ordinal()] *= trait.getValue();
|
|
||||||
charStat.getAttackTraitsCount()[trait.getKey().ordinal()]++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,9 +22,7 @@ import java.util.Map.Entry;
|
|||||||
|
|
||||||
import org.l2jmobius.gameserver.model.StatsSet;
|
import org.l2jmobius.gameserver.model.StatsSet;
|
||||||
import org.l2jmobius.gameserver.model.actor.Creature;
|
import org.l2jmobius.gameserver.model.actor.Creature;
|
||||||
import org.l2jmobius.gameserver.model.actor.stat.CreatureStat;
|
|
||||||
import org.l2jmobius.gameserver.model.effects.AbstractEffect;
|
import org.l2jmobius.gameserver.model.effects.AbstractEffect;
|
||||||
import org.l2jmobius.gameserver.model.items.instance.ItemInstance;
|
|
||||||
import org.l2jmobius.gameserver.model.skills.Skill;
|
import org.l2jmobius.gameserver.model.skills.Skill;
|
||||||
import org.l2jmobius.gameserver.model.stats.TraitType;
|
import org.l2jmobius.gameserver.model.stats.TraitType;
|
||||||
|
|
||||||
@@ -46,75 +44,22 @@ public final class DefenceTrait extends AbstractEffect
|
|||||||
|
|
||||||
for (Entry<String, Object> param : params.getSet().entrySet())
|
for (Entry<String, Object> param : params.getSet().entrySet())
|
||||||
{
|
{
|
||||||
try
|
_defenceTraits.put(TraitType.valueOf(param.getKey()), (Float.parseFloat((String) param.getValue()) + 100) / 100);
|
||||||
{
|
|
||||||
final TraitType traitType = TraitType.valueOf(param.getKey());
|
|
||||||
final float value = Float.parseFloat((String) param.getValue());
|
|
||||||
if (value == 0)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
_defenceTraits.put(traitType, (value + 100) / 100);
|
|
||||||
}
|
|
||||||
catch (NumberFormatException e)
|
|
||||||
{
|
|
||||||
LOGGER.warning(getClass().getSimpleName() + ": value of " + param.getKey() + " must be float value " + param.getValue() + " found.");
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
LOGGER.warning(getClass().getSimpleName() + ": value of TraitType enum required but found: " + param.getKey());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onExit(Creature effector, Creature effected, Skill skill)
|
public void pump(Creature effected, Skill skill)
|
||||||
{
|
{
|
||||||
final CreatureStat charStat = effected.getStat();
|
for (Entry<TraitType, Float> trait : _defenceTraits.entrySet())
|
||||||
synchronized (charStat.getDefenceTraits())
|
|
||||||
{
|
{
|
||||||
for (Entry<TraitType, Float> trait : _defenceTraits.entrySet())
|
if (trait.getValue() < 2.0f)
|
||||||
{
|
{
|
||||||
if (trait.getValue() < 2.0f)
|
effected.getStat().mergeDefenceTrait(trait.getKey(), trait.getValue());
|
||||||
{
|
|
||||||
if (charStat.getDefenceTraitsCount()[trait.getKey().ordinal()] == 0)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
charStat.getDefenceTraits()[trait.getKey().ordinal()] /= trait.getValue();
|
|
||||||
charStat.getDefenceTraitsCount()[trait.getKey().ordinal()]--;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (charStat.getTraitsInvul()[trait.getKey().ordinal()] == 0)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
charStat.getTraitsInvul()[trait.getKey().ordinal()]--;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
else
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onStart(Creature effector, Creature effected, Skill skill, ItemInstance item)
|
|
||||||
{
|
|
||||||
final CreatureStat charStat = effected.getStat();
|
|
||||||
synchronized (charStat.getDefenceTraits())
|
|
||||||
{
|
|
||||||
for (Entry<TraitType, Float> trait : _defenceTraits.entrySet())
|
|
||||||
{
|
{
|
||||||
if (trait.getValue() < 2.0f)
|
effected.getStat().mergeInvulnerableTrait(trait.getKey());
|
||||||
{
|
|
||||||
charStat.getDefenceTraits()[trait.getKey().ordinal()] *= trait.getValue();
|
|
||||||
charStat.getDefenceTraitsCount()[trait.getKey().ordinal()]++;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
charStat.getTraitsInvul()[trait.getKey().ordinal()]++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,10 +16,10 @@
|
|||||||
*/
|
*/
|
||||||
package org.l2jmobius.gameserver.model.actor.stat;
|
package org.l2jmobius.gameserver.model.actor.stat;
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Deque;
|
import java.util.Deque;
|
||||||
import java.util.EnumMap;
|
import java.util.EnumMap;
|
||||||
|
import java.util.EnumSet;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
@@ -72,11 +72,11 @@ public class CreatureStat
|
|||||||
private final Deque<StatsHolder> _additionalMul = new ConcurrentLinkedDeque<>();
|
private final Deque<StatsHolder> _additionalMul = new ConcurrentLinkedDeque<>();
|
||||||
private final Map<Stats, Double> _fixedValue = new ConcurrentHashMap<>();
|
private final Map<Stats, Double> _fixedValue = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
private final float[] _attackTraits = new float[TraitType.values().length];
|
private final float[] _attackTraitValues = new float[TraitType.values().length];
|
||||||
private final float[] _defenceTraits = new float[TraitType.values().length];
|
private final float[] _defenceTraitValues = new float[TraitType.values().length];
|
||||||
private final int[] _attackTraitsCount = new int[TraitType.values().length];
|
private final Set<TraitType> _attackTraits = EnumSet.noneOf(TraitType.class);
|
||||||
private final int[] _defenceTraitsCount = new int[TraitType.values().length];
|
private final Set<TraitType> _defenceTraits = EnumSet.noneOf(TraitType.class);
|
||||||
private final int[] _traitsInvul = new int[TraitType.values().length];
|
private final Set<TraitType> _invulnerableTraits = EnumSet.noneOf(TraitType.class);
|
||||||
|
|
||||||
/** Values to be recalculated after every stat update */
|
/** Values to be recalculated after every stat update */
|
||||||
private double _attackSpeedMultiplier = 1;
|
private double _attackSpeedMultiplier = 1;
|
||||||
@@ -87,8 +87,6 @@ public class CreatureStat
|
|||||||
public CreatureStat(Creature creature)
|
public CreatureStat(Creature creature)
|
||||||
{
|
{
|
||||||
_creature = creature;
|
_creature = creature;
|
||||||
Arrays.fill(_attackTraits, 1.0f);
|
|
||||||
Arrays.fill(_defenceTraits, 1.0f);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -573,54 +571,86 @@ public class CreatureStat
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public float getAttackTrait(TraitType traitType)
|
public void mergeAttackTrait(TraitType traitType, float value)
|
||||||
{
|
{
|
||||||
return _attackTraits[traitType.ordinal()];
|
_attackTraitValues[traitType.ordinal()] *= value;
|
||||||
|
_attackTraits.add(traitType);
|
||||||
}
|
}
|
||||||
|
|
||||||
public float[] getAttackTraits()
|
public float getAttackTrait(TraitType traitType)
|
||||||
{
|
{
|
||||||
return _attackTraits;
|
_lock.readLock().lock();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return _attackTraitValues[traitType.ordinal()];
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
_lock.readLock().unlock();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasAttackTrait(TraitType traitType)
|
public boolean hasAttackTrait(TraitType traitType)
|
||||||
{
|
{
|
||||||
return _attackTraitsCount[traitType.ordinal()] > 0;
|
_lock.readLock().lock();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return _attackTraits.contains(traitType);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
_lock.readLock().unlock();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public int[] getAttackTraitsCount()
|
public void mergeDefenceTrait(TraitType traitType, float value)
|
||||||
{
|
{
|
||||||
return _attackTraitsCount;
|
_defenceTraitValues[traitType.ordinal()] *= value;
|
||||||
|
_defenceTraits.add(traitType);
|
||||||
}
|
}
|
||||||
|
|
||||||
public float getDefenceTrait(TraitType traitType)
|
public float getDefenceTrait(TraitType traitType)
|
||||||
{
|
{
|
||||||
return _defenceTraits[traitType.ordinal()];
|
_lock.readLock().lock();
|
||||||
}
|
try
|
||||||
|
{
|
||||||
public float[] getDefenceTraits()
|
return _defenceTraitValues[traitType.ordinal()];
|
||||||
{
|
}
|
||||||
return _defenceTraits;
|
finally
|
||||||
|
{
|
||||||
|
_lock.readLock().unlock();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasDefenceTrait(TraitType traitType)
|
public boolean hasDefenceTrait(TraitType traitType)
|
||||||
{
|
{
|
||||||
return _defenceTraitsCount[traitType.ordinal()] > 0;
|
_lock.readLock().lock();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return _defenceTraits.contains(traitType);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
_lock.readLock().unlock();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public int[] getDefenceTraitsCount()
|
public void mergeInvulnerableTrait(TraitType traitType)
|
||||||
{
|
{
|
||||||
return _defenceTraitsCount;
|
_invulnerableTraits.add(traitType);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isTraitInvul(TraitType traitType)
|
public boolean isInvulnerableTrait(TraitType traitType)
|
||||||
{
|
{
|
||||||
return _traitsInvul[traitType.ordinal()] > 0;
|
_lock.readLock().lock();
|
||||||
}
|
try
|
||||||
|
{
|
||||||
public int[] getTraitsInvul()
|
return _invulnerableTraits.contains(traitType);
|
||||||
{
|
}
|
||||||
return _traitsInvul;
|
finally
|
||||||
|
{
|
||||||
|
_lock.readLock().unlock();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1241,7 +1241,7 @@ public final class Formulas
|
|||||||
return 1.0;
|
return 1.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (target.getStat().isTraitInvul(traitType))
|
if (target.getStat().isInvulnerableTrait(traitType))
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -63,6 +63,14 @@ public enum TraitType
|
|||||||
PHYSICAL_WEAKNESS(3),
|
PHYSICAL_WEAKNESS(3),
|
||||||
MAGICAL_WEAKNESS(3),
|
MAGICAL_WEAKNESS(3),
|
||||||
DUALDAGGER(1),
|
DUALDAGGER(1),
|
||||||
|
DEMONIC_WEAKNESS(2), // CT26_P4
|
||||||
|
DIVINE_WEAKNESS(2),
|
||||||
|
ELEMENTAL_WEAKNESS(2),
|
||||||
|
FAIRY_WEAKNESS(2),
|
||||||
|
HUMAN_WEAKNESS(2),
|
||||||
|
HUMANOID_WEAKNESS(2),
|
||||||
|
UNDEAD_WEAKNESS(2),
|
||||||
|
// The values from below are custom.
|
||||||
DUALBLUNT(1),
|
DUALBLUNT(1),
|
||||||
KNOCKBACK(3),
|
KNOCKBACK(3),
|
||||||
KNOCKDOWN(3),
|
KNOCKDOWN(3),
|
||||||
@@ -75,7 +83,9 @@ public enum TraitType
|
|||||||
CHANGEBODY(3),
|
CHANGEBODY(3),
|
||||||
TWOHANDCROSSBOW(1),
|
TWOHANDCROSSBOW(1),
|
||||||
ZONE(3),
|
ZONE(3),
|
||||||
PSYCHIC(3);
|
PSYCHIC(3),
|
||||||
|
EMBRYO_WEAKNESS(2),
|
||||||
|
SPIRIT_WEAKNESS(2);
|
||||||
|
|
||||||
private final int _type; // 1 = weapon, 2 = weakness, 3 = resistance
|
private final int _type; // 1 = weapon, 2 = weakness, 3 = resistance
|
||||||
|
|
||||||
|
|||||||
@@ -22,9 +22,7 @@ import java.util.Map.Entry;
|
|||||||
|
|
||||||
import org.l2jmobius.gameserver.model.StatsSet;
|
import org.l2jmobius.gameserver.model.StatsSet;
|
||||||
import org.l2jmobius.gameserver.model.actor.Creature;
|
import org.l2jmobius.gameserver.model.actor.Creature;
|
||||||
import org.l2jmobius.gameserver.model.actor.stat.CreatureStat;
|
|
||||||
import org.l2jmobius.gameserver.model.effects.AbstractEffect;
|
import org.l2jmobius.gameserver.model.effects.AbstractEffect;
|
||||||
import org.l2jmobius.gameserver.model.items.instance.ItemInstance;
|
|
||||||
import org.l2jmobius.gameserver.model.skills.Skill;
|
import org.l2jmobius.gameserver.model.skills.Skill;
|
||||||
import org.l2jmobius.gameserver.model.stats.TraitType;
|
import org.l2jmobius.gameserver.model.stats.TraitType;
|
||||||
|
|
||||||
@@ -51,35 +49,11 @@ public final class AttackTrait extends AbstractEffect
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onExit(Creature effector, Creature effected, Skill skill)
|
public void pump(Creature effected, Skill skill)
|
||||||
{
|
{
|
||||||
final CreatureStat charStat = effected.getStat();
|
for (Entry<TraitType, Float> trait : _attackTraits.entrySet())
|
||||||
synchronized (charStat.getAttackTraits())
|
|
||||||
{
|
{
|
||||||
for (Entry<TraitType, Float> trait : _attackTraits.entrySet())
|
effected.getStat().mergeAttackTrait(trait.getKey(), trait.getValue());
|
||||||
{
|
|
||||||
if (charStat.getAttackTraitsCount()[trait.getKey().ordinal()] == 0)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
charStat.getAttackTraits()[trait.getKey().ordinal()] /= trait.getValue();
|
|
||||||
charStat.getAttackTraitsCount()[trait.getKey().ordinal()]--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onStart(Creature effector, Creature effected, Skill skill, ItemInstance item)
|
|
||||||
{
|
|
||||||
final CreatureStat charStat = effected.getStat();
|
|
||||||
synchronized (charStat.getAttackTraits())
|
|
||||||
{
|
|
||||||
for (Entry<TraitType, Float> trait : _attackTraits.entrySet())
|
|
||||||
{
|
|
||||||
charStat.getAttackTraits()[trait.getKey().ordinal()] *= trait.getValue();
|
|
||||||
charStat.getAttackTraitsCount()[trait.getKey().ordinal()]++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,9 +22,7 @@ import java.util.Map.Entry;
|
|||||||
|
|
||||||
import org.l2jmobius.gameserver.model.StatsSet;
|
import org.l2jmobius.gameserver.model.StatsSet;
|
||||||
import org.l2jmobius.gameserver.model.actor.Creature;
|
import org.l2jmobius.gameserver.model.actor.Creature;
|
||||||
import org.l2jmobius.gameserver.model.actor.stat.CreatureStat;
|
|
||||||
import org.l2jmobius.gameserver.model.effects.AbstractEffect;
|
import org.l2jmobius.gameserver.model.effects.AbstractEffect;
|
||||||
import org.l2jmobius.gameserver.model.items.instance.ItemInstance;
|
|
||||||
import org.l2jmobius.gameserver.model.skills.Skill;
|
import org.l2jmobius.gameserver.model.skills.Skill;
|
||||||
import org.l2jmobius.gameserver.model.stats.TraitType;
|
import org.l2jmobius.gameserver.model.stats.TraitType;
|
||||||
|
|
||||||
@@ -46,75 +44,22 @@ public final class DefenceTrait extends AbstractEffect
|
|||||||
|
|
||||||
for (Entry<String, Object> param : params.getSet().entrySet())
|
for (Entry<String, Object> param : params.getSet().entrySet())
|
||||||
{
|
{
|
||||||
try
|
_defenceTraits.put(TraitType.valueOf(param.getKey()), (Float.parseFloat((String) param.getValue()) + 100) / 100);
|
||||||
{
|
|
||||||
final TraitType traitType = TraitType.valueOf(param.getKey());
|
|
||||||
final float value = Float.parseFloat((String) param.getValue());
|
|
||||||
if (value == 0)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
_defenceTraits.put(traitType, (value + 100) / 100);
|
|
||||||
}
|
|
||||||
catch (NumberFormatException e)
|
|
||||||
{
|
|
||||||
LOGGER.warning(getClass().getSimpleName() + ": value of " + param.getKey() + " must be float value " + param.getValue() + " found.");
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
LOGGER.warning(getClass().getSimpleName() + ": value of TraitType enum required but found: " + param.getKey());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onExit(Creature effector, Creature effected, Skill skill)
|
public void pump(Creature effected, Skill skill)
|
||||||
{
|
{
|
||||||
final CreatureStat charStat = effected.getStat();
|
for (Entry<TraitType, Float> trait : _defenceTraits.entrySet())
|
||||||
synchronized (charStat.getDefenceTraits())
|
|
||||||
{
|
{
|
||||||
for (Entry<TraitType, Float> trait : _defenceTraits.entrySet())
|
if (trait.getValue() < 2.0f)
|
||||||
{
|
{
|
||||||
if (trait.getValue() < 2.0f)
|
effected.getStat().mergeDefenceTrait(trait.getKey(), trait.getValue());
|
||||||
{
|
|
||||||
if (charStat.getDefenceTraitsCount()[trait.getKey().ordinal()] == 0)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
charStat.getDefenceTraits()[trait.getKey().ordinal()] /= trait.getValue();
|
|
||||||
charStat.getDefenceTraitsCount()[trait.getKey().ordinal()]--;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (charStat.getTraitsInvul()[trait.getKey().ordinal()] == 0)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
charStat.getTraitsInvul()[trait.getKey().ordinal()]--;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
else
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onStart(Creature effector, Creature effected, Skill skill, ItemInstance item)
|
|
||||||
{
|
|
||||||
final CreatureStat charStat = effected.getStat();
|
|
||||||
synchronized (charStat.getDefenceTraits())
|
|
||||||
{
|
|
||||||
for (Entry<TraitType, Float> trait : _defenceTraits.entrySet())
|
|
||||||
{
|
{
|
||||||
if (trait.getValue() < 2.0f)
|
effected.getStat().mergeInvulnerableTrait(trait.getKey());
|
||||||
{
|
|
||||||
charStat.getDefenceTraits()[trait.getKey().ordinal()] *= trait.getValue();
|
|
||||||
charStat.getDefenceTraitsCount()[trait.getKey().ordinal()]++;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
charStat.getTraitsInvul()[trait.getKey().ordinal()]++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,10 +16,10 @@
|
|||||||
*/
|
*/
|
||||||
package org.l2jmobius.gameserver.model.actor.stat;
|
package org.l2jmobius.gameserver.model.actor.stat;
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Deque;
|
import java.util.Deque;
|
||||||
import java.util.EnumMap;
|
import java.util.EnumMap;
|
||||||
|
import java.util.EnumSet;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
@@ -72,11 +72,11 @@ public class CreatureStat
|
|||||||
private final Deque<StatsHolder> _additionalMul = new ConcurrentLinkedDeque<>();
|
private final Deque<StatsHolder> _additionalMul = new ConcurrentLinkedDeque<>();
|
||||||
private final Map<Stats, Double> _fixedValue = new ConcurrentHashMap<>();
|
private final Map<Stats, Double> _fixedValue = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
private final float[] _attackTraits = new float[TraitType.values().length];
|
private final float[] _attackTraitValues = new float[TraitType.values().length];
|
||||||
private final float[] _defenceTraits = new float[TraitType.values().length];
|
private final float[] _defenceTraitValues = new float[TraitType.values().length];
|
||||||
private final int[] _attackTraitsCount = new int[TraitType.values().length];
|
private final Set<TraitType> _attackTraits = EnumSet.noneOf(TraitType.class);
|
||||||
private final int[] _defenceTraitsCount = new int[TraitType.values().length];
|
private final Set<TraitType> _defenceTraits = EnumSet.noneOf(TraitType.class);
|
||||||
private final int[] _traitsInvul = new int[TraitType.values().length];
|
private final Set<TraitType> _invulnerableTraits = EnumSet.noneOf(TraitType.class);
|
||||||
|
|
||||||
/** Values to be recalculated after every stat update */
|
/** Values to be recalculated after every stat update */
|
||||||
private double _attackSpeedMultiplier = 1;
|
private double _attackSpeedMultiplier = 1;
|
||||||
@@ -87,8 +87,6 @@ public class CreatureStat
|
|||||||
public CreatureStat(Creature creature)
|
public CreatureStat(Creature creature)
|
||||||
{
|
{
|
||||||
_creature = creature;
|
_creature = creature;
|
||||||
Arrays.fill(_attackTraits, 1.0f);
|
|
||||||
Arrays.fill(_defenceTraits, 1.0f);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -573,54 +571,86 @@ public class CreatureStat
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public float getAttackTrait(TraitType traitType)
|
public void mergeAttackTrait(TraitType traitType, float value)
|
||||||
{
|
{
|
||||||
return _attackTraits[traitType.ordinal()];
|
_attackTraitValues[traitType.ordinal()] *= value;
|
||||||
|
_attackTraits.add(traitType);
|
||||||
}
|
}
|
||||||
|
|
||||||
public float[] getAttackTraits()
|
public float getAttackTrait(TraitType traitType)
|
||||||
{
|
{
|
||||||
return _attackTraits;
|
_lock.readLock().lock();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return _attackTraitValues[traitType.ordinal()];
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
_lock.readLock().unlock();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasAttackTrait(TraitType traitType)
|
public boolean hasAttackTrait(TraitType traitType)
|
||||||
{
|
{
|
||||||
return _attackTraitsCount[traitType.ordinal()] > 0;
|
_lock.readLock().lock();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return _attackTraits.contains(traitType);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
_lock.readLock().unlock();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public int[] getAttackTraitsCount()
|
public void mergeDefenceTrait(TraitType traitType, float value)
|
||||||
{
|
{
|
||||||
return _attackTraitsCount;
|
_defenceTraitValues[traitType.ordinal()] *= value;
|
||||||
|
_defenceTraits.add(traitType);
|
||||||
}
|
}
|
||||||
|
|
||||||
public float getDefenceTrait(TraitType traitType)
|
public float getDefenceTrait(TraitType traitType)
|
||||||
{
|
{
|
||||||
return _defenceTraits[traitType.ordinal()];
|
_lock.readLock().lock();
|
||||||
}
|
try
|
||||||
|
{
|
||||||
public float[] getDefenceTraits()
|
return _defenceTraitValues[traitType.ordinal()];
|
||||||
{
|
}
|
||||||
return _defenceTraits;
|
finally
|
||||||
|
{
|
||||||
|
_lock.readLock().unlock();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasDefenceTrait(TraitType traitType)
|
public boolean hasDefenceTrait(TraitType traitType)
|
||||||
{
|
{
|
||||||
return _defenceTraitsCount[traitType.ordinal()] > 0;
|
_lock.readLock().lock();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return _defenceTraits.contains(traitType);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
_lock.readLock().unlock();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public int[] getDefenceTraitsCount()
|
public void mergeInvulnerableTrait(TraitType traitType)
|
||||||
{
|
{
|
||||||
return _defenceTraitsCount;
|
_invulnerableTraits.add(traitType);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isTraitInvul(TraitType traitType)
|
public boolean isInvulnerableTrait(TraitType traitType)
|
||||||
{
|
{
|
||||||
return _traitsInvul[traitType.ordinal()] > 0;
|
_lock.readLock().lock();
|
||||||
}
|
try
|
||||||
|
{
|
||||||
public int[] getTraitsInvul()
|
return _invulnerableTraits.contains(traitType);
|
||||||
{
|
}
|
||||||
return _traitsInvul;
|
finally
|
||||||
|
{
|
||||||
|
_lock.readLock().unlock();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1241,7 +1241,7 @@ public final class Formulas
|
|||||||
return 1.0;
|
return 1.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (target.getStat().isTraitInvul(traitType))
|
if (target.getStat().isInvulnerableTrait(traitType))
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -63,6 +63,14 @@ public enum TraitType
|
|||||||
PHYSICAL_WEAKNESS(3),
|
PHYSICAL_WEAKNESS(3),
|
||||||
MAGICAL_WEAKNESS(3),
|
MAGICAL_WEAKNESS(3),
|
||||||
DUALDAGGER(1),
|
DUALDAGGER(1),
|
||||||
|
DEMONIC_WEAKNESS(2), // CT26_P4
|
||||||
|
DIVINE_WEAKNESS(2),
|
||||||
|
ELEMENTAL_WEAKNESS(2),
|
||||||
|
FAIRY_WEAKNESS(2),
|
||||||
|
HUMAN_WEAKNESS(2),
|
||||||
|
HUMANOID_WEAKNESS(2),
|
||||||
|
UNDEAD_WEAKNESS(2),
|
||||||
|
// The values from below are custom.
|
||||||
DUALBLUNT(1),
|
DUALBLUNT(1),
|
||||||
KNOCKBACK(3),
|
KNOCKBACK(3),
|
||||||
KNOCKDOWN(3),
|
KNOCKDOWN(3),
|
||||||
@@ -75,7 +83,9 @@ public enum TraitType
|
|||||||
CHANGEBODY(3),
|
CHANGEBODY(3),
|
||||||
TWOHANDCROSSBOW(1),
|
TWOHANDCROSSBOW(1),
|
||||||
ZONE(3),
|
ZONE(3),
|
||||||
PSYCHIC(3);
|
PSYCHIC(3),
|
||||||
|
EMBRYO_WEAKNESS(2),
|
||||||
|
SPIRIT_WEAKNESS(2);
|
||||||
|
|
||||||
private final int _type; // 1 = weapon, 2 = weakness, 3 = resistance
|
private final int _type; // 1 = weapon, 2 = weakness, 3 = resistance
|
||||||
|
|
||||||
|
|||||||
@@ -22,9 +22,7 @@ import java.util.Map.Entry;
|
|||||||
|
|
||||||
import org.l2jmobius.gameserver.model.StatsSet;
|
import org.l2jmobius.gameserver.model.StatsSet;
|
||||||
import org.l2jmobius.gameserver.model.actor.Creature;
|
import org.l2jmobius.gameserver.model.actor.Creature;
|
||||||
import org.l2jmobius.gameserver.model.actor.stat.CreatureStat;
|
|
||||||
import org.l2jmobius.gameserver.model.effects.AbstractEffect;
|
import org.l2jmobius.gameserver.model.effects.AbstractEffect;
|
||||||
import org.l2jmobius.gameserver.model.items.instance.ItemInstance;
|
|
||||||
import org.l2jmobius.gameserver.model.skills.Skill;
|
import org.l2jmobius.gameserver.model.skills.Skill;
|
||||||
import org.l2jmobius.gameserver.model.stats.TraitType;
|
import org.l2jmobius.gameserver.model.stats.TraitType;
|
||||||
|
|
||||||
@@ -51,35 +49,11 @@ public final class AttackTrait extends AbstractEffect
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onExit(Creature effector, Creature effected, Skill skill)
|
public void pump(Creature effected, Skill skill)
|
||||||
{
|
{
|
||||||
final CreatureStat charStat = effected.getStat();
|
for (Entry<TraitType, Float> trait : _attackTraits.entrySet())
|
||||||
synchronized (charStat.getAttackTraits())
|
|
||||||
{
|
{
|
||||||
for (Entry<TraitType, Float> trait : _attackTraits.entrySet())
|
effected.getStat().mergeAttackTrait(trait.getKey(), trait.getValue());
|
||||||
{
|
|
||||||
if (charStat.getAttackTraitsCount()[trait.getKey().ordinal()] == 0)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
charStat.getAttackTraits()[trait.getKey().ordinal()] /= trait.getValue();
|
|
||||||
charStat.getAttackTraitsCount()[trait.getKey().ordinal()]--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onStart(Creature effector, Creature effected, Skill skill, ItemInstance item)
|
|
||||||
{
|
|
||||||
final CreatureStat charStat = effected.getStat();
|
|
||||||
synchronized (charStat.getAttackTraits())
|
|
||||||
{
|
|
||||||
for (Entry<TraitType, Float> trait : _attackTraits.entrySet())
|
|
||||||
{
|
|
||||||
charStat.getAttackTraits()[trait.getKey().ordinal()] *= trait.getValue();
|
|
||||||
charStat.getAttackTraitsCount()[trait.getKey().ordinal()]++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,9 +22,7 @@ import java.util.Map.Entry;
|
|||||||
|
|
||||||
import org.l2jmobius.gameserver.model.StatsSet;
|
import org.l2jmobius.gameserver.model.StatsSet;
|
||||||
import org.l2jmobius.gameserver.model.actor.Creature;
|
import org.l2jmobius.gameserver.model.actor.Creature;
|
||||||
import org.l2jmobius.gameserver.model.actor.stat.CreatureStat;
|
|
||||||
import org.l2jmobius.gameserver.model.effects.AbstractEffect;
|
import org.l2jmobius.gameserver.model.effects.AbstractEffect;
|
||||||
import org.l2jmobius.gameserver.model.items.instance.ItemInstance;
|
|
||||||
import org.l2jmobius.gameserver.model.skills.Skill;
|
import org.l2jmobius.gameserver.model.skills.Skill;
|
||||||
import org.l2jmobius.gameserver.model.stats.TraitType;
|
import org.l2jmobius.gameserver.model.stats.TraitType;
|
||||||
|
|
||||||
@@ -46,75 +44,22 @@ public final class DefenceTrait extends AbstractEffect
|
|||||||
|
|
||||||
for (Entry<String, Object> param : params.getSet().entrySet())
|
for (Entry<String, Object> param : params.getSet().entrySet())
|
||||||
{
|
{
|
||||||
try
|
_defenceTraits.put(TraitType.valueOf(param.getKey()), (Float.parseFloat((String) param.getValue()) + 100) / 100);
|
||||||
{
|
|
||||||
final TraitType traitType = TraitType.valueOf(param.getKey());
|
|
||||||
final float value = Float.parseFloat((String) param.getValue());
|
|
||||||
if (value == 0)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
_defenceTraits.put(traitType, (value + 100) / 100);
|
|
||||||
}
|
|
||||||
catch (NumberFormatException e)
|
|
||||||
{
|
|
||||||
LOGGER.warning(getClass().getSimpleName() + ": value of " + param.getKey() + " must be float value " + param.getValue() + " found.");
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
LOGGER.warning(getClass().getSimpleName() + ": value of TraitType enum required but found: " + param.getKey());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onExit(Creature effector, Creature effected, Skill skill)
|
public void pump(Creature effected, Skill skill)
|
||||||
{
|
{
|
||||||
final CreatureStat charStat = effected.getStat();
|
for (Entry<TraitType, Float> trait : _defenceTraits.entrySet())
|
||||||
synchronized (charStat.getDefenceTraits())
|
|
||||||
{
|
{
|
||||||
for (Entry<TraitType, Float> trait : _defenceTraits.entrySet())
|
if (trait.getValue() < 2.0f)
|
||||||
{
|
{
|
||||||
if (trait.getValue() < 2.0f)
|
effected.getStat().mergeDefenceTrait(trait.getKey(), trait.getValue());
|
||||||
{
|
|
||||||
if (charStat.getDefenceTraitsCount()[trait.getKey().ordinal()] == 0)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
charStat.getDefenceTraits()[trait.getKey().ordinal()] /= trait.getValue();
|
|
||||||
charStat.getDefenceTraitsCount()[trait.getKey().ordinal()]--;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (charStat.getTraitsInvul()[trait.getKey().ordinal()] == 0)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
charStat.getTraitsInvul()[trait.getKey().ordinal()]--;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
else
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onStart(Creature effector, Creature effected, Skill skill, ItemInstance item)
|
|
||||||
{
|
|
||||||
final CreatureStat charStat = effected.getStat();
|
|
||||||
synchronized (charStat.getDefenceTraits())
|
|
||||||
{
|
|
||||||
for (Entry<TraitType, Float> trait : _defenceTraits.entrySet())
|
|
||||||
{
|
{
|
||||||
if (trait.getValue() < 2.0f)
|
effected.getStat().mergeInvulnerableTrait(trait.getKey());
|
||||||
{
|
|
||||||
charStat.getDefenceTraits()[trait.getKey().ordinal()] *= trait.getValue();
|
|
||||||
charStat.getDefenceTraitsCount()[trait.getKey().ordinal()]++;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
charStat.getTraitsInvul()[trait.getKey().ordinal()]++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,10 +16,10 @@
|
|||||||
*/
|
*/
|
||||||
package org.l2jmobius.gameserver.model.actor.stat;
|
package org.l2jmobius.gameserver.model.actor.stat;
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Deque;
|
import java.util.Deque;
|
||||||
import java.util.EnumMap;
|
import java.util.EnumMap;
|
||||||
|
import java.util.EnumSet;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
@@ -72,11 +72,11 @@ public class CreatureStat
|
|||||||
private final Deque<StatsHolder> _additionalMul = new ConcurrentLinkedDeque<>();
|
private final Deque<StatsHolder> _additionalMul = new ConcurrentLinkedDeque<>();
|
||||||
private final Map<Stats, Double> _fixedValue = new ConcurrentHashMap<>();
|
private final Map<Stats, Double> _fixedValue = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
private final float[] _attackTraits = new float[TraitType.values().length];
|
private final float[] _attackTraitValues = new float[TraitType.values().length];
|
||||||
private final float[] _defenceTraits = new float[TraitType.values().length];
|
private final float[] _defenceTraitValues = new float[TraitType.values().length];
|
||||||
private final int[] _attackTraitsCount = new int[TraitType.values().length];
|
private final Set<TraitType> _attackTraits = EnumSet.noneOf(TraitType.class);
|
||||||
private final int[] _defenceTraitsCount = new int[TraitType.values().length];
|
private final Set<TraitType> _defenceTraits = EnumSet.noneOf(TraitType.class);
|
||||||
private final int[] _traitsInvul = new int[TraitType.values().length];
|
private final Set<TraitType> _invulnerableTraits = EnumSet.noneOf(TraitType.class);
|
||||||
|
|
||||||
/** Values to be recalculated after every stat update */
|
/** Values to be recalculated after every stat update */
|
||||||
private double _attackSpeedMultiplier = 1;
|
private double _attackSpeedMultiplier = 1;
|
||||||
@@ -87,8 +87,6 @@ public class CreatureStat
|
|||||||
public CreatureStat(Creature creature)
|
public CreatureStat(Creature creature)
|
||||||
{
|
{
|
||||||
_creature = creature;
|
_creature = creature;
|
||||||
Arrays.fill(_attackTraits, 1.0f);
|
|
||||||
Arrays.fill(_defenceTraits, 1.0f);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -573,54 +571,86 @@ public class CreatureStat
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public float getAttackTrait(TraitType traitType)
|
public void mergeAttackTrait(TraitType traitType, float value)
|
||||||
{
|
{
|
||||||
return _attackTraits[traitType.ordinal()];
|
_attackTraitValues[traitType.ordinal()] *= value;
|
||||||
|
_attackTraits.add(traitType);
|
||||||
}
|
}
|
||||||
|
|
||||||
public float[] getAttackTraits()
|
public float getAttackTrait(TraitType traitType)
|
||||||
{
|
{
|
||||||
return _attackTraits;
|
_lock.readLock().lock();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return _attackTraitValues[traitType.ordinal()];
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
_lock.readLock().unlock();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasAttackTrait(TraitType traitType)
|
public boolean hasAttackTrait(TraitType traitType)
|
||||||
{
|
{
|
||||||
return _attackTraitsCount[traitType.ordinal()] > 0;
|
_lock.readLock().lock();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return _attackTraits.contains(traitType);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
_lock.readLock().unlock();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public int[] getAttackTraitsCount()
|
public void mergeDefenceTrait(TraitType traitType, float value)
|
||||||
{
|
{
|
||||||
return _attackTraitsCount;
|
_defenceTraitValues[traitType.ordinal()] *= value;
|
||||||
|
_defenceTraits.add(traitType);
|
||||||
}
|
}
|
||||||
|
|
||||||
public float getDefenceTrait(TraitType traitType)
|
public float getDefenceTrait(TraitType traitType)
|
||||||
{
|
{
|
||||||
return _defenceTraits[traitType.ordinal()];
|
_lock.readLock().lock();
|
||||||
}
|
try
|
||||||
|
{
|
||||||
public float[] getDefenceTraits()
|
return _defenceTraitValues[traitType.ordinal()];
|
||||||
{
|
}
|
||||||
return _defenceTraits;
|
finally
|
||||||
|
{
|
||||||
|
_lock.readLock().unlock();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasDefenceTrait(TraitType traitType)
|
public boolean hasDefenceTrait(TraitType traitType)
|
||||||
{
|
{
|
||||||
return _defenceTraitsCount[traitType.ordinal()] > 0;
|
_lock.readLock().lock();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return _defenceTraits.contains(traitType);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
_lock.readLock().unlock();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public int[] getDefenceTraitsCount()
|
public void mergeInvulnerableTrait(TraitType traitType)
|
||||||
{
|
{
|
||||||
return _defenceTraitsCount;
|
_invulnerableTraits.add(traitType);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isTraitInvul(TraitType traitType)
|
public boolean isInvulnerableTrait(TraitType traitType)
|
||||||
{
|
{
|
||||||
return _traitsInvul[traitType.ordinal()] > 0;
|
_lock.readLock().lock();
|
||||||
}
|
try
|
||||||
|
{
|
||||||
public int[] getTraitsInvul()
|
return _invulnerableTraits.contains(traitType);
|
||||||
{
|
}
|
||||||
return _traitsInvul;
|
finally
|
||||||
|
{
|
||||||
|
_lock.readLock().unlock();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1241,7 +1241,7 @@ public final class Formulas
|
|||||||
return 1.0;
|
return 1.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (target.getStat().isTraitInvul(traitType))
|
if (target.getStat().isInvulnerableTrait(traitType))
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -63,6 +63,14 @@ public enum TraitType
|
|||||||
PHYSICAL_WEAKNESS(3),
|
PHYSICAL_WEAKNESS(3),
|
||||||
MAGICAL_WEAKNESS(3),
|
MAGICAL_WEAKNESS(3),
|
||||||
DUALDAGGER(1),
|
DUALDAGGER(1),
|
||||||
|
DEMONIC_WEAKNESS(2), // CT26_P4
|
||||||
|
DIVINE_WEAKNESS(2),
|
||||||
|
ELEMENTAL_WEAKNESS(2),
|
||||||
|
FAIRY_WEAKNESS(2),
|
||||||
|
HUMAN_WEAKNESS(2),
|
||||||
|
HUMANOID_WEAKNESS(2),
|
||||||
|
UNDEAD_WEAKNESS(2),
|
||||||
|
// The values from below are custom.
|
||||||
DUALBLUNT(1),
|
DUALBLUNT(1),
|
||||||
KNOCKBACK(3),
|
KNOCKBACK(3),
|
||||||
KNOCKDOWN(3),
|
KNOCKDOWN(3),
|
||||||
@@ -75,7 +83,9 @@ public enum TraitType
|
|||||||
CHANGEBODY(3),
|
CHANGEBODY(3),
|
||||||
TWOHANDCROSSBOW(1),
|
TWOHANDCROSSBOW(1),
|
||||||
ZONE(3),
|
ZONE(3),
|
||||||
PSYCHIC(3);
|
PSYCHIC(3),
|
||||||
|
EMBRYO_WEAKNESS(2),
|
||||||
|
SPIRIT_WEAKNESS(2);
|
||||||
|
|
||||||
private final int _type; // 1 = weapon, 2 = weakness, 3 = resistance
|
private final int _type; // 1 = weapon, 2 = weakness, 3 = resistance
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user