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 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 class ColdBreath : FireBreath
|
||||||
{
|
{
|
||||||
public override int BreathColdDamage => 100;
|
public override int ColdDamage => 100;
|
||||||
public override int BreathFireDamage => 0;
|
public override int FireDamage => 0;
|
||||||
public override int BreathEffectHue => 0x480;
|
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 class FireBreath : MonsterAbility
|
||||||
{
|
{
|
||||||
public override MonsterAbilityTrigger AbilityTrigger => MonsterAbilityTrigger.Action;
|
public override MonsterAbilityTrigger AbilityTrigger => MonsterAbilityTrigger.OnAction;
|
||||||
public override MonsterAbilityType AbilityType => MonsterAbilityType.FireBreath;
|
public override MonsterAbilityType AbilityType => MonsterAbilityType.FireBreath;
|
||||||
public override double ChanceToTrigger => 0.5;
|
public override double ChanceToTrigger => 0.5;
|
||||||
|
|
||||||
|
|
@ -27,12 +27,12 @@ public class FireBreath : MonsterAbility
|
||||||
public virtual int BreathRange(BaseCreature source) => source.RangePerception;
|
public virtual int BreathRange(BaseCreature source) => source.RangePerception;
|
||||||
|
|
||||||
// Damage Types
|
// Damage Types
|
||||||
public virtual int BreathChaosDamage => 0;
|
public virtual int ChaosDamage => 0;
|
||||||
public virtual int BreathPhysicalDamage => 0;
|
public virtual int PhysicalDamage => 0;
|
||||||
public virtual int BreathFireDamage => 100;
|
public virtual int FireDamage => 100;
|
||||||
public virtual int BreathColdDamage => 0;
|
public virtual int ColdDamage => 0;
|
||||||
public virtual int BreathPoisonDamage => 0;
|
public virtual int PoisonDamage => 0;
|
||||||
public virtual int BreathEnergyDamage => 0;
|
public virtual int EnergyDamage => 0;
|
||||||
|
|
||||||
// Effect details and sound
|
// Effect details and sound
|
||||||
public virtual int BreathEffectItemID => 0x36D4;
|
public virtual int BreathEffectItemID => 0x36D4;
|
||||||
|
|
@ -146,39 +146,39 @@ public class FireBreath : MonsterAbility
|
||||||
{
|
{
|
||||||
if (!Evasion.CheckSpellEvasion(target))
|
if (!Evasion.CheckSpellEvasion(target))
|
||||||
{
|
{
|
||||||
var physDamage = BreathPhysicalDamage;
|
var physDamage = PhysicalDamage;
|
||||||
var fireDamage = BreathFireDamage;
|
var fireDamage = FireDamage;
|
||||||
var coldDamage = BreathColdDamage;
|
var coldDamage = ColdDamage;
|
||||||
var poisDamage = BreathPoisonDamage;
|
var poisDamage = PoisonDamage;
|
||||||
var nrgyDamage = BreathEnergyDamage;
|
var nrgyDamage = EnergyDamage;
|
||||||
|
|
||||||
if (BreathChaosDamage > 0)
|
if (ChaosDamage > 0)
|
||||||
{
|
{
|
||||||
switch (Utility.Random(5))
|
switch (Utility.Random(5))
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
{
|
{
|
||||||
physDamage += BreathChaosDamage;
|
physDamage += ChaosDamage;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 1:
|
case 1:
|
||||||
{
|
{
|
||||||
fireDamage += BreathChaosDamage;
|
fireDamage += ChaosDamage;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 2:
|
case 2:
|
||||||
{
|
{
|
||||||
coldDamage += BreathChaosDamage;
|
coldDamage += ChaosDamage;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 3:
|
case 3:
|
||||||
{
|
{
|
||||||
poisDamage += BreathChaosDamage;
|
poisDamage += ChaosDamage;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 4:
|
case 4:
|
||||||
{
|
{
|
||||||
nrgyDamage += BreathChaosDamage;
|
nrgyDamage += ChaosDamage;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,4 +12,18 @@ public abstract partial class MonsterAbility
|
||||||
// Summon Undead
|
// Summon Undead
|
||||||
public static SummonSkeletons SummonSkeletons => new();
|
public static SummonSkeletons SummonSkeletons => new();
|
||||||
public static SummonLesserUndead SummonLesserUndead => 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]
|
[Flags]
|
||||||
public enum MonsterAbilityTrigger
|
public enum MonsterAbilityTrigger
|
||||||
{
|
{
|
||||||
None = 0x00000000, // Passive, or some custom event.
|
None = 0x00000000, // Passive, or some custom event.
|
||||||
Action = 0x00000001, // On Think
|
OnAction = 0x00000001, // On Think
|
||||||
TakeMeleeDamage = 0x00000002,
|
TakeMeleeDamage = 0x00000002,
|
||||||
GiveMeleeDamage = 0x00000004, // Includes firing a bow
|
GiveMeleeDamage = 0x00000004, // Includes firing a bow
|
||||||
TakeSpellDamage = 0x00000008,
|
TakeSpellDamage = 0x00000008,
|
||||||
GiveSpellDamage = 0x00000010,
|
GiveSpellDamage = 0x00000010,
|
||||||
|
OnCombatAction = 0x00000020,
|
||||||
|
OnDeath = 0x00000040,
|
||||||
|
|
||||||
TakeDamage = TakeMeleeDamage | TakeSpellDamage
|
TakeDamage = TakeMeleeDamage | TakeSpellDamage
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,5 +5,10 @@ public enum MonsterAbilityType
|
||||||
Generic,
|
Generic,
|
||||||
FireBreath,
|
FireBreath,
|
||||||
GraspingClaw,
|
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()
|
public override bool OnBeforeDeath()
|
||||||
{
|
{
|
||||||
|
TriggerAbility(MonsterAbilityTrigger.OnDeath, null);
|
||||||
|
|
||||||
var treasureLevel = TreasureMapLevel;
|
var treasureLevel = TreasureMapLevel;
|
||||||
|
|
||||||
if (treasureLevel == 1 && Map == Map.Trammel && TreasureMap.IsInHavenIsland(this))
|
if (treasureLevel == 1 && Map == Map.Trammel && TreasureMap.IsInHavenIsland(this))
|
||||||
|
|
@ -3515,7 +3517,7 @@ namespace Server.Mobiles
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fire breath, etc.
|
// Fire breath, etc.
|
||||||
TriggerAbility(MonsterAbilityTrigger.Action, Combatant);
|
TriggerAbility(MonsterAbilityTrigger.OnAction, Combatant);
|
||||||
|
|
||||||
if ((CanHeal || CanHealOwner) && Alive && !IsHealing && !BardPacified)
|
if ((CanHeal || CanHealOwner) && Alive && !IsHealing && !BardPacified)
|
||||||
{
|
{
|
||||||
|
|
@ -4170,6 +4172,7 @@ namespace Server.Mobiles
|
||||||
|
|
||||||
public virtual void OnActionCombat()
|
public virtual void OnActionCombat()
|
||||||
{
|
{
|
||||||
|
TriggerAbility(MonsterAbilityTrigger.OnCombatAction, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual void OnActionGuard()
|
public virtual void OnActionGuard()
|
||||||
|
|
|
||||||
|
|
@ -1,188 +1,117 @@
|
||||||
using System;
|
|
||||||
using Server.Items;
|
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;
|
Body = 767;
|
||||||
private bool m_Stunning;
|
|
||||||
|
|
||||||
[Constructible]
|
SetStr(401, 500);
|
||||||
public Betrayer() : base(AIType.AI_Mage)
|
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;
|
PackItem(new BlackthornWelcomeBook());
|
||||||
|
|
||||||
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));
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public Betrayer(Serial serial)
|
public Betrayer(Serial serial) : base(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)
|
||||||
{
|
{
|
||||||
}
|
if (!IsParagon)
|
||||||
|
|
||||||
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 (Utility.RandomDouble() < 0.75)
|
||||||
{
|
{
|
||||||
if (Utility.RandomDouble() < 0.75)
|
c.DropItem(DawnsMusicGear.RandomCommon);
|
||||||
{
|
|
||||||
c.DropItem(DawnsMusicGear.RandomCommon);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
c.DropItem(DawnsMusicGear.RandomUncommon);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
c.DropItem(DawnsMusicGear.RandomRare);
|
c.DropItem(DawnsMusicGear.RandomUncommon);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
else
|
||||||
|
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
m_Stunning = true;
|
c.DropItem(DawnsMusicGear.RandomRare);
|
||||||
|
|
||||||
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)
|
|
||||||
{
|
public override int GetDeathSound() => 0x423;
|
||||||
defender.Frozen = false;
|
|
||||||
defender.Combatant = null;
|
public override int GetAttackSound() => 0x23B;
|
||||||
defender.LocalOverheadMessage(MessageType.Regular, 0x3B2, false, "You recover your senses.");
|
|
||||||
m_Stunning = false;
|
public override int GetHurtSound() => 0x140;
|
||||||
}
|
|
||||||
|
public override void GenerateLoot()
|
||||||
public override void OnActionCombat()
|
{
|
||||||
{
|
AddLoot(LootPack.FilthyRich);
|
||||||
var combatant = Combatant;
|
AddLoot(LootPack.Rich);
|
||||||
|
AddLoot(LootPack.Gems, 1);
|
||||||
if (Core.Now < m_NextAbilityTime || combatant?.Deleted != false || combatant.Map != Map ||
|
}
|
||||||
!InRange(combatant, 3) || !CanBeHarmful(combatant) || !InLOS(combatant))
|
|
||||||
{
|
private static MonsterAbility[] _abilities = { MonsterAbility.ColossalBlow, MonsterAbility.PoisonGasAreaAttack };
|
||||||
return;
|
public override MonsterAbility[] GetMonsterAbilities() => _abilities;
|
||||||
}
|
|
||||||
|
public override void Serialize(IGenericWriter writer)
|
||||||
m_NextAbilityTime = Core.Now + TimeSpan.FromSeconds(Utility.RandomMinMax(5, 30));
|
{
|
||||||
|
base.Serialize(writer);
|
||||||
if (Utility.RandomBool())
|
|
||||||
{
|
writer.Write(0); // version
|
||||||
FixedParticles(0x376A, 9, 32, 0x2539, EffectLayer.LeftHand);
|
}
|
||||||
PlaySound(0x1DE);
|
|
||||||
|
public override void Deserialize(IGenericReader reader)
|
||||||
foreach (var m in GetMobilesInRange(2))
|
{
|
||||||
{
|
base.Deserialize(reader);
|
||||||
if (m != this && IsEnemy(m))
|
|
||||||
{
|
var version = reader.ReadInt();
|
||||||
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();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,106 +1,82 @@
|
||||||
using Server.Items;
|
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]
|
Body = 0x2F3;
|
||||||
public GargoyleDestroyer() : base(AIType.AI_Mage)
|
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;
|
PackItem(new GargoylesPickaxe());
|
||||||
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();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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.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]
|
SetStr(301, 400);
|
||||||
public Juggernaut() : base(AIType.AI_Melee)
|
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;
|
PackItem(new PowerCrystal());
|
||||||
|
|
||||||
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());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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 string DefaultName => "a blackthorn juggernaut";
|
||||||
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 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 (!IsParagon)
|
||||||
|
|
||||||
if (Utility.RandomDouble() < 0.05)
|
|
||||||
{
|
{
|
||||||
if (!IsParagon)
|
if (Utility.RandomDouble() < 0.75)
|
||||||
{
|
{
|
||||||
if (Utility.RandomDouble() < 0.75)
|
c.DropItem(DawnsMusicGear.RandomCommon);
|
||||||
{
|
|
||||||
c.DropItem(DawnsMusicGear.RandomCommon);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
c.DropItem(DawnsMusicGear.RandomUncommon);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
c.DropItem(DawnsMusicGear.RandomRare);
|
c.DropItem(DawnsMusicGear.RandomUncommon);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
else
|
||||||
|
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
m_Stunning = true;
|
c.DropItem(DawnsMusicGear.RandomRare);
|
||||||
|
|
||||||
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)
|
|
||||||
{
|
public override void GenerateLoot()
|
||||||
defender.Frozen = false;
|
{
|
||||||
defender.Combatant = null;
|
AddLoot(LootPack.Rich);
|
||||||
defender.LocalOverheadMessage(MessageType.Regular, 0x3B2, false, "You recover your senses.");
|
AddLoot(LootPack.Gems, 1);
|
||||||
m_Stunning = false;
|
}
|
||||||
}
|
|
||||||
|
public override int GetDeathSound() => 0x423;
|
||||||
public override void Serialize(IGenericWriter writer)
|
|
||||||
{
|
public override int GetAttackSound() => 0x23B;
|
||||||
base.Serialize(writer);
|
|
||||||
|
public override int GetHurtSound() => 0x140;
|
||||||
writer.Write(0); // version
|
|
||||||
}
|
public override void Serialize(IGenericWriter writer)
|
||||||
|
{
|
||||||
public override void Deserialize(IGenericReader reader)
|
base.Serialize(writer);
|
||||||
{
|
|
||||||
base.Deserialize(reader);
|
writer.Write(0); // version
|
||||||
|
}
|
||||||
var version = reader.ReadInt();
|
|
||||||
}
|
public override void Deserialize(IGenericReader reader)
|
||||||
|
{
|
||||||
|
base.Deserialize(reader);
|
||||||
|
|
||||||
|
var version = reader.ReadInt();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -90,7 +90,7 @@ namespace Server.Mobiles
|
||||||
}
|
}
|
||||||
case 1:
|
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));
|
defender.Freeze(TimeSpan.FromSeconds(3.0));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,246 +1,182 @@
|
||||||
using System;
|
|
||||||
using Server.Items;
|
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]
|
if (summoned)
|
||||||
public Golem(bool summoned = false, double scalar = 1.0) : base(AIType.AI_Melee)
|
|
||||||
{
|
{
|
||||||
Body = 752;
|
Hue = 2101;
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
SetSkill(SkillName.MagicResist, 150.1 * scalar, 190.0 * scalar);
|
||||||
public override bool IsScaryToPets => true;
|
SetSkill(SkillName.Tactics, 60.1 * scalar, 100.0 * scalar);
|
||||||
|
SetSkill(SkillName.Wrestling, 60.1 * scalar, 100.0 * scalar);
|
||||||
|
|
||||||
public override bool IsBondable => false;
|
if (summoned)
|
||||||
|
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
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);
|
||||||
{
|
|
||||||
c.DropItem(DawnsMusicGear.RandomCommon);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
c.DropItem(DawnsMusicGear.RandomUncommon);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
c.DropItem(DawnsMusicGear.RandomRare);
|
c.DropItem(DawnsMusicGear.RandomUncommon);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
else
|
||||||
|
|
||||||
public override int GetAngerSound() => 541;
|
|
||||||
|
|
||||||
public override int GetIdleSound()
|
|
||||||
{
|
|
||||||
if (!Controlled)
|
|
||||||
{
|
{
|
||||||
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;
|
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]
|
Body = 108;
|
||||||
public BronzeElemental(int oreAmount = 2) : base(AIType.AI_Melee)
|
BaseSoundID = 268;
|
||||||
{
|
|
||||||
// TODO: Gas attack
|
|
||||||
Body = 108;
|
|
||||||
BaseSoundID = 268;
|
|
||||||
|
|
||||||
SetStr(226, 255);
|
SetStr(226, 255);
|
||||||
SetDex(126, 145);
|
SetDex(126, 145);
|
||||||
SetInt(71, 92);
|
SetInt(71, 92);
|
||||||
|
|
||||||
SetHits(136, 153);
|
SetHits(136, 153);
|
||||||
|
|
||||||
SetDamage(9, 16);
|
SetDamage(9, 16);
|
||||||
|
|
||||||
SetDamageType(ResistanceType.Physical, 30);
|
SetDamageType(ResistanceType.Physical, 30);
|
||||||
SetDamageType(ResistanceType.Fire, 70);
|
SetDamageType(ResistanceType.Fire, 70);
|
||||||
|
|
||||||
SetResistance(ResistanceType.Physical, 30, 40);
|
SetResistance(ResistanceType.Physical, 30, 40);
|
||||||
SetResistance(ResistanceType.Fire, 30, 40);
|
SetResistance(ResistanceType.Fire, 30, 40);
|
||||||
SetResistance(ResistanceType.Cold, 10, 20);
|
SetResistance(ResistanceType.Cold, 10, 20);
|
||||||
SetResistance(ResistanceType.Poison, 70, 80);
|
SetResistance(ResistanceType.Poison, 70, 80);
|
||||||
SetResistance(ResistanceType.Energy, 20, 30);
|
SetResistance(ResistanceType.Energy, 20, 30);
|
||||||
|
|
||||||
SetSkill(SkillName.MagicResist, 50.1, 95.0);
|
SetSkill(SkillName.MagicResist, 50.1, 95.0);
|
||||||
SetSkill(SkillName.Tactics, 60.1, 100.0);
|
SetSkill(SkillName.Tactics, 60.1, 100.0);
|
||||||
SetSkill(SkillName.Wrestling, 60.1, 100.0);
|
SetSkill(SkillName.Wrestling, 60.1, 100.0);
|
||||||
|
|
||||||
Fame = 5000;
|
Fame = 5000;
|
||||||
Karma = -5000;
|
Karma = -5000;
|
||||||
|
|
||||||
VirtualArmor = 29;
|
VirtualArmor = 29;
|
||||||
|
|
||||||
Item ore = new BronzeOre(oreAmount);
|
Item ore = new BronzeOre(oreAmount);
|
||||||
ore.ItemID = 0x19B9;
|
ore.ItemID = 0x19B9;
|
||||||
PackItem(ore);
|
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 CorpseName => "an ore elemental corpse";
|
||||||
public override string DefaultName => "a bronze elemental";
|
public override string DefaultName => "a bronze elemental";
|
||||||
|
|
||||||
public override bool BleedImmune => true;
|
public override bool BleedImmune => true;
|
||||||
public override bool AutoDispel => true;
|
public override bool AutoDispel => true;
|
||||||
public override int TreasureMapLevel => 1;
|
public override int TreasureMapLevel => 1;
|
||||||
|
|
||||||
public override void GenerateLoot()
|
private static MonsterAbility[] _abilities = { MonsterAbility.PoisonGasCounter };
|
||||||
{
|
public override MonsterAbility[] GetMonsterAbilities() => _abilities;
|
||||||
AddLoot(LootPack.Average);
|
|
||||||
AddLoot(LootPack.Gems, 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Serialize(IGenericWriter writer)
|
public override void GenerateLoot()
|
||||||
{
|
{
|
||||||
base.Serialize(writer);
|
AddLoot(LootPack.Average);
|
||||||
writer.Write(0);
|
AddLoot(LootPack.Gems, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Deserialize(IGenericReader reader)
|
public override void Serialize(IGenericWriter writer)
|
||||||
{
|
{
|
||||||
base.Deserialize(reader);
|
base.Serialize(writer);
|
||||||
var version = reader.ReadInt();
|
writer.Write(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override void Deserialize(IGenericReader reader)
|
||||||
|
{
|
||||||
|
base.Deserialize(reader);
|
||||||
|
var version = reader.ReadInt();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,77 +1,76 @@
|
||||||
using Server.Items;
|
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]
|
Body = 109;
|
||||||
public CopperElemental(int oreAmount = 2) : base(AIType.AI_Melee)
|
BaseSoundID = 268;
|
||||||
{
|
|
||||||
Body = 109;
|
|
||||||
BaseSoundID = 268;
|
|
||||||
|
|
||||||
SetStr(226, 255);
|
SetStr(226, 255);
|
||||||
SetDex(126, 145);
|
SetDex(126, 145);
|
||||||
SetInt(71, 92);
|
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.Physical, 30, 40);
|
||||||
SetResistance(ResistanceType.Fire, 30, 40);
|
SetResistance(ResistanceType.Fire, 30, 40);
|
||||||
SetResistance(ResistanceType.Cold, 30, 40);
|
SetResistance(ResistanceType.Cold, 30, 40);
|
||||||
SetResistance(ResistanceType.Poison, 20, 30);
|
SetResistance(ResistanceType.Poison, 20, 30);
|
||||||
SetResistance(ResistanceType.Energy, 10, 20);
|
SetResistance(ResistanceType.Energy, 10, 20);
|
||||||
|
|
||||||
SetSkill(SkillName.MagicResist, 50.1, 95.0);
|
SetSkill(SkillName.MagicResist, 50.1, 95.0);
|
||||||
SetSkill(SkillName.Tactics, 60.1, 100.0);
|
SetSkill(SkillName.Tactics, 60.1, 100.0);
|
||||||
SetSkill(SkillName.Wrestling, 60.1, 100.0);
|
SetSkill(SkillName.Wrestling, 60.1, 100.0);
|
||||||
|
|
||||||
Fame = 4800;
|
Fame = 4800;
|
||||||
Karma = -4800;
|
Karma = -4800;
|
||||||
|
|
||||||
VirtualArmor = 26;
|
VirtualArmor = 26;
|
||||||
|
|
||||||
Item ore = new CopperOre(oreAmount);
|
Item ore = new CopperOre(oreAmount);
|
||||||
ore.ItemID = 0x19B9;
|
ore.ItemID = 0x19B9;
|
||||||
PackItem(ore);
|
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 CorpseName => "an ore elemental corpse";
|
||||||
public override string DefaultName => "a copper elemental";
|
public override string DefaultName => "a copper elemental";
|
||||||
|
|
||||||
public override bool BleedImmune => true;
|
public override bool BleedImmune => true;
|
||||||
public override bool AutoDispel => true;
|
public override bool AutoDispel => true;
|
||||||
public override int TreasureMapLevel => 1;
|
public override int TreasureMapLevel => 1;
|
||||||
|
|
||||||
public override void GenerateLoot()
|
public override void GenerateLoot()
|
||||||
{
|
{
|
||||||
AddLoot(LootPack.Average);
|
AddLoot(LootPack.Average);
|
||||||
AddLoot(LootPack.Gems, 2);
|
AddLoot(LootPack.Gems, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void CheckReflect(Mobile caster, ref bool reflect)
|
public override void CheckReflect(Mobile caster, ref bool reflect)
|
||||||
{
|
{
|
||||||
reflect = true; // Every spell is reflected back to the caster
|
reflect = true; // Every spell is reflected back to the caster
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Serialize(IGenericWriter writer)
|
public override void Serialize(IGenericWriter writer)
|
||||||
{
|
{
|
||||||
base.Serialize(writer);
|
base.Serialize(writer);
|
||||||
writer.Write(0);
|
writer.Write(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Deserialize(IGenericReader reader)
|
public override void Deserialize(IGenericReader reader)
|
||||||
{
|
{
|
||||||
base.Deserialize(reader);
|
base.Deserialize(reader);
|
||||||
var version = reader.ReadInt();
|
var version = reader.ReadInt();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,72 +1,74 @@
|
||||||
using Server.Items;
|
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]
|
Body = 110;
|
||||||
public DullCopperElemental(int oreAmount = 2) : base(AIType.AI_Melee)
|
BaseSoundID = 268;
|
||||||
{
|
|
||||||
Body = 110;
|
|
||||||
BaseSoundID = 268;
|
|
||||||
|
|
||||||
SetStr(226, 255);
|
SetStr(226, 255);
|
||||||
SetDex(126, 145);
|
SetDex(126, 145);
|
||||||
SetInt(71, 92);
|
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.Physical, 30, 40);
|
||||||
SetResistance(ResistanceType.Fire, 30, 40);
|
SetResistance(ResistanceType.Fire, 30, 40);
|
||||||
SetResistance(ResistanceType.Cold, 10, 20);
|
SetResistance(ResistanceType.Cold, 10, 20);
|
||||||
SetResistance(ResistanceType.Poison, 20, 30);
|
SetResistance(ResistanceType.Poison, 20, 30);
|
||||||
SetResistance(ResistanceType.Energy, 20, 30);
|
SetResistance(ResistanceType.Energy, 20, 30);
|
||||||
|
|
||||||
SetSkill(SkillName.MagicResist, 50.1, 95.0);
|
SetSkill(SkillName.MagicResist, 50.1, 95.0);
|
||||||
SetSkill(SkillName.Tactics, 60.1, 100.0);
|
SetSkill(SkillName.Tactics, 60.1, 100.0);
|
||||||
SetSkill(SkillName.Wrestling, 60.1, 100.0);
|
SetSkill(SkillName.Wrestling, 60.1, 100.0);
|
||||||
|
|
||||||
Fame = 3500;
|
Fame = 3500;
|
||||||
Karma = -3500;
|
Karma = -3500;
|
||||||
|
|
||||||
VirtualArmor = 20;
|
VirtualArmor = 20;
|
||||||
|
|
||||||
Item ore = new DullCopperOre(oreAmount);
|
Item ore = new DullCopperOre(oreAmount);
|
||||||
ore.ItemID = 0x19B9;
|
ore.ItemID = 0x19B9;
|
||||||
PackItem(ore);
|
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 CorpseName => "an ore elemental corpse";
|
||||||
public override string DefaultName => "a dull copper elemental";
|
public override string DefaultName => "a dull copper elemental";
|
||||||
|
|
||||||
public override bool AutoDispel => true;
|
public override bool AutoDispel => true;
|
||||||
public override bool BleedImmune => true;
|
public override bool BleedImmune => true;
|
||||||
public override int TreasureMapLevel => 1;
|
public override int TreasureMapLevel => 1;
|
||||||
|
|
||||||
public override void GenerateLoot()
|
private static MonsterAbility[] _abilities = { MonsterAbility.DeathExplosion };
|
||||||
{
|
public override MonsterAbility[] GetMonsterAbilities() => _abilities;
|
||||||
AddLoot(LootPack.Average);
|
|
||||||
AddLoot(LootPack.Gems, 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Serialize(IGenericWriter writer)
|
public override void GenerateLoot()
|
||||||
{
|
{
|
||||||
base.Serialize(writer);
|
AddLoot(LootPack.Average);
|
||||||
writer.Write(0);
|
AddLoot(LootPack.Gems, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Deserialize(IGenericReader reader)
|
public override void Serialize(IGenericWriter writer)
|
||||||
{
|
{
|
||||||
base.Deserialize(reader);
|
base.Serialize(writer);
|
||||||
var version = reader.ReadInt();
|
writer.Write(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override void Deserialize(IGenericReader reader)
|
||||||
|
{
|
||||||
|
base.Deserialize(reader);
|
||||||
|
var version = reader.ReadInt();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,92 +1,93 @@
|
||||||
using Server.Items;
|
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]
|
Body = 112;
|
||||||
public ValoriteElemental(int oreAmount = 2) : base(AIType.AI_Melee)
|
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
|
if (bc.Controlled || bc.BardTarget == this)
|
||||||
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)
|
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)
|
public override void CheckReflect(Mobile caster, ref bool reflect)
|
||||||
{
|
{
|
||||||
reflect = true; // Every spell is reflected back to the caster
|
reflect = true; // Every spell is reflected back to the caster
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Serialize(IGenericWriter writer)
|
public override void Serialize(IGenericWriter writer)
|
||||||
{
|
{
|
||||||
base.Serialize(writer);
|
base.Serialize(writer);
|
||||||
writer.Write(0);
|
writer.Write(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Deserialize(IGenericReader reader)
|
public override void Deserialize(IGenericReader reader)
|
||||||
{
|
{
|
||||||
base.Deserialize(reader);
|
base.Deserialize(reader);
|
||||||
var version = reader.ReadInt();
|
var version = reader.ReadInt();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,73 +1,75 @@
|
||||||
using Server.Items;
|
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]
|
Body = 113;
|
||||||
public VeriteElemental(int oreAmount = 2) : base(AIType.AI_Melee)
|
BaseSoundID = 268;
|
||||||
{
|
|
||||||
Body = 113;
|
|
||||||
BaseSoundID = 268;
|
|
||||||
|
|
||||||
SetStr(226, 255);
|
SetStr(226, 255);
|
||||||
SetDex(126, 145);
|
SetDex(126, 145);
|
||||||
SetInt(71, 92);
|
SetInt(71, 92);
|
||||||
|
|
||||||
SetHits(136, 153);
|
SetHits(136, 153);
|
||||||
|
|
||||||
SetDamage(9, 16);
|
SetDamage(9, 16);
|
||||||
|
|
||||||
SetDamageType(ResistanceType.Physical, 50);
|
SetDamageType(ResistanceType.Physical, 50);
|
||||||
SetDamageType(ResistanceType.Energy, 50);
|
SetDamageType(ResistanceType.Energy, 50);
|
||||||
|
|
||||||
SetResistance(ResistanceType.Physical, 30, 40);
|
SetResistance(ResistanceType.Physical, 30, 40);
|
||||||
SetResistance(ResistanceType.Fire, 10, 20);
|
SetResistance(ResistanceType.Fire, 10, 20);
|
||||||
SetResistance(ResistanceType.Cold, 50, 60);
|
SetResistance(ResistanceType.Cold, 50, 60);
|
||||||
SetResistance(ResistanceType.Poison, 50, 60);
|
SetResistance(ResistanceType.Poison, 50, 60);
|
||||||
SetResistance(ResistanceType.Energy, 50, 60);
|
SetResistance(ResistanceType.Energy, 50, 60);
|
||||||
|
|
||||||
SetSkill(SkillName.MagicResist, 50.1, 95.0);
|
SetSkill(SkillName.MagicResist, 50.1, 95.0);
|
||||||
SetSkill(SkillName.Tactics, 60.1, 100.0);
|
SetSkill(SkillName.Tactics, 60.1, 100.0);
|
||||||
SetSkill(SkillName.Wrestling, 60.1, 100.0);
|
SetSkill(SkillName.Wrestling, 60.1, 100.0);
|
||||||
|
|
||||||
Fame = 3500;
|
Fame = 3500;
|
||||||
Karma = -3500;
|
Karma = -3500;
|
||||||
|
|
||||||
VirtualArmor = 35;
|
VirtualArmor = 35;
|
||||||
|
|
||||||
Item ore = new VeriteOre(oreAmount);
|
Item ore = new VeriteOre(oreAmount);
|
||||||
ore.ItemID = 0x19B9;
|
ore.ItemID = 0x19B9;
|
||||||
PackItem(ore);
|
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 CorpseName => "an ore elemental corpse";
|
||||||
public override string DefaultName => "a verite elemental";
|
public override string DefaultName => "a verite elemental";
|
||||||
|
|
||||||
public override bool AutoDispel => true;
|
public override bool AutoDispel => true;
|
||||||
public override bool BleedImmune => true;
|
public override bool BleedImmune => true;
|
||||||
public override int TreasureMapLevel => 1;
|
public override int TreasureMapLevel => 1;
|
||||||
|
|
||||||
public override void GenerateLoot()
|
private static MonsterAbility[] _abilities = { MonsterAbility.DestroyEquipment };
|
||||||
{
|
public override MonsterAbility[] GetMonsterAbilities() => _abilities;
|
||||||
AddLoot(LootPack.Rich);
|
|
||||||
AddLoot(LootPack.Gems, 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Serialize(IGenericWriter writer)
|
public override void GenerateLoot()
|
||||||
{
|
{
|
||||||
base.Serialize(writer);
|
AddLoot(LootPack.Rich);
|
||||||
writer.Write(0);
|
AddLoot(LootPack.Gems, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Deserialize(IGenericReader reader)
|
public override void Serialize(IGenericWriter writer)
|
||||||
{
|
{
|
||||||
base.Deserialize(reader);
|
base.Serialize(writer);
|
||||||
var version = reader.ReadInt();
|
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 class LevianthanBreath : FireBreath
|
||||||
{
|
{
|
||||||
public override int BreathPhysicalDamage => 70;
|
public override int PhysicalDamage => 70;
|
||||||
public override int BreathColdDamage => 30;
|
public override int ColdDamage => 30;
|
||||||
public override int BreathFireDamage => 0;
|
public override int FireDamage => 0;
|
||||||
public override int BreathEffectHue => 0x1ED;
|
public override int BreathEffectHue => 0x1ED;
|
||||||
public override double BreathDamageScalar => 0.05;
|
public override double BreathDamageScalar => 0.05;
|
||||||
public override TimeSpan MinTriggerCooldown => TimeSpan.FromSeconds(5.0);
|
public override TimeSpan MinTriggerCooldown => TimeSpan.FromSeconds(5.0);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue