Various stat tweaks.

This commit is contained in:
MobiusDev
2018-02-15 20:22:57 +00:00
parent 74abc9ebec
commit c56603b7e3
64 changed files with 300 additions and 220 deletions

View File

@@ -41,11 +41,6 @@ public class MonsterRace
_second = new int[2];
}
public static MonsterRace getInstance()
{
return SingletonHolder._instance;
}
public void newRace()
{
int random = 0;
@@ -143,6 +138,11 @@ public class MonsterRace
return _second[0];
}
public static MonsterRace getInstance()
{
return SingletonHolder._instance;
}
private static class SingletonHolder
{
protected static final MonsterRace _instance = new MonsterRace();

View File

@@ -57,11 +57,6 @@ public class CharStat
private long _exp = 0;
private long _sp = 0;
private byte _level = 1;
private final float[] _attackTraits = new float[TraitType.values().length];
private final int[] _attackTraitsCount = new int[TraitType.values().length];
private final float[] _defenceTraits = new float[TraitType.values().length];
private final int[] _defenceTraitsCount = new int[TraitType.values().length];
private final int[] _traitsInvul = new int[TraitType.values().length];
/** Creature's maximum buff count. */
private int _maxBuffCount = Config.BUFFS_MAX_AMOUNT;
private double _vampiricSum = 0;
@@ -77,6 +72,12 @@ public class CharStat
private final Deque<StatsHolder> _additionalMul = new ConcurrentLinkedDeque<>();
private final Map<Stats, Double> _fixedValue = new ConcurrentHashMap<>();
private final float[] _attackTraits = new float[TraitType.values().length];
private final float[] _defenceTraits = new float[TraitType.values().length];
private final int[] _attackTraitsCount = new int[TraitType.values().length];
private final int[] _defenceTraitsCount = new int[TraitType.values().length];
private final int[] _traitsInvul = new int[TraitType.values().length];
/** Values to be recalculated after every stat update */
private double _attackSpeedMultiplier = 1;
private double _mAttackSpeedMultiplier = 1;

View File

@@ -18,7 +18,6 @@ package com.l2jmobius.gameserver.model.stats;
import java.io.File;
import java.util.NoSuchElementException;
import java.util.Optional;
import java.util.logging.Logger;
import org.w3c.dom.Document;
@@ -61,7 +60,8 @@ public enum BaseStats
{
if ((creature != null) && (_stat != null))
{
return (int) Math.min(_stat.finalize(creature, Optional.empty()), MAX_STAT_VALUE - 1);
// return (int) Math.min(_stat.finalize(creature, Optional.empty()), MAX_STAT_VALUE - 1);
return (int) creature.getStat().getValue(_stat);
}
return 0;
}

View File

@@ -105,7 +105,7 @@ public final class Formulas
final double criticalAddVuln = target.getStat().getValue(Stats.DEFENCE_CRITICAL_DAMAGE_ADD, 0);
// Trait, elements
final double weaponTraitMod = calcWeaponTraitBonus(attacker, target);
final double generalTraitMod = calcGeneralTraitBonus(attacker, target, skill.getTraitType(), false);
final double generalTraitMod = calcGeneralTraitBonus(attacker, target, skill.getTraitType(), true);
final double attributeMod = calcAttributeBonus(attacker, target, skill);
final double randomMod = attacker.getRandomDamageMultiplier();
final double pvpPveMod = calculatePvpPveBonus(attacker, target, skill, true);
@@ -138,7 +138,7 @@ public final class Formulas
final double critMod = mcrit ? (2 * calcCritDamage(attacker, target, skill)) : 1; // TODO not really a proper way... find how it works then implement. // damage += attacker.getStat().getValue(Stats.MAGIC_CRIT_DMG_ADD, 0);
// Trait, elements
final double generalTraitMod = calcGeneralTraitBonus(attacker, target, skill.getTraitType(), false);
final double generalTraitMod = calcGeneralTraitBonus(attacker, target, skill.getTraitType(), true);
final double attributeMod = calcAttributeBonus(attacker, target, skill);
final double randomMod = attacker.getRandomDamageMultiplier();
final double pvpPveMod = calculatePvpPveBonus(attacker, target, skill, mcrit);
@@ -687,7 +687,7 @@ public final class Formulas
final double elementMod = calcAttributeBonus(attacker, target, skill);
final double traitMod = calcGeneralTraitBonus(attacker, target, skill.getTraitType(), false);
final double basicPropertyResist = getBasicPropertyResistBonus(skill.getBasicProperty(), target);
final double buffDebuffMod = skill.isDebuff() ? target.getStat().getValue(Stats.RESIST_ABNORMAL_DEBUFF, 1) : 0;
final double buffDebuffMod = skill.isDebuff() ? target.getStat().getValue(Stats.RESIST_ABNORMAL_DEBUFF, 1) : 1;
final double rate = baseMod * elementMod * traitMod * buffDebuffMod;
final double finalRate = traitMod > 0 ? CommonUtil.constrain(rate, skill.getMinChance(), skill.getMaxChance()) * basicPropertyResist : 0;
@@ -977,7 +977,7 @@ public final class Formulas
double counterdmg = ((target.getPAtk() * 873) / attacker.getPDef()); // Old: (((target.getPAtk(attacker) * 10.0) * 70.0) / attacker.getPDef(target));
counterdmg *= calcWeaponTraitBonus(attacker, target);
counterdmg *= calcGeneralTraitBonus(attacker, target, skill.getTraitType(), false);
counterdmg *= calcGeneralTraitBonus(attacker, target, skill.getTraitType(), true);
counterdmg *= calcAttributeBonus(attacker, target, skill);
attacker.reduceCurrentHp(counterdmg, target, skill);
@@ -1145,6 +1145,12 @@ public final class Formulas
*/
public static boolean calcProbability(double baseChance, L2Character attacker, L2Character target, Skill skill)
{
// Skills without set probability should only test against trait invulnerability.
if (Double.isNaN(baseChance))
{
return calcGeneralTraitBonus(attacker, target, skill.getTraitType(), true) > 0;
}
// Outdated formula: return Rnd.get(100) < ((((((skill.getMagicLevel() + baseChance) - target.getLevel()) + 30) - target.getINT()) * calcAttributeBonus(attacker, target, skill)) * calcGeneralTraitBonus(attacker, target, skill.getTraitType(), false));
// TODO: Find more retail-like formula
return Rnd.get(100) < (((((skill.getMagicLevel() + baseChance) - target.getLevel()) - getAbnormalResist(skill.getBasicProperty(), target)) * calcAttributeBonus(attacker, target, skill)) * calcGeneralTraitBonus(attacker, target, skill.getTraitType(), false));

View File

@@ -22,6 +22,7 @@ import com.l2jmobius.Config;
import com.l2jmobius.gameserver.model.PcCondOverride;
import com.l2jmobius.gameserver.model.actor.L2Character;
import com.l2jmobius.gameserver.model.actor.instance.L2PetInstance;
import com.l2jmobius.gameserver.model.actor.transform.TransformType;
import com.l2jmobius.gameserver.model.itemcontainer.Inventory;
import com.l2jmobius.gameserver.model.items.L2Item;
import com.l2jmobius.gameserver.model.items.instance.L2ItemInstance;
@@ -63,24 +64,20 @@ public interface IStatsFunction
default double calcWeaponBaseValue(L2Character creature, Stats stat)
{
final double baseTemplateValue = creature.getTemplate().getBaseValue(stat, 0);
final double baseValue = creature.getTransformation().filter(transform -> !transform.isStance()).map(transform -> transform.getStats(creature, stat, baseTemplateValue)).orElseGet(() ->
{
double baseValue = creature.getTransformation().map(transform -> transform.getStats(creature, stat, baseTemplateValue)).orElse(baseTemplateValue);
if (creature.isPet())
{
final L2PetInstance pet = (L2PetInstance) creature;
final L2ItemInstance weapon = pet.getActiveWeaponInstance();
final double baseVal = stat == Stats.PHYSICAL_ATTACK ? pet.getPetLevelData().getPetPAtk() : stat == Stats.MAGIC_ATTACK ? pet.getPetLevelData().getPetMAtk() : baseTemplateValue;
return baseVal + (weapon != null ? weapon.getItem().getStats(stat, baseVal) : 0);
baseValue = baseVal + (weapon != null ? weapon.getItem().getStats(stat, baseVal) : 0);
}
else if (creature.isPlayer())
else if (creature.isPlayer() && (!creature.isTransformed() || (creature.getTransformation().get().getType() == TransformType.COMBAT) || (creature.getTransformation().get().getType() == TransformType.MODE_CHANGE)))
{
final L2ItemInstance weapon = creature.getActiveWeaponInstance();
return (weapon != null ? weapon.getItem().getStats(stat, baseTemplateValue) : baseTemplateValue);
baseValue = (weapon != null ? weapon.getItem().getStats(stat, baseTemplateValue) : baseTemplateValue);
}
return baseTemplateValue;
});
return baseValue;
}

View File

@@ -43,6 +43,13 @@ public class MAttackSpeedFinalizer implements IStatsFunction
final double chaBonus = creature.isPlayer() ? BaseStats.CHA.calcBonus(creature) : 1.;
final double witBonus = creature.getWIT() > 0 ? BaseStats.WIT.calcBonus(creature) : 1.;
baseValue *= witBonus * chaBonus;
return validateValue(creature, Stats.defaultValue(creature, stat, baseValue), 1, Config.MAX_MATK_SPEED);
return validateValue(creature, defaultValue(creature, stat, baseValue), 1, Config.MAX_MATK_SPEED);
}
private double defaultValue(L2Character creature, Stats stat, double baseValue)
{
final double mul = Math.max(creature.getStat().getMul(stat), 0.7);
final double add = creature.getStat().getAdd(stat);
return (baseValue * mul) + add + creature.getStat().getMoveTypeValue(stat, creature.getMoveType());
}
}

