Additional weakness calculations.

This commit is contained in:
MobiusDevelopment
2019-06-11 09:11:03 +00:00
parent 9b37677bd4
commit 0038104d78
135 changed files with 2100 additions and 273 deletions

View File

@@ -23,6 +23,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.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;
@@ -49,11 +50,20 @@ public final class AttackTrait extends AbstractEffect
} }
@Override @Override
public void pump(Creature effected, Skill skill) public void onStart(Creature effector, Creature effected, Skill skill, ItemInstance item)
{ {
for (Entry<TraitType, Float> trait : _attackTraits.entrySet()) for (Entry<TraitType, Float> trait : _attackTraits.entrySet())
{ {
effected.getStat().mergeAttackTrait(trait.getKey(), trait.getValue()); effected.getStat().mergeAttackTrait(trait.getKey(), trait.getValue());
} }
} }
@Override
public void onExit(Creature effector, Creature effected, Skill skill)
{
for (Entry<TraitType, Float> trait : _attackTraits.entrySet())
{
effected.getStat().removeAttackTrait(trait.getKey(), trait.getValue());
}
}
} }

View File

@@ -23,6 +23,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.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;
@@ -49,7 +50,7 @@ public final class DefenceTrait extends AbstractEffect
} }
@Override @Override
public void pump(Creature effected, Skill skill) public void onStart(Creature effector, Creature effected, Skill skill, ItemInstance item)
{ {
for (Entry<TraitType, Float> trait : _defenceTraits.entrySet()) for (Entry<TraitType, Float> trait : _defenceTraits.entrySet())
{ {
@@ -63,4 +64,20 @@ public final class DefenceTrait extends AbstractEffect
} }
} }
} }
@Override
public void onExit(Creature effector, Creature effected, Skill skill)
{
for (Entry<TraitType, Float> trait : _defenceTraits.entrySet())
{
if (trait.getValue() < 2.0f)
{
effected.getStat().removeDefenceTrait(trait.getKey(), trait.getValue());
}
else
{
effected.getStat().removeInvulnerableTrait(trait.getKey());
}
}
}
} }

View File

@@ -125,6 +125,7 @@ public final class EnergyAttack extends AbstractEffect
// Trait, elements // Trait, elements
final double weaponTraitMod = Formulas.calcWeaponTraitBonus(attacker, effected); final double weaponTraitMod = Formulas.calcWeaponTraitBonus(attacker, effected);
final double generalTraitMod = Formulas.calcGeneralTraitBonus(attacker, effected, skill.getTraitType(), true); final double generalTraitMod = Formulas.calcGeneralTraitBonus(attacker, effected, skill.getTraitType(), true);
final double weaknessMod = Formulas.calcWeaknessBonus(attacker, effected, skill.getTraitType());
final double attributeMod = Formulas.calcAttributeBonus(attacker, effected, skill); final double attributeMod = Formulas.calcAttributeBonus(attacker, effected, skill);
final double pvpPveMod = Formulas.calculatePvpPveBonus(attacker, effected, skill, true); final double pvpPveMod = Formulas.calculatePvpPveBonus(attacker, effected, skill, true);
@@ -148,7 +149,7 @@ public final class EnergyAttack extends AbstractEffect
// ATTACK CALCULATION ((77 * ((pAtk * lvlMod) + power) * (1 + (0.1 * chargesConsumed)) / pdef) * skillPower) + skillPowerAdd // ATTACK CALCULATION ((77 * ((pAtk * lvlMod) + power) * (1 + (0.1 * chargesConsumed)) / pdef) * skillPower) + skillPowerAdd
// ```````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^```^^^^^^^^^^^^^^^^^^^^^^^^^^^^^```^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ // ```````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^```^^^^^^^^^^^^^^^^^^^^^^^^^^^^^```^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
final double baseMod = (77 * ((attacker.getPAtk() * attacker.getLevelMod()) + _power + effector.getStat().getValue(Stats.SKILL_POWER_ADD, 0))) / defence; final double baseMod = (77 * ((attacker.getPAtk() * attacker.getLevelMod()) + _power + effector.getStat().getValue(Stats.SKILL_POWER_ADD, 0))) / defence;
damage = baseMod * ssmod * critMod * weaponTraitMod * generalTraitMod * attributeMod * energyChargesBoost * pvpPveMod; damage = baseMod * ssmod * critMod * weaponTraitMod * generalTraitMod * weaknessMod * attributeMod * energyChargesBoost * pvpPveMod;
} }
damage = Math.max(0, damage * effector.getStat().getValue(Stats.PHYSICAL_SKILL_POWER, 1)); damage = Math.max(0, damage * effector.getStat().getValue(Stats.PHYSICAL_SKILL_POWER, 1));

View File

@@ -141,6 +141,7 @@ public final class PhysicalAttack extends AbstractEffect
// Trait, elements // Trait, elements
final double weaponTraitMod = Formulas.calcWeaponTraitBonus(effector, effected); final double weaponTraitMod = Formulas.calcWeaponTraitBonus(effector, effected);
final double generalTraitMod = Formulas.calcGeneralTraitBonus(effector, effected, skill.getTraitType(), true); final double generalTraitMod = Formulas.calcGeneralTraitBonus(effector, effected, skill.getTraitType(), true);
final double weaknessMod = Formulas.calcWeaknessBonus(effector, effected, skill.getTraitType());
final double attributeMod = Formulas.calcAttributeBonus(effector, effected, skill); final double attributeMod = Formulas.calcAttributeBonus(effector, effected, skill);
final double pvpPveMod = Formulas.calculatePvpPveBonus(effector, effected, skill, true); final double pvpPveMod = Formulas.calculatePvpPveBonus(effector, effected, skill, true);
final double randomMod = effector.getRandomDamageMultiplier(); final double randomMod = effector.getRandomDamageMultiplier();
@@ -168,7 +169,7 @@ public final class PhysicalAttack extends AbstractEffect
// ATTACK CALCULATION 77 * ((pAtk * lvlMod) + power) / pdef            RANGED ATTACK CALCULATION 70 * ((pAtk * lvlMod) + power + patk + power) / pdef // ATTACK CALCULATION 77 * ((pAtk * lvlMod) + power) / pdef            RANGED ATTACK CALCULATION 70 * ((pAtk * lvlMod) + power + patk + power) / pdef
// ```````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^``````````````````````````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ // ```````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^``````````````````````````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
final double baseMod = (weaponMod * ((attack * effector.getLevelMod()) + power + rangedBonus)) / defence; final double baseMod = (weaponMod * ((attack * effector.getLevelMod()) + power + rangedBonus)) / defence;
damage = baseMod * abnormalMod * ssmod * critMod * weaponTraitMod * generalTraitMod * attributeMod * pvpPveMod * randomMod; damage = baseMod * abnormalMod * ssmod * critMod * weaponTraitMod * generalTraitMod * weaknessMod * attributeMod * pvpPveMod * randomMod;
damage *= effector.getStat().getValue(Stats.PHYSICAL_SKILL_POWER, 1); damage *= effector.getStat().getValue(Stats.PHYSICAL_SKILL_POWER, 1);
} }

View File

@@ -101,6 +101,7 @@ public final class PhysicalAttackHpLink extends AbstractEffect
// Trait, elements // Trait, elements
final double weaponTraitMod = Formulas.calcWeaponTraitBonus(effector, effected); final double weaponTraitMod = Formulas.calcWeaponTraitBonus(effector, effected);
final double generalTraitMod = Formulas.calcGeneralTraitBonus(effector, effected, skill.getTraitType(), true); final double generalTraitMod = Formulas.calcGeneralTraitBonus(effector, effected, skill.getTraitType(), true);
final double weaknessMod = Formulas.calcWeaknessBonus(effector, effected, skill.getTraitType());
final double attributeMod = Formulas.calcAttributeBonus(effector, effected, skill); final double attributeMod = Formulas.calcAttributeBonus(effector, effected, skill);
final double pvpPveMod = Formulas.calculatePvpPveBonus(effector, effected, skill, true); final double pvpPveMod = Formulas.calculatePvpPveBonus(effector, effected, skill, true);
final double randomMod = effector.getRandomDamageMultiplier(); final double randomMod = effector.getRandomDamageMultiplier();
@@ -127,7 +128,7 @@ public final class PhysicalAttackHpLink extends AbstractEffect
// ATTACK CALCULATION 77 * ((pAtk * lvlMod) + power) / pdef            RANGED ATTACK CALCULATION 70 * ((pAtk * lvlMod) + power + patk + power) / pdef // ATTACK CALCULATION 77 * ((pAtk * lvlMod) + power) / pdef            RANGED ATTACK CALCULATION 70 * ((pAtk * lvlMod) + power + patk + power) / pdef
// ```````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^``````````````````````````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ // ```````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^``````````````````````````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
final double baseMod = (weaponMod * ((attack * effector.getLevelMod()) + power + rangedBonus)) / defence; final double baseMod = (weaponMod * ((attack * effector.getLevelMod()) + power + rangedBonus)) / defence;
damage = baseMod * ssmod * critMod * weaponTraitMod * generalTraitMod * attributeMod * pvpPveMod * randomMod; damage = baseMod * ssmod * critMod * weaponTraitMod * generalTraitMod * weaknessMod * attributeMod * pvpPveMod * randomMod;
damage *= effector.getStat().getValue(Stats.PHYSICAL_SKILL_POWER, 1); damage *= effector.getStat().getValue(Stats.PHYSICAL_SKILL_POWER, 1);
damage *= -((effector.getCurrentHp() * 2) / effector.getMaxHp()) + 2; damage *= -((effector.getCurrentHp() * 2) / effector.getMaxHp()) + 2;
} }

View File

@@ -114,6 +114,7 @@ public final class PhysicalAttackSaveHp extends AbstractEffect
// Trait, elements // Trait, elements
final double weaponTraitMod = Formulas.calcWeaponTraitBonus(effector, effected); final double weaponTraitMod = Formulas.calcWeaponTraitBonus(effector, effected);
final double generalTraitMod = Formulas.calcGeneralTraitBonus(effector, effected, skill.getTraitType(), true); final double generalTraitMod = Formulas.calcGeneralTraitBonus(effector, effected, skill.getTraitType(), true);
final double weaknessMod = Formulas.calcWeaknessBonus(effector, effected, skill.getTraitType());
final double attributeMod = Formulas.calcAttributeBonus(effector, effected, skill); final double attributeMod = Formulas.calcAttributeBonus(effector, effected, skill);
final double pvpPveMod = Formulas.calculatePvpPveBonus(effector, effected, skill, true); final double pvpPveMod = Formulas.calculatePvpPveBonus(effector, effected, skill, true);
final double randomMod = effector.getRandomDamageMultiplier(); final double randomMod = effector.getRandomDamageMultiplier();
@@ -140,7 +141,7 @@ public final class PhysicalAttackSaveHp extends AbstractEffect
// ATTACK CALCULATION 77 * ((pAtk * lvlMod) + power) / pdef            RANGED ATTACK CALCULATION 70 * ((pAtk * lvlMod) + power + patk + power) / pdef // ATTACK CALCULATION 77 * ((pAtk * lvlMod) + power) / pdef            RANGED ATTACK CALCULATION 70 * ((pAtk * lvlMod) + power + patk + power) / pdef
// ```````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^``````````````````````````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ // ```````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^``````````````````````````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
final double baseMod = (weaponMod * ((attack * effector.getLevelMod()) + power + rangedBonus)) / defence; final double baseMod = (weaponMod * ((attack * effector.getLevelMod()) + power + rangedBonus)) / defence;
damage = baseMod * ssmod * critMod * weaponTraitMod * generalTraitMod * attributeMod * pvpPveMod * randomMod; damage = baseMod * ssmod * critMod * weaponTraitMod * generalTraitMod * weaknessMod * attributeMod * pvpPveMod * randomMod;
damage *= effector.getStat().getValue(Stats.PHYSICAL_SKILL_POWER, 1); damage *= effector.getStat().getValue(Stats.PHYSICAL_SKILL_POWER, 1);
} }

View File

@@ -134,6 +134,7 @@ public final class PhysicalAttackWeaponBonus extends AbstractEffect
// Trait, elements // Trait, elements
final double weaponTraitMod = Formulas.calcWeaponTraitBonus(effector, effected); final double weaponTraitMod = Formulas.calcWeaponTraitBonus(effector, effected);
final double generalTraitMod = Formulas.calcGeneralTraitBonus(effector, effected, skill.getTraitType(), true); final double generalTraitMod = Formulas.calcGeneralTraitBonus(effector, effected, skill.getTraitType(), true);
final double weaknessMod = Formulas.calcWeaknessBonus(effector, effected, skill.getTraitType());
final double attributeMod = Formulas.calcAttributeBonus(effector, effected, skill); final double attributeMod = Formulas.calcAttributeBonus(effector, effected, skill);
final double pvpPveMod = Formulas.calculatePvpPveBonus(effector, effected, skill, true); final double pvpPveMod = Formulas.calculatePvpPveBonus(effector, effected, skill, true);
final double randomMod = effector.getRandomDamageMultiplier(); final double randomMod = effector.getRandomDamageMultiplier();
@@ -161,7 +162,7 @@ public final class PhysicalAttackWeaponBonus extends AbstractEffect
// ATTACK CALCULATION 77 * ((pAtk * lvlMod) + power) / pdef            RANGED ATTACK CALCULATION 70 * ((pAtk * lvlMod) + power + patk + power) / pdef // ATTACK CALCULATION 77 * ((pAtk * lvlMod) + power) / pdef            RANGED ATTACK CALCULATION 70 * ((pAtk * lvlMod) + power + patk + power) / pdef
// ```````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^``````````````````````````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ // ```````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^``````````````````````````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
final double baseMod = (weaponMod * ((attack * effector.getLevelMod()) + power + rangedBonus)) / defence; final double baseMod = (weaponMod * ((attack * effector.getLevelMod()) + power + rangedBonus)) / defence;
damage = baseMod * ssmod * critMod * weaponBonus * weaponTraitMod * generalTraitMod * attributeMod * pvpPveMod * randomMod; damage = baseMod * ssmod * critMod * weaponBonus * weaponTraitMod * generalTraitMod * weaknessMod * attributeMod * pvpPveMod * randomMod;
damage *= effector.getStat().getValue(Stats.PHYSICAL_SKILL_POWER, 1); damage *= effector.getStat().getValue(Stats.PHYSICAL_SKILL_POWER, 1);
} }

View File

@@ -128,6 +128,7 @@ public final class PhysicalSoulAttack extends AbstractEffect
// Trait, elements // Trait, elements
final double weaponTraitMod = Formulas.calcWeaponTraitBonus(effector, effected); final double weaponTraitMod = Formulas.calcWeaponTraitBonus(effector, effected);
final double generalTraitMod = Formulas.calcGeneralTraitBonus(effector, effected, skill.getTraitType(), true); final double generalTraitMod = Formulas.calcGeneralTraitBonus(effector, effected, skill.getTraitType(), true);
final double weaknessMod = Formulas.calcWeaknessBonus(effector, effected, skill.getTraitType());
final double attributeMod = Formulas.calcAttributeBonus(effector, effected, skill); final double attributeMod = Formulas.calcAttributeBonus(effector, effected, skill);
final double pvpPveMod = Formulas.calculatePvpPveBonus(effector, effected, skill, true); final double pvpPveMod = Formulas.calculatePvpPveBonus(effector, effected, skill, true);
final double randomMod = effector.getRandomDamageMultiplier(); final double randomMod = effector.getRandomDamageMultiplier();
@@ -155,7 +156,7 @@ public final class PhysicalSoulAttack extends AbstractEffect
// ATTACK CALCULATION 77 * ((pAtk * lvlMod) + power) / pdef            RANGED ATTACK CALCULATION 70 * ((pAtk * lvlMod) + power + patk + power) / pdef // ATTACK CALCULATION 77 * ((pAtk * lvlMod) + power) / pdef            RANGED ATTACK CALCULATION 70 * ((pAtk * lvlMod) + power + patk + power) / pdef
// ```````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^``````````````````````````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ // ```````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^``````````````````````````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
final double baseMod = (weaponMod * ((attack * effector.getLevelMod()) + power + rangedBonus)) / defence; final double baseMod = (weaponMod * ((attack * effector.getLevelMod()) + power + rangedBonus)) / defence;
damage = baseMod * soulsMod * ssmod * critMod * weaponTraitMod * generalTraitMod * attributeMod * pvpPveMod * randomMod; damage = baseMod * soulsMod * ssmod * critMod * weaponTraitMod * generalTraitMod * weaknessMod * attributeMod * pvpPveMod * randomMod;
damage *= effector.getStat().getValue(Stats.PHYSICAL_SKILL_POWER, 1); damage *= effector.getStat().getValue(Stats.PHYSICAL_SKILL_POWER, 1);
} }

View File

@@ -87,6 +87,11 @@ public class CreatureStat
public CreatureStat(Creature creature) public CreatureStat(Creature creature)
{ {
_creature = creature; _creature = creature;
for (int i = 0; i < TraitType.values().length; i++)
{
_attackTraitValues[i] = 1;
_defenceTraitValues[i] = 1;
}
} }
/** /**
@@ -582,10 +587,35 @@ public class CreatureStat
} }
public void mergeAttackTrait(TraitType traitType, float value) public void mergeAttackTrait(TraitType traitType, float value)
{
_lock.readLock().lock();
try
{ {
_attackTraitValues[traitType.ordinal()] *= value; _attackTraitValues[traitType.ordinal()] *= value;
_attackTraits.add(traitType); _attackTraits.add(traitType);
} }
finally
{
_lock.readLock().unlock();
}
}
public void removeAttackTrait(TraitType traitType, float value)
{
_lock.readLock().lock();
try
{
_attackTraitValues[traitType.ordinal()] /= value;
if (_attackTraitValues[traitType.ordinal()] == 1)
{
_attackTraits.remove(traitType);
}
}
finally
{
_lock.readLock().unlock();
}
}
public float getAttackTrait(TraitType traitType) public float getAttackTrait(TraitType traitType)
{ {
@@ -614,10 +644,35 @@ public class CreatureStat
} }
public void mergeDefenceTrait(TraitType traitType, float value) public void mergeDefenceTrait(TraitType traitType, float value)
{
_lock.readLock().lock();
try
{ {
_defenceTraitValues[traitType.ordinal()] *= value; _defenceTraitValues[traitType.ordinal()] *= value;
_defenceTraits.add(traitType); _defenceTraits.add(traitType);
} }
finally
{
_lock.readLock().unlock();
}
}
public void removeDefenceTrait(TraitType traitType, float value)
{
_lock.readLock().lock();
try
{
_defenceTraitValues[traitType.ordinal()] /= value;
if (_defenceTraitValues[traitType.ordinal()] == 1)
{
_defenceTraits.remove(traitType);
}
}
finally
{
_lock.readLock().unlock();
}
}
public float getDefenceTrait(TraitType traitType) public float getDefenceTrait(TraitType traitType)
{ {
@@ -646,9 +701,30 @@ public class CreatureStat
} }
public void mergeInvulnerableTrait(TraitType traitType) public void mergeInvulnerableTrait(TraitType traitType)
{
_lock.readLock().lock();
try
{ {
_invulnerableTraits.add(traitType); _invulnerableTraits.add(traitType);
} }
finally
{
_lock.readLock().unlock();
}
}
public void removeInvulnerableTrait(TraitType traitType)
{
_lock.readLock().lock();
try
{
_invulnerableTraits.remove(traitType);
}
finally
{
_lock.readLock().unlock();
}
}
public boolean isInvulnerableTrait(TraitType traitType) public boolean isInvulnerableTrait(TraitType traitType)
{ {

View File

@@ -94,14 +94,15 @@ public final class Formulas
} }
// Critical // Critical
final double criticalMod = (attacker.getStat().getValue(Stats.CRITICAL_DAMAGE, 1)); final double criticalMod = attacker.getStat().getValue(Stats.CRITICAL_DAMAGE, 1);
final double criticalPositionMod = attacker.getStat().getPositionTypeValue(Stats.CRITICAL_DAMAGE, Position.getPosition(attacker, target)); final double criticalPositionMod = attacker.getStat().getPositionTypeValue(Stats.CRITICAL_DAMAGE, Position.getPosition(attacker, target));
final double criticalVulnMod = (target.getStat().getValue(Stats.DEFENCE_CRITICAL_DAMAGE, 1)); final double criticalVulnMod = target.getStat().getValue(Stats.DEFENCE_CRITICAL_DAMAGE, 1);
final double criticalAddMod = (attacker.getStat().getValue(Stats.CRITICAL_DAMAGE_ADD, 0)); final double criticalAddMod = attacker.getStat().getValue(Stats.CRITICAL_DAMAGE_ADD, 0);
final double criticalAddVuln = target.getStat().getValue(Stats.DEFENCE_CRITICAL_DAMAGE_ADD, 0); final double criticalAddVuln = target.getStat().getValue(Stats.DEFENCE_CRITICAL_DAMAGE_ADD, 0);
// Trait, elements // Trait, elements
final double weaponTraitMod = calcWeaponTraitBonus(attacker, target); final double weaponTraitMod = calcWeaponTraitBonus(attacker, target);
final double generalTraitMod = calcGeneralTraitBonus(attacker, target, skill.getTraitType(), true); final double generalTraitMod = calcGeneralTraitBonus(attacker, target, skill.getTraitType(), true);
final double weaknessMod = calcWeaknessBonus(attacker, target, skill.getTraitType());
final double attributeMod = calcAttributeBonus(attacker, target, skill); final double attributeMod = calcAttributeBonus(attacker, target, skill);
final double randomMod = attacker.getRandomDamageMultiplier(); final double randomMod = attacker.getRandomDamageMultiplier();
final double pvpPveMod = calculatePvpPveBonus(attacker, target, skill, true); final double pvpPveMod = calculatePvpPveBonus(attacker, target, skill, true);
@@ -122,8 +123,8 @@ public final class Formulas
// ........................_____________________________Initial Damage____________________________...___________Position Additional Damage___________..._CriticalAdd_ // ........................_____________________________Initial Damage____________________________...___________Position Additional Damage___________..._CriticalAdd_
// ATTACK CALCULATION 77 * [(skillpower+patk) * 0.666 * cdbonus * cdPosBonusHalf * cdVulnHalf * ss + isBack0.2Side0.05 * (skillpower+patk*ss) * random + 6 * cd_patk] / pdef // ATTACK CALCULATION 77 * [(skillpower+patk) * 0.666 * cdbonus * cdPosBonusHalf * cdVulnHalf * ss + isBack0.2Side0.05 * (skillpower+patk*ss) * random + 6 * cd_patk] / pdef
// ````````````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^```^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^```^^^^^^^^^^^^ // ````````````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^```^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^```^^^^^^^^^^^^
final double baseMod = ((77 * (((power + attacker.getPAtk()) * 0.666) + (isPosition * (power + attacker.getPAtk()) * randomMod) + (6 * cdPatk))) / defence); final double baseMod = (77 * (((power + attacker.getPAtk()) * 0.666) + (isPosition * (power + attacker.getPAtk()) * randomMod) + (6 * cdPatk))) / defence;
final double damage = baseMod * ssmod * cdMult * weaponTraitMod * generalTraitMod * attributeMod * randomMod * pvpPveMod; final double damage = baseMod * ssmod * cdMult * weaponTraitMod * generalTraitMod * weaknessMod * attributeMod * randomMod * pvpPveMod;
return damage; return damage;
} }
@@ -136,6 +137,7 @@ public final class Formulas
// Trait, elements // Trait, elements
final double generalTraitMod = calcGeneralTraitBonus(attacker, target, skill.getTraitType(), true); final double generalTraitMod = calcGeneralTraitBonus(attacker, target, skill.getTraitType(), true);
final double weaknessMod = calcWeaknessBonus(attacker, target, skill.getTraitType());
final double attributeMod = calcAttributeBonus(attacker, target, skill); final double attributeMod = calcAttributeBonus(attacker, target, skill);
final double randomMod = attacker.getRandomDamageMultiplier(); final double randomMod = attacker.getRandomDamageMultiplier();
final double pvpPveMod = calculatePvpPveBonus(attacker, target, skill, mcrit); final double pvpPveMod = calculatePvpPveBonus(attacker, target, skill, mcrit);
@@ -178,7 +180,7 @@ public final class Formulas
} }
} }
damage = damage * critMod * generalTraitMod * attributeMod * randomMod * pvpPveMod; damage = damage * critMod * generalTraitMod * weaknessMod * attributeMod * randomMod * pvpPveMod;
damage *= attacker.getStat().getValue(Stats.MAGICAL_SKILL_POWER, 1); damage *= attacker.getStat().getValue(Stats.MAGICAL_SKILL_POWER, 1);
return damage; return damage;
@@ -1270,8 +1272,20 @@ public final class Formulas
} }
} }
final double result = (attacker.getStat().getAttackTrait(traitType) - target.getStat().getDefenceTrait(traitType)) + 1.0; return Math.max(attacker.getStat().getAttackTrait(traitType) - target.getStat().getDefenceTrait(traitType), 0.05);
return CommonUtil.constrain(result, 0.05, 2.0); }
public static double calcWeaknessBonus(Creature attacker, Creature target, TraitType traitType)
{
double result = 1;
for (TraitType trait : TraitType.getAllWeakness())
{
if ((traitType != trait) && target.getStat().hasDefenceTrait(trait) && attacker.getStat().hasAttackTrait(trait) && !target.getStat().isInvulnerableTrait(traitType))
{
result *= Math.max(attacker.getStat().getAttackTrait(trait) - target.getStat().getDefenceTrait(trait), 0.05);
}
}
return result;
} }
public static double calcWeaponTraitBonus(Creature attacker, Creature target) public static double calcWeaponTraitBonus(Creature attacker, Creature target)
@@ -1300,7 +1314,7 @@ public final class Formulas
} }
} }
return CommonUtil.constrain((weaponTraitBonus * weaknessBonus), 0.05, 2.0); return Math.max(weaponTraitBonus * weaknessBonus, 0.05);
} }
public static double getBasicPropertyResistBonus(BasicProperty basicProperty, Creature target) public static double getBasicPropertyResistBonus(BasicProperty basicProperty, Creature target)

View File

@@ -16,6 +16,9 @@
*/ */
package org.l2jmobius.gameserver.model.stats; package org.l2jmobius.gameserver.model.stats;
import java.util.ArrayList;
import java.util.List;
/** /**
* @author UnAfraid, NosBit * @author UnAfraid, NosBit
*/ */
@@ -88,6 +91,33 @@ public enum TraitType
SPIRIT_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
private final static List<TraitType> _weaknesses = new ArrayList<>();
static
{
_weaknesses.add(BUG_WEAKNESS);
_weaknesses.add(ANIMAL_WEAKNESS);
_weaknesses.add(PLANT_WEAKNESS);
_weaknesses.add(BEAST_WEAKNESS);
_weaknesses.add(DRAGON_WEAKNESS);
_weaknesses.add(GIANT_WEAKNESS);
_weaknesses.add(CONSTRUCT_WEAKNESS);
_weaknesses.add(VALAKAS);
_weaknesses.add(ANESTHESIA);
_weaknesses.add(DEMONIC_WEAKNESS);
_weaknesses.add(DIVINE_WEAKNESS);
_weaknesses.add(ELEMENTAL_WEAKNESS);
_weaknesses.add(FAIRY_WEAKNESS);
_weaknesses.add(HUMAN_WEAKNESS);
_weaknesses.add(HUMANOID_WEAKNESS);
_weaknesses.add(UNDEAD_WEAKNESS);
_weaknesses.add(EMBRYO_WEAKNESS);
_weaknesses.add(SPIRIT_WEAKNESS);
}
public static List<TraitType> getAllWeakness()
{
return _weaknesses;
}
TraitType(int type) TraitType(int type)
{ {

View File

@@ -23,6 +23,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.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;
@@ -49,11 +50,20 @@ public final class AttackTrait extends AbstractEffect
} }
@Override @Override
public void pump(Creature effected, Skill skill) public void onStart(Creature effector, Creature effected, Skill skill, ItemInstance item)
{ {
for (Entry<TraitType, Float> trait : _attackTraits.entrySet()) for (Entry<TraitType, Float> trait : _attackTraits.entrySet())
{ {
effected.getStat().mergeAttackTrait(trait.getKey(), trait.getValue()); effected.getStat().mergeAttackTrait(trait.getKey(), trait.getValue());
} }
} }
@Override
public void onExit(Creature effector, Creature effected, Skill skill)
{
for (Entry<TraitType, Float> trait : _attackTraits.entrySet())
{
effected.getStat().removeAttackTrait(trait.getKey(), trait.getValue());
}
}
} }

View File

@@ -23,6 +23,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.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;
@@ -49,7 +50,7 @@ public final class DefenceTrait extends AbstractEffect
} }
@Override @Override
public void pump(Creature effected, Skill skill) public void onStart(Creature effector, Creature effected, Skill skill, ItemInstance item)
{ {
for (Entry<TraitType, Float> trait : _defenceTraits.entrySet()) for (Entry<TraitType, Float> trait : _defenceTraits.entrySet())
{ {
@@ -63,4 +64,20 @@ public final class DefenceTrait extends AbstractEffect
} }
} }
} }
@Override
public void onExit(Creature effector, Creature effected, Skill skill)
{
for (Entry<TraitType, Float> trait : _defenceTraits.entrySet())
{
if (trait.getValue() < 2.0f)
{
effected.getStat().removeDefenceTrait(trait.getKey(), trait.getValue());
}
else
{
effected.getStat().removeInvulnerableTrait(trait.getKey());
}
}
}
} }

View File

@@ -125,6 +125,7 @@ public final class EnergyAttack extends AbstractEffect
// Trait, elements // Trait, elements
final double weaponTraitMod = Formulas.calcWeaponTraitBonus(attacker, effected); final double weaponTraitMod = Formulas.calcWeaponTraitBonus(attacker, effected);
final double generalTraitMod = Formulas.calcGeneralTraitBonus(attacker, effected, skill.getTraitType(), true); final double generalTraitMod = Formulas.calcGeneralTraitBonus(attacker, effected, skill.getTraitType(), true);
final double weaknessMod = Formulas.calcWeaknessBonus(attacker, effected, skill.getTraitType());
final double attributeMod = Formulas.calcAttributeBonus(attacker, effected, skill); final double attributeMod = Formulas.calcAttributeBonus(attacker, effected, skill);
final double pvpPveMod = Formulas.calculatePvpPveBonus(attacker, effected, skill, true); final double pvpPveMod = Formulas.calculatePvpPveBonus(attacker, effected, skill, true);
@@ -148,7 +149,7 @@ public final class EnergyAttack extends AbstractEffect
// ATTACK CALCULATION ((77 * ((pAtk * lvlMod) + power) * (1 + (0.1 * chargesConsumed)) / pdef) * skillPower) + skillPowerAdd // ATTACK CALCULATION ((77 * ((pAtk * lvlMod) + power) * (1 + (0.1 * chargesConsumed)) / pdef) * skillPower) + skillPowerAdd
// ```````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^```^^^^^^^^^^^^^^^^^^^^^^^^^^^^^```^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ // ```````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^```^^^^^^^^^^^^^^^^^^^^^^^^^^^^^```^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
final double baseMod = (77 * ((attacker.getPAtk() * attacker.getLevelMod()) + _power + effector.getStat().getValue(Stats.SKILL_POWER_ADD, 0))) / defence; final double baseMod = (77 * ((attacker.getPAtk() * attacker.getLevelMod()) + _power + effector.getStat().getValue(Stats.SKILL_POWER_ADD, 0))) / defence;
damage = baseMod * ssmod * critMod * weaponTraitMod * generalTraitMod * attributeMod * energyChargesBoost * pvpPveMod; damage = baseMod * ssmod * critMod * weaponTraitMod * generalTraitMod * weaknessMod * attributeMod * energyChargesBoost * pvpPveMod;
} }
damage = Math.max(0, damage * effector.getStat().getValue(Stats.PHYSICAL_SKILL_POWER, 1)); damage = Math.max(0, damage * effector.getStat().getValue(Stats.PHYSICAL_SKILL_POWER, 1));

View File

@@ -141,6 +141,7 @@ public final class PhysicalAttack extends AbstractEffect
// Trait, elements // Trait, elements
final double weaponTraitMod = Formulas.calcWeaponTraitBonus(effector, effected); final double weaponTraitMod = Formulas.calcWeaponTraitBonus(effector, effected);
final double generalTraitMod = Formulas.calcGeneralTraitBonus(effector, effected, skill.getTraitType(), true); final double generalTraitMod = Formulas.calcGeneralTraitBonus(effector, effected, skill.getTraitType(), true);
final double weaknessMod = Formulas.calcWeaknessBonus(effector, effected, skill.getTraitType());
final double attributeMod = Formulas.calcAttributeBonus(effector, effected, skill); final double attributeMod = Formulas.calcAttributeBonus(effector, effected, skill);
final double pvpPveMod = Formulas.calculatePvpPveBonus(effector, effected, skill, true); final double pvpPveMod = Formulas.calculatePvpPveBonus(effector, effected, skill, true);
final double randomMod = effector.getRandomDamageMultiplier(); final double randomMod = effector.getRandomDamageMultiplier();
@@ -168,7 +169,7 @@ public final class PhysicalAttack extends AbstractEffect
// ATTACK CALCULATION 77 * ((pAtk * lvlMod) + power) / pdef            RANGED ATTACK CALCULATION 70 * ((pAtk * lvlMod) + power + patk + power) / pdef // ATTACK CALCULATION 77 * ((pAtk * lvlMod) + power) / pdef            RANGED ATTACK CALCULATION 70 * ((pAtk * lvlMod) + power + patk + power) / pdef
// ```````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^``````````````````````````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ // ```````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^``````````````````````````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
final double baseMod = (weaponMod * ((attack * effector.getLevelMod()) + power + rangedBonus)) / defence; final double baseMod = (weaponMod * ((attack * effector.getLevelMod()) + power + rangedBonus)) / defence;
damage = baseMod * abnormalMod * ssmod * critMod * weaponTraitMod * generalTraitMod * attributeMod * pvpPveMod * randomMod; damage = baseMod * abnormalMod * ssmod * critMod * weaponTraitMod * generalTraitMod * weaknessMod * attributeMod * pvpPveMod * randomMod;
damage *= effector.getStat().getValue(Stats.PHYSICAL_SKILL_POWER, 1); damage *= effector.getStat().getValue(Stats.PHYSICAL_SKILL_POWER, 1);
} }

View File

@@ -101,6 +101,7 @@ public final class PhysicalAttackHpLink extends AbstractEffect
// Trait, elements // Trait, elements
final double weaponTraitMod = Formulas.calcWeaponTraitBonus(effector, effected); final double weaponTraitMod = Formulas.calcWeaponTraitBonus(effector, effected);
final double generalTraitMod = Formulas.calcGeneralTraitBonus(effector, effected, skill.getTraitType(), true); final double generalTraitMod = Formulas.calcGeneralTraitBonus(effector, effected, skill.getTraitType(), true);
final double weaknessMod = Formulas.calcWeaknessBonus(effector, effected, skill.getTraitType());
final double attributeMod = Formulas.calcAttributeBonus(effector, effected, skill); final double attributeMod = Formulas.calcAttributeBonus(effector, effected, skill);
final double pvpPveMod = Formulas.calculatePvpPveBonus(effector, effected, skill, true); final double pvpPveMod = Formulas.calculatePvpPveBonus(effector, effected, skill, true);
final double randomMod = effector.getRandomDamageMultiplier(); final double randomMod = effector.getRandomDamageMultiplier();
@@ -127,7 +128,7 @@ public final class PhysicalAttackHpLink extends AbstractEffect
// ATTACK CALCULATION 77 * ((pAtk * lvlMod) + power) / pdef            RANGED ATTACK CALCULATION 70 * ((pAtk * lvlMod) + power + patk + power) / pdef // ATTACK CALCULATION 77 * ((pAtk * lvlMod) + power) / pdef            RANGED ATTACK CALCULATION 70 * ((pAtk * lvlMod) + power + patk + power) / pdef
// ```````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^``````````````````````````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ // ```````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^``````````````````````````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
final double baseMod = (weaponMod * ((attack * effector.getLevelMod()) + power + rangedBonus)) / defence; final double baseMod = (weaponMod * ((attack * effector.getLevelMod()) + power + rangedBonus)) / defence;
damage = baseMod * ssmod * critMod * weaponTraitMod * generalTraitMod * attributeMod * pvpPveMod * randomMod; damage = baseMod * ssmod * critMod * weaponTraitMod * generalTraitMod * weaknessMod * attributeMod * pvpPveMod * randomMod;
damage *= effector.getStat().getValue(Stats.PHYSICAL_SKILL_POWER, 1); damage *= effector.getStat().getValue(Stats.PHYSICAL_SKILL_POWER, 1);
damage *= -((effector.getCurrentHp() * 2) / effector.getMaxHp()) + 2; damage *= -((effector.getCurrentHp() * 2) / effector.getMaxHp()) + 2;
} }

View File

@@ -114,6 +114,7 @@ public final class PhysicalAttackSaveHp extends AbstractEffect
// Trait, elements // Trait, elements
final double weaponTraitMod = Formulas.calcWeaponTraitBonus(effector, effected); final double weaponTraitMod = Formulas.calcWeaponTraitBonus(effector, effected);
final double generalTraitMod = Formulas.calcGeneralTraitBonus(effector, effected, skill.getTraitType(), true); final double generalTraitMod = Formulas.calcGeneralTraitBonus(effector, effected, skill.getTraitType(), true);
final double weaknessMod = Formulas.calcWeaknessBonus(effector, effected, skill.getTraitType());
final double attributeMod = Formulas.calcAttributeBonus(effector, effected, skill); final double attributeMod = Formulas.calcAttributeBonus(effector, effected, skill);
final double pvpPveMod = Formulas.calculatePvpPveBonus(effector, effected, skill, true); final double pvpPveMod = Formulas.calculatePvpPveBonus(effector, effected, skill, true);
final double randomMod = effector.getRandomDamageMultiplier(); final double randomMod = effector.getRandomDamageMultiplier();
@@ -140,7 +141,7 @@ public final class PhysicalAttackSaveHp extends AbstractEffect
// ATTACK CALCULATION 77 * ((pAtk * lvlMod) + power) / pdef            RANGED ATTACK CALCULATION 70 * ((pAtk * lvlMod) + power + patk + power) / pdef // ATTACK CALCULATION 77 * ((pAtk * lvlMod) + power) / pdef            RANGED ATTACK CALCULATION 70 * ((pAtk * lvlMod) + power + patk + power) / pdef
// ```````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^``````````````````````````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ // ```````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^``````````````````````````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
final double baseMod = (weaponMod * ((attack * effector.getLevelMod()) + power + rangedBonus)) / defence; final double baseMod = (weaponMod * ((attack * effector.getLevelMod()) + power + rangedBonus)) / defence;
damage = baseMod * ssmod * critMod * weaponTraitMod * generalTraitMod * attributeMod * pvpPveMod * randomMod; damage = baseMod * ssmod * critMod * weaponTraitMod * generalTraitMod * weaknessMod * attributeMod * pvpPveMod * randomMod;
damage *= effector.getStat().getValue(Stats.PHYSICAL_SKILL_POWER, 1); damage *= effector.getStat().getValue(Stats.PHYSICAL_SKILL_POWER, 1);
} }

View File

@@ -134,6 +134,7 @@ public final class PhysicalAttackWeaponBonus extends AbstractEffect
// Trait, elements // Trait, elements
final double weaponTraitMod = Formulas.calcWeaponTraitBonus(effector, effected); final double weaponTraitMod = Formulas.calcWeaponTraitBonus(effector, effected);
final double generalTraitMod = Formulas.calcGeneralTraitBonus(effector, effected, skill.getTraitType(), true); final double generalTraitMod = Formulas.calcGeneralTraitBonus(effector, effected, skill.getTraitType(), true);
final double weaknessMod = Formulas.calcWeaknessBonus(effector, effected, skill.getTraitType());
final double attributeMod = Formulas.calcAttributeBonus(effector, effected, skill); final double attributeMod = Formulas.calcAttributeBonus(effector, effected, skill);
final double pvpPveMod = Formulas.calculatePvpPveBonus(effector, effected, skill, true); final double pvpPveMod = Formulas.calculatePvpPveBonus(effector, effected, skill, true);
final double randomMod = effector.getRandomDamageMultiplier(); final double randomMod = effector.getRandomDamageMultiplier();
@@ -161,7 +162,7 @@ public final class PhysicalAttackWeaponBonus extends AbstractEffect
// ATTACK CALCULATION 77 * ((pAtk * lvlMod) + power) / pdef            RANGED ATTACK CALCULATION 70 * ((pAtk * lvlMod) + power + patk + power) / pdef // ATTACK CALCULATION 77 * ((pAtk * lvlMod) + power) / pdef            RANGED ATTACK CALCULATION 70 * ((pAtk * lvlMod) + power + patk + power) / pdef
// ```````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^``````````````````````````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ // ```````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^``````````````````````````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
final double baseMod = (weaponMod * ((attack * effector.getLevelMod()) + power + rangedBonus)) / defence; final double baseMod = (weaponMod * ((attack * effector.getLevelMod()) + power + rangedBonus)) / defence;
damage = baseMod * ssmod * critMod * weaponBonus * weaponTraitMod * generalTraitMod * attributeMod * pvpPveMod * randomMod; damage = baseMod * ssmod * critMod * weaponBonus * weaponTraitMod * generalTraitMod * weaknessMod * attributeMod * pvpPveMod * randomMod;
damage *= effector.getStat().getValue(Stats.PHYSICAL_SKILL_POWER, 1); damage *= effector.getStat().getValue(Stats.PHYSICAL_SKILL_POWER, 1);
} }

View File

@@ -128,6 +128,7 @@ public final class PhysicalSoulAttack extends AbstractEffect
// Trait, elements // Trait, elements
final double weaponTraitMod = Formulas.calcWeaponTraitBonus(effector, effected); final double weaponTraitMod = Formulas.calcWeaponTraitBonus(effector, effected);
final double generalTraitMod = Formulas.calcGeneralTraitBonus(effector, effected, skill.getTraitType(), true); final double generalTraitMod = Formulas.calcGeneralTraitBonus(effector, effected, skill.getTraitType(), true);
final double weaknessMod = Formulas.calcWeaknessBonus(effector, effected, skill.getTraitType());
final double attributeMod = Formulas.calcAttributeBonus(effector, effected, skill); final double attributeMod = Formulas.calcAttributeBonus(effector, effected, skill);
final double pvpPveMod = Formulas.calculatePvpPveBonus(effector, effected, skill, true); final double pvpPveMod = Formulas.calculatePvpPveBonus(effector, effected, skill, true);
final double randomMod = effector.getRandomDamageMultiplier(); final double randomMod = effector.getRandomDamageMultiplier();
@@ -155,7 +156,7 @@ public final class PhysicalSoulAttack extends AbstractEffect
// ATTACK CALCULATION 77 * ((pAtk * lvlMod) + power) / pdef            RANGED ATTACK CALCULATION 70 * ((pAtk * lvlMod) + power + patk + power) / pdef // ATTACK CALCULATION 77 * ((pAtk * lvlMod) + power) / pdef            RANGED ATTACK CALCULATION 70 * ((pAtk * lvlMod) + power + patk + power) / pdef
// ```````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^``````````````````````````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ // ```````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^``````````````````````````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
final double baseMod = (weaponMod * ((attack * effector.getLevelMod()) + power + rangedBonus)) / defence; final double baseMod = (weaponMod * ((attack * effector.getLevelMod()) + power + rangedBonus)) / defence;
damage = baseMod * soulsMod * ssmod * critMod * weaponTraitMod * generalTraitMod * attributeMod * pvpPveMod * randomMod; damage = baseMod * soulsMod * ssmod * critMod * weaponTraitMod * generalTraitMod * weaknessMod * attributeMod * pvpPveMod * randomMod;
damage *= effector.getStat().getValue(Stats.PHYSICAL_SKILL_POWER, 1); damage *= effector.getStat().getValue(Stats.PHYSICAL_SKILL_POWER, 1);
} }

View File

@@ -87,6 +87,11 @@ public class CreatureStat
public CreatureStat(Creature creature) public CreatureStat(Creature creature)
{ {
_creature = creature; _creature = creature;
for (int i = 0; i < TraitType.values().length; i++)
{
_attackTraitValues[i] = 1;
_defenceTraitValues[i] = 1;
}
} }
/** /**
@@ -582,10 +587,35 @@ public class CreatureStat
} }
public void mergeAttackTrait(TraitType traitType, float value) public void mergeAttackTrait(TraitType traitType, float value)
{
_lock.readLock().lock();
try
{ {
_attackTraitValues[traitType.ordinal()] *= value; _attackTraitValues[traitType.ordinal()] *= value;
_attackTraits.add(traitType); _attackTraits.add(traitType);
} }
finally
{
_lock.readLock().unlock();
}
}
public void removeAttackTrait(TraitType traitType, float value)
{
_lock.readLock().lock();
try
{
_attackTraitValues[traitType.ordinal()] /= value;
if (_attackTraitValues[traitType.ordinal()] == 1)
{
_attackTraits.remove(traitType);
}
}
finally
{
_lock.readLock().unlock();
}
}
public float getAttackTrait(TraitType traitType) public float getAttackTrait(TraitType traitType)
{ {
@@ -614,10 +644,35 @@ public class CreatureStat
} }
public void mergeDefenceTrait(TraitType traitType, float value) public void mergeDefenceTrait(TraitType traitType, float value)
{
_lock.readLock().lock();
try
{ {
_defenceTraitValues[traitType.ordinal()] *= value; _defenceTraitValues[traitType.ordinal()] *= value;
_defenceTraits.add(traitType); _defenceTraits.add(traitType);
} }
finally
{
_lock.readLock().unlock();
}
}
public void removeDefenceTrait(TraitType traitType, float value)
{
_lock.readLock().lock();
try
{
_defenceTraitValues[traitType.ordinal()] /= value;
if (_defenceTraitValues[traitType.ordinal()] == 1)
{
_defenceTraits.remove(traitType);
}
}
finally
{
_lock.readLock().unlock();
}
}
public float getDefenceTrait(TraitType traitType) public float getDefenceTrait(TraitType traitType)
{ {
@@ -646,9 +701,30 @@ public class CreatureStat
} }
public void mergeInvulnerableTrait(TraitType traitType) public void mergeInvulnerableTrait(TraitType traitType)
{
_lock.readLock().lock();
try
{ {
_invulnerableTraits.add(traitType); _invulnerableTraits.add(traitType);
} }
finally
{
_lock.readLock().unlock();
}
}
public void removeInvulnerableTrait(TraitType traitType)
{
_lock.readLock().lock();
try
{
_invulnerableTraits.remove(traitType);
}
finally
{
_lock.readLock().unlock();
}
}
public boolean isInvulnerableTrait(TraitType traitType) public boolean isInvulnerableTrait(TraitType traitType)
{ {

View File

@@ -94,14 +94,15 @@ public final class Formulas
} }
// Critical // Critical
final double criticalMod = (attacker.getStat().getValue(Stats.CRITICAL_DAMAGE, 1)); final double criticalMod = attacker.getStat().getValue(Stats.CRITICAL_DAMAGE, 1);
final double criticalPositionMod = attacker.getStat().getPositionTypeValue(Stats.CRITICAL_DAMAGE, Position.getPosition(attacker, target)); final double criticalPositionMod = attacker.getStat().getPositionTypeValue(Stats.CRITICAL_DAMAGE, Position.getPosition(attacker, target));
final double criticalVulnMod = (target.getStat().getValue(Stats.DEFENCE_CRITICAL_DAMAGE, 1)); final double criticalVulnMod = target.getStat().getValue(Stats.DEFENCE_CRITICAL_DAMAGE, 1);
final double criticalAddMod = (attacker.getStat().getValue(Stats.CRITICAL_DAMAGE_ADD, 0)); final double criticalAddMod = attacker.getStat().getValue(Stats.CRITICAL_DAMAGE_ADD, 0);
final double criticalAddVuln = target.getStat().getValue(Stats.DEFENCE_CRITICAL_DAMAGE_ADD, 0); final double criticalAddVuln = target.getStat().getValue(Stats.DEFENCE_CRITICAL_DAMAGE_ADD, 0);
// Trait, elements // Trait, elements
final double weaponTraitMod = calcWeaponTraitBonus(attacker, target); final double weaponTraitMod = calcWeaponTraitBonus(attacker, target);
final double generalTraitMod = calcGeneralTraitBonus(attacker, target, skill.getTraitType(), true); final double generalTraitMod = calcGeneralTraitBonus(attacker, target, skill.getTraitType(), true);
final double weaknessMod = calcWeaknessBonus(attacker, target, skill.getTraitType());
final double attributeMod = calcAttributeBonus(attacker, target, skill); final double attributeMod = calcAttributeBonus(attacker, target, skill);
final double randomMod = attacker.getRandomDamageMultiplier(); final double randomMod = attacker.getRandomDamageMultiplier();
final double pvpPveMod = calculatePvpPveBonus(attacker, target, skill, true); final double pvpPveMod = calculatePvpPveBonus(attacker, target, skill, true);
@@ -122,8 +123,8 @@ public final class Formulas
// ........................_____________________________Initial Damage____________________________...___________Position Additional Damage___________..._CriticalAdd_ // ........................_____________________________Initial Damage____________________________...___________Position Additional Damage___________..._CriticalAdd_
// ATTACK CALCULATION 77 * [(skillpower+patk) * 0.666 * cdbonus * cdPosBonusHalf * cdVulnHalf * ss + isBack0.2Side0.05 * (skillpower+patk*ss) * random + 6 * cd_patk] / pdef // ATTACK CALCULATION 77 * [(skillpower+patk) * 0.666 * cdbonus * cdPosBonusHalf * cdVulnHalf * ss + isBack0.2Side0.05 * (skillpower+patk*ss) * random + 6 * cd_patk] / pdef
// ````````````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^```^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^```^^^^^^^^^^^^ // ````````````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^```^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^```^^^^^^^^^^^^
final double baseMod = ((77 * (((power + attacker.getPAtk()) * 0.666) + (isPosition * (power + attacker.getPAtk()) * randomMod) + (6 * cdPatk))) / defence); final double baseMod = (77 * (((power + attacker.getPAtk()) * 0.666) + (isPosition * (power + attacker.getPAtk()) * randomMod) + (6 * cdPatk))) / defence;
final double damage = baseMod * ssmod * cdMult * weaponTraitMod * generalTraitMod * attributeMod * randomMod * pvpPveMod; final double damage = baseMod * ssmod * cdMult * weaponTraitMod * generalTraitMod * weaknessMod * attributeMod * randomMod * pvpPveMod;
return damage; return damage;
} }
@@ -136,6 +137,7 @@ public final class Formulas
// Trait, elements // Trait, elements
final double generalTraitMod = calcGeneralTraitBonus(attacker, target, skill.getTraitType(), true); final double generalTraitMod = calcGeneralTraitBonus(attacker, target, skill.getTraitType(), true);
final double weaknessMod = calcWeaknessBonus(attacker, target, skill.getTraitType());
final double attributeMod = calcAttributeBonus(attacker, target, skill); final double attributeMod = calcAttributeBonus(attacker, target, skill);
final double randomMod = attacker.getRandomDamageMultiplier(); final double randomMod = attacker.getRandomDamageMultiplier();
final double pvpPveMod = calculatePvpPveBonus(attacker, target, skill, mcrit); final double pvpPveMod = calculatePvpPveBonus(attacker, target, skill, mcrit);
@@ -178,7 +180,7 @@ public final class Formulas
} }
} }
damage = damage * critMod * generalTraitMod * attributeMod * randomMod * pvpPveMod; damage = damage * critMod * generalTraitMod * weaknessMod * attributeMod * randomMod * pvpPveMod;
damage *= attacker.getStat().getValue(Stats.MAGICAL_SKILL_POWER, 1); damage *= attacker.getStat().getValue(Stats.MAGICAL_SKILL_POWER, 1);
return damage; return damage;
@@ -1270,8 +1272,20 @@ public final class Formulas
} }
} }
final double result = (attacker.getStat().getAttackTrait(traitType) - target.getStat().getDefenceTrait(traitType)) + 1.0; return Math.max(attacker.getStat().getAttackTrait(traitType) - target.getStat().getDefenceTrait(traitType), 0.05);
return CommonUtil.constrain(result, 0.05, 2.0); }
public static double calcWeaknessBonus(Creature attacker, Creature target, TraitType traitType)
{
double result = 1;
for (TraitType trait : TraitType.getAllWeakness())
{
if ((traitType != trait) && target.getStat().hasDefenceTrait(trait) && attacker.getStat().hasAttackTrait(trait) && !target.getStat().isInvulnerableTrait(traitType))
{
result *= Math.max(attacker.getStat().getAttackTrait(trait) - target.getStat().getDefenceTrait(trait), 0.05);
}
}
return result;
} }
public static double calcWeaponTraitBonus(Creature attacker, Creature target) public static double calcWeaponTraitBonus(Creature attacker, Creature target)
@@ -1300,7 +1314,7 @@ public final class Formulas
} }
} }
return CommonUtil.constrain((weaponTraitBonus * weaknessBonus), 0.05, 2.0); return Math.max(weaponTraitBonus * weaknessBonus, 0.05);
} }
public static double getBasicPropertyResistBonus(BasicProperty basicProperty, Creature target) public static double getBasicPropertyResistBonus(BasicProperty basicProperty, Creature target)

View File

@@ -16,6 +16,9 @@
*/ */
package org.l2jmobius.gameserver.model.stats; package org.l2jmobius.gameserver.model.stats;
import java.util.ArrayList;
import java.util.List;
/** /**
* @author UnAfraid, NosBit * @author UnAfraid, NosBit
*/ */
@@ -88,6 +91,33 @@ public enum TraitType
SPIRIT_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
private final static List<TraitType> _weaknesses = new ArrayList<>();
static
{
_weaknesses.add(BUG_WEAKNESS);
_weaknesses.add(ANIMAL_WEAKNESS);
_weaknesses.add(PLANT_WEAKNESS);
_weaknesses.add(BEAST_WEAKNESS);
_weaknesses.add(DRAGON_WEAKNESS);
_weaknesses.add(GIANT_WEAKNESS);
_weaknesses.add(CONSTRUCT_WEAKNESS);
_weaknesses.add(VALAKAS);
_weaknesses.add(ANESTHESIA);
_weaknesses.add(DEMONIC_WEAKNESS);
_weaknesses.add(DIVINE_WEAKNESS);
_weaknesses.add(ELEMENTAL_WEAKNESS);
_weaknesses.add(FAIRY_WEAKNESS);
_weaknesses.add(HUMAN_WEAKNESS);
_weaknesses.add(HUMANOID_WEAKNESS);
_weaknesses.add(UNDEAD_WEAKNESS);
_weaknesses.add(EMBRYO_WEAKNESS);
_weaknesses.add(SPIRIT_WEAKNESS);
}
public static List<TraitType> getAllWeakness()
{
return _weaknesses;
}
TraitType(int type) TraitType(int type)
{ {

View File

@@ -23,6 +23,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.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;
@@ -49,11 +50,20 @@ public final class AttackTrait extends AbstractEffect
} }
@Override @Override
public void pump(Creature effected, Skill skill) public void onStart(Creature effector, Creature effected, Skill skill, ItemInstance item)
{ {
for (Entry<TraitType, Float> trait : _attackTraits.entrySet()) for (Entry<TraitType, Float> trait : _attackTraits.entrySet())
{ {
effected.getStat().mergeAttackTrait(trait.getKey(), trait.getValue()); effected.getStat().mergeAttackTrait(trait.getKey(), trait.getValue());
} }
} }
@Override
public void onExit(Creature effector, Creature effected, Skill skill)
{
for (Entry<TraitType, Float> trait : _attackTraits.entrySet())
{
effected.getStat().removeAttackTrait(trait.getKey(), trait.getValue());
}
}
} }

View File

@@ -23,6 +23,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.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;
@@ -49,7 +50,7 @@ public final class DefenceTrait extends AbstractEffect
} }
@Override @Override
public void pump(Creature effected, Skill skill) public void onStart(Creature effector, Creature effected, Skill skill, ItemInstance item)
{ {
for (Entry<TraitType, Float> trait : _defenceTraits.entrySet()) for (Entry<TraitType, Float> trait : _defenceTraits.entrySet())
{ {
@@ -63,4 +64,20 @@ public final class DefenceTrait extends AbstractEffect
} }
} }
} }
@Override
public void onExit(Creature effector, Creature effected, Skill skill)
{
for (Entry<TraitType, Float> trait : _defenceTraits.entrySet())
{
if (trait.getValue() < 2.0f)
{
effected.getStat().removeDefenceTrait(trait.getKey(), trait.getValue());
}
else
{
effected.getStat().removeInvulnerableTrait(trait.getKey());
}
}
}
} }

View File

@@ -125,6 +125,7 @@ public final class EnergyAttack extends AbstractEffect
// Trait, elements // Trait, elements
final double weaponTraitMod = Formulas.calcWeaponTraitBonus(attacker, effected); final double weaponTraitMod = Formulas.calcWeaponTraitBonus(attacker, effected);
final double generalTraitMod = Formulas.calcGeneralTraitBonus(attacker, effected, skill.getTraitType(), true); final double generalTraitMod = Formulas.calcGeneralTraitBonus(attacker, effected, skill.getTraitType(), true);
final double weaknessMod = Formulas.calcWeaknessBonus(attacker, effected, skill.getTraitType());
final double attributeMod = Formulas.calcAttributeBonus(attacker, effected, skill); final double attributeMod = Formulas.calcAttributeBonus(attacker, effected, skill);
final double pvpPveMod = Formulas.calculatePvpPveBonus(attacker, effected, skill, true); final double pvpPveMod = Formulas.calculatePvpPveBonus(attacker, effected, skill, true);
@@ -148,7 +149,7 @@ public final class EnergyAttack extends AbstractEffect
// ATTACK CALCULATION ((77 * ((pAtk * lvlMod) + power) * (1 + (0.1 * chargesConsumed)) / pdef) * skillPower) + skillPowerAdd // ATTACK CALCULATION ((77 * ((pAtk * lvlMod) + power) * (1 + (0.1 * chargesConsumed)) / pdef) * skillPower) + skillPowerAdd
// ```````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^```^^^^^^^^^^^^^^^^^^^^^^^^^^^^^```^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ // ```````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^```^^^^^^^^^^^^^^^^^^^^^^^^^^^^^```^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
final double baseMod = (77 * ((attacker.getPAtk() * attacker.getLevelMod()) + _power + effector.getStat().getValue(Stats.SKILL_POWER_ADD, 0))) / defence; final double baseMod = (77 * ((attacker.getPAtk() * attacker.getLevelMod()) + _power + effector.getStat().getValue(Stats.SKILL_POWER_ADD, 0))) / defence;
damage = baseMod * ssmod * critMod * weaponTraitMod * generalTraitMod * attributeMod * energyChargesBoost * pvpPveMod; damage = baseMod * ssmod * critMod * weaponTraitMod * generalTraitMod * weaknessMod * attributeMod * energyChargesBoost * pvpPveMod;
} }
damage = Math.max(0, damage * effector.getStat().getValue(Stats.PHYSICAL_SKILL_POWER, 1)); damage = Math.max(0, damage * effector.getStat().getValue(Stats.PHYSICAL_SKILL_POWER, 1));

View File

