Reorganizes Project (#41)

This commit is contained in:
Kamron Batman 2019-08-02 18:13:40 -07:00 • committed by GitHub
parent 08bf44af9a
commit 3614a66aee
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3499 changed files with 79 additions and 55 deletions

View file

@ -0,0 +1,149 @@
using Server.Items;
namespace Server.Mobiles
{
public class CuSidhe : BaseMount
{
[Constructible]
public CuSidhe(string name = null) :
base(name, 277, 0x3E91, AIType.AI_Animal, FightMode.Aggressor, 10, 1, 0.2, 0.4)
{
double chance = Utility.RandomDouble() * 23301;
if (chance <= 1)
Hue = 0x489;
else if (chance < 50)
Hue = Utility.RandomList(0x657, 0x515, 0x4B1, 0x481, 0x482, 0x455);
else if (chance < 500)
Hue = Utility.RandomList(0x97A, 0x978, 0x901, 0x8AC, 0x5A7, 0x527);
SetStr(1200, 1225);
SetDex(150, 170);
SetInt(250, 285);
SetHits(1010, 1275);
SetDamage(21, 28);
SetDamageType(ResistanceType.Physical, 0);
SetDamageType(ResistanceType.Cold, 50);
SetDamageType(ResistanceType.Energy, 50);
SetResistance(ResistanceType.Physical, 50, 65);
SetResistance(ResistanceType.Fire, 25, 45);
SetResistance(ResistanceType.Cold, 70, 85);
SetResistance(ResistanceType.Poison, 30, 50);
SetResistance(ResistanceType.Energy, 70, 85);
SetSkill(SkillName.Wrestling, 90.1, 96.8);
SetSkill(SkillName.Tactics, 90.3, 99.3);
SetSkill(SkillName.MagicResist, 75.3, 90.0);
SetSkill(SkillName.Anatomy, 65.5, 69.4);
SetSkill(SkillName.Healing, 72.2, 98.9);
Fame = 5000; //Guessing here
Karma = 5000; //Guessing here
Tamable = true;
ControlSlots = 4;
MinTameSkill = 101.1;
if (Utility.RandomDouble() < 0.2)
PackItem(new TreasureMap(5, Map.Trammel));
//if ( Utility.RandomDouble() < 0.1 )
//PackItem( new ParrotItem() );
PackGold(500, 800);
// TODO 0-2 spellweaving scroll
}
public CuSidhe(Serial serial) : base(serial)
{
}
public override string CorpseName => "a cu sidhe corpse";
public override string DefaultName => "a cu sidhe";
public override bool CanHeal => true;
public override bool CanHealOwner => true;
public override FoodType FavoriteFood => FoodType.FruitsAndVegies;
public override bool CanAngerOnTame => true;
public override bool StatLossAfterTame => true;
public override int Hides => 10;
public override int Meat => 3;
public override void GenerateLoot()
{
AddLoot(LootPack.AosFilthyRich, 5);
}
public override void OnDoubleClick(Mobile from)
{
if (from.Race != Race.Elf && from == ControlMaster && from.AccessLevel == AccessLevel.Player)
{
Item pads = from.FindItemOnLayer(Layer.Shoes);
if (pads is PadsOfTheCuSidhe)
{
from.SendLocalizedMessage(1071981); // Your boots allow you to mount the Cu Sidhe.
}
else
{
from.SendLocalizedMessage(1072203); // Only Elves may use this.
return;
}
}
base.OnDoubleClick(from);
}
public override WeaponAbility GetWeaponAbility()
{
return WeaponAbility.BleedAttack;
}
public override int GetIdleSound()
{
return 0x577;
}
public override int GetAttackSound()
{
return 0x576;
}
public override int GetAngerSound()
{
return 0x578;
}
public override int GetHurtSound()
{
return 0x576;
}
public override int GetDeathSound()
{
return 0x579;
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write(1); // version
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
if (version < 1 && Name == "a Cu Sidhe")
Name = null;
}
}
}

View file

@ -0,0 +1,104 @@
using System;
using Server.Engines.Quests;
namespace Server.Mobiles
{
public class Ferret : BaseCreature
{
private static string[] m_Vocabulary =
{
"dook",
"dook dook",
"dook dook dook!"
};
private bool m_CanTalk;
[Constructible]
public Ferret() : base(AIType.AI_Animal, FightMode.Aggressor, 10, 1, 0.2, 0.4)
{
Body = 0x117;
SetStr(41, 48);
SetDex(55);
SetInt(75);
SetHits(45, 50);
SetDamage(7, 9);
SetDamageType(ResistanceType.Physical, 100);
SetResistance(ResistanceType.Physical, 45, 50);
SetResistance(ResistanceType.Fire, 10, 14);
SetResistance(ResistanceType.Cold, 30, 40);
SetResistance(ResistanceType.Poison, 21, 25);
SetResistance(ResistanceType.Energy, 20, 25);
SetSkill(SkillName.MagicResist, 4.0);
SetSkill(SkillName.Tactics, 4.0);
SetSkill(SkillName.Wrestling, 4.0);
Tamable = true;
ControlSlots = 1;
MinTameSkill = -21.3;
m_CanTalk = true;
}
public Ferret(Serial serial) : base(serial)
{
}
public override string CorpseName => "a ferret corpse";
public override string DefaultName => "a ferret";
public override int Meat => 1;
public override FoodType FavoriteFood => FoodType.Fish;
public override void OnMovement(Mobile m, Point3D oldLocation)
{
if (m is Ferret ferret && ferret.InRange(this, 3) && ferret.Alive)
Talk(ferret);
}
public void Talk()
{
Talk(null);
}
public void Talk(Ferret to)
{
if (m_CanTalk)
{
if (to != null)
QuestSystem.FocusTo(this, to);
Say(m_Vocabulary[Utility.Random(m_Vocabulary.Length)]);
if (to != null && Utility.RandomBool())
Timer.DelayCall(TimeSpan.FromSeconds(Utility.RandomMinMax(5, 8)), delegate { to.Talk(); });
m_CanTalk = false;
Timer.DelayCall(TimeSpan.FromSeconds(Utility.RandomMinMax(20, 30)), delegate { m_CanTalk = true; });
}
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
m_CanTalk = true;
}
}
}

View file

@ -0,0 +1,66 @@
namespace Server.Mobiles
{
[TypeAlias("Server.Mobiles.Grizzlybear")]
public class RagingGrizzlyBear : BaseCreature
{
[Constructible]
public RagingGrizzlyBear() : base(AIType.AI_Animal, FightMode.Aggressor, 10, 1, 0.2, 0.4)
{
Body = 212;
BaseSoundID = 0xA3;
SetStr(1251, 1550);
SetDex(801, 1050);
SetInt(151, 400);
SetHits(751, 930);
SetMana(0);
SetDamage(18, 23);
SetDamageType(ResistanceType.Physical, 100);
SetResistance(ResistanceType.Physical, 50, 70);
SetResistance(ResistanceType.Cold, 30, 50);
SetResistance(ResistanceType.Poison, 10, 20);
SetResistance(ResistanceType.Energy, 10, 20);
SetSkill(SkillName.Wrestling, 73.4, 88.1);
SetSkill(SkillName.Tactics, 73.6, 110.5);
SetSkill(SkillName.MagicResist, 32.8, 54.6);
SetSkill(SkillName.Anatomy, 0, 0);
Fame = 10000; //Guessing here
Karma = 10000; //Guessing here
VirtualArmor = 24;
Tamable = false;
}
public RagingGrizzlyBear(Serial serial) : base(serial)
{
}
public override string CorpseName => "a grizzly bear corpse";
public override string DefaultName => "a raging grizzly bear";
public override int Meat => 4;
public override int Hides => 32;
public override PackInstinct PackInstinct => PackInstinct.Bear;
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write(0);
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

View file

@ -0,0 +1,59 @@
namespace Server.Mobiles
{
public class Squirrel : BaseCreature
{
[Constructible]
public Squirrel() : base(AIType.AI_Animal, FightMode.Aggressor, 10, 1, 0.2, 0.4)
{
Body = 0x116;
SetStr(44, 50);
SetDex(35);
SetInt(5);
SetHits(42, 50);
SetDamage(1, 2);
SetDamageType(ResistanceType.Physical, 100);
SetResistance(ResistanceType.Physical, 30, 34);
SetResistance(ResistanceType.Fire, 10, 14);
SetResistance(ResistanceType.Cold, 30, 35);
SetResistance(ResistanceType.Poison, 20, 25);
SetResistance(ResistanceType.Energy, 20, 25);
SetSkill(SkillName.MagicResist, 4.0);
SetSkill(SkillName.Tactics, 4.0);
SetSkill(SkillName.Wrestling, 4.0);
Tamable = true;
ControlSlots = 1;
MinTameSkill = -21.3;
}
public Squirrel(Serial serial) : base(serial)
{
}
public override string CorpseName => "a squirrel corpse";
public override string DefaultName => "a squirrell";
public override int Meat => 1;
public override FoodType FavoriteFood => FoodType.FruitsAndVegies;
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

View file

@ -0,0 +1,136 @@
using System;
using System.Collections.Generic;
namespace Server.Mobiles
{
public class LadyJennifyr : SkeletalKnight
{
private static Dictionary<Mobile, ExpireTimer> m_Table = new Dictionary<Mobile, ExpireTimer>();
[Constructible]
public LadyJennifyr()
{
IsParagon = true;
Hue = 0x76D;
SetStr(208, 309);
SetDex(91, 118);
SetInt(44, 101);
SetHits(1113, 1285);
SetDamage(15, 25);
SetDamageType(ResistanceType.Physical, 40);
SetDamageType(ResistanceType.Cold, 60);
SetResistance(ResistanceType.Physical, 56, 65);
SetResistance(ResistanceType.Fire, 41, 49);
SetResistance(ResistanceType.Cold, 71, 80);
SetResistance(ResistanceType.Poison, 41, 50);
SetResistance(ResistanceType.Energy, 50, 58);
SetSkill(SkillName.Wrestling, 127.9, 137.1);
SetSkill(SkillName.Tactics, 128.4, 141.9);
SetSkill(SkillName.MagicResist, 102.1, 119.5);
SetSkill(SkillName.Anatomy, 129.0, 137.5);
Fame = 18000;
Karma = -18000;
}
public LadyJennifyr(Serial serial)
: base(serial)
{
}
public override string CorpseName => "a Lady Jennifyr corpse";
public override string DefaultName => "Lady Jennifyr";
/*
// TODO: Uncomment once added
public override void OnDeath( Container c )
{
base.OnDeath( c );
if ( Utility.RandomDouble() < 0.15 )
c.DropItem( new DisintegratingThesisNotes() );
if ( Utility.RandomDouble() < 0.1 )
c.DropItem( new ParrotItem() );
}
*/
public override bool GivesMLMinorArtifact => true;
public override void GenerateLoot()
{
AddLoot(LootPack.UltraRich, 3);
}
public override void OnGaveMeleeAttack(Mobile defender)
{
base.OnGaveMeleeAttack(defender);
if (Utility.RandomDouble() >= 0.1)
return;
if (m_Table.TryGetValue(defender, out ExpireTimer timer))
timer.DoExpire();
defender.FixedParticles(0x3709, 10, 30, 5052, EffectLayer.LeftFoot);
defender.PlaySound(0x208);
defender.SendLocalizedMessage(
1070833); // The creature fans you with fire, reducing your resistance to fire attacks.
ResistanceMod mod = new ResistanceMod(ResistanceType.Fire, -10);
defender.AddResistanceMod(mod);
m_Table[defender] = timer = new ExpireTimer(defender, mod);
timer.Start();
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
private class ExpireTimer : Timer
{
private Mobile m_Mobile;
private ResistanceMod m_Mod;
public ExpireTimer(Mobile m, ResistanceMod mod)
: base(TimeSpan.FromSeconds(10))
{
m_Mobile = m;
m_Mod = mod;
Priority = TimerPriority.TwoFiftyMS;
}
public void DoExpire()
{
m_Mobile.RemoveResistanceMod(m_Mod);
Stop();
m_Table.Remove(m_Mobile);
}
protected override void OnTick()
{
m_Mobile.SendLocalizedMessage(1070834); // Your resistance to fire attacks has returned.
DoExpire();
}
}
}
}

View file

@ -0,0 +1,88 @@
using Server.Items;
namespace Server.Mobiles
{
public class LadyMarai : SkeletalKnight
{
[Constructible]
public LadyMarai()
{
IsParagon = true;
Hue = 0x21;
SetStr(221, 304);
SetDex(98, 138);
SetInt(54, 99);
SetHits(694, 846);
SetDamage(15, 25);
SetDamageType(ResistanceType.Physical, 40);
SetDamageType(ResistanceType.Cold, 60);
SetResistance(ResistanceType.Physical, 55, 65);
SetResistance(ResistanceType.Fire, 40, 50);
SetResistance(ResistanceType.Cold, 70, 80);
SetResistance(ResistanceType.Poison, 40, 50);
SetResistance(ResistanceType.Energy, 50, 60);
SetSkill(SkillName.Wrestling, 126.6, 137.2);
SetSkill(SkillName.Tactics, 128.7, 134.5);
SetSkill(SkillName.MagicResist, 102.1, 119.1);
SetSkill(SkillName.Anatomy, 126.2, 136.5);
Fame = 18000;
Karma = -18000;
}
public LadyMarai(Serial serial)
: base(serial)
{
}
public override string CorpseName => "a Lady Marai corpse";
public override string DefaultName => "Lady Marai";
/*
// TODO: Uncomment once added
public override void OnDeath( Container c )
{
base.OnDeath( c );
if ( Utility.RandomDouble() < 0.15 )
c.DropItem( new DisintegratingThesisNotes() );
if ( Utility.RandomDouble() < 0.1 )
c.DropItem( new ParrotItem() );
}
*/
public override bool GivesMLMinorArtifact => true;
public override void GenerateLoot()
{
AddLoot(LootPack.UltraRich, 3);
}
public override WeaponAbility GetWeaponAbility()
{
return WeaponAbility.CrushingBlow;
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

View file

@ -0,0 +1,95 @@
namespace Server.Mobiles
{
public class MasterJonath : BoneMagi
{
[Constructible]
public MasterJonath()
{
IsParagon = true;
Hue = 0x455;
SetStr(109, 131);
SetDex(98, 110);
SetInt(232, 259);
SetHits(766, 920);
SetDamage(10, 15);
SetDamageType(ResistanceType.Physical, 100);
SetResistance(ResistanceType.Physical, 55, 60);
SetResistance(ResistanceType.Fire, 43, 49);
SetResistance(ResistanceType.Cold, 45, 80);
SetResistance(ResistanceType.Poison, 41, 45);
SetResistance(ResistanceType.Energy, 54, 55);
SetSkill(SkillName.Wrestling, 80.5, 88.6);
SetSkill(SkillName.Tactics, 88.5, 95.1);
SetSkill(SkillName.MagicResist, 102.7, 102.9);
SetSkill(SkillName.Magery, 100.0, 106.6);
SetSkill(SkillName.EvalInt, 99.6, 106.9);
SetSkill(SkillName.Necromancy, 100.0, 106.6);
SetSkill(SkillName.SpiritSpeak, 99.6, 106.9);
Fame = 18000;
Karma = -18000;
if (Utility.RandomBool())
PackNecroScroll(Utility.RandomMinMax(5, 9));
else
PackScroll(4, 7);
PackReg(7);
PackReg(7);
PackReg(8);
}
public MasterJonath(Serial serial)
: base(serial)
{
}
public override string CorpseName => "a Master Jonath corpse";
public override string DefaultName => "Master Jonath";
// TODO: Special move?
/*
// TODO: uncomment once added
public override void OnDeath( Container c )
{
base.OnDeath( c );
if ( Utility.RandomDouble() < 0.05 )
c.DropItem( new ParrotItem() );
if ( Utility.RandomDouble() < 0.15 )
c.DropItem( new DisintegratingThesisNotes() );
}
*/
public override bool GivesMLMinorArtifact => true;
public override int TreasureMapLevel => 5;
public override void GenerateLoot()
{
AddLoot(LootPack.UltraRich, 3);
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

View file

@ -0,0 +1,93 @@
namespace Server.Mobiles
{
public class MasterMikael : BoneMagi
{
[Constructible]
public MasterMikael()
{
IsParagon = true;
Hue = 0x8FD;
SetStr(93, 122);
SetDex(91, 100);
SetInt(252, 271);
SetHits(789, 1014);
SetDamage(11, 19);
SetDamageType(ResistanceType.Physical, 100);
SetResistance(ResistanceType.Physical, 55, 59);
SetResistance(ResistanceType.Fire, 40, 46);
SetResistance(ResistanceType.Cold, 72, 80);
SetResistance(ResistanceType.Poison, 44, 49);
SetResistance(ResistanceType.Energy, 50, 57);
SetSkill(SkillName.Wrestling, 80.1, 87.2);
SetSkill(SkillName.Tactics, 79.0, 90.9);
SetSkill(SkillName.MagicResist, 90.3, 106.9);
SetSkill(SkillName.Magery, 103.8, 108.0);
SetSkill(SkillName.EvalInt, 96.1, 105.3);
SetSkill(SkillName.Necromancy, 103.8, 108.0);
SetSkill(SkillName.SpiritSpeak, 96.1, 105.3);
Fame = 18000;
Karma = -18000;
if (Utility.RandomBool())
PackNecroScroll(Utility.RandomMinMax(5, 9));
else
PackScroll(4, 7);
PackReg(3);
PackNecroReg(1, 10);
}
public MasterMikael(Serial serial)
: base(serial)
{
}
public override string CorpseName => "a Master Mikael corpse";
public override string DefaultName => "Master Mikael";
// TODO: Special move?
/*
// TODO: uncomment once added
public override void OnDeath( Container c )
{
base.OnDeath( c );
if ( Utility.RandomDouble() < 0.15 )
c.DropItem( new DisintegratingThesisNotes() );
if ( Utility.RandomDouble() < 0.1 )
c.DropItem( new ParrotItem() );
}
*/
public override bool GivesMLMinorArtifact => true;
public override void GenerateLoot()
{
AddLoot(LootPack.UltraRich, 2);
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

View file

@ -0,0 +1,92 @@
using Server.Items;
namespace Server.Mobiles
{
public class MasterTheophilus : EvilMageLord
{
[Constructible]
public MasterTheophilus()
{
IsParagon = true;
Title = "the necromancer";
Hue = 0;
SetStr(137, 187);
SetDex(253, 301);
SetInt(393, 444);
SetHits(663, 876);
SetDamage(15, 20);
SetDamageType(ResistanceType.Physical, 100);
SetResistance(ResistanceType.Physical, 55, 60);
SetResistance(ResistanceType.Fire, 50, 58);
SetResistance(ResistanceType.Cold, 50, 60);
SetResistance(ResistanceType.Poison, 50, 60);
SetResistance(ResistanceType.Energy, 50, 60);
SetSkill(SkillName.Wrestling, 69.9, 105.3);
SetSkill(SkillName.Tactics, 113.0, 117.9);
SetSkill(SkillName.MagicResist, 127.0, 132.8);
SetSkill(SkillName.Magery, 138.1, 143.7);
SetSkill(SkillName.EvalInt, 125.6, 133.8);
SetSkill(SkillName.Necromancy, 125.6, 133.8);
SetSkill(SkillName.SpiritSpeak, 125.6, 133.8);
SetSkill(SkillName.Meditation, 128.8, 132.9);
Fame = 18000;
Karma = -18000;
AddItem(new Shoes(0x537));
AddItem(new Robe(0x452));
for (int i = 0; i < 2; ++i)
if (Utility.RandomBool())
PackNecroScroll(Utility.RandomMinMax(5, 9));
else
PackScroll(4, 7);
PackReg(7);
PackReg(7);
PackReg(8);
}
public MasterTheophilus(Serial serial)
: base(serial)
{
}
public override string CorpseName => "a Master Theophilus corpse";
public override string DefaultName => "Master Theophilus";
public override bool GivesMLMinorArtifact => true;
public override int TreasureMapLevel => 5;
public override void GenerateLoot()
{
AddLoot(LootPack.UltraRich, 3);
}
public override WeaponAbility GetWeaponAbility()
{
return WeaponAbility.ParalyzingBlow;
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

View file

@ -0,0 +1,95 @@
using Server.Items;
namespace Server.Mobiles
{
public class RedDeath : SkeletalMount
{
[Constructible]
public RedDeath()
: base("Red Death")
{
IsParagon = true;
Hue = 0x21;
BaseSoundID = 0x1C3;
AI = AIType.AI_Melee;
FightMode = FightMode.Closest;
SetStr(319, 324);
SetDex(241, 244);
SetInt(242, 255);
SetHits(1540, 1605);
SetDamage(25, 29);
SetDamageType(ResistanceType.Physical, 25);
SetDamageType(ResistanceType.Fire, 75);
SetDamageType(ResistanceType.Cold, 0);
SetResistance(ResistanceType.Physical, 60, 70);
SetResistance(ResistanceType.Fire, 90);
SetResistance(ResistanceType.Cold, 0);
SetResistance(ResistanceType.Poison, 100);
SetResistance(ResistanceType.Energy, 0);
SetSkill(SkillName.Wrestling, 121.4, 143.7);
SetSkill(SkillName.Tactics, 120.9, 142.2);
SetSkill(SkillName.MagicResist, 120.1, 142.3);
SetSkill(SkillName.Anatomy, 120.2, 144.0);
Fame = 28000;
Karma = -28000;
if (Utility.RandomBool())
PackNecroScroll(Utility.RandomMinMax(5, 9));
else
PackScroll(4, 7);
}
public RedDeath(Serial serial)
: base(serial)
{
}
public override string CorpseName => "a Red Death corpse";
public override bool GivesMLMinorArtifact => true;
public override bool AlwaysMurderer => true;
public override bool HasBreath => true;
public override int BreathChaosDamage => 100;
public override int BreathFireDamage => 0;
public override void GenerateLoot()
{
AddLoot(LootPack.UltraRich, 3);
}
public override WeaponAbility GetWeaponAbility()
{
return WeaponAbility.WhirlwindAttack;
}
public override void OnDeath(Container c)
{
base.OnDeath(c);
c.DropItem(new ResolvesBridle());
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

View file

@ -0,0 +1,133 @@
using System.Collections.Generic;
namespace Server.Mobiles
{
public class SirPatrick : SkeletalKnight
{
[Constructible]
public SirPatrick()
{
IsParagon = true;
Hue = 0x47E;
SetStr(208, 319);
SetDex(98, 132);
SetInt(45, 91);
SetHits(616, 884);
SetDamage(15, 25);
SetDamageType(ResistanceType.Physical, 40);
SetDamageType(ResistanceType.Cold, 60);
SetResistance(ResistanceType.Physical, 55, 62);
SetResistance(ResistanceType.Fire, 40, 48);
SetResistance(ResistanceType.Cold, 71, 80);
SetResistance(ResistanceType.Poison, 40, 50);
SetResistance(ResistanceType.Energy, 50, 60);
SetSkill(SkillName.Wrestling, 126.3, 136.5);
SetSkill(SkillName.Tactics, 128.5, 143.8);
SetSkill(SkillName.MagicResist, 102.8, 117.9);
SetSkill(SkillName.Anatomy, 127.5, 137.2);
Fame = 18000;
Karma = -18000;
}
public SirPatrick(Serial serial)
: base(serial)
{
}
public override string CorpseName => "a Sir Patrick corpse";
public override string DefaultName => "Sir Patrick";
/*
// TODO: uncomment once added
public override void OnDeath( Container c )
{
base.OnDeath( c );
if ( Utility.RandomDouble() < 0.15 )
c.DropItem( new DisintegratingThesisNotes() );
if ( Utility.RandomDouble() < 0.05 )
c.DropItem( new AssassinChest() );
}
*/
public override bool GivesMLMinorArtifact => true;
public override void GenerateLoot()
{
AddLoot(LootPack.UltraRich, 2);
}
public override void OnGaveMeleeAttack(Mobile defender)
{
base.OnGaveMeleeAttack(defender);
if (Utility.RandomDouble() < 0.1)
DrainLife();
}
public override void OnGotMeleeAttack(Mobile attacker)
{
base.OnGotMeleeAttack(attacker);
if (Utility.RandomDouble() < 0.1)
DrainLife();
}
public virtual void DrainLife()
{
List<Mobile> list = new List<Mobile>();
foreach (Mobile m in GetMobilesInRange(2))
{
if (m == this || !CanBeHarmful(m, false) || Core.AOS && !InLOS(m))
continue;
if (m is BaseCreature bc)
{
if (bc.Controlled || bc.Summoned || bc.Team != Team)
list.Add(bc);
}
else if (m.Player)
{
list.Add(m);
}
}
foreach (Mobile m in list)
{
DoHarmful(m);
m.FixedParticles(0x374A, 10, 15, 5013, 0x455, 0, EffectLayer.Waist);
m.PlaySound(0x1EA);
int drain = Utility.RandomMinMax(14, 30);
Hits += drain;
m.Damage(drain, this);
}
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

View file

@ -0,0 +1,78 @@
using Server.Items;
namespace Server.Mobiles
{
public class Abscess : Hydra
{
[Constructible]
public Abscess()
{
IsParagon = true;
Hue = 0x8FD;
SetStr(845, 871);
SetDex(121, 134);
SetInt(124, 142);
SetHits(7470, 7540);
SetDamage(26, 31);
SetDamageType(ResistanceType.Physical, 60);
SetDamageType(ResistanceType.Fire, 10);
SetDamageType(ResistanceType.Cold, 10);
SetDamageType(ResistanceType.Poison, 10);
SetDamageType(ResistanceType.Energy, 10);
SetResistance(ResistanceType.Physical, 65, 75);
SetResistance(ResistanceType.Fire, 70, 80);
SetResistance(ResistanceType.Cold, 25, 35);
SetResistance(ResistanceType.Poison, 35, 45);
SetResistance(ResistanceType.Energy, 35, 45);
SetSkill(SkillName.Wrestling, 132.3, 143.8);
SetSkill(SkillName.Tactics, 121.0, 130.5);
SetSkill(SkillName.MagicResist, 102.9, 119.0);
SetSkill(SkillName.Anatomy, 91.8, 94.3);
// TODO: Fame/Karma
}
public Abscess(Serial serial)
: base(serial)
{
}
public override string CorpseName => "an Abscess corpse";
public override string DefaultName => "Abscess";
public override bool GivesMLMinorArtifact => true;
public override void GenerateLoot()
{
AddLoot(LootPack.UltraRich, 4);
}
public override void OnDeath(Container c)
{
base.OnDeath(c);
c.DropItem(new AbscessTail());
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

View file

@ -0,0 +1,105 @@
using Server.Items;
namespace Server.Mobiles
{
public class Coil : SilverSerpent
{
[Constructible]
public Coil()
{
IsParagon = true;
Hue = 0x3F;
SetStr(205, 343);
SetDex(202, 283);
SetInt(88, 142);
SetHits(628, 1291);
SetDamage(19, 28);
SetDamageType(ResistanceType.Physical, 50);
SetDamageType(ResistanceType.Poison, 50);
SetResistance(ResistanceType.Physical, 56, 62);
SetResistance(ResistanceType.Fire, 25, 30);
SetResistance(ResistanceType.Cold, 25, 30);
SetResistance(ResistanceType.Poison, 100);
SetResistance(ResistanceType.Energy, 25, 30);
SetSkill(SkillName.Wrestling, 124.5, 141.3);
SetSkill(SkillName.Tactics, 130.2, 142.0);
SetSkill(SkillName.MagicResist, 102.3, 113.0);
SetSkill(SkillName.Anatomy, 120.8, 138.1);
SetSkill(SkillName.Poisoning, 110.1, 133.4);
// TODO: Fame/Karma
PackGem(2);
PackItem(new Bone());
}
public Coil(Serial serial)
: base(serial)
{
}
public override string CorpseName => "a Coil corpse";
// TODO: Check faction allegiance
public override string DefaultName => "Coil";
public override Poison HitPoison => Poison.Lethal;
public override Poison PoisonImmune => Poison.Lethal;
public override bool GivesMLMinorArtifact => true;
public override int Hides => 48;
public override int Meat => 1;
public override void GenerateLoot()
{
AddLoot(LootPack.UltraRich, 3);
}
public override WeaponAbility GetWeaponAbility()
{
return WeaponAbility.MortalStrike;
}
public override void OnDeath(Container c)
{
base.OnDeath(c);
c.DropItem(new CoilsFang());
/*
// TODO: uncomment once added
if ( Utility.RandomDouble() < 0.025 )
{
switch ( Utility.Random( 5 ) )
{
case 0: c.DropItem( new AssassinChest() ); break;
case 1: c.DropItem( new DeathGloves() ); break;
case 2: c.DropItem( new LeafweaveLegs() ); break;
case 3: c.DropItem( new HunterLegs() ); break;
case 4: c.DropItem( new MyrmidonLegs() ); break;
}
}
*/
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

View file

@ -0,0 +1,43 @@
namespace Server.Mobiles
{
public class EnslavedSatyr : Satyr
{
[Constructible]
public EnslavedSatyr()
{
}
/*
// TODO: uncomment once added
public override void OnDeath( Container c )
{
base.OnDeath( c );
if ( Utility.RandomDouble() < 0.1 )
c.DropItem( new ParrotItem() );
}
*/
public EnslavedSatyr(Serial serial)
: base(serial)
{
}
public override string CorpseName => "an enslaved satyr corpse";
public override string DefaultName => "an enslaved satyr";
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

View file

@ -0,0 +1,90 @@
using Server.Items;
namespace Server.Mobiles
{
public class Hydra : BaseCreature
{
[Constructible]
public Hydra()
: base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4)
{
Body = 0x109;
BaseSoundID = 0x16A;
SetStr(801, 828);
SetDex(102, 118);
SetInt(102, 120);
SetHits(1480, 1500);
SetDamage(21, 26);
SetDamageType(ResistanceType.Physical, 60);
SetDamageType(ResistanceType.Fire, 10);
SetDamageType(ResistanceType.Cold, 10);
SetDamageType(ResistanceType.Poison, 10);
SetDamageType(ResistanceType.Energy, 10);
SetResistance(ResistanceType.Physical, 65, 75);
SetResistance(ResistanceType.Fire, 70, 85);
SetResistance(ResistanceType.Cold, 25, 35);
SetResistance(ResistanceType.Poison, 35, 43);
SetResistance(ResistanceType.Energy, 36, 45);
SetSkill(SkillName.Wrestling, 103.5, 117.4);
SetSkill(SkillName.Tactics, 100.1, 109.8);
SetSkill(SkillName.MagicResist, 85.5, 98.5);
SetSkill(SkillName.Anatomy, 75.4, 79.8);
// TODO: Fame/Karma
}
public Hydra(Serial serial)
: base(serial)
{
}
public override string CorpseName => "a hydra corpse";
public override string DefaultName => "a hydra";
public override bool HasBreath => true;
public override int Hides => 40;
public override int Meat => 19;
public override int TreasureMapLevel => 5;
public override void GenerateLoot()
{
AddLoot(LootPack.UltraRich, 3);
}
public override void OnDeath(Container c)
{
base.OnDeath(c);
c.DropItem(new HydraScale());
/*
// TODO: uncomment once added
if ( Utility.RandomDouble() < 0.2 )
c.DropItem( new ParrotItem() );
if ( Utility.RandomDouble() < 0.05 )
c.DropItem( new ThorvaldsMedallion() );
*/
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

View file

@ -0,0 +1,46 @@
namespace Server.Mobiles
{
public class InsaneDryad : MLDryad
{
[Constructible]
public InsaneDryad()
{
// TODO: Perhaps these should have negative karma?
}
/*
// TODO: uncomment once added
public override void OnDeath( Container c )
{
base.OnDeath( c );
if ( Utility.RandomDouble() < 0.1 )
c.DropItem( new ParrotItem() );
}
*/
public InsaneDryad(Serial serial)
: base(serial)
{
}
public override string CorpseName => "an insane dryad corpse";
public override bool InitialInnocent => false;
public override string DefaultName => "an insane dryad";
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

View file

@ -0,0 +1,76 @@
using Server.Items;
namespace Server.Mobiles
{
public class Saliva : Harpy
{
[Constructible]
public Saliva()
{
// TODO: Not a paragon? No ML arties?
// It moves like a paragon on OSI...
Hue = 0x11E;
SetStr(110, 206);
SetDex(123, 222);
SetInt(80, 127);
SetHits(409, 842);
SetDamage(20, 22);
SetDamageType(ResistanceType.Physical, 100);
SetResistance(ResistanceType.Physical, 46, 48);
SetResistance(ResistanceType.Fire, 32, 40);
SetResistance(ResistanceType.Cold, 34, 49);
SetResistance(ResistanceType.Poison, 40, 48);
SetResistance(ResistanceType.Energy, 35, 39);
SetSkill(SkillName.Wrestling, 106.4, 128.8);
SetSkill(SkillName.Tactics, 129.9, 141.0);
SetSkill(SkillName.MagicResist, 84.3, 105.0);
// TODO: Fame/Karma?
}
public Saliva(Serial serial)
: base(serial)
{
}
public override string CorpseName => "a Saliva corpse";
public override string DefaultName => "Saliva";
public override void GenerateLoot()
{
AddLoot(LootPack.UltraRich, 2);
}
public override void OnDeath(Container c)
{
base.OnDeath(c);
c.DropItem(new SalivasFeather());
// TODO: uncomment once added
//if ( Utility.RandomDouble() < 0.1 )
// c.DropItem( new ParrotItem() );
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

View file

@ -0,0 +1,77 @@
using Server.Items;
namespace Server.Mobiles
{
public class Tangle : BogThing
{
[Constructible]
public Tangle()
{
// TODO: Not a paragon? No ML arties?
// It moves like a paragon on OSI...
Hue = 0x21;
SetStr(870, 940);
SetDex(58, 74);
SetInt(46, 58);
SetHits(2468, 2733);
SetMana(8, 12);
SetDamage(15, 28);
SetDamageType(ResistanceType.Physical, 60);
SetDamageType(ResistanceType.Poison, 40);
SetResistance(ResistanceType.Physical, 50, 57);
SetResistance(ResistanceType.Fire, 40, 43);
SetResistance(ResistanceType.Cold, 30, 35);
SetResistance(ResistanceType.Poison, 61, 69);
SetResistance(ResistanceType.Energy, 41, 45);
SetSkill(SkillName.Wrestling, 77.8, 94.6);
SetSkill(SkillName.Tactics, 90.6, 100.4);
SetSkill(SkillName.MagicResist, 108.4, 114.0);
// TODO: Fame/Karma?
}
public Tangle(Serial serial)
: base(serial)
{
}
public override string CorpseName => "a Tangle corpse";
public override string DefaultName => "Tangle";
public override Poison PoisonImmune => Poison.Lethal;
public override void GenerateLoot()
{
AddLoot(LootPack.UltraRich, 3);
}
public override void OnDeath(Container c)
{
base.OnDeath(c);
if (Utility.RandomDouble() < 0.3)
c.DropItem(new TaintedSeeds());
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

View file

@ -0,0 +1,80 @@
using Server.Items;
namespace Server.Mobiles
{
public class Thrasher : Alligator
{
[Constructible]
public Thrasher()
{
IsParagon = true;
Hue = 0x497;
SetStr(93, 327);
SetDex(7, 201);
SetInt(15, 67);
SetHits(260, 984);
SetStam(56, 75);
SetMana(25, 30);
SetDamage(20, 30);
SetDamageType(ResistanceType.Physical, 100);
SetResistance(ResistanceType.Physical, 50, 55);
SetResistance(ResistanceType.Fire, 25, 29);
SetResistance(ResistanceType.Poison, 25, 28);
SetSkill(SkillName.Wrestling, 101.2, 118.3);
SetSkill(SkillName.Tactics, 96.3, 117.3);
SetSkill(SkillName.MagicResist, 102.4, 118.6);
// TODO: Fame/Karma
}
public Thrasher(Serial serial)
: base(serial)
{
}
public override string CorpseName => "a Thrasher corpse";
public override string DefaultName => "Thrasher";
public override bool GivesMLMinorArtifact => true;
public override int Hides => 48;
public override int Meat => 1;
public override void GenerateLoot()
{
AddLoot(LootPack.FilthyRich, 4);
}
public override WeaponAbility GetWeaponAbility()
{
return WeaponAbility.ArmorIgnore;
}
public override void OnDeath(Container c)
{
base.OnDeath(c);
c.DropItem(new ThrashersTail());
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

View file

@ -0,0 +1,107 @@
namespace Server.Mobiles
{
public class FetidEssence : BaseCreature
{
[Constructible]
public FetidEssence() : base(AIType.AI_Mage, FightMode.Closest, 10, 1, 0.2, 0.4)
{
Body = 273;
SetStr(101, 150);
SetDex(210, 250);
SetInt(451, 550);
SetHits(551, 650);
SetDamage(21, 25);
SetDamageType(ResistanceType.Physical, 30);
SetDamageType(ResistanceType.Poison, 70);
SetResistance(ResistanceType.Physical, 40, 50);
SetResistance(ResistanceType.Fire, 40, 50);
SetResistance(ResistanceType.Cold, 40, 50);
SetResistance(ResistanceType.Poison, 70, 90);
SetResistance(ResistanceType.Energy, 75, 80);
SetSkill(SkillName.Meditation, 91.4, 99.4);
SetSkill(SkillName.EvalInt, 88.5, 92.3);
SetSkill(SkillName.Magery, 97.9, 101.7);
SetSkill(SkillName.Poisoning, 100);
SetSkill(SkillName.Anatomy, 0, 4.5);
SetSkill(SkillName.MagicResist, 103.5, 108.8);
SetSkill(SkillName.Tactics, 81.0, 84.6);
SetSkill(SkillName.Wrestling, 81.3, 83.9);
Fame = 3700; // Guessed
Karma = -3700; // Guessed
}
public FetidEssence(Serial serial) : base(serial)
{
}
public override string CorpseName => "a fetid essence corpse";
public override string DefaultName => "a fetid essence";
public override Poison HitPoison => Poison.Deadly;
public override Poison PoisonImmune => Poison.Deadly;
public override void GenerateLoot() // Need to verify
{
AddLoot(LootPack.FilthyRich);
}
public override int GetAngerSound()
{
return 0x56d;
}
public override int GetIdleSound()
{
return 0x56b;
}
public override int GetAttackSound()
{
return 0x56c;
}
public override int GetHurtSound()
{
return 0x56c;
}
public override int GetDeathSound()
{
return 0x56e;
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write(0);
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
/*private class InternalTimer : Timer
{
private Mobile m_From;
private Mobile m_Mobile;
private int m_Count;
public InternalTimer( Mobile from, Mobile m ) : base( TimeSpan.FromSeconds( 1.0 ), TimeSpan.FromSeconds( 1.0 ) )
{
m_From = from;
m_Mobile = m;
Priority = TimerPriority.TwoFiftyMS;
}
}*/
}
}

View file

@ -0,0 +1,168 @@
using System.Linq;
namespace Server.Mobiles
{
public class InterredGrizzle : BaseCreature
{
[Constructible]
public InterredGrizzle() : base(AIType.AI_Mage, FightMode.Closest, 10, 1, 0.2, 0.4)
{
Body = 259;
SetStr(451, 500);
SetDex(201, 250);
SetInt(801, 850);
SetHits(1500);
SetStam(150);
SetDamage(16, 19);
SetDamageType(ResistanceType.Physical, 30);
SetDamageType(ResistanceType.Fire, 70);
SetResistance(ResistanceType.Physical, 35, 55);
SetResistance(ResistanceType.Fire, 20, 65);
SetResistance(ResistanceType.Cold, 55, 80);
SetResistance(ResistanceType.Poison, 20, 35);
SetResistance(ResistanceType.Energy, 60, 80);
SetSkill(SkillName.Meditation, 77.7, 84.0);
SetSkill(SkillName.EvalInt, 72.2, 79.6);
SetSkill(SkillName.Magery, 83.7, 89.6);
SetSkill(SkillName.Poisoning, 0);
SetSkill(SkillName.Anatomy, 0);
SetSkill(SkillName.MagicResist, 80.2, 87.3);
SetSkill(SkillName.Tactics, 104.5, 105.1);
SetSkill(SkillName.Wrestling, 105.1, 109.4);
Fame = 3700; // Guessed
Karma = -3700; // Guessed
}
/*
public override bool OnBeforeDeath()
{
SpillAcid( 1, 4, 10, 6, 10 );
return base.OnBeforeDeath();
}
*/
public InterredGrizzle(Serial serial) : base(serial)
{
}
public override string CorpseName => "an interred grizzle corpse";
public override string DefaultName => "a interred grizzle";
public override void GenerateLoot() // -- Need to verify
{
AddLoot(LootPack.FilthyRich);
}
// TODO: Acid Blood
/*
* Message: 1070820
* Spits pool of acid (blood, hue 0x3F), hits lost 6-10 per second/step
* Damage is resistable (physical)
* Acid last 10 seconds
*/
public override int GetAngerSound()
{
return 0x581;
}
public override int GetIdleSound()
{
return 0x582;
}
public override int GetAttackSound()
{
return 0x580;
}
public override int GetHurtSound()
{
return 0x583;
}
public override int GetDeathSound()
{
return 0x584;
}
public override void OnDamage(int amount, Mobile from, bool willKill)
{
if (Utility.RandomDouble() < 0.1)
DropOoze();
base.OnDamage(amount, from, willKill);
}
private int RandomPoint(int mid)
{
return mid + Utility.RandomMinMax(-2, 2);
}
public virtual Point3D GetSpawnPosition(int range)
{
return GetSpawnPosition(Location, Map, range);
}
public virtual Point3D GetSpawnPosition(Point3D from, Map map, int range)
{
if (map == null)
return from;
Point3D loc = new Point3D(RandomPoint(X), RandomPoint(Y), Z);
loc.Z = Map.GetAverageZ(loc.X, loc.Y);
return loc;
}
public virtual void DropOoze()
{
int amount = Utility.RandomMinMax(1, 3);
bool corrosive = Utility.RandomBool();
for (int i = 0; i < amount; i++)
{
Item ooze = new StainedOoze(corrosive);
Point3D p = new Point3D(Location);
for (int j = 0; j < 5; j++)
{
p = GetSpawnPosition(2);
if (!Map.GetItemsInRange(p, 0).OfType<StainedOoze>().Any())
break;
}
ooze.MoveToWorld(p, Map);
}
if (Combatant != null)
{
if (corrosive)
Combatant.SendLocalizedMessage(1072071); // A corrosive gas seeps out of your enemy's skin!
else
Combatant.SendLocalizedMessage(1072072); // A poisonous gas seeps out of your enemy's skin!
}
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write(0);
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

View file

@ -0,0 +1,161 @@
using System;
using Server.Engines.Plants;
namespace Server.Mobiles
{
public class MLDryad : BaseCreature
{
[Constructible]
public MLDryad() : base(AIType.AI_Mage, FightMode.Evil, 10, 1, 0.2, 0.4)
{
Body = 266;
BaseSoundID = 0x57B;
SetStr(132, 149);
SetDex(152, 168);
SetInt(251, 280);
SetHits(304, 321);
SetDamage(11, 20);
SetDamageType(ResistanceType.Physical, 100);
SetResistance(ResistanceType.Physical, 40, 50);
SetResistance(ResistanceType.Fire, 15, 25);
SetResistance(ResistanceType.Cold, 40, 45);
SetResistance(ResistanceType.Poison, 30, 40);
SetResistance(ResistanceType.Energy, 25, 35);
SetSkill(SkillName.Meditation, 80.0, 90.0);
SetSkill(SkillName.EvalInt, 70.0, 80.0);
SetSkill(SkillName.Magery, 70.0, 80.0);
SetSkill(SkillName.Anatomy, 0);
SetSkill(SkillName.MagicResist, 100.0, 120.0);
SetSkill(SkillName.Tactics, 70.0, 80.0);
SetSkill(SkillName.Wrestling, 70.0, 80.0);
Fame = 5000;
Karma = 5000;
VirtualArmor = 28; // Don't know what it should be
if (Core.ML && Utility.RandomDouble() < .60)
PackItem(Seed.RandomPeculiarSeed(1));
PackArcanceScroll(0.05);
}
public MLDryad(Serial serial) : base(serial)
{
}
public override string CorpseName => "a dryad's corpse";
public override bool InitialInnocent => true;
public override OppositionGroup OppositionGroup => OppositionGroup.FeyAndUndead;
public override string DefaultName => "a dryad";
public override int Meat => 1;
public override void GenerateLoot()
{
AddLoot(LootPack.MlRich);
}
public override void OnThink()
{
base.OnThink();
AreaPeace();
AreaUndress();
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
#region Area Peace
private DateTime m_NextPeace;
public void AreaPeace()
{
if (Combatant == null || Deleted || !Alive || m_NextPeace > DateTime.UtcNow || 0.1 < Utility.RandomDouble())
return;
TimeSpan duration = TimeSpan.FromSeconds(Utility.RandomMinMax(20, 80));
foreach (Mobile m in GetMobilesInRange(RangePerception))
{
PlayerMobile p = m as PlayerMobile;
if (IsValidTarget(p))
{
p.PeacedUntil = DateTime.UtcNow + duration;
p.SendLocalizedMessage(1072065); // You gaze upon the dryad's beauty, and forget to continue battling!
p.FixedParticles(0x376A, 1, 20, 0x7F5, EffectLayer.Waist);
p.Combatant = null;
}
}
m_NextPeace = DateTime.UtcNow + TimeSpan.FromSeconds(10);
PlaySound(0x1D3);
}
public bool IsValidTarget(PlayerMobile m)
{
return m?.PeacedUntil < DateTime.UtcNow && !m.Hidden && m.AccessLevel == AccessLevel.Player &&
CanBeHarmful(m);
}
#endregion
#region Undress
private DateTime m_NextUndress;
public void AreaUndress()
{
if (Combatant == null || Deleted || !Alive || m_NextUndress > DateTime.UtcNow || 0.005 < Utility.RandomDouble())
return;
foreach (Mobile m in GetMobilesInRange(RangePerception))
if (m?.Player == true && !m.Female && !m.Hidden && m.AccessLevel == AccessLevel.Player &&
CanBeHarmful(m))
{
UndressItem(m, Layer.OuterTorso);
UndressItem(m, Layer.InnerTorso);
UndressItem(m, Layer.MiddleTorso);
UndressItem(m, Layer.Pants);
UndressItem(m, Layer.Shirt);
m.SendLocalizedMessage(
1072197); // The dryad's beauty makes your blood race. Your clothing is too confining.
}
m_NextUndress = DateTime.UtcNow + TimeSpan.FromMinutes(1);
}
public void UndressItem(Mobile m, Layer layer)
{
Item item = m.FindItemOnLayer(layer);
if (item?.Movable == true)
m.PlaceInBackpack(item);
}
#endregion
}
}

View file

@ -0,0 +1,241 @@
using System;
using System.Collections.Generic;
namespace Server.Mobiles
{
public class Satyr : BaseCreature
{
[Constructible]
public Satyr() : base(AIType.AI_Animal, FightMode.Aggressor, 10, 1, 0.2, 0.4)
{
Body = 271;
BaseSoundID = 0x586;
SetStr(177, 195);
SetDex(251, 269);
SetInt(153, 170);
SetHits(350, 400);
SetDamage(13, 24);
SetDamageType(ResistanceType.Physical, 100);
SetResistance(ResistanceType.Physical, 55, 60);
SetResistance(ResistanceType.Fire, 25, 35);
SetResistance(ResistanceType.Cold, 30, 40);
SetResistance(ResistanceType.Poison, 30, 40);
SetResistance(ResistanceType.Energy, 30, 40);
SetSkill(SkillName.MagicResist, 55.0, 65.0);
SetSkill(SkillName.Tactics, 80.0, 100.0);
SetSkill(SkillName.Wrestling, 80.0, 100.0);
Fame = 5000;
Karma = 0;
VirtualArmor = 28; // Don't know what it should be
PackArcanceScroll(0.05);
}
public Satyr(Serial serial) : base(serial)
{
}
public override string CorpseName => "a satyr's corpse";
public override string DefaultName => "a satyr";
public override OppositionGroup OppositionGroup => OppositionGroup.FeyAndUndead;
public override int Meat => 1;
public override void GenerateLoot()
{
AddLoot(LootPack.MlRich);
}
public override void OnThink()
{
base.OnThink();
Peace(Combatant);
Undress(Combatant);
Suppress(Combatant);
Provoke(Combatant);
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
#region Peace
private DateTime m_NextPeace;
public void Peace(Mobile target)
{
if (target == null || Deleted || !Alive || m_NextPeace > DateTime.UtcNow || 0.1 < Utility.RandomDouble())
return;
if (target is PlayerMobile p && p.PeacedUntil < DateTime.UtcNow && !p.Hidden && CanBeHarmful(p))
{
p.PeacedUntil = DateTime.UtcNow + TimeSpan.FromMinutes(1);
p.SendLocalizedMessage(500616); // You hear lovely music, and forget to continue battling!
p.FixedParticles(0x376A, 1, 32, 0x15BD, EffectLayer.Waist);
p.Combatant = null;
PlaySound(0x58D);
}
m_NextPeace = DateTime.UtcNow + TimeSpan.FromSeconds(10);
}
#endregion
#region Suppress
private static Dictionary<Mobile, Timer> m_Suppressed = new Dictionary<Mobile, Timer>();
private DateTime m_NextSuppress;
public void Suppress(Mobile target)
{
if (target == null || m_Suppressed.ContainsKey(target) || Deleted || !Alive ||
m_NextSuppress > DateTime.UtcNow || 0.1 < Utility.RandomDouble())
return;
TimeSpan delay = TimeSpan.FromSeconds(Utility.RandomMinMax(20, 80));
if (!target.Hidden && CanBeHarmful(target))
{
target.SendLocalizedMessage(1072061); // You hear jarring music, suppressing your strength.
for (int i = 0; i < target.Skills.Length; i++)
{
Skill s = target.Skills[i];
target.AddSkillMod(new TimedSkillMod(s.SkillName, true, s.Base * -0.28, delay));
}
int count = (int)Math.Round(delay.TotalSeconds / 1.25);
Timer timer = new AnimateTimer(target, count);
m_Suppressed.Add(target, timer);
timer.Start();
PlaySound(0x58C);
}
m_NextSuppress = DateTime.UtcNow + TimeSpan.FromSeconds(10);
}
public static void SuppressRemove(Mobile target)
{
if (target == null)
return;
if (m_Suppressed.TryGetValue(target, out Timer t))
{
if (t.Running)
t.Stop();
m_Suppressed.Remove(target);
}
}
private class AnimateTimer : Timer
{
private int m_Count;
private Mobile m_Owner;
public AnimateTimer(Mobile owner, int count) : base(TimeSpan.Zero, TimeSpan.FromSeconds(1.25))
{
m_Owner = owner;
m_Count = count;
}
protected override void OnTick()
{
if (m_Owner.Deleted || !m_Owner.Alive || m_Count-- < 0)
SuppressRemove(m_Owner);
else
m_Owner.FixedParticles(0x376A, 1, 32, 0x15BD, EffectLayer.Waist);
}
}
#endregion
#region Undress
private DateTime m_NextUndress;
public void Undress(Mobile target)
{
if (target == null || Deleted || !Alive || m_NextUndress > DateTime.UtcNow || 0.005 < Utility.RandomDouble())
return;
if (target.Player && target.Female && !target.Hidden && CanBeHarmful(target))
{
UndressItem(target, Layer.OuterTorso);
UndressItem(target, Layer.InnerTorso);
UndressItem(target, Layer.MiddleTorso);
UndressItem(target, Layer.Pants);
UndressItem(target, Layer.Shirt);
target.SendLocalizedMessage(
1072196); // The satyr's music makes your blood race. Your clothing is too confining.
}
m_NextUndress = DateTime.UtcNow + TimeSpan.FromMinutes(1);
}
public void UndressItem(Mobile m, Layer layer)
{
Item item = m.FindItemOnLayer(layer);
if (item?.Movable == true)
m.PlaceInBackpack(item);
}
#endregion
#region Provoke
private DateTime m_NextProvoke;
public void Provoke(Mobile target)
{
if (target == null || Deleted || !Alive || m_NextProvoke > DateTime.UtcNow || 0.05 < Utility.RandomDouble())
return;
foreach (Mobile m in GetMobilesInRange(RangePerception))
if (m is BaseCreature c)
{
if (c == this || c == target || c.Unprovokable || c.IsParagon || c.BardProvoked ||
c.AccessLevel != AccessLevel.Player || !c.CanBeHarmful(target))
continue;
c.Provoke(this, target, true);
if (target.Player)
target.SendLocalizedMessage(1072062); // You hear angry music, and start to fight.
PlaySound(0x58A);
break;
}
m_NextProvoke = DateTime.UtcNow + TimeSpan.FromSeconds(10);
}
#endregion
}
}

View file

@ -0,0 +1,92 @@
namespace Server.Mobiles
{
public class CorruptedSoul : BaseCreature
{
[Constructible]
public CorruptedSoul() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, .1, 5)
{
Body = 0x3CA;
Hue = 0x453;
SetStr(102, 115);
SetDex(101, 115);
SetInt(203, 215);
SetHits(61, 69);
SetDamage(4, 40);
SetDamageType(ResistanceType.Physical, 100);
SetResistance(ResistanceType.Physical, 61, 74);
SetResistance(ResistanceType.Fire, 22, 48);
SetResistance(ResistanceType.Cold, 73, 100);
SetResistance(ResistanceType.Poison, 0);
SetResistance(ResistanceType.Energy, 51, 60);
SetSkill(SkillName.MagicResist, 80.2, 89.4);
SetSkill(SkillName.Tactics, 81.3, 89.9);
SetSkill(SkillName.Wrestling, 80.1, 88.7);
Fame = 5000;
Karma = -5000;
// VirtualArmor = 6; Not sure
}
public CorruptedSoul(Serial serial) : base(serial)
{
}
public override bool DeleteCorpseOnDeath => true;
public override string DefaultName => "a corrupted soul";
public override bool AlwaysAttackable => true;
public override bool BleedImmune => true; // NEED TO VERIFY
/*public override int GetDeathSound()
{
return 0x0;
}*/
public override bool AlwaysMurderer => true;
// NEED TO VERIFY SOUNDS! Known: No Idle Sound.
/*public override int GetAngerSound()
{
return 0x0;
}*/
public override int GetAttackSound()
{
return 0x233;
}
// TODO: Proper OnDeath Effect
public override bool OnBeforeDeath()
{
if (!base.OnBeforeDeath())
return false;
// 1 in 20 chance that a Thread of Fate will appear in the killer's pack
Effects.SendLocationEffect(Location, Map, 0x376A, 10, 1);
return true;
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write(0);
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

View file

@ -0,0 +1,88 @@
using Server.Items;
namespace Server.Mobiles
{
[TypeAlias("Server.Mobiles.FerelTreefellow")]
public class FeralTreefellow : BaseCreature
{
[Constructible]
public FeralTreefellow() : base(AIType.AI_Melee, FightMode.Evil, 10, 1, 0.2, 0.4)
{
Body = 301;
SetStr(1351, 1600);
SetDex(301, 550);
SetInt(651, 900);
SetHits(1170, 1320);
SetDamage(26, 35);
SetDamageType(ResistanceType.Physical, 100);
SetResistance(ResistanceType.Physical, 60, 70);
SetResistance(ResistanceType.Cold, 70, 80);
SetResistance(ResistanceType.Poison, 60, 70);
SetResistance(ResistanceType.Energy, 40, 60);
SetSkill(SkillName.MagicResist, 40.1, 55.0); // Unknown
SetSkill(SkillName.Tactics, 65.1, 90.0); // Unknown
SetSkill(SkillName.Wrestling, 65.1, 85.0); // Unknown
Fame = 12500; //Unknown
Karma = 12500; //Unknown
VirtualArmor = 24;
PackItem(new Log(Utility.RandomMinMax(23, 34)));
}
public FeralTreefellow(Serial serial) : base(serial)
{
}
public override string CorpseName => "a treefellow corpse";
public override string DefaultName => "a feral treefellow";
public override OppositionGroup OppositionGroup => OppositionGroup.FeyAndUndead;
public override bool BleedImmune => true;
public override WeaponAbility GetWeaponAbility()
{
return WeaponAbility.Dismount;
}
public override int GetIdleSound()
{
return 443;
}
public override int GetDeathSound()
{
return 31;
}
public override int GetAttackSound()
{
return 672;
}
public override void GenerateLoot()
{
AddLoot(LootPack.Average); //Unknown
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write(0);
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

View file

@ -0,0 +1,99 @@
using Server.Items;
namespace Server.Mobiles
{
public class Minotaur : BaseCreature
{
[Constructible]
public Minotaur() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) // NEED TO CHECK
{
Body = 263;
SetStr(301, 340);
SetDex(91, 110);
SetInt(31, 50);
SetHits(301, 340);
SetDamage(11, 20);
SetDamageType(ResistanceType.Physical, 100);
SetResistance(ResistanceType.Physical, 55, 65);
SetResistance(ResistanceType.Fire, 25, 35);
SetResistance(ResistanceType.Cold, 30, 40);
SetResistance(ResistanceType.Poison, 30, 40);
SetResistance(ResistanceType.Energy, 30, 40);
SetSkill(SkillName.Meditation, 0);
SetSkill(SkillName.EvalInt, 0);
SetSkill(SkillName.Magery, 0);
SetSkill(SkillName.Poisoning, 0);
SetSkill(SkillName.Anatomy, 0);
SetSkill(SkillName.MagicResist, 56.1, 64.0);
SetSkill(SkillName.Tactics, 93.3, 97.8);
SetSkill(SkillName.Wrestling, 90.4, 92.1);
Fame = 5000;
Karma = -5000;
VirtualArmor = 28; // Don't know what it should be
}
public Minotaur(Serial serial) : base(serial)
{
}
public override string CorpseName => "a minotaur corpse";
public override string DefaultName => "a minotaur";
public override WeaponAbility GetWeaponAbility()
{
return WeaponAbility.ParalyzingBlow;
}
public override void GenerateLoot()
{
AddLoot(LootPack.Rich); // Need to verify
}
// Using Tormented Minotaur sounds - Need to veryfy
public override int GetAngerSound()
{
return 0x597;
}
public override int GetIdleSound()
{
return 0x596;
}
public override int GetAttackSound()
{
return 0x599;
}
public override int GetHurtSound()
{
return 0x59a;
}
public override int GetDeathSound()
{
return 0x59c;
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write(0);
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

View file

@ -0,0 +1,99 @@
using Server.Items;
namespace Server.Mobiles
{
public class MinotaurCaptain : BaseCreature
{
[Constructible]
public MinotaurCaptain() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) // NEED TO CHECK
{
Body = 280;
SetStr(401, 425);
SetDex(91, 110);
SetInt(31, 50);
SetHits(401, 440);
SetDamage(11, 20);
SetDamageType(ResistanceType.Physical, 100);
SetResistance(ResistanceType.Physical, 65, 75);
SetResistance(ResistanceType.Fire, 35, 45);
SetResistance(ResistanceType.Cold, 40, 50);
SetResistance(ResistanceType.Poison, 40, 50);
SetResistance(ResistanceType.Energy, 40, 50);
SetSkill(SkillName.Meditation, 0);
SetSkill(SkillName.EvalInt, 0);
SetSkill(SkillName.Magery, 0);
SetSkill(SkillName.Poisoning, 0);
SetSkill(SkillName.Anatomy, 0, 6.3);
SetSkill(SkillName.MagicResist, 66.1, 73.6);
SetSkill(SkillName.Tactics, 93.0, 109.9);
SetSkill(SkillName.Wrestling, 92.6, 107.2);
Fame = 7000;
Karma = -7000;
VirtualArmor = 28; // Don't know what it should be
}
public MinotaurCaptain(Serial serial) : base(serial)
{
}
public override string CorpseName => "a minotaur corpse";
public override string DefaultName => "a minotaur captain";
public override WeaponAbility GetWeaponAbility()
{
return WeaponAbility.ParalyzingBlow;
}
public override void GenerateLoot()
{
AddLoot(LootPack.Rich); // Need to verify
}
// Using Tormented Minotaur sounds - Need to veryfy
public override int GetAngerSound()
{
return 0x597;
}
public override int GetIdleSound()
{
return 0x596;
}
public override int GetAttackSound()
{
return 0x599;
}
public override int GetHurtSound()
{
return 0x59a;
}
public override int GetDeathSound()
{
return 0x59c;
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write(0);
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

View file

@ -0,0 +1,99 @@
using Server.Items;
namespace Server.Mobiles
{
public class MinotaurScout : BaseCreature
{
[Constructible]
public MinotaurScout() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) // NEED TO CHECK
{
Body = 281;
SetStr(353, 375);
SetDex(111, 130);
SetInt(34, 50);
SetHits(354, 383);
SetDamage(11, 20);
SetDamageType(ResistanceType.Physical, 100);
SetResistance(ResistanceType.Physical, 55, 65);
SetResistance(ResistanceType.Fire, 25, 35);
SetResistance(ResistanceType.Cold, 30, 40);
SetResistance(ResistanceType.Poison, 30, 40);
SetResistance(ResistanceType.Energy, 30, 40);
//SetSkill( SkillName.Meditation, Unknown );
//SetSkill( SkillName.EvalInt, Unknown );
//SetSkill( SkillName.Magery, Unknown );
//SetSkill( SkillName.Poisoning, Unknown );
SetSkill(SkillName.Anatomy, 0);
SetSkill(SkillName.MagicResist, 60.6, 67.5);
SetSkill(SkillName.Tactics, 86.9, 103.6);
SetSkill(SkillName.Wrestling, 85.6, 104.5);
Fame = 5000;
Karma = -5000;
VirtualArmor = 28; // Don't know what it should be
}
public MinotaurScout(Serial serial) : base(serial)
{
}
public override string CorpseName => "a minotaur corpse";
public override string DefaultName => "a minotaur scout";
public override WeaponAbility GetWeaponAbility()
{
return WeaponAbility.ParalyzingBlow;
}
public override void GenerateLoot()
{
AddLoot(LootPack.Rich); // Need to verify
}
// Using Tormented Minotaur sounds - Need to veryfy
public override int GetAngerSound()
{
return 0x597;
}
public override int GetIdleSound()
{
return 0x596;
}
public override int GetAttackSound()
{
return 0x599;
}
public override int GetHurtSound()
{
return 0x59a;
}
public override int GetDeathSound()
{
return 0x59c;
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write(0);
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

View file

@ -0,0 +1,80 @@
using Server.Items;
namespace Server.Mobiles
{
public class PestilentBandage : BaseCreature
{
[Constructible]
public PestilentBandage() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) // NEED TO CHECK
{
Body = 154;
Hue = 0x515;
BaseSoundID = 471;
SetStr(691, 740);
SetDex(141, 180);
SetInt(51, 80);
SetHits(415, 445);
SetDamage(13, 23);
SetDamageType(ResistanceType.Physical, 40);
SetDamageType(ResistanceType.Cold, 20);
SetDamageType(ResistanceType.Poison, 40);
SetResistance(ResistanceType.Physical, 45, 55);
SetResistance(ResistanceType.Fire, 10, 20);
SetResistance(ResistanceType.Cold, 50, 60);
SetResistance(ResistanceType.Poison, 20, 30);
SetResistance(ResistanceType.Energy, 20, 30);
SetSkill(SkillName.Poisoning, 0.0, 10.0);
SetSkill(SkillName.Anatomy, 0);
SetSkill(SkillName.MagicResist, 75.0, 80.0);
SetSkill(SkillName.Tactics, 80.0, 85.0);
SetSkill(SkillName.Wrestling, 70.0, 75.0);
Fame = 20000;
Karma = -20000;
// VirtualArmor = 28; // Don't know what it should be
PackItem(new Bandage(5)); // How many?
}
public PestilentBandage(Serial serial) : base(serial)
{
}
public override string CorpseName => "a pestilent bandage corpse";
// Neither Stratics nor UOGuide have much description
// beyond being a "Grey Mummy". BodyValue, Sound and
// Hue are all guessed until they can be verified.
// Loot and Fame/Karma are also guesses at this point.
//
// They also apparently have a Poison Attack, which I've stolen from Yamandons.
public override string DefaultName => "a pestilent bandage";
public override Poison HitPoison => Poison.Lethal;
public override bool CanHeal => true;
public override void GenerateLoot()
{
AddLoot(LootPack.Rich); // Need to verify
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write(0);
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

View file

@ -0,0 +1,97 @@
using Server.Items;
namespace Server.Mobiles
{
public class TormentedMinotaur : BaseCreature
{
[Constructible]
public TormentedMinotaur() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4)
{
Body = 262;
SetStr(822, 930);
SetDex(401, 415);
SetInt(128, 138);
SetHits(4000, 4200);
SetDamage(16, 30);
SetDamageType(ResistanceType.Physical, 100);
SetResistance(ResistanceType.Physical, 62);
SetResistance(ResistanceType.Fire, 74);
SetResistance(ResistanceType.Cold, 54);
SetResistance(ResistanceType.Poison, 56);
SetResistance(ResistanceType.Energy, 54);
SetSkill(SkillName.Wrestling, 110.1, 111.0);
SetSkill(SkillName.Tactics, 100.7, 102.8);
SetSkill(SkillName.MagicResist, 104.3, 116.3);
Fame = 20000;
Karma = -20000;
}
public TormentedMinotaur(Serial serial) : base(serial)
{
}
public override string CorpseName => "a tormented minotaur corpse";
public override string DefaultName => "Tormented Minotaur";
public override Poison PoisonImmune => Poison.Deadly;
public override int TreasureMapLevel => 3;
public override WeaponAbility GetWeaponAbility()
{
return WeaponAbility.Dismount;
}
public override void GenerateLoot()
{
AddLoot(LootPack.FilthyRich, 10);
}
public override int GetDeathSound()
{
return 0x596;
}
public override int GetAttackSound()
{
return 0x597;
}
public override int GetIdleSound()
{
return 0x598;
}
public override int GetAngerSound()
{
return 0x599;
}
public override int GetHurtSound()
{
return 0x59A;
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

View file

@ -0,0 +1,78 @@
using Server.Items;
namespace Server.Mobiles
{
public class Troglodyte : BaseCreature
{
[Constructible]
public Troglodyte() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4) // NEED TO CHECK
{
Body = 267;
BaseSoundID = 0x59F;
SetStr(148, 217);
SetDex(91, 120);
SetInt(51, 70);
SetHits(302, 340);
SetDamage(11, 14);
SetDamageType(ResistanceType.Physical, 100);
SetResistance(ResistanceType.Physical, 30, 35);
SetResistance(ResistanceType.Fire, 20, 30);
SetResistance(ResistanceType.Cold, 35, 40);
SetResistance(ResistanceType.Poison, 30, 40);
SetResistance(ResistanceType.Energy, 30, 40);
SetSkill(SkillName.Anatomy, 70.5, 94.8);
SetSkill(SkillName.MagicResist, 51.8, 65.0);
SetSkill(SkillName.Tactics, 80.4, 94.7);
SetSkill(SkillName.Wrestling, 70.2, 93.5);
SetSkill(SkillName.Healing, 70.0, 95.0);
Fame = 5000;
Karma = -5000;
VirtualArmor = 28; // Don't know what it should be
PackItem(new Bandage(5)); // How many?
PackItem(new Ribs());
}
public Troglodyte(Serial serial) : base(serial)
{
}
public override string CorpseName => "a troglodyte corpse";
public override string DefaultName => "a troglodyte";
public override bool CanHeal => true;
public override void GenerateLoot()
{
AddLoot(LootPack.Rich); // Need to verify
}
public override void OnDeath(Container c)
{
base.OnDeath(c);
if (Utility.RandomDouble() < 0.1)
c.DropItem(new PrimitiveFetish());
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write(0);
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

View file

@ -0,0 +1,113 @@
using Server.Items;
namespace Server.Mobiles
{
public class Miasma : Scorpion
{
[Constructible]
public Miasma()
{
IsParagon = true;
Hue = 0x8FD;
SetStr(255, 847);
SetDex(145, 428);
SetInt(26, 380);
SetHits(750, 2000);
SetMana(5, 60);
SetDamage(20, 30);
SetDamageType(ResistanceType.Physical, 60);
SetDamageType(ResistanceType.Poison, 40);
SetResistance(ResistanceType.Physical, 50, 54);
SetResistance(ResistanceType.Fire, 40, 45);
SetResistance(ResistanceType.Cold, 50, 55);
SetResistance(ResistanceType.Poison, 70, 80);
SetResistance(ResistanceType.Energy, 40, 45);
SetSkill(SkillName.Wrestling, 84.9, 103.3);
SetSkill(SkillName.Tactics, 98.4, 110.6);
SetSkill(SkillName.Anatomy, 0);
SetSkill(SkillName.MagicResist, 74.4, 77.7);
SetSkill(SkillName.Poisoning, 128.5, 143.6);
Fame = 21000;
Karma = -21000;
}
/*
// TODO: uncomment once added
public override void OnDeath( Container c )
{
base.OnDeath( c );
if ( Utility.RandomDouble() < 0.025 )
{
switch ( Utility.Random( 16 ) )
{
case 0: c.DropItem( new MyrmidonGloves() ); break;
case 1: c.DropItem( new MyrmidonGorget() ); break;
case 2: c.DropItem( new MyrmidonLegs() ); break;
case 3: c.DropItem( new MyrmidonArms() ); break;
case 4: c.DropItem( new PaladinArms() ); break;
case 5: c.DropItem( new PaladinGorget() ); break;
case 6: c.DropItem( new LeafweaveLegs() ); break;
case 7: c.DropItem( new DeathChest() ); break;
case 8: c.DropItem( new DeathGloves() ); break;
case 9: c.DropItem( new DeathLegs() ); break;
case 10: c.DropItem( new GreymistGloves() ); break;
case 11: c.DropItem( new GreymistArms() ); break;
case 12: c.DropItem( new AssassinChest() ); break;
case 13: c.DropItem( new AssassinArms() ); break;
case 14: c.DropItem( new HunterGloves() ); break;
case 15: c.DropItem( new HunterLegs() ); break;
}
}
}
*/
public Miasma(Serial serial)
: base(serial)
{
}
public override string CorpseName => "a Miasma corpse";
public override string DefaultName => "Miasma";
/* yes, this is OSI style */
public override double WeaponAbilityChance => 0.75;
public override double HitPoisonChance => 0.35;
public override Poison HitPoison => Poison.Lethal;
public override bool HasManaOveride => true;
public override bool GivesMLMinorArtifact => true;
public override int TreasureMapLevel => 5;
public override void GenerateLoot()
{
AddLoot(LootPack.UltraRich, 4);
}
public override WeaponAbility GetWeaponAbility()
{
return WeaponAbility.MortalStrike;
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

View file

@ -0,0 +1,82 @@
using Server.Items;
namespace Server.Mobiles
{
public class Pyre : Phoenix
{
[Constructible]
public Pyre()
{
IsParagon = true;
Hue = 0x489;
FightMode = FightMode.Closest;
SetStr(605, 611);
SetDex(391, 519);
SetInt(669, 818);
SetHits(1783, 1939);
SetDamage(30);
SetDamageType(ResistanceType.Physical, 50);
SetDamageType(ResistanceType.Fire, 50);
SetResistance(ResistanceType.Physical, 65);
SetResistance(ResistanceType.Fire, 72, 75);
SetResistance(ResistanceType.Poison, 36, 41);
SetResistance(ResistanceType.Energy, 50, 51);
SetSkill(SkillName.Wrestling, 121.9, 130.6);
SetSkill(SkillName.Tactics, 114.4, 117.4);
SetSkill(SkillName.MagicResist, 147.7, 153.0);
SetSkill(SkillName.Poisoning, 122.8, 124.0);
SetSkill(SkillName.Magery, 121.8, 127.8);
SetSkill(SkillName.EvalInt, 103.6, 117.0);
SetSkill(SkillName.Meditation, 100.0, 110.0);
Fame = 21000;
Karma = -21000;
}
public Pyre(Serial serial)
: base(serial)
{
}
public override string CorpseName => "a Pyre corpse";
public override string DefaultName => "Pyre";
public override bool GivesMLMinorArtifact => true;
public override int TreasureMapLevel => 5;
public override bool HasAura => true;
public override void GenerateLoot()
{
AddLoot(LootPack.UltraRich, 3);
}
public override WeaponAbility GetWeaponAbility()
{
if (Utility.RandomBool())
return WeaponAbility.ParalyzingBlow;
return WeaponAbility.BleedAttack;
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

View file

@ -0,0 +1,77 @@
using Server.Items;
namespace Server.Mobiles
{
public class Rend : Reptalon
{
[Constructible]
public Rend()
{
IsParagon = true;
Hue = 0x455;
SetStr(1261, 1284);
SetDex(363, 384);
SetInt(601, 642);
SetHits(5176, 6100);
SetDamage(26, 33);
SetDamageType(ResistanceType.Physical, 100);
SetDamageType(ResistanceType.Poison, 0);
SetDamageType(ResistanceType.Energy, 0);
SetResistance(ResistanceType.Physical, 75, 85);
SetResistance(ResistanceType.Fire, 81, 94);
SetResistance(ResistanceType.Cold, 46, 55);
SetResistance(ResistanceType.Poison, 35, 44);
SetResistance(ResistanceType.Energy, 45, 52);
SetSkill(SkillName.Wrestling, 136.3, 150.3);
SetSkill(SkillName.Tactics, 133.4, 141.4);
SetSkill(SkillName.MagicResist, 90.9, 110.0);
SetSkill(SkillName.Anatomy, 66.6, 72.0);
Fame = 21000;
Karma = -21000;
}
public Rend(Serial serial)
: base(serial)
{
}
public override string CorpseName => "a Rend corpse";
public override string DefaultName => "Rend";
public override bool GivesMLMinorArtifact => true;
public override void GenerateLoot()
{
AddLoot(LootPack.UltraRich, 3);
}
public override WeaponAbility GetWeaponAbility()
{
if (Utility.RandomBool())
return WeaponAbility.ParalyzingBlow;
return WeaponAbility.BleedAttack;
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

View file

@ -0,0 +1,105 @@
using Server.Items;
using Server.SkillHandlers;
namespace Server.Mobiles
{
public class GreaterDragon : BaseCreature
{
[Constructible]
public GreaterDragon() : base(AIType.AI_Mage, FightMode.Closest, 10, 1, 0.3, 0.5)
{
Body = Utility.RandomList(12, 59);
BaseSoundID = 362;
SetStr(1025, 1425);
SetDex(81, 148);
SetInt(475, 675);
SetHits(1000, 2000);
SetStam(120, 135);
SetDamage(24, 33);
SetDamageType(ResistanceType.Physical, 100);
SetResistance(ResistanceType.Physical, 60, 85);
SetResistance(ResistanceType.Fire, 65, 90);
SetResistance(ResistanceType.Cold, 40, 55);
SetResistance(ResistanceType.Poison, 40, 60);
SetResistance(ResistanceType.Energy, 50, 75);
SetSkill(SkillName.Meditation, 0);
SetSkill(SkillName.EvalInt, 110.0, 140.0);
SetSkill(SkillName.Magery, 110.0, 140.0);
SetSkill(SkillName.Poisoning, 0);
SetSkill(SkillName.Anatomy, 0);
SetSkill(SkillName.MagicResist, 110.0, 140.0);
SetSkill(SkillName.Tactics, 110.0, 140.0);
SetSkill(SkillName.Wrestling, 115.0, 145.0);
Fame = 22000;
Karma = -15000;
VirtualArmor = 60;
Tamable = true;
ControlSlots = 5;
MinTameSkill = 104.7;
}
public GreaterDragon(Serial serial) : base(serial)
{
}
public override string CorpseName => "a dragon corpse";
public override bool StatLossAfterTame => true;
public override string DefaultName => "a greater dragon";
public override bool ReacquireOnMovement => !Controlled;
public override bool HasBreath => true; // fire breath enabled
public override bool AutoDispel => !Controlled;
public override int TreasureMapLevel => 5;
public override int Meat => 19;
public override int Hides => 30;
public override HideType HideType => HideType.Barbed;
public override int Scales => 7;
public override ScaleType ScaleType => Body == 12 ? ScaleType.Yellow : ScaleType.Red;
public override FoodType FavoriteFood => FoodType.Meat;
public override bool CanAngerOnTame => true;
public override bool CanFly => true;
public override void GenerateLoot()
{
AddLoot(LootPack.FilthyRich, 4);
AddLoot(LootPack.Gems, 8);
}
public override WeaponAbility GetWeaponAbility()
{
return WeaponAbility.BleedAttack;
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write(1);
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
SetDamage(24, 33);
if (version == 0)
{
AnimalTaming.ScaleStats(this, 0.50);
AnimalTaming.ScaleSkills(this, 0.80, 0.90); // 90% * 80% = 72% of original skills trainable to 90%
Skills.Magery.Base =
Skills.Magery
.Cap; // Greater dragons have a 90% cap reduction and 90% skill reduction on magery
}
}
}
}

View file

@ -0,0 +1,73 @@
namespace Server.Mobiles
{
public class CorrosiveSlime : BaseCreature
{
[Constructible]
public CorrosiveSlime() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4)
{
Body = 51;
BaseSoundID = 456;
Hue = Utility.RandomSlimeHue();
SetStr(22, 34);
SetDex(16, 21);
SetInt(16, 20);
SetHits(15, 19);
SetDamage(1, 5);
SetDamageType(ResistanceType.Physical, 100);
SetResistance(ResistanceType.Physical, 5, 10);
SetResistance(ResistanceType.Poison, 15, 20);
SetSkill(SkillName.Poisoning, 36.0, 49.1);
SetSkill(SkillName.Anatomy, 0);
SetSkill(SkillName.MagicResist, 15.9, 18.9);
SetSkill(SkillName.Tactics, 24.6, 26.1);
SetSkill(SkillName.Wrestling, 24.9, 26.1);
Fame = 300;
Karma = -300;
VirtualArmor = 8;
Tamable = true;
ControlSlots = 1;
MinTameSkill = 23.1;
}
//TODO: Damage weapon via acid
public CorrosiveSlime(Serial serial) : base(serial)
{
}
public override string CorpseName => "a slimey corpse";
public override string DefaultName => "a corrosive slime";
public override Poison PoisonImmune => Poison.Regular;
public override Poison HitPoison => Poison.Regular;
public override FoodType FavoriteFood => FoodType.Fish;
public override void GenerateLoot()
{
AddLoot(LootPack.Poor);
AddLoot(LootPack.Gems);
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write(0);
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

View file

@ -0,0 +1,79 @@
using Server.Items;
namespace Server.Mobiles
{
public class Reptalon : BaseMount
{
[Constructible]
public Reptalon() : base("a reptalon", 0x114, 0x3E90, AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.35)
{
BaseSoundID = 0x16A;
SetStr(1001, 1025);
SetDex(152, 164);
SetInt(251, 289);
SetHits(833, 931);
SetDamage(21, 28);
SetDamageType(ResistanceType.Physical, 0);
SetDamageType(ResistanceType.Poison, 25);
SetDamageType(ResistanceType.Energy, 75);
SetResistance(ResistanceType.Physical, 53, 64);
SetResistance(ResistanceType.Fire, 35, 45);
SetResistance(ResistanceType.Cold, 36, 45);
SetResistance(ResistanceType.Poison, 52, 63);
SetResistance(ResistanceType.Energy, 71, 83);
SetSkill(SkillName.Wrestling, 101.5, 118.2);
SetSkill(SkillName.Tactics, 101.7, 108.2);
SetSkill(SkillName.MagicResist, 76.4, 89.9);
SetSkill(SkillName.Anatomy, 56.4, 59.7);
Tamable = true;
ControlSlots = 4;
MinTameSkill = 101.1;
}
public Reptalon(Serial serial) : base(serial)
{
}
public override string CorpseName => "a reptalon corpse";
public override int TreasureMapLevel => 5;
public override int Meat => 5;
public override int Hides => 10;
public override bool CanBreath => true;
public override bool CanAngerOnTame => true;
public override bool StatLossAfterTame => true;
public override FoodType FavoriteFood => FoodType.Meat;
public override bool CanFly => true;
public override void GenerateLoot()
{
AddLoot(LootPack.AosUltraRich, 3);
}
public override WeaponAbility GetWeaponAbility()
{
return WeaponAbility.ParalyzingBlow;
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

View file

@ -0,0 +1,80 @@
using Server.Items;
namespace Server.Mobiles
{
public class Grobu : BlackBear
{
[Constructible]
public Grobu()
{
IsParagon = true;
Hue = 0x455;
AI = AIType.AI_Melee;
FightMode = FightMode.Closest;
SetStr(192, 210);
SetDex(132, 150);
SetInt(50, 52);
SetHits(1235, 1299);
SetStam(132, 150);
SetMana(9);
SetDamage(15, 18);
SetDamageType(ResistanceType.Physical, 100);
SetResistance(ResistanceType.Physical, 40, 45);
SetResistance(ResistanceType.Fire, 20, 40);
SetResistance(ResistanceType.Cold, 32, 35);
SetResistance(ResistanceType.Poison, 25, 30);
SetResistance(ResistanceType.Energy, 22, 34);
SetSkill(SkillName.Wrestling, 96.4, 119.0);
SetSkill(SkillName.Tactics, 96.2, 116.5);
SetSkill(SkillName.MagicResist, 66.2, 83.7);
Fame = 1000;
Karma = 1000;
}
public Grobu(Serial serial)
: base(serial)
{
}
public override string CorpseName => "a Grobu corpse";
public override string DefaultName => "Grobu";
public override bool GivesMLMinorArtifact => true;
public override void GenerateLoot()
{
AddLoot(LootPack.FilthyRich, 2);
}
public override void OnDeath(Container c)
{
base.OnDeath(c);
c.DropItem(new GrobusFur());
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

View file

@ -0,0 +1,77 @@
using Server.Items;
namespace Server.Mobiles
{
public class Lurg : Troglodyte
{
[Constructible]
public Lurg()
{
IsParagon = true;
Hue = 0x455;
SetStr(584, 625);
SetDex(163, 176);
SetInt(90, 106);
SetHits(3034, 3189);
SetStam(163, 176);
SetMana(90, 106);
SetDamage(16, 19);
SetDamageType(ResistanceType.Physical, 100);
SetResistance(ResistanceType.Physical, 50, 53);
SetResistance(ResistanceType.Fire, 45, 47);
SetResistance(ResistanceType.Cold, 56, 60);
SetResistance(ResistanceType.Poison, 50, 60);
SetResistance(ResistanceType.Energy, 41, 56);
SetSkill(SkillName.Wrestling, 122.7, 130.5);
SetSkill(SkillName.Tactics, 109.3, 118.5);
SetSkill(SkillName.MagicResist, 72.9, 87.6);
SetSkill(SkillName.Anatomy, 110.5, 124.0);
SetSkill(SkillName.Healing, 84.1, 105.0);
Fame = 10000;
Karma = -10000;
}
public Lurg(Serial serial)
: base(serial)
{
}
public override string CorpseName => "a Lurg corpse";
public override string DefaultName => "Lurg";
public override bool GivesMLMinorArtifact => true;
public override int TreasureMapLevel => 4;
public override void GenerateLoot()
{
AddLoot(LootPack.UltraRich, 2);
}
public override WeaponAbility GetWeaponAbility()
{
return WeaponAbility.CrushingBlow;
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

View file

@ -0,0 +1,91 @@
namespace Server.Mobiles
{
public class Putrefier : Balron
{
[Constructible]
public Putrefier()
{
IsParagon = true;
Hue = 63;
SetStr(1057, 1400);
SetDex(232, 560);
SetInt(201, 440);
SetHits(3010, 4092);
SetDamage(27, 34);
SetDamageType(ResistanceType.Physical, 50);
SetDamageType(ResistanceType.Fire, 0);
SetDamageType(ResistanceType.Poison, 50);
SetDamageType(ResistanceType.Energy, 0);
SetResistance(ResistanceType.Physical, 65, 80);
SetResistance(ResistanceType.Fire, 65, 80);
SetResistance(ResistanceType.Cold, 50, 60);
SetResistance(ResistanceType.Poison, 100);
SetResistance(ResistanceType.Energy, 40, 50);
SetSkill(SkillName.Wrestling, 111.2, 128.0);
SetSkill(SkillName.Tactics, 115.2, 125.2);
SetSkill(SkillName.MagicResist, 143.4, 170.0);
SetSkill(SkillName.Anatomy, 44.6, 67.0);
SetSkill(SkillName.Magery, 117.6, 118.8);
SetSkill(SkillName.EvalInt, 113.0, 128.8);
SetSkill(SkillName.Meditation, 41.4, 85.0);
SetSkill(SkillName.Poisoning, 45.0, 50.0);
Fame = 24000;
Karma = -24000;
PackScroll(4, 7);
PackScroll(4, 7);
}
public Putrefier(Serial serial)
: base(serial)
{
}
public override string CorpseName => "a Putrefier corpse";
public override string DefaultName => "Putrefier";
/*
// TODO: uncomment once added
public override void OnDeath( Container c )
{
base.OnDeath( c );
c.DropItem( new SpleenOfThePutrefier() );
if ( Utility.RandomDouble() < 0.6 )
c.DropItem( new ParrotItem() );
}
*/
public override bool GivesMLMinorArtifact => true;
public override Poison HitPoison => Poison.Deadly; // Becomes Lethal with Paragon bonus
public override int TreasureMapLevel => 5;
public override void GenerateLoot()
{
AddLoot(LootPack.UltraRich, 3);
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

View file

@ -0,0 +1,82 @@
using System;
namespace Server.Mobiles
{
public class CorporealBrume : BaseCreature
{
[Constructible]
public CorporealBrume()
: base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4)
{
Body = 0x104; // TODO: Verify
BaseSoundID = 0x56B;
SetStr(400, 450);
SetDex(100, 150);
SetInt(50, 60);
SetHits(1150, 1250);
SetDamage(21, 25);
SetDamageType(ResistanceType.Physical, 100);
SetResistance(ResistanceType.Physical, 100);
SetResistance(ResistanceType.Fire, 40, 50);
SetResistance(ResistanceType.Cold, 40, 50);
SetResistance(ResistanceType.Poison, 50, 60);
SetResistance(ResistanceType.Energy, 30, 40);
SetSkill(SkillName.Wrestling, 110.0, 115.0);
SetSkill(SkillName.Tactics, 110.0, 115.0);
SetSkill(SkillName.MagicResist, 80.0, 95.0);
SetSkill(SkillName.Anatomy, 100.0, 110.0);
Fame = 12000;
Karma = -12000;
}
public CorporealBrume(Serial serial)
: base(serial)
{
}
public override string CorpseName => "a corporeal brume corpse";
public override string DefaultName => "a corporeal brume";
// TODO: Verify area attack specifics
public override bool HasAura => Combatant != null;
public override TimeSpan AuraInterval => TimeSpan.FromSeconds(20);
public override int AuraRange => 10;
public override int AuraBaseDamage => Utility.RandomMinMax(25, 35);
public override int AuraFireDamage => 0;
public override int AuraColdDamage => 100;
public override void GenerateLoot()
{
AddLoot(LootPack.FilthyRich);
AddLoot(LootPack.Rich);
}
public override void AuraEffect(Mobile m)
{
m.FixedParticles(0x374A, 10, 15, 5038, 1181, 2, EffectLayer.Head);
m.PlaySound(0x213);
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

View file

@ -0,0 +1,82 @@
namespace Server.Mobiles
{
public class CrystalDaemon : BaseCreature
{
[Constructible]
public CrystalDaemon()
: base(AIType.AI_Mage, FightMode.Closest, 10, 1, 0.2, 0.4)
{
Body = 0x310;
Hue = 0x3E8;
BaseSoundID = 0x47D;
SetStr(140, 200);
SetDex(120, 150);
SetInt(800, 850);
SetHits(200, 220);
SetDamage(16, 20);
SetDamageType(ResistanceType.Physical, 0);
SetDamageType(ResistanceType.Cold, 40);
SetDamageType(ResistanceType.Energy, 60);
SetResistance(ResistanceType.Physical, 20, 40);
SetResistance(ResistanceType.Fire, 0, 20);
SetResistance(ResistanceType.Cold, 60, 80);
SetResistance(ResistanceType.Poison, 20, 40);
SetResistance(ResistanceType.Energy, 65, 75);
SetSkill(SkillName.Wrestling, 60.0, 80.0);
SetSkill(SkillName.Tactics, 70.0, 80.0);
SetSkill(SkillName.MagicResist, 100.0, 110.0);
SetSkill(SkillName.Magery, 120.0, 130.0);
SetSkill(SkillName.EvalInt, 100.0, 110.0);
SetSkill(SkillName.Meditation, 100.0, 110.0);
Fame = 15000;
Karma = -15000;
PackArcaneScroll(0, 1);
}
/*
// TODO: uncomment once added
public override void OnDeath( Container c )
{
base.OnDeath( c );
if ( Utility.RandomDouble() < 0.4 )
c.DropItem( new ScatteredCrystals() );
}
*/
public CrystalDaemon(Serial serial)
: base(serial)
{
}
public override string CorpseName => "a crystal daemon corpse";
public override string DefaultName => "a crystal daemon";
public override void GenerateLoot()
{
AddLoot(LootPack.FilthyRich, 3);
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

View file

@ -0,0 +1,169 @@
namespace Server.Mobiles
{
public class CrystalLatticeSeeker : BaseCreature
{
[Constructible]
public CrystalLatticeSeeker()
: base(AIType.AI_Mage, FightMode.Closest, 10, 1, 0.2, 0.4)
{
Body = 0x7B;
Hue = 0x47E;
SetStr(550, 850);
SetDex(190, 250);
SetInt(350, 450);
SetHits(350, 550);
SetDamage(13, 19);
SetDamageType(ResistanceType.Physical, 100);
SetResistance(ResistanceType.Physical, 80, 90);
SetResistance(ResistanceType.Fire, 40, 50);
SetResistance(ResistanceType.Cold, 40, 50);
SetResistance(ResistanceType.Poison, 40, 50);
SetResistance(ResistanceType.Energy, 40, 50);
SetSkill(SkillName.Anatomy, 50.0, 75.0);
SetSkill(SkillName.EvalInt, 90.0, 100.0);
SetSkill(SkillName.Magery, 100.0, 100.0);
SetSkill(SkillName.Meditation, 90.0, 100.0);
SetSkill(SkillName.MagicResist, 90.0, 100.0);
SetSkill(SkillName.Tactics, 90.0, 100.0);
SetSkill(SkillName.Wrestling, 90.0, 100.0);
Fame = 17000;
Karma = -17000;
PackArcaneScroll(0, 2);
}
public CrystalLatticeSeeker(Serial serial)
: base(serial)
{
}
public override string CorpseName => "a Crystal Lattice Seeker corpse";
public override string DefaultName => "Crystal Lattice Seeker";
/*
// TODO: uncomment once added
public override void OnDeath( Container c )
{
base.OnDeath( c );
if ( Utility.RandomDouble() < 0.75 )
c.DropItem( new CrystallineFragments() );
if ( Utility.RandomDouble() < 0.07 )
c.DropItem( new PiecesOfCrystal() );
}
*/
public override int Feathers => 100;
public override int TreasureMapLevel => 5;
public override void GenerateLoot()
{
AddLoot(LootPack.FilthyRich, 4);
// TODO: uncomment once added
//AddLoot( LootPack.Parrot );
AddLoot(LootPack.Gems);
}
public override void OnGaveMeleeAttack(Mobile defender)
{
base.OnGaveMeleeAttack(defender);
if (Utility.RandomDouble() < 0.1)
Drain(defender);
}
public override void OnGotMeleeAttack(Mobile attacker)
{
base.OnGotMeleeAttack(attacker);
if (Utility.RandomDouble() < 0.1)
Drain(attacker);
}
public virtual void Drain(Mobile m)
{
int toDrain;
switch (Utility.Random(3))
{
case 0:
{
Say(1042156); // I can grant life, and I can sap it as easily.
PlaySound(0x1E6);
toDrain = Utility.RandomMinMax(3, 6);
Hits += toDrain;
m.Hits -= toDrain;
break;
}
case 1:
{
Say(1042157); // You'll go nowhere, unless I deem it should be so.
PlaySound(0x1DF);
toDrain = Utility.RandomMinMax(10, 25);
Stam += toDrain;
m.Stam -= toDrain;
break;
}
case 2:
{
Say(1042155); // Your power is mine to use as I will.
PlaySound(0x1F8);
toDrain = Utility.RandomMinMax(15, 25);
Mana += toDrain;
m.Mana -= toDrain;
break;
}
}
}
public override int GetAttackSound()
{
return 0x2F6;
}
public override int GetDeathSound()
{
return 0x2F7;
}
public override int GetAngerSound()
{
return 0x2F8;
}
public override int GetHurtSound()
{
return 0x2F9;
}
public override int GetIdleSound()
{
return 0x2FA;
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

View file

@ -0,0 +1,68 @@
namespace Server.Mobiles
{
public class CrystalSeaSerpent : SeaSerpent
{
[Constructible]
public CrystalSeaSerpent()
{
Hue = 0x47E;
SetStr(250, 450);
SetDex(100, 150);
SetInt(90, 190);
SetHits(230, 330);
SetDamage(10, 18);
SetDamageType(ResistanceType.Physical, 10);
SetDamageType(ResistanceType.Cold, 45);
SetDamageType(ResistanceType.Energy, 45);
SetResistance(ResistanceType.Physical, 50, 70);
SetResistance(ResistanceType.Fire, 0);
SetResistance(ResistanceType.Cold, 70, 90);
SetResistance(ResistanceType.Poison, 20, 30);
SetResistance(ResistanceType.Energy, 60, 80);
}
/*
// TODO: uncomment once added
public override void OnDeath( Container c )
{
base.OnDeath( c );
if ( Utility.RandomDouble() < 0.05 )
c.DropItem( new CrushedCrystals() );
if ( Utility.RandomDouble() < 0.1 )
c.DropItem( new IcyHeart() );
if ( Utility.RandomDouble() < 0.1 )
c.DropItem( new LuckyDagger() );
}
*/
public CrystalSeaSerpent(Serial serial)
: base(serial)
{
}
public override string CorpseName => "a crystal sea serpent corpse";
public override string DefaultName => "a crystal sea serpent";
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

View file

@ -0,0 +1,95 @@
namespace Server.Mobiles
{
public class CrystalVortex : BaseCreature
{
[Constructible]
public CrystalVortex()
: base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4)
{
Body = 0xD;
Hue = 0x2B2;
BaseSoundID = 0x107;
SetStr(800, 900);
SetDex(500, 600);
SetInt(200);
SetHits(350, 400);
SetMana(0);
SetDamage(15, 20);
SetDamageType(ResistanceType.Physical, 0);
SetDamageType(ResistanceType.Cold, 50);
SetDamageType(ResistanceType.Energy, 50);
SetResistance(ResistanceType.Physical, 60, 80);
SetResistance(ResistanceType.Fire, 0, 10);
SetResistance(ResistanceType.Cold, 70, 80);
SetResistance(ResistanceType.Poison, 40, 50);
SetResistance(ResistanceType.Energy, 60, 90);
SetSkill(SkillName.MagicResist, 120.0);
SetSkill(SkillName.Tactics, 120.0);
SetSkill(SkillName.Wrestling, 120.0);
Fame = 17000;
Karma = -17000;
PackArcaneScroll(0, 2);
}
public CrystalVortex(Serial serial)
: base(serial)
{
}
public override string CorpseName => "a crystal vortex corpse";
public override string DefaultName => "a crystal vortex";
public override void GenerateLoot()
{
AddLoot(LootPack.FilthyRich, 2);
// TODO: uncomment once added
//AddLoot( LootPack.Parrot );
}
/*
// TODO: uncomment once added
public override void OnDeath( Container c )
{
base.OnDeath( c );
if ( Utility.RandomDouble() < 0.75 )
c.DropItem( new CrystallineFragments() );
if ( Utility.RandomDouble() < 0.06 )
c.DropItem( new JaggedCrystals() );
}
*/
public override int GetAngerSound()
{
return 0x15;
}
public override int GetAttackSound()
{
return 0x28;
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

View file

@ -0,0 +1,34 @@
namespace Server.Mobiles
{
public class CrystalWisp : Wisp
{
[Constructible]
public CrystalWisp()
{
Hue = 0x482;
PackArcaneScroll(0, 1);
}
public CrystalWisp(Serial serial)
: base(serial)
{
}
public override string DefaultName => "a crystal wisp";
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

View file

@ -0,0 +1,68 @@
namespace Server.Mobiles
{
public class MantraEffervescence : BaseCreature
{
[Constructible]
public MantraEffervescence()
: base(AIType.AI_Mage, FightMode.Closest, 10, 1, 0.2, 0.4)
{
Body = 0x111;
BaseSoundID = 0x56E;
SetStr(130, 150);
SetDex(120, 130);
SetInt(150, 230);
SetHits(150, 250);
SetDamage(21, 25);
SetDamageType(ResistanceType.Physical, 30);
SetDamageType(ResistanceType.Energy, 70);
SetResistance(ResistanceType.Physical, 60, 65);
SetResistance(ResistanceType.Fire, 40, 50);
SetResistance(ResistanceType.Cold, 40, 50);
SetResistance(ResistanceType.Poison, 50, 60);
SetResistance(ResistanceType.Energy, 100);
SetSkill(SkillName.Wrestling, 80.0, 85.0);
SetSkill(SkillName.Tactics, 80.0, 85.0);
SetSkill(SkillName.MagicResist, 105.0, 115.0);
SetSkill(SkillName.Magery, 90.0, 110.0);
SetSkill(SkillName.EvalInt, 80.0, 90.0);
SetSkill(SkillName.Meditation, 90.0, 100.0);
Fame = 6500;
Karma = -6500;
}
public MantraEffervescence(Serial serial)
: base(serial)
{
}
public override string CorpseName => "a mantra effervescence corpse";
public override string DefaultName => "a mantra effervescence";
public override void GenerateLoot()
{
AddLoot(LootPack.FilthyRich);
AddLoot(LootPack.Rich);
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

View file

@ -0,0 +1,107 @@
using Server.Items;
namespace Server.Mobiles
{
public class Protector : BaseCreature
{
[Constructible]
public Protector()
: base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4)
{
Body = 401;
Female = true;
Hue = Race.Human.RandomSkinHue();
HairItemID = Race.Human.RandomHair(this);
HairHue = Race.Human.RandomHairHue();
Title = "the mystic llamaherder";
SetStr(700, 800);
SetDex(100, 150);
SetInt(50, 75);
SetHits(350, 450);
SetDamage(6, 12);
SetDamageType(ResistanceType.Physical, 100);
SetResistance(ResistanceType.Physical, 30, 40);
SetResistance(ResistanceType.Fire, 20, 30);
SetResistance(ResistanceType.Cold, 35, 40);
SetResistance(ResistanceType.Poison, 30, 40);
SetResistance(ResistanceType.Energy, 30, 40);
SetSkill(SkillName.Wrestling, 70.0, 100.0);
SetSkill(SkillName.Tactics, 80.0, 100.0);
SetSkill(SkillName.MagicResist, 50.0, 70.0);
SetSkill(SkillName.Anatomy, 70.0, 100.0);
Fame = 10000;
Karma = -10000;
Item boots = new ThighBoots();
boots.Movable = false;
boots.Hue = Utility.Random(2);
Item shroud = new Item(0x204E);
shroud.Layer = Layer.OuterTorso;
shroud.Movable = false;
shroud.Hue = Utility.Random(2);
AddItem(boots);
AddItem(shroud);
}
public Protector(Serial serial)
: base(serial)
{
}
public override string CorpseName => "a human corpse";
public override string DefaultName => "a Protector";
public override bool AlwaysMurderer => true;
public override bool PropertyTitle => false;
public override bool ShowFameTitle => false;
public override void GenerateLoot(bool spawning)
{
if (spawning)
return; // No loot/backpack on spawn
base.GenerateLoot(true);
base.GenerateLoot(false);
}
public override void GenerateLoot()
{
AddLoot(LootPack.FilthyRich);
}
/*
// TODO: uncomment once added
public override void OnDeath( Container c )
{
base.OnDeath( c );
if ( Utility.RandomDouble() < 0.4 )
c.DropItem( new ProtectorsEssence() );
}
*/
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

View file

@ -0,0 +1,87 @@
namespace Server.Mobiles
{
public class UnfrozenMummy : BaseCreature
{
[Constructible]
public UnfrozenMummy()
: base(AIType.AI_Mage, FightMode.Closest, 10, 1, 0.4, 0.8)
{
Body = 0x9B;
Hue = 0x480;
BaseSoundID = 0x1D7;
SetStr(450, 500);
SetDex(200, 250);
SetInt(800, 850);
SetHits(1500);
SetDamage(16, 20);
SetDamageType(ResistanceType.Physical, 0);
SetDamageType(ResistanceType.Energy, 50);
SetDamageType(ResistanceType.Cold, 50);
SetResistance(ResistanceType.Physical, 35, 40);
SetResistance(ResistanceType.Fire, 20, 30);
SetResistance(ResistanceType.Cold, 60, 80);
SetResistance(ResistanceType.Poison, 20, 30);
SetResistance(ResistanceType.Energy, 70, 80);
SetSkill(SkillName.Wrestling, 90.0, 100.0);
SetSkill(SkillName.Tactics, 100.0);
SetSkill(SkillName.MagicResist, 250.0);
SetSkill(SkillName.Magery, 50.0, 60.0);
SetSkill(SkillName.EvalInt, 50.0, 60.0);
SetSkill(SkillName.Meditation, 80.0);
Fame = 25000;
Karma = -25000;
PackArcaneScroll(0, 2);
}
/*
// TODO: uncomment once added
public override void OnDeath( Container c )
{
base.OnDeath( c );
if ( Utility.RandomDouble() < 0.6 )
c.DropItem( new BrokenCrystals() );
if ( Utility.RandomDouble() < 0.1 )
c.DropItem( new ParrotItem() );
}
*/
public UnfrozenMummy(Serial serial)
: base(serial)
{
}
public override string CorpseName => "an unfrozen mummy corpse";
public override string DefaultName => "an unfrozen mummy";
public override void GenerateLoot()
{
AddLoot(LootPack.UltraRich, 2);
// TODO: uncomment once added
//AddLoot( LootPack.Parrot );
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

View file

@ -0,0 +1,56 @@
namespace Server.Mobiles
{
public class Chiikkaha : RatmanMage
{
[Constructible]
public Chiikkaha()
{
SetStr(450, 476);
SetDex(157, 179);
SetInt(251, 275);
SetHits(400, 425);
SetDamage(10, 17);
SetDamageType(ResistanceType.Physical, 100);
SetResistance(ResistanceType.Physical, 40, 45);
SetResistance(ResistanceType.Fire, 10, 20);
SetResistance(ResistanceType.Cold, 10, 20);
SetResistance(ResistanceType.Poison, 10, 20);
SetResistance(ResistanceType.Energy, 100);
SetSkill(SkillName.EvalInt, 70.1, 80.0);
SetSkill(SkillName.Magery, 70.1, 90.0);
SetSkill(SkillName.MagicResist, 65.1, 96.0);
SetSkill(SkillName.Tactics, 50.1, 75.0);
SetSkill(SkillName.Wrestling, 50.1, 75.0);
Fame = 7500;
Karma = -7500;
}
public Chiikkaha(Serial serial)
: base(serial)
{
}
public override string CorpseName => "a Chiikkaha the Toothed corpse";
public override string DefaultName => "Chiikkaha the Toothed";
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

View file

@ -0,0 +1,54 @@
namespace Server.Mobiles
{
public class MougGuur : Ettin
{
[Constructible]
public MougGuur()
{
SetStr(556, 575);
SetDex(84, 94);
SetInt(59, 73);
SetHits(400, 415);
SetDamage(12, 20);
SetDamageType(ResistanceType.Physical, 100);
SetResistance(ResistanceType.Physical, 61, 65);
SetResistance(ResistanceType.Fire, 16, 19);
SetResistance(ResistanceType.Cold, 41, 46);
SetResistance(ResistanceType.Poison, 21, 24);
SetResistance(ResistanceType.Energy, 19, 25);
SetSkill(SkillName.MagicResist, 70.2, 75.0);
SetSkill(SkillName.Tactics, 80.8, 81.7);
SetSkill(SkillName.Wrestling, 93.9, 99.4);
Fame = 3000;
Karma = -3000;
}
public MougGuur(Serial serial)
: base(serial)
{
}
public override string CorpseName => "a Moug-Guur corpse";
public override string DefaultName => "Moug-Guur";
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

View file

@ -0,0 +1,58 @@
namespace Server.Mobiles
{
public class Szavetra : Succubus
{
[Constructible]
public Szavetra()
{
SetStr(627, 655);
SetDex(164, 193);
SetInt(566, 595);
SetHits(312, 415);
SetDamage(20, 30);
SetDamageType(ResistanceType.Physical, 75);
SetDamageType(ResistanceType.Energy, 25);
SetResistance(ResistanceType.Physical, 83, 90);
SetResistance(ResistanceType.Fire, 72, 80);
SetResistance(ResistanceType.Cold, 40, 49);
SetResistance(ResistanceType.Poison, 51, 60);
SetResistance(ResistanceType.Energy, 50, 60);
SetSkill(SkillName.EvalInt, 90.3, 99.8);
SetSkill(SkillName.Magery, 100.1, 100.6); // 10.1-10.6 on OSI, bug?
SetSkill(SkillName.Meditation, 90.1, 110.0);
SetSkill(SkillName.MagicResist, 112.2, 127.2);
SetSkill(SkillName.Tactics, 91.2, 92.8);
SetSkill(SkillName.Wrestling, 80.2, 86.4);
Fame = 24000;
Karma = -24000;
}
public Szavetra(Serial serial)
: base(serial)
{
}
public override string CorpseName => "a Szavetra corpse";
public override string DefaultName => "Szavetra";
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

View file

@ -0,0 +1,418 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Server.Engines.CannedEvil;
using Server.Items;
using Server.Network;
namespace Server.Mobiles
{
public class Ilhenir : BaseChampion
{
private static HashSet<Mobile> m_Table = new HashSet<Mobile>();
[Constructible]
public Ilhenir()
: base(AIType.AI_Mage)
{
Title = "the Stained";
Body = 0x103;
BaseSoundID = 589;
SetStr(1105, 1350);
SetDex(82, 160);
SetInt(505, 750);
SetHits(9000);
SetDamage(21, 28);
SetDamageType(ResistanceType.Physical, 60);
SetDamageType(ResistanceType.Fire, 20);
SetDamageType(ResistanceType.Poison, 20);
SetResistance(ResistanceType.Physical, 55, 65);
SetResistance(ResistanceType.Fire, 50, 60);
SetResistance(ResistanceType.Cold, 55, 65);
SetResistance(ResistanceType.Poison, 70, 90);
SetResistance(ResistanceType.Energy, 65, 75);
SetSkill(SkillName.EvalInt, 100);
SetSkill(SkillName.Magery, 100);
SetSkill(SkillName.Meditation, 0);
SetSkill(SkillName.Poisoning, 5.4);
SetSkill(SkillName.Anatomy, 117.5);
SetSkill(SkillName.MagicResist, 120.0);
SetSkill(SkillName.Tactics, 119.9);
SetSkill(SkillName.Wrestling, 119.9);
Fame = 50000;
Karma = -50000;
VirtualArmor = 44;
if (Core.ML)
{
PackResources(8);
PackTalismans(5);
}
}
public Ilhenir(Serial serial)
: base(serial)
{
}
public override string CorpseName => "a corpse of Ilhenir";
public override ChampionSkullType SkullType => ChampionSkullType.Pain;
public override Type[] UniqueList => new Type[] { };
public override Type[] SharedList => new[]
{
typeof(ANecromancerShroud),
typeof(LieutenantOfTheBritannianRoyalGuard),
typeof(OblivionsNeedle),
typeof(TheRobeOfBritanniaAri)
};
public override Type[] DecorativeList => new[] { typeof(MonsterStatuette) };
public override MonsterStatuetteType[] StatueTypes => new[]
{
MonsterStatuetteType.PlagueBeast,
MonsterStatuetteType.RedDeath
};
public override string DefaultName => "Ilhenir";
public override bool Unprovokable => true;
public override bool Uncalmable => true;
public override Poison PoisonImmune => Poison.Lethal;
//public override bool GivesMLMinorArtifact => true; // TODO: Needs verification
public override int TreasureMapLevel => 5;
public virtual void PackResources(int amount)
{
for (int i = 0; i < amount; i++)
switch (Utility.Random(6))
{
case 0:
PackItem(new Blight());
break;
case 1:
PackItem(new Scourge());
break;
case 2:
PackItem(new Taint());
break;
case 3:
PackItem(new Putrefication());
break;
case 4:
PackItem(new Corruption());
break;
case 5:
PackItem(new Muculent());
break;
}
}
public virtual void PackItems(Item item, int amount)
{
for (int i = 0; i < amount; i++)
PackItem(item);
}
public virtual void PackTalismans(int amount)
{
int count = Utility.Random(amount);
for (int i = 0; i < count; i++)
PackItem(new RandomTalisman());
}
public override void GenerateLoot()
{
AddLoot(LootPack.FilthyRich, 8);
}
public override void OnDeath(Container c)
{
base.OnDeath(c);
if (Core.ML)
{
c.DropItem(new GrizzledBones());
// TODO: Parrots
/*if ( Utility.RandomDouble() < 0.6 )
c.DropItem( new ParrotItem() ); */
if (Utility.RandomDouble() < 0.05)
c.DropItem(new GrizzledMareStatuette());
if (Utility.RandomDouble() < 0.025)
c.DropItem(new CrimsonCincture());
// TODO: Armor sets
/*if ( Utility.RandomDouble() < 0.05 )
{
switch ( Utility.Random(5) )
{
case 0: c.DropItem( new GrizzleGauntlets() ); break;
case 1: c.DropItem( new GrizzleGreaves() ); break;
case 2: c.DropItem( new GrizzleHelm() ); break;
case 3: c.DropItem( new GrizzleTunic() ); break;
case 4: c.DropItem( new GrizzleVambraces() ); break;
}
}*/
}
}
public override void OnGaveMeleeAttack(Mobile defender)
{
base.OnGaveMeleeAttack(defender);
if (Utility.RandomDouble() < 0.25)
CacophonicAttack(defender);
}
public override void OnDamage(int amount, Mobile from, bool willKill)
{
if (Utility.RandomDouble() < 0.1)
DropOoze();
base.OnDamage(amount, from, willKill);
}
public override int GetAngerSound()
{
return 0x581;
}
public override int GetIdleSound()
{
return 0x582;
}
public override int GetAttackSound()
{
return 0x580;
}
public override int GetHurtSound()
{
return 0x583;
}
public override int GetDeathSound()
{
return 0x584;
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
public virtual void CacophonicAttack(Mobile to)
{
if (to.Alive && to.Player && !UnderCacophonicAttack(to))
{
to.Send(SpeedControl.WalkSpeed);
to.SendLocalizedMessage(1072069); // A cacophonic sound lambastes you, suppressing your ability to move.
to.PlaySound(0x584);
m_Table.Add(to);
Timer.DelayCall(TimeSpan.FromSeconds(30), CacophonicEnd, to);
}
}
public virtual void CacophonicEnd(Mobile from)
{
m_Table.Remove(from);
from.Send(SpeedControl.Disable);
}
public static bool UnderCacophonicAttack(Mobile from)
{
return m_Table.Contains(from);
}
public virtual void DropOoze()
{
int amount = Utility.RandomMinMax(1, 3);
bool corrosive = Utility.RandomBool();
for (int i = 0; i < amount; i++)
{
Item ooze = new StainedOoze(corrosive);
Point3D p = new Point3D(Location);
for (int j = 0; j < 5; j++)
{
p = GetSpawnPosition(2);
if (!Map.GetItemsInRange(p, 0).OfType<StainedOoze>().Any())
break;
}
ooze.MoveToWorld(p, Map);
}
if (Combatant != null)
{
if (corrosive)
Combatant.SendLocalizedMessage(1072071); // A corrosive gas seeps out of your enemy's skin!
else
Combatant.SendLocalizedMessage(1072072); // A poisonous gas seeps out of your enemy's skin!
}
}
private int RandomPoint(int mid)
{
return mid + Utility.RandomMinMax(-2, 2);
}
public virtual Point3D GetSpawnPosition(int range)
{
return GetSpawnPosition(Location, Map, range);
}
public virtual Point3D GetSpawnPosition(Point3D from, Map map, int range)
{
if (map == null)
return from;
Point3D loc = new Point3D(RandomPoint(X), RandomPoint(Y), Z);
loc.Z = Map.GetAverageZ(loc.X, loc.Y);
return loc;
}
}
public class StainedOoze : Item
{
private int m_Ticks;
private Timer m_Timer;
[Constructible]
public StainedOoze(bool corrosive = false) : base(0x122A)
{
Movable = false;
Hue = 0x95;
Corrosive = corrosive;
m_Timer = Timer.DelayCall(TimeSpan.Zero, TimeSpan.FromSeconds(1), OnTick);
m_Ticks = 0;
}
public StainedOoze(Serial serial)
: base(serial)
{
}
[CommandProperty(AccessLevel.GameMaster)]
public bool Corrosive{ get; set; }
public override void OnAfterDelete()
{
if (m_Timer != null)
{
m_Timer.Stop();
m_Timer = null;
}
}
private void OnTick()
{
List<Mobile> toDamage = new List<Mobile>();
foreach (Mobile m in GetMobilesInRange(0))
{
if (m is BaseCreature bc)
{
if (!bc.Controlled && !bc.Summoned)
continue;
}
else if (!m.Player)
{
continue;
}
if (m.Alive && !m.IsDeadBondedPet && m.CanBeDamaged())
toDamage.Add(m);
}
for (int i = 0; i < toDamage.Count; ++i)
Damage(toDamage[i]);
++m_Ticks;
if (m_Ticks >= 35)
Delete();
else if (m_Ticks == 30)
ItemID = 0x122B;
}
public void Damage(Mobile m)
{
if (Corrosive)
{
List<Item> items = m.Items;
bool damaged = false;
for (int i = 0; i < items.Count; ++i)
if (items[i] is IDurability wearable && wearable.HitPoints >= 10 && Utility.RandomDouble() < 0.25)
{
wearable.HitPoints -= wearable.HitPoints == 10 ? Utility.Random(1, 5) : 10;
damaged = true;
}
if (damaged)
{
m.LocalOverheadMessage(MessageType.Regular, 0x21,
1072070); // The infernal ooze scorches you, setting you and your equipment ablaze!
return;
}
}
AOS.Damage(m, 40, 0, 0, 0, 100, 0);
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
writer.Write(Corrosive);
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
Corrosive = reader.ReadBool();
m_Timer = Timer.DelayCall(TimeSpan.Zero, TimeSpan.FromSeconds(1), OnTick);
m_Ticks = ItemID == 0x122A ? 0 : 30;
}
}
}

View file

@ -0,0 +1,252 @@
using System;
using Server.Engines.CannedEvil;
using Server.Items;
namespace Server.Mobiles
{
public class Meraktus : BaseChampion
{
[Constructible]
public Meraktus()
: base(AIType.AI_Melee)
{
Title = "the Tormented";
Body = 263;
BaseSoundID = 680;
Hue = 0x835;
SetStr(1419, 1438);
SetDex(309, 413);
SetInt(129, 131);
SetHits(4100, 4200);
SetDamage(16, 30);
SetDamageType(ResistanceType.Physical, 100);
SetResistance(ResistanceType.Physical, 65, 90);
SetResistance(ResistanceType.Fire, 65, 70);
SetResistance(ResistanceType.Cold, 50, 60);
SetResistance(ResistanceType.Poison, 40, 60);
SetResistance(ResistanceType.Energy, 50, 55);
//SetSkill( SkillName.Meditation, Unknown );
//SetSkill( SkillName.EvalInt, Unknown );
//SetSkill( SkillName.Magery, Unknown );
//SetSkill( SkillName.Poisoning, Unknown );
SetSkill(SkillName.Anatomy, 0);
SetSkill(SkillName.MagicResist, 107.0, 111.3);
SetSkill(SkillName.Tactics, 107.0, 117.0);
SetSkill(SkillName.Wrestling, 100.0, 105.0);
Fame = 70000;
Karma = -70000;
VirtualArmor = 28; // Don't know what it should be
if (Core.ML)
{
PackResources(8);
PackTalismans(5);
}
Timer.DelayCall(TimeSpan.FromSeconds(1), SpawnTormented);
}
public Meraktus(Serial serial) : base(serial)
{
}
public override string CorpseName => "the remains of Meraktus";
public override ChampionSkullType SkullType => ChampionSkullType.Pain;
public override Type[] UniqueList => new[] { typeof(Subdue) };
public override Type[] SharedList => new Type[] { };
public override Type[] DecorativeList => new[]
{
typeof(ArtifactLargeVase),
typeof(ArtifactVase),
typeof(MinotaurStatueDeed)
};
public override MonsterStatuetteType[] StatueTypes => new[] { MonsterStatuetteType.Minotaur };
public override string DefaultName => "Meraktus";
public override int Meat => 2;
public override int Hides => 10;
public override HideType HideType => HideType.Regular;
public override Poison PoisonImmune => Poison.Regular;
public override int TreasureMapLevel => 3;
public override bool BardImmune => true;
public override bool Unprovokable => true;
public override bool Uncalmable => true;
public override WeaponAbility GetWeaponAbility()
{
return WeaponAbility.Dismount;
}
public virtual void PackResources(int amount)
{
for (int i = 0; i < amount; i++)
switch (Utility.Random(6))
{
case 0:
PackItem(new Blight());
break;
case 1:
PackItem(new Scourge());
break;
case 2:
PackItem(new Taint());
break;
case 3:
PackItem(new Putrefication());
break;
case 4:
PackItem(new Corruption());
break;
case 5:
PackItem(new Muculent());
break;
}
}
public virtual void PackTalismans(int amount)
{
int count = Utility.Random(amount);
for (int i = 0; i < count; i++)
PackItem(new RandomTalisman());
}
public override void OnDeath(Container c)
{
base.OnDeath(c);
if (!Core.ML)
return;
c.DropItem(new MalletAndChisel());
switch (Utility.Random(3))
{
case 0:
c.DropItem(new MinotaurHedge());
break;
case 1:
c.DropItem(new BonePile());
break;
case 2:
c.DropItem(new LightYarn());
break;
}
if (Utility.RandomBool())
c.DropItem(new TormentedChains());
if (Utility.RandomDouble() < 0.025)
c.DropItem(new CrimsonCincture());
}
public override void GenerateLoot()
{
if (Core.ML)
AddLoot(LootPack.AosSuperBoss, 5); // Need to verify
}
public override int GetAngerSound()
{
return 0x597;
}
public override int GetIdleSound()
{
return 0x596;
}
public override int GetAttackSound()
{
return 0x599;
}
public override int GetHurtSound()
{
return 0x59a;
}
public override int GetDeathSound()
{
return 0x59c;
}
public override void OnGaveMeleeAttack(Mobile defender)
{
base.OnGaveMeleeAttack(defender);
if (0.2 >= Utility.RandomDouble())
Earthquake();
}
public void Earthquake()
{
IPooledEnumerable<Mobile> eable = GetMobilesInRange(8);
foreach (Mobile m in eable)
{
if (m == this || !CanBeHarmful(m) || m.Deleted || !m.Player &&
!(m is BaseCreature creature && (creature.Controlled || creature.Summoned || creature.Team != Team)))
continue;
if (m is PlayerMobile pm && pm.Mounted)
pm.Mount.Rider = null;
int damage = (int)(m.Hits * 0.6);
if (damage < 10)
damage = 10;
else if (damage > 75)
damage = 75;
DoHarmful(m);
AOS.Damage(m, this, damage, 100, 0, 0, 0, 0);
if (m.Alive && m.Body.IsHuman && !m.Mounted)
m.Animate(20, 7, 1, true, false, 0); // take hit
}
eable.Free();
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write(0);
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
#region SpawnHelpers
public void SpawnTormented()
{
BaseCreature spawna = new TormentedMinotaur();
spawna.MoveToWorld(Location, Map);
BaseCreature spawnb = new TormentedMinotaur();
spawnb.MoveToWorld(Location, Map);
BaseCreature spawnc = new TormentedMinotaur();
spawnc.MoveToWorld(Location, Map);
BaseCreature spawnd = new TormentedMinotaur();
spawnd.MoveToWorld(Location, Map);
}
#endregion
}
}

View file

@ -0,0 +1,138 @@
using System;
using Server.Engines.CannedEvil;
using Server.Items;
namespace Server.Mobiles
{
public class Twaulo : BaseChampion
{
[Constructible]
public Twaulo()
: base(AIType.AI_Melee)
{
Title = "of the Glade";
Body = 101;
BaseSoundID = 679;
Hue = 0x455;
SetStr(1751, 1950);
SetDex(251, 450);
SetInt(801, 1000);
SetHits(7500);
SetDamage(19, 24);
SetDamageType(ResistanceType.Physical, 100);
SetResistance(ResistanceType.Physical, 65, 75);
SetResistance(ResistanceType.Fire, 45, 55);
SetResistance(ResistanceType.Cold, 50, 60);
SetResistance(ResistanceType.Poison, 50, 60);
SetResistance(ResistanceType.Energy, 50, 60);
SetSkill(SkillName.EvalInt, 0); // Per Stratics?!?
SetSkill(SkillName.Magery, 0); // Per Stratics?!?
SetSkill(SkillName.Meditation, 0); // Per Stratics?!?
SetSkill(SkillName.Anatomy, 95.1, 115.0);
SetSkill(SkillName.Archery, 95.1, 100.0);
SetSkill(SkillName.MagicResist, 50.3, 80.0);
SetSkill(SkillName.Tactics, 90.1, 100.0);
SetSkill(SkillName.Wrestling, 95.1, 100.0);
Fame = 50000;
Karma = 50000;
VirtualArmor = 50;
AddItem(new Bow());
PackItem(new Arrow(Utility.RandomMinMax(500, 700)));
}
public Twaulo(Serial serial)
: base(serial)
{
}
public override string CorpseName => "a corpse of Twaulo";
public override ChampionSkullType SkullType => ChampionSkullType.Pain;
public override Type[] UniqueList => new[] { typeof(Quell) };
public override Type[] SharedList => new[] { typeof(TheMostKnowledgePerson), typeof(OblivionsNeedle) };
public override Type[] DecorativeList => new[] { typeof(Pier), typeof(MonsterStatuette) };
public override MonsterStatuetteType[] StatueTypes => new[] { MonsterStatuetteType.DreadHorn };
public override string DefaultName => "Twaulo";
public override OppositionGroup OppositionGroup => OppositionGroup.FeyAndUndead;
public override bool Unprovokable => true;
public override Poison PoisonImmune => Poison.Regular;
public override int TreasureMapLevel => 5;
public override int Meat => 1;
public override int Hides => 8;
public override HideType HideType => HideType.Spined;
public override void GenerateLoot()
{
AddLoot(LootPack.UltraRich, 2);
AddLoot(LootPack.Average);
AddLoot(LootPack.Gems);
}
public void SpawnPixies(Mobile target)
{
Map map = Map;
if (map == null)
return;
int newPixies = Utility.RandomMinMax(3, 6);
for (int i = 0; i < newPixies; ++i)
{
Pixie pixie = new Pixie { Team = Team, FightMode = FightMode.Closest };
pixie.MoveToWorld(map.GetRandomNearbyLocation(Location), map);
pixie.Combatant = target;
}
}
public override void AlterDamageScalarFrom(Mobile caster, ref double scalar)
{
if (0.1 >= Utility.RandomDouble())
SpawnPixies(caster);
}
public override void OnGaveMeleeAttack(Mobile defender)
{
base.OnGaveMeleeAttack(defender);
defender.Damage(Utility.Random(20, 10), this);
defender.Stam -= Utility.Random(20, 10);
defender.Mana -= Utility.Random(20, 10);
}
public override void OnGotMeleeAttack(Mobile attacker)
{
base.OnGotMeleeAttack(attacker);
if (0.1 >= Utility.RandomDouble())
SpawnPixies(attacker);
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write(0);
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

View file

@ -0,0 +1,315 @@
using System;
using Server.Items;
using Server.Spells;
namespace Server.Mobiles
{
public class Changeling : BaseCreature
{
private static readonly int[] m_FireNorth =
{
-1, -1,
1, -1,
-1, 2,
1, 2
};
private static readonly int[] m_FireEast =
{
-1, 0,
2, 0
};
private DateTime m_LastMorph;
private Mobile m_MorphedInto;
private DateTime m_NextFireRing;
[Constructible]
public Changeling()
: base(AIType.AI_Mage, FightMode.Closest, 10, 1, 0.2, 0.4)
{
Body = 264;
Hue = DefaultHue;
SetStr(36, 105);
SetDex(212, 262);
SetInt(317, 399);
SetHits(201, 211);
SetStam(212, 262);
SetMana(317, 399);
SetDamage(9, 15);
SetDamageType(ResistanceType.Physical, 100);
SetResistance(ResistanceType.Physical, 81, 90);
SetResistance(ResistanceType.Fire, 40, 50);
SetResistance(ResistanceType.Cold, 40, 49);
SetResistance(ResistanceType.Poison, 40, 50);
SetResistance(ResistanceType.Energy, 43, 50);
SetSkill(SkillName.Wrestling, 10.4, 12.5);
SetSkill(SkillName.Tactics, 101.1, 108.3);
SetSkill(SkillName.MagicResist, 121.6, 132.2);
SetSkill(SkillName.Magery, 91.6, 99.5);
SetSkill(SkillName.EvalInt, 91.5, 98.8);
SetSkill(SkillName.Meditation, 91.7, 98.5);
Fame = 15000;
Karma = -15000;
PackScroll(1, 7);
PackItem(new Arrow(35));
PackItem(new Bolt(25));
PackGem(2);
PackArcaneScroll(0, 1);
}
public Changeling(Serial serial)
: base(serial)
{
}
public override string CorpseName => "a changeling corpse";
public override string DefaultName => "a changeling";
public virtual int DefaultHue => 0;
public override bool ShowFameTitle => false;
public override bool InitialInnocent => m_MorphedInto != null;
[CommandProperty(AccessLevel.GameMaster)]
public Mobile MorphedInto
{
get => m_MorphedInto;
set
{
if (value == this)
value = null;
if (m_MorphedInto != value)
{
Revert();
if (value != null)
{
Morph(value);
m_LastMorph = DateTime.UtcNow;
}
m_MorphedInto = value;
Delta(MobileDelta.Noto);
}
}
}
public override void GenerateLoot()
{
AddLoot(LootPack.AosRich, 3);
}
public override int GetAngerSound()
{
return 0x46E;
}
public override int GetIdleSound()
{
return 0x470;
}
public override int GetAttackSound()
{
return 0x46D;
}
public override int GetHurtSound()
{
return 0x471;
}
public override int GetDeathSound()
{
return 0x46F;
}
public override void OnThink()
{
base.OnThink();
if (Combatant != null)
{
if (m_NextFireRing <= DateTime.UtcNow && Utility.RandomDouble() < 0.02)
{
FireRing();
m_NextFireRing = DateTime.UtcNow + TimeSpan.FromMinutes(2);
}
if (Combatant.Player && m_MorphedInto != Combatant && Utility.RandomDouble() < 0.05)
MorphedInto = Combatant;
}
}
public override bool CheckIdle()
{
bool idle = base.CheckIdle();
if (idle && m_MorphedInto != null && DateTime.UtcNow - m_LastMorph > TimeSpan.FromSeconds(30))
MorphedInto = null;
return idle;
}
private void FireEffects(int itemID, int[] offsets)
{
for (int i = 0; i < offsets.Length; i += 2)
{
Point3D p = Location;
p.X += offsets[i];
p.Y += offsets[i + 1];
if (SpellHelper.AdjustField(ref p, Map, 12, false))
Effects.SendLocationEffect(p, Map, itemID, 50);
}
}
protected virtual void FireRing()
{
FireEffects(0x3E27, m_FireNorth);
FireEffects(0x3E31, m_FireEast);
}
protected virtual void Morph(Mobile m)
{
Body = m.Body;
Hue = m.Hue;
Female = m.Female;
Name = m.Name;
NameHue = m.NameHue;
Title = m.Title;
Kills = m.Kills;
HairItemID = m.HairItemID;
HairHue = m.HairHue;
FacialHairItemID = m.FacialHairItemID;
FacialHairHue = m.FacialHairHue;
// TODO: Skills?
foreach (Item item in m.Items)
if (item.Layer != Layer.Backpack && item.Layer != Layer.Mount && item.Layer != Layer.Bank)
AddItem(new ClonedItem(item)); // TODO: Clone weapon/armor attributes
PlaySound(0x511);
FixedParticles(0x376A, 1, 14, 5045, EffectLayer.Waist);
}
protected virtual void Revert()
{
Body = 264;
Hue = IsParagon && DefaultHue == 0 ? Paragon.Hue : DefaultHue;
Female = false;
Name = null;
NameHue = -1;
Title = null;
Kills = 0;
HairItemID = 0;
HairHue = 0;
FacialHairItemID = 0;
FacialHairHue = 0;
DeleteClonedItems();
PlaySound(0x511);
FixedParticles(0x376A, 1, 14, 5045, EffectLayer.Waist);
}
public void DeleteClonedItems()
{
for (int i = Items.Count - 1; i >= 0; --i)
{
Item item = Items[i];
if (item is ClonedItem)
item.Delete();
}
if (Backpack != null)
for (int i = Backpack.Items.Count - 1; i >= 0; --i)
{
Item item = Backpack.Items[i];
if (item is ClonedItem)
item.Delete();
}
}
public override void OnAfterDelete()
{
DeleteClonedItems();
base.OnAfterDelete();
}
public override void ClearHands()
{
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
writer.Write(m_MorphedInto != null);
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
if (reader.ReadBool())
ValidationQueue<Changeling>.Add(this);
}
public void Validate()
{
Revert();
}
private class ClonedItem : Item
{
public ClonedItem(Item item)
: base(item.ItemID)
{
Name = item.Name;
Weight = item.Weight;
Hue = item.Hue;
Layer = item.Layer;
Movable = false;
}
public ClonedItem(Serial serial)
: base(serial)
{
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}
}

View file

@ -0,0 +1,80 @@
namespace Server.Mobiles
{
public class Gnaw : DireWolf
{
[Constructible]
public Gnaw()
{
IsParagon = true;
Hue = 0x130;
SetStr(151, 172);
SetDex(124, 145);
SetInt(60, 86);
SetHits(817, 857);
SetStam(124, 145);
SetMana(52, 86);
SetDamage(16, 22);
SetDamageType(ResistanceType.Physical, 100);
SetResistance(ResistanceType.Physical, 64, 69);
SetResistance(ResistanceType.Fire, 53, 56);
SetResistance(ResistanceType.Cold, 22, 27);
SetResistance(ResistanceType.Poison, 27, 30);
SetResistance(ResistanceType.Energy, 21, 34);
SetSkill(SkillName.Wrestling, 106.4, 116.5);
SetSkill(SkillName.Tactics, 84.1, 103.2);
SetSkill(SkillName.MagicResist, 96.8, 110.7);
Fame = 17500;
Karma = -17500;
}
/*
// TODO: uncomment once added
public override void OnDeath( Container c )
{
base.OnDeath( c );
if ( Utility.RandomDouble() < 0.3 )
c.DropItem( new GnawsFang() );
}
*/
public Gnaw(Serial serial)
: base(serial)
{
}
public override string CorpseName => "a Gnaw corpse";
public override string DefaultName => "Gnaw";
public override bool GivesMLMinorArtifact => true;
public override int Hides => 28;
public override int Meat => 4;
public override void GenerateLoot()
{
AddLoot(LootPack.FilthyRich, 2);
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

View file

@ -0,0 +1,84 @@
namespace Server.Mobiles
{
public class Guile : Changeling
{
[Constructible]
public Guile()
{
IsParagon = true;
Hue = DefaultHue;
SetStr(53, 214);
SetDex(243, 367);
SetInt(369, 586);
SetHits(1013, 1058);
SetStam(243, 367);
SetMana(369, 586);
SetDamage(14, 20);
SetDamageType(ResistanceType.Physical, 100);
SetResistance(ResistanceType.Physical, 80, 90);
SetResistance(ResistanceType.Fire, 43, 46);
SetResistance(ResistanceType.Cold, 42, 44);
SetResistance(ResistanceType.Poison, 42, 50);
SetResistance(ResistanceType.Energy, 47, 50);
SetSkill(SkillName.Wrestling, 12.8, 16.7);
SetSkill(SkillName.Tactics, 102.6, 131.0);
SetSkill(SkillName.MagicResist, 141.2, 161.6);
SetSkill(SkillName.Magery, 108.4, 120.0);
SetSkill(SkillName.EvalInt, 108.4, 120.0);
SetSkill(SkillName.Meditation, 109.2, 120.0);
Fame = 21000;
Karma = -21000;
}
public Guile(Serial serial)
: base(serial)
{
}
public override string CorpseName => "a Guile corpse";
public override string DefaultName => "Guile";
public override int DefaultHue => 0x3F;
public override bool GivesMLMinorArtifact => true;
public override void OnGaveMeleeAttack(Mobile defender)
{
base.OnGaveMeleeAttack(defender);
if (Utility.RandomBool())
if (!Kappa.IsBeingDrained(defender) && Mana > 14)
{
defender.SendLocalizedMessage(1070848); // You feel your life force being stolen away.
Kappa.BeginLifeDrain(defender, this);
Mana -= 15;
}
}
public override void GenerateLoot()
{
AddLoot(LootPack.UltraRich, 2);
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

View file

@ -0,0 +1,85 @@
namespace Server.Mobiles
{
public class Irk : Changeling
{
[Constructible]
public Irk()
{
IsParagon = true;
Hue = DefaultHue;
SetStr(23, 183);
SetDex(259, 360);
SetInt(374, 600);
SetHits(1006, 1064);
SetStam(259, 360);
SetMana(374, 600);
SetDamage(14, 20);
SetResistance(ResistanceType.Physical, 80, 90);
SetResistance(ResistanceType.Fire, 40, 50);
SetResistance(ResistanceType.Cold, 40, 50);
SetResistance(ResistanceType.Poison, 41, 50);
SetResistance(ResistanceType.Energy, 40, 49);
SetSkill(SkillName.Wrestling, 120.3, 123.0);
SetSkill(SkillName.Tactics, 120.1, 131.8);
SetSkill(SkillName.MagicResist, 132.3, 165.8);
SetSkill(SkillName.Magery, 108.9, 119.7);
SetSkill(SkillName.EvalInt, 108.4, 120.0);
SetSkill(SkillName.Meditation, 108.9, 119.1);
Fame = 21000;
Karma = -21000;
}
/*
// TODO: uncomment once added
public override void OnDeath( Container c )
{
base.OnDeath( c );
if ( Utility.RandomDouble() < 0.25 )
c.DropItem( new IrksBrain() );
if ( Utility.RandomDouble() < 0.025 )
c.DropItem( new PaladinGloves() );
}
*/
public Irk(Serial serial)
: base(serial)
{
}
public override string CorpseName => "an Irk corpse";
public override string DefaultName => "Irk";
public override int DefaultHue => 0x489;
// TODO: Angry fire
public override bool GivesMLMinorArtifact => true;
public override void GenerateLoot()
{
AddLoot(LootPack.UltraRich, 2);
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

View file

@ -0,0 +1,92 @@
using Server.Items;
namespace Server.Mobiles
{
public class LadyLissith : GiantBlackWidow
{
[Constructible]
public LadyLissith()
{
IsParagon = true;
Hue = 0x452;
SetStr(81, 130);
SetDex(116, 152);
SetInt(44, 100);
SetHits(245, 375);
SetStam(116, 152);
SetMana(44, 100);
SetDamage(15, 22);
SetDamageType(ResistanceType.Physical, 100);
SetResistance(ResistanceType.Physical, 40, 50);
SetResistance(ResistanceType.Fire, 31, 39);
SetResistance(ResistanceType.Cold, 30, 40);
SetResistance(ResistanceType.Poison, 71, 80);
SetResistance(ResistanceType.Energy, 30, 40);
SetSkill(SkillName.Wrestling, 108.6, 123.0);
SetSkill(SkillName.Tactics, 102.7, 119.0);
SetSkill(SkillName.MagicResist, 78.8, 95.6);
SetSkill(SkillName.Anatomy, 68.6, 106.8);
SetSkill(SkillName.Poisoning, 96.6, 112.9);
Fame = 18900;
Karma = -18900;
}
public LadyLissith(Serial serial)
: base(serial)
{
}
public override string CorpseName => "a Lady Lissith corpse";
public override string DefaultName => "Lady Lissith";
/*
// TODO: uncomment once added
public override void OnDeath( Container c )
{
base.OnDeath( c );
if ( Utility.RandomDouble() < 0.025 )
c.DropItem( new GreymistChest() );
if ( Utility.RandomDouble() < 0.45 )
c.DropItem( new LissithsSilk() );
if ( Utility.RandomDouble() < 0.1 )
c.DropItem( new ParrotItem() );
}
*/
public override bool GivesMLMinorArtifact => true;
public override void GenerateLoot()
{
AddLoot(LootPack.UltraRich, 2);
}
public override WeaponAbility GetWeaponAbility()
{
return WeaponAbility.BleedAttack;
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

View file

@ -0,0 +1,98 @@
using Server.Items;
namespace Server.Mobiles
{
public class LadySabrix : GiantBlackWidow
{
[Constructible]
public LadySabrix()
{
IsParagon = true;
Hue = 0x497;
SetStr(82, 130);
SetDex(117, 146);
SetInt(50, 98);
SetHits(233, 361);
SetStam(117, 146);
SetMana(50, 98);
SetDamage(15, 22);
SetDamageType(ResistanceType.Physical, 100);
SetResistance(ResistanceType.Physical, 40, 50);
SetResistance(ResistanceType.Fire, 30, 40);
SetResistance(ResistanceType.Cold, 30, 39);
SetResistance(ResistanceType.Poison, 70, 80);
SetResistance(ResistanceType.Energy, 35, 44);
SetSkill(SkillName.Wrestling, 109.8, 122.8);
SetSkill(SkillName.Tactics, 102.8, 120.0);
SetSkill(SkillName.MagicResist, 79.4, 95.1);
SetSkill(SkillName.Anatomy, 68.8, 105.1);
SetSkill(SkillName.Poisoning, 97.8, 116.7);
Fame = 18900;
Karma = -18900;
}
public LadySabrix(Serial serial)
: base(serial)
{
}
public override string CorpseName => "a Lady Sabrix corpse";
public override string DefaultName => "Lady Sabrix";
/*
// TODO: uncomment once added
public override void OnDeath( Container c )
{
base.OnDeath( c );
if ( Utility.RandomDouble() < 0.2 )
c.DropItem( new SabrixsEye() );
if ( Utility.RandomDouble() < 0.25 )
{
switch ( Utility.Random( 2 ) )
{
case 0: AddToBackpack( new PaladinArms() ); break;
case 1: AddToBackpack( new HunterLegs() ); break;
}
}
if ( Utility.RandomDouble() < 0.1 )
c.DropItem( new ParrotItem() );
}
*/
public override bool GivesMLMinorArtifact => true;
public override void GenerateLoot()
{
AddLoot(LootPack.UltraRich, 2);
}
public override WeaponAbility GetWeaponAbility()
{
return WeaponAbility.ArmorIgnore;
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

View file

@ -0,0 +1,83 @@
using Server.Items;
namespace Server.Mobiles
{
public class Malefic : DreadSpider
{
[Constructible]
public Malefic()
{
IsParagon = true;
Hue = 0x455;
SetStr(210, 284);
SetDex(153, 197);
SetInt(349, 390);
SetHits(600, 747);
SetStam(153, 197);
SetMana(349, 390);
SetDamage(15, 22);
SetDamageType(ResistanceType.Physical, 20);
SetDamageType(ResistanceType.Poison, 80);
SetResistance(ResistanceType.Physical, 60, 70);
SetResistance(ResistanceType.Fire, 40, 50);
SetResistance(ResistanceType.Cold, 40, 49);
SetResistance(ResistanceType.Poison, 100);
SetResistance(ResistanceType.Energy, 41, 48);
SetSkill(SkillName.Wrestling, 96.9, 112.4);
SetSkill(SkillName.Tactics, 91.3, 105.4);
SetSkill(SkillName.MagicResist, 79.8, 95.1);
SetSkill(SkillName.Magery, 103.0, 118.6);
SetSkill(SkillName.EvalInt, 105.7, 119.6);
SetSkill(SkillName.Meditation, 0);
Fame = 21000;
Karma = -21000;
/*
// TODO: uncomment once added
if ( Utility.RandomDouble() < 0.1 )
PackItem( new ParrotItem() );
*/
}
public Malefic(Serial serial)
: base(serial)
{
}
public override string CorpseName => "a Malefic corpse";
public override string DefaultName => "Malefic";
public override bool GivesMLMinorArtifact => true;
public override void GenerateLoot()
{
AddLoot(LootPack.UltraRich, 3);
}
public override WeaponAbility GetWeaponAbility()
{
return WeaponAbility.Dismount;
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

View file

@ -0,0 +1,75 @@
using Server.Items;
namespace Server.Mobiles
{
public class Silk : GiantBlackWidow
{
[Constructible]
public Silk()
{
IsParagon = true;
Hue = 0x47E;
SetStr(80, 131);
SetDex(126, 156);
SetInt(63, 102);
SetHits(279, 378);
SetStam(126, 156);
SetMana(63, 102);
SetDamage(15, 22);
SetDamageType(ResistanceType.Physical, 100);
SetResistance(ResistanceType.Physical, 40, 50);
SetResistance(ResistanceType.Fire, 30, 39);
SetResistance(ResistanceType.Cold, 30, 40);
SetResistance(ResistanceType.Poison, 70, 76);
SetResistance(ResistanceType.Energy, 30, 40);
SetSkill(SkillName.Wrestling, 114.1, 123.7);
SetSkill(SkillName.Tactics, 102.6, 118.3);
SetSkill(SkillName.MagicResist, 78.6, 94.8);
SetSkill(SkillName.Anatomy, 81.3, 105.7);
SetSkill(SkillName.Poisoning, 106.0, 119.2);
Fame = 18900;
Karma = -18900;
}
public Silk(Serial serial)
: base(serial)
{
}
public override string CorpseName => "a Silk corpse";
public override string DefaultName => "Silk";
public override bool GivesMLMinorArtifact => true;
public override void GenerateLoot()
{
AddLoot(LootPack.UltraRich, 2);
}
public override WeaponAbility GetWeaponAbility()
{
return WeaponAbility.ParalyzingBlow;
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

View file

@ -0,0 +1,71 @@
namespace Server.Mobiles
{
public class Spite : Changeling
{
[Constructible]
public Spite()
{
IsParagon = true;
Hue = DefaultHue;
SetStr(53, 214);
SetDex(243, 367);
SetInt(369, 586);
SetHits(1013, 1052);
SetStam(243, 367);
SetMana(369, 586);
SetDamage(14, 20);
SetDamageType(ResistanceType.Physical, 100);
SetResistance(ResistanceType.Physical, 85, 90);
SetResistance(ResistanceType.Fire, 41, 46);
SetResistance(ResistanceType.Cold, 40, 44);
SetResistance(ResistanceType.Poison, 42, 46);
SetResistance(ResistanceType.Energy, 45, 47);
SetSkill(SkillName.Wrestling, 12.8, 16.7);
SetSkill(SkillName.Tactics, 102.6, 131.0);
SetSkill(SkillName.MagicResist, 141.2, 161.6);
SetSkill(SkillName.Magery, 108.4, 119.2);
SetSkill(SkillName.EvalInt, 108.4, 120.0);
SetSkill(SkillName.Meditation, 109.2, 120.0);
Fame = 21000;
Karma = -21000;
}
public Spite(Serial serial)
: base(serial)
{
}
public override string CorpseName => "a Spite corpse";
public override string DefaultName => "Spite";
public override int DefaultHue => 0x21;
public override bool GivesMLMinorArtifact => true;
public override void GenerateLoot()
{
AddLoot(LootPack.UltraRich, 2);
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

View file

@ -0,0 +1,170 @@
using System;
using System.Collections.Generic;
namespace Server.Mobiles
{
public class Swoop : Eagle
{
private static Dictionary<Mobile, ExpireTimer> m_Table = new Dictionary<Mobile, ExpireTimer>();
[Constructible]
public Swoop()
{
IsParagon = true;
Hue = 0xE0;
AI = AIType.AI_Melee;
SetStr(100, 150);
SetDex(400, 500);
SetInt(80, 90);
SetHits(1500, 2000);
SetDamage(20, 30);
SetDamageType(ResistanceType.Physical, 100);
SetResistance(ResistanceType.Physical, 75, 90);
SetResistance(ResistanceType.Fire, 60, 77);
SetResistance(ResistanceType.Cold, 70, 85);
SetResistance(ResistanceType.Poison, 55, 85);
SetResistance(ResistanceType.Energy, 50, 60);
SetSkill(SkillName.Wrestling, 120.0, 140.0);
SetSkill(SkillName.Tactics, 120.0, 140.0);
SetSkill(SkillName.MagicResist, 95.0, 105.0);
Fame = 18000;
Karma = 0;
PackReg(4);
PackArcaneScroll(0, 1);
}
/*
// TODO: uncomment once added
public override void OnDeath( Container c )
{
base.OnDeath( c );
if ( Utility.RandomDouble() < 0.025 )
{
switch ( Utility.Random( 18 ) )
{
case 0: c.DropItem( new AssassinChest() ); break;
case 1: c.DropItem( new AssassinArms() ); break;
case 2: c.DropItem( new DeathChest() ); break;
case 3: c.DropItem( new MyrmidonArms() ); break;
case 4: c.DropItem( new MyrmidonLegs() ); break;
case 5: c.DropItem( new MyrmidonGorget() ); break;
case 6: c.DropItem( new LeafweaveGloves() ); break;
case 7: c.DropItem( new LeafweaveLegs() ); break;
case 8: c.DropItem( new LeafweavePauldrons() ); break;
case 9: c.DropItem( new PaladinGloves() ); break;
case 10: c.DropItem( new PaladinGorget() ); break;
case 11: c.DropItem( new PaladinArms() ); break;
case 12: c.DropItem( new HunterArms() ); break;
case 13: c.DropItem( new HunterGloves() ); break;
case 14: c.DropItem( new HunterLegs() ); break;
case 15: c.DropItem( new HunterChest() ); break;
case 16: c.DropItem( new GreymistArms() ); break;
case 17: c.DropItem( new GreymistGloves() ); break;
}
}
if ( Utility.RandomDouble() < 0.1 )
c.DropItem( new ParrotItem() );
}
*/
public Swoop(Serial serial)
: base(serial)
{
}
public override string CorpseName => "a Swoop corpse";
public override string DefaultName => "Swoop";
public override bool CanFly => true;
public override bool GivesMLMinorArtifact => true;
public override int Feathers => 72;
public override void GenerateLoot()
{
AddLoot(LootPack.UltraRich, 2);
}
// TODO: Put this attack shared with Hiryu and Lesser Hiryu in one place
public override void OnGaveMeleeAttack(Mobile defender)
{
base.OnGaveMeleeAttack(defender);
if (0.1 <= Utility.RandomDouble())
return;
if (m_Table.TryGetValue(defender, out ExpireTimer timer))
{
timer.DoExpire();
defender.SendLocalizedMessage(1070837); // The creature lands another blow in your weakened state.
}
else
{
defender.SendLocalizedMessage(
1070836); // The blow from the creature's claws has made you more susceptible to physical attacks.
}
int effect = -(defender.PhysicalResistance * 15 / 100);
ResistanceMod mod = new ResistanceMod(ResistanceType.Physical, effect);
defender.FixedEffect(0x37B9, 10, 5);
defender.AddResistanceMod(mod);
timer = new ExpireTimer(defender, mod, TimeSpan.FromSeconds(5.0));
timer.Start();
m_Table[defender] = timer;
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
private class ExpireTimer : Timer
{
private Mobile m_Mobile;
private ResistanceMod m_Mod;
public ExpireTimer(Mobile m, ResistanceMod mod, TimeSpan delay)
: base(delay)
{
m_Mobile = m;
m_Mod = mod;
Priority = TimerPriority.TwoFiftyMS;
}
public void DoExpire()
{
m_Mobile.RemoveResistanceMod(m_Mod);
Stop();
m_Table.Remove(m_Mobile);
}
protected override void OnTick()
{
m_Mobile.SendLocalizedMessage(1070838); // Your resistance to physical attacks has returned.
DoExpire();
}
}
}
}

View file

@ -0,0 +1,97 @@
using Server.Items;
namespace Server.Mobiles
{
public class Virulent : DreadSpider
{
[Constructible]
public Virulent()
{
IsParagon = true;
Hue = 0x8FD;
SetStr(207, 252);
SetDex(156, 194);
SetInt(346, 398);
SetHits(616, 740);
SetStam(156, 194);
SetMana(346, 398);
SetDamage(15, 22);
SetDamageType(ResistanceType.Physical, 20);
SetDamageType(ResistanceType.Poison, 80);
SetResistance(ResistanceType.Physical, 60, 68);
SetResistance(ResistanceType.Fire, 40, 49);
SetResistance(ResistanceType.Cold, 41, 50);
SetResistance(ResistanceType.Poison, 100);
SetResistance(ResistanceType.Energy, 40, 49);
SetSkill(SkillName.Wrestling, 92.8, 111.7);
SetSkill(SkillName.Tactics, 91.6, 107.4);
SetSkill(SkillName.MagicResist, 78.1, 93.3);
SetSkill(SkillName.Poisoning, 120.0);
SetSkill(SkillName.Magery, 104.2, 119.8);
SetSkill(SkillName.EvalInt, 102.8, 117.8);
Fame = 21000;
Karma = -21000;
}
public Virulent(Serial serial)
: base(serial)
{
}
public override string CorpseName => "a Virulent corpse";
public override string DefaultName => "Virulent";
/*
// TODO: uncomment once added
public override void OnDeath( Container c )
{
base.OnDeath( c );
if ( Utility.RandomDouble() < 0.025 )
{
switch ( Utility.Random( 2 ) )
{
case 0: c.DropItem( new HunterLegs() ); break;
case 1: c.DropItem( new MalekisHonor() ); break;
}
}
if ( Utility.RandomDouble() < 0.1 )
c.DropItem( new ParrotItem() );
}
*/
public override bool GivesMLMinorArtifact => true;
public override void GenerateLoot()
{
AddLoot(LootPack.UltraRich, 3);
}
public override WeaponAbility GetWeaponAbility()
{
return WeaponAbility.MortalStrike;
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}