View File

@@ -82,5 +82,4 @@ public class PAccuracyFinalizer implements IStatsFunction
return (0.2 * Math.max(enchantLevel - 3, 0)) + (0.2 * Math.max(enchantLevel - 6, 0));
}
}

View File

@@ -41,6 +41,13 @@ public class PAttackSpeedFinalizer implements IStatsFunction
final double chaBonus = creature.isPlayer() ? BaseStats.CHA.calcBonus(creature) : 1.;
final double dexBonus = creature.getDEX() > 0 ? BaseStats.DEX.calcBonus(creature) : 1.;
baseValue *= dexBonus * chaBonus;
return validateValue(creature, Stats.defaultValue(creature, stat, baseValue), 1, Config.MAX_PATK_SPEED);
return validateValue(creature, defaultValue(creature, stat, baseValue), 1, Config.MAX_PATK_SPEED);
}
private double defaultValue(L2Character creature, Stats stat, double baseValue)
{
final double mul = Math.max(creature.getStat().getMul(stat), 0.7);
final double add = creature.getStat().getAdd(stat);
return (baseValue * mul) + add + creature.getStat().getMoveTypeValue(stat, creature.getMoveType());
}
}

View File

@@ -78,14 +78,17 @@ public class PDefenseFinalizer implements IStatsFunction
baseValue -= creature.getTransformation().map(transform -> transform.getBaseDefBySlot(player, slot)).orElse(defaultStatValue);
}
}
}
baseValue *= BaseStats.CHA.calcBonus(creature);
}
}
if (creature.isRaid())
{
baseValue *= Config.RAID_PDEFENCE_MULTIPLIER;
}
if (creature.getLevel() > 0)
{
baseValue *= creature.getLevelMod();
}
return defaultValue(creature, stat, baseValue);
}

View File

@@ -32,7 +32,6 @@ public class PRangeFinalizer implements IStatsFunction
{
throwIfPresent(base);
final double baseValue = calcWeaponBaseValue(creature, stat);
return Stats.defaultValue(creature, stat, baseValue);
return Stats.defaultValue(creature, stat, calcWeaponBaseValue(creature, stat));
}
}

View File

@@ -32,7 +32,6 @@ public class RandomDamageFinalizer implements IStatsFunction
{
throwIfPresent(base);
final double baseValue = calcWeaponBaseValue(creature, stat);
return Stats.defaultValue(creature, stat, baseValue);
return Stats.defaultValue(creature, stat, calcWeaponBaseValue(creature, stat));
}
}

View File

@@ -32,7 +32,6 @@ public class ShieldDefenceFinalizer implements IStatsFunction
{
throwIfPresent(base);
final double baseValue = calcWeaponPlusBaseValue(creature, stat);
return Stats.defaultValue(creature, stat, baseValue);
return Stats.defaultValue(creature, stat, calcWeaponPlusBaseValue(creature, stat));
}
}

View File

@@ -32,7 +32,6 @@ public class ShieldDefenceRateFinalizer implements IStatsFunction
{
throwIfPresent(base);
final double baseValue = calcWeaponPlusBaseValue(creature, stat);
return Stats.defaultValue(creature, stat, baseValue);
return Stats.defaultValue(creature, stat, calcWeaponPlusBaseValue(creature, stat));
}
}

View File

