feat: Adds stun, death explosion, poison gas, throw hatchet abilities (#1180)
* Adds Colossal Blow * Adds Death Explosion * Adds Poison Gas * Adds AOE Poison Gas (Counter) * Adds Stun * Adds Throw Hatchet
This commit is contained in:
parent
43e7fe29c2
commit
dc6f75c3b4
27 changed files with 1062 additions and 935 deletions
|
|
@ -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<Mobile>.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);
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
27
Projects/UOContent/Mobiles/Abilities/ColossalBlow.cs
Normal file
27
Projects/UOContent/Mobiles/Abilities/ColossalBlow.cs
Normal file
|
|
@ -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.");
|
||||
}
|
||||
}
|
||||
29
Projects/UOContent/Mobiles/Abilities/DeathExplosion.cs
Normal file
29
Projects/UOContent/Mobiles/Abilities/DeathExplosion.cs
Normal file
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
55
Projects/UOContent/Mobiles/Abilities/DestroyEquipment.cs
Normal file
55
Projects/UOContent/Mobiles/Abilities/DestroyEquipment.cs
Normal file
|
|
@ -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<Item>.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);
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
|
|
|||
22
Projects/UOContent/Mobiles/Abilities/MonsterAbilityAttack.cs
Normal file
22
Projects/UOContent/Mobiles/Abilities/MonsterAbilityAttack.cs
Normal file
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,5 +5,10 @@ public enum MonsterAbilityType
|
|||
Generic,
|
||||
FireBreath,
|
||||
GraspingClaw,
|
||||
SummonUndead
|
||||
SummonUndead,
|
||||
Stun,
|
||||
Poison,
|
||||
MassPoison,
|
||||
ThrowWeapon,
|
||||
DestroyEquipment
|
||||
}
|
||||
|
|
|
|||
19
Projects/UOContent/Mobiles/Abilities/PoisonGasAreaAttack.cs
Normal file
19
Projects/UOContent/Mobiles/Abilities/PoisonGasAreaAttack.cs
Normal file
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
22
Projects/UOContent/Mobiles/Abilities/PoisonGasCounter.cs
Normal file
22
Projects/UOContent/Mobiles/Abilities/PoisonGasCounter.cs
Normal file
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
44
Projects/UOContent/Mobiles/Abilities/StunAttack.cs
Normal file
44
Projects/UOContent/Mobiles/Abilities/StunAttack.cs
Normal file
|
|
@ -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<BaseCreature> _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<BaseCreature>();
|
||||
_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;
|
||||
}
|
||||
}
|
||||
19
Projects/UOContent/Mobiles/Abilities/ThrowHatchetCounter.cs
Normal file
19
Projects/UOContent/Mobiles/Abilities/ThrowHatchetCounter.cs
Normal file
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue