#W# Source and Scripts added. Added Scripts/Settings.cs to expose some basic tweak able settings.

This commit is contained in:
WarrentyExpired 2026-08-06 11:06:05 -04:00
parent b51c58f514
commit 3045c83799
3512 changed files with 627673 additions and 0 deletions

View file

@ -0,0 +1,607 @@
using System;
using Server;
using Server.Items;
using Server.Mobiles;
namespace Server.Engines.Quests.Necro
{
public class AcceptConversation : QuestConversation
{
public override object Message
{
get
{
/* <I><U>Important Quest Information</U></I><BR><BR>
*
* During your quest, any important information that a
* <a href = "?ForceTopic31">NPC</a> gives you, will appear in a
* window such as this one. You can review the information at
* any time during your quest.<BR><BR><U>Getting Help</U><BR><BR>
*
* Some of the text you will come across during your quest, will
* be underlined <a href = "?ForceTopic73">links to the codex of
* wisdom</a>, or online help system. You can click on the text
* to get detailed information on the underlined subject. You
* may also access the Codex Of Wisdom by pressing "F1" or by
* clicking on the "?" on the toolbar at the top of your screen.<BR><BR>
*
* <U>Context Menus</U><BR><BR>Context menus can be called up by
* single left-clicking (or Shift + single left-click, if you
* changed it) on most objects or NPCs in the world. Nearly
* everything, including your own avatar will have context menus
* available. Bringing up your avatar's context menu will give
* you options to cancel your quest and review various quest
* information.<BR><BR>
*/
return 1049092;
}
}
public AcceptConversation()
{
}
public override void OnRead()
{
Container bag = Mardoth.GetNewContainer();
bag.DropItem( new DarkTidesHorn() );
System.From.AddToBackpack( bag );
System.AddConversation( new ReanimateMaabusConversation() );
}
}
public class ReanimateMaabusConversation : QuestConversation
{
public override object Message
{
get
{
/* Excellent choice, young apprentice of evil!<BR><BR>
*
* I will not waste our time with pleasantries. There is much work
* to be done – especially in light of the recent Paladin ambushes
* that we have suffered. The necromantic brotherhood is working
* towards the summoning of the elder daemon Kronus, who will rise
* from the Well of Tears to help us finally crush the Paladin forces
* that have plagued our lands for so long now.<BR><BR>
*
* To summon Kronus, we must energize the Well of Tears with a series
* of dark rituals. Unfortunately the rituals needed to sufficiently
* energize the Well of Tears have been lost to us. Your task will be
* to recover one of the ritual scrolls needed for the summoning.<BR><BR>
*
* You will need to find the corpse of the Arch Necromancer Maabus, which
* has been laid to rest in the tomb of elders. We believe his spirit may
* have memory of where we may find the scrolls needed for the summoning.
* You will need to awaken him from the slumber of death, using your
* Animate Dead spell, of course.<BR><BR>
*
* To reach the tomb, step onto the magical teleporter just to the
* <a href = "?ForceTopic13">West</a> of where I am standing.<BR><BR>
*
* Once you have been teleported, follow the path, which will lead you to
* the tomb of Maabus.<BR><BR>One more thing before you go:<BR><BR>
*
* Should you get into trouble out there or should you lose your way, do
* not worry. I have also given you a magical horn - a <I>Horn of Retreat</I>.
* Play the horn at any time to open a magical gateway that leads back to this
* tower.<BR><BR>
*
* Should your horn run out of <a href = "?ForceTopic83">charges</a>, simply
* hand me the horn to have it recharged.<BR><BR>
*
* Good luck friend.
*/
return 1060099;
}
}
private static QuestItemInfo[] m_Info = new QuestItemInfo[]
{
new QuestItemInfo( 1026153, 6178 ), // teleporter
new QuestItemInfo( 1049117, 4036 ), // Horn of Retreat
new QuestItemInfo( 1048032, 3702 ) // a bag
};
public override QuestItemInfo[] Info{ get{ return m_Info; } }
public ReanimateMaabusConversation()
{
}
public override void OnRead()
{
System.AddObjective( new FindMaabusTombObjective() );
}
}
public class MaabasConversation : QuestConversation
{
public override object Message
{
get
{
/* <I>Maabus emits an ear-crawling screech as his body reanimates.
* He turns and angrily screams at you</I>:<BR><BR>
*
* YOU INFIDEL! HOW DARE YOU AWAKEN MAABUS!?!<BR><BR>
*
* <I>Maabus continues to scream at you angrily for some time.
* As he settles down, you explain to him the purpose of your visit.
* Once you explain that you are on a quest to summon the elder daemon
* Kronus, Maabus begins to cooperate, and begins to speak in a more
* reasonable tone</I>:<BR><BR>
*
* Well, why didn’t you say so? If you’re going to raise Kronus from
* the Well of Tears, you must first complete a long series of dark
* rituals. I once owned one of the scrolls needed for the summoning,
* but alas it was lost to me when I lost my life to a cowardly Paladin
* ambush near the Paladin city of Light. They would have probably
* hidden the scroll in their precious crystal cave near the city.<BR><BR>
*
* There is a teleporter in the corner of this tomb. It will transport
* you near the crystal cave at which I believe one of the calling scrolls
* is hidden. Good luck.<BR><BR>
*
* <I>Maabus' body slumps back into the coffinas your magic expires</I>.
*/
return 1060103;
}
}
private static QuestItemInfo[] m_Info = new QuestItemInfo[]
{
new QuestItemInfo( 1026153, 6178 ) // teleporter
};
public override QuestItemInfo[] Info{ get{ return m_Info; } }
public MaabasConversation()
{
}
public override void OnRead()
{
System.AddObjective( new FindCrystalCaveObjective() );
}
}
public class HorusConversation : QuestConversation
{
public override object Message
{
get
{
/* <I>An old man, dressed in slightly tattered armor, whom you recognize
* to be a Paladin stands before the Crystal Cave staring blankly into
* the space in front of him. As he begins to speak to you, you realize
* this man is blind. You attempt to persuade the blind man that you are
* a Paladin seeking to inspect the scroll of calling...</I><BR><BR>
*
* Greetings traveler!<BR><BR>
*
* You seek entrance to the Crystal Cave, home of the Calling Scroll? Hmm.
* You reak of death and decay, brother. You reak of death like a Necromancer,
* but yet you claim to be a Paladin in hopes that I will grant thee passage
* into the cave?<BR><BR>
*
* Please don’t think ill of me for this, but I’m just a blind, old man looking
* to keep the brotherhood of Paladins safe from the clutches of the elder daemon
* Kronus. The Necromancers have been after this particular scroll for quite some
* time, so we must take all the security precautions we can.<BR><BR>
*
* Before I can let you pass into the Crystal Cave, you must speak to me the secret
* word that is kept in the Scroll of Abraxus in the Vault of Secrets at the Paladin
* city of Light. It’s the only way that I can be sure you are who you claim to be,
* since Necromancers cannot enter the Vault due to powerful protective magic that
* the brotherhood has blessed the vault with.
*/
return 1060105;
}
}
public HorusConversation()
{
}
public override void OnRead()
{
System.AddObjective( new FindMardothAboutVaultObjective() );
}
}
public class MardothVaultConversation : QuestConversation
{
public override object Message
{
get
{
/* <I>Mardoth looks at you expectantly until you tell him that you failed
* to retrieve the scroll...</I><BR><BR>
*
* You failed? Very unfortunate... So now you must find your way into
* the paladin’s Vault of Secrets, eh? Well, you won't be able to get in
* – there is a powerful magic aura that protects the Vault from all
* Necromancers. We simply cannot enter. However, that's not to say you
* familiar spirit can't.<BR><BR>
*
* <I>Mardoth grins with obvious satisfaction
* as he explains the details of the <a href="?ForceTopic127">Summon
* Familiar</a> spell to you...</I>, which will allow you to summon a
* scavenging Horde Minion to steal the scroll.<BR><BR>
*
* Very well. You are prepared to go. Take the teleporter just to the
* <a href = "?ForceTopic13">West</a> of where I am standing to transport
* to the Paladin city of Light. Once you have arrived in the city, follow
* the road of glowing runes to the Vault of Secrets. You know what to do.
*/
return 1060107;
}
}
public MardothVaultConversation()
{
}
public override void OnRead()
{
System.AddObjective( new FindCityOfLightObjective() );
}
}
public class VaultOfSecretsConversation : QuestConversation
{
public override object Message
{
get
{
/* You have arrived in the Vault of Secrets. You can feel the
* protective magic in this place restricting you, making you
* feel nearly claustrophobic.<BR><BR>
*
* Just ahead of you and out of your reach, you see a collection
* of scrolls and books, one of them being entitled
* 'Scroll of Abraxus' . You can only assume that this scroll
* holds the current password required to enter the Crystal Cave.<BR><BR>
*
* This would be a good opportunity to <a href="?ForceTopic127">summon
* your familiar</a>. Since your familiar is not a Necromancer, it
* will not be affected by the anti-magic aura that surrounds the Vault.<BR><BR>
*
* Summon your familiar with the <a href="?ForceTopic127">Summon Familiar</a> spell.
*/
return 1060110;
}
}
private static QuestItemInfo[] m_Info = new QuestItemInfo[]
{
new QuestItemInfo( 1023643, 8787 ) // spellbook
};
public override QuestItemInfo[] Info{ get{ return m_Info; } }
public VaultOfSecretsConversation()
{
}
public override void OnRead()
{
System.AddObjective( new FetchAbraxusScrollObjective() );
}
}
public class ReadAbraxusScrollConversation : QuestConversation
{
public override object Message
{
get
{
/* You have obtained the Scroll of Abraxus, which contains the secret
* password needed to gain passage into the Crystal Cave where the
* Scroll of Calling is kept. Read the scroll (double click) and
* figure out the password.<BR><BR>
*
* Once you have the password, return to the Crystal Cave and speak
* the password to the guard.<BR><BR>
*
* If you do not know the way to the Crystal Cave from the Paladin City,
* you can use the magic teleporter located just outside of the vault.
*/
return 1060114;
}
}
public ReadAbraxusScrollConversation()
{
}
public override void OnRead()
{
System.AddObjective( new ReadAbraxusScrollObjective() );
}
}
public class SecondHorusConversation : QuestConversation
{
public override object Message
{
get
{
/* Very well Paladin, you have proven to me your identity.
* I grant thee passage.<BR><BR>
*
* Be careful, however – I’ve heard that the cave has been
* infested with a vermin of some sort. Our High Lord
* Melkeer was supposed to send some troops to clear the
* vermin out of the cave, but that was last week already.
* I fear that he forgot.<BR><BR>
*
* If you can find it in your goodness to dispose of at
* least 5 of those vermin in there, I shall reward your
* efforts. If however you are too busy, and I would
* understand if you were, don’t bother with the vermin.<BR><BR>
*
* You may now pass through the energy barrier to enter the
* Crystal Cave. Take care honorable Paladin soul.
* Walk in the light my friend.
*/
return 1060118;
}
}
public SecondHorusConversation()
{
}
public override void OnRead()
{
System.AddObjective( new FindCallingScrollObjective() );
}
}
public class HealConversation : QuestConversation
{
public override object Message
{
get
{
/* You've just slain a creature. Now is a good time to learn how
* to heal yourself as a Necromancer.<BR><BR>
*
* As a follower of the dark path, you are able to recover lost
* hitpoints by communing with the spirit world via the skill
* <a href="?ForceTopic133">Spirit Speak</a>. Learn more about it now,
* <a href="?ForceTopic73">in the codex of Wisdom</a>.
*/
return 1061610;
}
}
public HealConversation()
{
}
}
public class HorusRewardConversation : QuestConversation
{
public override object Message
{
get
{
/* I thank you for going out of your way to clean out some
* of the vermin in that cave – here is your reward: a bag
* containing 500 gold coins plus a strange and magical artifact
* that should come in handy in your travels.<BR><BR>
*
* Take care young Paladin!
*/
return 1060717;
}
}
public override bool Logged{ get{ return false; } }
public HorusRewardConversation()
{
}
}
public class LostCallingScrollConversation : QuestConversation
{
private bool m_FromMardoth;
public override object Message
{
get
{
if ( m_FromMardoth )
{
/* You return without the scroll of Calling? I'm afraid that
* won't do. You must return to the Crystal Cave and fetch
* another scroll. Use the teleporter to the West of me to
* get there. Return here when you have the scroll. Do not
* fail me this time, young apprentice of evil.
*/
return 1062058;
}
else // from well of tears
{
/* You have arrived at the well, but no longer have the scroll
* of calling. Use Mardoth's teleporter to return to the
* Crystal Cave and fetch another scroll from the box.
*/
return 1060129;
}
}
}
public override bool Logged{ get{ return false; } }
public LostCallingScrollConversation( bool fromMardoth )
{
m_FromMardoth = fromMardoth;
}
// Serialization
public LostCallingScrollConversation()
{
}
public override void ChildDeserialize( GenericReader reader )
{
int version = reader.ReadEncodedInt();
m_FromMardoth = reader.ReadBool();
}
public override void ChildSerialize( GenericWriter writer )
{
writer.WriteEncodedInt( (int) 0 ); // version
writer.Write( (bool) m_FromMardoth );
}
}
public class MardothKronusConversation : QuestConversation
{
public override object Message
{
get
{
/* You have returned with the scroll! I knew I could count on you.
* You can now perform the rite of calling at the Well of Tears.
* This ritual will help charge the Well to prepare for the coming
* of Kronus. You are prepared to do your part young Necromancer!<BR><BR>
*
* Just outside of this tower, you will find a path lined with red
* lanterns. Follow this path to get to the Well of Tears. Once
* you have arrived at the Well, use the scroll to perform the
* ritual of calling. Performing the rite will empower the well
* and bring us that much closer to the arrival of Kronus.<BR><BR>
*
* Once you have completed the ritual, return here for your
* promised reward.
*/
return 1060121;
}
}
public MardothKronusConversation()
{
}
public override void OnRead()
{
System.AddObjective( new FindWellOfTearsObjective() );
}
}
public class MardothEndConversation : QuestConversation
{
public override object Message
{
get
{
/* You have done as I asked... I knew I could count on you from
* the moment you walked in here!<BR><BR>
*
* The forces of evil are strong within you. You will become
* a great Necromancer in this life - perhaps even the greatest.<BR><BR>
*
* My work for you is done here. I release you from my service
* to go into the world and fight for our cause...<BR><BR>
*
* Oh...I almost forgot - your reward. Here is a magical
* weapon and 2000 gold for you, in the form of a check. Don't
* spend it all in one place though, eh?<BR><BR>
*
* Actually, before you can spend any of it at all, you will
* have to <a href="?ForceTopic86">cash the check</a> at the
* nearest bank. Shopkeepers never accept checks for payment,
* they require cash.<BR><BR>
*
* In your pack, you will find an enchanted sextant. Use this
* sextant to guide you to the nearest bank.<BR><BR>
*
* Farewell, and stay true to the ways of the shadow...
*/
return 1060133;
}
}
public MardothEndConversation()
{
}
public override void OnRead()
{
System.AddObjective( new FindBankObjective() );
}
}
public class BankerConversation : QuestConversation
{
public override object Message
{
get
{
/* <I>The banker smiles at you and greets you in a loud and robust voice...</I><BR><BR>
*
* Well hello there adventurer! I see you've learned how to cash checks. Wonderful!
* Let me tell you a bit about the banks in this world...<BR><BR>
*
* Anything that you place into any bank box, can be retrieved from any other
* bank box in the land. For instance, if you place an item into a bank box in
* Britain, it can be retrieved from your bank box in Moonglow or any other city.<BR><BR>
*
* Bank boxes are very secure. So secure, in fact, that no one can ever get into
* your bank box except for yourself. Security is hard to come by these days,
* but you can trust in the banking system of Britannia! We shall not let you down!<BR><BR>
*
* I hope to be seeing much more of you as your riches grow! May your bank box overflow
* with the spoils of your adventures.<BR><BR>Farewell adventurer, you are now free to
* explore the world on your own.
*/
return 1060137;
}
}
public BankerConversation()
{
}
public override void OnRead()
{
System.Complete();
}
}
public class RadarConversation : QuestConversation
{
public override object Message
{
get
{
/* If you are leaving the tower, you should learn about the Radar Map.<BR><BR>
*
* The Radar Map (or Overhead View) can be opened by pressing 'ALT-R'
* on your keyboard. It shows your immediate surroundings from a bird's
* eye view.<BR><BR>Pressing ALT-R twice, will enlarge the Radar Map a
* little. Use the Radar Map often as you travel throughout the world
* to familiarize yourself with your surroundings.
*/
return 1061692;
}
}
public override bool Logged{ get{ return false; } }
public RadarConversation()
{
}
}
}

View file

@ -0,0 +1,153 @@
using System;
using Server;
using Server.Items;
using Server.Mobiles;
namespace Server.Engines.Quests.Necro
{
public class DarkTidesQuest : QuestSystem
{
private static Type[] m_TypeReferenceTable = new Type[]
{
typeof( Necro.AcceptConversation ),
typeof( Necro.AnimateMaabusCorpseObjective ),
typeof( Necro.BankerConversation ),
typeof( Necro.CashBankCheckObjective ),
typeof( Necro.FetchAbraxusScrollObjective ),
typeof( Necro.FindBankObjective ),
typeof( Necro.FindCallingScrollObjective ),
typeof( Necro.FindCityOfLightObjective ),
typeof( Necro.FindCrystalCaveObjective ),
typeof( Necro.FindMaabusCorpseObjective ),
typeof( Necro.FindMaabusTombObjective ),
typeof( Necro.FindMardothAboutKronusObjective ),
typeof( Necro.FindMardothAboutVaultObjective ),
typeof( Necro.FindMardothEndObjective ),
typeof( Necro.FindVaultOfSecretsObjective ),
typeof( Necro.FindWellOfTearsObjective ),
typeof( Necro.HorusConversation ),
typeof( Necro.LostCallingScrollConversation ),
typeof( Necro.MaabasConversation ),
typeof( Necro.MardothEndConversation ),
typeof( Necro.MardothKronusConversation ),
typeof( Necro.MardothVaultConversation ),
typeof( Necro.RadarConversation ),
typeof( Necro.ReadAbraxusScrollConversation ),
typeof( Necro.ReadAbraxusScrollObjective ),
typeof( Necro.ReanimateMaabusConversation ),
typeof( Necro.RetrieveAbraxusScrollObjective ),
typeof( Necro.ReturnToCrystalCaveObjective ),
typeof( Necro.SecondHorusConversation ),
typeof( Necro.SpeakCavePasswordObjective ),
typeof( Necro.UseCallingScrollObjective ),
typeof( Necro.VaultOfSecretsConversation ),
typeof( Necro.FindHorusAboutRewardObjective ),
typeof( Necro.HealConversation ),
typeof( Necro.HorusRewardConversation )
};
public override Type[] TypeReferenceTable{ get{ return m_TypeReferenceTable; } }
public override object Name
{
get
{
// Dark Tides
return 1060095;
}
}
public override object OfferMessage
{
get
{
/* <I>An old man who looks to be 200 years old from the looks
* of his translucently pale and heavily wrinkled skin, turns
* to you and gives you a half-cocked grin that makes you
* feel somewhat uneasy.<BR><BR>
*
* After a short pause, he begins to speak to you...</I><BR><BR>
*
* Hmm. What's this? Another budding Necromancer to join the
* ranks of Evil? Here... let me take a look at you... Ah
* yes... Very Good! I sense the forces of evil are strong
* within you, child – but you need training so that you can
* learn to focus your skills against those aligned against
* our cause. You are destined to become a legendary
* Necromancer - with the proper training, that only I can
* give you.<BR><BR>
*
* <I>Mardoth pauses just long enough to give you a wide,
* skin-crawling grin.</I><BR><BR>
*
* Let me introduce myself. I am Mardoth, the guildmaster of
* the Necromantic Brotherhood. I have taken it upon myself
* to train anyone willing to learn the dark arts of Necromancy.
* The path of destruction, decay and obliteration is not an
* easy one. Only the most evil and the most dedicated can
* hope to master the sinister art of death.<BR><BR>
*
* I can lend you training and help supply you with equipment –
* in exchange for a few services rendered by you, of course.
* Nothing major, just a little death and destruction here and
* there - the tasks should be easy as a tasty meat pie for one
* as treacherous and evil as yourself.<BR><BR>
*
* What do you say? Do we have a deal?
*/
return 1060094;
}
}
public override TimeSpan RestartDelay{ get{ return TimeSpan.MaxValue; } }
public override bool IsTutorial{ get{ return true; } }
public override int Picture{ get{ return 0x15B5; } }
public DarkTidesQuest( PlayerMobile from ) : base( from )
{
}
// Serialization
public DarkTidesQuest()
{
}
public override void Accept()
{
base.Accept();
AddConversation( new AcceptConversation() );
}
public override bool IgnoreYoungProtection( Mobile from )
{
if ( from is SummonedPaladin )
return true;
return base.IgnoreYoungProtection( from );
}
public static bool HasLostCallingScroll( Mobile from )
{
PlayerMobile pm = from as PlayerMobile;
if ( pm == null )
return false;
QuestSystem qs = pm.Quest;
if ( qs is DarkTidesQuest )
{
if ( qs.IsObjectiveInProgress( typeof( FindMardothAboutKronusObjective ) ) || qs.IsObjectiveInProgress( typeof( FindWellOfTearsObjective ) ) || qs.IsObjectiveInProgress( typeof( UseCallingScrollObjective ) ) )
{
Container pack = from.Backpack;
return ( pack == null || pack.FindItemByType( typeof( KronusScroll ) ) == null );
}
}
return false;
}
}
}

View file

@ -0,0 +1,72 @@
using System;
using Server;
using Server.Items;
using Server.Mobiles;
using Server.Engines.Quests;
using Server.Engines.Quests.Necro;
namespace Server.Engines.Quests.Necro
{
public class CrystalCaveBarrier : Item
{
[Constructable]
public CrystalCaveBarrier() : base( 0x3967 )
{
Movable = false;
}
public override bool OnMoveOver( Mobile m )
{
if ( m.AccessLevel > AccessLevel.Player )
return true;
bool sendMessage = m.Player;
if ( m is BaseCreature )
m = ((BaseCreature)m).ControlMaster;
PlayerMobile pm = m as PlayerMobile;
if ( pm != null )
{
QuestSystem qs = pm.Quest;
if ( qs is DarkTidesQuest )
{
QuestObjective obj = qs.FindObjective( typeof( SpeakCavePasswordObjective ) );
if ( obj != null && obj.Completed )
{
if ( sendMessage )
m.SendLocalizedMessage( 1060648 ); // With Horus' permission, you are able to pass through the barrier.
return true;
}
}
}
if ( sendMessage )
m.SendLocalizedMessage( 1060649, "", 0x66D ); // Without the permission of the guardian Horus, the magic of the barrier prevents your passage.
return false;
}
public CrystalCaveBarrier( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
}
}
}

View file

@ -0,0 +1,44 @@
using System;
using Server;
using Server.Items;
using Server.Mobiles;
using Server.Engines.Quests;
using Server.Engines.Quests.Necro;
namespace Server.Engines.Quests.Necro
{
public class DarkTidesHorn : HornOfRetreat
{
public override bool ValidateUse( Mobile from )
{
PlayerMobile pm = from as PlayerMobile;
return ( pm != null && pm.Quest is DarkTidesQuest );
}
[Constructable]
public DarkTidesHorn()
{
DestLoc = new Point3D( 2103, 1319, -68 );
DestMap = Map.Malas;
}
public DarkTidesHorn( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
}
}
}

View file

@ -0,0 +1,77 @@
using System;
using Server;
using Server.Items;
using Server.Mobiles;
using Server.Engines.Quests;
using Server.Engines.Quests.Necro;
namespace Server.Engines.Quests.Necro
{
public class DarkTidesTeleporter : DynamicTeleporter
{
[Constructable]
public DarkTidesTeleporter()
{
}
public override bool GetDestination( PlayerMobile player, ref Point3D loc, ref Map map )
{
QuestSystem qs = player.Quest;
if ( qs is DarkTidesQuest )
{
if ( qs.IsObjectiveInProgress( typeof( FindMaabusTombObjective ) ) )
{
loc = new Point3D( 2038, 1263, -90 );
map = Map.Malas;
qs.AddConversation( new RadarConversation() );
return true;
}
else if ( qs.IsObjectiveInProgress( typeof( FindCrystalCaveObjective ) ) )
{
loc = new Point3D( 1194, 521, -90 );
map = Map.Malas;
return true;
}
else if ( qs.IsObjectiveInProgress( typeof( FindCityOfLightObjective ) ) )
{
loc = new Point3D( 1091, 519, -90 );
map = Map.Malas;
return true;
}
else if ( qs.IsObjectiveInProgress( typeof( ReturnToCrystalCaveObjective ) ) )
{
loc = new Point3D( 1194, 521, -90 );
map = Map.Malas;
return true;
}
else if ( DarkTidesQuest.HasLostCallingScroll( player ) )
{
loc = new Point3D( 1194, 521, -90 );
map = Map.Malas;
return true;
}
}
return false;
}
public DarkTidesTeleporter( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
}
}
}

View file

@ -0,0 +1,166 @@
using System;
using Server;
using Server.Mobiles;
using Server.Items;
using Server.Network;
namespace Server.Engines.Quests.Necro
{
public class KronusScroll : QuestItem
{
public override int LabelNumber { get { return 1060149; } } // Calling of Kronus
[Constructable]
public KronusScroll() : base( 0x227A )
{
Weight = 1.0;
Hue = 0x44E;
}
public KronusScroll( Serial serial ) : base( serial )
{
}
public override bool CanDrop( PlayerMobile player )
{
DarkTidesQuest qs = player.Quest as DarkTidesQuest;
if ( qs == null )
return true;
/*return !( qs.IsObjectiveInProgress( typeof( FindCallingScrollObjective ) )
|| qs.IsObjectiveInProgress( typeof( FindMardothAboutKronusObjective ) )
|| qs.IsObjectiveInProgress( typeof( FindWellOfTearsObjective ) )
|| qs.IsObjectiveInProgress( typeof( UseCallingScrollObjective ) ) );*/
return false;
}
private static readonly Rectangle2D m_WellOfTearsArea = new Rectangle2D( 2080, 1346, 10, 10 );
private static readonly Map m_WellOfTearsMap = Map.Malas;
public override void OnDoubleClick( Mobile from )
{
if ( !IsChildOf( from ) )
return;
PlayerMobile pm = from as PlayerMobile;
if ( pm != null )
{
QuestSystem qs = pm.Quest;
if ( qs is DarkTidesQuest )
{
if ( qs.IsObjectiveInProgress( typeof( FindMardothAboutKronusObjective ) ) )
{
pm.SendLocalizedMessage( 1060151, "", 0x41 ); // You read the scroll, but decide against performing the calling until you are instructed to do so by Mardoth.
}
else if ( qs.IsObjectiveInProgress( typeof( FindWellOfTearsObjective ) ) )
{
pm.SendLocalizedMessage( 1060152, "", 0x41 ); // You must be at the Well of Tears in the city of Necromancers to use this scroll.
}
else if ( qs.IsObjectiveInProgress( typeof( UseCallingScrollObjective ) ) )
{
if ( pm.Map == m_WellOfTearsMap && m_WellOfTearsArea.Contains( pm ) )
{
QuestObjective obj = qs.FindObjective( typeof( UseCallingScrollObjective ) );
if ( obj != null && !obj.Completed )
obj.Complete();
Delete();
new CallingTimer( pm ).Start();
}
else
{
pm.SendLocalizedMessage( 1060152, "", 0x41 ); // You must be at the Well of Tears in the city of Necromancers to use this scroll.
}
}
else
{
pm.SendLocalizedMessage( 1060150, "", 0x41 ); // A strange terror grips your heart as you attempt to read the scroll. You decide it would be a bad idea to read it out loud.
}
}
}
}
private class CallingTimer : Timer
{
private PlayerMobile m_Player;
private int m_Step;
public CallingTimer( PlayerMobile player ) : base( TimeSpan.Zero, TimeSpan.FromSeconds( 1.0 ), 6 )
{
Priority = TimerPriority.TwentyFiveMS;
m_Player = player;
m_Step = 0;
}
protected override void OnTick()
{
if ( m_Player.Deleted )
{
Stop();
return;
}
if ( !m_Player.Mounted )
m_Player.Animate( Utility.RandomBool() ? 16 : 17, 7, 1, true, false, 0 );
if ( m_Step == 4 )
{
int baseX = KronusScroll.m_WellOfTearsArea.X;
int baseY = KronusScroll.m_WellOfTearsArea.Y;
int width = KronusScroll.m_WellOfTearsArea.Width;
int height = KronusScroll.m_WellOfTearsArea.Height;
Map map = KronusScroll.m_WellOfTearsMap;
Effects.SendLocationParticles( EffectItem.Create( m_Player.Location, m_Player.Map, TimeSpan.FromSeconds( 1.0 ) ), 0, 0, 0, 0x13C4 );
Effects.PlaySound( m_Player.Location, m_Player.Map, 0x243 );
for ( int i = 0; i < 15; i++ )
{
int x = baseX + Utility.Random( width );
int y = baseY + Utility.Random( height );
int z = map.GetAverageZ( x, y );
Point3D from = new Point3D( x, y, z + Utility.RandomMinMax( 5, 20 ) );
Point3D to = new Point3D( x, y, z );
int hue = Utility.RandomList( 0x481, 0x482, 0x489, 0x497, 0x66D );
Effects.SendPacket( from, map, new HuedEffect( EffectType.Moving, Serial.Zero, Serial.Zero, 0x36D4, from, to, 0, 0, false, true, hue, 0 ) );
}
}
if ( m_Step < 5 )
{
m_Player.Frozen = true;
}
else // Cast completed
{
m_Player.Frozen = false;
SummonedPaladin.BeginSummon( m_Player );
}
m_Step++;
}
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
}
}
}

View file

@ -0,0 +1,77 @@
using System;
using Server;
using Server.Items;
using Server.Mobiles;
namespace Server.Engines.Quests.Necro
{
public class KronusScrollBox : MetalBox
{
[Constructable]
public KronusScrollBox()
{
ItemID = 0xE80;
Movable = false;
for ( int i = 0; i < 40; i++ )
{
Item scroll = Loot.RandomScroll( 0, 15, SpellbookType.Necromancer );
scroll.Movable = false;
DropItem( scroll );
}
}
public KronusScrollBox( Serial serial ) : base( serial )
{
}
public override void OnDoubleClick( Mobile from )
{
PlayerMobile pm = from as PlayerMobile;
if ( pm != null && pm.InRange( GetWorldLocation(), 2 ) )
{
QuestSystem qs = pm.Quest;
if ( qs is DarkTidesQuest )
{
QuestObjective obj = qs.FindObjective( typeof( FindCallingScrollObjective ) );
if ( (obj != null && !obj.Completed) || DarkTidesQuest.HasLostCallingScroll( from ) )
{
Item scroll = new KronusScroll();
if ( pm.PlaceInBackpack( scroll ) )
{
pm.SendLocalizedMessage( 1060120, "", 0x41 ); // You rummage through the scrolls until you find the Scroll of Calling. You quickly put it in your pack.
if ( obj != null && !obj.Completed )
obj.Complete();
}
else
{
pm.SendLocalizedMessage( 1060148, "", 0x41 ); // You were unable to take the scroll.
scroll.Delete();
}
}
}
}
base.OnDoubleClick( from );
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
}
}
}

View file

@ -0,0 +1,158 @@
using System;
using Server;
using Server.Items;
namespace Server.Engines.Quests.Necro
{
public class MaabusCoffin : BaseAddon
{
private Maabus m_Maabus;
private Point3D m_SpawnLocation;
[CommandProperty( AccessLevel.GameMaster )]
public Maabus Maabus { get { return m_Maabus; } }
[CommandProperty( AccessLevel.GameMaster )]
public Point3D SpawnLocation { get { return m_SpawnLocation; } set { m_SpawnLocation = value; } }
[Constructable]
public MaabusCoffin()
{
AddComponent( new MaabusCoffinComponent( 0x1C2B, 0x1C2B ), -1, -1, 0 );
AddComponent( new MaabusCoffinComponent( 0x1D16, 0x1C2C ), 0, -1, 0 );
AddComponent( new MaabusCoffinComponent( 0x1D17, 0x1C2D ), 1, -1, 0 );
AddComponent( new MaabusCoffinComponent( 0x1D51, 0x1C2E ), 2, -1, 0 );
AddComponent( new MaabusCoffinComponent( 0x1D4E, 0x1C2A ), 0, 0, 0 );
AddComponent( new MaabusCoffinComponent( 0x1D4D, 0x1C29 ), 1, 0, 0 );
AddComponent( new MaabusCoffinComponent( 0x1D4C, 0x1C28 ), 2, 0, 0 );
}
public void Awake( Mobile caller )
{
if ( m_Maabus != null || m_SpawnLocation == Point3D.Zero )
return;
foreach ( MaabusCoffinComponent c in Components )
c.TurnToEmpty();
m_Maabus = new Maabus();
m_Maabus.Location = m_SpawnLocation;
m_Maabus.Map = Map;
m_Maabus.Direction = m_Maabus.GetDirectionTo( caller );
Timer.DelayCall( TimeSpan.FromSeconds( 7.5 ), new TimerCallback( BeginSleep ) );
}
public void BeginSleep()
{
if ( m_Maabus == null )
return;
Effects.PlaySound( m_Maabus.Location, m_Maabus.Map, 0x48E );
Timer.DelayCall( TimeSpan.FromSeconds( 2.5 ), new TimerCallback( Sleep ) );
}
public void Sleep()
{
if ( m_Maabus == null )
return;
Effects.SendLocationParticles( EffectItem.Create( m_Maabus.Location, m_Maabus.Map, EffectItem.DefaultDuration ), 0x3728, 10, 10, 0x7E7 );
Effects.PlaySound( m_Maabus.Location, m_Maabus.Map, 0x1FE );
m_Maabus.Delete();
m_Maabus = null;
foreach ( MaabusCoffinComponent c in Components )
c.TurnToFull();
}
public MaabusCoffin( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 0 ); // version
writer.Write( (Mobile) m_Maabus );
writer.Write( (Point3D) m_SpawnLocation );
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
m_Maabus = reader.ReadMobile() as Maabus;
m_SpawnLocation = reader.ReadPoint3D();
Sleep();
}
}
public class MaabusCoffinComponent : AddonComponent
{
private int m_FullItemID;
private int m_EmptyItemID;
[CommandProperty( AccessLevel.GameMaster )]
public Point3D SpawnLocation
{
get { return Addon is MaabusCoffin ? ((MaabusCoffin)Addon).SpawnLocation : Point3D.Zero; }
set { if ( Addon is MaabusCoffin ) ((MaabusCoffin)Addon).SpawnLocation = value; }
}
public MaabusCoffinComponent( int itemID ) : this( itemID, itemID )
{
}
public MaabusCoffinComponent( int fullItemID, int emptyItemID ) : base( fullItemID )
{
m_FullItemID = fullItemID;
m_EmptyItemID = emptyItemID;
}
public void TurnToEmpty()
{
ItemID = m_EmptyItemID;
}
public void TurnToFull()
{
ItemID = m_FullItemID;
}
public MaabusCoffinComponent( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 0 ); // version
writer.Write( (int) m_FullItemID );
writer.Write( (int) m_EmptyItemID );
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
m_FullItemID = reader.ReadInt();
m_EmptyItemID = reader.ReadInt();
}
}
}

View file

@ -0,0 +1,146 @@
using System;
using Server;
using Server.Items;
using Server.Gumps;
using Server.Mobiles;
using Server.Engines.Quests;
using Server.Engines.Quests.Necro;
namespace Server.Engines.Quests.Necro
{
public class ScrollOfAbraxus : QuestItem
{
public override int LabelNumber { get { return 1028827; } } // Scroll of Abraxus
[Constructable]
public ScrollOfAbraxus() : base( 0x227B )
{
Weight = 1.0;
}
public override bool CanDrop( PlayerMobile player )
{
DarkTidesQuest qs = player.Quest as DarkTidesQuest;
if ( qs == null )
return true;
//return !( qs.IsObjectiveInProgress( typeof( RetrieveAbraxusScrollObjective ) ) || qs.IsObjectiveInProgress( typeof( ReadAbraxusScrollObjective ) ) );
return false;
}
public override void OnAdded(IEntity parent)
{
base.OnAdded( parent );
PlayerMobile pm = RootParent as PlayerMobile;
if ( pm != null )
{
QuestSystem qs = pm.Quest;
if ( qs is DarkTidesQuest )
{
QuestObjective obj = qs.FindObjective( typeof( RetrieveAbraxusScrollObjective ) );
if ( obj != null && !obj.Completed )
obj.Complete();
}
}
}
public override void OnDoubleClick( Mobile from )
{
if ( IsChildOf( from.Backpack ) )
{
from.SendGump( new ScrollOfAbraxusGump() );
PlayerMobile pm = from as PlayerMobile;
if ( pm != null )
{
QuestSystem qs = pm.Quest;
if ( qs is DarkTidesQuest )
{
QuestObjective obj = qs.FindObjective( typeof( ReadAbraxusScrollObjective ) );
if ( obj != null && !obj.Completed )
obj.Complete();
}
}
}
else
{
from.SendLocalizedMessage( 1042001 ); // That must be in your pack for you to use it.
}
}
public ScrollOfAbraxus( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
}
}
public class ScrollOfAbraxusGump : Gump
{
public ScrollOfAbraxusGump() : base( 150, 50 )
{
AddPage( 0 );
AddImage( 0, 0, 1228 );
AddImage( 340, 255, 9005 );
/* Security at the Crystal Cave<BR><BR>
*
* We have taken great measuresto ensure the safety of the
* Scroll of Calling, which we have so valiantly taken from
* the Necromancer Maabus during the battle of the wood
* nearly 200 years ago.<BR><BR>
*
* The scroll must never fall into the hands of the
* Necromancers again, lest they use it to summon the ancient
* daemon Kronus. The scroll of calling is a necessity in the
* series of dark rites the Necromancers must perform to once again
* re-awaken Kronus.<BR><BR>
*
* Should Kronus ever rise again, the days of the Paladins, and
* indeed humanity as we know it will be numbered.<BR><BR>
*
* For this reason, we have posted the honorable Horus, former
* General of the Northern Legions to guard the entrance of the
* Crystal Cave where we keep the Scroll of Calling. Horus was
* infused with magical life from the tree Urywen during his last
* battle. The power gave him eternal life, but it also,
* unfortunately, took his eye sight.<BR><BR>
*
* Since Horus cannot see those he admits to the Crystal Cave,
* he will only allow those that know the secret password to enter.
* Speak the following word to Horus and he shall grant you passage
* to the Crystal Cave:<BR><BR>
*
* <I>Urywen</I><BR><BR>
*
* Do not speak this password anywhere except when seeking passage
* into the Crystal Cave, as our adversaries are lurking in the
* shadows – they are everywhere.<BR><BR>Go with the light, friend.<BR><BR>
*
* <I>- Frater Melkeer</I>
*/
AddHtmlLocalized( 25, 36, 350, 210, 1060116, 1, false, true );
}
}
}

View file

@ -0,0 +1,53 @@
using System;
using Server;
using Server.Items;
using Server.Mobiles;
using Server.Engines.Quests;
using Server.Engines.Quests.Necro;
namespace Server.Engines.Quests.Necro
{
public class VaultOfSecretsBarrier : Item
{
[Constructable]
public VaultOfSecretsBarrier() : base( 0x49E )
{
Movable = false;
Visible = false;
}
public override bool OnMoveOver( Mobile m )
{
if ( m.AccessLevel > AccessLevel.Player )
return true;
PlayerMobile pm = m as PlayerMobile;
if ( pm != null && pm.Profession == 4 )
{
m.SendLocalizedMessage( 1060188, "", 0x24 ); // The wicked may not enter!
return false;
}
return base.OnMoveOver( m );
}
public VaultOfSecretsBarrier( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
}
}
}

View file

@ -0,0 +1,198 @@
using System;
using System.Collections;
using System.Collections.Generic;
using Server;
using Server.Items;
using Server.Mobiles;
using Server.Network;
using Server.ContextMenus;
using Server.Engines.Quests;
using Server.Engines.Quests.Necro;
namespace Server.Engines.Quests.Necro
{
public class Horus : BaseQuester
{
[Constructable]
public Horus() : base( "the Guardian" )
{
}
public override void InitBody()
{
InitStats( 100, 100, 25 );
Hue = 0x83F3;
Body = 0x190;
Name = "Horus";
}
public override void InitOutfit()
{
AddItem( SetHue( new PlateLegs(), 0x849 ) );
AddItem( SetHue( new PlateChest(), 0x849 ) );
AddItem( SetHue( new PlateArms(), 0x849 ) );
AddItem( SetHue( new PlateGloves(), 0x849 ) );
AddItem( SetHue( new PlateGorget(), 0x849 ) );
AddItem( SetHue( new Bardiche(), 0x482 ) );
AddItem( SetHue( new Boots(), 0x001 ) );
AddItem( SetHue( new Cloak(), 0x482 ) );
Utility.AssignRandomHair( this, false );
Utility.AssignRandomFacialHair( this, false );
}
public override int GetAutoTalkRange( PlayerMobile m )
{
return 3;
}
public override bool CanTalkTo( PlayerMobile to )
{
QuestSystem qs = to.Quest;
return ( qs is DarkTidesQuest && qs.IsObjectiveInProgress( typeof( FindCrystalCaveObjective ) ) );
}
public override void OnTalk( PlayerMobile player, bool contextMenu )
{
QuestSystem qs = player.Quest;
if ( qs is DarkTidesQuest )
{
QuestObjective obj = qs.FindObjective( typeof( FindCrystalCaveObjective ) );
if ( obj != null && !obj.Completed )
obj.Complete();
}
}
public override void OnMovement( Mobile m, Point3D oldLocation )
{
base.OnMovement( m, oldLocation );
if ( InRange( m.Location, 2 ) && !InRange( oldLocation, 2 ) && m is PlayerMobile )
{
PlayerMobile pm = (PlayerMobile)m;
QuestSystem qs = pm.Quest;
if ( qs is DarkTidesQuest )
{
QuestObjective obj = qs.FindObjective( typeof( ReturnToCrystalCaveObjective ) );
if ( obj != null && !obj.Completed )
obj.Complete();
else
{
obj = qs.FindObjective( typeof( FindHorusAboutRewardObjective ) );
if ( obj != null && !obj.Completed )
{
Container cont = GetNewContainer();
cont.DropItem( new Gold( 500 ) );
BaseJewel jewel = new GoldBracelet();
if ( Core.AOS )
BaseRunicTool.ApplyAttributesTo( jewel, 3, 20, 40 );
cont.DropItem( jewel );
if ( !pm.PlaceInBackpack( cont ) )
{
cont.Delete();
pm.SendLocalizedMessage( 1046260 ); // You need to clear some space in your inventory to continue with the quest. Come back here when you have more space in your inventory.
}
else
{
obj.Complete();
}
}
}
}
}
}
public override void GetContextMenuEntries( Mobile from, List<ContextMenuEntry> list )
{
base.GetContextMenuEntries( from, list );
if ( from.Alive )
{
PlayerMobile pm = from as PlayerMobile;
if ( pm != null )
{
QuestSystem qs = pm.Quest;
if ( qs is DarkTidesQuest )
{
QuestObjective obj = qs.FindObjective( typeof( SpeakCavePasswordObjective ) );
bool enabled = ( obj != null && !obj.Completed );
list.Add( new SpeakPasswordEntry( this, pm, enabled ) );
}
}
}
}
public virtual void OnPasswordSpoken( PlayerMobile from )
{
QuestSystem qs = from.Quest;
if ( qs is DarkTidesQuest )
{
QuestObjective obj = qs.FindObjective( typeof( SpeakCavePasswordObjective ) );
if ( obj != null && !obj.Completed )
{
obj.Complete();
return;
}
}
from.SendLocalizedMessage( 1060185 ); // Horus ignores you.
}
private class SpeakPasswordEntry : ContextMenuEntry
{
private Horus m_Horus;
private PlayerMobile m_From;
public SpeakPasswordEntry( Horus horus, PlayerMobile from, bool enabled ) : base( 6193, 3 )
{
m_Horus = horus;
m_From = from;
if ( !enabled )
Flags |= CMEFlags.Disabled;
}
public override void OnClick()
{
if ( m_From.Alive )
m_Horus.OnPasswordSpoken( m_From );
}
}
public Horus( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
}
}
}