@@ -41,11 +41,6 @@ public class MonsterRace
_second = new int[2];
}
public static MonsterRace getInstance()
{
return SingletonHolder._instance;
}
public void newRace()
{
int random = 0;
@@ -143,6 +138,11 @@ public class MonsterRace
return _second[0];
}
public static MonsterRace getInstance()
{
return SingletonHolder._instance;
}
private static class SingletonHolder
{
protected static final MonsterRace _instance = new MonsterRace();

View File

@@ -57,11 +57,6 @@ public class CharStat
private long _exp = 0;
private long _sp = 0;
private byte _level = 1;
private final float[] _attackTraits = new float[TraitType.values().length];
private final int[] _attackTraitsCount = new int[TraitType.values().length];
private final float[] _defenceTraits = new float[TraitType.values().length];
private final int[] _defenceTraitsCount = new int[TraitType.values().length];
private final int[] _traitsInvul = new int[TraitType.values().length];
/** Creature's maximum buff count. */
private int _maxBuffCount = Config.BUFFS_MAX_AMOUNT;
private double _vampiricSum = 0;
@@ -77,6 +72,12 @@ public class CharStat
private final Deque<StatsHolder> _additionalMul = new ConcurrentLinkedDeque<>();
private final Map<Stats, Double> _fixedValue = new ConcurrentHashMap<>();
private final float[] _attackTraits = new float[TraitType.values().length];
private final float[] _defenceTraits = new float[TraitType.values().length];
private final int[] _attackTraitsCount = new int[TraitType.values().length];
private final int[] _defenceTraitsCount = new int[TraitType.values().length];
private final int[] _traitsInvul = new int[TraitType.values().length];
/** Values to be recalculated after every stat update */
private double _attackSpeedMultiplier = 1;
private double _mAttackSpeedMultiplier = 1;

View File

@@ -18,7 +18,6 @@ package com.l2jmobius.gameserver.model.stats;
import java.io.File;
import java.util.NoSuchElementException;
import java.util.Optional;
import java.util.logging.Logger;
import org.w3c.dom.Document;
@@ -61,7 +60,8 @@ public enum BaseStats
{
if ((creature != null) && (_stat != null))
{
return (int) Math.min(_stat.finalize(creature, Optional.empty()), MAX_STAT_VALUE - 1);
// return (int) Math.min(_stat.finalize(creature, Optional.empty()), MAX_STAT_VALUE - 1);
return (int) creature.getStat().getValue(_stat);
}
return 0;
}

View File

@@ -105,7 +105,7 @@ public final class Formulas
final double criticalAddVuln = target.getStat().getValue(Stats.DEFENCE_CRITICAL_DAMAGE_ADD, 0);
// Trait, elements
final double weaponTraitMod = calcWeaponTraitBonus(attacker, target);
final double generalTraitMod = calcGeneralTraitBonus(attacker, target, skill.getTraitType(), false);
final double generalTraitMod = calcGeneralTraitBonus(attacker, target, skill.getTraitType(), true);
final double attributeMod = calcAttributeBonus(attacker, target, skill);
final double randomMod = attacker.getRandomDamageMultiplier();
final double pvpPveMod = calculatePvpPveBonus(attacker, target, skill, true);
@@ -138,7 +138,7 @@ public final class Formulas
final double critMod = mcrit ? (2 * calcCritDamage(attacker, target, skill)) : 1; // TODO not really a proper way... find how it works then implement. // damage += attacker.getStat().getValue(Stats.MAGIC_CRIT_DMG_ADD, 0);
// Trait, elements
final double generalTraitMod = calcGeneralTraitBonus(attacker, target, skill.getTraitType(), false);
final double generalTraitMod = calcGeneralTraitBonus(attacker, target, skill.getTraitType(), true);
final double attributeMod = calcAttributeBonus(attacker, target, skill);
final double randomMod = attacker.getRandomDamageMultiplier();
final double pvpPveMod = calculatePvpPveBonus(attacker, target, skill, mcrit);
@@ -687,7 +687,7 @@ public final class Formulas
final double elementMod = calcAttributeBonus(attacker, target, skill);
final double traitMod = calcGeneralTraitBonus(attacker, target, skill.getTraitType(), false);
final double basicPropertyResist = getBasicPropertyResistBonus(skill.getBasicProperty(), target);
final double buffDebuffMod = skill.isDebuff() ? target.getStat().getValue(Stats.RESIST_ABNORMAL_DEBUFF, 1) : 0;
final double buffDebuffMod = skill.isDebuff() ? target.getStat().getValue(Stats.RESIST_ABNORMAL_DEBUFF, 1) : 1;
final double rate = baseMod * elementMod * traitMod * buffDebuffMod;
final double finalRate = traitMod > 0 ? CommonUtil.constrain(rate, skill.getMinChance(), skill.getMaxChance()) * basicPropertyResist : 0;
@@ -977,7 +977,7 @@ public final class Formulas
double counterdmg = ((target.getPAtk() * 873) / attacker.getPDef()); // Old: (((target.getPAtk(attacker) * 10.0) * 70.0) / attacker.getPDef(target));
counterdmg *= calcWeaponTraitBonus(attacker, target);
counterdmg *= calcGeneralTraitBonus(attacker, target, skill.getTraitType(), false);
counterdmg *= calcGeneralTraitBonus(attacker, target, skill.getTraitType(), true);
counterdmg *= calcAttributeBonus(attacker, target, skill);
attacker.reduceCurrentHp(counterdmg, target, skill);
@@ -1145,6 +1145,12 @@ public final class Formulas
*/
public static boolean calcProbability(double baseChance, L2Character attacker, L2Character target, Skill skill)
{
// Skills without set probability should only test against trait invulnerability.
if (Double.isNaN(baseChance))
{
return calcGeneralTraitBonus(attacker, target, skill.getTraitType(), true) > 0;
}
// Outdated formula: return Rnd.get(100) < ((((((skill.getMagicLevel() + baseChance) - target.getLevel()) + 30) - target.getINT()) * calcAttributeBonus(attacker, target, skill)) * calcGeneralTraitBonus(attacker, target, skill.getTraitType(), false));
// TODO: Find more retail-like formula
return Rnd.get(100) < (((((skill.getMagicLevel() + baseChance) - target.getLevel()) - getAbnormalResist(skill.getBasicProperty(), target)) * calcAttributeBonus(attacker, target, skill)) * calcGeneralTraitBonus(attacker, target, skill.getTraitType(), false));

View File

@@ -22,6 +22,7 @@ import com.l2jmobius.Config;
import com.l2jmobius.gameserver.model.PcCondOverride;
import com.l2jmobius.gameserver.model.actor.L2Character;
import com.l2jmobius.gameserver.model.actor.instance.L2PetInstance;
import com.l2jmobius.gameserver.model.actor.transform.TransformType;
import com.l2jmobius.gameserver.model.itemcontainer.Inventory;
import com.l2jmobius.gameserver.model.items.L2Item;
import com.l2jmobius.gameserver.model.items.instance.L2ItemInstance;
@@ -63,24 +64,20 @@ public interface IStatsFunction
default double calcWeaponBaseValue(L2Character creature, Stats stat)
{
final double baseTemplateValue = creature.getTemplate().getBaseValue(stat, 0);
final double baseValue = creature.getTransformation().filter(transform -> !transform.isStance()).map(transform -> transform.getStats(creature, stat, baseTemplateValue)).orElseGet(() ->
{
double baseValue = creature.getTransformation().map(transform -> transform.getStats(creature, stat, baseTemplateValue)).orElse(baseTemplateValue);
if (creature.isPet())
{
final L2PetInstance pet = (L2PetInstance) creature;
final L2ItemInstance weapon = pet.getActiveWeaponInstance();
final double baseVal = stat == Stats.PHYSICAL_ATTACK ? pet.getPetLevelData().getPetPAtk() : stat == Stats.MAGIC_ATTACK ? pet.getPetLevelData().getPetMAtk() : baseTemplateValue;
return baseVal + (weapon != null ? weapon.getItem().getStats(stat, baseVal) : 0);
baseValue = baseVal + (weapon != null ? weapon.getItem().getStats(stat, baseVal) : 0);
}
else if (creature.isPlayer())
else if (creature.isPlayer() && (!creature.isTransformed() || (creature.getTransformation().get().getType() == TransformType.COMBAT) || (creature.getTransformation().get().getType() == TransformType.MODE_CHANGE)))
{
final L2ItemInstance weapon = creature.getActiveWeaponInstance();
return (weapon != null ? weapon.getItem().getStats(stat, baseTemplateValue) : baseTemplateValue);
baseValue = (weapon != null ? weapon.getItem().getStats(stat, baseTemplateValue) : baseTemplateValue);
}
return baseTemplateValue;
});
return baseValue;
}

View File

@@ -43,6 +43,13 @@ public class MAttackSpeedFinalizer implements IStatsFunction
final double chaBonus = creature.isPlayer() ? BaseStats.CHA.calcBonus(creature) : 1.;
final double witBonus = creature.getWIT() > 0 ? BaseStats.WIT.calcBonus(creature) : 1.;
baseValue *= witBonus * chaBonus;
return validateValue(creature, Stats.defaultValue(creature, stat, baseValue), 1, Config.MAX_MATK_SPEED);
return validateValue(creature, defaultValue(creature, stat, baseValue), 1, Config.MAX_MATK_SPEED);
}
private double defaultValue(L2Character creature, Stats stat, double baseValue)
{
final double mul = Math.max(creature.getStat().getMul(stat), 0.7);
final double add = creature.getStat().getAdd(stat);
return (baseValue * mul) + add + creature.getStat().getMoveTypeValue(stat, creature.getMoveType());
}
}

View File

@@ -82,5 +82,4 @@ public class PAccuracyFinalizer implements IStatsFunction
return (0.2 * Math.max(enchantLevel - 3, 0)) + (0.2 * Math.max(enchantLevel - 6, 0));
}
}

View File

@@ -41,6 +41,13 @@ public class PAttackSpeedFinalizer implements IStatsFunction
final double chaBonus = creature.isPlayer() ? BaseStats.CHA.calcBonus(creature) : 1.;
final double dexBonus = creature.getDEX() > 0 ? BaseStats.DEX.calcBonus(creature) : 1.;
baseValue *= dexBonus * chaBonus;
return validateValue(creature, Stats.defaultValue(creature, stat, baseValue), 1, Config.MAX_PATK_SPEED);
return validateValue(creature, defaultValue(creature, stat, baseValue), 1, Config.MAX_PATK_SPEED);
}
private double defaultValue(L2Character creature, Stats stat, double baseValue)
{
final double mul = Math.max(creature.getStat().getMul(stat), 0.7);
final double add = creature.getStat().getAdd(stat);
return (baseValue * mul) + add + creature.getStat().getMoveTypeValue(stat, creature.getMoveType());
}
}

View File

@@ -78,14 +78,17 @@ public class PDefenseFinalizer implements IStatsFunction
baseValue -= creature.getTransformation().map(transform -> transform.getBaseDefBySlot(player, slot)).orElse(defaultStatValue);
}
}
}
baseValue *= BaseStats.CHA.calcBonus(creature);
}
}
if (creature.isRaid())
{
baseValue *= Config.RAID_PDEFENCE_MULTIPLIER;
}
if (creature.getLevel() > 0)
{
baseValue *= creature.getLevelMod();
}
return defaultValue(creature, stat, baseValue);
}

View File

@@ -32,7 +32,6 @@ public class PRangeFinalizer implements IStatsFunction
{
throwIfPresent(base);
final double baseValue = calcWeaponBaseValue(creature, stat);
return Stats.defaultValue(creature, stat, baseValue);
return Stats.defaultValue(creature, stat, calcWeaponBaseValue(creature, stat));
}
}

View File

@@ -32,7 +32,6 @@ public class RandomDamageFinalizer implements IStatsFunction
{
throwIfPresent(base);
final double baseValue = calcWeaponBaseValue(creature, stat);
return Stats.defaultValue(creature, stat, baseValue);
return Stats.defaultValue(creature, stat, calcWeaponBaseValue(creature, stat));
}
}

View File

@@ -32,7 +32,6 @@ public class ShieldDefenceFinalizer implements IStatsFunction
{
throwIfPresent(base);
final double baseValue = calcWeaponPlusBaseValue(creature, stat);
return Stats.defaultValue(creature, stat, baseValue);
return Stats.defaultValue(creature, stat, calcWeaponPlusBaseValue(creature, stat));
}
}

View File

@@ -32,7 +32,6 @@ public class ShieldDefenceRateFinalizer implements IStatsFunction
{
throwIfPresent(base);
final double baseValue = calcWeaponPlusBaseValue(creature, stat);
return Stats.defaultValue(creature, stat, baseValue);
return Stats.defaultValue(creature, stat, calcWeaponPlusBaseValue(creature, stat));
}
}

View File

@@ -41,11 +41,6 @@ public class MonsterRace
_second = new int[2];
}
public static MonsterRace getInstance()
{
return SingletonHolder._instance;
}
public void newRace()
{
int random = 0;
@@ -143,6 +138,11 @@ public class MonsterRace
return _second[0];
}
public static MonsterRace getInstance()
{
return SingletonHolder._instance;
}
private static class SingletonHolder
{
protected static final MonsterRace _instance = new MonsterRace();

View File

@@ -57,11 +57,6 @@ public class CharStat
private long _exp = 0;
private long _sp = 0;
private byte _level = 1;
private final float[] _attackTraits = new float[TraitType.values().length];
private final int[] _attackTraitsCount = new int[TraitType.values().length];
private final float[] _defenceTraits = new float[TraitType.values().length];
private final int[] _defenceTraitsCount = new int[TraitType.values().length];
private final int[] _traitsInvul = new int[TraitType.values().length];
/** Creature's maximum buff count. */
private int _maxBuffCount = Config.BUFFS_MAX_AMOUNT;
private double _vampiricSum = 0;
@@ -77,6 +72,12 @@ public class CharStat
private final Deque<StatsHolder> _additionalMul = new ConcurrentLinkedDeque<>();
private final Map<Stats, Double> _fixedValue = new ConcurrentHashMap<>();
private final float[] _attackTraits = new float[TraitType.values().length];
private final float[] _defenceTraits = new float[TraitType.values().length];
private final int[] _attackTraitsCount = new int[TraitType.values().length];
private final int[] _defenceTraitsCount = new int[TraitType.values().length];
private final int[] _traitsInvul = new int[TraitType.values().length];
/** Values to be recalculated after every stat update */
private double _attackSpeedMultiplier = 1;
private double _mAttackSpeedMultiplier = 1;

View File

@@ -18,7 +18,6 @@ package com.l2jmobius.gameserver.model.stats;
import java.io.File;
import java.util.NoSuchElementException;
import java.util.Optional;
import java.util.logging.Logger;
import org.w3c.dom.Document;
@@ -61,7 +60,8 @@ public enum BaseStats
{
if ((creature != null) && (_stat != null))
{
return (int) Math.min(_stat.finalize(creature, Optional.empty()), MAX_STAT_VALUE - 1);
// return (int) Math.min(_stat.finalize(creature, Optional.empty()), MAX_STAT_VALUE - 1);
return (int) creature.getStat().getValue(_stat);
}
return 0;
}

View File

@@ -105,7 +105,7 @@ public final class Formulas
final double criticalAddVuln = target.getStat().getValue(Stats.DEFENCE_CRITICAL_DAMAGE_ADD, 0);
// Trait, elements
final double weaponTraitMod = calcWeaponTraitBonus(attacker, target);
final double generalTraitMod = calcGeneralTraitBonus(attacker, target, skill.getTraitType(), false);
final double generalTraitMod = calcGeneralTraitBonus(attacker, target, skill.getTraitType(), true);
final double attributeMod = calcAttributeBonus(attacker, target, skill);
final double randomMod = attacker.getRandomDamageMultiplier();
final double pvpPveMod = calculatePvpPveBonus(attacker, target, skill, true);
@@ -138,7 +138,7 @@ public final class Formulas
final double critMod = mcrit ? (2 * calcCritDamage(attacker, target, skill)) : 1; // TODO not really a proper way... find how it works then implement. // damage += attacker.getStat().getValue(Stats.MAGIC_CRIT_DMG_ADD, 0);
// Trait, elements
final double generalTraitMod = calcGeneralTraitBonus(attacker, target, skill.getTraitType(), false);
final double generalTraitMod = calcGeneralTraitBonus(attacker, target, skill.getTraitType(), true);
final double attributeMod = calcAttributeBonus(attacker, target, skill);
final double randomMod = attacker.getRandomDamageMultiplier();
final double pvpPveMod = calculatePvpPveBonus(attacker, target, skill, mcrit);
@@ -687,7 +687,7 @@ public final class Formulas
final double elementMod = calcAttributeBonus(attacker, target, skill);
final double traitMod = calcGeneralTraitBonus(attacker, target, skill.getTraitType(), false);
final double basicPropertyResist = getBasicPropertyResistBonus(skill.getBasicProperty(), target);
final double buffDebuffMod = skill.isDebuff() ? target.getStat().getValue(Stats.RESIST_ABNORMAL_DEBUFF, 1) : 0;
final double buffDebuffMod = skill.isDebuff() ? target.getStat().getValue(Stats.RESIST_ABNORMAL_DEBUFF, 1) : 1;
final double rate = baseMod * elementMod * traitMod * buffDebuffMod;
final double finalRate = traitMod > 0 ? CommonUtil.constrain(rate, skill.getMinChance(), skill.getMaxChance()) * basicPropertyResist : 0;
@@ -977,7 +977,7 @@ public final class Formulas
double counterdmg = ((target.getPAtk() * 873) / attacker.getPDef()); // Old: (((target.getPAtk(attacker) * 10.0) * 70.0) / attacker.getPDef(target));
counterdmg *= calcWeaponTraitBonus(attacker, target);
counterdmg *= calcGeneralTraitBonus(attacker, target, skill.getTraitType(), false);
counterdmg *= calcGeneralTraitBonus(attacker, target, skill.getTraitType(), true);
counterdmg *= calcAttributeBonus(attacker, target, skill);
attacker.reduceCurrentHp(counterdmg, target, skill);
@@ -1145,6 +1145,12 @@ public final class Formulas
*/
public static boolean calcProbability(double baseChance, L2Character attacker, L2Character target, Skill skill)
{
// Skills without set probability should only test against trait invulnerability.
if (Double.isNaN(baseChance))
{
return calcGeneralTraitBonus(attacker, target, skill.getTraitType(), true) > 0;
}
// Outdated formula: return Rnd.get(100) < ((((((skill.getMagicLevel() + baseChance) - target.getLevel()) + 30) - target.getINT()) * calcAttributeBonus(attacker, target, skill)) * calcGeneralTraitBonus(attacker, target, skill.getTraitType(), false));
// TODO: Find more retail-like formula
return Rnd.get(100) < (((((skill.getMagicLevel() + baseChance) - target.getLevel()) - getAbnormalResist(skill.getBasicProperty(), target)) * calcAttributeBonus(attacker, target, skill)) * calcGeneralTraitBonus(attacker, target, skill.getTraitType(), false));

View File

@@ -22,6 +22,7 @@ import com.l2jmobius.Config;
import com.l2jmobius.gameserver.model.PcCondOverride;
import com.l2jmobius.gameserver.model.actor.L2Character;
import com.l2jmobius.gameserver.model.actor.instance.L2PetInstance;
import com.l2jmobius.gameserver.model.actor.transform.TransformType;
import com.l2jmobius.gameserver.model.itemcontainer.Inventory;
import com.l2jmobius.gameserver.model.items.L2Item;
import com.l2jmobius.gameserver.model.items.instance.L2ItemInstance;
@@ -63,24 +64,20 @@ public interface IStatsFunction
default double calcWeaponBaseValue(L2Character creature, Stats stat)
{
final double baseTemplateValue = creature.getTemplate().getBaseValue(stat, 0);
final double baseValue = creature.getTransformation().filter(transform -> !transform.isStance()).map(transform -> transform.getStats(creature, stat, baseTemplateValue)).orElseGet(() ->
{
double baseValue = creature.getTransformation().map(transform -> transform.getStats(creature, stat, baseTemplateValue)).orElse(baseTemplateValue);
if (creature.isPet())
{
final L2PetInstance pet = (L2PetInstance) creature;
final L2ItemInstance weapon = pet.getActiveWeaponInstance();
final double baseVal = stat == Stats.PHYSICAL_ATTACK ? pet.getPetLevelData().getPetPAtk() : stat == Stats.MAGIC_ATTACK ? pet.getPetLevelData().getPetMAtk() : baseTemplateValue;
return baseVal + (weapon != null ? weapon.getItem().getStats(stat, baseVal) : 0);
baseValue = baseVal + (weapon != null ? weapon.getItem().getStats(stat, baseVal) : 0);
}
else if (creature.isPlayer())
else if (creature.isPlayer() && (!creature.isTransformed() || (creature.getTransformation().get().getType() == TransformType.COMBAT) || (creature.getTransformation().get().getType() == TransformType.MODE_CHANGE)))
{
final L2ItemInstance weapon = creature.getActiveWeaponInstance();
return (weapon != null ? weapon.getItem().getStats(stat, baseTemplateValue) : baseTemplateValue);
baseValue = (weapon != null ? weapon.getItem().getStats(stat, baseTemplateValue) : baseTemplateValue);
}
return baseTemplateValue;
});
return baseValue;
}

View File

@@ -43,6 +43,13 @@ public class MAttackSpeedFinalizer implements IStatsFunction
final double chaBonus = creature.isPlayer() ? BaseStats.CHA.calcBonus(creature) : 1.;
final double witBonus = creature.getWIT() > 0 ? BaseStats.WIT.calcBonus(creature) : 1.;
baseValue *= witBonus * chaBonus;
return validateValue(creature, Stats.defaultValue(creature, stat, baseValue), 1, Config.MAX_MATK_SPEED);
return validateValue(creature, defaultValue(creature, stat, baseValue), 1, Config.MAX_MATK_SPEED);
}
private double defaultValue(L2Character creature, Stats stat, double baseValue)
{
final double mul = Math.max(creature.getStat().getMul(stat), 0.7);
final double add = creature.getStat().getAdd(stat);
return (baseValue * mul) + add + creature.getStat().getMoveTypeValue(stat, creature.getMoveType());
}
}

