mirror of
https://github.com/ACEmulator/ACE
synced 2026-08-17 12:26:06 -04:00
359 lines
16 KiB
C#
359 lines
16 KiB
C#
using System;
|
|
using ACE.Entity.Enum;
|
|
using ACE.Entity.Enum.Properties;
|
|
using ACE.Server.Managers;
|
|
|
|
namespace ACE.Server.WorldObjects
|
|
{
|
|
partial class Creature
|
|
{
|
|
public double? ResistSlash
|
|
{
|
|
get => GetProperty(PropertyFloat.ResistSlash);
|
|
set { if (!value.HasValue) RemoveProperty(PropertyFloat.ResistSlash); else SetProperty(PropertyFloat.ResistSlash, value.Value); }
|
|
}
|
|
|
|
public double? ResistPierce
|
|
{
|
|
get => GetProperty(PropertyFloat.ResistPierce);
|
|
set { if (!value.HasValue) RemoveProperty(PropertyFloat.ResistPierce); else SetProperty(PropertyFloat.ResistPierce, value.Value); }
|
|
}
|
|
|
|
public double? ResistBludgeon
|
|
{
|
|
get => GetProperty(PropertyFloat.ResistBludgeon);
|
|
set { if (!value.HasValue) RemoveProperty(PropertyFloat.ResistBludgeon); else SetProperty(PropertyFloat.ResistBludgeon, value.Value); }
|
|
}
|
|
|
|
public double? ResistFire
|
|
{
|
|
get => GetProperty(PropertyFloat.ResistFire);
|
|
set { if (!value.HasValue) RemoveProperty(PropertyFloat.ResistFire); else SetProperty(PropertyFloat.ResistFire, value.Value); }
|
|
}
|
|
|
|
public double? ResistCold
|
|
{
|
|
get => GetProperty(PropertyFloat.ResistCold);
|
|
set { if (!value.HasValue) RemoveProperty(PropertyFloat.ResistCold); else SetProperty(PropertyFloat.ResistCold, value.Value); }
|
|
}
|
|
|
|
public double? ResistAcid
|
|
{
|
|
get => GetProperty(PropertyFloat.ResistAcid);
|
|
set { if (!value.HasValue) RemoveProperty(PropertyFloat.ResistAcid); else SetProperty(PropertyFloat.ResistAcid, value.Value); }
|
|
}
|
|
|
|
public double? ResistElectric
|
|
{
|
|
get => GetProperty(PropertyFloat.ResistElectric);
|
|
set { if (!value.HasValue) RemoveProperty(PropertyFloat.ResistElectric); else SetProperty(PropertyFloat.ResistElectric, value.Value); }
|
|
}
|
|
|
|
public double? ResistHealthDrain
|
|
{
|
|
get => GetProperty(PropertyFloat.ResistHealthDrain);
|
|
set { if (!value.HasValue) RemoveProperty(PropertyFloat.ResistHealthDrain); else SetProperty(PropertyFloat.ResistHealthDrain, value.Value); }
|
|
}
|
|
|
|
public double? ResistHealthBoost
|
|
{
|
|
get => GetProperty(PropertyFloat.ResistHealthBoost);
|
|
set { if (!value.HasValue) RemoveProperty(PropertyFloat.ResistHealthBoost); else SetProperty(PropertyFloat.ResistHealthBoost, value.Value); }
|
|
}
|
|
|
|
public double? ResistStaminaDrain
|
|
{
|
|
get => GetProperty(PropertyFloat.ResistStaminaDrain);
|
|
set { if (!value.HasValue) RemoveProperty(PropertyFloat.ResistStaminaDrain); else SetProperty(PropertyFloat.ResistStaminaDrain, value.Value); }
|
|
}
|
|
|
|
public double? ResistStaminaBoost
|
|
{
|
|
get => GetProperty(PropertyFloat.ResistStaminaBoost);
|
|
set { if (!value.HasValue) RemoveProperty(PropertyFloat.ResistStaminaBoost); else SetProperty(PropertyFloat.ResistStaminaBoost, value.Value); }
|
|
}
|
|
|
|
public double? ResistManaDrain
|
|
{
|
|
get => GetProperty(PropertyFloat.ResistManaDrain);
|
|
set { if (!value.HasValue) RemoveProperty(PropertyFloat.ResistManaDrain); else SetProperty(PropertyFloat.ResistManaDrain, value.Value); }
|
|
}
|
|
|
|
public double? ResistManaBoost
|
|
{
|
|
get => GetProperty(PropertyFloat.ResistManaBoost);
|
|
set { if (!value.HasValue) RemoveProperty(PropertyFloat.ResistManaBoost); else SetProperty(PropertyFloat.ResistManaBoost, value.Value); }
|
|
}
|
|
|
|
public double? ResistNether
|
|
{
|
|
get => GetProperty(PropertyFloat.ResistNether);
|
|
set { if (!value.HasValue) RemoveProperty(PropertyFloat.ResistNether); else SetProperty(PropertyFloat.ResistNether, value.Value); }
|
|
}
|
|
|
|
public bool NonProjectileMagicImmune
|
|
{
|
|
get => GetProperty(PropertyBool.NonProjectileMagicImmune) ?? false;
|
|
set { if (!value) RemoveProperty(PropertyBool.NonProjectileMagicImmune); else SetProperty(PropertyBool.NonProjectileMagicImmune, value); }
|
|
}
|
|
|
|
public float GetResistanceMod(DamageType damageType, WorldObject attacker, WorldObject weapon, float weaponResistanceMod = 1.0f)
|
|
{
|
|
var ignoreMagicResist = (weapon?.IgnoreMagicResist ?? false) || (attacker?.IgnoreMagicResist ?? false);
|
|
|
|
// hollow weapons also ignore player natural resistances
|
|
if (ignoreMagicResist)
|
|
{
|
|
if (!(attacker is Player) || !(this is Player) || PropertyManager.GetDouble("ignore_magic_resist_pvp_scalar").Item == 1.0)
|
|
return weaponResistanceMod;
|
|
}
|
|
|
|
var protMod = EnchantmentManager.GetProtectionResistanceMod(damageType);
|
|
var vulnMod = EnchantmentManager.GetVulnerabilityResistanceMod(damageType);
|
|
|
|
var naturalResistMod = GetNaturalResistance(damageType);
|
|
|
|
// protection mod becomes either life protection or natural resistance,
|
|
// whichever is more powerful (more powerful = lower value here)
|
|
if (protMod > naturalResistMod)
|
|
protMod = naturalResistMod;
|
|
|
|
// does this stack with natural resistance?
|
|
if (this is Player player)
|
|
{
|
|
var resistAug = player.GetAugmentationResistance(damageType);
|
|
if (resistAug > 0)
|
|
{
|
|
var augFactor = Math.Min(1.0f, resistAug * 0.1f);
|
|
protMod *= 1.0f - augFactor;
|
|
}
|
|
}
|
|
|
|
// vulnerability mod becomes either life vuln or weapon resistance mod,
|
|
// whichever is more powerful
|
|
if (vulnMod < weaponResistanceMod)
|
|
vulnMod = weaponResistanceMod;
|
|
|
|
if (ignoreMagicResist)
|
|
{
|
|
// convert to additive space
|
|
var addProt = -ModToRating(protMod);
|
|
var addVuln = ModToRating(vulnMod);
|
|
|
|
// scale
|
|
addProt = IgnoreMagicResistScaled(addProt);
|
|
addVuln = IgnoreMagicResistScaled(addVuln);
|
|
|
|
protMod = GetNegativeRatingMod(addProt);
|
|
vulnMod = GetPositiveRatingMod(addVuln);
|
|
}
|
|
|
|
return protMod * vulnMod;
|
|
}
|
|
|
|
public virtual float GetNaturalResistance(DamageType damageType)
|
|
{
|
|
// overridden for players
|
|
return 1.0f;
|
|
}
|
|
|
|
public double GetArmorVsType(DamageType damageType)
|
|
{
|
|
switch (damageType)
|
|
{
|
|
case DamageType.Slash:
|
|
return GetProperty(PropertyFloat.ArmorModVsSlash) ?? 1.0f;
|
|
case DamageType.Pierce:
|
|
return GetProperty(PropertyFloat.ArmorModVsPierce) ?? 1.0f;
|
|
case DamageType.Bludgeon:
|
|
return GetProperty(PropertyFloat.ArmorModVsBludgeon) ?? 1.0f;
|
|
case DamageType.Fire:
|
|
return GetProperty(PropertyFloat.ArmorModVsFire) ?? 1.0f;
|
|
case DamageType.Cold:
|
|
return GetProperty(PropertyFloat.ArmorModVsCold) ?? 1.0f;
|
|
case DamageType.Acid:
|
|
return GetProperty(PropertyFloat.ArmorModVsAcid) ?? 1.0f;
|
|
case DamageType.Electric:
|
|
return GetProperty(PropertyFloat.ArmorModVsElectric) ?? 1.0f;
|
|
case DamageType.Nether:
|
|
return GetProperty(PropertyFloat.ArmorModVsNether) ?? 1.0f;
|
|
default:
|
|
return 1.0f;
|
|
}
|
|
}
|
|
|
|
public double GetResistanceMod(ResistanceType resistance, WorldObject attacker = null, WorldObject weapon = null, float weaponResistanceMod = 1.0f)
|
|
{
|
|
switch (resistance)
|
|
{
|
|
case ResistanceType.Slash:
|
|
return (ResistSlash ?? 1.0) * GetResistanceMod(DamageType.Slash, attacker, weapon, weaponResistanceMod);
|
|
case ResistanceType.Pierce:
|
|
return (ResistPierce ?? 1.0) * GetResistanceMod(DamageType.Pierce, attacker, weapon, weaponResistanceMod);
|
|
case ResistanceType.Bludgeon:
|
|
return (ResistBludgeon ?? 1.0) * GetResistanceMod(DamageType.Bludgeon, attacker, weapon, weaponResistanceMod);
|
|
case ResistanceType.Fire:
|
|
return (ResistFire ?? 1.0) * GetResistanceMod(DamageType.Fire, attacker, weapon, weaponResistanceMod);
|
|
case ResistanceType.Cold:
|
|
return (ResistCold ?? 1.0) * GetResistanceMod(DamageType.Cold, attacker, weapon, weaponResistanceMod);
|
|
case ResistanceType.Acid:
|
|
return (ResistAcid ?? 1.0) * GetResistanceMod(DamageType.Acid, attacker, weapon, weaponResistanceMod);
|
|
case ResistanceType.Electric:
|
|
return (ResistElectric ?? 1.0) * GetResistanceMod(DamageType.Electric, attacker, weapon, weaponResistanceMod);
|
|
case ResistanceType.Nether:
|
|
return (ResistNether ?? 1.0) * GetResistanceMod(DamageType.Nether, attacker, weapon, weaponResistanceMod);
|
|
case ResistanceType.HealthBoost:
|
|
return (ResistHealthBoost ?? 1.0) * GetHealingRatingMod();
|
|
case ResistanceType.HealthDrain:
|
|
return (ResistHealthDrain ?? 1.0) * GetNaturalResistance(DamageType.Health) * GetLifeResistRatingMod();
|
|
case ResistanceType.StaminaBoost:
|
|
return (ResistStaminaBoost ?? 1.0) * GetHealingRatingMod(); // does healing rating affect these?
|
|
case ResistanceType.StaminaDrain:
|
|
return (ResistStaminaDrain ?? 1.0) * GetNaturalResistance(DamageType.Stamina);
|
|
case ResistanceType.ManaBoost:
|
|
return (ResistManaBoost ?? 1.0) * GetHealingRatingMod();
|
|
case ResistanceType.ManaDrain:
|
|
return (ResistManaDrain ?? 1.0) * GetNaturalResistance(DamageType.Mana);
|
|
default:
|
|
return 1.0;
|
|
}
|
|
}
|
|
|
|
public double? HealthRate
|
|
{
|
|
get => GetProperty(PropertyFloat.HealthRate);
|
|
set { if (!value.HasValue) RemoveProperty(PropertyFloat.HealthRate); else SetProperty(PropertyFloat.HealthRate, value.Value); }
|
|
}
|
|
|
|
public double? StaminaRate
|
|
{
|
|
get => GetProperty(PropertyFloat.StaminaRate);
|
|
set { if (!value.HasValue) RemoveProperty(PropertyFloat.StaminaRate); else SetProperty(PropertyFloat.StaminaRate, value.Value); }
|
|
}
|
|
|
|
public double ResistSlashMod => (ResistSlash ?? 1.0) * EnchantmentManager.GetResistanceMod(DamageType.Slash);
|
|
public double ResistPierceMod => (ResistPierce ?? 1.0) * EnchantmentManager.GetResistanceMod(DamageType.Pierce);
|
|
public double ResistBludgeonMod => (ResistBludgeon ?? 1.0) * EnchantmentManager.GetResistanceMod(DamageType.Bludgeon);
|
|
public double ResistFireMod => (ResistFire ?? 1.0) * EnchantmentManager.GetResistanceMod(DamageType.Fire);
|
|
public double ResistColdMod => (ResistCold ?? 1.0) * EnchantmentManager.GetResistanceMod(DamageType.Cold);
|
|
public double ResistAcidMod => (ResistAcid ?? 1.0) * EnchantmentManager.GetResistanceMod(DamageType.Acid);
|
|
public double ResistElectricMod => (ResistElectric ?? 1.0) * EnchantmentManager.GetResistanceMod(DamageType.Electric);
|
|
public double ResistNetherMod => (ResistNether ?? 1.0) * EnchantmentManager.GetResistanceMod(DamageType.Nether);
|
|
|
|
public bool NoCorpse
|
|
{
|
|
get => GetProperty(PropertyBool.NoCorpse) ?? false;
|
|
set { if (!value) RemoveProperty(PropertyBool.NoCorpse); else SetProperty(PropertyBool.NoCorpse, value); }
|
|
}
|
|
|
|
public bool TreasureCorpse
|
|
{
|
|
get => GetProperty(PropertyBool.TreasureCorpse) ?? false;
|
|
set { if (!value) RemoveProperty(PropertyBool.TreasureCorpse); else SetProperty(PropertyBool.TreasureCorpse, value); }
|
|
}
|
|
|
|
public uint? DeathTreasureType
|
|
{
|
|
get => GetProperty(PropertyDataId.DeathTreasureType);
|
|
set { if (!value.HasValue) RemoveProperty(PropertyDataId.DeathTreasureType); else SetProperty(PropertyDataId.DeathTreasureType, value.Value); }
|
|
}
|
|
|
|
public int? LuminanceAward
|
|
{
|
|
get => GetProperty(PropertyInt.LuminanceAward);
|
|
set { if (!value.HasValue) RemoveProperty(PropertyInt.LuminanceAward); else SetProperty(PropertyInt.LuminanceAward, value.Value); }
|
|
}
|
|
|
|
public bool AiImmobile
|
|
{
|
|
get => GetProperty(PropertyBool.AiImmobile) ?? false;
|
|
set { if (!value) RemoveProperty(PropertyBool.AiImmobile); else SetProperty(PropertyBool.AiImmobile, value); }
|
|
}
|
|
|
|
public int? Overpower
|
|
{
|
|
get => GetProperty(PropertyInt.Overpower);
|
|
set { if (!value.HasValue) RemoveProperty(PropertyInt.Overpower); else SetProperty(PropertyInt.Overpower, value.Value); }
|
|
}
|
|
|
|
public int? OverpowerResist
|
|
{
|
|
get => GetProperty(PropertyInt.OverpowerResist);
|
|
set { if (!value.HasValue) RemoveProperty(PropertyInt.OverpowerResist); else SetProperty(PropertyInt.OverpowerResist, value.Value); }
|
|
}
|
|
|
|
public string KillQuest
|
|
{
|
|
get => GetProperty(PropertyString.KillQuest);
|
|
set { if (value == null) RemoveProperty(PropertyString.KillQuest); else SetProperty(PropertyString.KillQuest, value); }
|
|
}
|
|
|
|
public string KillQuest2
|
|
{
|
|
get => GetProperty(PropertyString.KillQuest2);
|
|
set { if (value == null) RemoveProperty(PropertyString.KillQuest2); else SetProperty(PropertyString.KillQuest2, value); }
|
|
}
|
|
|
|
public string KillQuest3
|
|
{
|
|
get => GetProperty(PropertyString.KillQuest3);
|
|
set { if (value == null) RemoveProperty(PropertyString.KillQuest3); else SetProperty(PropertyString.KillQuest3, value); }
|
|
}
|
|
|
|
public FactionBits? Faction1Bits
|
|
{
|
|
get => (FactionBits?)GetProperty(PropertyInt.Faction1Bits);
|
|
set { if (!value.HasValue) RemoveProperty(PropertyInt.Faction1Bits); else SetProperty(PropertyInt.Faction1Bits, (int)value); }
|
|
}
|
|
|
|
public int? Faction2Bits
|
|
{
|
|
get => GetProperty(PropertyInt.Faction2Bits);
|
|
set { if (!value.HasValue) RemoveProperty(PropertyInt.Faction2Bits); else SetProperty(PropertyInt.Faction2Bits, value.Value); }
|
|
}
|
|
|
|
public int? Faction3Bits
|
|
{
|
|
get => GetProperty(PropertyInt.Faction3Bits);
|
|
set { if (!value.HasValue) RemoveProperty(PropertyInt.Faction3Bits); else SetProperty(PropertyInt.Faction3Bits, value.Value); }
|
|
}
|
|
|
|
public int? Hatred1Bits
|
|
{
|
|
get => GetProperty(PropertyInt.Hatred1Bits);
|
|
set { if (!value.HasValue) RemoveProperty(PropertyInt.Hatred1Bits); else SetProperty(PropertyInt.Hatred1Bits, value.Value); }
|
|
}
|
|
|
|
public int? Hatred2Bits
|
|
{
|
|
get => GetProperty(PropertyInt.Hatred2Bits);
|
|
set { if (!value.HasValue) RemoveProperty(PropertyInt.Hatred2Bits); else SetProperty(PropertyInt.Hatred2Bits, value.Value); }
|
|
}
|
|
|
|
public int? Hatred3Bits
|
|
{
|
|
get => GetProperty(PropertyInt.Hatred3Bits);
|
|
set { if (!value.HasValue) RemoveProperty(PropertyInt.Hatred3Bits); else SetProperty(PropertyInt.Hatred3Bits, value.Value); }
|
|
}
|
|
|
|
public int? SocietyRankCelhan
|
|
{
|
|
get => GetProperty(PropertyInt.SocietyRankCelhan);
|
|
set { if (!value.HasValue) RemoveProperty(PropertyInt.SocietyRankCelhan); else SetProperty(PropertyInt.SocietyRankCelhan, value.Value); }
|
|
}
|
|
|
|
public int? SocietyRankEldweb
|
|
{
|
|
get => GetProperty(PropertyInt.SocietyRankEldweb);
|
|
set { if (!value.HasValue) RemoveProperty(PropertyInt.SocietyRankEldweb); else SetProperty(PropertyInt.SocietyRankEldweb, value.Value); }
|
|
}
|
|
|
|
public int? SocietyRankRadblo
|
|
{
|
|
get => GetProperty(PropertyInt.SocietyRankRadblo);
|
|
set { if (!value.HasValue) RemoveProperty(PropertyInt.SocietyRankRadblo); else SetProperty(PropertyInt.SocietyRankRadblo, value.Value); }
|
|
}
|
|
|
|
public FactionBits Society => Faction1Bits ?? FactionBits.None;
|
|
}
|
|
}
|