View file

@ -0,0 +1,47 @@
using System;
using Server;
using Server.Mobiles;
using Server.Items;
namespace Server.Engines.Quests.Necro
{
public class Maabus : BaseQuester
{
public Maabus()
{
}
public override void InitBody()
{
Body = 0x94;
Name = "Maabus";
}
public Maabus( Serial serial ) : base( serial )
{
}
public override bool CanTalkTo( PlayerMobile to )
{
return false;
}
public override void OnTalk( PlayerMobile player, bool contextMenu )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
}
}
}

View file

@ -0,0 +1,230 @@
using System;
using Server;
using Server.Gumps;
using Server.Items;
using Server.Mobiles;
using Server.Engines.Quests;
using Server.Engines.Quests.Necro;
namespace Server.Engines.Quests.Necro
{
public class Mardoth : BaseQuester
{
[Constructable]
public Mardoth() : base( "the Ancient Necromancer" )
{
}
public override void InitBody()
{
InitStats( 100, 100, 25 );
Hue = 0x8849;
Body = 0x190;
Name = "Mardoth";
}
public override bool OnDragDrop( Mobile from, Item dropped )
{
PlayerMobile player = from as PlayerMobile;
if ( player != null )
{
QuestSystem qs = player.Quest;
if ( qs is DarkTidesQuest )
{
if ( dropped is DarkTidesHorn )
{
if ( player.Young )
{
DarkTidesHorn horn = (DarkTidesHorn)dropped;
if ( horn.Charges < 10 )
{
SayTo( from, 1049384 ); // I have recharged the item for you.
horn.Charges = 10;
}
else
{
SayTo( from, 1049385 ); // That doesn't need recharging yet.
}
}
else
{
player.SendLocalizedMessage(1114333); //You must be young to have this item recharged.
}
return false;
}
}
}
return base.OnDragDrop( from, dropped );
}
public override void InitOutfit()
{
AddItem( new Sandals( 0x1 ) );
AddItem( new Robe( 0x66D ) );
AddItem( new BlackStaff() );
AddItem( new WizardsHat( 0x1 ) );
FacialHairItemID = 0x2041;
FacialHairHue = 0x482;
HairItemID = 0x203C;
HairHue = 0x482;
Item gloves = new BoneGloves();
gloves.Hue = 0x66D;
AddItem( gloves );
Item gorget = new PlateGorget();
gorget.Hue = 0x1;
AddItem( gorget );
}
public override int GetAutoTalkRange( PlayerMobile m )
{
return 3;
}
public override bool CanTalkTo( PlayerMobile to )
{
DarkTidesQuest qs = to.Quest as DarkTidesQuest;
if ( qs == null )
return ( to.Quest == null && QuestSystem.CanOfferQuest( to, typeof( DarkTidesQuest ) ) );
return ( qs.FindObjective( typeof( FindMardothAboutVaultObjective ) ) != null );
}
public override void OnTalk( PlayerMobile player, bool contextMenu )
{
QuestSystem qs = player.Quest;
if ( qs is DarkTidesQuest )
{
if ( DarkTidesQuest.HasLostCallingScroll( player ) )
{
qs.AddConversation( new LostCallingScrollConversation( true ) );
}
else
{
QuestObjective obj = qs.FindObjective( typeof( FindMardothAboutVaultObjective ) );
if ( obj != null && !obj.Completed )
{
obj.Complete();
}
else
{
obj = qs.FindObjective( typeof( FindMardothAboutKronusObjective ) );
if ( obj != null && !obj.Completed )
{
obj.Complete();
}
else
{
obj = qs.FindObjective( typeof( FindMardothEndObjective ) );
if ( obj != null && !obj.Completed )
{
Container cont = GetNewContainer();
cont.DropItem( new PigIron( 20 ) );
cont.DropItem( new NoxCrystal( 20 ) );
cont.DropItem( new BatWing( 25 ) );
cont.DropItem( new DaemonBlood( 20 ) );
cont.DropItem( new GraveDust( 20 ) );
BaseWeapon weapon = new BoneHarvester();
weapon.Slayer = SlayerName.OrcSlaying;
if ( Core.AOS )
{
BaseRunicTool.ApplyAttributesTo( weapon, 3, 20, 40 );
}
else
{
weapon.DamageLevel = (WeaponDamageLevel)BaseCreature.RandomMinMaxScaled( 2, 4 );
weapon.AccuracyLevel = (WeaponAccuracyLevel)BaseCreature.RandomMinMaxScaled( 2, 4 );
weapon.DurabilityLevel = (WeaponDurabilityLevel)BaseCreature.RandomMinMaxScaled( 2, 4 );
}
cont.DropItem( weapon );
cont.DropItem( new BankCheck( 2000 ) );
cont.DropItem( new EnchantedSextant() );
if ( !player.PlaceInBackpack( cont ) )
{
cont.Delete();
player.SendLocalizedMessage( 1046260 ); // You need to clear some space in your inventory to continue with the quest. Come back here when you have more space in your inventory.
}
else
{
obj.Complete();
}
}
else if ( contextMenu )
{
FocusTo( player );
player.SendLocalizedMessage( 1061821 ); // Mardoth has nothing more for you at this time.
}
}
}
}
}
else if ( qs == null && QuestSystem.CanOfferQuest( player, typeof( DarkTidesQuest ) ) )
{
new DarkTidesQuest( player ).SendOffer();
}
}
public override void OnMovement( Mobile m, Point3D oldLocation )
{
base.OnMovement( m, oldLocation );
if ( m is PlayerMobile && !m.Frozen && !m.Alive && InRange( m, 4 ) && !InRange( oldLocation, 4 ) && InLOS( m ) )
{
if ( m.Map == null || !m.Map.CanFit( m.Location, 16, false, false ) )
{
m.SendLocalizedMessage( 502391 ); // Thou can not be resurrected there!
}
else
{
Direction = GetDirectionTo( m );
m.PlaySound( 0x214 );
m.FixedEffect( 0x376A, 10, 16 );
m.CloseGump( typeof( ResurrectGump ) );
m.SendGump( new ResurrectGump( m, ResurrectMessage.Healer ) );
}
}
}
public Mardoth( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
}
}
}

View file