View File

@@ -82,5 +82,4 @@ public class PAccuracyFinalizer implements IStatsFunction
return (0.2 * Math.max(enchantLevel - 3, 0)) + (0.2 * Math.max(enchantLevel - 6, 0));
}
}

View File

@@ -41,6 +41,13 @@ public class PAttackSpeedFinalizer implements IStatsFunction
final double chaBonus = creature.isPlayer() ? BaseStats.CHA.calcBonus(creature) : 1.;
final double dexBonus = creature.getDEX() > 0 ? BaseStats.DEX.calcBonus(creature) : 1.;
baseValue *= dexBonus * chaBonus;
return validateValue(creature, Stats.defaultValue(creature, stat, baseValue), 1, Config.MAX_PATK_SPEED);
return validateValue(creature, defaultValue(creature, stat, baseValue), 1, Config.MAX_PATK_SPEED);
}
private double defaultValue(L2Character creature, Stats stat, double baseValue)
{
final double mul = Math.max(creature.getStat().getMul(stat), 0.7);
final double add = creature.getStat().getAdd(stat);
return (baseValue * mul) + add + creature.getStat().getMoveTypeValue(stat, creature.getMoveType());
}
}

View File

@@ -78,14 +78,17 @@ public class PDefenseFinalizer implements IStatsFunction
baseValue -= creature.getTransformation().map(transform -> transform.getBaseDefBySlot(player, slot)).orElse(defaultStatValue);
}
}
}
baseValue *= BaseStats.CHA.calcBonus(creature);
}
}
if (creature.isRaid())
{
baseValue *= Config.RAID_PDEFENCE_MULTIPLIER;
}
if (creature.getLevel() > 0)
{
baseValue *= creature.getLevelMod();
}
return defaultValue(creature, stat, baseValue);
}

View File

@@ -32,7 +32,6 @@ public class PRangeFinalizer implements IStatsFunction
{
throwIfPresent(base);
final double baseValue = calcWeaponBaseValue(creature, stat);
return Stats.defaultValue(creature, stat, baseValue);
return Stats.defaultValue(creature, stat, calcWeaponBaseValue(creature, stat));
}
}

View File

@@ -32,7 +32,6 @@ public class RandomDamageFinalizer implements IStatsFunction
{
throwIfPresent(base);
final double baseValue = calcWeaponBaseValue(creature, stat);
return Stats.defaultValue(creature, stat, baseValue);
return Stats.defaultValue(creature, stat, calcWeaponBaseValue(creature, stat));
}
}

View File

@@ -32,7 +32,6 @@ public class ShieldDefenceFinalizer implements IStatsFunction
{
throwIfPresent(base);
final double baseValue = calcWeaponPlusBaseValue(creature, stat);
return Stats.defaultValue(creature, stat, baseValue);
return Stats.defaultValue(creature, stat, calcWeaponPlusBaseValue(creature, stat));
}
}

View File

@@ -32,7 +32,6 @@ public class ShieldDefenceRateFinalizer implements IStatsFunction
{
throwIfPresent(base);
final double baseValue = calcWeaponPlusBaseValue(creature, stat);
return Stats.defaultValue(creature, stat, baseValue);
return Stats.defaultValue(creature, stat, calcWeaponPlusBaseValue(creature, stat));
}
}

View File

@@ -41,11 +41,6 @@ public class MonsterRace
_second = new int[2];
}
public static MonsterRace getInstance()
{
return SingletonHolder._instance;
}
public void newRace()
{
int random = 0;
@@ -143,6 +138,11 @@ public class MonsterRace
return _second[0];
}
public static MonsterRace getInstance()
{
return SingletonHolder._instance;
}
private static class SingletonHolder
{
protected static final MonsterRace _instance = new MonsterRace();

View File

@@ -57,11 +57,6 @@ public class CharStat
private long _exp = 0;
private long _sp = 0;
private byte _level = 1;
private final float[] _attackTraits = new float[TraitType.values().length];
private final int[] _attackTraitsCount = new int[TraitType.values().length];
private final float[] _defenceTraits = new float[TraitType.values().length];
private final int[] _defenceTraitsCount = new int[TraitType.values().length];
private final int[] _traitsInvul = new int[TraitType.values().length];
/** Creature's maximum buff count. */
private int _maxBuffCount = Config.BUFFS_MAX_AMOUNT;
private double _vampiricSum = 0;
@@ -77,6 +72,12 @@ public class CharStat
private final Deque<StatsHolder> _additionalMul = new ConcurrentLinkedDeque<>();
private final Map<Stats, Double> _fixedValue = new ConcurrentHashMap<>();
private final float[] _attackTraits = new float[TraitType.values().length];
private final float[] _defenceTraits = new float[TraitType.values().length];
private final int[] _attackTraitsCount = new int[TraitType.values().length];
private final int[] _defenceTraitsCount = new int[TraitType.values().length];
private final int[] _traitsInvul = new int[TraitType.values().length];
/** Values to be recalculated after every stat update */
private double _attackSpeedMultiplier = 1;
private double _mAttackSpeedMultiplier = 1;

View File

@@ -18,7 +18,6 @@ package com.l2jmobius.gameserver.model.stats;
import java.io.File;
import java.util.NoSuchElementException;
import java.util.Optional;
import java.util.logging.Logger;
import org.w3c.dom.Document;
@@ -61,7 +60,8 @@ public enum BaseStats
{
if ((creature != null) && (_stat != null))
{
return (int) Math.min(_stat.finalize(creature, Optional.empty()), MAX_STAT_VALUE - 1);
// return (int) Math.min(_stat.finalize(creature, Optional.empty()), MAX_STAT_VALUE - 1);
return (int) creature.getStat().getValue(_stat);
}
return 0;
}

View File

@@ -105,7 +105,7 @@ public final class Formulas
final double criticalAddVuln = target.getStat().getValue(Stats.DEFENCE_CRITICAL_DAMAGE_ADD, 0);
// Trait, elements
final double weaponTraitMod = calcWeaponTraitBonus(attacker, target);
final double generalTraitMod = calcGeneralTraitBonus(attacker, target, skill.getTraitType(), false);
final double generalTraitMod = calcGeneralTraitBonus(attacker, target, skill.getTraitType(), true);
final double attributeMod = calcAttributeBonus(attacker, target, skill);
final double randomMod = attacker.getRandomDamageMultiplier();
final double pvpPveMod = calculatePvpPveBonus(attacker, target, skill, true);
@@ -138,7 +138,7 @@ public final class Formulas
final double critMod = mcrit ? (2 * calcCritDamage(attacker, target, skill)) : 1; // TODO not really a proper way... find how it works then implement. // damage += attacker.getStat().getValue(Stats.MAGIC_CRIT_DMG_ADD, 0);
// Trait, elements
final double generalTraitMod = calcGeneralTraitBonus(attacker, target, skill.getTraitType(), false);
final double generalTraitMod = calcGeneralTraitBonus(attacker, target, skill.getTraitType(), true);
final double attributeMod = calcAttributeBonus(attacker, target, skill);
final double randomMod = attacker.getRandomDamageMultiplier();
final double pvpPveMod = calculatePvpPveBonus(attacker, target, skill, mcrit);
@@ -687,7 +687,7 @@ public final class Formulas
final double elementMod = calcAttributeBonus(attacker, target, skill);
final double traitMod = calcGeneralTraitBonus(attacker, target, skill.getTraitType(), false);
final double basicPropertyResist = getBasicPropertyResistBonus(skill.getBasicProperty(), target);
final double buffDebuffMod = skill.isDebuff() ? target.getStat().getValue(Stats.RESIST_ABNORMAL_DEBUFF, 1) : 0;
final double buffDebuffMod = skill.isDebuff() ? target.getStat().getValue(Stats.RESIST_ABNORMAL_DEBUFF, 1) : 1;
final double rate = baseMod * elementMod * traitMod * buffDebuffMod;
final double finalRate = traitMod > 0 ? CommonUtil.constrain(rate, skill.getMinChance(), skill.getMaxChance()) * basicPropertyResist : 0;
@@ -977,7 +977,7 @@ public final class Formulas
double counterdmg = ((target.getPAtk() * 873) / attacker.getPDef()); // Old: (((target.getPAtk(attacker) * 10.0) * 70.0) / attacker.getPDef(target));
counterdmg *= calcWeaponTraitBonus(attacker, target);
counterdmg *= calcGeneralTraitBonus(attacker, target, skill.getTraitType(), false);
counterdmg *= calcGeneralTraitBonus(attacker, target, skill.getTraitType(), true);
counterdmg *= calcAttributeBonus(attacker, target, skill);
attacker.reduceCurrentHp(counterdmg, target, skill);
@@ -1145,6 +1145,12 @@ public final class Formulas
*/
public static boolean calcProbability(double baseChance, L2Character attacker, L2Character target, Skill skill)
{
// Skills without set probability should only test against trait invulnerability.
if (Double.isNaN(baseChance))
{
return calcGeneralTraitBonus(attacker, target, skill.getTraitType(), true) > 0;
}
// Outdated formula: return Rnd.get(100) < ((((((skill.getMagicLevel() + baseChance) - target.getLevel()) + 30) - target.getINT()) * calcAttributeBonus(attacker, target, skill)) * calcGeneralTraitBonus(attacker, target, skill.getTraitType(), false));
// TODO: Find more retail-like formula
return Rnd.get(100) < (((((skill.getMagicLevel() + baseChance) - target.getLevel()) - getAbnormalResist(skill.getBasicProperty(), target)) * calcAttributeBonus(attacker, target, skill)) * calcGeneralTraitBonus(attacker, target, skill.getTraitType(), false));

View File

@@ -22,6 +22,7 @@ import com.l2jmobius.Config;
import com.l2jmobius.gameserver.model.PcCondOverride;
import com.l2jmobius.gameserver.model.actor.L2Character;
import com.l2jmobius.gameserver.model.actor.instance.L2PetInstance;
import com.l2jmobius.gameserver.model.actor.transform.TransformType;
import com.l2jmobius.gameserver.model.itemcontainer.Inventory;
import com.l2jmobius.gameserver.model.items.L2Item;
import com.l2jmobius.gameserver.model.items.instance.L2ItemInstance;
@@ -63,24 +64,20 @@ public interface IStatsFunction
default double calcWeaponBaseValue(L2Character creature, Stats stat)
{
final double baseTemplateValue = creature.getTemplate().getBaseValue(stat, 0);
final double baseValue = creature.getTransformation().filter(transform -> !transform.isStance()).map(transform -> transform.getStats(creature, stat, baseTemplateValue)).orElseGet(() ->
{
double baseValue = creature.getTransformation().map(transform -> transform.getStats(creature, stat, baseTemplateValue)).orElse(baseTemplateValue);
if (creature.isPet())
{
final L2PetInstance pet = (L2PetInstance) creature;
final L2ItemInstance weapon = pet.getActiveWeaponInstance();
final double baseVal = stat == Stats.PHYSICAL_ATTACK ? pet.getPetLevelData().getPetPAtk() : stat == Stats.MAGIC_ATTACK ? pet.getPetLevelData().getPetMAtk() : baseTemplateValue;
return baseVal + (weapon != null ? weapon.getItem().getStats(stat, baseVal) : 0);
baseValue = baseVal + (weapon != null ? weapon.getItem().getStats(stat, baseVal) : 0);
}
else if (creature.isPlayer())
else if (creature.isPlayer() && (!creature.isTransformed() || (creature.getTransformation().get().getType() == TransformType.COMBAT) || (creature.getTransformation().get().getType() == TransformType.MODE_CHANGE)))
{
final L2ItemInstance weapon = creature.getActiveWeaponInstance();
return (weapon != null ? weapon.getItem().getStats(stat, baseTemplateValue) : baseTemplateValue);
baseValue = (weapon != null ? weapon.getItem().getStats(stat, baseTemplateValue) : baseTemplateValue);
}
return baseTemplateValue;
});
return baseValue;
}

View File

@@ -43,6 +43,13 @@ public class MAttackSpeedFinalizer implements IStatsFunction
final double chaBonus = creature.isPlayer() ? BaseStats.CHA.calcBonus(creature) : 1.;
final double witBonus = creature.getWIT() > 0 ? BaseStats.WIT.calcBonus(creature) : 1.;
baseValue *= witBonus * chaBonus;
return validateValue(creature, Stats.defaultValue(creature, stat, baseValue), 1, Config.MAX_MATK_SPEED);
return validateValue(creature, defaultValue(creature, stat, baseValue), 1, Config.MAX_MATK_SPEED);
}
private double defaultValue(L2Character creature, Stats stat, double baseValue)
{
final double mul = Math.max(creature.getStat().getMul(stat), 0.7);
final double add = creature.getStat().getAdd(stat);
return (baseValue * mul) + add + creature.getStat().getMoveTypeValue(stat, creature.getMoveType());
}
}

