ace/Source/ACE.Server/WorldObjects/Creature_Rating.cs

520 lines
19 KiB
C#

using System;
using System.Linq;
using ACE.Entity.Enum;
using ACE.Entity.Enum.Properties;
using ACE.Server.Managers;
namespace ACE.Server.WorldObjects
{
partial class Creature
{
// Ratings:
// http://asheron.wikia.com/wiki/Rating
private static float GetRatingMod(int rating)
{
if (rating == 0) return 1.0f;
if (rating >= 0)
return GetPositiveRatingMod(rating);
else
return GetNegativeRatingMod(-rating);
}
/// <summary>
/// Returns a 1.xx rating modifier by default,
/// or a 0.xx rating modifier if negative
/// </summary>
public static float GetPositiveRatingMod(int rating)
{
if (rating < 0) return GetNegativeRatingMod(-rating);
// formula: (100 + rating) / 100 = 1.xx modifier
var ratingMod = (100 + rating) / 100.0f;
return ratingMod;
}
/// <summary>
/// Returns a 0.xx rating modifier by default,
/// or a 1.xx rating modifier if negative
/// </summary>
public static float GetNegativeRatingMod(int rating, bool allowBug = false)
{
if (rating < 0 && !allowBug)
return GetPositiveRatingMod(-rating);
if (allowBug)
{
// with the bug allowed for DRR reduction from void dots,
// this method will produce unbalanced modifiers for negative ratings
// as negative rating approaches -100, it ramps up in a curve to infinity, eventually getting a divide by 0 crash for -100
// values less than -100 would produce negative multipliers, which would result in undefined behavior throughout the system,
// such as negative damage numbers. even with the bug enabled, we still limit to -99 on the lower end to prevent system failure
rating = Math.Max(rating, -99);
}
// formula: 100 / (100 + rating) = 0.xx modifier
var ratingMod = 100.0f / (100 + rating);
return ratingMod;
}
// - Damage rating - increases all damage done to a target, including critical hits
// Formula: (100 + <total damage rating>) / 100 = 1.xx modifier to damage
public float GetDamageRating(int damageRating)
{
return GetPositiveRatingMod(damageRating);
}
// - Critical damage rating - increases critical hit damage done to a target
// Formula: (100 + <total critical damage rating>) / 100 = 1.xx modifier to critical damage
public float GetCriticalDamageRating(int criticalDmgRating)
{
return GetPositiveRatingMod(criticalDmgRating);
}
// - Damage resistance rating - decreases the amount of all incoming damage, including critical hits
// Formula: 100 / (100 + <total damage resistance rating>) = 0.xxx modifier to incoming damage
public float GetDamageResistanceRating(int damageResistanceRating)
{
return GetNegativeRatingMod(damageResistanceRating);
}
// - Critical damage resistance rating - decreases critical hit damage received
// Formula: 100 / (100 + <total critical damage resistance rating>) = 0.xxx modifier to critical hit damage received
public float GetCriticalDamageResistanceRating(int criticalDmgResistanceRating)
{
return GetNegativeRatingMod(criticalDmgResistanceRating);
}
// - DoT resistance rating - decreases the effectiveness of damage over time (DoT) spells cast upon the user
// Formula: 100 / (100 + <total DoT reduction rating> = 0.xxx modifier to outgoing incoming DoT attacks
public float GetDamageOverTimeResistanceRating(int dotResistanceRating)
{
return GetNegativeRatingMod(dotResistanceRating);
}
// - Health drain resistance rating - decreases the effect of drain spells cast upon the target
// Formula: 100 / (100 + <total health drain resistance rating>) = 0.xxx modifier to incoming health drains
public float GetHealthDrainResistanceRating(int healthDrainResistRating)
{
return GetNegativeRatingMod(healthDrainResistRating);
}
// - Healing boost rating - increases the amount of health received from consumables, healing kits, and life magic
// Formula: (100 + <total healing rating>) / 100 = 1.xx modifier to healing
public float GetHealingBoostRating(int healingBoostRating)
{
return GetPositiveRatingMod(healingBoostRating);
}
// - Aetheria Surge rating - increases the chance that Aetheria will surge
// Formula: (100 + <aetheria surge rating>) / 100 = 1.xx modifier to Aetheria Surges
public float GetAetheriaSurgeRating(int aetheriaSurgeRating)
{
return GetPositiveRatingMod(aetheriaSurgeRating);
}
// - Mana charge rating - increases the amount of mana released from mana stones into magical items
// Formula: (100 + <mana charge rating>) / 100 = 1.xx modifier to mana charges
public float GetManaChargeRating(int manaChargeRating)
{
return GetPositiveRatingMod(manaChargeRating);
}
// - Mana reduction rating - decreases the amount of mana consumed in equipped magical items
// Formula: 100 / (100 + <mana reduction rating>) = 0.xxx modifier to magical item mana consumed
public float GetManaReductionRating(int manaReductionRating)
{
return GetNegativeRatingMod(manaReductionRating);
}
// - Damage reduction rating - debuff applied to decrease the effective damage rating of the target
// Formula: 100 / (100 + <total damage reduction rating>) = 0.xxx modifier to outgoing damage
public float GetDamageReductionRating(int damageReductionRating)
{
return GetNegativeRatingMod(damageReductionRating);
}
// - Healing reduction rating - debuff applied to decrease the effective healing rate of the target
// Formula: 100 / (100 + <total healing reduction rating>) = 0.xxx modifier to healing
public float GetHealingReductionRating(int healingReductionRating)
{
return GetNegativeRatingMod(healingReductionRating);
}
// - Damage resistance reduction rating - debuff applied to decrease the effective damage resistance rating of the target
// Formula: 100 / (100 + <total damage resistance reduction rating>) = 0.xxx modifier to incoming damage
public float GetDamageResistanceReductionRating(int damageResistReduceRating)
{
return GetNegativeRatingMod(damageResistReduceRating);
}
// - Player Killer damage rating - increases all damage done to other players, including critical hits
// Formula: (100 + <total PK damage rating> / 100 = 1.xx modifier to PK damage
public float GetPKDamageRating(int pkDamageRating)
{
return GetPositiveRatingMod(pkDamageRating);
}
// - Player Killer damage resistance rating - decreases all incoming damage done by other players, including critical hits
// Formula: 100 / (100 + <total PK damage resistance rating>) = 0.xxx modifier to incoming PK damage
public float GetPKDamageResistanceRating(int pkDamageResistRating)
{
return GetNegativeRatingMod(pkDamageResistRating);
}
/// <summary>
/// Converts a 1.xx modifier to a +x rating,
/// or a 0.xx modifier to a -x rating.
/// </summary>
public static int ModToRating(float mod)
{
if (mod >= 1.0f)
return (int)Math.Round(mod * 100 - 100);
else
return (int)Math.Round(-100 / mod + 100);
}
/// <summary>
/// Returns a modifier to an implicitly negative rating (ie. damage resistance)
/// </summary>
public static int NegativeModToRating(float mod)
{
return -ModToRating(mod);
}
/// <summary>
/// Combines rating modifiers additively
/// </summary>
/// <param name="mods">A list of rating modifiers</param>
public static float AdditiveCombine(params float[] mods)
{
int totalRating = 0;
foreach (var mod in mods)
totalRating += ModToRating(mod);
return GetRatingMod(totalRating);
}
public int GetDamageRating()
{
// get from base properties (monsters)?
var damageRating = DamageRating ?? 0;
// additive enchantments
var enchantments = EnchantmentManager.GetRating(PropertyInt.DamageRating);
// equipment ratings
var equipment = GetEquippedItemsRatingSum(PropertyInt.GearDamage);
// weakness as negative damage rating?
// TODO: this should be factored in as a separate weakness rating...
var weaknessRating = EnchantmentManager.GetRating(PropertyInt.WeaknessRating);
var augBonus = 0;
var lumAugBonus = 0;
if (this is Player player)
{
augBonus = player.AugmentationDamageBonus * 3;
lumAugBonus = player.LumAugDamageRating;
}
// heritage / weapon type bonus factored in elsewhere?
return damageRating + equipment + enchantments - weaknessRating + augBonus + lumAugBonus;
}
public int GetDamageResistRating(CombatType? combatType = null, bool directDamage = true)
{
// get from base properties (monsters)?
var damageResistRating = DamageResistRating ?? 0;
// additive enchantments
var enchantments = EnchantmentManager.GetRating(PropertyInt.DamageResistRating);
// equipment ratings
var equipment = GetEquippedItemsRatingSum(PropertyInt.GearDamageResist);
// nether DoTs as negative DRR?
// TODO: this should be factored in as a separate nether damage rating...
var netherDotDamageRating = directDamage ? EnchantmentManager.GetNetherDotDamageRating() : 0;
var augBonus = 0;
var lumAugBonus = 0;
var specBonus = 0;
if (this is Player player)
{
augBonus = player.AugmentationDamageReduction * 3;
lumAugBonus = player.LumAugDamageReductionRating;
specBonus = GetSpecDefenseBonus(combatType);
}
return damageResistRating + equipment + enchantments - netherDotDamageRating + augBonus + lumAugBonus + specBonus;
}
public float GetDamageResistRatingMod(CombatType? combatType = null, bool directDamage = true)
{
var damageResistRating = GetDamageResistRating(combatType, directDamage);
var allowBug = PropertyManager.GetBool("allow_negative_rating_curve").Item;
return GetNegativeRatingMod(damageResistRating, allowBug);
}
public int GetSpecDefenseBonus(CombatType? combatType)
{
// https://asheron.fandom.com/wiki/Announcements_-_2013/02_-_Balance_of_Power
// New bonus added to specialized defenses against damage of their respective attack type. (Applied in both PvE & PvP)
// - Specialized Melee Defense skill now adds 1 Damage Rating Resist for every 60 pts against melee attacks
// - Specialized Missile Defense skill now adds 1 Damage Rating Resist for every 50 pts against missile attacks
// - Specialized Magic Defense skill now adds 1 Damage Rating Resist for every 50 pts against magic attacks
// only applies to players
if (combatType == null || !(this is Player player))
return 0;
var skill = GetDefenseSkill(combatType.Value);
var creatureSkill = player.GetCreatureSkill(skill);
// ensure defense skill is specialized
if (creatureSkill.AdvancementClass != SkillAdvancementClass.Specialized)
return 0;
var divisor = skill == Skill.MeleeDefense ? 60 : 50;
// floor?
return (int)creatureSkill.Base / divisor;
}
public int GetCritRating()
{
// crit chance
// get from base properties (monsters)?
var critChanceRating = CritRating ?? 0;
// additive enchantments
var enchantments = EnchantmentManager.GetRating(PropertyInt.CritRating);
// equipment ratings
var equipment = GetEquippedItemsRatingSum(PropertyInt.GearCrit);
// augmentations
var augBonus = 0;
if (this is Player player)
augBonus = player.AugmentationCriticalExpertise;
return critChanceRating + enchantments + equipment + augBonus;
}
public int GetCritDamageRating()
{
// get from base properties (monsters)?
var critDamageRating = CritDamageRating ?? 0;
// additive enchantments
var enchantments = EnchantmentManager.GetRating(PropertyInt.CritDamageRating);
// equipment ratings
var equipment = GetEquippedItemsRatingSum(PropertyInt.GearCritDamage);
// augmentations
var augBonus = 0;
var lumAugBonus = 0;
if (this is Player player)
{
augBonus = player.AugmentationCriticalPower * 3;
lumAugBonus = player.LumAugCritDamageRating;
}
return critDamageRating + equipment + enchantments + augBonus + lumAugBonus;
}
public int GetCritResistRating()
{
// crit resist chance
// get from base properties (monsters)?
var critResistRating = CritResistRating ?? 0;
// additive enchantments
var enchantments = EnchantmentManager.GetRating(PropertyInt.CritResistRating);
// equipment ratings
var equipment = GetEquippedItemsRatingSum(PropertyInt.GearCritResist);
// no augs / lum augs?
return critResistRating + enchantments + equipment;
}
public int GetCritDamageResistRating()
{
// get from base properties (monsters)?
var critDamageResistRating = CritDamageResistRating ?? 0;
// additive enchantments
var enchantments = EnchantmentManager.GetRating(PropertyInt.CritDamageResistRating);
// equipment ratings
var equipment = GetEquippedItemsRatingSum(PropertyInt.GearCritDamageResist);
var lumAugBonus = 0;
if (this is Player player)
lumAugBonus = player.LumAugCritReductionRating;
return critDamageResistRating + equipment + enchantments + lumAugBonus;
}
public int GetHealingBoostRating()
{
// get from base properties (monsters)?
var healBoostRating = HealingBoostRating ?? 0;
// additive enchantments
var enchantments = EnchantmentManager.GetRating(PropertyInt.HealingBoostRating);
// equipment ratings
var equipment = GetEquippedItemsRatingSum(PropertyInt.GearHealingBoost);
var lumAugBonus = 0;
if (this is Player player)
lumAugBonus = player.LumAugHealingRating;
return healBoostRating + equipment + enchantments + lumAugBonus;
}
public int GetHealingResistRating()
{
// debuff?
var healResistRating = HealingResistRating ?? 0;
// additive enchantments
var enchantments = EnchantmentManager.GetRating(PropertyInt.HealingResistRating);
return healResistRating + enchantments;
}
public float GetHealingRatingMod()
{
var boostMod = GetPositiveRatingMod(GetHealingBoostRating());
var resistMod = GetNegativeRatingMod(GetHealingResistRating());
return boostMod * resistMod;
}
public int GetLifeResistRating()
{
// only affects health drain?
// only cast by Sigil of Perserverance (Aetheria)?
// get from base properties (monsters)?
var lifeResistRating = LifeResistRating ?? 0;
// additive enchantments
var enchantments = EnchantmentManager.GetRating(PropertyInt.LifeResistRating);
return lifeResistRating + enchantments;
}
public float GetLifeResistRatingMod()
{
return GetNegativeRatingMod(GetLifeResistRating());
}
public int GetDotResistanceRating()
{
// get from base properties (monsters)?
var dotResistRating = DotResistRating ?? 0;
// additive enchantments
var enchantments = EnchantmentManager.GetRating(PropertyInt.DotResistRating);
return dotResistRating + enchantments;
}
public int GetNetherResistRating()
{
// there is a property defined for this,
// but does anything use this?
// get from base properties (monsters)?
var netherResistRating = NetherResistRating ?? 0;
// additive enchantments
var enchantments = EnchantmentManager.GetRating(PropertyInt.NetherResistRating);
return netherResistRating + enchantments;
}
public int GetGearMaxHealth()
{
return GetEquippedItemsRatingSum(PropertyInt.GearMaxHealth);
}
public int GetPKDamageRating()
{
var pkDamageRating = PKDamageRating ?? 0;
// additive enchantments?
var enchantments = EnchantmentManager.GetRating(PropertyInt.PKDamageRating);
// equipment ratings
var equipment = GetEquippedItemsRatingSum(PropertyInt.GearPKDamageRating);
return pkDamageRating + equipment + enchantments;
}
public int GetPKDamageResistRating()
{
var pkDamageResistRating = PKDamageResistRating ?? 0;
// additive enchantments?
var enchantments = EnchantmentManager.GetRating(PropertyInt.PKDamageResistRating);
// equipment ratings
var equipment = GetEquippedItemsRatingSum(PropertyInt.GearPKDamageResistRating);
return pkDamageResistRating + equipment + enchantments;
}
public int GetGearPKDamageRating()
{
return GetEquippedItemsRatingSum(PropertyInt.GearPKDamageRating);
}
public int GetGearPKDamageResistRating()
{
return GetEquippedItemsRatingSum(PropertyInt.GearPKDamageResistRating);
}
public int GetItemManaReductionRating()
{
// only comes from luminance aug?
var lumAugBonus = 0;
if (this is Player player)
lumAugBonus = player.LumAugItemManaUsage;
return lumAugBonus;
}
public int GetManaChargeRating()
{
// only comes from luminance aug?
var lumAugBonus = 0;
if (this is Player player)
lumAugBonus = player.LumAugItemManaGain;
return lumAugBonus;
}
}
}