diff --git a/Projects/UOContent/Mobiles/Abilities/AreaEffectMonsterAbility.cs b/Projects/UOContent/Mobiles/Abilities/AreaEffectMonsterAbility.cs new file mode 100644 index 000000000..06400c0e3 --- /dev/null +++ b/Projects/UOContent/Mobiles/Abilities/AreaEffectMonsterAbility.cs @@ -0,0 +1,60 @@ +using System; +using Server.Collections; + +namespace Server.Mobiles; + +public abstract class AreaEffectMonsterAbility : MonsterAbility +{ + public override MonsterAbilityTrigger AbilityTrigger => MonsterAbilityTrigger.OnCombatAction; + public override MonsterAbilityType AbilityType => MonsterAbilityType.MassPoison; + + public override double ChanceToTrigger => 0.5; + public override TimeSpan MinTriggerCooldown => TimeSpan.FromSeconds(5.0); + public override TimeSpan MaxTriggerCooldown => TimeSpan.FromSeconds(30.0); + + public virtual int CombatantRange => 3; + + public virtual int AreaRange => 3; + + public override bool CanTrigger(BaseCreature source) + { + if (!base.CanTrigger(source)) + { + return false; + } + + var combatant = source.Combatant; + + // Only do the mass ability as a side-effect of combating a specific target + return combatant?.Deleted == false && combatant.Map == source.Map && source.InRange(combatant.Location, CombatantRange) && + source.CanBeHarmful(combatant) && source.InLOS(combatant); + } + + public override void Trigger(BaseCreature source, Mobile target) + { + // target is null for OnCombatAction triggers + + var eable = source.GetMobilesInRange(2); + using var queue = PooledRefQueue.Create(); + foreach (var m in eable) + { + if (CanEffectTarget(source, m)) + { + queue.Enqueue(m); + } + } + eable.Free(); + + while (queue.Count > 0) + { + DoEffectTarget(source, queue.Dequeue()); + } + + base.Trigger(source, target); + } + + protected virtual bool CanEffectTarget(BaseCreature source, Mobile defender) => + source != defender && defender.Alive && source.IsEnemy(defender) && source.CanBeHarmful(defender); + + protected abstract void DoEffectTarget(BaseCreature source, Mobile defender); +} diff --git a/Projects/UOContent/Mobiles/Abilities/ChaosBreath.cs b/Projects/UOContent/Mobiles/Abilities/ChaosBreath.cs index fa6dc8847..4854cae86 100644 --- a/Projects/UOContent/Mobiles/Abilities/ChaosBreath.cs +++ b/Projects/UOContent/Mobiles/Abilities/ChaosBreath.cs @@ -2,7 +2,7 @@ public class ChaosBreath : FireBreath { - public override int BreathChaosDamage => 100; + public override int ChaosDamage => 100; - public override int BreathFireDamage => 0; + public override int FireDamage => 0; } diff --git a/Projects/UOContent/Mobiles/Abilities/ColdBreath.cs b/Projects/UOContent/Mobiles/Abilities/ColdBreath.cs index 8e6066b66..69981821e 100644 --- a/Projects/UOContent/Mobiles/Abilities/ColdBreath.cs +++ b/Projects/UOContent/Mobiles/Abilities/ColdBreath.cs @@ -2,7 +2,7 @@ public class ColdBreath : FireBreath { - public override int BreathColdDamage => 100; - public override int BreathFireDamage => 0; + public override int ColdDamage => 100; + public override int FireDamage => 0; public override int BreathEffectHue => 0x480; } diff --git a/Projects/UOContent/Mobiles/Abilities/ColossalBlow.cs b/Projects/UOContent/Mobiles/Abilities/ColossalBlow.cs new file mode 100644 index 000000000..23a5661eb --- /dev/null +++ b/Projects/UOContent/Mobiles/Abilities/ColossalBlow.cs @@ -0,0 +1,27 @@ +using Server.Network; + +namespace Server.Mobiles; + +public class ColossalBlow : StunAttack +{ + public override void Trigger(BaseCreature source, Mobile target) + { + target.Animate(21, 6, 1, true, false, 0); + source.PlaySound(0xEE); + target.LocalOverheadMessage( + MessageType.Regular, + 0x3B2, + false, + "You have been stunned by a colossal blow!" + ); + + base.Trigger(source, target); + } + + protected override void Recover(Mobile defender) + { + base.Recover(defender); + + defender.LocalOverheadMessage(MessageType.Regular, 0x3B2, false, "You recover your senses."); + } +} diff --git a/Projects/UOContent/Mobiles/Abilities/DeathExplosion.cs b/Projects/UOContent/Mobiles/Abilities/DeathExplosion.cs new file mode 100644 index 000000000..6ba629a2f --- /dev/null +++ b/Projects/UOContent/Mobiles/Abilities/DeathExplosion.cs @@ -0,0 +1,29 @@ +using System; + +namespace Server.Mobiles; + +public class DeathExplosion : AreaEffectMonsterAbility +{ + public override MonsterAbilityTrigger AbilityTrigger => MonsterAbilityTrigger.OnDeath; + + public override double ChanceToTrigger => 1.0; + public override TimeSpan MinTriggerCooldown => TimeSpan.Zero; + public override TimeSpan MaxTriggerCooldown => TimeSpan.Zero; + + public override bool CanTrigger(BaseCreature source) => true; + + public override void Trigger(BaseCreature source, Mobile target) + { + source.FixedParticles(0x36BD, 20, 10, 5044, EffectLayer.Head); + source. PlaySound(0x307); + + base.Trigger(source, target); + } + + protected override void DoEffectTarget(BaseCreature source, Mobile defender) + { + source.DoHarmful(defender); + // TODO: Is the damage type correct? + AOS.Damage(defender, source, defender.HitsMax / 5, true, 100, 0, 0, 0, 0); + } +} diff --git a/Projects/UOContent/Mobiles/Abilities/DestroyEquipment.cs b/Projects/UOContent/Mobiles/Abilities/DestroyEquipment.cs new file mode 100644 index 000000000..f4a0ab030 --- /dev/null +++ b/Projects/UOContent/Mobiles/Abilities/DestroyEquipment.cs @@ -0,0 +1,55 @@ +using Server.Collections; +using Server.Items; +using Server.Network; + +namespace Server.Mobiles; + +public class DestroyEquipment : MonsterAbilityAttack +{ + public override MonsterAbilityType AbilityType => MonsterAbilityType.DestroyEquipment; + public override MonsterAbilityTrigger AbilityTrigger => MonsterAbilityTrigger.GiveMeleeDamage; + public override double ChanceToTrigger => 0.05; + + public virtual int AttackRange => 1; + + protected override void OnAttack(BaseCreature source, Mobile defender) + { + base.OnAttack(source, defender); + using var queue = PooledRefQueue.Create(); + + for (var i = 0; i < defender.Items.Count; i++) + { + var item = defender.Items[i]; + if (item.Deleted || item.LootType is LootType.Blessed or LootType.Newbied || item.BlessedFor != null) + { + continue; + } + + if (!(Mobile.InsuranceEnabled && item.Insured) && item is IDurability { MaxHitPoints: > 0 }) + { + queue.Enqueue(item); + } + } + + if (queue.Count == 0) + { + return; + } + + var toDestroy = queue.PeekRandom(); + var name = toDestroy.Name?.Trim().DefaultIfNullOrEmpty(toDestroy.ItemData.Name); + + // TODO: Is there supposed to be a special effect? + // TODO: Is there supposed to be a special sound? + toDestroy.Delete(); + + // Their ~1_NAME~ is destroyed by the attack. + defender.NonlocalOverheadMessage(MessageType.Regular, 0x3B2, 1080034, name); + + // Your ~1_NAME~ is destroyed by the attack. + defender.LocalOverheadMessage(MessageType.Regular, 0x3B2, 1080035, name); + } + + protected override bool CanEffectTarget(BaseCreature source, Mobile defender) => + defender.Player && defender.AccessLevel == AccessLevel.Player && source.InRange(defender, AttackRange); +} diff --git a/Projects/UOContent/Mobiles/Abilities/FireBreath.cs b/Projects/UOContent/Mobiles/Abilities/FireBreath.cs index f5038dbb6..527f586db 100644 --- a/Projects/UOContent/Mobiles/Abilities/FireBreath.cs +++ b/Projects/UOContent/Mobiles/Abilities/FireBreath.cs @@ -5,7 +5,7 @@ namespace Server.Mobiles; public class FireBreath : MonsterAbility { - public override MonsterAbilityTrigger AbilityTrigger => MonsterAbilityTrigger.Action; + public override MonsterAbilityTrigger AbilityTrigger => MonsterAbilityTrigger.OnAction; public override MonsterAbilityType AbilityType => MonsterAbilityType.FireBreath; public override double ChanceToTrigger => 0.5; @@ -27,12 +27,12 @@ public class FireBreath : MonsterAbility public virtual int BreathRange(BaseCreature source) => source.RangePerception; // Damage Types - public virtual int BreathChaosDamage => 0; - public virtual int BreathPhysicalDamage => 0; - public virtual int BreathFireDamage => 100; - public virtual int BreathColdDamage => 0; - public virtual int BreathPoisonDamage => 0; - public virtual int BreathEnergyDamage => 0; + public virtual int ChaosDamage => 0; + public virtual int PhysicalDamage => 0; + public virtual int FireDamage => 100; + public virtual int ColdDamage => 0; + public virtual int PoisonDamage => 0; + public virtual int EnergyDamage => 0; // Effect details and sound public virtual int BreathEffectItemID => 0x36D4; @@ -146,39 +146,39 @@ public class FireBreath : MonsterAbility { if (!Evasion.CheckSpellEvasion(target)) { - var physDamage = BreathPhysicalDamage; - var fireDamage = BreathFireDamage; - var coldDamage = BreathColdDamage; - var poisDamage = BreathPoisonDamage; - var nrgyDamage = BreathEnergyDamage; + var physDamage = PhysicalDamage; + var fireDamage = FireDamage; + var coldDamage = ColdDamage; + var poisDamage = PoisonDamage; + var nrgyDamage = EnergyDamage; - if (BreathChaosDamage > 0) + if (ChaosDamage > 0) { switch (Utility.Random(5)) { case 0: { - physDamage += BreathChaosDamage; + physDamage += ChaosDamage; break; } case 1: { - fireDamage += BreathChaosDamage; + fireDamage += ChaosDamage; break; } case 2: { - coldDamage += BreathChaosDamage; + coldDamage += ChaosDamage; break; } case 3: { - poisDamage += BreathChaosDamage; + poisDamage += ChaosDamage; break; } case 4: { - nrgyDamage += BreathChaosDamage; + nrgyDamage += ChaosDamage; break; } } diff --git a/Projects/UOContent/Mobiles/Abilities/MonsterAbility.Abilities.cs b/Projects/UOContent/Mobiles/Abilities/MonsterAbility.Abilities.cs index fd02f4c36..e828473b1 100644 --- a/Projects/UOContent/Mobiles/Abilities/MonsterAbility.Abilities.cs +++ b/Projects/UOContent/Mobiles/Abilities/MonsterAbility.Abilities.cs @@ -12,4 +12,18 @@ public abstract partial class MonsterAbility // Summon Undead public static SummonSkeletons SummonSkeletons => new(); public static SummonLesserUndead SummonLesserUndead => new(); + + // Stun + public static ColossalBlow ColossalBlow => new(); + + // Poison + public static PoisonGasCounter PoisonGasCounter => new(); + public static PoisonGasAreaAttack PoisonGasAreaAttack => new(); + + // Explosions + public static DeathExplosion DeathExplosion => new(); + + public static ThrowHatchetCounter ThrowHatchetCounter => new(); + + public static DestroyEquipment DestroyEquipment => new(); } diff --git a/Projects/UOContent/Mobiles/Abilities/MonsterAbilityAttack.cs b/Projects/UOContent/Mobiles/Abilities/MonsterAbilityAttack.cs new file mode 100644 index 000000000..2fb8c4142 --- /dev/null +++ b/Projects/UOContent/Mobiles/Abilities/MonsterAbilityAttack.cs @@ -0,0 +1,22 @@ +namespace Server.Mobiles; + +public abstract class MonsterAbilityAttack : MonsterAbility +{ + public override void Trigger(BaseCreature source, Mobile target) + { + if (CanEffectTarget(source, target)) + { + OnAttack(source, target); + } + + base.Trigger(source, target); + } + + protected virtual void OnAttack(BaseCreature source, Mobile defender) + { + source.DoHarmful(defender); + } + + protected virtual bool CanEffectTarget(BaseCreature source, Mobile defender) => + defender.Alive && source.CanBeHarmful(defender); +} diff --git a/Projects/UOContent/Mobiles/Abilities/MonsterAbilityTrigger.cs b/Projects/UOContent/Mobiles/Abilities/MonsterAbilityTrigger.cs index 6bd4a9455..88548463d 100644 --- a/Projects/UOContent/Mobiles/Abilities/MonsterAbilityTrigger.cs +++ b/Projects/UOContent/Mobiles/Abilities/MonsterAbilityTrigger.cs @@ -5,12 +5,14 @@ namespace Server.Mobiles; [Flags] public enum MonsterAbilityTrigger { - None = 0x00000000, // Passive, or some custom event. - Action = 0x00000001, // On Think + None = 0x00000000, // Passive, or some custom event. + OnAction = 0x00000001, // On Think TakeMeleeDamage = 0x00000002, GiveMeleeDamage = 0x00000004, // Includes firing a bow TakeSpellDamage = 0x00000008, GiveSpellDamage = 0x00000010, + OnCombatAction = 0x00000020, + OnDeath = 0x00000040, TakeDamage = TakeMeleeDamage | TakeSpellDamage } diff --git a/Projects/UOContent/Mobiles/Abilities/MonsterAbilityType.cs b/Projects/UOContent/Mobiles/Abilities/MonsterAbilityType.cs index 422e6962f..d26848b71 100644 --- a/Projects/UOContent/Mobiles/Abilities/MonsterAbilityType.cs +++ b/Projects/UOContent/Mobiles/Abilities/MonsterAbilityType.cs @@ -5,5 +5,10 @@ public enum MonsterAbilityType Generic, FireBreath, GraspingClaw, - SummonUndead + SummonUndead, + Stun, + Poison, + MassPoison, + ThrowWeapon, + DestroyEquipment } diff --git a/Projects/UOContent/Mobiles/Abilities/PoisonGasAreaAttack.cs b/Projects/UOContent/Mobiles/Abilities/PoisonGasAreaAttack.cs new file mode 100644 index 000000000..fac4b792f --- /dev/null +++ b/Projects/UOContent/Mobiles/Abilities/PoisonGasAreaAttack.cs @@ -0,0 +1,19 @@ +namespace Server.Mobiles; + +public class PoisonGasAreaAttack : AreaEffectMonsterAbility +{ + public override MonsterAbilityType AbilityType => MonsterAbilityType.MassPoison; + + public override void Trigger(BaseCreature source, Mobile target) + { + source.FixedParticles(0x376A, 9, 32, 0x2539, EffectLayer.LeftHand); + source.PlaySound(0x1DE); + + base.Trigger(source, target); + } + + protected override void DoEffectTarget(BaseCreature source, Mobile defender) + { + defender.ApplyPoison(source, Poison.Deadly); + } +} diff --git a/Projects/UOContent/Mobiles/Abilities/PoisonGasCounter.cs b/Projects/UOContent/Mobiles/Abilities/PoisonGasCounter.cs new file mode 100644 index 000000000..a83bd459a --- /dev/null +++ b/Projects/UOContent/Mobiles/Abilities/PoisonGasCounter.cs @@ -0,0 +1,22 @@ +namespace Server.Mobiles; + +public class PoisonGasCounter : MonsterAbilityAttack +{ + public override MonsterAbilityType AbilityType => MonsterAbilityType.Poison; + public override MonsterAbilityTrigger AbilityTrigger => MonsterAbilityTrigger.TakeDamage; + + public override double ChanceToTrigger => 0.05; + public virtual int AttackRange => 1; + + protected override bool CanEffectTarget(BaseCreature source, Mobile defender) => + source.InRange(defender, AttackRange) && defender is not BaseCreature { BardProvoked: true }; + + protected override void OnAttack(BaseCreature source, Mobile defender) + { + source.Animate(10, 4, 1, true, false, 0); + AOS.Damage(defender, source, 50, 100, 0, 0, 0, 0, 0); + + defender.FixedParticles(0x36BD, 1, 10, 0x1F78, 0xA6, 0, (EffectLayer)255); + defender.ApplyPoison(source, Poison.Deadly); + } +} diff --git a/Projects/UOContent/Mobiles/Abilities/StunAttack.cs b/Projects/UOContent/Mobiles/Abilities/StunAttack.cs new file mode 100644 index 000000000..3a74210bd --- /dev/null +++ b/Projects/UOContent/Mobiles/Abilities/StunAttack.cs @@ -0,0 +1,44 @@ +using System; +using System.Collections.Generic; +using Server.Items; + +namespace Server.Mobiles; + +public abstract class StunAttack : MonsterAbility +{ + // Prevents infinite loop + private HashSet _stunning; + + public override MonsterAbilityTrigger AbilityTrigger => MonsterAbilityTrigger.GiveMeleeDamage; + public override MonsterAbilityType AbilityType => MonsterAbilityType.Stun; + public override double ChanceToTrigger => 0.3; + + public virtual TimeSpan StunDuration => TimeSpan.FromSeconds(5.0); + + public override bool CanTrigger(BaseCreature source) => !_stunning.Contains(source) && base.CanTrigger(source); + + public override void Trigger(BaseCreature source, Mobile target) + { + if (source.Weapon is BaseWeapon weapon) + { + _stunning ??= new HashSet(); + _stunning.Add(source); + weapon.OnHit(source, target); + _stunning.Remove(source); + } + + if (target.Alive) + { + target.Frozen = true; + Timer.DelayCall(StunDuration, Recover, target); + } + + base.Trigger(source, target); + } + + protected virtual void Recover(Mobile defender) + { + defender.Frozen = false; + defender.Combatant = null; + } +} diff --git a/Projects/UOContent/Mobiles/Abilities/ThrowHatchetCounter.cs b/Projects/UOContent/Mobiles/Abilities/ThrowHatchetCounter.cs new file mode 100644 index 000000000..ecfe8b826 --- /dev/null +++ b/Projects/UOContent/Mobiles/Abilities/ThrowHatchetCounter.cs @@ -0,0 +1,19 @@ +using Server.Items; + +namespace Server.Mobiles; + +public class ThrowHatchetCounter : MonsterAbilityAttack +{ + public override MonsterAbilityType AbilityType => MonsterAbilityType.ThrowWeapon; + public override MonsterAbilityTrigger AbilityTrigger => MonsterAbilityTrigger.TakeDamage; + public override double ChanceToTrigger => 0.4; + + protected override void OnAttack(BaseCreature source, Mobile defender) + { + source.MovingEffect(defender, 0xF43, 10, 0, false, false); + AOS.Damage(defender, source, 50, 100, 0, 0, 0, 0, 0); + } + + protected override bool CanEffectTarget(BaseCreature source, Mobile defender) => + base.CanEffectTarget(source, defender) && defender.Weapon is BaseRanged; +} diff --git a/Projects/UOContent/Mobiles/BaseCreature.cs b/Projects/UOContent/Mobiles/BaseCreature.cs index 1fecd1fbc..89eec0a18 100644 --- a/Projects/UOContent/Mobiles/BaseCreature.cs +++ b/Projects/UOContent/Mobiles/BaseCreature.cs @@ -2869,6 +2869,8 @@ namespace Server.Mobiles public override bool OnBeforeDeath() { + TriggerAbility(MonsterAbilityTrigger.OnDeath, null); + var treasureLevel = TreasureMapLevel; if (treasureLevel == 1 && Map == Map.Trammel && TreasureMap.IsInHavenIsland(this)) @@ -3515,7 +3517,7 @@ namespace Server.Mobiles } // Fire breath, etc. - TriggerAbility(MonsterAbilityTrigger.Action, Combatant); + TriggerAbility(MonsterAbilityTrigger.OnAction, Combatant); if ((CanHeal || CanHealOwner) && Alive && !IsHealing && !BardPacified) { @@ -4170,6 +4172,7 @@ namespace Server.Mobiles public virtual void OnActionCombat() { + TriggerAbility(MonsterAbilityTrigger.OnCombatAction, null); } public virtual void OnActionGuard() diff --git a/Projects/UOContent/Mobiles/Monsters/Humanoid/Magic/Betrayer.cs b/Projects/UOContent/Mobiles/Monsters/Humanoid/Magic/Betrayer.cs index f37095325..026ddd579 100644 --- a/Projects/UOContent/Mobiles/Monsters/Humanoid/Magic/Betrayer.cs +++ b/Projects/UOContent/Mobiles/Monsters/Humanoid/Magic/Betrayer.cs @@ -1,188 +1,117 @@ -using System; using Server.Items; -using Server.Network; -namespace Server.Mobiles +namespace Server.Mobiles; + +public class Betrayer : BaseCreature { - public class Betrayer : BaseCreature + [Constructible] + public Betrayer() : base(AIType.AI_Mage) { - private DateTime m_NextAbilityTime; - private bool m_Stunning; + Body = 767; - [Constructible] - public Betrayer() : base(AIType.AI_Mage) + SetStr(401, 500); + SetDex(81, 100); + SetInt(151, 200); + + SetHits(241, 300); + + SetDamage(16, 22); + + SetDamageType(ResistanceType.Physical, 100); + + SetResistance(ResistanceType.Physical, 60, 70); + SetResistance(ResistanceType.Fire, 60, 70); + SetResistance(ResistanceType.Cold, 60, 70); + SetResistance(ResistanceType.Poison, 30, 40); + SetResistance(ResistanceType.Energy, 20, 30); + + SetSkill(SkillName.Anatomy, 90.1, 100.0); + SetSkill(SkillName.EvalInt, 90.1, 100.0); + SetSkill(SkillName.Magery, 50.1, 100.0); + SetSkill(SkillName.Meditation, 90.1, 100.0); + SetSkill(SkillName.MagicResist, 120.1, 130.0); + SetSkill(SkillName.Tactics, 90.1, 100.0); + SetSkill(SkillName.Wrestling, 90.1, 100.0); + + Fame = 15000; + Karma = -15000; + + VirtualArmor = 65; + SpeechHue = Utility.RandomDyedHue(); + + PackItem(new PowerCrystal()); + + if (Utility.RandomDouble() < 0.02) { - Body = 767; - - SetStr(401, 500); - SetDex(81, 100); - SetInt(151, 200); - - SetHits(241, 300); - - SetDamage(16, 22); - - SetDamageType(ResistanceType.Physical, 100); - - SetResistance(ResistanceType.Physical, 60, 70); - SetResistance(ResistanceType.Fire, 60, 70); - SetResistance(ResistanceType.Cold, 60, 70); - SetResistance(ResistanceType.Poison, 30, 40); - SetResistance(ResistanceType.Energy, 20, 30); - - SetSkill(SkillName.Anatomy, 90.1, 100.0); - SetSkill(SkillName.EvalInt, 90.1, 100.0); - SetSkill(SkillName.Magery, 50.1, 100.0); - SetSkill(SkillName.Meditation, 90.1, 100.0); - SetSkill(SkillName.MagicResist, 120.1, 130.0); - SetSkill(SkillName.Tactics, 90.1, 100.0); - SetSkill(SkillName.Wrestling, 90.1, 100.0); - - Fame = 15000; - Karma = -15000; - - VirtualArmor = 65; - SpeechHue = Utility.RandomDyedHue(); - - PackItem(new PowerCrystal()); - - if (Utility.RandomDouble() < 0.02) - { - PackItem(new BlackthornWelcomeBook()); - } - - m_NextAbilityTime = Core.Now + TimeSpan.FromSeconds(Utility.RandomMinMax(5, 30)); + PackItem(new BlackthornWelcomeBook()); } + } - public Betrayer(Serial serial) - : base(serial) + public Betrayer(Serial serial) : base(serial) + { + } + + public override string CorpseName => "a betrayer corpse"; + + public override string DefaultName => "a betrayer"; + + public override bool AlwaysMurderer => true; + public override bool BardImmune => !Core.AOS; + public override Poison PoisonImmune => Poison.Lethal; + public override int Meat => 1; + public override int TreasureMapLevel => 5; + + public override void OnDeath(Container c) + { + base.OnDeath(c); + + if (Utility.RandomDouble() < 0.05) { - } - - public override string CorpseName => "a betrayer corpse"; - - public override string DefaultName => "a betrayer"; - - public override bool AlwaysMurderer => true; - public override bool BardImmune => !Core.AOS; - public override Poison PoisonImmune => Poison.Lethal; - public override int Meat => 1; - public override int TreasureMapLevel => 5; - - public override void OnDeath(Container c) - { - base.OnDeath(c); - - if (Utility.RandomDouble() < 0.05) + if (!IsParagon) { - if (!IsParagon) + if (Utility.RandomDouble() < 0.75) { - if (Utility.RandomDouble() < 0.75) - { - c.DropItem(DawnsMusicGear.RandomCommon); - } - else - { - c.DropItem(DawnsMusicGear.RandomUncommon); - } + c.DropItem(DawnsMusicGear.RandomCommon); } else { - c.DropItem(DawnsMusicGear.RandomRare); + c.DropItem(DawnsMusicGear.RandomUncommon); } } - } - - public override int GetDeathSound() => 0x423; - - public override int GetAttackSound() => 0x23B; - - public override int GetHurtSound() => 0x140; - - public override void GenerateLoot() - { - AddLoot(LootPack.FilthyRich); - AddLoot(LootPack.Rich); - AddLoot(LootPack.Gems, 1); - } - - public override void OnGaveMeleeAttack(Mobile defender, int damage) - { - base.OnGaveMeleeAttack(defender, damage); - - if (!m_Stunning && Utility.RandomDouble() < 0.3) + else { - m_Stunning = true; - - defender.Animate(21, 6, 1, true, false, 0); - PlaySound(0xEE); - defender.LocalOverheadMessage( - MessageType.Regular, - 0x3B2, - false, - "You have been stunned by a colossal blow!" - ); - - if (Weapon is BaseWeapon weapon) - { - weapon.OnHit(this, defender); - } - - if (defender.Alive) - { - defender.Frozen = true; - Timer.StartTimer(TimeSpan.FromSeconds(5.0), () => Recover_Callback(defender)); - } + c.DropItem(DawnsMusicGear.RandomRare); } } - - private void Recover_Callback(Mobile defender) - { - defender.Frozen = false; - defender.Combatant = null; - defender.LocalOverheadMessage(MessageType.Regular, 0x3B2, false, "You recover your senses."); - m_Stunning = false; - } - - public override void OnActionCombat() - { - var combatant = Combatant; - - if (Core.Now < m_NextAbilityTime || combatant?.Deleted != false || combatant.Map != Map || - !InRange(combatant, 3) || !CanBeHarmful(combatant) || !InLOS(combatant)) - { - return; - } - - m_NextAbilityTime = Core.Now + TimeSpan.FromSeconds(Utility.RandomMinMax(5, 30)); - - if (Utility.RandomBool()) - { - FixedParticles(0x376A, 9, 32, 0x2539, EffectLayer.LeftHand); - PlaySound(0x1DE); - - foreach (var m in GetMobilesInRange(2)) - { - if (m != this && IsEnemy(m)) - { - m.ApplyPoison(this, Poison.Deadly); - } - } - } - } - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.Write(0); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadInt(); - } + } + + public override int GetDeathSound() => 0x423; + + public override int GetAttackSound() => 0x23B; + + public override int GetHurtSound() => 0x140; + + public override void GenerateLoot() + { + AddLoot(LootPack.FilthyRich); + AddLoot(LootPack.Rich); + AddLoot(LootPack.Gems, 1); + } + + private static MonsterAbility[] _abilities = { MonsterAbility.ColossalBlow, MonsterAbility.PoisonGasAreaAttack }; + public override MonsterAbility[] GetMonsterAbilities() => _abilities; + + public override void Serialize(IGenericWriter writer) + { + base.Serialize(writer); + + writer.Write(0); // version + } + + public override void Deserialize(IGenericReader reader) + { + base.Deserialize(reader); + + var version = reader.ReadInt(); } } diff --git a/Projects/UOContent/Mobiles/Monsters/Humanoid/Magic/GargoyleDestroyer.cs b/Projects/UOContent/Mobiles/Monsters/Humanoid/Magic/GargoyleDestroyer.cs index 8caddf440..7059e5480 100644 --- a/Projects/UOContent/Mobiles/Monsters/Humanoid/Magic/GargoyleDestroyer.cs +++ b/Projects/UOContent/Mobiles/Monsters/Humanoid/Magic/GargoyleDestroyer.cs @@ -1,106 +1,82 @@ using Server.Items; -namespace Server.Mobiles +namespace Server.Mobiles; + +public class GargoyleDestroyer : BaseCreature { - public class GargoyleDestroyer : BaseCreature + [Constructible] + public GargoyleDestroyer() : base(AIType.AI_Mage) { - [Constructible] - public GargoyleDestroyer() : base(AIType.AI_Mage) + Body = 0x2F3; + BaseSoundID = 0x174; + + SetStr(760, 850); + SetDex(102, 150); + SetInt(152, 200); + + SetHits(482, 485); + + SetDamage(7, 14); + + SetResistance(ResistanceType.Physical, 40, 60); + SetResistance(ResistanceType.Fire, 60, 70); + SetResistance(ResistanceType.Cold, 15, 25); + SetResistance(ResistanceType.Poison, 15, 25); + SetResistance(ResistanceType.Energy, 15, 25); + + SetSkill(SkillName.Wrestling, 90.1, 100.0); + SetSkill(SkillName.Tactics, 90.1, 100.0); + SetSkill(SkillName.MagicResist, 120.4, 160.0); + SetSkill(SkillName.Anatomy, 50.5, 100.0); + SetSkill(SkillName.Swords, 90.1, 100.0); + SetSkill(SkillName.Macing, 90.1, 100.0); + SetSkill(SkillName.Fencing, 90.1, 100.0); + SetSkill(SkillName.Magery, 90.1, 100.0); + SetSkill(SkillName.EvalInt, 90.1, 100.0); + SetSkill(SkillName.Meditation, 90.1, 100.0); + + Fame = 10000; + Karma = -10000; + + VirtualArmor = 50; + + if (Utility.RandomDouble() < 0.2) { - Body = 0x2F3; - BaseSoundID = 0x174; - - SetStr(760, 850); - SetDex(102, 150); - SetInt(152, 200); - - SetHits(482, 485); - - SetDamage(7, 14); - - SetResistance(ResistanceType.Physical, 40, 60); - SetResistance(ResistanceType.Fire, 60, 70); - SetResistance(ResistanceType.Cold, 15, 25); - SetResistance(ResistanceType.Poison, 15, 25); - SetResistance(ResistanceType.Energy, 15, 25); - - SetSkill(SkillName.Wrestling, 90.1, 100.0); - SetSkill(SkillName.Tactics, 90.1, 100.0); - SetSkill(SkillName.MagicResist, 120.4, 160.0); - SetSkill(SkillName.Anatomy, 50.5, 100.0); - SetSkill(SkillName.Swords, 90.1, 100.0); - SetSkill(SkillName.Macing, 90.1, 100.0); - SetSkill(SkillName.Fencing, 90.1, 100.0); - SetSkill(SkillName.Magery, 90.1, 100.0); - SetSkill(SkillName.EvalInt, 90.1, 100.0); - SetSkill(SkillName.Meditation, 90.1, 100.0); - - Fame = 10000; - Karma = -10000; - - VirtualArmor = 50; - - if (Utility.RandomDouble() < 0.2) - { - PackItem(new GargoylesPickaxe()); - } - } - - public GargoyleDestroyer(Serial serial) : base(serial) - { - } - - public override string CorpseName => "a gargoyle corpse"; - public override string DefaultName => "a gargoyle destroyer"; - - public override bool BardImmune => !Core.AOS; - public override int Meat => 1; - public override bool CanFly => true; - - public override void GenerateLoot() - { - AddLoot(LootPack.FilthyRich); - AddLoot(LootPack.Rich); - AddLoot(LootPack.MedScrolls); - AddLoot(LootPack.Gems, 2); - } - - public override void OnDamagedBySpell(Mobile from, int damage) - { - if (from?.Alive == true && Utility.RandomDouble() < 0.4) - { - ThrowHatchet(from); - } - } - - public override void OnGotMeleeAttack(Mobile attacker, int damage) - { - base.OnGotMeleeAttack(attacker, damage); - - if (attacker?.Alive == true && attacker.Weapon is BaseRanged && Utility.RandomDouble() < 0.4) - { - ThrowHatchet(attacker); - } - } - - public void ThrowHatchet(Mobile to) - { - var damage = 50; - MovingEffect(to, 0xF43, 10, 0, false, false); - DoHarmful(to); - AOS.Damage(to, this, damage, 100, 0, 0, 0, 0); - } - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - writer.Write(0); - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - var version = reader.ReadInt(); + PackItem(new GargoylesPickaxe()); } } + + public GargoyleDestroyer(Serial serial) : base(serial) + { + } + + public override string CorpseName => "a gargoyle corpse"; + public override string DefaultName => "a gargoyle destroyer"; + + public override bool BardImmune => !Core.AOS; + public override int Meat => 1; + public override bool CanFly => true; + + private static MonsterAbility[] _abilities = { MonsterAbility.ThrowHatchetCounter }; + public override MonsterAbility[] GetMonsterAbilities() => _abilities; + + public override void GenerateLoot() + { + AddLoot(LootPack.FilthyRich); + AddLoot(LootPack.Rich); + AddLoot(LootPack.MedScrolls); + AddLoot(LootPack.Gems, 2); + } + + public override void Serialize(IGenericWriter writer) + { + base.Serialize(writer); + writer.Write(0); + } + + public override void Deserialize(IGenericReader reader) + { + base.Deserialize(reader); + var version = reader.ReadInt(); + } } diff --git a/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/Juggernaut.cs b/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/Juggernaut.cs index 0a72928ab..37a22df75 100644 --- a/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/Juggernaut.cs +++ b/Projects/UOContent/Mobiles/Monsters/Humanoid/Melee/Juggernaut.cs @@ -1,158 +1,118 @@ -using System; using Server.Items; -using Server.Network; -namespace Server.Mobiles +namespace Server.Mobiles; + +public class Juggernaut : BaseCreature { - public class Juggernaut : BaseCreature + [Constructible] + public Juggernaut() : base(AIType.AI_Melee) { - private bool m_Stunning; + Body = 768; - [Constructible] - public Juggernaut() : base(AIType.AI_Melee) + SetStr(301, 400); + SetDex(51, 70); + SetInt(51, 100); + + SetHits(181, 240); + + SetDamage(12, 19); + + SetDamageType(ResistanceType.Physical, 50); + SetDamageType(ResistanceType.Fire, 25); + SetDamageType(ResistanceType.Energy, 25); + + SetResistance(ResistanceType.Physical, 65, 75); + SetResistance(ResistanceType.Fire, 35, 45); + SetResistance(ResistanceType.Cold, 35, 45); + SetResistance(ResistanceType.Poison, 15, 25); + SetResistance(ResistanceType.Energy, 10, 20); + + SetSkill(SkillName.Anatomy, 90.1, 100.0); + SetSkill(SkillName.MagicResist, 140.1, 150.0); + SetSkill(SkillName.Tactics, 90.1, 100.0); + SetSkill(SkillName.Wrestling, 90.1, 100.0); + + Fame = 12000; + Karma = -12000; + + VirtualArmor = 70; + + if (Utility.RandomDouble() < 0.1) { - Body = 768; - - SetStr(301, 400); - SetDex(51, 70); - SetInt(51, 100); - - SetHits(181, 240); - - SetDamage(12, 19); - - SetDamageType(ResistanceType.Physical, 50); - SetDamageType(ResistanceType.Fire, 25); - SetDamageType(ResistanceType.Energy, 25); - - SetResistance(ResistanceType.Physical, 65, 75); - SetResistance(ResistanceType.Fire, 35, 45); - SetResistance(ResistanceType.Cold, 35, 45); - SetResistance(ResistanceType.Poison, 15, 25); - SetResistance(ResistanceType.Energy, 10, 20); - - SetSkill(SkillName.Anatomy, 90.1, 100.0); - SetSkill(SkillName.MagicResist, 140.1, 150.0); - SetSkill(SkillName.Tactics, 90.1, 100.0); - SetSkill(SkillName.Wrestling, 90.1, 100.0); - - Fame = 12000; - Karma = -12000; - - VirtualArmor = 70; - - if (Utility.RandomDouble() < 0.1) - { - PackItem(new PowerCrystal()); - } - - if (Utility.RandomDouble() < 0.4) - { - PackItem(new ClockworkAssembly()); - } + PackItem(new PowerCrystal()); } - public Juggernaut(Serial serial) : base(serial) + if (Utility.RandomDouble() < 0.4) { + PackItem(new ClockworkAssembly()); } + } - public override string CorpseName => "a juggernaut corpse"; + public Juggernaut(Serial serial) : base(serial) + { + } - public override string DefaultName => "a blackthorn juggernaut"; + public override string CorpseName => "a juggernaut corpse"; - public override bool AlwaysMurderer => true; - public override bool BardImmune => !Core.AOS; - public override bool BleedImmune => true; - public override Poison PoisonImmune => Poison.Lethal; - public override int Meat => 1; - public override int TreasureMapLevel => 5; + public override string DefaultName => "a blackthorn juggernaut"; - public override void OnDeath(Container c) + public override bool AlwaysMurderer => true; + public override bool BardImmune => !Core.AOS; + public override bool BleedImmune => true; + public override Poison PoisonImmune => Poison.Lethal; + public override int Meat => 1; + public override int TreasureMapLevel => 5; + + private static MonsterAbility[] _abilities = { MonsterAbility.ColossalBlow }; + public override MonsterAbility[] GetMonsterAbilities() => _abilities; + + public override void OnDeath(Container c) + { + base.OnDeath(c); + + if (Utility.RandomDouble() < 0.05) { - base.OnDeath(c); - - if (Utility.RandomDouble() < 0.05) + if (!IsParagon) { - if (!IsParagon) + if (Utility.RandomDouble() < 0.75) { - if (Utility.RandomDouble() < 0.75) - { - c.DropItem(DawnsMusicGear.RandomCommon); - } - else - { - c.DropItem(DawnsMusicGear.RandomUncommon); - } + c.DropItem(DawnsMusicGear.RandomCommon); } else { - c.DropItem(DawnsMusicGear.RandomRare); + c.DropItem(DawnsMusicGear.RandomUncommon); } } - } - - public override void GenerateLoot() - { - AddLoot(LootPack.Rich); - AddLoot(LootPack.Gems, 1); - } - - public override int GetDeathSound() => 0x423; - - public override int GetAttackSound() => 0x23B; - - public override int GetHurtSound() => 0x140; - - public override void OnGaveMeleeAttack(Mobile defender, int damage) - { - base.OnGaveMeleeAttack(defender, damage); - - if (!m_Stunning && Utility.RandomDouble() < 0.3) + else { - m_Stunning = true; - - defender.Animate(21, 6, 1, true, false, 0); - PlaySound(0xEE); - defender.LocalOverheadMessage( - MessageType.Regular, - 0x3B2, - false, - "You have been stunned by a colossal blow!" - ); - - if (Weapon is BaseWeapon weapon) - { - weapon.OnHit(this, defender); - } - - if (defender.Alive) - { - defender.Frozen = true; - Timer.StartTimer(TimeSpan.FromSeconds(5.0), () => Recover_Callback(defender)); - } + c.DropItem(DawnsMusicGear.RandomRare); } } - - private void Recover_Callback(Mobile defender) - { - defender.Frozen = false; - defender.Combatant = null; - defender.LocalOverheadMessage(MessageType.Regular, 0x3B2, false, "You recover your senses."); - m_Stunning = false; - } - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.Write(0); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadInt(); - } + } + + public override void GenerateLoot() + { + AddLoot(LootPack.Rich); + AddLoot(LootPack.Gems, 1); + } + + public override int GetDeathSound() => 0x423; + + public override int GetAttackSound() => 0x23B; + + public override int GetHurtSound() => 0x140; + + public override void Serialize(IGenericWriter writer) + { + base.Serialize(writer); + + writer.Write(0); // version + } + + public override void Deserialize(IGenericReader reader) + { + base.Deserialize(reader); + + var version = reader.ReadInt(); } } diff --git a/Projects/UOContent/Mobiles/Monsters/LBR/Jukas/JukaWarrior.cs b/Projects/UOContent/Mobiles/Monsters/LBR/Jukas/JukaWarrior.cs index 0bf5800af..9585a617a 100644 --- a/Projects/UOContent/Mobiles/Monsters/LBR/Jukas/JukaWarrior.cs +++ b/Projects/UOContent/Mobiles/Monsters/LBR/Jukas/JukaWarrior.cs @@ -90,7 +90,7 @@ namespace Server.Mobiles } case 1: { - defender.SendAsciiMessage("You have been hit by a paralyzing blow!"); + defender.SendLocalizedMessage(1072221); // You have been hit by a paralyzing blow! defender.Freeze(TimeSpan.FromSeconds(3.0)); break; } diff --git a/Projects/UOContent/Mobiles/Monsters/Misc/Melee/Golem.cs b/Projects/UOContent/Mobiles/Monsters/Misc/Melee/Golem.cs index 42f76389f..e61858540 100644 --- a/Projects/UOContent/Mobiles/Monsters/Misc/Melee/Golem.cs +++ b/Projects/UOContent/Mobiles/Monsters/Misc/Melee/Golem.cs @@ -1,246 +1,182 @@ -using System; using Server.Items; -using Server.Network; -namespace Server.Mobiles +namespace Server.Mobiles; + +public class Golem : BaseCreature { - public class Golem : BaseCreature + [Constructible] + public Golem(bool summoned = false, double scalar = 1.0) : base(AIType.AI_Melee) { - private bool m_Stunning; + Body = 752; - [Constructible] - public Golem(bool summoned = false, double scalar = 1.0) : base(AIType.AI_Melee) + if (summoned) { - Body = 752; - - if (summoned) - { - Hue = 2101; - } - - SetStr((int)(251 * scalar), (int)(350 * scalar)); - SetDex((int)(76 * scalar), (int)(100 * scalar)); - SetInt((int)(101 * scalar), (int)(150 * scalar)); - - SetHits((int)(151 * scalar), (int)(210 * scalar)); - - SetDamage((int)(13 * scalar), (int)(24 * scalar)); - - SetDamageType(ResistanceType.Physical, 100); - - SetResistance(ResistanceType.Physical, (int)(35 * scalar), (int)(55 * scalar)); - - if (summoned) - { - SetResistance(ResistanceType.Fire, (int)(50 * scalar), (int)(60 * scalar)); - } - else - { - SetResistance(ResistanceType.Fire, (int)(100 * scalar)); - } - - SetResistance(ResistanceType.Cold, (int)(10 * scalar), (int)(30 * scalar)); - SetResistance(ResistanceType.Poison, (int)(10 * scalar), (int)(25 * scalar)); - SetResistance(ResistanceType.Energy, (int)(30 * scalar), (int)(40 * scalar)); - - SetSkill(SkillName.MagicResist, 150.1 * scalar, 190.0 * scalar); - SetSkill(SkillName.Tactics, 60.1 * scalar, 100.0 * scalar); - SetSkill(SkillName.Wrestling, 60.1 * scalar, 100.0 * scalar); - - if (summoned) - { - Fame = 10; - Karma = 10; - } - else - { - Fame = 3500; - Karma = -3500; - } - - if (!summoned) - { - PackItem(new IronIngot(Utility.RandomMinMax(13, 21))); - - if (Utility.RandomDouble() < 0.1) - { - PackItem(new PowerCrystal()); - } - - if (Utility.RandomDouble() < 0.15) - { - PackItem(new ClockworkAssembly()); - } - - if (Utility.RandomDouble() < 0.2) - { - PackItem(new ArcaneGem()); - } - - if (Utility.RandomDouble() < 0.25) - { - PackItem(new Gears()); - } - } - - ControlSlots = 3; + Hue = 2101; } - public Golem(Serial serial) : base(serial) + SetStr((int)(251 * scalar), (int)(350 * scalar)); + SetDex((int)(76 * scalar), (int)(100 * scalar)); + SetInt((int)(101 * scalar), (int)(150 * scalar)); + + SetHits((int)(151 * scalar), (int)(210 * scalar)); + + SetDamage((int)(13 * scalar), (int)(24 * scalar)); + + SetDamageType(ResistanceType.Physical, 100); + + SetResistance(ResistanceType.Physical, (int)(35 * scalar), (int)(55 * scalar)); + + if (summoned) { + SetResistance(ResistanceType.Fire, (int)(50 * scalar), (int)(60 * scalar)); + } + else + { + SetResistance(ResistanceType.Fire, (int)(100 * scalar)); } - public override string CorpseName => "a golem corpse"; + SetResistance(ResistanceType.Cold, (int)(10 * scalar), (int)(30 * scalar)); + SetResistance(ResistanceType.Poison, (int)(10 * scalar), (int)(25 * scalar)); + SetResistance(ResistanceType.Energy, (int)(30 * scalar), (int)(40 * scalar)); - public override bool IsScaredOfScaryThings => false; - public override bool IsScaryToPets => true; + SetSkill(SkillName.MagicResist, 150.1 * scalar, 190.0 * scalar); + SetSkill(SkillName.Tactics, 60.1 * scalar, 100.0 * scalar); + SetSkill(SkillName.Wrestling, 60.1 * scalar, 100.0 * scalar); - public override bool IsBondable => false; - - public override FoodType FavoriteFood => FoodType.None; - - public override bool CanBeDistracted => false; - - public override string DefaultName => "a golem"; - - public override bool DeleteOnRelease => true; - - public override bool AutoDispel => !Controlled; - public override bool BleedImmune => true; - - public override bool BardImmune => !Core.AOS || Controlled; - public override Poison PoisonImmune => Poison.Lethal; - - public override void OnDeath(Container c) + if (summoned) { - base.OnDeath(c); + Fame = 10; + Karma = 10; + } + else + { + Fame = 3500; + Karma = -3500; + } - if (Utility.RandomDouble() < 0.05) + if (!summoned) + { + PackItem(new IronIngot(Utility.RandomMinMax(13, 21))); + + if (Utility.RandomDouble() < 0.1) { - if (!IsParagon) + PackItem(new PowerCrystal()); + } + + if (Utility.RandomDouble() < 0.15) + { + PackItem(new ClockworkAssembly()); + } + + if (Utility.RandomDouble() < 0.2) + { + PackItem(new ArcaneGem()); + } + + if (Utility.RandomDouble() < 0.25) + { + PackItem(new Gears()); + } + } + + ControlSlots = 3; + } + + public Golem(Serial serial) : base(serial) + { + } + + public override string CorpseName => "a golem corpse"; + + public override bool IsScaredOfScaryThings => false; + public override bool IsScaryToPets => true; + + public override bool IsBondable => false; + + public override FoodType FavoriteFood => FoodType.None; + + public override bool CanBeDistracted => false; + + public override string DefaultName => "a golem"; + + public override bool DeleteOnRelease => true; + + public override bool AutoDispel => !Controlled; + public override bool BleedImmune => true; + + public override bool BardImmune => !Core.AOS || Controlled; + public override Poison PoisonImmune => Poison.Lethal; + + private static MonsterAbility[] _abilities = { MonsterAbility.ColossalBlow }; + public override MonsterAbility[] GetMonsterAbilities() => _abilities; + + public override void OnDeath(Container c) + { + base.OnDeath(c); + + if (Utility.RandomDouble() < 0.05) + { + if (!IsParagon) + { + if (Utility.RandomDouble() < 0.75) { - if (Utility.RandomDouble() < 0.75) - { - c.DropItem(DawnsMusicGear.RandomCommon); - } - else - { - c.DropItem(DawnsMusicGear.RandomUncommon); - } + c.DropItem(DawnsMusicGear.RandomCommon); } else { - c.DropItem(DawnsMusicGear.RandomRare); + c.DropItem(DawnsMusicGear.RandomUncommon); } } - } - - public override int GetAngerSound() => 541; - - public override int GetIdleSound() - { - if (!Controlled) + else { - return 542; + c.DropItem(DawnsMusicGear.RandomRare); } - - return base.GetIdleSound(); - } - - public override int GetDeathSound() - { - if (!Controlled) - { - return 545; - } - - return base.GetDeathSound(); - } - - public override int GetAttackSound() => 562; - - public override int GetHurtSound() - { - if (Controlled) - { - return 320; - } - - return base.GetHurtSound(); - } - - public override void OnGaveMeleeAttack(Mobile defender, int damage) - { - base.OnGaveMeleeAttack(defender, damage); - - if (!m_Stunning && Utility.RandomDouble() < 0.3) - { - m_Stunning = true; - - defender.Animate(21, 6, 1, true, false, 0); - PlaySound(0xEE); - defender.LocalOverheadMessage( - MessageType.Regular, - 0x3B2, - false, - "You have been stunned by a colossal blow!" - ); - - if (Weapon is BaseWeapon weapon) - { - weapon.OnHit(this, defender); - } - - if (defender.Alive) - { - defender.Frozen = true; - Timer.StartTimer(TimeSpan.FromSeconds(5.0), () => Recover_Callback(defender)); - } - } - } - - private void Recover_Callback(Mobile defender) - { - defender.Frozen = false; - defender.Combatant = null; - defender.LocalOverheadMessage(MessageType.Regular, 0x3B2, false, "You recover your senses."); - m_Stunning = false; - } - - public override void OnDamage(int amount, Mobile from, bool willKill) - { - if (Controlled || Summoned) - { - var master = ControlMaster ?? SummonMaster; - - if (master?.Player == true && master.Map == Map && master.InRange(Location, 20)) - { - if (master.Mana >= amount) - { - master.Mana -= amount; - } - else - { - amount -= master.Mana; - master.Mana = 0; - master.Damage(amount); - } - } - } - - base.OnDamage(amount, from, willKill); - } - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - writer.Write(0); - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - var version = reader.ReadInt(); } } + + public override int GetAngerSound() => 541; + + public override int GetIdleSound() => !Controlled ? 542 : base.GetIdleSound(); + + public override int GetDeathSound() => !Controlled ? 545 : base.GetDeathSound(); + + public override int GetAttackSound() => 562; + + public override int GetHurtSound() => Controlled ? 320 : base.GetHurtSound(); + + public override void OnDamage(int amount, Mobile from, bool willKill) + { + if (Controlled || Summoned) + { + var master = ControlMaster ?? SummonMaster; + + if (master?.Player == true && master.Map == Map && master.InRange(Location, 20)) + { + if (master.Mana >= amount) + { + master.Mana -= amount; + } + else + { + amount -= master.Mana; + master.Mana = 0; + master.Damage(amount); + } + } + } + + base.OnDamage(amount, from, willKill); + } + + public override void Serialize(IGenericWriter writer) + { + base.Serialize(writer); + writer.Write(0); + } + + public override void Deserialize(IGenericReader reader) + { + base.Deserialize(reader); + var version = reader.ReadInt(); + } } diff --git a/Projects/UOContent/Mobiles/Monsters/Ore Elementals/BronzeElemental.cs b/Projects/UOContent/Mobiles/Monsters/Ore Elementals/BronzeElemental.cs index 3ff35fc5d..545a208d0 100644 --- a/Projects/UOContent/Mobiles/Monsters/Ore Elementals/BronzeElemental.cs +++ b/Projects/UOContent/Mobiles/Monsters/Ore Elementals/BronzeElemental.cs @@ -1,74 +1,75 @@ using Server.Items; -namespace Server.Mobiles +namespace Server.Mobiles; + +public class BronzeElemental : BaseCreature { - public class BronzeElemental : BaseCreature + [Constructible] + public BronzeElemental(int oreAmount = 2) : base(AIType.AI_Melee) { - [Constructible] - public BronzeElemental(int oreAmount = 2) : base(AIType.AI_Melee) - { - // TODO: Gas attack - Body = 108; - BaseSoundID = 268; + Body = 108; + BaseSoundID = 268; - SetStr(226, 255); - SetDex(126, 145); - SetInt(71, 92); + SetStr(226, 255); + SetDex(126, 145); + SetInt(71, 92); - SetHits(136, 153); + SetHits(136, 153); - SetDamage(9, 16); + SetDamage(9, 16); - SetDamageType(ResistanceType.Physical, 30); - SetDamageType(ResistanceType.Fire, 70); + SetDamageType(ResistanceType.Physical, 30); + SetDamageType(ResistanceType.Fire, 70); - SetResistance(ResistanceType.Physical, 30, 40); - SetResistance(ResistanceType.Fire, 30, 40); - SetResistance(ResistanceType.Cold, 10, 20); - SetResistance(ResistanceType.Poison, 70, 80); - SetResistance(ResistanceType.Energy, 20, 30); + SetResistance(ResistanceType.Physical, 30, 40); + SetResistance(ResistanceType.Fire, 30, 40); + SetResistance(ResistanceType.Cold, 10, 20); + SetResistance(ResistanceType.Poison, 70, 80); + SetResistance(ResistanceType.Energy, 20, 30); - SetSkill(SkillName.MagicResist, 50.1, 95.0); - SetSkill(SkillName.Tactics, 60.1, 100.0); - SetSkill(SkillName.Wrestling, 60.1, 100.0); + SetSkill(SkillName.MagicResist, 50.1, 95.0); + SetSkill(SkillName.Tactics, 60.1, 100.0); + SetSkill(SkillName.Wrestling, 60.1, 100.0); - Fame = 5000; - Karma = -5000; + Fame = 5000; + Karma = -5000; - VirtualArmor = 29; + VirtualArmor = 29; - Item ore = new BronzeOre(oreAmount); - ore.ItemID = 0x19B9; - PackItem(ore); - } + Item ore = new BronzeOre(oreAmount); + ore.ItemID = 0x19B9; + PackItem(ore); + } - public BronzeElemental(Serial serial) : base(serial) - { - } + public BronzeElemental(Serial serial) : base(serial) + { + } - public override string CorpseName => "an ore elemental corpse"; - public override string DefaultName => "a bronze elemental"; + public override string CorpseName => "an ore elemental corpse"; + public override string DefaultName => "a bronze elemental"; - public override bool BleedImmune => true; - public override bool AutoDispel => true; - public override int TreasureMapLevel => 1; + public override bool BleedImmune => true; + public override bool AutoDispel => true; + public override int TreasureMapLevel => 1; - public override void GenerateLoot() - { - AddLoot(LootPack.Average); - AddLoot(LootPack.Gems, 2); - } + private static MonsterAbility[] _abilities = { MonsterAbility.PoisonGasCounter }; + public override MonsterAbility[] GetMonsterAbilities() => _abilities; - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - writer.Write(0); - } + public override void GenerateLoot() + { + AddLoot(LootPack.Average); + AddLoot(LootPack.Gems, 2); + } - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - var version = reader.ReadInt(); - } + public override void Serialize(IGenericWriter writer) + { + base.Serialize(writer); + writer.Write(0); + } + + public override void Deserialize(IGenericReader reader) + { + base.Deserialize(reader); + var version = reader.ReadInt(); } } diff --git a/Projects/UOContent/Mobiles/Monsters/Ore Elementals/CopperElemental.cs b/Projects/UOContent/Mobiles/Monsters/Ore Elementals/CopperElemental.cs index e076e2c3f..14cb23a25 100644 --- a/Projects/UOContent/Mobiles/Monsters/Ore Elementals/CopperElemental.cs +++ b/Projects/UOContent/Mobiles/Monsters/Ore Elementals/CopperElemental.cs @@ -1,77 +1,76 @@ using Server.Items; -namespace Server.Mobiles +namespace Server.Mobiles; + +public class CopperElemental : BaseCreature { - public class CopperElemental : BaseCreature + [Constructible] + public CopperElemental(int oreAmount = 2) : base(AIType.AI_Melee) { - [Constructible] - public CopperElemental(int oreAmount = 2) : base(AIType.AI_Melee) - { - Body = 109; - BaseSoundID = 268; + Body = 109; + BaseSoundID = 268; - SetStr(226, 255); - SetDex(126, 145); - SetInt(71, 92); + SetStr(226, 255); + SetDex(126, 145); + SetInt(71, 92); - SetHits(136, 153); + SetHits(136, 153); - SetDamage(9, 16); + SetDamage(9, 16); - SetDamageType(ResistanceType.Physical, 100); + SetDamageType(ResistanceType.Physical, 100); - SetResistance(ResistanceType.Physical, 30, 40); - SetResistance(ResistanceType.Fire, 30, 40); - SetResistance(ResistanceType.Cold, 30, 40); - SetResistance(ResistanceType.Poison, 20, 30); - SetResistance(ResistanceType.Energy, 10, 20); + SetResistance(ResistanceType.Physical, 30, 40); + SetResistance(ResistanceType.Fire, 30, 40); + SetResistance(ResistanceType.Cold, 30, 40); + SetResistance(ResistanceType.Poison, 20, 30); + SetResistance(ResistanceType.Energy, 10, 20); - SetSkill(SkillName.MagicResist, 50.1, 95.0); - SetSkill(SkillName.Tactics, 60.1, 100.0); - SetSkill(SkillName.Wrestling, 60.1, 100.0); + SetSkill(SkillName.MagicResist, 50.1, 95.0); + SetSkill(SkillName.Tactics, 60.1, 100.0); + SetSkill(SkillName.Wrestling, 60.1, 100.0); - Fame = 4800; - Karma = -4800; + Fame = 4800; + Karma = -4800; - VirtualArmor = 26; + VirtualArmor = 26; - Item ore = new CopperOre(oreAmount); - ore.ItemID = 0x19B9; - PackItem(ore); - } + Item ore = new CopperOre(oreAmount); + ore.ItemID = 0x19B9; + PackItem(ore); + } - public CopperElemental(Serial serial) : base(serial) - { - } + public CopperElemental(Serial serial) : base(serial) + { + } - public override string CorpseName => "an ore elemental corpse"; - public override string DefaultName => "a copper elemental"; + public override string CorpseName => "an ore elemental corpse"; + public override string DefaultName => "a copper elemental"; - public override bool BleedImmune => true; - public override bool AutoDispel => true; - public override int TreasureMapLevel => 1; + public override bool BleedImmune => true; + public override bool AutoDispel => true; + public override int TreasureMapLevel => 1; - public override void GenerateLoot() - { - AddLoot(LootPack.Average); - AddLoot(LootPack.Gems, 2); - } + public override void GenerateLoot() + { + AddLoot(LootPack.Average); + AddLoot(LootPack.Gems, 2); + } - public override void CheckReflect(Mobile caster, ref bool reflect) - { - reflect = true; // Every spell is reflected back to the caster - } + public override void CheckReflect(Mobile caster, ref bool reflect) + { + reflect = true; // Every spell is reflected back to the caster + } - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - writer.Write(0); - } + public override void Serialize(IGenericWriter writer) + { + base.Serialize(writer); + writer.Write(0); + } - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - var version = reader.ReadInt(); - } + public override void Deserialize(IGenericReader reader) + { + base.Deserialize(reader); + var version = reader.ReadInt(); } } diff --git a/Projects/UOContent/Mobiles/Monsters/Ore Elementals/DullCopperElemental.cs b/Projects/UOContent/Mobiles/Monsters/Ore Elementals/DullCopperElemental.cs index e5c12b5e4..2edd12e15 100644 --- a/Projects/UOContent/Mobiles/Monsters/Ore Elementals/DullCopperElemental.cs +++ b/Projects/UOContent/Mobiles/Monsters/Ore Elementals/DullCopperElemental.cs @@ -1,72 +1,74 @@ using Server.Items; -namespace Server.Mobiles +namespace Server.Mobiles; + +public class DullCopperElemental : BaseCreature { - public class DullCopperElemental : BaseCreature + [Constructible] + public DullCopperElemental(int oreAmount = 2) : base(AIType.AI_Melee) { - [Constructible] - public DullCopperElemental(int oreAmount = 2) : base(AIType.AI_Melee) - { - Body = 110; - BaseSoundID = 268; + Body = 110; + BaseSoundID = 268; - SetStr(226, 255); - SetDex(126, 145); - SetInt(71, 92); + SetStr(226, 255); + SetDex(126, 145); + SetInt(71, 92); - SetHits(136, 153); + SetHits(136, 153); - SetDamage(9, 16); + SetDamage(9, 16); - SetDamageType(ResistanceType.Physical, 100); + SetDamageType(ResistanceType.Physical, 100); - SetResistance(ResistanceType.Physical, 30, 40); - SetResistance(ResistanceType.Fire, 30, 40); - SetResistance(ResistanceType.Cold, 10, 20); - SetResistance(ResistanceType.Poison, 20, 30); - SetResistance(ResistanceType.Energy, 20, 30); + SetResistance(ResistanceType.Physical, 30, 40); + SetResistance(ResistanceType.Fire, 30, 40); + SetResistance(ResistanceType.Cold, 10, 20); + SetResistance(ResistanceType.Poison, 20, 30); + SetResistance(ResistanceType.Energy, 20, 30); - SetSkill(SkillName.MagicResist, 50.1, 95.0); - SetSkill(SkillName.Tactics, 60.1, 100.0); - SetSkill(SkillName.Wrestling, 60.1, 100.0); + SetSkill(SkillName.MagicResist, 50.1, 95.0); + SetSkill(SkillName.Tactics, 60.1, 100.0); + SetSkill(SkillName.Wrestling, 60.1, 100.0); - Fame = 3500; - Karma = -3500; + Fame = 3500; + Karma = -3500; - VirtualArmor = 20; + VirtualArmor = 20; - Item ore = new DullCopperOre(oreAmount); - ore.ItemID = 0x19B9; - PackItem(ore); - } + Item ore = new DullCopperOre(oreAmount); + ore.ItemID = 0x19B9; + PackItem(ore); + } - public DullCopperElemental(Serial serial) : base(serial) - { - } + public DullCopperElemental(Serial serial) : base(serial) + { + } - public override string CorpseName => "an ore elemental corpse"; - public override string DefaultName => "a dull copper elemental"; + public override string CorpseName => "an ore elemental corpse"; + public override string DefaultName => "a dull copper elemental"; - public override bool AutoDispel => true; - public override bool BleedImmune => true; - public override int TreasureMapLevel => 1; + public override bool AutoDispel => true; + public override bool BleedImmune => true; + public override int TreasureMapLevel => 1; - public override void GenerateLoot() - { - AddLoot(LootPack.Average); - AddLoot(LootPack.Gems, 2); - } + private static MonsterAbility[] _abilities = { MonsterAbility.DeathExplosion }; + public override MonsterAbility[] GetMonsterAbilities() => _abilities; - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - writer.Write(0); - } + public override void GenerateLoot() + { + AddLoot(LootPack.Average); + AddLoot(LootPack.Gems, 2); + } - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - var version = reader.ReadInt(); - } + public override void Serialize(IGenericWriter writer) + { + base.Serialize(writer); + writer.Write(0); + } + + public override void Deserialize(IGenericReader reader) + { + base.Deserialize(reader); + var version = reader.ReadInt(); } } diff --git a/Projects/UOContent/Mobiles/Monsters/Ore Elementals/ValoriteElemental.cs b/Projects/UOContent/Mobiles/Monsters/Ore Elementals/ValoriteElemental.cs index 7bad63bfd..2a4895805 100644 --- a/Projects/UOContent/Mobiles/Monsters/Ore Elementals/ValoriteElemental.cs +++ b/Projects/UOContent/Mobiles/Monsters/Ore Elementals/ValoriteElemental.cs @@ -1,92 +1,93 @@ using Server.Items; -namespace Server.Mobiles +namespace Server.Mobiles; + +public class ValoriteElemental : BaseCreature { - public class ValoriteElemental : BaseCreature + [Constructible] + public ValoriteElemental(int oreAmount = 2) : base(AIType.AI_Melee) { - [Constructible] - public ValoriteElemental(int oreAmount = 2) : base(AIType.AI_Melee) + Body = 112; + BaseSoundID = 268; + + SetStr(226, 255); + SetDex(126, 145); + SetInt(71, 92); + + SetHits(136, 153); + + SetDamage(28); + + SetDamageType(ResistanceType.Physical, 25); + SetDamageType(ResistanceType.Fire, 25); + SetDamageType(ResistanceType.Cold, 25); + SetDamageType(ResistanceType.Energy, 25); + + SetResistance(ResistanceType.Physical, 65, 75); + SetResistance(ResistanceType.Fire, 50, 60); + SetResistance(ResistanceType.Cold, 50, 60); + SetResistance(ResistanceType.Poison, 50, 60); + SetResistance(ResistanceType.Energy, 40, 50); + + SetSkill(SkillName.MagicResist, 50.1, 95.0); + SetSkill(SkillName.Tactics, 60.1, 100.0); + SetSkill(SkillName.Wrestling, 60.1, 100.0); + + Fame = 3500; + Karma = -3500; + + VirtualArmor = 38; + + Item ore = new ValoriteOre(oreAmount); + ore.ItemID = 0x19B9; + PackItem(ore); + } + + public ValoriteElemental(Serial serial) : base(serial) + { + } + + public override string CorpseName => "an ore elemental corpse"; + public override string DefaultName => "a valorite elemental"; + + public override bool AutoDispel => true; + public override bool BleedImmune => true; + public override int TreasureMapLevel => 1; + + private static MonsterAbility[] _abilities = { MonsterAbility.PoisonGasCounter, MonsterAbility.DestroyEquipment }; + public override MonsterAbility[] GetMonsterAbilities() => _abilities; + + public override void GenerateLoot() + { + AddLoot(LootPack.FilthyRich); + AddLoot(LootPack.Gems, 4); + } + + public override void AlterMeleeDamageFrom(Mobile from, ref int damage) + { + if (from is BaseCreature bc) { - // TODO: Gas attack - Body = 112; - BaseSoundID = 268; - - SetStr(226, 255); - SetDex(126, 145); - SetInt(71, 92); - - SetHits(136, 153); - - SetDamage(28); - - SetDamageType(ResistanceType.Physical, 25); - SetDamageType(ResistanceType.Fire, 25); - SetDamageType(ResistanceType.Cold, 25); - SetDamageType(ResistanceType.Energy, 25); - - SetResistance(ResistanceType.Physical, 65, 75); - SetResistance(ResistanceType.Fire, 50, 60); - SetResistance(ResistanceType.Cold, 50, 60); - SetResistance(ResistanceType.Poison, 50, 60); - SetResistance(ResistanceType.Energy, 40, 50); - - SetSkill(SkillName.MagicResist, 50.1, 95.0); - SetSkill(SkillName.Tactics, 60.1, 100.0); - SetSkill(SkillName.Wrestling, 60.1, 100.0); - - Fame = 3500; - Karma = -3500; - - VirtualArmor = 38; - - Item ore = new ValoriteOre(oreAmount); - ore.ItemID = 0x19B9; - PackItem(ore); - } - - public ValoriteElemental(Serial serial) : base(serial) - { - } - - public override string CorpseName => "an ore elemental corpse"; - public override string DefaultName => "a valorite elemental"; - - public override bool AutoDispel => true; - public override bool BleedImmune => true; - public override int TreasureMapLevel => 1; - - public override void GenerateLoot() - { - AddLoot(LootPack.FilthyRich); - AddLoot(LootPack.Gems, 4); - } - - public override void AlterMeleeDamageFrom(Mobile from, ref int damage) - { - if (from is BaseCreature bc) + if (bc.Controlled || bc.BardTarget == this) { - if (bc.Controlled || bc.BardTarget == this) - { - damage = 0; // Immune to pets and provoked creatures - } + damage = 0; // Immune to pets and provoked creatures } } + } - public override void CheckReflect(Mobile caster, ref bool reflect) - { - reflect = true; // Every spell is reflected back to the caster - } + public override void CheckReflect(Mobile caster, ref bool reflect) + { + reflect = true; // Every spell is reflected back to the caster + } - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - writer.Write(0); - } + public override void Serialize(IGenericWriter writer) + { + base.Serialize(writer); + writer.Write(0); + } - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - var version = reader.ReadInt(); - } + public override void Deserialize(IGenericReader reader) + { + base.Deserialize(reader); + var version = reader.ReadInt(); } } diff --git a/Projects/UOContent/Mobiles/Monsters/Ore Elementals/VeriteElemental.cs b/Projects/UOContent/Mobiles/Monsters/Ore Elementals/VeriteElemental.cs index 8aaf413fc..5690fd287 100644 --- a/Projects/UOContent/Mobiles/Monsters/Ore Elementals/VeriteElemental.cs +++ b/Projects/UOContent/Mobiles/Monsters/Ore Elementals/VeriteElemental.cs @@ -1,73 +1,75 @@ using Server.Items; -namespace Server.Mobiles +namespace Server.Mobiles; + +public class VeriteElemental : BaseCreature { - public class VeriteElemental : BaseCreature + [Constructible] + public VeriteElemental(int oreAmount = 2) : base(AIType.AI_Melee) { - [Constructible] - public VeriteElemental(int oreAmount = 2) : base(AIType.AI_Melee) - { - Body = 113; - BaseSoundID = 268; + Body = 113; + BaseSoundID = 268; - SetStr(226, 255); - SetDex(126, 145); - SetInt(71, 92); + SetStr(226, 255); + SetDex(126, 145); + SetInt(71, 92); - SetHits(136, 153); + SetHits(136, 153); - SetDamage(9, 16); + SetDamage(9, 16); - SetDamageType(ResistanceType.Physical, 50); - SetDamageType(ResistanceType.Energy, 50); + SetDamageType(ResistanceType.Physical, 50); + SetDamageType(ResistanceType.Energy, 50); - SetResistance(ResistanceType.Physical, 30, 40); - SetResistance(ResistanceType.Fire, 10, 20); - SetResistance(ResistanceType.Cold, 50, 60); - SetResistance(ResistanceType.Poison, 50, 60); - SetResistance(ResistanceType.Energy, 50, 60); + SetResistance(ResistanceType.Physical, 30, 40); + SetResistance(ResistanceType.Fire, 10, 20); + SetResistance(ResistanceType.Cold, 50, 60); + SetResistance(ResistanceType.Poison, 50, 60); + SetResistance(ResistanceType.Energy, 50, 60); - SetSkill(SkillName.MagicResist, 50.1, 95.0); - SetSkill(SkillName.Tactics, 60.1, 100.0); - SetSkill(SkillName.Wrestling, 60.1, 100.0); + SetSkill(SkillName.MagicResist, 50.1, 95.0); + SetSkill(SkillName.Tactics, 60.1, 100.0); + SetSkill(SkillName.Wrestling, 60.1, 100.0); - Fame = 3500; - Karma = -3500; + Fame = 3500; + Karma = -3500; - VirtualArmor = 35; + VirtualArmor = 35; - Item ore = new VeriteOre(oreAmount); - ore.ItemID = 0x19B9; - PackItem(ore); - } + Item ore = new VeriteOre(oreAmount); + ore.ItemID = 0x19B9; + PackItem(ore); + } - public VeriteElemental(Serial serial) : base(serial) - { - } + public VeriteElemental(Serial serial) : base(serial) + { + } - public override string CorpseName => "an ore elemental corpse"; - public override string DefaultName => "a verite elemental"; + public override string CorpseName => "an ore elemental corpse"; + public override string DefaultName => "a verite elemental"; - public override bool AutoDispel => true; - public override bool BleedImmune => true; - public override int TreasureMapLevel => 1; + public override bool AutoDispel => true; + public override bool BleedImmune => true; + public override int TreasureMapLevel => 1; - public override void GenerateLoot() - { - AddLoot(LootPack.Rich); - AddLoot(LootPack.Gems, 2); - } + private static MonsterAbility[] _abilities = { MonsterAbility.DestroyEquipment }; + public override MonsterAbility[] GetMonsterAbilities() => _abilities; - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - writer.Write(0); - } + public override void GenerateLoot() + { + AddLoot(LootPack.Rich); + AddLoot(LootPack.Gems, 2); + } - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - var version = reader.ReadInt(); - } + public override void Serialize(IGenericWriter writer) + { + base.Serialize(writer); + writer.Write(0); + } + + public override void Deserialize(IGenericReader reader) + { + base.Deserialize(reader); + var version = reader.ReadInt(); } } diff --git a/Projects/UOContent/Mobiles/Monsters/Reptile/Magic/Leviathan.cs b/Projects/UOContent/Mobiles/Monsters/Reptile/Magic/Leviathan.cs index bf944cc15..3b6d9c991 100644 --- a/Projects/UOContent/Mobiles/Monsters/Reptile/Magic/Leviathan.cs +++ b/Projects/UOContent/Mobiles/Monsters/Reptile/Magic/Leviathan.cs @@ -169,9 +169,9 @@ namespace Server.Mobiles public class LevianthanBreath : FireBreath { - public override int BreathPhysicalDamage => 70; - public override int BreathColdDamage => 30; - public override int BreathFireDamage => 0; + public override int PhysicalDamage => 70; + public override int ColdDamage => 30; + public override int FireDamage => 0; public override int BreathEffectHue => 0x1ED; public override double BreathDamageScalar => 0.05; public override TimeSpan MinTriggerCooldown => TimeSpan.FromSeconds(5.0);