@@ -141,6 +141,7 @@ public final class PhysicalAttack extends AbstractEffect
// Trait, elements // Trait, elements
final double weaponTraitMod = Formulas.calcWeaponTraitBonus(effector, effected); final double weaponTraitMod = Formulas.calcWeaponTraitBonus(effector, effected);
final double generalTraitMod = Formulas.calcGeneralTraitBonus(effector, effected, skill.getTraitType(), true); final double generalTraitMod = Formulas.calcGeneralTraitBonus(effector, effected, skill.getTraitType(), true);
final double weaknessMod = Formulas.calcWeaknessBonus(effector, effected, skill.getTraitType());
final double attributeMod = Formulas.calcAttributeBonus(effector, effected, skill); final double attributeMod = Formulas.calcAttributeBonus(effector, effected, skill);
final double pvpPveMod = Formulas.calculatePvpPveBonus(effector, effected, skill, true); final double pvpPveMod = Formulas.calculatePvpPveBonus(effector, effected, skill, true);
final double randomMod = effector.getRandomDamageMultiplier(); final double randomMod = effector.getRandomDamageMultiplier();
@@ -168,7 +169,7 @@ public final class PhysicalAttack extends AbstractEffect
// ATTACK CALCULATION 77 * ((pAtk * lvlMod) + power) / pdef            RANGED ATTACK CALCULATION 70 * ((pAtk * lvlMod) + power + patk + power) / pdef // ATTACK CALCULATION 77 * ((pAtk * lvlMod) + power) / pdef            RANGED ATTACK CALCULATION 70 * ((pAtk * lvlMod) + power + patk + power) / pdef
// ```````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^``````````````````````````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ // ```````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^``````````````````````````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
final double baseMod = (weaponMod * ((attack * effector.getLevelMod()) + power + rangedBonus)) / defence; final double baseMod = (weaponMod * ((attack * effector.getLevelMod()) + power + rangedBonus)) / defence;
damage = baseMod * abnormalMod * ssmod * critMod * weaponTraitMod * generalTraitMod * attributeMod * pvpPveMod * randomMod; damage = baseMod * abnormalMod * ssmod * critMod * weaponTraitMod * generalTraitMod * weaknessMod * attributeMod * pvpPveMod * randomMod;
damage *= effector.getStat().getValue(Stats.PHYSICAL_SKILL_POWER, 1); damage *= effector.getStat().getValue(Stats.PHYSICAL_SKILL_POWER, 1);
} }

View File

@@ -101,6 +101,7 @@ public final class PhysicalAttackHpLink extends AbstractEffect
// Trait, elements // Trait, elements
final double weaponTraitMod = Formulas.calcWeaponTraitBonus(effector, effected); final double weaponTraitMod = Formulas.calcWeaponTraitBonus(effector, effected);
final double generalTraitMod = Formulas.calcGeneralTraitBonus(effector, effected, skill.getTraitType(), true); final double generalTraitMod = Formulas.calcGeneralTraitBonus(effector, effected, skill.getTraitType(), true);
final double weaknessMod = Formulas.calcWeaknessBonus(effector, effected, skill.getTraitType());
final double attributeMod = Formulas.calcAttributeBonus(effector, effected, skill); final double attributeMod = Formulas.calcAttributeBonus(effector, effected, skill);
final double pvpPveMod = Formulas.calculatePvpPveBonus(effector, effected, skill, true); final double pvpPveMod = Formulas.calculatePvpPveBonus(effector, effected, skill, true);
final double randomMod = effector.getRandomDamageMultiplier(); final double randomMod = effector.getRandomDamageMultiplier();
@@ -127,7 +128,7 @@ public final class PhysicalAttackHpLink extends AbstractEffect
// ATTACK CALCULATION 77 * ((pAtk * lvlMod) + power) / pdef            RANGED ATTACK CALCULATION 70 * ((pAtk * lvlMod) + power + patk + power) / pdef // ATTACK CALCULATION 77 * ((pAtk * lvlMod) + power) / pdef            RANGED ATTACK CALCULATION 70 * ((pAtk * lvlMod) + power + patk + power) / pdef
// ```````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^``````````````````````````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ // ```````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^``````````````````````````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
final double baseMod = (weaponMod * ((attack * effector.getLevelMod()) + power + rangedBonus)) / defence; final double baseMod = (weaponMod * ((attack * effector.getLevelMod()) + power + rangedBonus)) / defence;
damage = baseMod * ssmod * critMod * weaponTraitMod * generalTraitMod * attributeMod * pvpPveMod * randomMod; damage = baseMod * ssmod * critMod * weaponTraitMod * generalTraitMod * weaknessMod * attributeMod * pvpPveMod * randomMod;
damage *= effector.getStat().getValue(Stats.PHYSICAL_SKILL_POWER, 1); damage *= effector.getStat().getValue(Stats.PHYSICAL_SKILL_POWER, 1);
damage *= -((effector.getCurrentHp() * 2) / effector.getMaxHp()) + 2; damage *= -((effector.getCurrentHp() * 2) / effector.getMaxHp()) + 2;
} }

View File

@@ -114,6 +114,7 @@ public final class PhysicalAttackSaveHp extends AbstractEffect
// Trait, elements // Trait, elements
final double weaponTraitMod = Formulas.calcWeaponTraitBonus(effector, effected); final double weaponTraitMod = Formulas.calcWeaponTraitBonus(effector, effected);
final double generalTraitMod = Formulas.calcGeneralTraitBonus(effector, effected, skill.getTraitType(), true); final double generalTraitMod = Formulas.calcGeneralTraitBonus(effector, effected, skill.getTraitType(), true);
final double weaknessMod = Formulas.calcWeaknessBonus(effector, effected, skill.getTraitType());
final double attributeMod = Formulas.calcAttributeBonus(effector, effected, skill); final double attributeMod = Formulas.calcAttributeBonus(effector, effected, skill);
final double pvpPveMod = Formulas.calculatePvpPveBonus(effector, effected, skill, true); final double pvpPveMod = Formulas.calculatePvpPveBonus(effector, effected, skill, true);
final double randomMod = effector.getRandomDamageMultiplier(); final double randomMod = effector.getRandomDamageMultiplier();
@@ -140,7 +141,7 @@ public final class PhysicalAttackSaveHp extends AbstractEffect
// ATTACK CALCULATION 77 * ((pAtk * lvlMod) + power) / pdef            RANGED ATTACK CALCULATION 70 * ((pAtk * lvlMod) + power + patk + power) / pdef // ATTACK CALCULATION 77 * ((pAtk * lvlMod) + power) / pdef            RANGED ATTACK CALCULATION 70 * ((pAtk * lvlMod) + power + patk + power) / pdef
// ```````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^``````````````````````````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ // ```````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^``````````````````````````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
final double baseMod = (weaponMod * ((attack * effector.getLevelMod()) + power + rangedBonus)) / defence; final double baseMod = (weaponMod * ((attack * effector.getLevelMod()) + power + rangedBonus)) / defence;
damage = baseMod * ssmod * critMod * weaponTraitMod * generalTraitMod * attributeMod * pvpPveMod * randomMod; damage = baseMod * ssmod * critMod * weaponTraitMod * generalTraitMod * weaknessMod * attributeMod * pvpPveMod * randomMod;
damage *= effector.getStat().getValue(Stats.PHYSICAL_SKILL_POWER, 1); damage *= effector.getStat().getValue(Stats.PHYSICAL_SKILL_POWER, 1);
} }

View File

@@ -134,6 +134,7 @@ public final class PhysicalAttackWeaponBonus extends AbstractEffect
// Trait, elements // Trait, elements
final double weaponTraitMod = Formulas.calcWeaponTraitBonus(effector, effected); final double weaponTraitMod = Formulas.calcWeaponTraitBonus(effector, effected);
final double generalTraitMod = Formulas.calcGeneralTraitBonus(effector, effected, skill.getTraitType(), true); final double generalTraitMod = Formulas.calcGeneralTraitBonus(effector, effected, skill.getTraitType(), true);
final double weaknessMod = Formulas.calcWeaknessBonus(effector, effected, skill.getTraitType());
final double attributeMod = Formulas.calcAttributeBonus(effector, effected, skill); final double attributeMod = Formulas.calcAttributeBonus(effector, effected, skill);
final double pvpPveMod = Formulas.calculatePvpPveBonus(effector, effected, skill, true); final double pvpPveMod = Formulas.calculatePvpPveBonus(effector, effected, skill, true);
final double randomMod = effector.getRandomDamageMultiplier(); final double randomMod = effector.getRandomDamageMultiplier();
@@ -161,7 +162,7 @@ public final class PhysicalAttackWeaponBonus extends AbstractEffect
// ATTACK CALCULATION 77 * ((pAtk * lvlMod) + power) / pdef            RANGED ATTACK CALCULATION 70 * ((pAtk * lvlMod) + power + patk + power) / pdef // ATTACK CALCULATION 77 * ((pAtk * lvlMod) + power) / pdef            RANGED ATTACK CALCULATION 70 * ((pAtk * lvlMod) + power + patk + power) / pdef
// ```````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^``````````````````````````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ // ```````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^``````````````````````````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
final double baseMod = (weaponMod * ((attack * effector.getLevelMod()) + power + rangedBonus)) / defence; final double baseMod = (weaponMod * ((attack * effector.getLevelMod()) + power + rangedBonus)) / defence;
damage = baseMod * ssmod * critMod * weaponBonus * weaponTraitMod * generalTraitMod * attributeMod * pvpPveMod * randomMod; damage = baseMod * ssmod * critMod * weaponBonus * weaponTraitMod * generalTraitMod * weaknessMod * attributeMod * pvpPveMod * randomMod;
damage *= effector.getStat().getValue(Stats.PHYSICAL_SKILL_POWER, 1); damage *= effector.getStat().getValue(Stats.PHYSICAL_SKILL_POWER, 1);
} }

View File

@@ -128,6 +128,7 @@ public final class PhysicalSoulAttack extends AbstractEffect
// Trait, elements // Trait, elements
final double weaponTraitMod = Formulas.calcWeaponTraitBonus(effector, effected); final double weaponTraitMod = Formulas.calcWeaponTraitBonus(effector, effected);
final double generalTraitMod = Formulas.calcGeneralTraitBonus(effector, effected, skill.getTraitType(), true); final double generalTraitMod = Formulas.calcGeneralTraitBonus(effector, effected, skill.getTraitType(), true);
final double weaknessMod = Formulas.calcWeaknessBonus(effector, effected, skill.getTraitType());
final double attributeMod = Formulas.calcAttributeBonus(effector, effected, skill); final double attributeMod = Formulas.calcAttributeBonus(effector, effected, skill);
final double pvpPveMod = Formulas.calculatePvpPveBonus(effector, effected, skill, true); final double pvpPveMod = Formulas.calculatePvpPveBonus(effector, effected, skill, true);
final double randomMod = effector.getRandomDamageMultiplier(); final double randomMod = effector.getRandomDamageMultiplier();
@@ -155,7 +156,7 @@ public final class PhysicalSoulAttack extends AbstractEffect
// ATTACK CALCULATION 77 * ((pAtk * lvlMod) + power) / pdef            RANGED ATTACK CALCULATION 70 * ((pAtk * lvlMod) + power + patk + power) / pdef // ATTACK CALCULATION 77 * ((pAtk * lvlMod) + power) / pdef            RANGED ATTACK CALCULATION 70 * ((pAtk * lvlMod) + power + patk + power) / pdef
// ```````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^``````````````````````````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ // ```````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^``````````````````````````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
final double baseMod = (weaponMod * ((attack * effector.getLevelMod()) + power + rangedBonus)) / defence; final double baseMod = (weaponMod * ((attack * effector.getLevelMod()) + power + rangedBonus)) / defence;
damage = baseMod * soulsMod * ssmod * critMod * weaponTraitMod * generalTraitMod * attributeMod * pvpPveMod * randomMod; damage = baseMod * soulsMod * ssmod * critMod * weaponTraitMod * generalTraitMod * weaknessMod * attributeMod * pvpPveMod * randomMod;
damage *= effector.getStat().getValue(Stats.PHYSICAL_SKILL_POWER, 1); damage *= effector.getStat().getValue(Stats.PHYSICAL_SKILL_POWER, 1);
} }

View File

@@ -87,6 +87,11 @@ public class CreatureStat
public CreatureStat(Creature creature) public CreatureStat(Creature creature)
{ {
_creature = creature; _creature = creature;
for (int i = 0; i < TraitType.values().length; i++)
{
_attackTraitValues[i] = 1;
_defenceTraitValues[i] = 1;
}
} }
/** /**
@@ -582,10 +587,35 @@ public class CreatureStat
} }
public void mergeAttackTrait(TraitType traitType, float value) public void mergeAttackTrait(TraitType traitType, float value)
{
_lock.readLock().lock();
try
{ {
_attackTraitValues[traitType.ordinal()] *= value; _attackTraitValues[traitType.ordinal()] *= value;
_attackTraits.add(traitType); _attackTraits.add(traitType);
} }
finally
{
_lock.readLock().unlock();
}
}
public void removeAttackTrait(TraitType traitType, float value)
{
_lock.readLock().lock();
try
{
_attackTraitValues[traitType.ordinal()] /= value;
if (_attackTraitValues[traitType.ordinal()] == 1)
{
_attackTraits.remove(traitType);
}
}
finally
{
_lock.readLock().unlock();
}
}
public float getAttackTrait(TraitType traitType) public float getAttackTrait(TraitType traitType)
{ {
@@ -614,10 +644,35 @@ public class CreatureStat
} }
public void mergeDefenceTrait(TraitType traitType, float value) public void mergeDefenceTrait(TraitType traitType, float value)
{
_lock.readLock().lock();
try
{ {
_defenceTraitValues[traitType.ordinal()] *= value; _defenceTraitValues[traitType.ordinal()] *= value;
_defenceTraits.add(traitType); _defenceTraits.add(traitType);
} }
finally
{
_lock.readLock().unlock();
}
}
public void removeDefenceTrait(TraitType traitType, float value)
{
_lock.readLock().lock();
try
{
_defenceTraitValues[traitType.ordinal()] /= value;
if (_defenceTraitValues[traitType.ordinal()] == 1)
{
_defenceTraits.remove(traitType);
}
}
finally
{
_lock.readLock().unlock();
}
}
public float getDefenceTrait(TraitType traitType) public float getDefenceTrait(TraitType traitType)
{ {
@@ -646,9 +701,30 @@ public class CreatureStat
} }
public void mergeInvulnerableTrait(TraitType traitType) public void mergeInvulnerableTrait(TraitType traitType)
{
_lock.readLock().lock();
try
{ {
_invulnerableTraits.add(traitType); _invulnerableTraits.add(traitType);
} }
finally
{
_lock.readLock().unlock();
}
}
public void removeInvulnerableTrait(TraitType traitType)
{
_lock.readLock().lock();
try
{
_invulnerableTraits.remove(traitType);
}
finally
{
_lock.readLock().unlock();
}
}
public boolean isInvulnerableTrait(TraitType traitType) public boolean isInvulnerableTrait(TraitType traitType)
{ {

View File

@@ -94,14 +94,15 @@ public final class Formulas
} }
// Critical // Critical
final double criticalMod = (attacker.getStat().getValue(Stats.CRITICAL_DAMAGE, 1)); final double criticalMod = attacker.getStat().getValue(Stats.CRITICAL_DAMAGE, 1);
final double criticalPositionMod = attacker.getStat().getPositionTypeValue(Stats.CRITICAL_DAMAGE, Position.getPosition(attacker, target)); final double criticalPositionMod = attacker.getStat().getPositionTypeValue(Stats.CRITICAL_DAMAGE, Position.getPosition(attacker, target));
final double criticalVulnMod = (target.getStat().getValue(Stats.DEFENCE_CRITICAL_DAMAGE, 1)); final double criticalVulnMod = target.getStat().getValue(Stats.DEFENCE_CRITICAL_DAMAGE, 1);
final double criticalAddMod = (attacker.getStat().getValue(Stats.CRITICAL_DAMAGE_ADD, 0)); final double criticalAddMod = attacker.getStat().getValue(Stats.CRITICAL_DAMAGE_ADD, 0);
final double criticalAddVuln = target.getStat().getValue(Stats.DEFENCE_CRITICAL_DAMAGE_ADD, 0); final double criticalAddVuln = target.getStat().getValue(Stats.DEFENCE_CRITICAL_DAMAGE_ADD, 0);
// Trait, elements // Trait, elements
final double weaponTraitMod = calcWeaponTraitBonus(attacker, target); final double weaponTraitMod = calcWeaponTraitBonus(attacker, target);
final double generalTraitMod = calcGeneralTraitBonus(attacker, target, skill.getTraitType(), true); final double generalTraitMod = calcGeneralTraitBonus(attacker, target, skill.getTraitType(), true);
final double weaknessMod = calcWeaknessBonus(attacker, target, skill.getTraitType());
final double attributeMod = calcAttributeBonus(attacker, target, skill); final double attributeMod = calcAttributeBonus(attacker, target, skill);
final double randomMod = attacker.getRandomDamageMultiplier(); final double randomMod = attacker.getRandomDamageMultiplier();
final double pvpPveMod = calculatePvpPveBonus(attacker, target, skill, true); final double pvpPveMod = calculatePvpPveBonus(attacker, target, skill, true);
@@ -122,8 +123,8 @@ public final class Formulas
// ........................_____________________________Initial Damage____________________________...___________Position Additional Damage___________..._CriticalAdd_ // ........................_____________________________Initial Damage____________________________...___________Position Additional Damage___________..._CriticalAdd_
// ATTACK CALCULATION 77 * [(skillpower+patk) * 0.666 * cdbonus * cdPosBonusHalf * cdVulnHalf * ss + isBack0.2Side0.05 * (skillpower+patk*ss) * random + 6 * cd_patk] / pdef // ATTACK CALCULATION 77 * [(skillpower+patk) * 0.666 * cdbonus * cdPosBonusHalf * cdVulnHalf * ss + isBack0.2Side0.05 * (skillpower+patk*ss) * random + 6 * cd_patk] / pdef
// ````````````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^```^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^```^^^^^^^^^^^^ // ````````````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^```^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^```^^^^^^^^^^^^
final double baseMod = ((77 * (((power + attacker.getPAtk()) * 0.666) + (isPosition * (power + attacker.getPAtk()) * randomMod) + (6 * cdPatk))) / defence); final double baseMod = (77 * (((power + attacker.getPAtk()) * 0.666) + (isPosition * (power + attacker.getPAtk()) * randomMod) + (6 * cdPatk))) / defence;
final double damage = baseMod * ssmod * cdMult * weaponTraitMod * generalTraitMod * attributeMod * randomMod * pvpPveMod; final double damage = baseMod * ssmod * cdMult * weaponTraitMod * generalTraitMod * weaknessMod * attributeMod * randomMod * pvpPveMod;
return damage; return damage;
} }
@@ -136,6 +137,7 @@ public final class Formulas
// Trait, elements // Trait, elements
final double generalTraitMod = calcGeneralTraitBonus(attacker, target, skill.getTraitType(), true); final double generalTraitMod = calcGeneralTraitBonus(attacker, target, skill.getTraitType(), true);
final double weaknessMod = calcWeaknessBonus(attacker, target, skill.getTraitType());
final double attributeMod = calcAttributeBonus(attacker, target, skill); final double attributeMod = calcAttributeBonus(attacker, target, skill);
final double randomMod = attacker.getRandomDamageMultiplier(); final double randomMod = attacker.getRandomDamageMultiplier();
final double pvpPveMod = calculatePvpPveBonus(attacker, target, skill, mcrit); final double pvpPveMod = calculatePvpPveBonus(attacker, target, skill, mcrit);
@@ -178,7 +180,7 @@ public final class Formulas
} }
} }
damage = damage * critMod * generalTraitMod * attributeMod * randomMod * pvpPveMod; damage = damage * critMod * generalTraitMod * weaknessMod * attributeMod * randomMod * pvpPveMod;
damage *= attacker.getStat().getValue(Stats.MAGICAL_SKILL_POWER, 1); damage *= attacker.getStat().getValue(Stats.MAGICAL_SKILL_POWER, 1);
return damage; return damage;
@@ -1270,8 +1272,20 @@ public final class Formulas
} }
} }
final double result = (attacker.getStat().getAttackTrait(traitType) - target.getStat().getDefenceTrait(traitType)) + 1.0; return Math.max(attacker.getStat().getAttackTrait(traitType) - target.getStat().getDefenceTrait(traitType), 0.05);
return CommonUtil.constrain(result, 0.05, 2.0); }
public static double calcWeaknessBonus(Creature attacker, Creature target, TraitType traitType)
{
double result = 1;
for (TraitType trait : TraitType.getAllWeakness())
{
if ((traitType != trait) && target.getStat().hasDefenceTrait(trait) && attacker.getStat().hasAttackTrait(trait) && !target.getStat().isInvulnerableTrait(traitType))
{
result *= Math.max(attacker.getStat().getAttackTrait(trait) - target.getStat().getDefenceTrait(trait), 0.05);
}
}
return result;
} }
public static double calcWeaponTraitBonus(Creature attacker, Creature target) public static double calcWeaponTraitBonus(Creature attacker, Creature target)
@@ -1300,7 +1314,7 @@ public final class Formulas
} }
} }
return CommonUtil.constrain((weaponTraitBonus * weaknessBonus), 0.05, 2.0); return Math.max(weaponTraitBonus * weaknessBonus, 0.05);
} }
public static double getBasicPropertyResistBonus(BasicProperty basicProperty, Creature target) public static double getBasicPropertyResistBonus(BasicProperty basicProperty, Creature target)

View File

@@ -16,6 +16,9 @@
*/ */
package org.l2jmobius.gameserver.model.stats; package org.l2jmobius.gameserver.model.stats;
import java.util.ArrayList;
import java.util.List;
/** /**
* @author UnAfraid, NosBit * @author UnAfraid, NosBit
*/ */
@@ -88,6 +91,33 @@ public enum TraitType
SPIRIT_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
private final static List<TraitType> _weaknesses = new ArrayList<>();
static
{
_weaknesses.add(BUG_WEAKNESS);
_weaknesses.add(ANIMAL_WEAKNESS);
_weaknesses.add(PLANT_WEAKNESS);
_weaknesses.add(BEAST_WEAKNESS);
_weaknesses.add(DRAGON_WEAKNESS);
_weaknesses.add(GIANT_WEAKNESS);
_weaknesses.add(CONSTRUCT_WEAKNESS);
_weaknesses.add(VALAKAS);
_weaknesses.add(ANESTHESIA);
_weaknesses.add(DEMONIC_WEAKNESS);
_weaknesses.add(DIVINE_WEAKNESS);
_weaknesses.add(ELEMENTAL_WEAKNESS);
_weaknesses.add(FAIRY_WEAKNESS);
_weaknesses.add(HUMAN_WEAKNESS);
_weaknesses.add(HUMANOID_WEAKNESS);
_weaknesses.add(UNDEAD_WEAKNESS);
_weaknesses.add(EMBRYO_WEAKNESS);
_weaknesses.add(SPIRIT_WEAKNESS);
}
public static List<TraitType> getAllWeakness()
{
return _weaknesses;
}
TraitType(int type) TraitType(int type)
{ {

View File

@@ -23,6 +23,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.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;
@@ -49,11 +50,20 @@ public final class AttackTrait extends AbstractEffect
} }
@Override @Override
public void pump(Creature effected, Skill skill) public void onStart(Creature effector, Creature effected, Skill skill, ItemInstance item)
{ {
for (Entry<TraitType, Float> trait : _attackTraits.entrySet()) for (Entry<TraitType, Float> trait : _attackTraits.entrySet())
{ {
effected.getStat().mergeAttackTrait(trait.getKey(), trait.getValue()); effected.getStat().mergeAttackTrait(trait.getKey(), trait.getValue());
} }
} }
@Override
public void onExit(Creature effector, Creature effected, Skill skill)
{
for (Entry<TraitType, Float> trait : _attackTraits.entrySet())
{
effected.getStat().removeAttackTrait(trait.getKey(), trait.getValue());
}
}
} }

View File

@@ -23,6 +23,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.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;
@@ -49,7 +50,7 @@ public final class DefenceTrait extends AbstractEffect
} }
@Override @Override
public void pump(Creature effected, Skill skill) public void onStart(Creature effector, Creature effected, Skill skill, ItemInstance item)
{ {
for (Entry<TraitType, Float> trait : _defenceTraits.entrySet()) for (Entry<TraitType, Float> trait : _defenceTraits.entrySet())
{ {
@@ -63,4 +64,20 @@ public final class DefenceTrait extends AbstractEffect
} }
} }
} }
@Override
public void onExit(Creature effector, Creature effected, Skill skill)
{
for (Entry<TraitType, Float> trait : _defenceTraits.entrySet())
{
if (trait.getValue() < 2.0f)
{
effected.getStat().removeDefenceTrait(trait.getKey(), trait.getValue());
}
else
{
effected.getStat().removeInvulnerableTrait(trait.getKey());
}
}
}
} }

View File

@@ -125,6 +125,7 @@ public final class EnergyAttack extends AbstractEffect
// Trait, elements // Trait, elements
final double weaponTraitMod = Formulas.calcWeaponTraitBonus(attacker, effected); final double weaponTraitMod = Formulas.calcWeaponTraitBonus(attacker, effected);
final double generalTraitMod = Formulas.calcGeneralTraitBonus(attacker, effected, skill.getTraitType(), true); final double generalTraitMod = Formulas.calcGeneralTraitBonus(attacker, effected, skill.getTraitType(), true);
final double weaknessMod = Formulas.calcWeaknessBonus(attacker, effected, skill.getTraitType());
final double attributeMod = Formulas.calcAttributeBonus(attacker, effected, skill); final double attributeMod = Formulas.calcAttributeBonus(attacker, effected, skill);
final double pvpPveMod = Formulas.calculatePvpPveBonus(attacker, effected, skill, true); final double pvpPveMod = Formulas.calculatePvpPveBonus(attacker, effected, skill, true);
@@ -148,7 +149,7 @@ public final class EnergyAttack extends AbstractEffect
// ATTACK CALCULATION ((77 * ((pAtk * lvlMod) + power) * (1 + (0.1 * chargesConsumed)) / pdef) * skillPower) + skillPowerAdd // ATTACK CALCULATION ((77 * ((pAtk * lvlMod) + power) * (1 + (0.1 * chargesConsumed)) / pdef) * skillPower) + skillPowerAdd
// ```````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^```^^^^^^^^^^^^^^^^^^^^^^^^^^^^^```^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ // ```````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^```^^^^^^^^^^^^^^^^^^^^^^^^^^^^^```^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
final double baseMod = (77 * ((attacker.getPAtk() * attacker.getLevelMod()) + _power + effector.getStat().getValue(Stats.SKILL_POWER_ADD, 0))) / defence; final double baseMod = (77 * ((attacker.getPAtk() * attacker.getLevelMod()) + _power + effector.getStat().getValue(Stats.SKILL_POWER_ADD, 0))) / defence;
damage = baseMod * ssmod * critMod * weaponTraitMod * generalTraitMod * attributeMod * energyChargesBoost * pvpPveMod; damage = baseMod * ssmod * critMod * weaponTraitMod * generalTraitMod * weaknessMod * attributeMod * energyChargesBoost * pvpPveMod;
} }
damage = Math.max(0, damage * effector.getStat().getValue(Stats.PHYSICAL_SKILL_POWER, 1)); damage = Math.max(0, damage * effector.getStat().getValue(Stats.PHYSICAL_SKILL_POWER, 1));

View File

@@ -141,6 +141,7 @@ public final class PhysicalAttack extends AbstractEffect
// Trait, elements // Trait, elements
final double weaponTraitMod = Formulas.calcWeaponTraitBonus(effector, effected); final double weaponTraitMod = Formulas.calcWeaponTraitBonus(effector, effected);
final double generalTraitMod = Formulas.calcGeneralTraitBonus(effector, effected, skill.getTraitType(), true); final double generalTraitMod = Formulas.calcGeneralTraitBonus(effector, effected, skill.getTraitType(), true);
final double weaknessMod = Formulas.calcWeaknessBonus(effector, effected, skill.getTraitType());
final double attributeMod = Formulas.calcAttributeBonus(effector, effected, skill); final double attributeMod = Formulas.calcAttributeBonus(effector, effected, skill);
final double pvpPveMod = Formulas.calculatePvpPveBonus(effector, effected, skill, true); final double pvpPveMod = Formulas.calculatePvpPveBonus(effector, effected, skill, true);
final double randomMod = effector.getRandomDamageMultiplier(); final double randomMod = effector.getRandomDamageMultiplier();
@@ -168,7 +169,7 @@ public final class PhysicalAttack extends AbstractEffect
// ATTACK CALCULATION 77 * ((pAtk * lvlMod) + power) / pdef            RANGED ATTACK CALCULATION 70 * ((pAtk * lvlMod) + power + patk + power) / pdef // ATTACK CALCULATION 77 * ((pAtk * lvlMod) + power) / pdef            RANGED ATTACK CALCULATION 70 * ((pAtk * lvlMod) + power + patk + power) / pdef
// ```````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^``````````````````````````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ // ```````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^``````````````````````````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
final double baseMod = (weaponMod * ((attack * effector.getLevelMod()) + power + rangedBonus)) / defence; final double baseMod = (weaponMod * ((attack * effector.getLevelMod()) + power + rangedBonus)) / defence;
damage = baseMod * abnormalMod * ssmod * critMod * weaponTraitMod * generalTraitMod * attributeMod * pvpPveMod * randomMod; damage = baseMod * abnormalMod * ssmod * critMod * weaponTraitMod * generalTraitMod * weaknessMod * attributeMod * pvpPveMod * randomMod;
damage *= effector.getStat().getValue(Stats.PHYSICAL_SKILL_POWER, 1); damage *= effector.getStat().getValue(Stats.PHYSICAL_SKILL_POWER, 1);
} }

View File