@ -0,0 +1,241 @@
using System;
using Server;
using Server.Mobiles;
using Server.Items;
namespace Server.Engines.Quests.Necro
{
public class SummonedPaladin : BaseCreature
{
private PlayerMobile m_Necromancer;
private bool m_ToDelete;
public SummonedPaladin( PlayerMobile necromancer ) : base( AIType.AI_Melee, FightMode.Aggressor, 10, 1, 0.2, 0.4 )
{
m_Necromancer = necromancer;
InitStats( 45, 30, 5 );
Title = "the Paladin";
Hue = 0x83F3;
Female = false;
Body = 0x190;
Name = NameList.RandomName( "male" );
Utility.AssignRandomHair( this );
Utility.AssignRandomFacialHair( this, false );
FacialHairHue = HairHue;
AddItem( new Boots( 0x1 ) );
AddItem( new ChainChest() );
AddItem( new ChainLegs() );
AddItem( new RingmailArms() );
AddItem( new PlateHelm() );
AddItem( new PlateGloves() );
AddItem( new PlateGorget() );
AddItem( new Cloak( 0xCF ) );
AddItem( new ThinLongsword() );
SetSkill( SkillName.Swords, 50.0 );
SetSkill( SkillName.Tactics, 50.0 );
PackGold( 500 );
}
public override bool IsHarmfulCriminal(Mobile target)
{
if ( target == m_Necromancer )
return false;
return base.IsHarmfulCriminal( target );
}
public override bool ClickTitle{ get { return false; } }
public override bool PlayerRangeSensitive{ get { return false; } }
public override void OnThink()
{
if ( !m_ToDelete && !Frozen )
{
if ( m_Necromancer == null || m_Necromancer.Deleted || m_Necromancer.Map == Map.Internal )
{
Delete();
return;
}
if ( Combatant != m_Necromancer )
Combatant = m_Necromancer;
if ( !m_Necromancer.Alive )
{
QuestSystem qs = m_Necromancer.Quest;
if ( qs is DarkTidesQuest && qs.FindObjective( typeof( FindMardothEndObjective ) ) == null )
qs.AddObjective( new FindMardothEndObjective( false ) );
Say( 1060139, m_Necromancer.Name ); // You have made my work easy for me, ~1_NAME~. My task here is done.
m_ToDelete = true;
Timer.DelayCall( TimeSpan.FromSeconds( 5.0 ), new TimerCallback( Delete ) );
}
else if ( m_Necromancer.Map != Map || GetDistanceToSqrt( m_Necromancer ) > RangePerception + 1 )
{
Effects.SendLocationParticles( EffectItem.Create( Location, Map, EffectItem.DefaultDuration ), 0x3728, 10, 10, 2023 );
Effects.SendLocationParticles( EffectItem.Create( m_Necromancer.Location, m_Necromancer.Map, EffectItem.DefaultDuration ), 0x3728, 10, 10, 5023 );
Map = m_Necromancer.Map;
Location = m_Necromancer.Location;
PlaySound( 0x1FE );
Say( 1060140 ); // You cannot escape me, knave of evil!
}
}
base.OnThink();
}
public override void OnDeath( Container c )
{
base.OnDeath( c );
QuestSystem qs = m_Necromancer.Quest;
if ( qs is DarkTidesQuest && qs.FindObjective( typeof( FindMardothEndObjective ) ) == null )
qs.AddObjective( new FindMardothEndObjective( true ) );
}
public SummonedPaladin( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 0 ); // version
writer.Write( (Mobile) m_Necromancer );
writer.Write( (bool) m_ToDelete );
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
m_Necromancer = reader.ReadMobile() as PlayerMobile;
m_ToDelete = reader.ReadBool();
if ( m_ToDelete )
Delete();
}
public static void BeginSummon( PlayerMobile player )
{
new SummonTimer( player ).Start();
}
private class SummonTimer : Timer
{
private PlayerMobile m_Player;
private SummonedPaladin m_Paladin;
private int m_Step;
public SummonTimer( PlayerMobile player ) : base( TimeSpan.FromSeconds( 4.0 ) )
{
Priority = TimerPriority.FiftyMS;
m_Player = player;
}
protected override void OnTick()
{
if ( m_Player.Deleted )
{
if ( m_Step > 0 )
m_Paladin.Delete();
return;
}
if ( m_Step > 0 && m_Paladin.Deleted )
return;
if ( m_Step == 0 )
{
SummonedPaladinMoongate moongate = new SummonedPaladinMoongate();
moongate.MoveToWorld( new Point3D( 2091, 1348, -90 ), Map.Malas );
Effects.PlaySound( moongate.Location, moongate.Map, 0x20E );
m_Paladin = new SummonedPaladin( m_Player );
m_Paladin.Frozen = true;
m_Paladin.Location = moongate.Location;
m_Paladin.Map = moongate.Map;
Delay = TimeSpan.FromSeconds( 2.0 );
Start();
}
else if ( m_Step == 1 )
{
m_Paladin.Direction = m_Paladin.GetDirectionTo( m_Player );
m_Paladin.Say( 1060122 ); // STOP WICKED ONE!
Delay = TimeSpan.FromSeconds( 3.0 );
Start();
}
else
{
m_Paladin.Frozen = false;
m_Paladin.Say( 1060123 ); // I will slay you before I allow you to complete your evil rites!
m_Paladin.Combatant = m_Player;
}
m_Step++;
}
}
}
public class SummonedPaladinMoongate : Item
{
public SummonedPaladinMoongate() : base( 0xF6C )
{
Movable = false;
Hue = 0x482;
Light = LightType.Circle300;
Timer.DelayCall( TimeSpan.FromSeconds( 10.0 ), new TimerCallback( Delete ) );
}
public SummonedPaladinMoongate( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
Delete();
}
}
}

View file

@ -0,0 +1,642 @@
using System;
using Server;
using Server.Items;
using Server.Mobiles;
namespace Server.Engines.Quests.Necro
{
public class AnimateMaabusCorpseObjective : QuestObjective
{
public override object Message
{
get
{
/* Re-animate the corpse of Maabus using your <a href="?ForceTopic112">Animate Dead</a>
* spell and question him about the Kronus rituals.
*/
return 1060102;
}
}
private static QuestItemInfo[] m_Info = new QuestItemInfo[]
{
new QuestItemInfo( 1023643, 8787 ) // spellbook
};
public override QuestItemInfo[] Info{ get{ return m_Info; } }
public AnimateMaabusCorpseObjective()
{
}
public override void OnComplete()
{
System.AddConversation( new MaabasConversation() );
}
}
public class FindCrystalCaveObjective : QuestObjective
{
public override object Message
{
get
{
/* Take the teleporter in the corner of Maabus' tomb to
* the crystal cave where the calling scroll is kept.
*/
return 1060104;
}
}
public FindCrystalCaveObjective()
{
}
public override void OnComplete()
{
System.AddConversation( new HorusConversation() );
}
}
public class FindMardothAboutVaultObjective : QuestObjective
{
public override object Message
{
get
{
/* Infiltrate the city of the Paladins and figure out a way into
* the Vault. See Mardoth for help with this objective.
*/
return 1060106;
}
}
public FindMardothAboutVaultObjective()
{
}
public override void OnComplete()
{
System.AddConversation( new MardothVaultConversation() );
}
}
public class FindMaabusTombObjective : QuestObjective
{
public override object Message
{
get
{
/* Step onto the teleporter near Mardoth and follow the path
* of glowing runes to the tomb of Maabus.
*/
return 1060124;
}
}
public FindMaabusTombObjective()
{
}
public override void CheckProgress()
{
if ( System.From.Map == Map.Malas && System.From.InRange( new Point3D( 2024, 1240, -90 ), 3 ) )
Complete();
}
public override void OnComplete()
{
System.AddObjective( new FindMaabusCorpseObjective() );
}
}
public class FindMaabusCorpseObjective : QuestObjective
{
public override object Message
{
get
{
/* This is the tomb of Maabus. Enter within and find
* the corpse of the ancient necromancer.
*/
return 1061142;
}
}
public FindMaabusCorpseObjective()
{
}
public override void CheckProgress()
{
if ( System.From.Map == Map.Malas && System.From.InRange( new Point3D( 2024, 1223, -90 ), 3 ) )
Complete();
}
public override void OnComplete()
{
System.AddObjective( new AnimateMaabusCorpseObjective() );
}
}
public class FindCityOfLightObjective : QuestObjective
{
public override object Message
{
get
{
/* Use the teleporter near Mardoth to be transported
* to the Paladin City of Light.
*/
return 1060108;
}
}
public FindCityOfLightObjective()
{
}
public override void CheckProgress()
{
if ( System.From.Map == Map.Malas && System.From.InRange( new Point3D( 1076, 519, -90 ), 5 ) )
Complete();
}
public override void OnComplete()
{
System.AddObjective( new FindVaultOfSecretsObjective() );
}
}
public class FindVaultOfSecretsObjective : QuestObjective
{
public override object Message
{
get
{
/* Follow the road paved with glowing runes to
* find the Vault of Secrets. Be careful not
* to give yourself away as a Necromancer while
* in the city.
*/
return 1060109;
}
}
private static QuestItemInfo[] m_Info = new QuestItemInfo[]
{
new QuestItemInfo( 1023676, 3679 ) // glowing rune
};
public override QuestItemInfo[] Info{ get{ return m_Info; } }
public FindVaultOfSecretsObjective()
{
}
public override void CheckProgress()
{
if ( System.From.Map == Map.Malas && System.From.InRange( new Point3D( 1072, 455, -90 ), 1 ) )
Complete();
}
public override void OnComplete()
{
System.AddConversation( new VaultOfSecretsConversation() );
}
}
public class FetchAbraxusScrollObjective : QuestObjective
{
public override object Message
{
get
{
// <a href="?ForceTopic127">Summon your Horde Minion familiar</a> to fetch the scroll for you.
return 1060196;
}
}
public FetchAbraxusScrollObjective()
{
}
public override void CheckProgress()
{
if ( System.From.Map == Map.Malas && System.From.InRange( new Point3D( 1076, 450, -84 ), 5 ) )
{
HordeMinionFamiliar hmf = Spells.Necromancy.SummonFamiliarSpell.Table[System.From] as HordeMinionFamiliar;
if ( hmf != null && hmf.InRange( System.From, 5 ) && hmf.TargetLocation == null )
{
System.From.SendLocalizedMessage( 1060113 ); // You instinctively will your familiar to fetch the scroll for you.
hmf.TargetLocation = new Point2D( 1076, 450 );
}
}
}
public override void OnComplete()
{
System.AddObjective( new RetrieveAbraxusScrollObjective() );
}
}
public class RetrieveAbraxusScrollObjective : QuestObjective
{
public override object Message
{
get
{
/* Double click your Horde Minion to open his pack and retrieve
* the Scroll of Abraxus that he looted for you.
*/
return 1060199;
}
}
public RetrieveAbraxusScrollObjective()
{
}
public override void OnComplete()
{
System.AddConversation( new ReadAbraxusScrollConversation() );
}
}
public class ReadAbraxusScrollObjective : QuestObjective
{
public override object Message
{
get
{
/* Find the Crystal Cave password by reading (double click)
* the golden scroll entitled "Scroll of Abraxus" that you
* got from your familiar..
*/
return 1060125;
}
}
public ReadAbraxusScrollObjective()
{
}
public override void OnComplete()
{
System.AddObjective( new ReturnToCrystalCaveObjective() );
}
}
public class ReturnToCrystalCaveObjective : QuestObjective
{
public override object Message
{
get
{
/* Now that you have the password, return to the Crystal Cave
* to speak with the guard there. Use the teleporter outside
* of the vault to get there if necessary.
*/
return 1060115;
}
}
private static QuestItemInfo[] m_Info = new QuestItemInfo[]
{
new QuestItemInfo( 1026153, 6178 ) // teleporter
};
public override QuestItemInfo[] Info{ get{ return m_Info; } }
public ReturnToCrystalCaveObjective()
{
}
public override void OnComplete()
{
System.AddObjective( new SpeakCavePasswordObjective() );
}
}
public class SpeakCavePasswordObjective : QuestObjective
{
public override object Message
{
get
{
/* Speak the secret word that you read in the scroll
* stolen from the Vault to Horus the guard, using
* his <a href="?ForceTopic90">context menu</a>.
*/
return 1060117;
}
}
public SpeakCavePasswordObjective()
{
}
public override void OnComplete()
{
System.AddConversation( new SecondHorusConversation() );
}
}
public class FindCallingScrollObjective : QuestObjective
{
public override object Message
{
get
{
/* Enter the Crystal Cave and find the Scroll of Calling.
* The barrier will now allow you to pass.
*/
return 1060119;
}
}
private int m_SkitteringHoppersKilled;
private bool m_HealConversationShown;
private bool m_SkitteringHoppersDisposed;
public FindCallingScrollObjective()
{
}
public override bool IgnoreYoungProtection( Mobile from )
{
return !m_SkitteringHoppersDisposed && from is SkitteringHopper;
}
public override bool GetKillEvent( BaseCreature creature, Container corpse )
{
return !m_SkitteringHoppersDisposed;
}
public override void OnKill( BaseCreature creature, Container corpse )
{
if ( creature is SkitteringHopper )
{
if ( !m_HealConversationShown )
{
m_HealConversationShown = true;
System.AddConversation( new HealConversation() );
}
if ( ++m_SkitteringHoppersKilled >= 5 )
{
m_SkitteringHoppersDisposed = true;
System.AddObjective( new FindHorusAboutRewardObjective() );
}
}
}
public override void OnComplete()
{
System.AddObjective( new FindMardothAboutKronusObjective() );
}
public override void ChildDeserialize( GenericReader reader )
{
int version = reader.ReadEncodedInt();
m_SkitteringHoppersKilled = reader.ReadEncodedInt();
m_HealConversationShown = reader.ReadBool();
m_SkitteringHoppersDisposed = reader.ReadBool();
}
public override void ChildSerialize( GenericWriter writer )
{
writer.WriteEncodedInt( (int) 0 ); // version
writer.WriteEncodedInt( (int) m_SkitteringHoppersKilled );
writer.Write( (bool) m_HealConversationShown );
writer.Write( (bool) m_SkitteringHoppersDisposed );
}
}
public class FindHorusAboutRewardObjective : QuestObjective
{
public override object Message
{
get
{
/* You have disposed of the creatures as Horus has asked.
* See him on your way out of the Crystal Cave to claim your reward.
*/
return 1060126;
}
}
public FindHorusAboutRewardObjective()
{
}
public override void OnComplete()
{
System.AddConversation( new HorusRewardConversation() );
}
}
public class FindMardothAboutKronusObjective : QuestObjective
{
public override object Message
{
get
{
/* You have obtained the scroll of calling. See Mardoth
* for further instructions.
*/
return 1060127;
}
}
public FindMardothAboutKronusObjective()
{
}
public override void OnComplete()
{
System.AddConversation( new MardothKronusConversation() );
}
}
public class FindWellOfTearsObjective : QuestObjective
{
public override object Message
{
get
{
/* Follow the red lanterns to the Well of Tears where
* you will perform the calling of Kronus.
*/
return 1060128;
}
}
public FindWellOfTearsObjective()
{
}
private static readonly Rectangle2D m_WellOfTearsArea = new Rectangle2D( 2080, 1346, 10, 10 );
private bool m_Inside;
public override void CheckProgress()
{
if ( System.From.Map == Map.Malas && m_WellOfTearsArea.Contains( System.From.Location ) )
{
if ( DarkTidesQuest.HasLostCallingScroll( System.From ) )
{
if ( !m_Inside )
System.AddConversation( new LostCallingScrollConversation( false ) );
}
else
{
Complete();
}
m_Inside = true;
}
else
{
m_Inside = false;
}
}
public override void OnComplete()
{
System.AddObjective( new UseCallingScrollObjective() );
}
}
public class UseCallingScrollObjective : QuestObjective
{
public override object Message
{
get
{
/* Use the Scroll of Calling (double click) near the
* Well of Tears to charge the waters for the arrival
* of Kronus.
*/
return 1060130;
}
}
public UseCallingScrollObjective()
{
}
}
public class FindMardothEndObjective : QuestObjective
{
private bool m_Victory;
public override object Message
{
get
{
if ( m_Victory )
{
/* Victory! You have done as Mardoth has asked of you.
* Take as much of your foe's loot as you can carry
* and return to Mardoth for your reward.
*/
return 1060131;
}
else
{
/* Although you were slain by the cowardly paladin,
* you managed to complete the rite of calling as
* instructed. Return to Mardoth.
*/
return 1060132;
}
}
}
public FindMardothEndObjective( bool victory )
{
m_Victory = victory;
}
// Serialization
public FindMardothEndObjective()
{
}
public override void OnComplete()
{
System.AddConversation( new MardothEndConversation() );
}
public override void ChildDeserialize( GenericReader reader )
{
int version = reader.ReadEncodedInt();
m_Victory = reader.ReadBool();
}
public override void ChildSerialize( GenericWriter writer )
{
writer.WriteEncodedInt( (int) 0 ); // version
writer.Write( (bool) m_Victory );
}
}
public class FindBankObjective : QuestObjective
{
public override object Message
{
get
{
/* Use the enchanted sextant in your pack to locate
* the nearest bank. Go there and speak with the
* Banker.
*/
return 1060134;
}
}
public FindBankObjective()
{
}
public override void CheckProgress()
{
if ( System.From.Map == Map.Malas && System.From.InRange( new Point3D( 2048, 1345, -84 ), 5 ) )
Complete();
}
public override void OnComplete()
{
System.AddObjective( new CashBankCheckObjective() );
}
}
public class CashBankCheckObjective : QuestObjective
{
public override object Message
{
get
{
/* You have arrived at the Bank. <a href="?ForceTopic38">Open your bank box</a>
* and then <a href="?ForceTopic86">cash the check</a> that Mardoth gave you.
*/
return 1060644;
}
}
public CashBankCheckObjective()
{
}
public override void OnComplete()
{
System.AddConversation( new BankerConversation() );
}
}
}