/// <summary> /// Called for a spell projectile to damage its target /// </summary> public void DamageTarget(WorldObject _target, double?damage, bool critical, bool critDefended, bool overpower) { var player = ProjectileSource as Player; var target = _target as Creature; var targetPlayer = _target as Player; if (targetPlayer != null && (targetPlayer.Invincible || targetPlayer.IsDead)) { return; } uint amount; var percent = 0.0f; var heritageMod = 1.0f; var sneakAttackMod = 1.0f; // handle life projectiles for stamina / mana if (Spell.Category == SpellCategory.StaminaLowering) { percent = (float)damage / target.Stamina.MaxValue; amount = (uint)-target.UpdateVitalDelta(target.Stamina, (int)-Math.Round(damage.Value)); } else if (Spell.Category == SpellCategory.ManaLowering) { percent = (float)damage / target.Mana.MaxValue; amount = (uint)-target.UpdateVitalDelta(target.Mana, (int)-Math.Round(damage.Value)); } else { // for possibly applying sneak attack to magic projectiles, // only do this for health-damaging projectiles? if (player != null) { // TODO: use target direction vs. projectile position, instead of player position // could sneak attack be applied to void DoTs? sneakAttackMod = player.GetSneakAttackMod(target); //Console.WriteLine("Magic sneak attack: + sneakAttackMod); heritageMod = player.GetHeritageBonus(player.GetEquippedWand()) ? 1.05f : 1.0f; } // DR / DRR applies for magic too? var creatureSource = ProjectileSource as Creature; var damageRating = creatureSource != null?creatureSource.GetDamageRating() : 0; var damageRatingMod = Creature.AdditiveCombine(Creature.GetPositiveRatingMod(damageRating), heritageMod, sneakAttackMod); var damageResistRatingMod = Creature.GetNegativeRatingMod(target.GetDamageResistRating(CombatType.Magic)); damage *= damageRatingMod * damageResistRatingMod; //Console.WriteLine($"Damage rating: " + Creature.ModToRating(damageRatingMod)); percent = (float)damage / target.Health.MaxValue; amount = (uint)-target.UpdateVitalDelta(target.Health, (int)-Math.Round(damage.Value)); target.DamageHistory.Add(ProjectileSource, Spell.DamageType, amount); //if (targetPlayer != null && targetPlayer.Fellowship != null) //targetPlayer.Fellowship.OnVitalUpdate(targetPlayer); } amount = (uint)Math.Round(damage.Value); // full amount for debugging if (critical) { target.EmoteManager.OnReceiveCritical(player); } if (target.IsAlive) { string verb = null, plural = null; Strings.GetAttackVerb(Spell.DamageType, percent, ref verb, ref plural); var type = Spell.DamageType.GetName().ToLower(); var critMsg = critical ? "Critical hit! " : ""; var sneakMsg = sneakAttackMod > 1.0f ? "Sneak Attack! " : ""; var overpowerMsg = overpower ? "Overpower! " : ""; if (player != null) { var critProt = critDefended ? " Your target's Critical Protection augmentation allows them to avoid your critical hit!" : ""; var attackerMsg = $"{critMsg}{overpowerMsg}{sneakMsg}You {verb} {target.Name} for {amount} points with {Spell.Name}.{critProt}"; // could these crit / sneak attack? if (Spell.Category == SpellCategory.StaminaLowering || Spell.Category == SpellCategory.ManaLowering) { var vital = Spell.Category == SpellCategory.StaminaLowering ? "stamina" : "mana"; attackerMsg = $"With {Spell.Name} you drain {amount} points of {vital} from {target.Name}."; } if (!player.SquelchManager.Squelches.Contains(target, ChatMessageType.Magic)) { player.Session.Network.EnqueueSend(new GameMessageSystemChat(attackerMsg, ChatMessageType.Magic)); } player.Session.Network.EnqueueSend(new GameEventUpdateHealth(player.Session, target.Guid.Full, (float)target.Health.Current / target.Health.MaxValue)); } if (targetPlayer != null) { var critProt = critDefended ? " Your Critical Protection augmentation allows you to avoid a critical hit!" : ""; var defenderMsg = $"{critMsg}{overpowerMsg}{sneakMsg}{ProjectileSource.Name} {plural} you for {amount} points with {Spell.Name}.{critProt}"; if (Spell.Category == SpellCategory.StaminaLowering || Spell.Category == SpellCategory.ManaLowering) { var vital = Spell.Category == SpellCategory.StaminaLowering ? "stamina" : "mana"; defenderMsg = $"{ProjectileSource.Name} casts {Spell.Name} and drains {amount} points of your {vital}."; } if (!targetPlayer.SquelchManager.Squelches.Contains(ProjectileSource, ChatMessageType.Magic)) { targetPlayer.Session.Network.EnqueueSend(new GameMessageSystemChat(defenderMsg, ChatMessageType.Magic)); } } } else { var lastDamager = ProjectileSource != null ? new DamageHistoryInfo(ProjectileSource) : null; target.OnDeath(lastDamager, Spell.DamageType, critical); target.Die(); } }
/// <summary> /// Called for a spell projectile to damage its target /// </summary> public void DamageTarget(WorldObject _target, double?damage, bool critical) { var player = ProjectileSource as Player; var target = _target as Creature; var targetPlayer = _target as Player; { uint amount; var percent = 0.0f; var sneakAttackMod = 1.0f; // handle life projectiles for stamina / mana if (Spell.School == MagicSchool.LifeMagic && (Spell.Name.Contains("Blight") || Spell.Name.Contains("Tenacity"))) { if (Spell.Name.Contains("Blight")) { percent = (float)damage / targetPlayer.Mana.MaxValue; amount = (uint)-target.UpdateVitalDelta(target.Mana, (int)-Math.Round(damage.Value)); } else { percent = (float)damage / targetPlayer.Stamina.MaxValue; amount = (uint)-target.UpdateVitalDelta(target.Stamina, (int)-Math.Round(damage.Value)); } } else { // for possibly applying sneak attack to magic projectiles, // only do this for health-damaging projectiles? if (player != null) { // TODO: use target direction vs. projectile position, instead of player position // could sneak attack be applied to void DoTs? sneakAttackMod = player.GetSneakAttackMod(target); //Console.WriteLine("Magic sneak attack: + sneakAttackMod); damage *= sneakAttackMod; } // DR / DRR applies for magic too? var damageRatingMod = Creature.GetRatingMod(ProjectileSource.EnchantmentManager.GetDamageRating()); var damageResistRatingMod = Creature.GetNegativeRatingMod(target.EnchantmentManager.GetDamageResistRating()); damage *= damageRatingMod * damageResistRatingMod; percent = (float)damage / target.Health.MaxValue; amount = (uint)-target.UpdateVitalDelta(target.Health, (int)-Math.Round(damage.Value)); target.DamageHistory.Add(ProjectileSource, Spell.DamageType, amount); } amount = (uint)Math.Round(damage.Value); // full amount for debugging if (target.IsAlive) { string verb = null, plural = null; Strings.GetAttackVerb(Spell.DamageType, percent, ref verb, ref plural); var type = Spell.DamageType.GetName().ToLower(); var critMsg = critical ? "Critical hit! " : ""; var sneakMsg = sneakAttackMod > 1.0f ? "Sneak Attack! " : ""; if (player != null) { var attackerMsg = new GameMessageSystemChat($"{critMsg}{sneakMsg}You {verb} {target.Name} for {amount} points of {type} damage!", ChatMessageType.Magic); var updateHealth = new GameEventUpdateHealth(player.Session, target.Guid.Full, (float)target.Health.Current / target.Health.MaxValue); player.Session.Network.EnqueueSend(attackerMsg, updateHealth); } if (targetPlayer != null) { targetPlayer.Session.Network.EnqueueSend(new GameMessageSystemChat($"{critMsg}{sneakMsg}{ProjectileSource.Name} {plural} you for {amount} points of {type} damage!", ChatMessageType.Magic)); } } else { target.OnDeath(ProjectileSource, Spell.DamageType, critical); target.Die(); } } }
/// <summary> /// Called for a spell projectile to damage its target /// </summary> public void DamageTarget(Creature target, float damage, bool critical, bool critDefended, bool overpower) { var targetPlayer = target as Player; if (targetPlayer != null && targetPlayer.Invincible || target.IsDead) { return; } var sourceCreature = ProjectileSource as Creature; var sourcePlayer = ProjectileSource as Player; var amount = 0u; var percent = 0.0f; var damageRatingMod = 1.0f; var heritageMod = 1.0f; var sneakAttackMod = 1.0f; var critDamageRatingMod = 1.0f; var damageResistRatingMod = 1.0f; var critDamageResistRatingMod = 1.0f; WorldObject equippedCloak = null; // handle life projectiles for stamina / mana if (Spell.Category == SpellCategory.StaminaLowering) { percent = damage / target.Stamina.MaxValue; amount = (uint)-target.UpdateVitalDelta(target.Stamina, (int)-Math.Round(damage)); } else if (Spell.Category == SpellCategory.ManaLowering) { percent = damage / target.Mana.MaxValue; amount = (uint)-target.UpdateVitalDelta(target.Mana, (int)-Math.Round(damage)); } else { // for possibly applying sneak attack to magic projectiles, // only do this for health-damaging projectiles? if (sourcePlayer != null) { // TODO: use target direction vs. projectile position, instead of player position // could sneak attack be applied to void DoTs? sneakAttackMod = sourcePlayer.GetSneakAttackMod(target); //Console.WriteLine("Magic sneak attack: + sneakAttackMod); heritageMod = sourcePlayer.GetHeritageBonus(sourcePlayer.GetEquippedWand()) ? 1.05f : 1.0f; } var damageRating = sourceCreature?.GetDamageRating() ?? 0; damageRatingMod = Creature.AdditiveCombine(Creature.GetPositiveRatingMod(damageRating), heritageMod, sneakAttackMod); damageResistRatingMod = target.GetDamageResistRatingMod(CombatType.Magic); if (critical) { critDamageRatingMod = Creature.GetPositiveRatingMod(sourceCreature?.GetCritDamageRating() ?? 0); critDamageResistRatingMod = Creature.GetNegativeRatingMod(target.GetCritDamageResistRating()); damageRatingMod = Creature.AdditiveCombine(damageRatingMod, critDamageRatingMod); damageResistRatingMod = Creature.AdditiveCombine(damageResistRatingMod, critDamageResistRatingMod); } damage *= damageRatingMod * damageResistRatingMod; percent = damage / target.Health.MaxValue; //Console.WriteLine($"Damage rating: " + Creature.ModToRating(damageRatingMod)); equippedCloak = target.EquippedCloak; if (equippedCloak != null && Cloak.HasDamageProc(equippedCloak) && Cloak.RollProc(equippedCloak, percent)) { var reducedDamage = Cloak.GetReducedAmount(ProjectileSource, damage); Cloak.ShowMessage(target, ProjectileSource, damage, reducedDamage); damage = reducedDamage; percent = damage / target.Health.MaxValue; } amount = (uint)-target.UpdateVitalDelta(target.Health, (int)-Math.Round(damage)); target.DamageHistory.Add(ProjectileSource, Spell.DamageType, amount); //if (targetPlayer != null && targetPlayer.Fellowship != null) //targetPlayer.Fellowship.OnVitalUpdate(targetPlayer); } amount = (uint)Math.Round(damage); // full amount for debugging // show debug info if (sourceCreature != null && sourceCreature.DebugDamage.HasFlag(Creature.DebugDamageType.Attacker)) { ShowInfo(sourceCreature, heritageMod, sneakAttackMod, damageRatingMod, damageResistRatingMod, critDamageRatingMod, critDamageResistRatingMod, damage); } if (target.DebugDamage.HasFlag(Creature.DebugDamageType.Defender)) { ShowInfo(target, heritageMod, sneakAttackMod, damageRatingMod, damageResistRatingMod, critDamageRatingMod, critDamageResistRatingMod, damage); } if (target.IsAlive) { string verb = null, plural = null; Strings.GetAttackVerb(Spell.DamageType, percent, ref verb, ref plural); var type = Spell.DamageType.GetName().ToLower(); var critMsg = critical ? "Critical hit! " : ""; var sneakMsg = sneakAttackMod > 1.0f ? "Sneak Attack! " : ""; var overpowerMsg = overpower ? "Overpower! " : ""; var nonHealth = Spell.Category == SpellCategory.StaminaLowering || Spell.Category == SpellCategory.ManaLowering; if (sourcePlayer != null) { var critProt = critDefended ? " Your critical hit was avoided with their augmentation!" : ""; var attackerMsg = $"{critMsg}{overpowerMsg}{sneakMsg}You {verb} {target.Name} for {amount} points with {Spell.Name}.{critProt}"; // could these crit / sneak attack? if (nonHealth) { var vital = Spell.Category == SpellCategory.StaminaLowering ? "stamina" : "mana"; attackerMsg = $"With {Spell.Name} you drain {amount} points of {vital} from {target.Name}."; } if (!sourcePlayer.SquelchManager.Squelches.Contains(target, ChatMessageType.Magic)) { sourcePlayer.Session.Network.EnqueueSend(new GameMessageSystemChat(attackerMsg, ChatMessageType.Magic)); } } if (targetPlayer != null) { var critProt = critDefended ? " Your augmentation allows you to avoid a critical hit!" : ""; var defenderMsg = $"{critMsg}{overpowerMsg}{sneakMsg}{ProjectileSource.Name} {plural} you for {amount} points with {Spell.Name}.{critProt}"; if (nonHealth) { var vital = Spell.Category == SpellCategory.StaminaLowering ? "stamina" : "mana"; defenderMsg = $"{ProjectileSource.Name} casts {Spell.Name} and drains {amount} points of your {vital}."; } if (!targetPlayer.SquelchManager.Squelches.Contains(ProjectileSource, ChatMessageType.Magic)) { targetPlayer.Session.Network.EnqueueSend(new GameMessageSystemChat(defenderMsg, ChatMessageType.Magic)); } if (sourceCreature != null) { targetPlayer.SetCurrentAttacker(sourceCreature); } } if (!nonHealth) { if (equippedCloak != null && Cloak.HasProcSpell(equippedCloak)) { Cloak.TryProcSpell(target, ProjectileSource, equippedCloak, percent); } target.EmoteManager.OnDamage(sourcePlayer); if (critical) { target.EmoteManager.OnReceiveCritical(sourcePlayer); } } } else { var lastDamager = ProjectileSource != null ? new DamageHistoryInfo(ProjectileSource) : null; target.OnDeath(lastDamager, Spell.DamageType, critical); target.Die(); } }