@@ -101,6 +101,7 @@ public final class PhysicalAttackHpLink extends AbstractEffect
// Trait, elements // Trait, elements
final double weaponTraitMod = Formulas.calcWeaponTraitBonus(effector, effected); final double weaponTraitMod = Formulas.calcWeaponTraitBonus(effector, effected);
final double generalTraitMod = Formulas.calcGeneralTraitBonus(effector, effected, skill.getTraitType(), true); final double generalTraitMod = Formulas.calcGeneralTraitBonus(effector, effected, skill.getTraitType(), true);
final double weaknessMod = Formulas.calcWeaknessBonus(effector, effected, skill.getTraitType());
final double attributeMod = Formulas.calcAttributeBonus(effector, effected, skill); final double attributeMod = Formulas.calcAttributeBonus(effector, effected, skill);
final double pvpPveMod = Formulas.calculatePvpPveBonus(effector, effected, skill, true); final double pvpPveMod = Formulas.calculatePvpPveBonus(effector, effected, skill, true);
final double randomMod = effector.getRandomDamageMultiplier(); final double randomMod = effector.getRandomDamageMultiplier();
@@ -127,7 +128,7 @@ public final class PhysicalAttackHpLink extends AbstractEffect
// ATTACK CALCULATION 77 * ((pAtk * lvlMod) + power) / pdef            RANGED ATTACK CALCULATION 70 * ((pAtk * lvlMod) + power + patk + power) / pdef // ATTACK CALCULATION 77 * ((pAtk * lvlMod) + power) / pdef            RANGED ATTACK CALCULATION 70 * ((pAtk * lvlMod) + power + patk + power) / pdef
// ```````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^``````````````````````````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ // ```````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^``````````````````````````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
final double baseMod = (weaponMod * ((attack * effector.getLevelMod()) + power + rangedBonus)) / defence; final double baseMod = (weaponMod * ((attack * effector.getLevelMod()) + power + rangedBonus)) / defence;
damage = baseMod * ssmod * critMod * weaponTraitMod * generalTraitMod * attributeMod * pvpPveMod * randomMod; damage = baseMod * ssmod * critMod * weaponTraitMod * generalTraitMod * weaknessMod * attributeMod * pvpPveMod * randomMod;
damage *= effector.getStat().getValue(Stats.PHYSICAL_SKILL_POWER, 1); damage *= effector.getStat().getValue(Stats.PHYSICAL_SKILL_POWER, 1);
damage *= -((effector.getCurrentHp() * 2) / effector.getMaxHp()) + 2; damage *= -((effector.getCurrentHp() * 2) / effector.getMaxHp()) + 2;
} }

View File

@@ -114,6 +114,7 @@ public final class PhysicalAttackSaveHp extends AbstractEffect
// Trait, elements // Trait, elements
final double weaponTraitMod = Formulas.calcWeaponTraitBonus(effector, effected); final double weaponTraitMod = Formulas.calcWeaponTraitBonus(effector, effected);
final double generalTraitMod = Formulas.calcGeneralTraitBonus(effector, effected, skill.getTraitType(), true); final double generalTraitMod = Formulas.calcGeneralTraitBonus(effector, effected, skill.getTraitType(), true);
final double weaknessMod = Formulas.calcWeaknessBonus(effector, effected, skill.getTraitType());
final double attributeMod = Formulas.calcAttributeBonus(effector, effected, skill); final double attributeMod = Formulas.calcAttributeBonus(effector, effected, skill);
final double pvpPveMod = Formulas.calculatePvpPveBonus(effector, effected, skill, true); final double pvpPveMod = Formulas.calculatePvpPveBonus(effector, effected, skill, true);
final double randomMod = effector.getRandomDamageMultiplier(); final double randomMod = effector.getRandomDamageMultiplier();
@@ -140,7 +141,7 @@ public final class PhysicalAttackSaveHp extends AbstractEffect
// ATTACK CALCULATION 77 * ((pAtk * lvlMod) + power) / pdef            RANGED ATTACK CALCULATION 70 * ((pAtk * lvlMod) + power + patk + power) / pdef // ATTACK CALCULATION 77 * ((pAtk * lvlMod) + power) / pdef            RANGED ATTACK CALCULATION 70 * ((pAtk * lvlMod) + power + patk + power) / pdef
// ```````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^``````````````````````````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ // ```````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^``````````````````````````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
final double baseMod = (weaponMod * ((attack * effector.getLevelMod()) + power + rangedBonus)) / defence; final double baseMod = (weaponMod * ((attack * effector.getLevelMod()) + power + rangedBonus)) / defence;
damage = baseMod * ssmod * critMod * weaponTraitMod * generalTraitMod * attributeMod * pvpPveMod * randomMod; damage = baseMod * ssmod * critMod * weaponTraitMod * generalTraitMod * weaknessMod * attributeMod * pvpPveMod * randomMod;
damage *= effector.getStat().getValue(Stats.PHYSICAL_SKILL_POWER, 1); damage *= effector.getStat().getValue(Stats.PHYSICAL_SKILL_POWER, 1);
} }

View File

@@ -134,6 +134,7 @@ public final class PhysicalAttackWeaponBonus extends AbstractEffect
// Trait, elements // Trait, elements
final double weaponTraitMod = Formulas.calcWeaponTraitBonus(effector, effected); final double weaponTraitMod = Formulas.calcWeaponTraitBonus(effector, effected);
final double generalTraitMod = Formulas.calcGeneralTraitBonus(effector, effected, skill.getTraitType(), true); final double generalTraitMod = Formulas.calcGeneralTraitBonus(effector, effected, skill.getTraitType(), true);
final double weaknessMod = Formulas.calcWeaknessBonus(effector, effected, skill.getTraitType());
final double attributeMod = Formulas.calcAttributeBonus(effector, effected, skill); final double attributeMod = Formulas.calcAttributeBonus(effector, effected, skill);
final double pvpPveMod = Formulas.calculatePvpPveBonus(effector, effected, skill, true); final double pvpPveMod = Formulas.calculatePvpPveBonus(effector, effected, skill, true);
final double randomMod = effector.getRandomDamageMultiplier(); final double randomMod = effector.getRandomDamageMultiplier();
@@ -161,7 +162,7 @@ public final class PhysicalAttackWeaponBonus extends AbstractEffect
// ATTACK CALCULATION 77 * ((pAtk * lvlMod) + power) / pdef            RANGED ATTACK CALCULATION 70 * ((pAtk * lvlMod) + power + patk + power) / pdef // ATTACK CALCULATION 77 * ((pAtk * lvlMod) + power) / pdef            RANGED ATTACK CALCULATION 70 * ((pAtk * lvlMod) + power + patk + power) / pdef
// ```````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^``````````````````````````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ // ```````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^``````````````````````````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
final double baseMod = (weaponMod * ((attack * effector.getLevelMod()) + power + rangedBonus)) / defence; final double baseMod = (weaponMod * ((attack * effector.getLevelMod()) + power + rangedBonus)) / defence;
damage = baseMod * ssmod * critMod * weaponBonus * weaponTraitMod * generalTraitMod * attributeMod * pvpPveMod * randomMod; damage = baseMod * ssmod * critMod * weaponBonus * weaponTraitMod * generalTraitMod * weaknessMod * attributeMod * pvpPveMod * randomMod;
damage *= effector.getStat().getValue(Stats.PHYSICAL_SKILL_POWER, 1); damage *= effector.getStat().getValue(Stats.PHYSICAL_SKILL_POWER, 1);
} }

View File

@@ -128,6 +128,7 @@ public final class PhysicalSoulAttack extends AbstractEffect
// Trait, elements // Trait, elements
final double weaponTraitMod = Formulas.calcWeaponTraitBonus(effector, effected); final double weaponTraitMod = Formulas.calcWeaponTraitBonus(effector, effected);
final double generalTraitMod = Formulas.calcGeneralTraitBonus(effector, effected, skill.getTraitType(), true); final double generalTraitMod = Formulas.calcGeneralTraitBonus(effector, effected, skill.getTraitType(), true);
final double weaknessMod = Formulas.calcWeaknessBonus(effector, effected, skill.getTraitType());
final double attributeMod = Formulas.calcAttributeBonus(effector, effected, skill); final double attributeMod = Formulas.calcAttributeBonus(effector, effected, skill);
final double pvpPveMod = Formulas.calculatePvpPveBonus(effector, effected, skill, true); final double pvpPveMod = Formulas.calculatePvpPveBonus(effector, effected, skill, true);
final double randomMod = effector.getRandomDamageMultiplier(); final double randomMod = effector.getRandomDamageMultiplier();
@@ -155,7 +156,7 @@ public final class PhysicalSoulAttack extends AbstractEffect
// ATTACK CALCULATION 77 * ((pAtk * lvlMod) + power) / pdef            RANGED ATTACK CALCULATION 70 * ((pAtk * lvlMod) + power + patk + power) / pdef // ATTACK CALCULATION 77 * ((pAtk * lvlMod) + power) / pdef            RANGED ATTACK CALCULATION 70 * ((pAtk * lvlMod) + power + patk + power) / pdef
// ```````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^``````````````````````````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ // ```````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^``````````````````````````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
final double baseMod = (weaponMod * ((attack * effector.getLevelMod()) + power + rangedBonus)) / defence; final double baseMod = (weaponMod * ((attack * effector.getLevelMod()) + power + rangedBonus)) / defence;
damage = baseMod * soulsMod * ssmod * critMod * weaponTraitMod * generalTraitMod * attributeMod * pvpPveMod * randomMod; damage = baseMod * soulsMod * ssmod * critMod * weaponTraitMod * generalTraitMod * weaknessMod * attributeMod * pvpPveMod * randomMod;
damage *= effector.getStat().getValue(Stats.PHYSICAL_SKILL_POWER, 1); damage *= effector.getStat().getValue(Stats.PHYSICAL_SKILL_POWER, 1);
} }

View File

@@ -87,6 +87,11 @@ public class CreatureStat
public CreatureStat(Creature creature) public CreatureStat(Creature creature)
{ {
_creature = creature; _creature = creature;
for (int i = 0; i < TraitType.values().length; i++)
{
_attackTraitValues[i] = 1;
_defenceTraitValues[i] = 1;
}
} }
/** /**
@@ -582,10 +587,35 @@ public class CreatureStat
} }
public void mergeAttackTrait(TraitType traitType, float value) public void mergeAttackTrait(TraitType traitType, float value)
{
_lock.readLock().lock();
try
{ {
_attackTraitValues[traitType.ordinal()] *= value; _attackTraitValues[traitType.ordinal()] *= value;
_attackTraits.add(traitType); _attackTraits.add(traitType);
} }
finally
{
_lock.readLock().unlock();
}
}
public void removeAttackTrait(TraitType traitType, float value)
{
_lock.readLock().lock();
try
{
_attackTraitValues[traitType.ordinal()] /= value;
if (_attackTraitValues[traitType.ordinal()] == 1)
{
_attackTraits.remove(traitType);
}
}
finally
{
_lock.readLock().unlock();
}
}
public float getAttackTrait(TraitType traitType) public float getAttackTrait(TraitType traitType)
{ {
@@ -614,10 +644,35 @@ public class CreatureStat
} }
public void mergeDefenceTrait(TraitType traitType, float value) public void mergeDefenceTrait(TraitType traitType, float value)
{
_lock.readLock().lock();
try
{ {
_defenceTraitValues[traitType.ordinal()] *= value; _defenceTraitValues[traitType.ordinal()] *= value;
_defenceTraits.add(traitType); _defenceTraits.add(traitType);
} }
finally
{
_lock.readLock().unlock();
}
}
public void removeDefenceTrait(TraitType traitType, float value)
{
_lock.readLock().lock();
try
{
_defenceTraitValues[traitType.ordinal()] /= value;
if (_defenceTraitValues[traitType.ordinal()] == 1)
{
_defenceTraits.remove(traitType);
}
}
finally
{
_lock.readLock().unlock();
}
}
public float getDefenceTrait(TraitType traitType) public float getDefenceTrait(TraitType traitType)
{ {
@@ -646,9 +701,30 @@ public class CreatureStat
} }
public void mergeInvulnerableTrait(TraitType traitType) public void mergeInvulnerableTrait(TraitType traitType)
{
_lock.readLock().lock();
try
{ {
_invulnerableTraits.add(traitType); _invulnerableTraits.add(traitType);
} }
finally
{
_lock.readLock().unlock();
}
}
public void removeInvulnerableTrait(TraitType traitType)
{
_lock.readLock().lock();
try
{
_invulnerableTraits.remove(traitType);
}
finally
{
_lock.readLock().unlock();
}
}
public boolean isInvulnerableTrait(TraitType traitType) public boolean isInvulnerableTrait(TraitType traitType)
{ {

View File

@@ -94,14 +94,15 @@ public final class Formulas
} }
// Critical // Critical
final double criticalMod = (attacker.getStat().getValue(Stats.CRITICAL_DAMAGE, 1)); final double criticalMod = attacker.getStat().getValue(Stats.CRITICAL_DAMAGE, 1);
final double criticalPositionMod = attacker.getStat().getPositionTypeValue(Stats.CRITICAL_DAMAGE, Position.getPosition(attacker, target)); final double criticalPositionMod = attacker.getStat().getPositionTypeValue(Stats.CRITICAL_DAMAGE, Position.getPosition(attacker, target));
final double criticalVulnMod = (target.getStat().getValue(Stats.DEFENCE_CRITICAL_DAMAGE, 1)); final double criticalVulnMod = target.getStat().getValue(Stats.DEFENCE_CRITICAL_DAMAGE, 1);
final double criticalAddMod = (attacker.getStat().getValue(Stats.CRITICAL_DAMAGE_ADD, 0)); final double criticalAddMod = attacker.getStat().getValue(Stats.CRITICAL_DAMAGE_ADD, 0);
final double criticalAddVuln = target.getStat().getValue(Stats.DEFENCE_CRITICAL_DAMAGE_ADD, 0); final double criticalAddVuln = target.getStat().getValue(Stats.DEFENCE_CRITICAL_DAMAGE_ADD, 0);
// Trait, elements // Trait, elements
final double weaponTraitMod = calcWeaponTraitBonus(attacker, target); final double weaponTraitMod = calcWeaponTraitBonus(attacker, target);
final double generalTraitMod = calcGeneralTraitBonus(attacker, target, skill.getTraitType(), true); final double generalTraitMod = calcGeneralTraitBonus(attacker, target, skill.getTraitType(), true);
final double weaknessMod = calcWeaknessBonus(attacker, target, skill.getTraitType());
final double attributeMod = calcAttributeBonus(attacker, target, skill); final double attributeMod = calcAttributeBonus(attacker, target, skill);
final double randomMod = attacker.getRandomDamageMultiplier(); final double randomMod = attacker.getRandomDamageMultiplier();
final double pvpPveMod = calculatePvpPveBonus(attacker, target, skill, true); final double pvpPveMod = calculatePvpPveBonus(attacker, target, skill, true);
@@ -122,8 +123,8 @@ public final class Formulas
// ........................_____________________________Initial Damage____________________________...___________Position Additional Damage___________..._CriticalAdd_ // ........................_____________________________Initial Damage____________________________...___________Position Additional Damage___________..._CriticalAdd_
// ATTACK CALCULATION 77 * [(skillpower+patk) * 0.666 * cdbonus * cdPosBonusHalf * cdVulnHalf * ss + isBack0.2Side0.05 * (skillpower+patk*ss) * random + 6 * cd_patk] / pdef // ATTACK CALCULATION 77 * [(skillpower+patk) * 0.666 * cdbonus * cdPosBonusHalf * cdVulnHalf * ss + isBack0.2Side0.05 * (skillpower+patk*ss) * random + 6 * cd_patk] / pdef
// ````````````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^```^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^```^^^^^^^^^^^^ // ````````````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^```^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^```^^^^^^^^^^^^
final double baseMod = ((77 * (((power + attacker.getPAtk()) * 0.666) + (isPosition * (power + attacker.getPAtk()) * randomMod) + (6 * cdPatk))) / defence); final double baseMod = (77 * (((power + attacker.getPAtk()) * 0.666) + (isPosition * (power + attacker.getPAtk()) * randomMod) + (6 * cdPatk))) / defence;
final double damage = baseMod * ssmod * cdMult * weaponTraitMod * generalTraitMod * attributeMod * randomMod * pvpPveMod; final double damage = baseMod * ssmod * cdMult * weaponTraitMod * generalTraitMod * weaknessMod * attributeMod * randomMod * pvpPveMod;
return damage; return damage;
} }
@@ -136,6 +137,7 @@ public final class Formulas
// Trait, elements // Trait, elements
final double generalTraitMod = calcGeneralTraitBonus(attacker, target, skill.getTraitType(), true); final double generalTraitMod = calcGeneralTraitBonus(attacker, target, skill.getTraitType(), true);
final double weaknessMod = calcWeaknessBonus(attacker, target, skill.getTraitType());
final double attributeMod = calcAttributeBonus(attacker, target, skill); final double attributeMod = calcAttributeBonus(attacker, target, skill);
final double randomMod = attacker.getRandomDamageMultiplier(); final double randomMod = attacker.getRandomDamageMultiplier();
final double pvpPveMod = calculatePvpPveBonus(attacker, target, skill, mcrit); final double pvpPveMod = calculatePvpPveBonus(attacker, target, skill, mcrit);
@@ -178,7 +180,7 @@ public final class Formulas
} }
} }
damage = damage * critMod * generalTraitMod * attributeMod * randomMod * pvpPveMod; damage = damage * critMod * generalTraitMod * weaknessMod * attributeMod * randomMod * pvpPveMod;
damage *= attacker.getStat().getValue(Stats.MAGICAL_SKILL_POWER, 1); damage *= attacker.getStat().getValue(Stats.MAGICAL_SKILL_POWER, 1);
return damage; return damage;
@@ -1270,8 +1272,20 @@ public final class Formulas
} }
} }
final double result = (attacker.getStat().getAttackTrait(traitType) - target.getStat().getDefenceTrait(traitType)) + 1.0; return Math.max(attacker.getStat().getAttackTrait(traitType) - target.getStat().getDefenceTrait(traitType), 0.05);
return CommonUtil.constrain(result, 0.05, 2.0); }
public static double calcWeaknessBonus(Creature attacker, Creature target, TraitType traitType)
{
double result = 1;
for (TraitType trait : TraitType.getAllWeakness())
{
if ((traitType != trait) && target.getStat().hasDefenceTrait(trait) && attacker.getStat().hasAttackTrait(trait) && !target.getStat().isInvulnerableTrait(traitType))
{
result *= Math.max(attacker.getStat().getAttackTrait(trait) - target.getStat().getDefenceTrait(trait), 0.05);
}
}
return result;
} }
public static double calcWeaponTraitBonus(Creature attacker, Creature target) public static double calcWeaponTraitBonus(Creature attacker, Creature target)
@@ -1300,7 +1314,7 @@ public final class Formulas
} }
} }
return CommonUtil.constrain((weaponTraitBonus * weaknessBonus), 0.05, 2.0); return Math.max(weaponTraitBonus * weaknessBonus, 0.05);
} }
public static double getBasicPropertyResistBonus(BasicProperty basicProperty, Creature target) public static double getBasicPropertyResistBonus(BasicProperty basicProperty, Creature target)

View File

@@ -16,6 +16,9 @@
*/ */
package org.l2jmobius.gameserver.model.stats; package org.l2jmobius.gameserver.model.stats;
import java.util.ArrayList;
import java.util.List;
/** /**
* @author UnAfraid, NosBit * @author UnAfraid, NosBit
*/ */
@@ -88,6 +91,33 @@ public enum TraitType
SPIRIT_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
private final static List<TraitType> _weaknesses = new ArrayList<>();
static
{
_weaknesses.add(BUG_WEAKNESS);
_weaknesses.add(ANIMAL_WEAKNESS);
_weaknesses.add(PLANT_WEAKNESS);
_weaknesses.add(BEAST_WEAKNESS);
_weaknesses.add(DRAGON_WEAKNESS);
_weaknesses.add(GIANT_WEAKNESS);
_weaknesses.add(CONSTRUCT_WEAKNESS);
_weaknesses.add(VALAKAS);
_weaknesses.add(ANESTHESIA);
_weaknesses.add(DEMONIC_WEAKNESS);
_weaknesses.add(DIVINE_WEAKNESS);
_weaknesses.add(ELEMENTAL_WEAKNESS);
_weaknesses.add(FAIRY_WEAKNESS);
_weaknesses.add(HUMAN_WEAKNESS);
_weaknesses.add(HUMANOID_WEAKNESS);
_weaknesses.add(UNDEAD_WEAKNESS);
_weaknesses.add(EMBRYO_WEAKNESS);
_weaknesses.add(SPIRIT_WEAKNESS);
}
public static List<TraitType> getAllWeakness()
{
return _weaknesses;
}
TraitType(int type) TraitType(int type)
{ {

View File

@@ -23,6 +23,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.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;
@@ -49,11 +50,20 @@ public final class AttackTrait extends AbstractEffect
} }
@Override @Override
public void pump(Creature effected, Skill skill) public void onStart(Creature effector, Creature effected, Skill skill, ItemInstance item)
{ {
for (Entry<TraitType, Float> trait : _attackTraits.entrySet()) for (Entry<TraitType, Float> trait : _attackTraits.entrySet())
{ {
effected.getStat().mergeAttackTrait(trait.getKey(), trait.getValue()); effected.getStat().mergeAttackTrait(trait.getKey(), trait.getValue());
} }
} }
@Override
public void onExit(Creature effector, Creature effected, Skill skill)
{
for (Entry<TraitType, Float> trait : _attackTraits.entrySet())
{
effected.getStat().removeAttackTrait(trait.getKey(), trait.getValue());
}
}
} }

View File

@@ -23,6 +23,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.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;
@@ -49,7 +50,7 @@ public final class DefenceTrait extends AbstractEffect
} }
@Override @Override
public void pump(Creature effected, Skill skill) public void onStart(Creature effector, Creature effected, Skill skill, ItemInstance item)
{ {
for (Entry<TraitType, Float> trait : _defenceTraits.entrySet()) for (Entry<TraitType, Float> trait : _defenceTraits.entrySet())
{ {
@@ -63,4 +64,20 @@ public final class DefenceTrait extends AbstractEffect
} }
} }
} }
@Override
public void onExit(Creature effector, Creature effected, Skill skill)
{
for (Entry<TraitType, Float> trait : _defenceTraits.entrySet())
{
if (trait.getValue() < 2.0f)
{
effected.getStat().removeDefenceTrait(trait.getKey(), trait.getValue());
}
else
{
effected.getStat().removeInvulnerableTrait(trait.getKey());
}
}
}
} }

View File

@@ -125,6 +125,7 @@ public final class EnergyAttack extends AbstractEffect
// Trait, elements // Trait, elements
final double weaponTraitMod = Formulas.calcWeaponTraitBonus(attacker, effected); final double weaponTraitMod = Formulas.calcWeaponTraitBonus(attacker, effected);
final double generalTraitMod = Formulas.calcGeneralTraitBonus(attacker, effected, skill.getTraitType(), true); final double generalTraitMod = Formulas.calcGeneralTraitBonus(attacker, effected, skill.getTraitType(), true);
final double weaknessMod = Formulas.calcWeaknessBonus(attacker, effected, skill.getTraitType());
final double attributeMod = Formulas.calcAttributeBonus(attacker, effected, skill); final double attributeMod = Formulas.calcAttributeBonus(attacker, effected, skill);
final double pvpPveMod = Formulas.calculatePvpPveBonus(attacker, effected, skill, true); final double pvpPveMod = Formulas.calculatePvpPveBonus(attacker, effected, skill, true);
@@ -148,7 +149,7 @@ public final class EnergyAttack extends AbstractEffect
// ATTACK CALCULATION ((77 * ((pAtk * lvlMod) + power) * (1 + (0.1 * chargesConsumed)) / pdef) * skillPower) + skillPowerAdd // ATTACK CALCULATION ((77 * ((pAtk * lvlMod) + power) * (1 + (0.1 * chargesConsumed)) / pdef) * skillPower) + skillPowerAdd
// ```````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^```^^^^^^^^^^^^^^^^^^^^^^^^^^^^^```^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ // ```````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^```^^^^^^^^^^^^^^^^^^^^^^^^^^^^^```^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
final double baseMod = (77 * ((attacker.getPAtk() * attacker.getLevelMod()) + _power + effector.getStat().getValue(Stats.SKILL_POWER_ADD, 0))) / defence; final double baseMod = (77 * ((attacker.getPAtk() * attacker.getLevelMod()) + _power + effector.getStat().getValue(Stats.SKILL_POWER_ADD, 0))) / defence;
damage = baseMod * ssmod * critMod * weaponTraitMod * generalTraitMod * attributeMod * energyChargesBoost * pvpPveMod; damage = baseMod * ssmod * critMod * weaponTraitMod * generalTraitMod * weaknessMod * attributeMod * energyChargesBoost * pvpPveMod;
} }
damage = Math.max(0, damage * effector.getStat().getValue(Stats.PHYSICAL_SKILL_POWER, 1)); damage = Math.max(0, damage * effector.getStat().getValue(Stats.PHYSICAL_SKILL_POWER, 1));

View File

@@ -141,6 +141,7 @@ public final class PhysicalAttack extends AbstractEffect
// Trait, elements // Trait, elements
final double weaponTraitMod = Formulas.calcWeaponTraitBonus(effector, effected); final double weaponTraitMod = Formulas.calcWeaponTraitBonus(effector, effected);
final double generalTraitMod = Formulas.calcGeneralTraitBonus(effector, effected, skill.getTraitType(), true); final double generalTraitMod = Formulas.calcGeneralTraitBonus(effector, effected, skill.getTraitType(), true);
final double weaknessMod = Formulas.calcWeaknessBonus(effector, effected, skill.getTraitType());
final double attributeMod = Formulas.calcAttributeBonus(effector, effected, skill); final double attributeMod = Formulas.calcAttributeBonus(effector, effected, skill);
final double pvpPveMod = Formulas.calculatePvpPveBonus(effector, effected, skill, true); final double pvpPveMod = Formulas.calculatePvpPveBonus(effector, effected, skill, true);
final double randomMod = effector.getRandomDamageMultiplier(); final double randomMod = effector.getRandomDamageMultiplier();
@@ -168,7 +169,7 @@ public final class PhysicalAttack extends AbstractEffect
// ATTACK CALCULATION 77 * ((pAtk * lvlMod) + power) / pdef            RANGED ATTACK CALCULATION 70 * ((pAtk * lvlMod) + power + patk + power) / pdef // ATTACK CALCULATION 77 * ((pAtk * lvlMod) + power) / pdef            RANGED ATTACK CALCULATION 70 * ((pAtk * lvlMod) + power + patk + power) / pdef
// ```````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^``````````````````````````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ // ```````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^``````````````````````````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
final double baseMod = (weaponMod * ((attack * effector.getLevelMod()) + power + rangedBonus)) / defence; final double baseMod = (weaponMod * ((attack * effector.getLevelMod()) + power + rangedBonus)) / defence;
damage = baseMod * abnormalMod * ssmod * critMod * weaponTraitMod * generalTraitMod * attributeMod * pvpPveMod * randomMod; damage = baseMod * abnormalMod * ssmod * critMod * weaponTraitMod * generalTraitMod * weaknessMod * attributeMod * pvpPveMod * randomMod;
damage *= effector.getStat().getValue(Stats.PHYSICAL_SKILL_POWER, 1); damage *= effector.getStat().getValue(Stats.PHYSICAL_SKILL_POWER, 1);
} }

View File

@@ -101,6 +101,7 @@ public final class PhysicalAttackHpLink extends AbstractEffect
// Trait, elements // Trait, elements
final double weaponTraitMod = Formulas.calcWeaponTraitBonus(effector, effected); final double weaponTraitMod = Formulas.calcWeaponTraitBonus(effector, effected);
final double generalTraitMod = Formulas.calcGeneralTraitBonus(effector, effected, skill.getTraitType(), true); final double generalTraitMod = Formulas.calcGeneralTraitBonus(effector, effected, skill.getTraitType(), true);
final double weaknessMod = Formulas.calcWeaknessBonus(effector, effected, skill.getTraitType());
final double attributeMod = Formulas.calcAttributeBonus(effector, effected, skill); final double attributeMod = Formulas.calcAttributeBonus(effector, effected, skill);
final double pvpPveMod = Formulas.calculatePvpPveBonus(effector, effected, skill, true); final double pvpPveMod = Formulas.calculatePvpPveBonus(effector, effected, skill, true);
final double randomMod = effector.getRandomDamageMultiplier(); final double randomMod = effector.getRandomDamageMultiplier();
@@ -127,7 +128,7 @@ public final class PhysicalAttackHpLink extends AbstractEffect
// ATTACK CALCULATION 77 * ((pAtk * lvlMod) + power) / pdef            RANGED ATTACK CALCULATION 70 * ((pAtk * lvlMod) + power + patk + power) / pdef // ATTACK CALCULATION 77 * ((pAtk * lvlMod) + power) / pdef            RANGED ATTACK CALCULATION 70 * ((pAtk * lvlMod) + power + patk + power) / pdef
// ```````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^``````````````````````````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ // ```````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^``````````````````````````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
final double baseMod = (weaponMod * ((attack * effector.getLevelMod()) + power + rangedBonus)) / defence; final double baseMod = (weaponMod * ((attack * effector.getLevelMod()) + power + rangedBonus)) / defence;
damage = baseMod * ssmod * critMod * weaponTraitMod * generalTraitMod * attributeMod * pvpPveMod * randomMod; damage = baseMod * ssmod * critMod * weaponTraitMod * generalTraitMod * weaknessMod * attributeMod * pvpPveMod * randomMod;
damage *= effector.getStat().getValue(Stats.PHYSICAL_SKILL_POWER, 1); damage *= effector.getStat().getValue(Stats.PHYSICAL_SKILL_POWER, 1);
damage *= -((effector.getCurrentHp() * 2) / effector.getMaxHp()) + 2; damage *= -((effector.getCurrentHp() * 2) / effector.getMaxHp()) + 2;
} }

View File

@@ -114,6 +114,7 @@ public final class PhysicalAttackSaveHp extends AbstractEffect
// Trait, elements // Trait, elements
final double weaponTraitMod = Formulas.calcWeaponTraitBonus(effector, effected); final double weaponTraitMod = Formulas.calcWeaponTraitBonus(effector, effected);
final double generalTraitMod = Formulas.calcGeneralTraitBonus(effector, effected, skill.getTraitType(), true); final double generalTraitMod = Formulas.calcGeneralTraitBonus(effector, effected, skill.getTraitType(), true);
final double weaknessMod = Formulas.calcWeaknessBonus(effector, effected, skill.getTraitType());
final double attributeMod = Formulas.calcAttributeBonus(effector, effected, skill); final double attributeMod = Formulas.calcAttributeBonus(effector, effected, skill);
final double pvpPveMod = Formulas.calculatePvpPveBonus(effector, effected, skill, true); final double pvpPveMod = Formulas.calculatePvpPveBonus(effector, effected, skill, true);
final double randomMod = effector.getRandomDamageMultiplier(); final double randomMod = effector.getRandomDamageMultiplier();
@@ -140,7 +141,7 @@ public final class PhysicalAttackSaveHp extends AbstractEffect
// ATTACK CALCULATION 77 * ((pAtk * lvlMod) + power) / pdef            RANGED ATTACK CALCULATION 70 * ((pAtk * lvlMod) + power + patk + power) / pdef // ATTACK CALCULATION 77 * ((pAtk * lvlMod) + power) / pdef            RANGED ATTACK CALCULATION 70 * ((pAtk * lvlMod) + power + patk + power) / pdef
// ```````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^``````````````````````````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ // ```````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^``````````````````````````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
final double baseMod = (weaponMod * ((attack * effector.getLevelMod()) + power + rangedBonus)) / defence; final double baseMod = (weaponMod * ((attack * effector.getLevelMod()) + power + rangedBonus)) / defence;
damage = baseMod * ssmod * critMod * weaponTraitMod * generalTraitMod * attributeMod * pvpPveMod * randomMod; damage = baseMod * ssmod * critMod * weaponTraitMod * generalTraitMod * weaknessMod * attributeMod * pvpPveMod * randomMod;
damage *= effector.getStat().getValue(Stats.PHYSICAL_SKILL_POWER, 1); damage *= effector.getStat().getValue(Stats.PHYSICAL_SKILL_POWER, 1);
} }

View File

@@ -134,6 +134,7 @@ public final class PhysicalAttackWeaponBonus extends AbstractEffect
// Trait, elements // Trait, elements
final double weaponTraitMod = Formulas.calcWeaponTraitBonus(effector, effected); final double weaponTraitMod = Formulas.calcWeaponTraitBonus(effector, effected);
final double generalTraitMod = Formulas.calcGeneralTraitBonus(effector, effected, skill.getTraitType(), true); final double generalTraitMod = Formulas.calcGeneralTraitBonus(effector, effected, skill.getTraitType(), true);
final double weaknessMod = Formulas.calcWeaknessBonus(effector, effected, skill.getTraitType());
final double attributeMod = Formulas.calcAttributeBonus(effector, effected, skill); final double attributeMod = Formulas.calcAttributeBonus(effector, effected, skill);
final double pvpPveMod = Formulas.calculatePvpPveBonus(effector, effected, skill, true); final double pvpPveMod = Formulas.calculatePvpPveBonus(effector, effected, skill, true);
final double randomMod = effector.getRandomDamageMultiplier(); final double randomMod = effector.getRandomDamageMultiplier();
@@ -161,7 +162,7 @@ public final class PhysicalAttackWeaponBonus extends AbstractEffect
// ATTACK CALCULATION 77 * ((pAtk * lvlMod) + power) / pdef            RANGED ATTACK CALCULATION 70 * ((pAtk * lvlMod) + power + patk + power) / pdef // ATTACK CALCULATION 77 * ((pAtk * lvlMod) + power) / pdef            RANGED ATTACK CALCULATION 70 * ((pAtk * lvlMod) + power + patk + power) / pdef
// ```````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^``````````````````````````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ // ```````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^``````````````````````````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
final double baseMod = (weaponMod * ((attack * effector.getLevelMod()) + power + rangedBonus)) / defence; final double baseMod = (weaponMod * ((attack * effector.getLevelMod()) + power + rangedBonus)) / defence;
damage = baseMod * ssmod * critMod * weaponBonus * weaponTraitMod * generalTraitMod * attributeMod * pvpPveMod * randomMod; damage = baseMod * ssmod * critMod * weaponBonus * weaponTraitMod * generalTraitMod * weaknessMod * attributeMod * pvpPveMod * randomMod;
damage *= effector.getStat().getValue(Stats.PHYSICAL_SKILL_POWER, 1); damage *= effector.getStat().getValue(Stats.PHYSICAL_SKILL_POWER, 1);
} }

View File

@@ -128,6 +128,7 @@ public final class PhysicalSoulAttack extends AbstractEffect
// Trait, elements // Trait, elements
final double weaponTraitMod = Formulas.calcWeaponTraitBonus(effector, effected); final double weaponTraitMod = Formulas.calcWeaponTraitBonus(effector, effected);
final double generalTraitMod = Formulas.calcGeneralTraitBonus(effector, effected, skill.getTraitType(), true); final double generalTraitMod = Formulas.calcGeneralTraitBonus(effector, effected, skill.getTraitType(), true);
final double weaknessMod = Formulas.calcWeaknessBonus(effector, effected, skill.getTraitType());
final double attributeMod = Formulas.calcAttributeBonus(effector, effected, skill); final double attributeMod = Formulas.calcAttributeBonus(effector, effected, skill);
final double pvpPveMod = Formulas.calculatePvpPveBonus(effector, effected, skill, true); final double pvpPveMod = Formulas.calculatePvpPveBonus(effector, effected, skill, true);
final double randomMod = effector.getRandomDamageMultiplier(); final double randomMod = effector.getRandomDamageMultiplier();
@@ -155,7 +156,7 @@ public final class PhysicalSoulAttack extends AbstractEffect
// ATTACK CALCULATION 77 * ((pAtk * lvlMod) + power) / pdef            RANGED ATTACK CALCULATION 70 * ((pAtk * lvlMod) + power + patk + power) / pdef // ATTACK CALCULATION 77 * ((pAtk * lvlMod) + power) / pdef            RANGED ATTACK CALCULATION 70 * ((pAtk * lvlMod) + power + patk + power) / pdef
// ```````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^``````````````````````````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ // ```````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^``````````````````````````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
final double baseMod = (weaponMod * ((attack * effector.getLevelMod()) + power + rangedBonus)) / defence; final double baseMod = (weaponMod * ((attack * effector.getLevelMod()) + power + rangedBonus)) / defence;
damage = baseMod * soulsMod * ssmod * critMod * weaponTraitMod * generalTraitMod * attributeMod * pvpPveMod * randomMod; damage = baseMod * soulsMod * ssmod * critMod * weaponTraitMod * generalTraitMod * weaknessMod * attributeMod * pvpPveMod * randomMod;
damage *= effector.getStat().getValue(Stats.PHYSICAL_SKILL_POWER, 1); damage *= effector.getStat().getValue(Stats.PHYSICAL_SKILL_POWER, 1);
} }

View File

@@ -98,9 +98,6 @@
<amount>50</amount> <amount>50</amount>
<mode>PER</mode> <mode>PER</mode>
</effect> </effect>
<effect name="AttackTrait">
<DRAGON_WEAKNESS>300</DRAGON_WEAKNESS>
</effect>
</effects> </effects>
</skill> </skill>
<skill id="8902" toLevel="1" name="Dragon Mage"> <skill id="8902" toLevel="1" name="Dragon Mage">

View File

@@ -87,6 +87,11 @@ public class CreatureStat
public CreatureStat(Creature creature) public CreatureStat(Creature creature)
{ {
_creature = creature; _creature = creature;
for (int i = 0; i < TraitType.values().length; i++)
{
_attackTraitValues[i] = 1;
_defenceTraitValues[i] = 1;
}
} }
/** /**
@@ -582,10 +587,35 @@ public class CreatureStat
} }
public void mergeAttackTrait(TraitType traitType, float value) public void mergeAttackTrait(TraitType traitType, float value)
{
_lock.readLock().lock();
try
{ {
_attackTraitValues[traitType.ordinal()] *= value; _attackTraitValues[traitType.ordinal()] *= value;
_attackTraits.add(traitType); _attackTraits.add(traitType);
} }
finally
{
_lock.readLock().unlock();
}
}
public void removeAttackTrait(TraitType traitType, float value)
{
_lock.readLock().lock();
try
{
_attackTraitValues[traitType.ordinal()] /= value;
if (_attackTraitValues[traitType.ordinal()] == 1)
{
_attackTraits.remove(traitType);
}
}
finally
{
_lock.readLock().unlock();
}
}
public float getAttackTrait(TraitType traitType) public float getAttackTrait(TraitType traitType)
{ {
@@ -614,10 +644,35 @@ public class CreatureStat
} }
public void mergeDefenceTrait(TraitType traitType, float value) public void mergeDefenceTrait(TraitType traitType, float value)
{
_lock.readLock().lock();
try
{ {
_defenceTraitValues[traitType.ordinal()] *= value; _defenceTraitValues[traitType.ordinal()] *= value;
_defenceTraits.add(traitType); _defenceTraits.add(traitType);
} }
finally
{
_lock.readLock().unlock();
}
}
public void removeDefenceTrait(TraitType traitType, float value)
{
_lock.readLock().lock();
try
{
_defenceTraitValues[traitType.ordinal()] /= value;
if (_defenceTraitValues[traitType.ordinal()] == 1)
{
_defenceTraits.remove(traitType);
}
}
finally
{
_lock.readLock().unlock();
}
}
public float getDefenceTrait(TraitType traitType) public float getDefenceTrait(TraitType traitType)
{ {
@@ -646,9 +701,30 @@ public class CreatureStat
} }
public void mergeInvulnerableTrait(TraitType traitType) public void mergeInvulnerableTrait(TraitType traitType)
{
_lock.readLock().lock();
try
{ {
_invulnerableTraits.add(traitType); _invulnerableTraits.add(traitType);
} }
finally
{
_lock.readLock().unlock();
}
}
public void removeInvulnerableTrait(TraitType traitType)
{
_lock.readLock().lock();
try
{
_invulnerableTraits.remove(traitType);
}
finally
{
_lock.readLock().unlock();
}
}
public boolean isInvulnerableTrait(TraitType traitType) public boolean isInvulnerableTrait(TraitType traitType)
{ {

View File

@@ -94,14 +94,15 @@ public final class Formulas
} }
// Critical // Critical
final double criticalMod = (attacker.getStat().getValue(Stats.CRITICAL_DAMAGE, 1)); final double criticalMod = attacker.getStat().getValue(Stats.CRITICAL_DAMAGE, 1);
final double criticalPositionMod = attacker.getStat().getPositionTypeValue(Stats.CRITICAL_DAMAGE, Position.getPosition(attacker, target)); final double criticalPositionMod = attacker.getStat().getPositionTypeValue(Stats.CRITICAL_DAMAGE, Position.getPosition(attacker, target));
final double criticalVulnMod = (target.getStat().getValue(Stats.DEFENCE_CRITICAL_DAMAGE, 1)); final double criticalVulnMod = target.getStat().getValue(Stats.DEFENCE_CRITICAL_DAMAGE, 1);
final double criticalAddMod = (attacker.getStat().getValue(Stats.CRITICAL_DAMAGE_ADD, 0)); final double criticalAddMod = attacker.getStat().getValue(Stats.CRITICAL_DAMAGE_ADD, 0);
final double criticalAddVuln = target.getStat().getValue(Stats.DEFENCE_CRITICAL_DAMAGE_ADD, 0); final double criticalAddVuln = target.getStat().getValue(Stats.DEFENCE_CRITICAL_DAMAGE_ADD, 0);
// Trait, elements // Trait, elements
final double weaponTraitMod = calcWeaponTraitBonus(attacker, target); final double weaponTraitMod = calcWeaponTraitBonus(attacker, target);
final double generalTraitMod = calcGeneralTraitBonus(attacker, target, skill.getTraitType(), true); final double generalTraitMod = calcGeneralTraitBonus(attacker, target, skill.getTraitType(), true);
final double weaknessMod = calcWeaknessBonus(attacker, target, skill.getTraitType());
final double attributeMod = calcAttributeBonus(attacker, target, skill); final double attributeMod = calcAttributeBonus(attacker, target, skill);
final double randomMod = attacker.getRandomDamageMultiplier(); final double randomMod = attacker.getRandomDamageMultiplier();
final double pvpPveMod = calculatePvpPveBonus(attacker, target, skill, true); final double pvpPveMod = calculatePvpPveBonus(attacker, target, skill, true);
@@ -122,8 +123,8 @@ public final class Formulas
// ........................_____________________________Initial Damage____________________________...___________Position Additional Damage___________..._CriticalAdd_ // ........................_____________________________Initial Damage____________________________...___________Position Additional Damage___________..._CriticalAdd_
// ATTACK CALCULATION 77 * [(skillpower+patk) * 0.666 * cdbonus * cdPosBonusHalf * cdVulnHalf * ss + isBack0.2Side0.05 * (skillpower+patk*ss) * random + 6 * cd_patk] / pdef // ATTACK CALCULATION 77 * [(skillpower+patk) * 0.666 * cdbonus * cdPosBonusHalf * cdVulnHalf * ss + isBack0.2Side0.05 * (skillpower+patk*ss) * random + 6 * cd_patk] / pdef
// ````````````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^```^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^```^^^^^^^^^^^^ // ````````````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^```^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^```^^^^^^^^^^^^
final double baseMod = ((77 * (((power + attacker.getPAtk()) * 0.666) + (isPosition * (power + attacker.getPAtk()) * randomMod) + (6 * cdPatk))) / defence); final double baseMod = (77 * (((power + attacker.getPAtk()) * 0.666) + (isPosition * (power + attacker.getPAtk()) * randomMod) + (6 * cdPatk))) / defence;
final double damage = baseMod * ssmod * cdMult * weaponTraitMod * generalTraitMod * attributeMod * randomMod * pvpPveMod; final double damage = baseMod * ssmod * cdMult * weaponTraitMod * generalTraitMod * weaknessMod * attributeMod * randomMod * pvpPveMod;
return damage; return damage;
} }
@@ -136,6 +137,7 @@ public final class Formulas
// Trait, elements // Trait, elements
final double generalTraitMod = calcGeneralTraitBonus(attacker, target, skill.getTraitType(), true); final double generalTraitMod = calcGeneralTraitBonus(attacker, target, skill.getTraitType(), true);
final double weaknessMod = calcWeaknessBonus(attacker, target, skill.getTraitType());
final double attributeMod = calcAttributeBonus(attacker, target, skill); final double attributeMod = calcAttributeBonus(attacker, target, skill);
final double randomMod = attacker.getRandomDamageMultiplier(); final double randomMod = attacker.getRandomDamageMultiplier();
final double pvpPveMod = calculatePvpPveBonus(attacker, target, skill, mcrit); final double pvpPveMod = calculatePvpPveBonus(attacker, target, skill, mcrit);
@@ -178,7 +180,7 @@ public final class Formulas
} }
} }
damage = damage * critMod * generalTraitMod * attributeMod * randomMod * pvpPveMod; damage = damage * critMod * generalTraitMod * weaknessMod * attributeMod * randomMod * pvpPveMod;
damage *= attacker.getStat().getValue(Stats.MAGICAL_SKILL_POWER, 1); damage *= attacker.getStat().getValue(Stats.MAGICAL_SKILL_POWER, 1);
return damage; return damage;
@@ -1270,8 +1272,20 @@ public final class Formulas
} }
} }
final double result = (attacker.getStat().getAttackTrait(traitType) - target.getStat().getDefenceTrait(traitType)) + 1.0; return Math.max(attacker.getStat().getAttackTrait(traitType) - target.getStat().getDefenceTrait(traitType), 0.05);
return CommonUtil.constrain(result, 0.05, 2.0); }
public static double calcWeaknessBonus(Creature attacker, Creature target, TraitType traitType)
{
double result = 1;
for (TraitType trait : TraitType.getAllWeakness())
{
if ((traitType != trait) && target.getStat().hasDefenceTrait(trait) && attacker.getStat().hasAttackTrait(trait) && !target.getStat().isInvulnerableTrait(traitType))
{
result *= Math.max(attacker.getStat().getAttackTrait(trait) - target.getStat().getDefenceTrait(trait), 0.05);
}
}
return result;
} }
public static double calcWeaponTraitBonus(Creature attacker, Creature target) public static double calcWeaponTraitBonus(Creature attacker, Creature target)
@@ -1300,7 +1314,7 @@ public final class Formulas
} }
} }
return CommonUtil.constrain((weaponTraitBonus * weaknessBonus), 0.05, 2.0); return Math.max(weaponTraitBonus * weaknessBonus, 0.05);
} }
public static double getBasicPropertyResistBonus(BasicProperty basicProperty, Creature target) public static double getBasicPropertyResistBonus(BasicProperty basicProperty, Creature target)

View File

@@ -16,6 +16,9 @@
*/ */
package org.l2jmobius.gameserver.model.stats; package org.l2jmobius.gameserver.model.stats;
import java.util.ArrayList;
import java.util.List;
/** /**
* @author UnAfraid, NosBit * @author UnAfraid, NosBit
*/ */
@@ -88,6 +91,33 @@ public enum TraitType
SPIRIT_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
private final static List<TraitType> _weaknesses = new ArrayList<>();
static
{
_weaknesses.add(BUG_WEAKNESS);
_weaknesses.add(ANIMAL_WEAKNESS);
_weaknesses.add(PLANT_WEAKNESS);
_weaknesses.add(BEAST_WEAKNESS);
_weaknesses.add(DRAGON_WEAKNESS);
_weaknesses.add(GIANT_WEAKNESS);
_weaknesses.add(CONSTRUCT_WEAKNESS);
_weaknesses.add(VALAKAS);
_weaknesses.add(ANESTHESIA);
_weaknesses.add(DEMONIC_WEAKNESS);
_weaknesses.add(DIVINE_WEAKNESS);
_weaknesses.add(ELEMENTAL_WEAKNESS);
_weaknesses.add(FAIRY_WEAKNESS);
_weaknesses.add(HUMAN_WEAKNESS);
_weaknesses.add(HUMANOID_WEAKNESS);
_weaknesses.add(UNDEAD_WEAKNESS);
_weaknesses.add(EMBRYO_WEAKNESS);
_weaknesses.add(SPIRIT_WEAKNESS);
}
public static List<TraitType> getAllWeakness()
{
return _weaknesses;
}
TraitType(int type) TraitType(int type)
{ {

View File

@@ -23,6 +23,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.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;
@@ -49,11 +50,20 @@ public final class AttackTrait extends AbstractEffect
} }
@Override @Override
public void pump(Creature effected, Skill skill) public void onStart(Creature effector, Creature effected, Skill skill, ItemInstance item)
{ {
for (Entry<TraitType, Float> trait : _attackTraits.entrySet()) for (Entry<TraitType, Float> trait : _attackTraits.entrySet())
{ {
effected.getStat().mergeAttackTrait(trait.getKey(), trait.getValue()); effected.getStat().mergeAttackTrait(trait.getKey(), trait.getValue());
} }
} }
@Override
public void onExit(Creature effector, Creature effected, Skill skill)
{
for (Entry<TraitType, Float> trait : _attackTraits.entrySet())
{
effected.getStat().removeAttackTrait(trait.getKey(), trait.getValue());
}
}
} }

View File

@@ -23,6 +23,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.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;
@@ -49,7 +50,7 @@ public final class DefenceTrait extends AbstractEffect
} }
@Override @Override
public void pump(Creature effected, Skill skill) public void onStart(Creature effector, Creature effected, Skill skill, ItemInstance item)
{ {
for (Entry<TraitType, Float> trait : _defenceTraits.entrySet()) for (Entry<TraitType, Float> trait : _defenceTraits.entrySet())
{ {
@@ -63,4 +64,20 @@ public final class DefenceTrait extends AbstractEffect
} }
} }
} }
@Override
public void onExit(Creature effector, Creature effected, Skill skill)
{
for (Entry<TraitType, Float> trait : _defenceTraits.entrySet())
{
if (trait.getValue() < 2.0f)
{
effected.getStat().removeDefenceTrait(trait.getKey(), trait.getValue());
}
else
{
effected.getStat().removeInvulnerableTrait(trait.getKey());
}
}
}
} }

View File

@@ -125,6 +125,7 @@ public final class EnergyAttack extends AbstractEffect
// Trait, elements // Trait, elements
final double weaponTraitMod = Formulas.calcWeaponTraitBonus(attacker, effected); final double weaponTraitMod = Formulas.calcWeaponTraitBonus(attacker, effected);
final double generalTraitMod = Formulas.calcGeneralTraitBonus(attacker, effected, skill.getTraitType(), true); final double generalTraitMod = Formulas.calcGeneralTraitBonus(attacker, effected, skill.getTraitType(), true);
final double weaknessMod = Formulas.calcWeaknessBonus(attacker, effected, skill.getTraitType());
final double attributeMod = Formulas.calcAttributeBonus(attacker, effected, skill); final double attributeMod = Formulas.calcAttributeBonus(attacker, effected, skill);
final double pvpPveMod = Formulas.calculatePvpPveBonus(attacker, effected, skill, true); final double pvpPveMod = Formulas.calculatePvpPveBonus(attacker, effected, skill, true);
@@ -148,7 +149,7 @@ public final class EnergyAttack extends AbstractEffect
// ATTACK CALCULATION ((77 * ((pAtk * lvlMod) + power) * (1 + (0.1 * chargesConsumed)) / pdef) * skillPower) + skillPowerAdd // ATTACK CALCULATION ((77 * ((pAtk * lvlMod) + power) * (1 + (0.1 * chargesConsumed)) / pdef) * skillPower) + skillPowerAdd
// ```````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^```^^^^^^^^^^^^^^^^^^^^^^^^^^^^^```^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ // ```````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^```^^^^^^^^^^^^^^^^^^^^^^^^^^^^^```^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
final double baseMod = (77 * ((attacker.getPAtk() * attacker.getLevelMod()) + _power + effector.getStat().getValue(Stats.SKILL_POWER_ADD, 0))) / defence; final double baseMod = (77 * ((attacker.getPAtk() * attacker.getLevelMod()) + _power + effector.getStat().getValue(Stats.SKILL_POWER_ADD, 0))) / defence;
damage = baseMod * ssmod * critMod * weaponTraitMod * generalTraitMod * attributeMod * energyChargesBoost * pvpPveMod; damage = baseMod * ssmod * critMod * weaponTraitMod * generalTraitMod * weaknessMod * attributeMod * energyChargesBoost * pvpPveMod;
} }
damage = Math.max(0, damage * effector.getStat().getValue(Stats.PHYSICAL_SKILL_POWER, 1)); damage = Math.max(0, damage * effector.getStat().getValue(Stats.PHYSICAL_SKILL_POWER, 1));

View File

@@ -141,6 +141,7 @@ public final class PhysicalAttack extends AbstractEffect
// Trait, elements // Trait, elements
final double weaponTraitMod = Formulas.calcWeaponTraitBonus(effector, effected); final double weaponTraitMod = Formulas.calcWeaponTraitBonus(effector, effected);
final double generalTraitMod = Formulas.calcGeneralTraitBonus(effector, effected, skill.getTraitType(), true); final double generalTraitMod = Formulas.calcGeneralTraitBonus(effector, effected, skill.getTraitType(), true);
final double weaknessMod = Formulas.calcWeaknessBonus(effector, effected, skill.getTraitType());
final double attributeMod = Formulas.calcAttributeBonus(effector, effected, skill); final double attributeMod = Formulas.calcAttributeBonus(effector, effected, skill);
final double pvpPveMod = Formulas.calculatePvpPveBonus(effector, effected, skill, true); final double pvpPveMod = Formulas.calculatePvpPveBonus(effector, effected, skill, true);
final double randomMod = effector.getRandomDamageMultiplier(); final double randomMod = effector.getRandomDamageMultiplier();
@@ -168,7 +169,7 @@ public final class PhysicalAttack extends AbstractEffect
// ATTACK CALCULATION 77 * ((pAtk * lvlMod) + power) / pdef            RANGED ATTACK CALCULATION 70 * ((pAtk * lvlMod) + power + patk + power) / pdef // ATTACK CALCULATION 77 * ((pAtk * lvlMod) + power) / pdef            RANGED ATTACK CALCULATION 70 * ((pAtk * lvlMod) + power + patk + power) / pdef
// ```````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^``````````````````````````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ // ```````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^``````````````````````````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
final double baseMod = (weaponMod * ((attack * effector.getLevelMod()) + power + rangedBonus)) / defence; final double baseMod = (weaponMod * ((attack * effector.getLevelMod()) + power + rangedBonus)) / defence;
damage = baseMod * abnormalMod * ssmod * critMod * weaponTraitMod * generalTraitMod * attributeMod * pvpPveMod * randomMod; damage = baseMod * abnormalMod * ssmod * critMod * weaponTraitMod * generalTraitMod * weaknessMod * attributeMod * pvpPveMod * randomMod;
damage *= effector.getStat().getValue(Stats.PHYSICAL_SKILL_POWER, 1); damage *= effector.getStat().getValue(Stats.PHYSICAL_SKILL_POWER, 1);
} }

View File

@@ -101,6 +101,7 @@ public final class PhysicalAttackHpLink extends AbstractEffect
// Trait, elements // Trait, elements
final double weaponTraitMod = Formulas.calcWeaponTraitBonus(effector, effected); final double weaponTraitMod = Formulas.calcWeaponTraitBonus(effector, effected);
final double generalTraitMod = Formulas.calcGeneralTraitBonus(effector, effected, skill.getTraitType(), true); final double generalTraitMod = Formulas.calcGeneralTraitBonus(effector, effected, skill.getTraitType(), true);
final double weaknessMod = Formulas.calcWeaknessBonus(effector, effected, skill.getTraitType());
final double attributeMod = Formulas.calcAttributeBonus(effector, effected, skill); final double attributeMod = Formulas.calcAttributeBonus(effector, effected, skill);
final double pvpPveMod = Formulas.calculatePvpPveBonus(effector, effected, skill, true); final double pvpPveMod = Formulas.calculatePvpPveBonus(effector, effected, skill, true);
final double randomMod = effector.getRandomDamageMultiplier(); final double randomMod = effector.getRandomDamageMultiplier();
@@ -127,7 +128,7 @@ public final class PhysicalAttackHpLink extends AbstractEffect
// ATTACK CALCULATION 77 * ((pAtk * lvlMod) + power) / pdef            RANGED ATTACK CALCULATION 70 * ((pAtk * lvlMod) + power + patk + power) / pdef // ATTACK CALCULATION 77 * ((pAtk * lvlMod) + power) / pdef            RANGED ATTACK CALCULATION 70 * ((pAtk * lvlMod) + power + patk + power) / pdef
// ```````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^``````````````````````````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ // ```````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^``````````````````````````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
final double baseMod = (weaponMod * ((attack * effector.getLevelMod()) + power + rangedBonus)) / defence; final double baseMod = (weaponMod * ((attack * effector.getLevelMod()) + power + rangedBonus)) / defence;
damage = baseMod * ssmod * critMod * weaponTraitMod * generalTraitMod * attributeMod * pvpPveMod * randomMod; damage = baseMod * ssmod * critMod * weaponTraitMod * generalTraitMod * weaknessMod * attributeMod * pvpPveMod * randomMod;
damage *= effector.getStat().getValue(Stats.PHYSICAL_SKILL_POWER, 1); damage *= effector.getStat().getValue(Stats.PHYSICAL_SKILL_POWER, 1);
damage *= -((effector.getCurrentHp() * 2) / effector.getMaxHp()) + 2; damage *= -((effector.getCurrentHp() * 2) / effector.getMaxHp()) + 2;
} }

View File

@@ -114,6 +114,7 @@ public final class PhysicalAttackSaveHp extends AbstractEffect
// Trait, elements // Trait, elements
final double weaponTraitMod = Formulas.calcWeaponTraitBonus(effector, effected); final double weaponTraitMod = Formulas.calcWeaponTraitBonus(effector, effected);
final double generalTraitMod = Formulas.calcGeneralTraitBonus(effector, effected, skill.getTraitType(), true); final double generalTraitMod = Formulas.calcGeneralTraitBonus(effector, effected, skill.getTraitType(), true);
final double weaknessMod = Formulas.calcWeaknessBonus(effector, effected, skill.getTraitType());
final double attributeMod = Formulas.calcAttributeBonus(effector, effected, skill); final double attributeMod = Formulas.calcAttributeBonus(effector, effected, skill);
final double pvpPveMod = Formulas.calculatePvpPveBonus(effector, effected, skill, true); final double pvpPveMod = Formulas.calculatePvpPveBonus(effector, effected, skill, true);
final double randomMod = effector.getRandomDamageMultiplier(); final double randomMod = effector.getRandomDamageMultiplier();
@@ -140,7 +141,7 @@ public final class PhysicalAttackSaveHp extends AbstractEffect
// ATTACK CALCULATION 77 * ((pAtk * lvlMod) + power) / pdef            RANGED ATTACK CALCULATION 70 * ((pAtk * lvlMod) + power + patk + power) / pdef // ATTACK CALCULATION 77 * ((pAtk * lvlMod) + power) / pdef            RANGED ATTACK CALCULATION 70 * ((pAtk * lvlMod) + power + patk + power) / pdef
// ```````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^``````````````````````````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ // ```````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^``````````````````````````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
final double baseMod = (weaponMod * ((attack * effector.getLevelMod()) + power + rangedBonus)) / defence; final double baseMod = (weaponMod * ((attack * effector.getLevelMod()) + power + rangedBonus)) / defence;
damage = baseMod * ssmod * critMod * weaponTraitMod * generalTraitMod * attributeMod * pvpPveMod * randomMod; damage = baseMod * ssmod * critMod * weaponTraitMod * generalTraitMod * weaknessMod * attributeMod * pvpPveMod * randomMod;
damage *= effector.getStat().getValue(Stats.PHYSICAL_SKILL_POWER, 1); damage *= effector.getStat().getValue(Stats.PHYSICAL_SKILL_POWER, 1);
} }

View File

@@ -134,6 +134,7 @@ public final class PhysicalAttackWeaponBonus extends AbstractEffect
// Trait, elements // Trait, elements
final double weaponTraitMod = Formulas.calcWeaponTraitBonus(effector, effected); final double weaponTraitMod = Formulas.calcWeaponTraitBonus(effector, effected);
final double generalTraitMod = Formulas.calcGeneralTraitBonus(effector, effected, skill.getTraitType(), true); final double generalTraitMod = Formulas.calcGeneralTraitBonus(effector, effected, skill.getTraitType(), true);
final double weaknessMod = Formulas.calcWeaknessBonus(effector, effected, skill.getTraitType());
final double attributeMod = Formulas.calcAttributeBonus(effector, effected, skill); final double attributeMod = Formulas.calcAttributeBonus(effector, effected, skill);
final double pvpPveMod = Formulas.calculatePvpPveBonus(effector, effected, skill, true); final double pvpPveMod = Formulas.calculatePvpPveBonus(effector, effected, skill, true);
final double randomMod = effector.getRandomDamageMultiplier(); final double randomMod = effector.getRandomDamageMultiplier();
@@ -161,7 +162,7 @@ public final class PhysicalAttackWeaponBonus extends AbstractEffect
// ATTACK CALCULATION 77 * ((pAtk * lvlMod) + power) / pdef            RANGED ATTACK CALCULATION 70 * ((pAtk * lvlMod) + power + patk + power) / pdef // ATTACK CALCULATION 77 * ((pAtk * lvlMod) + power) / pdef            RANGED ATTACK CALCULATION 70 * ((pAtk * lvlMod) + power + patk + power) / pdef
// ```````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^``````````````````````````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ // ```````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^``````````````````````````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
final double baseMod = (weaponMod * ((attack * effector.getLevelMod()) + power + rangedBonus)) / defence; final double baseMod = (weaponMod * ((attack * effector.getLevelMod()) + power + rangedBonus)) / defence;
damage = baseMod * ssmod * critMod * weaponBonus * weaponTraitMod * generalTraitMod * attributeMod * pvpPveMod * randomMod; damage = baseMod * ssmod * critMod * weaponBonus * weaponTraitMod * generalTraitMod * weaknessMod * attributeMod * pvpPveMod * randomMod;
damage *= effector.getStat().getValue(Stats.PHYSICAL_SKILL_POWER, 1); damage *= effector.getStat().getValue(Stats.PHYSICAL_SKILL_POWER, 1);
} }

View File

@@ -128,6 +128,7 @@ public final class PhysicalSoulAttack extends AbstractEffect
// Trait, elements // Trait, elements
final double weaponTraitMod = Formulas.calcWeaponTraitBonus(effector, effected); final double weaponTraitMod = Formulas.calcWeaponTraitBonus(effector, effected);
final double generalTraitMod = Formulas.calcGeneralTraitBonus(effector, effected, skill.getTraitType(), true); final double generalTraitMod = Formulas.calcGeneralTraitBonus(effector, effected, skill.getTraitType(), true);
final double weaknessMod = Formulas.calcWeaknessBonus(effector, effected, skill.getTraitType());
final double attributeMod = Formulas.calcAttributeBonus(effector, effected, skill); final double attributeMod = Formulas.calcAttributeBonus(effector, effected, skill);
final double pvpPveMod = Formulas.calculatePvpPveBonus(effector, effected, skill, true); final double pvpPveMod = Formulas.calculatePvpPveBonus(effector, effected, skill, true);
final double randomMod = effector.getRandomDamageMultiplier(); final double randomMod = effector.getRandomDamageMultiplier();
@@ -155,7 +156,7 @@ public final class PhysicalSoulAttack extends AbstractEffect
// ATTACK CALCULATION 77 * ((pAtk * lvlMod) + power) / pdef            RANGED ATTACK CALCULATION 70 * ((pAtk * lvlMod) + power + patk + power) / pdef // ATTACK CALCULATION 77 * ((pAtk * lvlMod) + power) / pdef            RANGED ATTACK CALCULATION 70 * ((pAtk * lvlMod) + power + patk + power) / pdef
// ```````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^``````````````````````````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ // ```````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^``````````````````````````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
final double baseMod = (weaponMod * ((attack * effector.getLevelMod()) + power + rangedBonus)) / defence; final double baseMod = (weaponMod * ((attack * effector.getLevelMod()) + power + rangedBonus)) / defence;
damage = baseMod * soulsMod * ssmod * critMod * weaponTraitMod * generalTraitMod * attributeMod * pvpPveMod * randomMod; damage = baseMod * soulsMod * ssmod * critMod * weaponTraitMod * generalTraitMod * weaknessMod * attributeMod * pvpPveMod * randomMod;
damage *= effector.getStat().getValue(Stats.PHYSICAL_SKILL_POWER, 1); damage *= effector.getStat().getValue(Stats.PHYSICAL_SKILL_POWER, 1);
} }

View File

@@ -98,9 +98,6 @@
<amount>50</amount> <amount>50</amount>
<mode>PER</mode> <mode>PER</mode>
</effect> </effect>
<effect name="AttackTrait">
<DRAGON_WEAKNESS>300</DRAGON_WEAKNESS>
</effect>
</effects> </effects>
</skill> </skill>
<skill id="8902" toLevel="1" name="Dragon Mage"> <skill id="8902" toLevel="1" name="Dragon Mage">

View File

@@ -87,6 +87,11 @@ public class CreatureStat
public CreatureStat(Creature creature) public CreatureStat(Creature creature)
{ {
_creature = creature; _creature = creature;
for (int i = 0; i < TraitType.values().length; i++)
{
_attackTraitValues[i] = 1;
_defenceTraitValues[i] = 1;
}
} }
/** /**
@@ -582,10 +587,35 @@ public class CreatureStat
} }
public void mergeAttackTrait(TraitType traitType, float value) public void mergeAttackTrait(TraitType traitType, float value)
{
_lock.readLock().lock();
try
{ {
_attackTraitValues[traitType.ordinal()] *= value; _attackTraitValues[traitType.ordinal()] *= value;
_attackTraits.add(traitType); _attackTraits.add(traitType);
} }
finally
{
_lock.readLock().unlock();
}
}
public void removeAttackTrait(TraitType traitType, float value)
{
_lock.readLock().lock();
try
{
_attackTraitValues[traitType.ordinal()] /= value;
if (_attackTraitValues[traitType.ordinal()] == 1)
{
_attackTraits.remove(traitType);
}
}
finally
{
_lock.readLock().unlock();
}
}
public float getAttackTrait(TraitType traitType) public float getAttackTrait(TraitType traitType)
{ {
@@ -614,10 +644,35 @@ public class CreatureStat
} }
public void mergeDefenceTrait(TraitType traitType, float value) public void mergeDefenceTrait(TraitType traitType, float value)
{
_lock.readLock().lock();
try
{ {
_defenceTraitValues[traitType.ordinal()] *= value; _defenceTraitValues[traitType.ordinal()] *= value;
_defenceTraits.add(traitType); _defenceTraits.add(traitType);
} }
finally
{
_lock.readLock().unlock();
}
}
public void removeDefenceTrait(TraitType traitType, float value)
{
_lock.readLock().lock();
try
{
_defenceTraitValues[traitType.ordinal()] /= value;
if (_defenceTraitValues[traitType.ordinal()] == 1)
{
_defenceTraits.remove(traitType);
}
}
finally
{
_lock.readLock().unlock();
}
}
public float getDefenceTrait(TraitType traitType) public float getDefenceTrait(TraitType traitType)
{ {
@@ -646,9 +701,30 @@ public class CreatureStat
} }
public void mergeInvulnerableTrait(TraitType traitType) public void mergeInvulnerableTrait(TraitType traitType)
{
_lock.readLock().lock();
try
{ {
_invulnerableTraits.add(traitType); _invulnerableTraits.add(traitType);
} }
finally
{
_lock.readLock().unlock();
}
}
public void removeInvulnerableTrait(TraitType traitType)
{
_lock.readLock().lock();
try
{
_invulnerableTraits.remove(traitType);
}
finally
{
_lock.readLock().unlock();
}
}
public boolean isInvulnerableTrait(TraitType traitType) public boolean isInvulnerableTrait(TraitType traitType)
{ {

View File

@@ -94,14 +94,15 @@ public final class Formulas
} }
// Critical // Critical
final double criticalMod = (attacker.getStat().getValue(Stats.CRITICAL_DAMAGE, 1)); final double criticalMod = attacker.getStat().getValue(Stats.CRITICAL_DAMAGE, 1);
final double criticalPositionMod = attacker.getStat().getPositionTypeValue(Stats.CRITICAL_DAMAGE, Position.getPosition(attacker, target)); final double criticalPositionMod = attacker.getStat().getPositionTypeValue(Stats.CRITICAL_DAMAGE, Position.getPosition(attacker, target));
final double criticalVulnMod = (target.getStat().getValue(Stats.DEFENCE_CRITICAL_DAMAGE, 1)); final double criticalVulnMod = target.getStat().getValue(Stats.DEFENCE_CRITICAL_DAMAGE, 1);
final double criticalAddMod = (attacker.getStat().getValue(Stats.CRITICAL_DAMAGE_ADD, 0)); final double criticalAddMod = attacker.getStat().getValue(Stats.CRITICAL_DAMAGE_ADD, 0);
final double criticalAddVuln = target.getStat().getValue(Stats.DEFENCE_CRITICAL_DAMAGE_ADD, 0); final double criticalAddVuln = target.getStat().getValue(Stats.DEFENCE_CRITICAL_DAMAGE_ADD, 0);
// Trait, elements // Trait, elements
final double weaponTraitMod = calcWeaponTraitBonus(attacker, target); final double weaponTraitMod = calcWeaponTraitBonus(attacker, target);
final double generalTraitMod = calcGeneralTraitBonus(attacker, target, skill.getTraitType(), true); final double generalTraitMod = calcGeneralTraitBonus(attacker, target, skill.getTraitType(), true);
final double weaknessMod = calcWeaknessBonus(attacker, target, skill.getTraitType());
final double attributeMod = calcAttributeBonus(attacker, target, skill); final double attributeMod = calcAttributeBonus(attacker, target, skill);
final double randomMod = attacker.getRandomDamageMultiplier(); final double randomMod = attacker.getRandomDamageMultiplier();
final double pvpPveMod = calculatePvpPveBonus(attacker, target, skill, true); final double pvpPveMod = calculatePvpPveBonus(attacker, target, skill, true);
@@ -122,8 +123,8 @@ public final class Formulas
// ........................_____________________________Initial Damage____________________________...___________Position Additional Damage___________..._CriticalAdd_ // ........................_____________________________Initial Damage____________________________...___________Position Additional Damage___________..._CriticalAdd_
// ATTACK CALCULATION 77 * [(skillpower+patk) * 0.666 * cdbonus * cdPosBonusHalf * cdVulnHalf * ss + isBack0.2Side0.05 * (skillpower+patk*ss) * random + 6 * cd_patk] / pdef // ATTACK CALCULATION 77 * [(skillpower+patk) * 0.666 * cdbonus * cdPosBonusHalf * cdVulnHalf * ss + isBack0.2Side0.05 * (skillpower+patk*ss) * random + 6 * cd_patk] / pdef
// ````````````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^```^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^```^^^^^^^^^^^^ // ````````````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^```^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^```^^^^^^^^^^^^
final double baseMod = ((77 * (((power + attacker.getPAtk()) * 0.666) + (isPosition * (power + attacker.getPAtk()) * randomMod) + (6 * cdPatk))) / defence); final double baseMod = (77 * (((power + attacker.getPAtk()) * 0.666) + (isPosition * (power + attacker.getPAtk()) * randomMod) + (6 * cdPatk))) / defence;
final double damage = baseMod * ssmod * cdMult * weaponTraitMod * generalTraitMod * attributeMod * randomMod * pvpPveMod; final double damage = baseMod * ssmod * cdMult * weaponTraitMod * generalTraitMod * weaknessMod * attributeMod * randomMod * pvpPveMod;
return damage; return damage;
} }
@@ -136,6 +137,7 @@ public final class Formulas
// Trait, elements // Trait, elements
final double generalTraitMod = calcGeneralTraitBonus(attacker, target, skill.getTraitType(), true); final double generalTraitMod = calcGeneralTraitBonus(attacker, target, skill.getTraitType(), true);
final double weaknessMod = calcWeaknessBonus(attacker, target, skill.getTraitType());
final double attributeMod = calcAttributeBonus(attacker, target, skill); final double attributeMod = calcAttributeBonus(attacker, target, skill);
final double randomMod = attacker.getRandomDamageMultiplier(); final double randomMod = attacker.getRandomDamageMultiplier();
final double pvpPveMod = calculatePvpPveBonus(attacker, target, skill, mcrit); final double pvpPveMod = calculatePvpPveBonus(attacker, target, skill, mcrit);
@@ -178,7 +180,7 @@ public final class Formulas
} }
} }
damage = damage * critMod * generalTraitMod * attributeMod * randomMod * pvpPveMod; damage = damage * critMod * generalTraitMod * weaknessMod * attributeMod * randomMod * pvpPveMod;
damage *= attacker.getStat().getValue(Stats.MAGICAL_SKILL_POWER, 1); damage *= attacker.getStat().getValue(Stats.MAGICAL_SKILL_POWER, 1);
return damage; return damage;
@@ -1270,8 +1272,20 @@ public final class Formulas
} }
} }
final double result = (attacker.getStat().getAttackTrait(traitType) - target.getStat().getDefenceTrait(traitType)) + 1.0; return Math.max(attacker.getStat().getAttackTrait(traitType) - target.getStat().getDefenceTrait(traitType), 0.05);
return CommonUtil.constrain(result, 0.05, 2.0); }
public static double calcWeaknessBonus(Creature attacker, Creature target, TraitType traitType)
{
double result = 1;
for (TraitType trait : TraitType.getAllWeakness())
{
if ((traitType != trait) && target.getStat().hasDefenceTrait(trait) && attacker.getStat().hasAttackTrait(trait) && !target.getStat().isInvulnerableTrait(traitType))
{
result *= Math.max(attacker.getStat().getAttackTrait(trait) - target.getStat().getDefenceTrait(trait), 0.05);
}
}
return result;
} }
public static double calcWeaponTraitBonus(Creature attacker, Creature target) public static double calcWeaponTraitBonus(Creature attacker, Creature target)
@@ -1300,7 +1314,7 @@ public final class Formulas
} }
} }
return CommonUtil.constrain((weaponTraitBonus * weaknessBonus), 0.05, 2.0); return Math.max(weaponTraitBonus * weaknessBonus, 0.05);
} }
public static double getBasicPropertyResistBonus(BasicProperty basicProperty, Creature target) public static double getBasicPropertyResistBonus(BasicProperty basicProperty, Creature target)

View File

@@ -16,6 +16,9 @@
*/ */
package org.l2jmobius.gameserver.model.stats; package org.l2jmobius.gameserver.model.stats;
import java.util.ArrayList;
import java.util.List;
/** /**
* @author UnAfraid, NosBit * @author UnAfraid, NosBit
*/ */
@@ -88,6 +91,33 @@ public enum TraitType
SPIRIT_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
private final static List<TraitType> _weaknesses = new ArrayList<>();
static
{
_weaknesses.add(BUG_WEAKNESS);
_weaknesses.add(ANIMAL_WEAKNESS);
_weaknesses.add(PLANT_WEAKNESS);
_weaknesses.add(BEAST_WEAKNESS);
_weaknesses.add(DRAGON_WEAKNESS);
_weaknesses.add(GIANT_WEAKNESS);
_weaknesses.add(CONSTRUCT_WEAKNESS);
_weaknesses.add(VALAKAS);
_weaknesses.add(ANESTHESIA);
_weaknesses.add(DEMONIC_WEAKNESS);
_weaknesses.add(DIVINE_WEAKNESS);
_weaknesses.add(ELEMENTAL_WEAKNESS);
_weaknesses.add(FAIRY_WEAKNESS);
_weaknesses.add(HUMAN_WEAKNESS);
_weaknesses.add(HUMANOID_WEAKNESS);
_weaknesses.add(UNDEAD_WEAKNESS);
_weaknesses.add(EMBRYO_WEAKNESS);
_weaknesses.add(SPIRIT_WEAKNESS);
}
public static List<TraitType> getAllWeakness()
{
return _weaknesses;
}
TraitType(int type) TraitType(int type)
{ {

View File

@@ -23,6 +23,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.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;
@@ -49,11 +50,20 @@ public final class AttackTrait extends AbstractEffect
} }
@Override @Override
public void pump(Creature effected, Skill skill) public void onStart(Creature effector, Creature effected, Skill skill, ItemInstance item)
{ {
for (Entry<TraitType, Float> trait : _attackTraits.entrySet()) for (Entry<TraitType, Float> trait : _attackTraits.entrySet())
{ {
effected.getStat().mergeAttackTrait(trait.getKey(), trait.getValue()); effected.getStat().mergeAttackTrait(trait.getKey(), trait.getValue());
} }
} }
@Override
public void onExit(Creature effector, Creature effected, Skill skill)
{
for (Entry<TraitType, Float> trait : _attackTraits.entrySet())
{
effected.getStat().removeAttackTrait(trait.getKey(), trait.getValue());
}
}
} }

View File

@@ -23,6 +23,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.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;
@@ -49,7 +50,7 @@ public final class DefenceTrait extends AbstractEffect
} }
@Override @Override
public void pump(Creature effected, Skill skill) public void onStart(Creature effector, Creature effected, Skill skill, ItemInstance item)
{ {
for (Entry<TraitType, Float> trait : _defenceTraits.entrySet()) for (Entry<TraitType, Float> trait : _defenceTraits.entrySet())
{ {
@@ -63,4 +64,20 @@ public final class DefenceTrait extends AbstractEffect
} }
} }
} }
@Override
public void onExit(Creature effector, Creature effected, Skill skill)
{
for (Entry<TraitType, Float> trait : _defenceTraits.entrySet())
{
if (trait.getValue() < 2.0f)
{
effected.getStat().removeDefenceTrait(trait.getKey(), trait.getValue());
}
else
{
effected.getStat().removeInvulnerableTrait(trait.getKey());
}
}
}
} }

View File

@@ -125,6 +125,7 @@ public final class EnergyAttack extends AbstractEffect
// Trait, elements // Trait, elements
final double weaponTraitMod = Formulas.calcWeaponTraitBonus(attacker, effected); final double weaponTraitMod = Formulas.calcWeaponTraitBonus(attacker, effected);
final double generalTraitMod = Formulas.calcGeneralTraitBonus(attacker, effected, skill.getTraitType(), true); final double generalTraitMod = Formulas.calcGeneralTraitBonus(attacker, effected, skill.getTraitType(), true);
final double weaknessMod = Formulas.calcWeaknessBonus(attacker, effected, skill.getTraitType());
final double attributeMod = Formulas.calcAttributeBonus(attacker, effected, skill); final double attributeMod = Formulas.calcAttributeBonus(attacker, effected, skill);
final double pvpPveMod = Formulas.calculatePvpPveBonus(attacker, effected, skill, true); final double pvpPveMod = Formulas.calculatePvpPveBonus(attacker, effected, skill, true);
@@ -148,7 +149,7 @@ public final class EnergyAttack extends AbstractEffect
// ATTACK CALCULATION ((77 * ((pAtk * lvlMod) + power) * (1 + (0.1 * chargesConsumed)) / pdef) * skillPower) + skillPowerAdd // ATTACK CALCULATION ((77 * ((pAtk * lvlMod) + power) * (1 + (0.1 * chargesConsumed)) / pdef) * skillPower) + skillPowerAdd
// ```````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^```^^^^^^^^^^^^^^^^^^^^^^^^^^^^^```^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ // ```````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^```^^^^^^^^^^^^^^^^^^^^^^^^^^^^^```^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
final double baseMod = (77 * ((attacker.getPAtk() * attacker.getLevelMod()) + _power + effector.getStat().getValue(Stats.SKILL_POWER_ADD, 0))) / defence; final double baseMod = (77 * ((attacker.getPAtk() * attacker.getLevelMod()) + _power + effector.getStat().getValue(Stats.SKILL_POWER_ADD, 0))) / defence;
damage = baseMod * ssmod * critMod * weaponTraitMod * generalTraitMod * attributeMod * energyChargesBoost * pvpPveMod; damage = baseMod * ssmod * critMod * weaponTraitMod * generalTraitMod * weaknessMod * attributeMod * energyChargesBoost * pvpPveMod;
} }
damage = Math.max(0, damage * effector.getStat().getValue(Stats.PHYSICAL_SKILL_POWER, 1)); damage = Math.max(0, damage * effector.getStat().getValue(Stats.PHYSICAL_SKILL_POWER, 1));

View File

@@ -141,6 +141,7 @@ public final class PhysicalAttack extends AbstractEffect
// Trait, elements // Trait, elements
final double weaponTraitMod = Formulas.calcWeaponTraitBonus(effector, effected); final double weaponTraitMod = Formulas.calcWeaponTraitBonus(effector, effected);
final double generalTraitMod = Formulas.calcGeneralTraitBonus(effector, effected, skill.getTraitType(), true); final double generalTraitMod = Formulas.calcGeneralTraitBonus(effector, effected, skill.getTraitType(), true);
final double weaknessMod = Formulas.calcWeaknessBonus(effector, effected, skill.getTraitType());
final double attributeMod = Formulas.calcAttributeBonus(effector, effected, skill); final double attributeMod = Formulas.calcAttributeBonus(effector, effected, skill);
final double pvpPveMod = Formulas.calculatePvpPveBonus(effector, effected, skill, true); final double pvpPveMod = Formulas.calculatePvpPveBonus(effector, effected, skill, true);
final double randomMod = effector.getRandomDamageMultiplier(); final double randomMod = effector.getRandomDamageMultiplier();
@@ -168,7 +169,7 @@ public final class PhysicalAttack extends AbstractEffect
// ATTACK CALCULATION 77 * ((pAtk * lvlMod) + power) / pdef            RANGED ATTACK CALCULATION 70 * ((pAtk * lvlMod) + power + patk + power) / pdef // ATTACK CALCULATION 77 * ((pAtk * lvlMod) + power) / pdef            RANGED ATTACK CALCULATION 70 * ((pAtk * lvlMod) + power + patk + power) / pdef
// ```````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^``````````````````````````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ // ```````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^``````````````````````````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
final double baseMod = (weaponMod * ((attack * effector.getLevelMod()) + power + rangedBonus)) / defence; final double baseMod = (weaponMod * ((attack * effector.getLevelMod()) + power + rangedBonus)) / defence;
damage = baseMod * abnormalMod * ssmod * critMod * weaponTraitMod * generalTraitMod * attributeMod * pvpPveMod * randomMod; damage = baseMod * abnormalMod * ssmod * critMod * weaponTraitMod * generalTraitMod * weaknessMod * attributeMod * pvpPveMod * randomMod;
damage *= effector.getStat().getValue(Stats.PHYSICAL_SKILL_POWER, 1); damage *= effector.getStat().getValue(Stats.PHYSICAL_SKILL_POWER, 1);
} }

View File

@@ -101,6 +101,7 @@ public final class PhysicalAttackHpLink extends AbstractEffect
// Trait, elements // Trait, elements
final double weaponTraitMod = Formulas.calcWeaponTraitBonus(effector, effected); final double weaponTraitMod = Formulas.calcWeaponTraitBonus(effector, effected);
final double generalTraitMod = Formulas.calcGeneralTraitBonus(effector, effected, skill.getTraitType(), true); final double generalTraitMod = Formulas.calcGeneralTraitBonus(effector, effected, skill.getTraitType(), true);
final double weaknessMod = Formulas.calcWeaknessBonus(effector, effected, skill.getTraitType());
final double attributeMod = Formulas.calcAttributeBonus(effector, effected, skill); final double attributeMod = Formulas.calcAttributeBonus(effector, effected, skill);
final double pvpPveMod = Formulas.calculatePvpPveBonus(effector, effected, skill, true); final double pvpPveMod = Formulas.calculatePvpPveBonus(effector, effected, skill, true);
final double randomMod = effector.getRandomDamageMultiplier(); final double randomMod = effector.getRandomDamageMultiplier();
@@ -127,7 +128,7 @@ public final class PhysicalAttackHpLink extends AbstractEffect
// ATTACK CALCULATION 77 * ((pAtk * lvlMod) + power) / pdef            RANGED ATTACK CALCULATION 70 * ((pAtk * lvlMod) + power + patk + power) / pdef // ATTACK CALCULATION 77 * ((pAtk * lvlMod) + power) / pdef            RANGED ATTACK CALCULATION 70 * ((pAtk * lvlMod) + power + patk + power) / pdef
// ```````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^``````````````````````````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ // ```````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^``````````````````````````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
final double baseMod = (weaponMod * ((attack * effector.getLevelMod()) + power + rangedBonus)) / defence; final double baseMod = (weaponMod * ((attack * effector.getLevelMod()) + power + rangedBonus)) / defence;
damage = baseMod * ssmod * critMod * weaponTraitMod * generalTraitMod * attributeMod * pvpPveMod * randomMod; damage = baseMod * ssmod * critMod * weaponTraitMod * generalTraitMod * weaknessMod * attributeMod * pvpPveMod * randomMod;
damage *= effector.getStat().getValue(Stats.PHYSICAL_SKILL_POWER, 1); damage *= effector.getStat().getValue(Stats.PHYSICAL_SKILL_POWER, 1);
damage *= -((effector.getCurrentHp() * 2) / effector.getMaxHp()) + 2; damage *= -((effector.getCurrentHp() * 2) / effector.getMaxHp()) + 2;
} }

View File

@@ -114,6 +114,7 @@ public final class PhysicalAttackSaveHp extends AbstractEffect
// Trait, elements // Trait, elements
final double weaponTraitMod = Formulas.calcWeaponTraitBonus(effector, effected); final double weaponTraitMod = Formulas.calcWeaponTraitBonus(effector, effected);
final double generalTraitMod = Formulas.calcGeneralTraitBonus(effector, effected, skill.getTraitType(), true); final double generalTraitMod = Formulas.calcGeneralTraitBonus(effector, effected, skill.getTraitType(), true);
final double weaknessMod = Formulas.calcWeaknessBonus(effector, effected, skill.getTraitType());
final double attributeMod = Formulas.calcAttributeBonus(effector, effected, skill); final double attributeMod = Formulas.calcAttributeBonus(effector, effected, skill);
final double pvpPveMod = Formulas.calculatePvpPveBonus(effector, effected, skill, true); final double pvpPveMod = Formulas.calculatePvpPveBonus(effector, effected, skill, true);
final double randomMod = effector.getRandomDamageMultiplier(); final double randomMod = effector.getRandomDamageMultiplier();
@@ -140,7 +141,7 @@ public final class PhysicalAttackSaveHp extends AbstractEffect
// ATTACK CALCULATION 77 * ((pAtk * lvlMod) + power) / pdef            RANGED ATTACK CALCULATION 70 * ((pAtk * lvlMod) + power + patk + power) / pdef // ATTACK CALCULATION 77 * ((pAtk * lvlMod) + power) / pdef            RANGED ATTACK CALCULATION 70 * ((pAtk * lvlMod) + power + patk + power) / pdef
// ```````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^``````````````````````````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ // ```````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^``````````````````````````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
final double baseMod = (weaponMod * ((attack * effector.getLevelMod()) + power + rangedBonus)) / defence; final double baseMod = (weaponMod * ((attack * effector.getLevelMod()) + power + rangedBonus)) / defence;
damage = baseMod * ssmod * critMod * weaponTraitMod * generalTraitMod * attributeMod * pvpPveMod * randomMod; damage = baseMod * ssmod * critMod * weaponTraitMod * generalTraitMod * weaknessMod * attributeMod * pvpPveMod * randomMod;
damage *= effector.getStat().getValue(Stats.PHYSICAL_SKILL_POWER, 1); damage *= effector.getStat().getValue(Stats.PHYSICAL_SKILL_POWER, 1);
} }

View File

@@ -134,6 +134,7 @@ public final class PhysicalAttackWeaponBonus extends AbstractEffect
// Trait, elements // Trait, elements
final double weaponTraitMod = Formulas.calcWeaponTraitBonus(effector, effected); final double weaponTraitMod = Formulas.calcWeaponTraitBonus(effector, effected);
final double generalTraitMod = Formulas.calcGeneralTraitBonus(effector, effected, skill.getTraitType(), true); final double generalTraitMod = Formulas.calcGeneralTraitBonus(effector, effected, skill.getTraitType(), true);
final double weaknessMod = Formulas.calcWeaknessBonus(effector, effected, skill.getTraitType());
final double attributeMod = Formulas.calcAttributeBonus(effector, effected, skill); final double attributeMod = Formulas.calcAttributeBonus(effector, effected, skill);
final double pvpPveMod = Formulas.calculatePvpPveBonus(effector, effected, skill, true); final double pvpPveMod = Formulas.calculatePvpPveBonus(effector, effected, skill, true);
final double randomMod = effector.getRandomDamageMultiplier(); final double randomMod = effector.getRandomDamageMultiplier();
@@ -161,7 +162,7 @@ public final class PhysicalAttackWeaponBonus extends AbstractEffect
// ATTACK CALCULATION 77 * ((pAtk * lvlMod) + power) / pdef            RANGED ATTACK CALCULATION 70 * ((pAtk * lvlMod) + power + patk + power) / pdef // ATTACK CALCULATION 77 * ((pAtk * lvlMod) + power) / pdef            RANGED ATTACK CALCULATION 70 * ((pAtk * lvlMod) + power + patk + power) / pdef
// ```````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^``````````````````````````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ // ```````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^``````````````````````````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
final double baseMod = (weaponMod * ((attack * effector.getLevelMod()) + power + rangedBonus)) / defence; final double baseMod = (weaponMod * ((attack * effector.getLevelMod()) + power + rangedBonus)) / defence;
damage = baseMod * ssmod * critMod * weaponBonus * weaponTraitMod * generalTraitMod * attributeMod * pvpPveMod * randomMod; damage = baseMod * ssmod * critMod * weaponBonus * weaponTraitMod * generalTraitMod * weaknessMod * attributeMod * pvpPveMod * randomMod;
damage *= effector.getStat().getValue(Stats.PHYSICAL_SKILL_POWER, 1); damage *= effector.getStat().getValue(Stats.PHYSICAL_SKILL_POWER, 1);
} }

View File