View File

@@ -82,5 +82,4 @@ public class PAccuracyFinalizer implements IStatsFunction
return (0.2 * Math.max(enchantLevel - 3, 0)) + (0.2 * Math.max(enchantLevel - 6, 0));
}
}

View File

@@ -41,6 +41,13 @@ public class PAttackSpeedFinalizer implements IStatsFunction
final double chaBonus = creature.isPlayer() ? BaseStats.CHA.calcBonus(creature) : 1.;
final double dexBonus = creature.getDEX() > 0 ? BaseStats.DEX.calcBonus(creature) : 1.;
baseValue *= dexBonus * chaBonus;
return validateValue(creature, Stats.defaultValue(creature, stat, baseValue), 1, Config.MAX_PATK_SPEED);
return validateValue(creature, defaultValue(creature, stat, baseValue), 1, Config.MAX_PATK_SPEED);
}
private double defaultValue(L2Character creature, Stats stat, double baseValue)
{
final double mul = Math.max(creature.getStat().getMul(stat), 0.7);
final double add = creature.getStat().getAdd(stat);
return (baseValue * mul) + add + creature.getStat().getMoveTypeValue(stat, creature.getMoveType());
}
}

View File

@@ -78,14 +78,17 @@ public class PDefenseFinalizer implements IStatsFunction
baseValue -= creature.getTransformation().map(transform -> transform.getBaseDefBySlot(player, slot)).orElse(defaultStatValue);
}
}
}
baseValue *= BaseStats.CHA.calcBonus(creature);
}
}
if (creature.isRaid())
{
baseValue *= Config.RAID_PDEFENCE_MULTIPLIER;
}
if (creature.getLevel() > 0)
{
baseValue *= creature.getLevelMod();
}
return defaultValue(creature, stat, baseValue);
}

View File

@@ -32,7 +32,6 @@ public class PRangeFinalizer implements IStatsFunction
{
throwIfPresent(base);
final double baseValue = calcWeaponBaseValue(creature, stat);
return Stats.defaultValue(creature, stat, baseValue);
return Stats.defaultValue(creature, stat, calcWeaponBaseValue(creature, stat));
}
}

View File

@@ -32,7 +32,6 @@ public class RandomDamageFinalizer implements IStatsFunction
{
throwIfPresent(base);
final double baseValue = calcWeaponBaseValue(creature, stat);
return Stats.defaultValue(creature, stat, baseValue);
return Stats.defaultValue(creature, stat, calcWeaponBaseValue(creature, stat));
}
}

View File

@@ -32,7 +32,6 @@ public class ShieldDefenceFinalizer implements IStatsFunction
{
throwIfPresent(base);
final double baseValue = calcWeaponPlusBaseValue(creature, stat);
return Stats.defaultValue(creature, stat, baseValue);
return Stats.defaultValue(creature, stat, calcWeaponPlusBaseValue(creature, stat));
}
}

View File

@@ -32,7 +32,6 @@ public class ShieldDefenceRateFinalizer implements IStatsFunction
{
throwIfPresent(base);
final double baseValue = calcWeaponPlusBaseValue(creature, stat);
return Stats.defaultValue(creature, stat, baseValue);
return Stats.defaultValue(creature, stat, calcWeaponPlusBaseValue(creature, stat));
}
}

View File

@@ -57,11 +57,6 @@ public class CharStat
private long _exp = 0;
private long _sp = 0;
private byte _level = 1;
private final float[] _attackTraits = new float[TraitType.values().length];
private final int[] _attackTraitsCount = new int[TraitType.values().length];
private final float[] _defenceTraits = new float[TraitType.values().length];
private final int[] _defenceTraitsCount = new int[TraitType.values().length];
private final int[] _traitsInvul = new int[TraitType.values().length];
/** Creature's maximum buff count. */
private int _maxBuffCount = Config.BUFFS_MAX_AMOUNT;
private double _vampiricSum = 0;
@@ -77,6 +72,12 @@ public class CharStat
private final Deque<StatsHolder> _additionalMul = new ConcurrentLinkedDeque<>();
private final Map<Stats, Double> _fixedValue = new ConcurrentHashMap<>();
private final float[] _attackTraits = new float[TraitType.values().length];
private final float[] _defenceTraits = new float[TraitType.values().length];
private final int[] _attackTraitsCount = new int[TraitType.values().length];
private final int[] _defenceTraitsCount = new int[TraitType.values().length];
private final int[] _traitsInvul = new int[TraitType.values().length];
/** Values to be recalculated after every stat update */
private double _attackSpeedMultiplier = 1;
private double _mAttackSpeedMultiplier = 1;

View File

@@ -18,7 +18,6 @@ package com.l2jmobius.gameserver.model.stats;
import java.io.File;
import java.util.NoSuchElementException;
import java.util.Optional;
import java.util.logging.Logger;
import org.w3c.dom.Document;
@@ -61,7 +60,8 @@ public enum BaseStats
{
if ((creature != null) && (_stat != null))
{
return (int) Math.min(_stat.finalize(creature, Optional.empty()), MAX_STAT_VALUE - 1);
// return (int) Math.min(_stat.finalize(creature, Optional.empty()), MAX_STAT_VALUE - 1);
return (int) creature.getStat().getValue(_stat);
}
return 0;
}

View File