@@ -128,6 +128,7 @@ public final class PhysicalSoulAttack extends AbstractEffect
// Trait, elements // Trait, elements
final double weaponTraitMod = Formulas.calcWeaponTraitBonus(effector, effected); final double weaponTraitMod = Formulas.calcWeaponTraitBonus(effector, effected);
final double generalTraitMod = Formulas.calcGeneralTraitBonus(effector, effected, skill.getTraitType(), true); final double generalTraitMod = Formulas.calcGeneralTraitBonus(effector, effected, skill.getTraitType(), true);
final double weaknessMod = Formulas.calcWeaknessBonus(effector, effected, skill.getTraitType());
final double attributeMod = Formulas.calcAttributeBonus(effector, effected, skill); final double attributeMod = Formulas.calcAttributeBonus(effector, effected, skill);
final double pvpPveMod = Formulas.calculatePvpPveBonus(effector, effected, skill, true); final double pvpPveMod = Formulas.calculatePvpPveBonus(effector, effected, skill, true);
final double randomMod = effector.getRandomDamageMultiplier(); final double randomMod = effector.getRandomDamageMultiplier();
@@ -155,7 +156,7 @@ public final class PhysicalSoulAttack extends AbstractEffect
// ATTACK CALCULATION 77 * ((pAtk * lvlMod) + power) / pdef            RANGED ATTACK CALCULATION 70 * ((pAtk * lvlMod) + power + patk + power) / pdef // ATTACK CALCULATION 77 * ((pAtk * lvlMod) + power) / pdef            RANGED ATTACK CALCULATION 70 * ((pAtk * lvlMod) + power + patk + power) / pdef
// ```````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^``````````````````````````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ // ```````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^``````````````````````````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
final double baseMod = (weaponMod * ((attack * effector.getLevelMod()) + power + rangedBonus)) / defence; final double baseMod = (weaponMod * ((attack * effector.getLevelMod()) + power + rangedBonus)) / defence;
damage = baseMod * soulsMod * ssmod * critMod * weaponTraitMod * generalTraitMod * attributeMod * pvpPveMod * randomMod; damage = baseMod * soulsMod * ssmod * critMod * weaponTraitMod * generalTraitMod * weaknessMod * attributeMod * pvpPveMod * randomMod;
damage *= effector.getStat().getValue(Stats.PHYSICAL_SKILL_POWER, 1); damage *= effector.getStat().getValue(Stats.PHYSICAL_SKILL_POWER, 1);
} }

View File

@@ -98,9 +98,6 @@
<amount>50</amount> <amount>50</amount>
<mode>PER</mode> <mode>PER</mode>
</effect> </effect>
<effect name="AttackTrait">
<DRAGON_WEAKNESS>300</DRAGON_WEAKNESS>
</effect>
</effects> </effects>
</skill> </skill>
<skill id="8902" toLevel="1" name="Dragon Mage"> <skill id="8902" toLevel="1" name="Dragon Mage">

View File

@@ -87,6 +87,11 @@ public class CreatureStat
public CreatureStat(Creature creature) public CreatureStat(Creature creature)
{ {
_creature = creature; _creature = creature;
for (int i = 0; i < TraitType.values().length; i++)
{
_attackTraitValues[i] = 1;
_defenceTraitValues[i] = 1;
}
} }
/** /**
@@ -582,10 +587,35 @@ public class CreatureStat
} }
public void mergeAttackTrait(TraitType traitType, float value) public void mergeAttackTrait(TraitType traitType, float value)
{
_lock.readLock().lock();
try
{ {
_attackTraitValues[traitType.ordinal()] *= value; _attackTraitValues[traitType.ordinal()] *= value;
_attackTraits.add(traitType); _attackTraits.add(traitType);
} }
finally
{
_lock.readLock().unlock();
}
}
public void removeAttackTrait(TraitType traitType, float value)
{
_lock.readLock().lock();
try
{
_attackTraitValues[traitType.ordinal()] /= value;
if (_attackTraitValues[traitType.ordinal()] == 1)
{
_attackTraits.remove(traitType);
}
}
finally
{
_lock.readLock().unlock();
}
}
public float getAttackTrait(TraitType traitType) public float getAttackTrait(TraitType traitType)
{ {
@@ -614,10 +644,35 @@ public class CreatureStat
} }
public void mergeDefenceTrait(TraitType traitType, float value) public void mergeDefenceTrait(TraitType traitType, float value)
{
_lock.readLock().lock();
try
{ {
_defenceTraitValues[traitType.ordinal()] *= value; _defenceTraitValues[traitType.ordinal()] *= value;
_defenceTraits.add(traitType); _defenceTraits.add(traitType);
} }
finally
{
_lock.readLock().unlock();
}
}
public void removeDefenceTrait(TraitType traitType, float value)
{
_lock.readLock().lock();
try
{
_defenceTraitValues[traitType.ordinal()] /= value;
if (_defenceTraitValues[traitType.ordinal()] == 1)
{
_defenceTraits.remove(traitType);
}
}
finally
{
_lock.readLock().unlock();
}
}
public float getDefenceTrait(TraitType traitType) public float getDefenceTrait(TraitType traitType)
{ {
@@ -646,9 +701,30 @@ public class CreatureStat
} }
public void mergeInvulnerableTrait(TraitType traitType) public void mergeInvulnerableTrait(TraitType traitType)
{
_lock.readLock().lock();
try
{ {
_invulnerableTraits.add(traitType); _invulnerableTraits.add(traitType);
} }
finally
{
_lock.readLock().unlock();
}
}
public void removeInvulnerableTrait(TraitType traitType)
{
_lock.readLock().lock();
try
{
_invulnerableTraits.remove(traitType);
}
finally
{
_lock.readLock().unlock();
}
}
public boolean isInvulnerableTrait(TraitType traitType) public boolean isInvulnerableTrait(TraitType traitType)
{ {

View File

@@ -94,14 +94,15 @@ public final class Formulas
} }
// Critical // Critical
final double criticalMod = (attacker.getStat().getValue(Stats.CRITICAL_DAMAGE, 1)); final double criticalMod = attacker.getStat().getValue(Stats.CRITICAL_DAMAGE, 1);
final double criticalPositionMod = attacker.getStat().getPositionTypeValue(Stats.CRITICAL_DAMAGE, Position.getPosition(attacker, target)); final double criticalPositionMod = attacker.getStat().getPositionTypeValue(Stats.CRITICAL_DAMAGE, Position.getPosition(attacker, target));
final double criticalVulnMod = (target.getStat().getValue(Stats.DEFENCE_CRITICAL_DAMAGE, 1)); final double criticalVulnMod = target.getStat().getValue(Stats.DEFENCE_CRITICAL_DAMAGE, 1);
final double criticalAddMod = (attacker.getStat().getValue(Stats.CRITICAL_DAMAGE_ADD, 0)); final double criticalAddMod = attacker.getStat().getValue(Stats.CRITICAL_DAMAGE_ADD, 0);
final double criticalAddVuln = target.getStat().getValue(Stats.DEFENCE_CRITICAL_DAMAGE_ADD, 0); final double criticalAddVuln = target.getStat().getValue(Stats.DEFENCE_CRITICAL_DAMAGE_ADD, 0);
// Trait, elements // Trait, elements
final double weaponTraitMod = calcWeaponTraitBonus(attacker, target); final double weaponTraitMod = calcWeaponTraitBonus(attacker, target);
final double generalTraitMod = calcGeneralTraitBonus(attacker, target, skill.getTraitType(), true); final double generalTraitMod = calcGeneralTraitBonus(attacker, target, skill.getTraitType(), true);
final double weaknessMod = calcWeaknessBonus(attacker, target, skill.getTraitType());
final double attributeMod = calcAttributeBonus(attacker, target, skill); final double attributeMod = calcAttributeBonus(attacker, target, skill);
final double randomMod = attacker.getRandomDamageMultiplier(); final double randomMod = attacker.getRandomDamageMultiplier();
final double pvpPveMod = calculatePvpPveBonus(attacker, target, skill, true); final double pvpPveMod = calculatePvpPveBonus(attacker, target, skill, true);
@@ -122,8 +123,8 @@ public final class Formulas
// ........................_____________________________Initial Damage____________________________...___________Position Additional Damage___________..._CriticalAdd_ // ........................_____________________________Initial Damage____________________________...___________Position Additional Damage___________..._CriticalAdd_
// ATTACK CALCULATION 77 * [(skillpower+patk) * 0.666 * cdbonus * cdPosBonusHalf * cdVulnHalf * ss + isBack0.2Side0.05 * (skillpower+patk*ss) * random + 6 * cd_patk] / pdef // ATTACK CALCULATION 77 * [(skillpower+patk) * 0.666 * cdbonus * cdPosBonusHalf * cdVulnHalf * ss + isBack0.2Side0.05 * (skillpower+patk*ss) * random + 6 * cd_patk] / pdef
// ````````````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^```^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^```^^^^^^^^^^^^ // ````````````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^```^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^```^^^^^^^^^^^^
final double baseMod = ((77 * (((power + attacker.getPAtk()) * 0.666) + (isPosition * (power + attacker.getPAtk()) * randomMod) + (6 * cdPatk))) / defence); final double baseMod = (77 * (((power + attacker.getPAtk()) * 0.666) + (isPosition * (power + attacker.getPAtk()) * randomMod) + (6 * cdPatk))) / defence;
final double damage = baseMod * ssmod * cdMult * weaponTraitMod * generalTraitMod * attributeMod * randomMod * pvpPveMod; final double damage = baseMod * ssmod * cdMult * weaponTraitMod * generalTraitMod * weaknessMod * attributeMod * randomMod * pvpPveMod;
return damage; return damage;
} }
@@ -136,6 +137,7 @@ public final class Formulas
// Trait, elements // Trait, elements
final double generalTraitMod = calcGeneralTraitBonus(attacker, target, skill.getTraitType(), true); final double generalTraitMod = calcGeneralTraitBonus(attacker, target, skill.getTraitType(), true);
final double weaknessMod = calcWeaknessBonus(attacker, target, skill.getTraitType());
final double attributeMod = calcAttributeBonus(attacker, target, skill); final double attributeMod = calcAttributeBonus(attacker, target, skill);
final double randomMod = attacker.getRandomDamageMultiplier(); final double randomMod = attacker.getRandomDamageMultiplier();
final double pvpPveMod = calculatePvpPveBonus(attacker, target, skill, mcrit); final double pvpPveMod = calculatePvpPveBonus(attacker, target, skill, mcrit);
@@ -178,7 +180,7 @@ public final class Formulas
} }
} }
damage = damage * critMod * generalTraitMod * attributeMod * randomMod * pvpPveMod; damage = damage * critMod * generalTraitMod * weaknessMod * attributeMod * randomMod * pvpPveMod;
damage *= attacker.getStat().getValue(Stats.MAGICAL_SKILL_POWER, 1); damage *= attacker.getStat().getValue(Stats.MAGICAL_SKILL_POWER, 1);
return damage; return damage;
@@ -1270,8 +1272,20 @@ public final class Formulas
} }
} }
final double result = (attacker.getStat().getAttackTrait(traitType) - target.getStat().getDefenceTrait(traitType)) + 1.0; return Math.max(attacker.getStat().getAttackTrait(traitType) - target.getStat().getDefenceTrait(traitType), 0.05);
return CommonUtil.constrain(result, 0.05, 2.0); }
public static double calcWeaknessBonus(Creature attacker, Creature target, TraitType traitType)
{
double result = 1;
for (TraitType trait : TraitType.getAllWeakness())
{
if ((traitType != trait) && target.getStat().hasDefenceTrait(trait) && attacker.getStat().hasAttackTrait(trait) && !target.getStat().isInvulnerableTrait(traitType))
{
result *= Math.max(attacker.getStat().getAttackTrait(trait) - target.getStat().getDefenceTrait(trait), 0.05);
}
}
return result;
} }
public static double calcWeaponTraitBonus(Creature attacker, Creature target) public static double calcWeaponTraitBonus(Creature attacker, Creature target)
@@ -1300,7 +1314,7 @@ public final class Formulas
} }
} }
return CommonUtil.constrain((weaponTraitBonus * weaknessBonus), 0.05, 2.0); return Math.max(weaponTraitBonus * weaknessBonus, 0.05);
} }
public static double getBasicPropertyResistBonus(BasicProperty basicProperty, Creature target) public static double getBasicPropertyResistBonus(BasicProperty basicProperty, Creature target)

View File

@@ -16,6 +16,9 @@
*/ */
package org.l2jmobius.gameserver.model.stats; package org.l2jmobius.gameserver.model.stats;
import java.util.ArrayList;
import java.util.List;
/** /**
* @author UnAfraid, NosBit * @author UnAfraid, NosBit
*/ */
@@ -88,6 +91,33 @@ public enum TraitType
SPIRIT_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
private final static List<TraitType> _weaknesses = new ArrayList<>();
static
{
_weaknesses.add(BUG_WEAKNESS);
_weaknesses.add(ANIMAL_WEAKNESS);
_weaknesses.add(PLANT_WEAKNESS);
_weaknesses.add(BEAST_WEAKNESS);
_weaknesses.add(DRAGON_WEAKNESS);
_weaknesses.add(GIANT_WEAKNESS);
_weaknesses.add(CONSTRUCT_WEAKNESS);
_weaknesses.add(VALAKAS);
_weaknesses.add(ANESTHESIA);
_weaknesses.add(DEMONIC_WEAKNESS);
_weaknesses.add(DIVINE_WEAKNESS);
_weaknesses.add(ELEMENTAL_WEAKNESS);
_weaknesses.add(FAIRY_WEAKNESS);
_weaknesses.add(HUMAN_WEAKNESS);
_weaknesses.add(HUMANOID_WEAKNESS);
_weaknesses.add(UNDEAD_WEAKNESS);
_weaknesses.add(EMBRYO_WEAKNESS);
_weaknesses.add(SPIRIT_WEAKNESS);
}
public static List<TraitType> getAllWeakness()
{
return _weaknesses;
}
TraitType(int type) TraitType(int type)
{ {

View File

@@ -23,6 +23,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.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;
@@ -49,11 +50,20 @@ public final class AttackTrait extends AbstractEffect
} }
@Override @Override
public void pump(Creature effected, Skill skill) public void onStart(Creature effector, Creature effected, Skill skill, ItemInstance item)
{ {
for (Entry<TraitType, Float> trait : _attackTraits.entrySet()) for (Entry<TraitType, Float> trait : _attackTraits.entrySet())
{ {
effected.getStat().mergeAttackTrait(trait.getKey(), trait.getValue()); effected.getStat().mergeAttackTrait(trait.getKey(), trait.getValue());
} }
} }
@Override
public void onExit(Creature effector, Creature effected, Skill skill)
{
for (Entry<TraitType, Float> trait : _attackTraits.entrySet())
{
effected.getStat().removeAttackTrait(trait.getKey(), trait.getValue());
}
}
} }

View File

@@ -23,6 +23,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.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;
@@ -49,7 +50,7 @@ public final class DefenceTrait extends AbstractEffect
} }
@Override @Override
public void pump(Creature effected, Skill skill) public void onStart(Creature effector, Creature effected, Skill skill, ItemInstance item)
{ {
for (Entry<TraitType, Float> trait : _defenceTraits.entrySet()) for (Entry<TraitType, Float> trait : _defenceTraits.entrySet())
{ {
@@ -63,4 +64,20 @@ public final class DefenceTrait extends AbstractEffect
} }
} }
} }
@Override
public void onExit(Creature effector, Creature effected, Skill skill)
{
for (Entry<TraitType, Float> trait : _defenceTraits.entrySet())
{
if (trait.getValue() < 2.0f)
{
effected.getStat().removeDefenceTrait(trait.getKey(), trait.getValue());
}
else
{
effected.getStat().removeInvulnerableTrait(trait.getKey());
}
}
}
} }

View File

@@ -125,6 +125,7 @@ public final class EnergyAttack extends AbstractEffect
// Trait, elements // Trait, elements
final double weaponTraitMod = Formulas.calcWeaponTraitBonus(attacker, effected); final double weaponTraitMod = Formulas.calcWeaponTraitBonus(attacker, effected);
final double generalTraitMod = Formulas.calcGeneralTraitBonus(attacker, effected, skill.getTraitType(), true); final double generalTraitMod = Formulas.calcGeneralTraitBonus(attacker, effected, skill.getTraitType(), true);
final double weaknessMod = Formulas.calcWeaknessBonus(attacker, effected, skill.getTraitType());
final double attributeMod = Formulas.calcAttributeBonus(attacker, effected, skill); final double attributeMod = Formulas.calcAttributeBonus(attacker, effected, skill);
final double pvpPveMod = Formulas.calculatePvpPveBonus(attacker, effected, skill, true); final double pvpPveMod = Formulas.calculatePvpPveBonus(attacker, effected, skill, true);
@@ -148,7 +149,7 @@ public final class EnergyAttack extends AbstractEffect
// ATTACK CALCULATION ((77 * ((pAtk * lvlMod) + power) * (1 + (0.1 * chargesConsumed)) / pdef) * skillPower) + skillPowerAdd // ATTACK CALCULATION ((77 * ((pAtk * lvlMod) + power) * (1 + (0.1 * chargesConsumed)) / pdef) * skillPower) + skillPowerAdd
// ```````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^```^^^^^^^^^^^^^^^^^^^^^^^^^^^^^```^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ // ```````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^```^^^^^^^^^^^^^^^^^^^^^^^^^^^^^```^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
final double baseMod = (77 * ((attacker.getPAtk() * attacker.getLevelMod()) + _power + effector.getStat().getValue(Stats.SKILL_POWER_ADD, 0))) / defence; final double baseMod = (77 * ((attacker.getPAtk() * attacker.getLevelMod()) + _power + effector.getStat().getValue(Stats.SKILL_POWER_ADD, 0))) / defence;
damage = baseMod * ssmod * critMod * weaponTraitMod * generalTraitMod * attributeMod * energyChargesBoost * pvpPveMod; damage = baseMod * ssmod * critMod * weaponTraitMod * generalTraitMod * weaknessMod * attributeMod * energyChargesBoost * pvpPveMod;
} }
damage = Math.max(0, damage * effector.getStat().getValue(Stats.PHYSICAL_SKILL_POWER, 1)); damage = Math.max(0, damage * effector.getStat().getValue(Stats.PHYSICAL_SKILL_POWER, 1));

View File

@@ -141,6 +141,7 @@ public final class PhysicalAttack extends AbstractEffect
// Trait, elements // Trait, elements
final double weaponTraitMod = Formulas.calcWeaponTraitBonus(effector, effected); final double weaponTraitMod = Formulas.calcWeaponTraitBonus(effector, effected);
final double generalTraitMod = Formulas.calcGeneralTraitBonus(effector, effected, skill.getTraitType(), true); final double generalTraitMod = Formulas.calcGeneralTraitBonus(effector, effected, skill.getTraitType(), true);
final double weaknessMod = Formulas.calcWeaknessBonus(effector, effected, skill.getTraitType());
final double attributeMod = Formulas.calcAttributeBonus(effector, effected, skill); final double attributeMod = Formulas.calcAttributeBonus(effector, effected, skill);
final double pvpPveMod = Formulas.calculatePvpPveBonus(effector, effected, skill, true); final double pvpPveMod = Formulas.calculatePvpPveBonus(effector, effected, skill, true);
final double randomMod = effector.getRandomDamageMultiplier(); final double randomMod = effector.getRandomDamageMultiplier();
@@ -168,7 +169,7 @@ public final class PhysicalAttack extends AbstractEffect
// ATTACK CALCULATION 77 * ((pAtk * lvlMod) + power) / pdef            RANGED ATTACK CALCULATION 70 * ((pAtk * lvlMod) + power + patk + power) / pdef // ATTACK CALCULATION 77 * ((pAtk * lvlMod) + power) / pdef            RANGED ATTACK CALCULATION 70 * ((pAtk * lvlMod) + power + patk + power) / pdef
// ```````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^``````````````````````````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ // ```````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^``````````````````````````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
final double baseMod = (weaponMod * ((attack * effector.getLevelMod()) + power + rangedBonus)) / defence; final double baseMod = (weaponMod * ((attack * effector.getLevelMod()) + power + rangedBonus)) / defence;
damage = baseMod * abnormalMod * ssmod * critMod * weaponTraitMod * generalTraitMod * attributeMod * pvpPveMod * randomMod; damage = baseMod * abnormalMod * ssmod * critMod * weaponTraitMod * generalTraitMod * weaknessMod * attributeMod * pvpPveMod * randomMod;
damage *= effector.getStat().getValue(Stats.PHYSICAL_SKILL_POWER, 1); damage *= effector.getStat().getValue(Stats.PHYSICAL_SKILL_POWER, 1);
} }

View File

@@ -101,6 +101,7 @@ public final class PhysicalAttackHpLink extends AbstractEffect
// Trait, elements // Trait, elements
final double weaponTraitMod = Formulas.calcWeaponTraitBonus(effector, effected); final double weaponTraitMod = Formulas.calcWeaponTraitBonus(effector, effected);
final double generalTraitMod = Formulas.calcGeneralTraitBonus(effector, effected, skill.getTraitType(), true); final double generalTraitMod = Formulas.calcGeneralTraitBonus(effector, effected, skill.getTraitType(), true);
final double weaknessMod = Formulas.calcWeaknessBonus(effector, effected, skill.getTraitType());
final double attributeMod = Formulas.calcAttributeBonus(effector, effected, skill); final double attributeMod = Formulas.calcAttributeBonus(effector, effected, skill);
final double pvpPveMod = Formulas.calculatePvpPveBonus(effector, effected, skill, true); final double pvpPveMod = Formulas.calculatePvpPveBonus(effector, effected, skill, true);
final double randomMod = effector.getRandomDamageMultiplier(); final double randomMod = effector.getRandomDamageMultiplier();
@@ -127,7 +128,7 @@ public final class PhysicalAttackHpLink extends AbstractEffect
// ATTACK CALCULATION 77 * ((pAtk * lvlMod) + power) / pdef            RANGED ATTACK CALCULATION 70 * ((pAtk * lvlMod) + power + patk + power) / pdef // ATTACK CALCULATION 77 * ((pAtk * lvlMod) + power) / pdef            RANGED ATTACK CALCULATION 70 * ((pAtk * lvlMod) + power + patk + power) / pdef
// ```````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^``````````````````````````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ // ```````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^``````````````````````````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
final double baseMod = (weaponMod * ((attack * effector.getLevelMod()) + power + rangedBonus)) / defence; final double baseMod = (weaponMod * ((attack * effector.getLevelMod()) + power + rangedBonus)) / defence;
damage = baseMod * ssmod * critMod * weaponTraitMod * generalTraitMod * attributeMod * pvpPveMod * randomMod; damage = baseMod * ssmod * critMod * weaponTraitMod * generalTraitMod * weaknessMod * attributeMod * pvpPveMod * randomMod;
damage *= effector.getStat().getValue(Stats.PHYSICAL_SKILL_POWER, 1); damage *= effector.getStat().getValue(Stats.PHYSICAL_SKILL_POWER, 1);
damage *= -((effector.getCurrentHp() * 2) / effector.getMaxHp()) + 2; damage *= -((effector.getCurrentHp() * 2) / effector.getMaxHp()) + 2;
} }

View File

@@ -114,6 +114,7 @@ public final class PhysicalAttackSaveHp extends AbstractEffect
// Trait, elements // Trait, elements
final double weaponTraitMod = Formulas.calcWeaponTraitBonus(effector, effected); final double weaponTraitMod = Formulas.calcWeaponTraitBonus(effector, effected);
final double generalTraitMod = Formulas.calcGeneralTraitBonus(effector, effected, skill.getTraitType(), true); final double generalTraitMod = Formulas.calcGeneralTraitBonus(effector, effected, skill.getTraitType(), true);
final double weaknessMod = Formulas.calcWeaknessBonus(effector, effected, skill.getTraitType());
final double attributeMod = Formulas.calcAttributeBonus(effector, effected, skill); final double attributeMod = Formulas.calcAttributeBonus(effector, effected, skill);
final double pvpPveMod = Formulas.calculatePvpPveBonus(effector, effected, skill, true); final double pvpPveMod = Formulas.calculatePvpPveBonus(effector, effected, skill, true);
final double randomMod = effector.getRandomDamageMultiplier(); final double randomMod = effector.getRandomDamageMultiplier();
@@ -140,7 +141,7 @@ public final class PhysicalAttackSaveHp extends AbstractEffect
// ATTACK CALCULATION 77 * ((pAtk * lvlMod) + power) / pdef            RANGED ATTACK CALCULATION 70 * ((pAtk * lvlMod) + power + patk + power) / pdef // ATTACK CALCULATION 77 * ((pAtk * lvlMod) + power) / pdef            RANGED ATTACK CALCULATION 70 * ((pAtk * lvlMod) + power + patk + power) / pdef
// ```````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^``````````````````````````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ // ```````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^``````````````````````````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
final double baseMod = (weaponMod * ((attack * effector.getLevelMod()) + power + rangedBonus)) / defence; final double baseMod = (weaponMod * ((attack * effector.getLevelMod()) + power + rangedBonus)) / defence;
damage = baseMod * ssmod * critMod * weaponTraitMod * generalTraitMod * attributeMod * pvpPveMod * randomMod; damage = baseMod * ssmod * critMod * weaponTraitMod * generalTraitMod * weaknessMod * attributeMod * pvpPveMod * randomMod;
damage *= effector.getStat().getValue(Stats.PHYSICAL_SKILL_POWER, 1); damage *= effector.getStat().getValue(Stats.PHYSICAL_SKILL_POWER, 1);
} }

View File

@@ -134,6 +134,7 @@ public final class PhysicalAttackWeaponBonus extends AbstractEffect
// Trait, elements // Trait, elements
final double weaponTraitMod = Formulas.calcWeaponTraitBonus(effector, effected); final double weaponTraitMod = Formulas.calcWeaponTraitBonus(effector, effected);
final double generalTraitMod = Formulas.calcGeneralTraitBonus(effector, effected, skill.getTraitType(), true); final double generalTraitMod = Formulas.calcGeneralTraitBonus(effector, effected, skill.getTraitType(), true);
final double weaknessMod = Formulas.calcWeaknessBonus(effector, effected, skill.getTraitType());
final double attributeMod = Formulas.calcAttributeBonus(effector, effected, skill); final double attributeMod = Formulas.calcAttributeBonus(effector, effected, skill);
final double pvpPveMod = Formulas.calculatePvpPveBonus(effector, effected, skill, true); final double pvpPveMod = Formulas.calculatePvpPveBonus(effector, effected, skill, true);
final double randomMod = effector.getRandomDamageMultiplier(); final double randomMod = effector.getRandomDamageMultiplier();
@@ -161,7 +162,7 @@ public final class PhysicalAttackWeaponBonus extends AbstractEffect
// ATTACK CALCULATION 77 * ((pAtk * lvlMod) + power) / pdef            RANGED ATTACK CALCULATION 70 * ((pAtk * lvlMod) + power + patk + power) / pdef // ATTACK CALCULATION 77 * ((pAtk * lvlMod) + power) / pdef            RANGED ATTACK CALCULATION 70 * ((pAtk * lvlMod) + power + patk + power) / pdef
// ```````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^``````````````````````````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ // ```````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^``````````````````````````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
final double baseMod = (weaponMod * ((attack * effector.getLevelMod()) + power + rangedBonus)) / defence; final double baseMod = (weaponMod * ((attack * effector.getLevelMod()) + power + rangedBonus)) / defence;
damage = baseMod * ssmod * critMod * weaponBonus * weaponTraitMod * generalTraitMod * attributeMod * pvpPveMod * randomMod; damage = baseMod * ssmod * critMod * weaponBonus * weaponTraitMod * generalTraitMod * weaknessMod * attributeMod * pvpPveMod * randomMod;
damage *= effector.getStat().getValue(Stats.PHYSICAL_SKILL_POWER, 1); damage *= effector.getStat().getValue(Stats.PHYSICAL_SKILL_POWER, 1);
} }

View File

@@ -128,6 +128,7 @@ public final class PhysicalSoulAttack extends AbstractEffect
// Trait, elements // Trait, elements
final double weaponTraitMod = Formulas.calcWeaponTraitBonus(effector, effected); final double weaponTraitMod = Formulas.calcWeaponTraitBonus(effector, effected);
final double generalTraitMod = Formulas.calcGeneralTraitBonus(effector, effected, skill.getTraitType(), true); final double generalTraitMod = Formulas.calcGeneralTraitBonus(effector, effected, skill.getTraitType(), true);
final double weaknessMod = Formulas.calcWeaknessBonus(effector, effected, skill.getTraitType());
final double attributeMod = Formulas.calcAttributeBonus(effector, effected, skill); final double attributeMod = Formulas.calcAttributeBonus(effector, effected, skill);
final double pvpPveMod = Formulas.calculatePvpPveBonus(effector, effected, skill, true); final double pvpPveMod = Formulas.calculatePvpPveBonus(effector, effected, skill, true);
final double randomMod = effector.getRandomDamageMultiplier(); final double randomMod = effector.getRandomDamageMultiplier();
@@ -155,7 +156,7 @@ public final class PhysicalSoulAttack extends AbstractEffect
// ATTACK CALCULATION 77 * ((pAtk * lvlMod) + power) / pdef            RANGED ATTACK CALCULATION 70 * ((pAtk * lvlMod) + power + patk + power) / pdef // ATTACK CALCULATION 77 * ((pAtk * lvlMod) + power) / pdef            RANGED ATTACK CALCULATION 70 * ((pAtk * lvlMod) + power + patk + power) / pdef
// ```````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^``````````````````````````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ // ```````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^``````````````````````````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
final double baseMod = (weaponMod * ((attack * effector.getLevelMod()) + power + rangedBonus)) / defence; final double baseMod = (weaponMod * ((attack * effector.getLevelMod()) + power + rangedBonus)) / defence;
damage = baseMod * soulsMod * ssmod * critMod * weaponTraitMod * generalTraitMod * attributeMod * pvpPveMod * randomMod; damage = baseMod * soulsMod * ssmod * critMod * weaponTraitMod * generalTraitMod * weaknessMod * attributeMod * pvpPveMod * randomMod;
damage *= effector.getStat().getValue(Stats.PHYSICAL_SKILL_POWER, 1); damage *= effector.getStat().getValue(Stats.PHYSICAL_SKILL_POWER, 1);
} }

View File