@@ -105,7 +105,7 @@ public final class Formulas
final double criticalAddVuln = target.getStat().getValue(Stats.DEFENCE_CRITICAL_DAMAGE_ADD, 0);
// Trait, elements
final double weaponTraitMod = calcWeaponTraitBonus(attacker, target);
final double generalTraitMod = calcGeneralTraitBonus(attacker, target, skill.getTraitType(), false);
final double generalTraitMod = calcGeneralTraitBonus(attacker, target, skill.getTraitType(), true);
final double attributeMod = calcAttributeBonus(attacker, target, skill);
final double randomMod = attacker.getRandomDamageMultiplier();
final double pvpPveMod = calculatePvpPveBonus(attacker, target, skill, true);
@@ -138,7 +138,7 @@ public final class Formulas
final double critMod = mcrit ? (2 * calcCritDamage(attacker, target, skill)) : 1; // TODO not really a proper way... find how it works then implement. // damage += attacker.getStat().getValue(Stats.MAGIC_CRIT_DMG_ADD, 0);
// Trait, elements
final double generalTraitMod = calcGeneralTraitBonus(attacker, target, skill.getTraitType(), false);
final double generalTraitMod = calcGeneralTraitBonus(attacker, target, skill.getTraitType(), true);
final double attributeMod = calcAttributeBonus(attacker, target, skill);
final double randomMod = attacker.getRandomDamageMultiplier();
final double pvpPveMod = calculatePvpPveBonus(attacker, target, skill, mcrit);
@@ -687,7 +687,7 @@ public final class Formulas
final double elementMod = calcAttributeBonus(attacker, target, skill);
final double traitMod = calcGeneralTraitBonus(attacker, target, skill.getTraitType(), false);
final double basicPropertyResist = getBasicPropertyResistBonus(skill.getBasicProperty(), target);
final double buffDebuffMod = skill.isDebuff() ? target.getStat().getValue(Stats.RESIST_ABNORMAL_DEBUFF, 1) : 0;
final double buffDebuffMod = skill.isDebuff() ? target.getStat().getValue(Stats.RESIST_ABNORMAL_DEBUFF, 1) : 1;
final double rate = baseMod * elementMod * traitMod * buffDebuffMod;
final double finalRate = traitMod > 0 ? CommonUtil.constrain(rate, skill.getMinChance(), skill.getMaxChance()) * basicPropertyResist : 0;
@@ -977,7 +977,7 @@ public final class Formulas
double counterdmg = ((target.getPAtk() * 873) / attacker.getPDef()); // Old: (((target.getPAtk(attacker) * 10.0) * 70.0) / attacker.getPDef(target));
counterdmg *= calcWeaponTraitBonus(attacker, target);
counterdmg *= calcGeneralTraitBonus(attacker, target, skill.getTraitType(), false);
counterdmg *= calcGeneralTraitBonus(attacker, target, skill.getTraitType(), true);
counterdmg *= calcAttributeBonus(attacker, target, skill);
attacker.reduceCurrentHp(counterdmg, target, skill);
@@ -1145,6 +1145,12 @@ public final class Formulas
*/
public static boolean calcProbability(double baseChance, L2Character attacker, L2Character target, Skill skill)
{
// Skills without set probability should only test against trait invulnerability.
if (Double.isNaN(baseChance))
{
return calcGeneralTraitBonus(attacker, target, skill.getTraitType(), true) > 0;
}
// Outdated formula: return Rnd.get(100) < ((((((skill.getMagicLevel() + baseChance) - target.getLevel()) + 30) - target.getINT()) * calcAttributeBonus(attacker, target, skill)) * calcGeneralTraitBonus(attacker, target, skill.getTraitType(), false));
// TODO: Find more retail-like formula
return Rnd.get(100) < (((((skill.getMagicLevel() + baseChance) - target.getLevel()) - getAbnormalResist(skill.getBasicProperty(), target)) * calcAttributeBonus(attacker, target, skill)) * calcGeneralTraitBonus(attacker, target, skill.getTraitType(), false));

View File

@@ -22,6 +22,7 @@ import com.l2jmobius.Config;
import com.l2jmobius.gameserver.model.PcCondOverride;
import com.l2jmobius.gameserver.model.actor.L2Character;
import com.l2jmobius.gameserver.model.actor.instance.L2PetInstance;
import com.l2jmobius.gameserver.model.actor.transform.TransformType;
import com.l2jmobius.gameserver.model.itemcontainer.Inventory;
import com.l2jmobius.gameserver.model.items.L2Item;
import com.l2jmobius.gameserver.model.items.instance.L2ItemInstance;
@@ -63,24 +64,20 @@ public interface IStatsFunction
default double calcWeaponBaseValue(L2Character creature, Stats stat)
{
final double baseTemplateValue = creature.getTemplate().getBaseValue(stat, 0);
final double baseValue = creature.getTransformation().filter(transform -> !transform.isStance()).map(transform -> transform.getStats(creature, stat, baseTemplateValue)).orElseGet(() ->
{
double baseValue = creature.getTransformation().map(transform -> transform.getStats(creature, stat, baseTemplateValue)).orElse(baseTemplateValue);
if (creature.isPet())
{
final L2PetInstance pet = (L2PetInstance) creature;
final L2ItemInstance weapon = pet.getActiveWeaponInstance();
final double baseVal = stat == Stats.PHYSICAL_ATTACK ? pet.getPetLevelData().getPetPAtk() : stat == Stats.MAGIC_ATTACK ? pet.getPetLevelData().getPetMAtk() : baseTemplateValue;
return baseVal + (weapon != null ? weapon.getItem().getStats(stat, baseVal) : 0);
baseValue = baseVal + (weapon != null ? weapon.getItem().getStats(stat, baseVal) : 0);
}
else if (creature.isPlayer())
else if (creature.isPlayer() && (!creature.isTransformed() || (creature.getTransformation().get().getType() == TransformType.COMBAT) || (creature.getTransformation().get().getType() == TransformType.MODE_CHANGE)))
{
final L2ItemInstance weapon = creature.getActiveWeaponInstance();
return (weapon != null ? weapon.getItem().getStats(stat, baseTemplateValue) : baseTemplateValue);
baseValue = (weapon != null ? weapon.getItem().getStats(stat, baseTemplateValue) : baseTemplateValue);
}
return baseTemplateValue;
});
return baseValue;
}

View File

@@ -43,6 +43,13 @@ public class MAttackSpeedFinalizer implements IStatsFunction
final double chaBonus = creature.isPlayer() ? BaseStats.CHA.calcBonus(creature) : 1.;
final double witBonus = creature.getWIT() > 0 ? BaseStats.WIT.calcBonus(creature) : 1.;
baseValue *= witBonus * chaBonus;
return validateValue(creature, Stats.defaultValue(creature, stat, baseValue), 1, Config.MAX_MATK_SPEED);
return validateValue(creature, defaultValue(creature, stat, baseValue), 1, Config.MAX_MATK_SPEED);
}
private double defaultValue(L2Character creature, Stats stat, double baseValue)
{
final double mul = Math.max(creature.getStat().getMul(stat), 0.7);
final double add = creature.getStat().getAdd(stat);
return (baseValue * mul) + add + creature.getStat().getMoveTypeValue(stat, creature.getMoveType());
}
}

View File

@@ -82,5 +82,4 @@ public class PAccuracyFinalizer implements IStatsFunction
return (0.2 * Math.max(enchantLevel - 3, 0)) + (0.2 * Math.max(enchantLevel - 6, 0));
}
}

View File

@@ -41,6 +41,13 @@ public class PAttackSpeedFinalizer implements IStatsFunction
final double chaBonus = creature.isPlayer() ? BaseStats.CHA.calcBonus(creature) : 1.;
final double dexBonus = creature.getDEX() > 0 ? BaseStats.DEX.calcBonus(creature) : 1.;
baseValue *= dexBonus * chaBonus;
return validateValue(creature, Stats.defaultValue(creature, stat, baseValue), 1, Config.MAX_PATK_SPEED);
return validateValue(creature, defaultValue(creature, stat, baseValue), 1, Config.MAX_PATK_SPEED);
}
private double defaultValue(L2Character creature, Stats stat, double baseValue)
{
final double mul = Math.max(creature.getStat().getMul(stat), 0.7);
final double add = creature.getStat().getAdd(stat);
return (baseValue * mul) + add + creature.getStat().getMoveTypeValue(stat, creature.getMoveType());
}
}

View File

@@ -78,14 +78,17 @@ public class PDefenseFinalizer implements IStatsFunction
baseValue -= creature.getTransformation().map(transform -> transform.getBaseDefBySlot(player, slot)).orElse(defaultStatValue);
}
}
}
baseValue *= BaseStats.CHA.calcBonus(creature);
}
}
if (creature.isRaid())
{
baseValue *= Config.RAID_PDEFENCE_MULTIPLIER;
}
if (creature.getLevel() > 0)
{
baseValue *= creature.getLevelMod();
}
return defaultValue(creature, stat, baseValue);
}

View File

@@ -32,7 +32,6 @@ public class PRangeFinalizer implements IStatsFunction
{
throwIfPresent(base);
final double baseValue = calcWeaponBaseValue(creature, stat);
return Stats.defaultValue(creature, stat, baseValue);
return Stats.defaultValue(creature, stat, calcWeaponBaseValue(creature, stat));
}
}

View File

@@ -32,7 +32,6 @@ public class RandomDamageFinalizer implements IStatsFunction
{
throwIfPresent(base);
final double baseValue = calcWeaponBaseValue(creature, stat);
return Stats.defaultValue(creature, stat, baseValue);
return Stats.defaultValue(creature, stat, calcWeaponBaseValue(creature, stat));
}
}

View File

@@ -32,7 +32,6 @@ public class ShieldDefenceFinalizer implements IStatsFunction
{
throwIfPresent(base);
final double baseValue = calcWeaponPlusBaseValue(creature, stat);
return Stats.defaultValue(creature, stat, baseValue);
return Stats.defaultValue(creature, stat, calcWeaponPlusBaseValue(creature, stat));
}
}

View File

@@ -32,7 +32,6 @@ public class ShieldDefenceRateFinalizer implements IStatsFunction
{
throwIfPresent(base);
final double baseValue = calcWeaponPlusBaseValue(creature, stat);
return Stats.defaultValue(creature, stat, baseValue);
return Stats.defaultValue(creature, stat, calcWeaponPlusBaseValue(creature, stat));
}
}