@@ -87,6 +87,11 @@ public class CreatureStat
public CreatureStat(Creature creature) public CreatureStat(Creature creature)
{ {
_creature = creature; _creature = creature;
for (int i = 0; i < TraitType.values().length; i++)
{
_attackTraitValues[i] = 1;
_defenceTraitValues[i] = 1;
}
} }
/** /**
@@ -572,10 +577,35 @@ public class CreatureStat
} }
public void mergeAttackTrait(TraitType traitType, float value) public void mergeAttackTrait(TraitType traitType, float value)
{
_lock.readLock().lock();
try
{ {
_attackTraitValues[traitType.ordinal()] *= value; _attackTraitValues[traitType.ordinal()] *= value;
_attackTraits.add(traitType); _attackTraits.add(traitType);
} }
finally
{
_lock.readLock().unlock();
}
}
public void removeAttackTrait(TraitType traitType, float value)
{
_lock.readLock().lock();
try
{
_attackTraitValues[traitType.ordinal()] /= value;
if (_attackTraitValues[traitType.ordinal()] == 1)
{
_attackTraits.remove(traitType);
}
}
finally
{
_lock.readLock().unlock();
}
}
public float getAttackTrait(TraitType traitType) public float getAttackTrait(TraitType traitType)
{ {
@@ -604,10 +634,35 @@ public class CreatureStat
} }
public void mergeDefenceTrait(TraitType traitType, float value) public void mergeDefenceTrait(TraitType traitType, float value)
{
_lock.readLock().lock();
try
{ {
_defenceTraitValues[traitType.ordinal()] *= value; _defenceTraitValues[traitType.ordinal()] *= value;
_defenceTraits.add(traitType); _defenceTraits.add(traitType);
} }
finally
{
_lock.readLock().unlock();
}
}
public void removeDefenceTrait(TraitType traitType, float value)
{
_lock.readLock().lock();
try
{
_defenceTraitValues[traitType.ordinal()] /= value;
if (_defenceTraitValues[traitType.ordinal()] == 1)
{
_defenceTraits.remove(traitType);
}
}
finally
{
_lock.readLock().unlock();
}
}
public float getDefenceTrait(TraitType traitType) public float getDefenceTrait(TraitType traitType)
{ {
@@ -636,9 +691,30 @@ public class CreatureStat
} }
public void mergeInvulnerableTrait(TraitType traitType) public void mergeInvulnerableTrait(TraitType traitType)
{
_lock.readLock().lock();
try
{ {
_invulnerableTraits.add(traitType); _invulnerableTraits.add(traitType);
} }
finally
{
_lock.readLock().unlock();
}
}
public void removeInvulnerableTrait(TraitType traitType)
{
_lock.readLock().lock();
try
{
_invulnerableTraits.remove(traitType);
}
finally
{
_lock.readLock().unlock();
}
}
public boolean isInvulnerableTrait(TraitType traitType) public boolean isInvulnerableTrait(TraitType traitType)
{ {

View File

@@ -94,14 +94,15 @@ public final class Formulas
} }
// Critical // Critical
final double criticalMod = (attacker.getStat().getValue(Stats.CRITICAL_DAMAGE, 1)); final double criticalMod = attacker.getStat().getValue(Stats.CRITICAL_DAMAGE, 1);
final double criticalPositionMod = attacker.getStat().getPositionTypeValue(Stats.CRITICAL_DAMAGE, Position.getPosition(attacker, target)); final double criticalPositionMod = attacker.getStat().getPositionTypeValue(Stats.CRITICAL_DAMAGE, Position.getPosition(attacker, target));
final double criticalVulnMod = (target.getStat().getValue(Stats.DEFENCE_CRITICAL_DAMAGE, 1)); final double criticalVulnMod = target.getStat().getValue(Stats.DEFENCE_CRITICAL_DAMAGE, 1);
final double criticalAddMod = (attacker.getStat().getValue(Stats.CRITICAL_DAMAGE_ADD, 0)); final double criticalAddMod = attacker.getStat().getValue(Stats.CRITICAL_DAMAGE_ADD, 0);
final double criticalAddVuln = target.getStat().getValue(Stats.DEFENCE_CRITICAL_DAMAGE_ADD, 0); final double criticalAddVuln = target.getStat().getValue(Stats.DEFENCE_CRITICAL_DAMAGE_ADD, 0);
// Trait, elements // Trait, elements
final double weaponTraitMod = calcWeaponTraitBonus(attacker, target); final double weaponTraitMod = calcWeaponTraitBonus(attacker, target);
final double generalTraitMod = calcGeneralTraitBonus(attacker, target, skill.getTraitType(), true); final double generalTraitMod = calcGeneralTraitBonus(attacker, target, skill.getTraitType(), true);
final double weaknessMod = calcWeaknessBonus(attacker, target, skill.getTraitType());
final double attributeMod = calcAttributeBonus(attacker, target, skill); final double attributeMod = calcAttributeBonus(attacker, target, skill);
final double randomMod = attacker.getRandomDamageMultiplier(); final double randomMod = attacker.getRandomDamageMultiplier();
final double pvpPveMod = calculatePvpPveBonus(attacker, target, skill, true); final double pvpPveMod = calculatePvpPveBonus(attacker, target, skill, true);
@@ -122,8 +123,8 @@ public final class Formulas
// ........................_____________________________Initial Damage____________________________...___________Position Additional Damage___________..._CriticalAdd_ // ........................_____________________________Initial Damage____________________________...___________Position Additional Damage___________..._CriticalAdd_
// ATTACK CALCULATION 77 * [(skillpower+patk) * 0.666 * cdbonus * cdPosBonusHalf * cdVulnHalf * ss + isBack0.2Side0.05 * (skillpower+patk*ss) * random + 6 * cd_patk] / pdef // ATTACK CALCULATION 77 * [(skillpower+patk) * 0.666 * cdbonus * cdPosBonusHalf * cdVulnHalf * ss + isBack0.2Side0.05 * (skillpower+patk*ss) * random + 6 * cd_patk] / pdef
// ````````````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^```^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^```^^^^^^^^^^^^ // ````````````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^```^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^```^^^^^^^^^^^^
final double baseMod = ((77 * (((power + attacker.getPAtk()) * 0.666) + (isPosition * (power + attacker.getPAtk()) * randomMod) + (6 * cdPatk))) / defence); final double baseMod = (77 * (((power + attacker.getPAtk()) * 0.666) + (isPosition * (power + attacker.getPAtk()) * randomMod) + (6 * cdPatk))) / defence;
final double damage = baseMod * ssmod * cdMult * weaponTraitMod * generalTraitMod * attributeMod * randomMod * pvpPveMod; final double damage = baseMod * ssmod * cdMult * weaponTraitMod * generalTraitMod * weaknessMod * attributeMod * randomMod * pvpPveMod;
return damage; return damage;
} }
@@ -136,6 +137,7 @@ public final class Formulas
// Trait, elements // Trait, elements
final double generalTraitMod = calcGeneralTraitBonus(attacker, target, skill.getTraitType(), true); final double generalTraitMod = calcGeneralTraitBonus(attacker, target, skill.getTraitType(), true);
final double weaknessMod = calcWeaknessBonus(attacker, target, skill.getTraitType());
final double attributeMod = calcAttributeBonus(attacker, target, skill); final double attributeMod = calcAttributeBonus(attacker, target, skill);
final double randomMod = attacker.getRandomDamageMultiplier(); final double randomMod = attacker.getRandomDamageMultiplier();
final double pvpPveMod = calculatePvpPveBonus(attacker, target, skill, mcrit); final double pvpPveMod = calculatePvpPveBonus(attacker, target, skill, mcrit);
@@ -178,7 +180,7 @@ public final class Formulas
} }
} }
damage = damage * critMod * generalTraitMod * attributeMod * randomMod * pvpPveMod; damage = damage * critMod * generalTraitMod * weaknessMod * attributeMod * randomMod * pvpPveMod;
damage *= attacker.getStat().getValue(Stats.MAGICAL_SKILL_POWER, 1); damage *= attacker.getStat().getValue(Stats.MAGICAL_SKILL_POWER, 1);
return damage; return damage;
@@ -1270,8 +1272,20 @@ public final class Formulas
} }
} }
final double result = (attacker.getStat().getAttackTrait(traitType) - target.getStat().getDefenceTrait(traitType)) + 1.0; return Math.max(attacker.getStat().getAttackTrait(traitType) - target.getStat().getDefenceTrait(traitType), 0.05);
return CommonUtil.constrain(result, 0.05, 2.0); }
public static double calcWeaknessBonus(Creature attacker, Creature target, TraitType traitType)
{
double result = 1;
for (TraitType trait : TraitType.getAllWeakness())
{
if ((traitType != trait) && target.getStat().hasDefenceTrait(trait) && attacker.getStat().hasAttackTrait(trait) && !target.getStat().isInvulnerableTrait(traitType))
{
result *= Math.max(attacker.getStat().getAttackTrait(trait) - target.getStat().getDefenceTrait(trait), 0.05);
}
}
return result;
} }
public static double calcWeaponTraitBonus(Creature attacker, Creature target) public static double calcWeaponTraitBonus(Creature attacker, Creature target)
@@ -1300,7 +1314,7 @@ public final class Formulas
} }
} }
return CommonUtil.constrain((weaponTraitBonus * weaknessBonus), 0.05, 2.0); return Math.max(weaponTraitBonus * weaknessBonus, 0.05);
} }
public static double getBasicPropertyResistBonus(BasicProperty basicProperty, Creature target) public static double getBasicPropertyResistBonus(BasicProperty basicProperty, Creature target)

View File

@@ -16,6 +16,9 @@
*/ */
package org.l2jmobius.gameserver.model.stats; package org.l2jmobius.gameserver.model.stats;
import java.util.ArrayList;
import java.util.List;
/** /**
* @author UnAfraid, NosBit * @author UnAfraid, NosBit
*/ */
@@ -88,6 +91,33 @@ public enum TraitType
SPIRIT_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
private final static List<TraitType> _weaknesses = new ArrayList<>();
static
{
_weaknesses.add(BUG_WEAKNESS);
_weaknesses.add(ANIMAL_WEAKNESS);
_weaknesses.add(PLANT_WEAKNESS);
_weaknesses.add(BEAST_WEAKNESS);
_weaknesses.add(DRAGON_WEAKNESS);
_weaknesses.add(GIANT_WEAKNESS);
_weaknesses.add(CONSTRUCT_WEAKNESS);
_weaknesses.add(VALAKAS);
_weaknesses.add(ANESTHESIA);
_weaknesses.add(DEMONIC_WEAKNESS);
_weaknesses.add(DIVINE_WEAKNESS);
_weaknesses.add(ELEMENTAL_WEAKNESS);
_weaknesses.add(FAIRY_WEAKNESS);
_weaknesses.add(HUMAN_WEAKNESS);
_weaknesses.add(HUMANOID_WEAKNESS);
_weaknesses.add(UNDEAD_WEAKNESS);
_weaknesses.add(EMBRYO_WEAKNESS);
_weaknesses.add(SPIRIT_WEAKNESS);
}
public static List<TraitType> getAllWeakness()
{
return _weaknesses;
}
TraitType(int type) TraitType(int type)
{ {

View File

@@ -23,6 +23,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.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;
@@ -49,11 +50,20 @@ public final class AttackTrait extends AbstractEffect
} }
@Override @Override
public void pump(Creature effected, Skill skill) public void onStart(Creature effector, Creature effected, Skill skill, ItemInstance item)
{ {
for (Entry<TraitType, Float> trait : _attackTraits.entrySet()) for (Entry<TraitType, Float> trait : _attackTraits.entrySet())
{ {
effected.getStat().mergeAttackTrait(trait.getKey(), trait.getValue()); effected.getStat().mergeAttackTrait(trait.getKey(), trait.getValue());
} }
} }
@Override
public void onExit(Creature effector, Creature effected, Skill skill)
{
for (Entry<TraitType, Float> trait : _attackTraits.entrySet())
{
effected.getStat().removeAttackTrait(trait.getKey(), trait.getValue());
}
}
} }

View File

@@ -23,6 +23,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.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;
@@ -49,7 +50,7 @@ public final class DefenceTrait extends AbstractEffect
} }
@Override @Override
public void pump(Creature effected, Skill skill) public void onStart(Creature effector, Creature effected, Skill skill, ItemInstance item)
{ {
for (Entry<TraitType, Float> trait : _defenceTraits.entrySet()) for (Entry<TraitType, Float> trait : _defenceTraits.entrySet())
{ {
@@ -63,4 +64,20 @@ public final class DefenceTrait extends AbstractEffect
} }
} }
} }
@Override
public void onExit(Creature effector, Creature effected, Skill skill)
{
for (Entry<TraitType, Float> trait : _defenceTraits.entrySet())
{
if (trait.getValue() < 2.0f)
{
effected.getStat().removeDefenceTrait(trait.getKey(), trait.getValue());
}
else
{
effected.getStat().removeInvulnerableTrait(trait.getKey());
}
}
}
} }

View File

@@ -125,6 +125,7 @@ public final class EnergyAttack extends AbstractEffect
// Trait, elements // Trait, elements
final double weaponTraitMod = Formulas.calcWeaponTraitBonus(attacker, effected); final double weaponTraitMod = Formulas.calcWeaponTraitBonus(attacker, effected);
final double generalTraitMod = Formulas.calcGeneralTraitBonus(attacker, effected, skill.getTraitType(), true); final double generalTraitMod = Formulas.calcGeneralTraitBonus(attacker, effected, skill.getTraitType(), true);
final double weaknessMod = Formulas.calcWeaknessBonus(attacker, effected, skill.getTraitType());
final double attributeMod = Formulas.calcAttributeBonus(attacker, effected, skill); final double attributeMod = Formulas.calcAttributeBonus(attacker, effected, skill);
final double pvpPveMod = Formulas.calculatePvpPveBonus(attacker, effected, skill, true); final double pvpPveMod = Formulas.calculatePvpPveBonus(attacker, effected, skill, true);
@@ -148,7 +149,7 @@ public final class EnergyAttack extends AbstractEffect
// ATTACK CALCULATION ((77 * ((pAtk * lvlMod) + power) * (1 + (0.1 * chargesConsumed)) / pdef) * skillPower) + skillPowerAdd // ATTACK CALCULATION ((77 * ((pAtk * lvlMod) + power) * (1 + (0.1 * chargesConsumed)) / pdef) * skillPower) + skillPowerAdd
// ```````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^```^^^^^^^^^^^^^^^^^^^^^^^^^^^^^```^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ // ```````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^```^^^^^^^^^^^^^^^^^^^^^^^^^^^^^```^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
final double baseMod = (77 * ((attacker.getPAtk() * attacker.getLevelMod()) + _power + effector.getStat().getValue(Stats.SKILL_POWER_ADD, 0))) / defence; final double baseMod = (77 * ((attacker.getPAtk() * attacker.getLevelMod()) + _power + effector.getStat().getValue(Stats.SKILL_POWER_ADD, 0))) / defence;
damage = baseMod * ssmod * critMod * weaponTraitMod * generalTraitMod * attributeMod * energyChargesBoost * pvpPveMod; damage = baseMod * ssmod * critMod * weaponTraitMod * generalTraitMod * weaknessMod * attributeMod * energyChargesBoost * pvpPveMod;
} }
damage = Math.max(0, damage * effector.getStat().getValue(Stats.PHYSICAL_SKILL_POWER, 1)); damage = Math.max(0, damage * effector.getStat().getValue(Stats.PHYSICAL_SKILL_POWER, 1));

View File

@@ -141,6 +141,7 @@ public final class PhysicalAttack extends AbstractEffect
// Trait, elements // Trait, elements
final double weaponTraitMod = Formulas.calcWeaponTraitBonus(effector, effected); final double weaponTraitMod = Formulas.calcWeaponTraitBonus(effector, effected);
final double generalTraitMod = Formulas.calcGeneralTraitBonus(effector, effected, skill.getTraitType(), true); final double generalTraitMod = Formulas.calcGeneralTraitBonus(effector, effected, skill.getTraitType(), true);
final double weaknessMod = Formulas.calcWeaknessBonus(effector, effected, skill.getTraitType());
final double attributeMod = Formulas.calcAttributeBonus(effector, effected, skill); final double attributeMod = Formulas.calcAttributeBonus(effector, effected, skill);
final double pvpPveMod = Formulas.calculatePvpPveBonus(effector, effected, skill, true); final double pvpPveMod = Formulas.calculatePvpPveBonus(effector, effected, skill, true);
final double randomMod = effector.getRandomDamageMultiplier(); final double randomMod = effector.getRandomDamageMultiplier();
@@ -168,7 +169,7 @@ public final class PhysicalAttack extends AbstractEffect
// ATTACK CALCULATION 77 * ((pAtk * lvlMod) + power) / pdef            RANGED ATTACK CALCULATION 70 * ((pAtk * lvlMod) + power + patk + power) / pdef // ATTACK CALCULATION 77 * ((pAtk * lvlMod) + power) / pdef            RANGED ATTACK CALCULATION 70 * ((pAtk * lvlMod) + power + patk + power) / pdef
// ```````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^``````````````````````````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ // ```````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^``````````````````````````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
final double baseMod = (weaponMod * ((attack * effector.getLevelMod()) + power + rangedBonus)) / defence; final double baseMod = (weaponMod * ((attack * effector.getLevelMod()) + power + rangedBonus)) / defence;
damage = baseMod * abnormalMod * ssmod * critMod * weaponTraitMod * generalTraitMod * attributeMod * pvpPveMod * randomMod; damage = baseMod * abnormalMod * ssmod * critMod * weaponTraitMod * generalTraitMod * weaknessMod * attributeMod * pvpPveMod * randomMod;
damage *= effector.getStat().getValue(Stats.PHYSICAL_SKILL_POWER, 1); damage *= effector.getStat().getValue(Stats.PHYSICAL_SKILL_POWER, 1);
} }

View File

@@ -101,6 +101,7 @@ public final class PhysicalAttackHpLink extends AbstractEffect
// Trait, elements // Trait, elements
final double weaponTraitMod = Formulas.calcWeaponTraitBonus(effector, effected); final double weaponTraitMod = Formulas.calcWeaponTraitBonus(effector, effected);
final double generalTraitMod = Formulas.calcGeneralTraitBonus(effector, effected, skill.getTraitType(), true); final double generalTraitMod = Formulas.calcGeneralTraitBonus(effector, effected, skill.getTraitType(), true);
final double weaknessMod = Formulas.calcWeaknessBonus(effector, effected, skill.getTraitType());
final double attributeMod = Formulas.calcAttributeBonus(effector, effected, skill); final double attributeMod = Formulas.calcAttributeBonus(effector, effected, skill);
final double pvpPveMod = Formulas.calculatePvpPveBonus(effector, effected, skill, true); final double pvpPveMod = Formulas.calculatePvpPveBonus(effector, effected, skill, true);
final double randomMod = effector.getRandomDamageMultiplier(); final double randomMod = effector.getRandomDamageMultiplier();
@@ -127,7 +128,7 @@ public final class PhysicalAttackHpLink extends AbstractEffect
// ATTACK CALCULATION 77 * ((pAtk * lvlMod) + power) / pdef            RANGED ATTACK CALCULATION 70 * ((pAtk * lvlMod) + power + patk + power) / pdef // ATTACK CALCULATION 77 * ((pAtk * lvlMod) + power) / pdef            RANGED ATTACK CALCULATION 70 * ((pAtk * lvlMod) + power + patk + power) / pdef
// ```````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^``````````````````````````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ // ```````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^``````````````````````````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
final double baseMod = (weaponMod * ((attack * effector.getLevelMod()) + power + rangedBonus)) / defence; final double baseMod = (weaponMod * ((attack * effector.getLevelMod()) + power + rangedBonus)) / defence;
damage = baseMod * ssmod * critMod * weaponTraitMod * generalTraitMod * attributeMod * pvpPveMod * randomMod; damage = baseMod * ssmod * critMod * weaponTraitMod * generalTraitMod * weaknessMod * attributeMod * pvpPveMod * randomMod;
damage *= effector.getStat().getValue(Stats.PHYSICAL_SKILL_POWER, 1); damage *= effector.getStat().getValue(Stats.PHYSICAL_SKILL_POWER, 1);
damage *= -((effector.getCurrentHp() * 2) / effector.getMaxHp()) + 2; damage *= -((effector.getCurrentHp() * 2) / effector.getMaxHp()) + 2;
} }

View File

@@ -114,6 +114,7 @@ public final class PhysicalAttackSaveHp extends AbstractEffect
// Trait, elements // Trait, elements
final double weaponTraitMod = Formulas.calcWeaponTraitBonus(effector, effected); final double weaponTraitMod = Formulas.calcWeaponTraitBonus(effector, effected);
final double generalTraitMod = Formulas.calcGeneralTraitBonus(effector, effected, skill.getTraitType(), true); final double generalTraitMod = Formulas.calcGeneralTraitBonus(effector, effected, skill.getTraitType(), true);
final double weaknessMod = Formulas.calcWeaknessBonus(effector, effected, skill.getTraitType());
final double attributeMod = Formulas.calcAttributeBonus(effector, effected, skill); final double attributeMod = Formulas.calcAttributeBonus(effector, effected, skill);
final double pvpPveMod = Formulas.calculatePvpPveBonus(effector, effected, skill, true); final double pvpPveMod = Formulas.calculatePvpPveBonus(effector, effected, skill, true);
final double randomMod = effector.getRandomDamageMultiplier(); final double randomMod = effector.getRandomDamageMultiplier();
@@ -140,7 +141,7 @@ public final class PhysicalAttackSaveHp extends AbstractEffect
// ATTACK CALCULATION 77 * ((pAtk * lvlMod) + power) / pdef            RANGED ATTACK CALCULATION 70 * ((pAtk * lvlMod) + power + patk + power) / pdef // ATTACK CALCULATION 77 * ((pAtk * lvlMod) + power) / pdef            RANGED ATTACK CALCULATION 70 * ((pAtk * lvlMod) + power + patk + power) / pdef
// ```````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^``````````````````````````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ // ```````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^``````````````````````````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
final double baseMod = (weaponMod * ((attack * effector.getLevelMod()) + power + rangedBonus)) / defence; final double baseMod = (weaponMod * ((attack * effector.getLevelMod()) + power + rangedBonus)) / defence;
damage = baseMod * ssmod * critMod * weaponTraitMod * generalTraitMod * attributeMod * pvpPveMod * randomMod; damage = baseMod * ssmod * critMod * weaponTraitMod * generalTraitMod * weaknessMod * attributeMod * pvpPveMod * randomMod;
damage *= effector.getStat().getValue(Stats.PHYSICAL_SKILL_POWER, 1); damage *= effector.getStat().getValue(Stats.PHYSICAL_SKILL_POWER, 1);
} }

View File

@@ -134,6 +134,7 @@ public final class PhysicalAttackWeaponBonus extends AbstractEffect
// Trait, elements // Trait, elements
final double weaponTraitMod = Formulas.calcWeaponTraitBonus(effector, effected); final double weaponTraitMod = Formulas.calcWeaponTraitBonus(effector, effected);
final double generalTraitMod = Formulas.calcGeneralTraitBonus(effector, effected, skill.getTraitType(), true); final double generalTraitMod = Formulas.calcGeneralTraitBonus(effector, effected, skill.getTraitType(), true);
final double weaknessMod = Formulas.calcWeaknessBonus(effector, effected, skill.getTraitType());
final double attributeMod = Formulas.calcAttributeBonus(effector, effected, skill); final double attributeMod = Formulas.calcAttributeBonus(effector, effected, skill);
final double pvpPveMod = Formulas.calculatePvpPveBonus(effector, effected, skill, true); final double pvpPveMod = Formulas.calculatePvpPveBonus(effector, effected, skill, true);
final double randomMod = effector.getRandomDamageMultiplier(); final double randomMod = effector.getRandomDamageMultiplier();
@@ -161,7 +162,7 @@ public final class PhysicalAttackWeaponBonus extends AbstractEffect
// ATTACK CALCULATION 77 * ((pAtk * lvlMod) + power) / pdef            RANGED ATTACK CALCULATION 70 * ((pAtk * lvlMod) + power + patk + power) / pdef // ATTACK CALCULATION 77 * ((pAtk * lvlMod) + power) / pdef            RANGED ATTACK CALCULATION 70 * ((pAtk * lvlMod) + power + patk + power) / pdef
// ```````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^``````````````````````````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ // ```````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^``````````````````````````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
final double baseMod = (weaponMod * ((attack * effector.getLevelMod()) + power + rangedBonus)) / defence; final double baseMod = (weaponMod * ((attack * effector.getLevelMod()) + power + rangedBonus)) / defence;
damage = baseMod * ssmod * critMod * weaponBonus * weaponTraitMod * generalTraitMod * attributeMod * pvpPveMod * randomMod; damage = baseMod * ssmod * critMod * weaponBonus * weaponTraitMod * generalTraitMod * weaknessMod * attributeMod * pvpPveMod * randomMod;
damage *= effector.getStat().getValue(Stats.PHYSICAL_SKILL_POWER, 1); damage *= effector.getStat().getValue(Stats.PHYSICAL_SKILL_POWER, 1);
} }

View File

@@ -128,6 +128,7 @@ public final class PhysicalSoulAttack extends AbstractEffect
// Trait, elements // Trait, elements
final double weaponTraitMod = Formulas.calcWeaponTraitBonus(effector, effected); final double weaponTraitMod = Formulas.calcWeaponTraitBonus(effector, effected);
final double generalTraitMod = Formulas.calcGeneralTraitBonus(effector, effected, skill.getTraitType(), true); final double generalTraitMod = Formulas.calcGeneralTraitBonus(effector, effected, skill.getTraitType(), true);
final double weaknessMod = Formulas.calcWeaknessBonus(effector, effected, skill.getTraitType());
final double attributeMod = Formulas.calcAttributeBonus(effector, effected, skill); final double attributeMod = Formulas.calcAttributeBonus(effector, effected, skill);
final double pvpPveMod = Formulas.calculatePvpPveBonus(effector, effected, skill, true); final double pvpPveMod = Formulas.calculatePvpPveBonus(effector, effected, skill, true);
final double randomMod = effector.getRandomDamageMultiplier(); final double randomMod = effector.getRandomDamageMultiplier();
@@ -155,7 +156,7 @@ public final class PhysicalSoulAttack extends AbstractEffect
// ATTACK CALCULATION 77 * ((pAtk * lvlMod) + power) / pdef            RANGED ATTACK CALCULATION 70 * ((pAtk * lvlMod) + power + patk + power) / pdef // ATTACK CALCULATION 77 * ((pAtk * lvlMod) + power) / pdef            RANGED ATTACK CALCULATION 70 * ((pAtk * lvlMod) + power + patk + power) / pdef
// ```````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^``````````````````````````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ // ```````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^``````````````````````````````````````^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
final double baseMod = (weaponMod * ((attack * effector.getLevelMod()) + power + rangedBonus)) / defence; final double baseMod = (weaponMod * ((attack * effector.getLevelMod()) + power + rangedBonus)) / defence;
damage = baseMod * soulsMod * ssmod * critMod * weaponTraitMod * generalTraitMod * attributeMod * pvpPveMod * randomMod; damage = baseMod * soulsMod * ssmod * critMod * weaponTraitMod * generalTraitMod * weaknessMod * attributeMod * pvpPveMod * randomMod;
damage *= effector.getStat().getValue(Stats.PHYSICAL_SKILL_POWER, 1); damage *= effector.getStat().getValue(Stats.PHYSICAL_SKILL_POWER, 1);
} }

View File

@@ -87,6 +87,11 @@ public class CreatureStat
public CreatureStat(Creature creature) public CreatureStat(Creature creature)
{ {
_creature = creature; _creature = creature;
for (int i = 0; i < TraitType.values().length; i++)
{
_attackTraitValues[i] = 1;
_defenceTraitValues[i] = 1;
}
} }
/** /**
@@ -572,10 +577,35 @@ public class CreatureStat
} }
public void mergeAttackTrait(TraitType traitType, float value) public void mergeAttackTrait(TraitType traitType, float value)
{
_lock.readLock().lock();
try
{ {
_attackTraitValues[traitType.ordinal()] *= value; _attackTraitValues[traitType.ordinal()] *= value;
_attackTraits.add(traitType); _attackTraits.add(traitType);
} }
finally
{
_lock.readLock().unlock();
}
}
public void removeAttackTrait(TraitType traitType, float value)
{
_lock.readLock().lock();
try
{
_attackTraitValues[traitType.ordinal()] /= value;
if (_attackTraitValues[traitType.ordinal()] == 1)
{
_attackTraits.remove(traitType);
}
}
finally
{
_lock.readLock().unlock();
}
}
public float getAttackTrait(TraitType traitType) public float getAttackTrait(TraitType traitType)
{ {
@@ -604,10 +634,35 @@ public class CreatureStat
} }
public void mergeDefenceTrait(TraitType traitType, float value) public void mergeDefenceTrait(TraitType traitType, float value)
{
_lock.readLock().lock();
try
{ {
_defenceTraitValues[traitType.ordinal()] *= value; _defenceTraitValues[traitType.ordinal()] *= value;
_defenceTraits.add(traitType); _defenceTraits.add(traitType);
} }
finally
{
_lock.readLock().unlock();
}
}
public void removeDefenceTrait(TraitType traitType, float value)
{
_lock.readLock().lock();
try
{
_defenceTraitValues[traitType.ordinal()] /= value;
if (_defenceTraitValues[traitType.ordinal()] == 1)
{
_defenceTraits.remove(traitType);
}
}
finally
{
_lock.readLock().unlock();
}
}
public float getDefenceTrait(TraitType traitType) public float getDefenceTrait(TraitType traitType)
{ {
@@ -636,9 +691,30 @@ public class CreatureStat
} }
public void mergeInvulnerableTrait(TraitType traitType) public void mergeInvulnerableTrait(TraitType traitType)
{
_lock.readLock().lock();
try
{ {
_invulnerableTraits.add(traitType); _invulnerableTraits.add(traitType);
} }
finally
{
_lock.readLock().unlock();
}
}
public void removeInvulnerableTrait(TraitType traitType)
{
_lock.readLock().lock();
try
{
_invulnerableTraits.remove(traitType);
}
finally
{
_lock.readLock().unlock();
}
}
public boolean isInvulnerableTrait(TraitType traitType) public boolean isInvulnerableTrait(TraitType traitType)
{ {

Some files were not shown because too many files have changed in this diff Show More