#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,157 @@
using System;
using Server;
using Server.Mobiles;
using Server.Items;
namespace Server.Engines.Quests.Ambitious
{
public class AmbitiousQueenQuest : QuestSystem
{
private static Type[] m_TypeReferenceTable = new Type[]
{
typeof( Ambitious.DontOfferConversation ),
typeof( Ambitious.AcceptConversation ),
typeof( Ambitious.DuringKillQueensConversation ),
typeof( Ambitious.GatherFungiConversation ),
typeof( Ambitious.DuringFungiGatheringConversation ),
typeof( Ambitious.EndConversation ),
typeof( Ambitious.FullBackpackConversation ),
typeof( Ambitious.End2Conversation ),
typeof( Ambitious.KillQueensObjective ),
typeof( Ambitious.ReturnAfterKillsObjective ),
typeof( Ambitious.GatherFungiObjective ),
typeof( Ambitious.GetRewardObjective )
};
public override Type[] TypeReferenceTable{ get{ return m_TypeReferenceTable; } }
public override object Name
{
get
{
// Ambitious Solen Queen Quest
return 1054146;
}
}
public override object OfferMessage
{
get
{
/* <I>The Solen queen considers you eagerly for a moment then says,</I><BR><BR>
*
* Yes. Yes, I think you could be of use. Normally, of course, I would handle
* these things on my own, but these are busy times. Much to do, much to do.
* And besides, if I am to one day become the Matriarch, then it will be good to
* have experience trusting others to carry out various tasks for me. Yes.<BR><BR>
*
* That is my plan, you see - I will become the next Matriarch. Our current
* Matriarch is fine and all, but she won't be around forever. And when she steps
* down, I intend to be the next in line. Ruling others is my destiny, you see.<BR><BR>
*
* What I ask of you is quite simple. First, I need you to remove some of the
* - well - competition, I suppose. Though I dare say most are hardly competent to
* live up to such a title. I'm referring to the other queens of this colony,
* of course. My dear sisters, so to speak. If you could remove 5 of them, I would
* be most pleased. *sighs* By remove, I mean kill them. Don't make that face
* at me - this is how things work in a proper society, and ours has been more proper
* than most since the dawn of time. It's them or me, and whenever I give it
* any thought, I'm quite sure I'd prefer it to be them.<BR><BR>
*
* I also need you to gather some zoogi fungus for me - 50 should do the trick.<BR><BR>
*
* Will you accept my offer?
*/
return 1054060;
}
}
public override TimeSpan RestartDelay{ get{ return TimeSpan.Zero; } }
public override bool IsTutorial{ get{ return false; } }
public override int Picture{ get{ return 0x15C9; } }
private bool m_RedSolen;
public bool RedSolen{ get{ return m_RedSolen; } }
public AmbitiousQueenQuest( PlayerMobile from, bool redSolen ) : base( from )
{
m_RedSolen = redSolen;
}
// Serialization
public AmbitiousQueenQuest()
{
}
public override void ChildDeserialize( GenericReader reader )
{
int version = reader.ReadEncodedInt();
m_RedSolen = reader.ReadBool();
}
public override void ChildSerialize( GenericWriter writer )
{
writer.WriteEncodedInt( (int) 0 ); // version
writer.Write( (bool) m_RedSolen );
}
public override void Accept()
{
base.Accept();
AddConversation( new AcceptConversation() );
}
public static void GiveRewardTo( PlayerMobile player, ref bool bagOfSending, ref bool powderOfTranslocation, ref bool gold )
{
if ( bagOfSending )
{
Item reward = new BagOfSending();
if ( player.PlaceInBackpack( reward ) )
{
player.SendLocalizedMessage( 1054074, "", 0x59 ); // You have been given a bag of sending.
bagOfSending = false;
}
else
{
reward.Delete();
}
}
if ( powderOfTranslocation )
{
Item reward = new PowderOfTranslocation( Utility.RandomMinMax( 10, 12 ) );
if ( player.PlaceInBackpack( reward ) )
{
player.SendLocalizedMessage( 1054075, "", 0x59 ); // You have been given some powder of translocation.
powderOfTranslocation = false;
}
else
{
reward.Delete();
}
}
if ( gold )
{
Item reward = new Gold( Utility.RandomMinMax( 250, 350 ) );
if ( player.PlaceInBackpack( reward ) )
{
player.SendLocalizedMessage( 1054076, "", 0x59 ); // You have been given some gold.
gold = false;
}
else
{
reward.Delete();
}
}
}
}
}

View file

@ -0,0 +1,274 @@
using System;
using Server;
namespace Server.Engines.Quests.Ambitious
{
public class DontOfferConversation : QuestConversation
{
public override object Message
{
get
{
/* <I>The Solen queen considers you for a moment then says,</I><BR><BR>
*
* Hmmm... I could perhaps benefit from your assistance, but you seem to be
* busy with another task at the moment. Return to me when you complete whatever
* it is that you're working on and maybe I can still put you to good use.
*/
return 1054059;
}
}
public override bool Logged{ get{ return false; } }
public DontOfferConversation()
{
}
}
public class AcceptConversation : QuestConversation
{
public override object Message
{
get
{
/* <I>The Solen queen smiles as you decide to help her.</I><BR><BR>
*
* Excellent. We'll worry about the zoogi fungus later - start by eliminating
* 5 queens from my colony.<BR><BR>That part's important, by the way; they must
* be queens from my colony. Killing queens from the other solen colony does
* little to help me become Matriarch of this colony and will not count
* toward your task.<BR><BR>
*
* Oh, and none of those nasty infiltrator queens either. They perform a necessary
* duty, I suppose, spying on the other colony. I fail to see why that couldn't be
* left totally to the warriors, though. Nevertheless, they do not count as well.<BR><BR>
*
* Very well. Carry on. I'll be waiting for your return.
*/
return 1054061;
}
}
public AcceptConversation()
{
}
public override void OnRead()
{
System.AddObjective( new KillQueensObjective() );
}
}
public class DuringKillQueensConversation : QuestConversation
{
public override object Message
{
get
{
/* <I>The Solen queen looks up as you approach.</I><BR><BR>
*
* You're back, but you have not yet eliminated 5 queens from my colony.
* Return when you have completed this task.<BR><BR>
*
* Remember, by the way, that queens from the other solen colony and
* infiltrator queens do not count toward your task.<BR><BR>
*
* Very well. Carry on. I'll be waiting for your return.
*/
return 1054066;
}
}
public override bool Logged{ get{ return false; } }
public DuringKillQueensConversation()
{
}
}
public class GatherFungiConversation : QuestConversation
{
public override object Message
{
get
{
/* <I>The Solen queen looks pleased to see you.</I><BR><BR>
*
* Splendid! You've done quite well in reducing my competition to become
* the next Matriarch. Now I must ask that you gather some zoogi fungus for me.
* I must practice processing it into powder of translocation.<BR><BR>
*
* I believe the amount we agreed upon earlier was 50. Please return when
* you have that amount and then give them to me.<BR><BR>
*
* Farewell for now.
*/
return 1054068;
}
}
public GatherFungiConversation()
{
}
public override void OnRead()
{
System.AddObjective( new GatherFungiObjective() );
}
}
public class DuringFungiGatheringConversation : QuestConversation
{
public override object Message
{
get
{
/* <I>The Solen queen looks up as you approach.</I><BR><BR>
*
* Do you have the zoogi fungus?<BR><BR>
*
* If so, give them to me. Otherwise, go gather some and then return to me.
*/
return 1054070;
}
}
public override bool Logged{ get{ return false; } }
public DuringFungiGatheringConversation()
{
}
}
public class EndConversation : QuestConversation
{
public override object Message
{
get
{
/* <I>The Solen queen smiles as she takes the zoogi fungus from you.</I><BR><BR>
*
* Wonderful! I greatly appreciate your help with these tasks. My plans are beginning
* to take shape ensuring that I will be the next Matriarch. But there is still
* much to be done until then.<BR><BR>
*
* You've done what I've asked of you and for that I thank you. Please accept this
* bag of sending and some powder of translocation as a reward. Oh, and I suppose
* I should give you some gold as well. Yes, yes. Of course.
*/
return 1054073;
}
}
public EndConversation()
{
}
public override void OnRead()
{
bool bagOfSending = true;
bool powderOfTranslocation = true;
bool gold = true;
AmbitiousQueenQuest.GiveRewardTo( System.From, ref bagOfSending, ref powderOfTranslocation, ref gold );
if ( !bagOfSending && !powderOfTranslocation && !gold )
{
System.Complete();
}
else
{
System.AddConversation( new FullBackpackConversation( true, bagOfSending, powderOfTranslocation, gold ) );
}
}
}
public class FullBackpackConversation : QuestConversation
{
public override object Message
{
get
{
/* <I>The Solen queen looks at you with a smile.</I><BR><BR>
*
* While I'd like to finish conducting our business, it seems that you're a
* bit overloaded with equipment at the moment.<BR><BR>
*
* Perhaps you should free some room in your backpack before we proceed.
*/
return 1054077;
}
}
private bool m_Logged;
private bool m_BagOfSending;
private bool m_PowderOfTranslocation;
private bool m_Gold;
public override bool Logged{ get{ return m_Logged; } }
public FullBackpackConversation( bool logged, bool bagOfSending, bool powderOfTranslocation, bool gold )
{
m_Logged = logged;
m_BagOfSending = bagOfSending;
m_PowderOfTranslocation = powderOfTranslocation;
m_Gold = gold;
}
public FullBackpackConversation()
{
m_Logged = true;
}
public override void OnRead()
{
if ( m_Logged )
System.AddObjective( new GetRewardObjective( m_BagOfSending, m_PowderOfTranslocation, m_Gold ) );
}
public override void ChildDeserialize( GenericReader reader )
{
int version = reader.ReadEncodedInt();
m_BagOfSending = reader.ReadBool();
m_PowderOfTranslocation = reader.ReadBool();
m_Gold = reader.ReadBool();
}
public override void ChildSerialize( GenericWriter writer )
{
writer.WriteEncodedInt( (int) 0 ); // version
writer.Write( (bool) m_BagOfSending );
writer.Write( (bool) m_PowderOfTranslocation );
writer.Write( (bool) m_Gold );
}
}
public class End2Conversation : QuestConversation
{
public override object Message
{
get
{
/* <I>The Solen queen looks up as you approach.</I><BR><BR>
*
* Ah good, you've returned. I will conclude our business by giving you any
* remaining rewards I owe you for aiding me.
*/
return 1054078;
}
}
public End2Conversation()
{
}
public override void OnRead()
{
System.Complete();
}
}
}

View file

@ -0,0 +1,225 @@
using System;
using Server;
using Server.Mobiles;
using Server.Items;
namespace Server.Engines.Quests.Ambitious
{
public abstract class BaseAmbitiousSolenQueen : BaseQuester
{
public abstract bool RedSolen{ get; }
public override bool DisallowAllMoves{ get{ return false; } }
public BaseAmbitiousSolenQueen()
{
}
public override void InitBody()
{
Name = "an ambitious solen queen";
Body = 0x30F;
if ( !RedSolen )
Hue = 0x453;
SpeechHue = 0;
}
public override int GetIdleSound()
{
return 0x10D;
}
public override void OnTalk( PlayerMobile player, bool contextMenu )
{
this.Direction = GetDirectionTo( player );
AmbitiousQueenQuest qs = player.Quest as AmbitiousQueenQuest;
if ( qs != null && qs.RedSolen == this.RedSolen )
{
if ( qs.IsObjectiveInProgress( typeof( KillQueensObjective ) ) )
{
qs.AddConversation( new DuringKillQueensConversation() );
}
else
{
QuestObjective obj = qs.FindObjective( typeof( ReturnAfterKillsObjective ) );
if ( obj != null && !obj.Completed )
{
obj.Complete();
}
else if ( qs.IsObjectiveInProgress( typeof( GatherFungiObjective ) ) )
{
qs.AddConversation( new DuringFungiGatheringConversation() );
}
else
{
GetRewardObjective lastObj = qs.FindObjective( typeof( GetRewardObjective ) ) as GetRewardObjective;
if ( lastObj != null && !lastObj.Completed )
{
bool bagOfSending = lastObj.BagOfSending;
bool powderOfTranslocation = lastObj.PowderOfTranslocation;
bool gold = lastObj.Gold;
AmbitiousQueenQuest.GiveRewardTo( player, ref bagOfSending, ref powderOfTranslocation, ref gold );
lastObj.BagOfSending = bagOfSending;
lastObj.PowderOfTranslocation = powderOfTranslocation;
lastObj.Gold = gold;
if ( !bagOfSending && !powderOfTranslocation && !gold )
{
lastObj.Complete();
}
else
{
qs.AddConversation( new FullBackpackConversation( false, lastObj.BagOfSending, lastObj.PowderOfTranslocation, lastObj.Gold ) );
}
}
}
}
}
else
{
QuestSystem newQuest = new AmbitiousQueenQuest( player, this.RedSolen );
if ( player.Quest == null && QuestSystem.CanOfferQuest( player, typeof( AmbitiousQueenQuest ) ) )
{
newQuest.SendOffer();
}
else
{
newQuest.AddConversation( new DontOfferConversation() );
}
}
}
public override bool OnDragDrop( Mobile from, Item dropped )
{
this.Direction = GetDirectionTo( from );
PlayerMobile player = from as PlayerMobile;
if ( player != null )
{
AmbitiousQueenQuest qs = player.Quest as AmbitiousQueenQuest;
if ( qs != null && qs.RedSolen == this.RedSolen )
{
QuestObjective obj = qs.FindObjective( typeof( GatherFungiObjective ) );
if ( obj != null && !obj.Completed )
{
if ( dropped is ZoogiFungus )
{
ZoogiFungus fungi = (ZoogiFungus)dropped;
if ( fungi.Amount >= 50 )
{
obj.Complete();
fungi.Amount -= 50;
if ( fungi.Amount == 0 )
{
fungi.Delete();
return true;
}
else
{
return false;
}
}
else
{
SayTo( player, 1054072 ); // Our arrangement was for 50 of the zoogi fungus. Please return to me when you have that amount.
return false;
}
}
}
}
}
return base.OnDragDrop( from, dropped );
}
public BaseAmbitiousSolenQueen( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.WriteEncodedInt( (int) 0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadEncodedInt();
}
}
public class RedAmbitiousSolenQueen : BaseAmbitiousSolenQueen
{
public override bool RedSolen{ get{ return true; } }
[Constructable]
public RedAmbitiousSolenQueen()
{
}
public RedAmbitiousSolenQueen( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.WriteEncodedInt( (int) 0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadEncodedInt();
}
}
public class BlackAmbitiousSolenQueen : BaseAmbitiousSolenQueen
{
public override bool RedSolen{ get{ return false; } }
[Constructable]
public BlackAmbitiousSolenQueen()
{
}
public BlackAmbitiousSolenQueen( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.WriteEncodedInt( (int) 0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadEncodedInt();
}
}
}

View file

@ -0,0 +1,175 @@
using System;
using Server;
using Server.Mobiles;
using Server.Items;
namespace Server.Engines.Quests.Ambitious
{
public class KillQueensObjective : QuestObjective
{
public override object Message
{
get
{
// Kill 5 red/black solen queens.
return ((AmbitiousQueenQuest)System).RedSolen ? 1054062 : 1054063;
}
}
public override int MaxProgress{ get{ return 5; } }
public KillQueensObjective()
{
}
public override void RenderProgress( BaseQuestGump gump )
{
if ( !Completed )
{
// Red/Black Solen Queens killed:
gump.AddHtmlLocalized( 70, 260, 270, 100, ((AmbitiousQueenQuest)System).RedSolen ? 1054064 : 1054065, BaseQuestGump.Blue, false, false );
gump.AddLabel( 70, 280, 0x64, CurProgress.ToString() );
gump.AddLabel( 100, 280, 0x64, "/" );
gump.AddLabel( 130, 280, 0x64, MaxProgress.ToString() );
}
else
{
base.RenderProgress( gump );
}
}
public override bool IgnoreYoungProtection( Mobile from )
{
if ( Completed )
return false;
bool redSolen = ((AmbitiousQueenQuest)System).RedSolen;
if ( redSolen )
return from is RedSolenQueen;
else
return from is BlackSolenQueen;
}
public override void OnKill( BaseCreature creature, Container corpse )
{
bool redSolen = ((AmbitiousQueenQuest)System).RedSolen;
if ( redSolen )
{
if ( creature is RedSolenQueen )
CurProgress++;
}
else
{
if ( creature is BlackSolenQueen )
CurProgress++;
}
}
public override void OnComplete()
{
System.AddObjective( new ReturnAfterKillsObjective() );
}
}
public class ReturnAfterKillsObjective : QuestObjective
{
public override object Message
{
get
{
/* You've completed your task of slaying solen queens. Return to
* the ambitious queen who asked for your help.
*/
return 1054067;
}
}
public ReturnAfterKillsObjective()
{
}
public override void OnComplete()
{
System.AddConversation( new GatherFungiConversation() );
}
}
public class GatherFungiObjective : QuestObjective
{
public override object Message
{
get
{
/* Gather zoogi fungus until you have 50 of them, then give them
* to the ambitious queen you are helping.
*/
return 1054069;
}
}
public GatherFungiObjective()
{
}
public override void OnComplete()
{
System.AddConversation( new EndConversation() );
}
}
public class GetRewardObjective : QuestObjective
{
public override object Message
{
get
{
// Return to the ambitious solen queen for your reward.
return 1054148;
}
}
private bool m_BagOfSending;
private bool m_PowderOfTranslocation;
private bool m_Gold;
public bool BagOfSending{ get{ return m_BagOfSending; } set{ m_BagOfSending = value; } }
public bool PowderOfTranslocation{ get{ return m_PowderOfTranslocation; } set{ m_PowderOfTranslocation = value; } }
public bool Gold{ get{ return m_Gold; } set{ m_Gold = value; } }
public GetRewardObjective( bool bagOfSending, bool powderOfTranslocation, bool gold)
{
m_BagOfSending = bagOfSending;
m_PowderOfTranslocation = powderOfTranslocation;
m_Gold = gold;
}
public GetRewardObjective()
{
}
public override void OnComplete()
{
System.AddConversation( new End2Conversation() );
}
public override void ChildDeserialize( GenericReader reader )
{
int version = reader.ReadEncodedInt();
m_BagOfSending = reader.ReadBool();
m_PowderOfTranslocation = reader.ReadBool();
m_Gold = reader.ReadBool();
}
public override void ChildSerialize( GenericWriter writer )
{
writer.WriteEncodedInt( (int) 0 ); // version
writer.Write( (bool) m_BagOfSending );
writer.Write( (bool) m_PowderOfTranslocation );
writer.Write( (bool) m_Gold );
}
}
}

View file

@ -0,0 +1,122 @@
using System;
using Server;
using Server.Items;
using Server.Mobiles;
namespace Server.Engines.Quests.Collector
{
public class CollectorQuest : QuestSystem
{
private static Type[] m_TypeReferenceTable = new Type[]
{
typeof( Collector.DontOfferConversation ),
typeof( Collector.DeclineConversation ),
typeof( Collector.AcceptConversation ),
typeof( Collector.ElwoodDuringFishConversation ),
typeof( Collector.ReturnPearlsConversation ),
typeof( Collector.AlbertaPaintingConversation ),
typeof( Collector.AlbertaStoolConversation ),
typeof( Collector.AlbertaEndPaintingConversation ),
typeof( Collector.AlbertaAfterPaintingConversation ),
typeof( Collector.ElwoodDuringPainting1Conversation ),
typeof( Collector.ElwoodDuringPainting2Conversation ),
typeof( Collector.ReturnPaintingConversation ),
typeof( Collector.GabrielAutographConversation ),
typeof( Collector.GabrielNoSheetMusicConversation ),
typeof( Collector.NoSheetMusicConversation ),
typeof( Collector.GetSheetMusicConversation ),
typeof( Collector.GabrielSheetMusicConversation ),
typeof( Collector.GabrielIgnoreConversation ),
typeof( Collector.ElwoodDuringAutograph1Conversation ),
typeof( Collector.ElwoodDuringAutograph2Conversation ),
typeof( Collector.ElwoodDuringAutograph3Conversation ),
typeof( Collector.ReturnAutographConversation ),
typeof( Collector.TomasToysConversation ),
typeof( Collector.TomasDuringCollectingConversation ),
typeof( Collector.ReturnImagesConversation ),
typeof( Collector.ElwoodDuringToys1Conversation ),
typeof( Collector.ElwoodDuringToys2Conversation ),
typeof( Collector.ElwoodDuringToys3Conversation ),
typeof( Collector.FullEndConversation ),
typeof( Collector.FishPearlsObjective ),
typeof( Collector.ReturnPearlsObjective ),
typeof( Collector.FindAlbertaObjective ),
typeof( Collector.SitOnTheStoolObjective ),
typeof( Collector.ReturnPaintingObjective ),
typeof( Collector.FindGabrielObjective ),
typeof( Collector.FindSheetMusicObjective ),
typeof( Collector.ReturnSheetMusicObjective ),
typeof( Collector.ReturnAutographObjective ),
typeof( Collector.FindTomasObjective ),
typeof( Collector.CaptureImagesObjective ),
typeof( Collector.ReturnImagesObjective ),
typeof( Collector.ReturnToysObjective ),
typeof( Collector.MakeRoomObjective )
};
public override Type[] TypeReferenceTable{ get{ return m_TypeReferenceTable; } }
public override object Name
{
get
{
//return 1020549; // This localized message seems broken...
return "Collector's Quest";
}
}
public override object OfferMessage
{
get
{
/* <I>Elwood greets you warmly, like an old friend he's not
* quite sure he ever had.</I><BR><BR>
*
* Hello. Yes. Sit down. Please. Good. Okay, stand. Up to you.<BR><BR>
*
* So, what brings you to these parts... hey, wait. Just had a thought.
* Would you like to do me a favor? Yes, really. You know, for old
* times sake. The good ole days. You were always one of my best
* suppliers. Or maybe you weren't, who knows any more. Anyway,
* could use some help supplementing my stock. You know me. Always
* looking for something new to add to the collection. Or sometimes
* not so new - just more of the same. But don't have to tell you that.
* You know, don't you. Yes. Just like old times. That's what it'll be.
* You and me - together again. Ah, it's been too long.<BR><BR>
*
* So what do you think? The fee will be the same as always. I'm a fair
* man. You know that. So what do you say?
*/
return 1055081;
}
}
public override TimeSpan RestartDelay{ get{ return TimeSpan.Zero; } }
public override bool IsTutorial{ get{ return false; } }
public override int Picture{ get{ return 0x15A9; } }
public CollectorQuest( PlayerMobile from ) : base( from )
{
}
// Serialization
public CollectorQuest()
{
}
public override void Accept()
{
base.Accept();
AddConversation( new AcceptConversation() );
}
public override void Decline()
{
base.Decline();
AddConversation( new DeclineConversation() );
}
}
}

View file

@ -0,0 +1,874 @@
using System;
using Server;
namespace Server.Engines.Quests.Collector
{
public class DontOfferConversation : QuestConversation
{
public override object Message
{
get
{
/* <I>Elwood looks up from his ale as you greet him.</I><BR><BR>
*
* What's that? Who me? No, no. You must be looking for someone else.
*/
return 1055080;
}
}
public override bool Logged{ get{ return false; } }
public DontOfferConversation()
{
}
}
public class DeclineConversation : QuestConversation
{
public override object Message
{
get
{
/* <I>Elwood looks a bit flustered and nearly knocks over his
* bottle of ale.</I><BR><BR>
*
* Well, I see. It's like that, is it? Yes. Well then. Okay.
* You've changed. Yes. Yes, you have. Something's changed. I know
* I haven't. Not me. Not good ole Elwood.<BR><BR>
*
* <I>Elwood trails off, though you can still hear him muttering softly.</I>
*/
return 1055082;
}
}
public override bool Logged{ get{ return false; } }
public DeclineConversation()
{
}
}
public class AcceptConversation : QuestConversation
{
public override object Message
{
get
{
/* <I>Elwood slaps his knee and grins at you.</I><BR><BR>
*
* Yes. Yes. That's the spirit. I knew it. Knew it when I
* first saw you. You remind me so much of your dear departed
* father. Or someone. Not sure. Maybe no one. But that's okay.
* Ah, good times.<BR><BR>
*
* Anyway, so as you know, I'm a collector. Got all kinds of
* interesting things laying around back at my warehouse.
* You know. You've seen it. Haven't you? Yes? No? Nevermind.
* Not important.<BR><BR>
*
* Right. So, always trying to add new things to my collection.
* Or sometimes just get more of something. Can't have too many.
* Right? Yeah? Sure.<BR><BR>
*
* Let's see. Where to start. Oh, I know. Pearls. Yes. But not
* just any pearls. Rainbow pearls. Yes. From the lake here in
* Haven. Seems all that magic Uzeraan was throwing around when
* he transformed the island had an interesting effect on some
* of the shellfish down there. Exactly, rainbow pearls. Useless
* for magic, but an item worth collecting. Trust me on this.
* Trust me.<BR><BR>
*
* Need you to go fish some up for me. Down at the lake. Lake Haven.
* Off ya go. Happy fishing!<BR><BR>
*
* <I>Elwood turns back to his ale and now seems oblivious to you.</I>
*/
return 1055083;
}
}
public AcceptConversation()
{
}
public override void OnRead()
{
System.AddObjective( new FishPearlsObjective() );
}
}
public class ElwoodDuringFishConversation : QuestConversation
{
public override object Message
{
get
{
/* <I>Elwood looks up as you tap him on the shoulder.</I><BR><BR>
*
* Good. Good. You're back. Wait. You don't have the rainbow pearls I
* need. Taking a break? Yeah. Sure. There's no hurry. Let me know when
* you've got all those pearls, though. I'll be here.
*/
return 1055089;
}
}
public override bool Logged{ get{ return false; } }
public ElwoodDuringFishConversation()
{
}
}
public class ReturnPearlsConversation : QuestConversation
{
public override object Message
{
get
{
/* <I>Elwood jumps slightly when you call his name.</I><BR><BR>
*
* What. I'm awake. Oh, It's you. Hey, look at those pearls.
* Beautiful. Wow. Where'd you get those... oh right. I sent you to get
* them. From the lake. Lake Haven. Great job. Gotta love rainbow
* pearls. Oooh, Colors.<BR><BR>
*
* Okay, let's see. Next. Need a painting. Go to the Colored Canvas and
* speak to Alberta. Alberta Giacco. Best painter I've ever met. Ask
* her to do a painting of you. Yes. Of you. A portrait. Never know if
* you might up and become famous one day. Need to have a painting of you
* in my collection. From now. Before all the fame. Go. Alberta awaits.
* She's in Vesper.<BR><BR>
*
* <I>Elwood starts playing with the pearls you brought him and seems
* to have forgotten you're there.</I>
*/
return 1055090;
}
}
public ReturnPearlsConversation()
{
}
public override void OnRead()
{
System.AddObjective( new FindAlbertaObjective() );
}
}
public class AlbertaPaintingConversation : QuestConversation
{
public override object Message
{
get
{
/* <I>Alberta looks up from the painting she is working on and
* faces you.</I><BR><BR>
*
* Excuse me. I don't mean to be rude, but I'm in the middle
* of something, and can't... oh wait, I see. You must be the one
* Elwood sent over.<BR><BR>
*
* Very well. If you'll have a seat on the stool over there, we'll
* get started. This will just take a few seconds. I paint quite
* quickly, you see. I'll start once you are seated.<BR><BR>
*
* <I>Alberta exchanges the painting she was working on for a blank canvas.</I>
*/
return 1055092;
}
}
public AlbertaPaintingConversation()
{
}
public override void OnRead()
{
System.AddObjective( new SitOnTheStoolObjective() );
}
}
public class AlbertaStoolConversation : QuestConversation
{
public override object Message
{
get
{
/* <I>Alberta looks at you sympathetically.</I><BR><BR>
*
* Don't worry, this will only take a few seconds. I realize
* that stool can be uncomfortable, and I apologize for that.
* Perhaps I should replace it with a more comfortable chair.
* But then again, it's that very discomfort that helps produce
* such wonderful facial expressions for my paintings. Ah well.
*/
return 1055096;
}
}
public override bool Logged{ get{ return false; } }
public AlbertaStoolConversation()
{
}
}
public class AlbertaEndPaintingConversation : QuestConversation
{
public override object Message
{
get
{
/* <I>Alberta stands back from the canvas and surveys her
* work.</I><BR><BR>
*
* Not too bad. Quite good even, if I do say so myself. As always,
* of course.<BR><BR>
*
* Oh, you're still here. Please let Elwood know that the painting
* has been completed. I'll have it sent to him once it dries.<BR><BR>
*
* <I>Alberta removes the portrait from her easel and sets
* it aside to dry.</I>
*/
return 1055098;
}
}
public AlbertaEndPaintingConversation()
{
}
public override void OnRead()
{
System.AddObjective( new ReturnPaintingObjective() );
}
}
public class AlbertaAfterPaintingConversation : QuestConversation
{
public override object Message
{
get
{
/* <I>Alberta stops cleaning her brushes and looks your way.</I><BR><BR>
*
* Don't worry, I'll send the painting to Elwood once it's dry. Please
* let him know that the painting has been finished.
*/
return 1055102;
}
}
public override bool Logged{ get{ return false; } }
public AlbertaAfterPaintingConversation()
{
}
}
public class ElwoodDuringPainting1Conversation : QuestConversation
{
public override object Message
{
get
{
/* <I>Elwood yawns and stretches, then focuses his gaze
* on you.</I><BR><BR>
*
* Hello. Do I know you? Hold on a second. Yes. Yes, I do.
* You were going to bring me some rainbow pearls. Wait. No.
* You already did that. I remember now. Right. So go get that
* portrait painted. Alberta is in Vesper. Go to her. Alberta
* Giacco. Come back when she's done.
*/
return 1055094;
}
}
public override bool Logged{ get{ return false; } }
public ElwoodDuringPainting1Conversation()
{
}
}
public class ElwoodDuringPainting2Conversation : QuestConversation
{
public override object Message
{
get
{
/* <I>Elwood drums his fingers on the counter then looks
* up at you expectantly.</I><BR><BR>
*
* Ah, finally. I'm famished. This so-called tavern doesn't
* even serve pizza, so one must have it delivered. It's an
* outrage. Er... wait. Where's my pizza? Yes, my pizza.
* What kind of delivery is this? Didn't even bring my pizza.
* This will severely impact your tip, I'm afraid.<BR><BR>
*
* Hold on a moment. You were helping me with something else,
* weren't you? Ah. Yes. I've got it now. You were to have a
* portrait done. Well. Good. Yes. But let's not dawdle.
* Off you go. If you happen to see anyone with my pizza,
* please insist they hurry.<BR><BR>
*/
return 1055097;
}
}
public override bool Logged{ get{ return false; } }
public ElwoodDuringPainting2Conversation()
{
}
}
public class ReturnPaintingConversation : QuestConversation
{
public override object Message
{
get
{
/* <I>Elwood notices you immediately and waves you over.</I><BR><BR>
*
* You're back. Good. That's good. Hmm. You don't seem to have that
* painting yet. Don't tell me Alberta refused. That's no good. I made
* her what she is! She was living in the gutter when I found her. The
* gutter. And she has the... what's that? Oh, she finished the portrait.
* Right. Good. Can always count on Alberta. Always. Best painter in
* the land.<BR><BR>
*
* Just have a couple... er... wait... make that... two more task for you.
* Then our business will be concluded. For now. Old chums like us will
* always work together again. Yes. We go so far back. Right. I think.<BR><BR>
*
* Anyway. There's a musician. A minstrel. His name's Gabriel Piete. Quite
* the good singer. One of my favorites. Absolute favorite. What I'd like
* is his autograph. Simple. Just his autograph. You're likely to find him
* at the Conservatory of Music in Britain. He's often there. Often. Between
* performances. Hurry now. There ya go.<BR><BR>
*
* <I>Elwood falls silent though his lips are still moving. It looks like
* he's quietly repeating the word, "autograph."</I>
*/
return 1055100;
}
}
public ReturnPaintingConversation()
{
}
public override void OnRead()
{
System.AddObjective( new FindGabrielObjective() );
}
}
public class GabrielAutographConversation : QuestConversation
{
public override object Message
{
get
{
/* <I>Gabriel sighs loudly as you address him and stops whatever
* it was that he was doing.</I><BR><BR>
*
* WHAT?!? Can you not see that I'm working here? Ugh, sometimes
* I wish they'd just lock the outer doors to anyone who doesn't
* belong here. So go ahead and fawn. Get it over with, and then
* leave. Sooner you're out of here, the sooner I'm back to work.<BR><BR>
*
* I see. So you want an autograph. Fine. If it'll get rid of you,
* I'll give you my autograph. But I'll only sign some sheet music
* for one of my songs. Until then, please let me get back to work.<BR><BR>
*
* You can probably find some of my sheet music at one of the theaters
* in the land. When I perform there, they often sell it as a souvenir.
* Speak to the impresario... the theater manager. My last three
* performances were in Nujel'm, Jhelom, and here in Britian.
*/
return 1055103;
}
}
public GabrielAutographConversation()
{
}
public override void OnRead()
{
System.AddObjective( new FindSheetMusicObjective( true ) );
}
}
public class GabrielNoSheetMusicConversation : QuestConversation
{
public override object Message
{
get
{
/* <I>Gabriel does not look happy to see you.</I><BR><BR>
*
* Do you have any sheet music? No. Please return when you do,
* but until then please leave me to my work.
*/
return 1055111;
}
}
public override bool Logged{ get{ return false; } }
public GabrielNoSheetMusicConversation()
{
}
}
public class NoSheetMusicConversation : QuestConversation
{
public override object Message
{
get
{
/* Sheet music for a Gabriel Piete song? No, I'm sorry, but we've run out.
* We might get some more after he performs here again, but right now
* we don't have any. My apologies.
*/
return 1055106;
}
}
public override bool Logged{ get{ return false; } }
public NoSheetMusicConversation()
{
}
}
public class GetSheetMusicConversation : QuestConversation
{
public override object Message
{
get
{
// The theater impresario hands you some sheet of music for one of Gabriel Piete's songs.
return 1055109;
}
}
public GetSheetMusicConversation()
{
}
public override void OnRead()
{
System.AddObjective( new ReturnSheetMusicObjective() );
}
}
public class GabrielSheetMusicConversation : QuestConversation
{
public override object Message
{
get
{
/* <I>Gabriel looks up impatiently as you approach.</I><BR><BR>
*
* Good. We can finally be done with one another. Here, let me
* sign that and have this business completed.<BR><BR>
*
* <I>Gabriel takes the sheet music, autographs it, and then hands it back to you.</I>
*/
return 1055113;
}
}
public GabrielSheetMusicConversation()
{
}
public override void OnRead()
{
System.AddObjective( new ReturnAutographObjective() );
}
}
public class GabrielIgnoreConversation : QuestConversation
{
public override object Message
{
get
{
// <I>Gabriel ignores you.</I>
return 1055118;
}
}
public override bool Logged{ get{ return false; } }
public GabrielIgnoreConversation()
{
}
}
public class ElwoodDuringAutograph1Conversation : QuestConversation
{
public override object Message
{
get
{
/* <I>Elwood jumps and almost falls from his stool when you
* tap his shoulder.</I><BR><BR>
*
* Oh my. Don't do that. Scared me half to death. Sneaking up on
* people like that. I don't even know you. Yes, I do. I do know you.
* Ordered a pizza from you and never received it. I'm rather miffed
* about that.<BR><BR>
*
* No. No. Wait. Of course. Not the pizza. You're here with the
* moonfire brew I wanted. Magical moonfire brew. Not sure what it is.
* Just want some.<BR><BR>
*
* What's that? Oh. The autograph. Gabriel Piete. Yes. Of course.
* Do you have it? No. Well. Hmm. Don't sneak up on people like that. Not polite.
*/
return 1055105;
}
}
public override bool Logged{ get{ return false; } }
public ElwoodDuringAutograph1Conversation()
{
}
}
public class ElwoodDuringAutograph2Conversation : QuestConversation
{
public override object Message
{
get
{
/* <I>Elwood seems to be studying the bottom of his bottle of ale
* as you approach.</I><BR><BR>
*
* What's this? Strange. Quite strange. I could have sworn I was
* drinking wine.<BR><BR>
*
* Oh, hello. Yes. Good to see you. Any luck with that autograph?
* Bet you thought I'd forgotten. No. Not me. Mind like a steel trap.
* Can't get it open no matter how hard you try. Or something. No luck
* yet? Ah well. keep trying. I have faith in you. Whoever you are.
*/
return 1055112;
}
}
public override bool Logged{ get{ return false; } }
public ElwoodDuringAutograph2Conversation()
{
}
}
public class ElwoodDuringAutograph3Conversation : QuestConversation
{
public override object Message
{
get
{
/* <I>Elwood scratches his ear then notices you.</I><BR><BR>
*
* Good day. What brings you to the Albatross? Me? An autograph?
* You want my autograph? Well, I suppose. What's that? Oh. Yes.
* Gabriel Piete. Yes. Get his autograph and return to me. Good day.
*/
return 1055115;
}
}
public override bool Logged{ get{ return false; } }
public ElwoodDuringAutograph3Conversation()
{
}
}
public class ReturnAutographConversation : QuestConversation
{
public override object Message
{
get
{
/* <I>Elwood looks up eagerly as you tell him about the autographed
* sheet music.</I><BR><BR>
*
* Quite good work. Not an easy one to deal with, that one. Gabriel Piete.
* Yes. Well done. Nice autograph.<BR><BR>
*
* One last task. I would like a set of toy monster figurines made by the
* famous toymaker, Tomas O'Neerlan. You'll find him in Trinsic. He's often
* at the Tinker's Guild. Try looking there.<BR><BR>
*
* You're doing quite well. Quite well indeed. Knew you would. Just like old
* times. Yes. Quite good.
*/
return 1055116;
}
}
public ReturnAutographConversation()
{
}
public override void OnRead()
{
System.AddObjective( new FindTomasObjective() );
}
}
public class TomasToysConversation : QuestConversation
{
public override object Message
{
get
{
/* <I>Tomas smiles freely as you speak to him.</I><BR><BR>
*
* Ah, to be sure I can make you some toy monster figurines.
* That's my work, making toys. Worry not, we'll put together
* a good set of monsters for you and your figurines.<BR><BR>
*
* But I'll be needing something from you before I can begin.
* Here, take these enchanted paints. Using them, you can capture
* a set of images of the creatures you wish me to make into toys.
* It'll only work on the group of creatures I select for your
* set of figurines. Oh, and I'll be needing those enchanted paints
* back when all is said and done.<BR><BR>
*/
return 1055119;
}
}
public TomasToysConversation()
{
}
public override void OnRead()
{
System.AddObjective( new CaptureImagesObjective( true ) );
}
}
public class TomasDuringCollectingConversation : QuestConversation
{
public override object Message
{
get
{
/* <I>Tomas greets you warmly as you approach.</I><BR><BR>
*
* 'Tis good to see you. I see that you have not yet collected
* all of the images we need. 'Tis fine, but I'll be needing
* those before I can make the toy figurines. Return when you have
* the complete set of images.<BR><BR>
*/
return 1055129;
}
}
public override bool Logged{ get{ return false; } }
public TomasDuringCollectingConversation()
{
}
}
public class ReturnImagesConversation : QuestConversation
{
public override object Message
{
get
{
/* <I>Tomas grins as you walk toward him.</I><BR><BR>
*
* I see that you have collected all of the images we need.
* 'Tis good. I'll begin straight away on the toy figurines.
* I'll have them delivered to you when ready. Where shall I send
* them? To Elwood in Haven? Yes, I know him. We've done business
* in the past. Odd fellow.<BR><BR>Tomas smiles as you return his
* enchanted paints back to him.<BR><BR>
*/
return 1055131;
}
}
public ReturnImagesConversation()
{
}
public override void OnRead()
{
System.AddObjective( new ReturnToysObjective() );
}
}
public class ElwoodDuringToys1Conversation : QuestConversation
{
public override object Message
{
get
{
/* <I>You watch as Elwood spins around blissfully on his stool.</I><BR><BR>
*
* Oh. Forgive me. Didn't see you there. Whoo. Dizzy. Can't see straight.
* Have you gotten those figurines yet? No. Ah. Not to worry. Keep at it.
* No doubt you'll come through with those.<BR><BR>
*
* Excuse me a moment. I think I need to sit down. Wait. I am sitting down.
* Good then. Yes. Sitting down.<BR><BR><I>Elwood reaches out and takes hold
* of the counter as if to steady himself.</I>
*/
return 1055123;
}
}
public override bool Logged{ get{ return false; } }
public ElwoodDuringToys1Conversation()
{
}
}
public class ElwoodDuringToys2Conversation : QuestConversation
{
public override object Message
{
get
{
/* <I>Elwood suddenly stops and beckons you over to him.</I><BR><BR>
*
* Over here. Come here. Don't be alarmed, but I think one of the
* tavernkeepers used to be a wandering healer. Said something about
* the good ole days when people would just walk up and hand gold to
* them. Piles of gold. Out of the blue. Can you imagine? Got so much
* gold, this ex-healer decided to buy a tavern and settle down. Kind
* of sad really. Can't even cure my hangover now. Nice tavern though.<BR><BR>
*
* Right. Anyway. Let me know when those toy figurines are ready.
* I'll be here. As always.
*/
return 1055130;
}
}
public override bool Logged{ get{ return false; } }
public ElwoodDuringToys2Conversation()
{
}
}
public class ElwoodDuringToys3Conversation : QuestConversation
{
public override object Message
{
get
{
/* <I>Elwood is singing as you greet him.</I><BR><BR>
*
* Come. Join in. It's a Gabriel Piete song. I have the sheet music
* for it. It's even autographed by Gabriel Piete himself. Yes.
* One of his songs. Brilliant.<BR><BR>
*
* So let me see the toys. Figurines. Let's see them. Oh. You don't
* have them yet. I see. Well. Okay. That's too bad.
*/
return 1055133;
}
}
public override bool Logged{ get{ return false; } }
public ElwoodDuringToys3Conversation()
{
}
}
public class EndConversation : QuestConversation
{
public override object Message
{
get
{
/* <I>Elwood takes a sip of his ale as you address him.</I><BR><BR>
*
* Ah. That's the stuff. Ale. Nothing better. What's that? Toy figurines
* will be delivered. Right. Yes. Perhaps better than Ale. Tough one.<BR><BR>
*
* Very good work. Quite. Think we're all done now. You completed everything
* I asked. Would work with you again. Yes. We should.<BR><BR>
*
* Ah. Yes. your payment. The usual. I think you'll be pleased.<BR><BR>
*
* <I>With that Elwood rummages around in his backpack. He eventually
* pulls out a small bag and hands it to you.</I>
*/
return 1055134;
}
}
public EndConversation()
{
}
public override void OnRead()
{
System.Complete();
}
}
public class FullEndConversation : QuestConversation
{
private bool m_Logged;
public override object Message
{
get
{
/* <I>Elwood stares at you as you approach.</I><BR><BR>
*
* I know you. Oh yes. You've been running some errands for me.
* We are about done. Noticed that your backpack is a bit full.
* Might want to make some room. Won't be able to hold your payment.
* Come back when you have more room, and we'll conclude our business.
*/
return 1055135;
}
}
public override bool Logged{ get{ return m_Logged; } }
public FullEndConversation( bool logged )
{
m_Logged = logged;
}
public FullEndConversation()
{
m_Logged = true;
}
public override void OnRead()
{
if ( m_Logged )
System.AddObjective( new MakeRoomObjective() );
}
}
}

View file

@ -0,0 +1,141 @@
using System;
using Server;
using Server.Mobiles;
using Server.Targeting;
using Server.Engines.Quests;
namespace Server.Engines.Quests.Collector
{
public class EnchantedPaints : QuestItem
{
[Constructable]
public EnchantedPaints() : base( 0xFC1 )
{
LootType = LootType.Blessed;
Weight = 1.0;
}
public EnchantedPaints( Serial serial ) : base( serial )
{
}
public override bool CanDrop( PlayerMobile player )
{
CollectorQuest qs = player.Quest as CollectorQuest;
if ( qs == null )
return true;
/*return !( qs.IsObjectiveInProgress( typeof( CaptureImagesObjective ) )
|| qs.IsObjectiveInProgress( typeof( ReturnImagesObjective ) ) );*/
return false;
}
public override void OnDoubleClick( Mobile from )
{
PlayerMobile player = from as PlayerMobile;
if ( player != null )
{
QuestSystem qs = player.Quest;
if ( qs is CollectorQuest )
{
if ( qs.IsObjectiveInProgress( typeof( CaptureImagesObjective ) ) )
{
player.SendAsciiMessage( 0x59, "Target the creature whose image you wish to create." );
player.Target = new InternalTarget( this );
return;
}
}
}
from.SendLocalizedMessage( 1010085 ); // You cannot use this.
}
private class InternalTarget : Target
{
private EnchantedPaints m_Paints;
public InternalTarget( EnchantedPaints paints ) : base( -1, false, TargetFlags.None )
{
CheckLOS = false;
m_Paints = paints;
}
protected override void OnTarget( Mobile from, object targeted )
{
if ( m_Paints.Deleted || !m_Paints.IsChildOf( from.Backpack ) )
return;
PlayerMobile player = from as PlayerMobile;
if ( player != null )
{
QuestSystem qs = player.Quest;
if ( qs is CollectorQuest )
{
CaptureImagesObjective obj = qs.FindObjective( typeof( CaptureImagesObjective ) ) as CaptureImagesObjective;
if ( obj != null && !obj.Completed )
{
if ( targeted is Mobile )
{
ImageType image;
CaptureResponse response = obj.CaptureImage(( targeted.GetType().Name=="GreaterMongbat" ? new Mongbat().GetType() : targeted.GetType() ), out image );
switch ( response )
{
case CaptureResponse.Valid:
{
player.SendLocalizedMessage( 1055125 ); // The enchanted paints swirl for a moment then an image begins to take shape. *Click*
player.AddToBackpack( new PaintedImage( image ) );
break;
}
case CaptureResponse.AlreadyDone:
{
player.SendAsciiMessage( 0x2C, "You have already captured the image of this creature" );
break;
}
case CaptureResponse.Invalid:
{
player.SendLocalizedMessage( 1055124 ); // You have no interest in capturing the image of this creature.
break;
}
}
}
else
{
player.SendAsciiMessage( 0x35, "You have no interest in that." );
}
return;
}
}
}
from.SendLocalizedMessage( 1010085 ); // You cannot use this.
}
}
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,107 @@
using System;
using System.Collections;
using Server;
using Server.Mobiles;
namespace Server.Engines.Quests.Collector
{
public enum ImageType
{
Betrayer,
Bogling,
BogThing,
Gazer,
Beetle,
GiantBlackWidow,
Scorpion,
JukaMage,
JukaWarrior,
Lich,
MeerMage,
MeerWarrior,
Mongbat,
Mummy,
Pixie,
PlagueBeast,
SandVortex,
StoneGargoyle,
SwampDragon,
Wisp,
Juggernaut
}
public class ImageTypeInfo
{
private static readonly ImageTypeInfo[] m_Table = new ImageTypeInfo[]
{
new ImageTypeInfo( 9734, typeof( Betrayer ), 75, 45 ),
new ImageTypeInfo( 9735, typeof( Bogling ), 75, 45 ),
new ImageTypeInfo( 9736, typeof( BogThing ), 60, 47 ),
new ImageTypeInfo( 9615, typeof( Gazer ), 75, 45 ),
new ImageTypeInfo( 9743, typeof( Beetle ), 60, 55 ),
new ImageTypeInfo( 9667, typeof( GiantBlackWidow ), 55, 52 ),
new ImageTypeInfo( 9657, typeof( Scorpion ), 65, 47 ),
new ImageTypeInfo( 9758, typeof( JukaMage ), 75, 45 ),
new ImageTypeInfo( 9759, typeof( JukaWarrior ), 75, 45 ),
new ImageTypeInfo( 9636, typeof( Lich ), 75, 45 ),
new ImageTypeInfo( 9756, typeof( MeerMage ), 75, 45 ),
new ImageTypeInfo( 9757, typeof( MeerWarrior ), 75, 45 ),
new ImageTypeInfo( 9638, typeof( Mongbat ), 70, 50 ),
new ImageTypeInfo( 9639, typeof( Mummy ), 75, 45 ),
new ImageTypeInfo( 9654, typeof( Pixie ), 75, 45 ),
new ImageTypeInfo( 9747, typeof( PlagueBeast ), 60, 45 ),
new ImageTypeInfo( 9750, typeof( SandVortex ), 60, 43 ),
new ImageTypeInfo( 9614, typeof( StoneGargoyle ), 75, 45 ),
new ImageTypeInfo( 9753, typeof( SwampDragon ), 50, 55 ),
new ImageTypeInfo( 8448, typeof( Wisp ), 75, 45 ),
new ImageTypeInfo( 9746, typeof( Juggernaut ), 55, 38 )
};
public static ImageTypeInfo Get( ImageType image )
{
int index = (int)image;
if ( index >= 0 && index < m_Table.Length )
return m_Table[index];
else
return m_Table[0];
}
public static ImageType[] RandomList( int count )
{
ArrayList list = new ArrayList( m_Table.Length );
for ( int i = 0; i < m_Table.Length; i++ )
list.Add( (ImageType)i );
ImageType[] images = new ImageType[count];
for ( int i = 0; i < images.Length; i++ )
{
int index = Utility.Random( list.Count );
images[i] = (ImageType)list[index];
list.RemoveAt( index );
}
return images;
}
private int m_Figurine;
private Type m_Type;
private int m_X;
private int m_Y;
public int Figurine { get { return m_Figurine; } }
public Type Type { get { return m_Type; } }
public int Name { get { return m_Figurine < 0x4000 ? 1020000 + m_Figurine : 1078872 + m_Figurine; } }
public int X { get { return m_X; } }
public int Y { get { return m_Y; } }
public ImageTypeInfo( int figurine, Type type, int x, int y )
{
m_Figurine = figurine;
m_Type = type;
m_X = x;
m_Y = y;
}
}
}

View file

@ -0,0 +1,264 @@
using System;
using System.Collections;
using System.Collections.Generic;
using Server;
using Server.Network;
using Server.Targeting;
using Server.ContextMenus;
namespace Server.Engines.Quests.Collector
{
public class Obsidian : Item
{
private static readonly string[] m_Names = new string[]
{
null,
"an aggressive cavalier",
"a beguiling rogue",
"a benevolent physician",
"a brilliant artisan",
"a capricious adventurer",
"a clever beggar",
"a convincing charlatan",
"a creative inventor",
"a creative tinker",
"a cunning knave",
"a dauntless explorer",
"a despicable ruffian",
"an earnest malcontent",
"an exultant animal tamer",
"a famed adventurer",
"a fanatical crusader",
"a fastidious clerk",
"a fearless hunter",
"a festive harlequin",
"a fidgety assassin",
"a fierce soldier",
"a fierce warrior",
"a frugal magnate",
"a glib pundit",
"a gnomic shaman",
"a graceful noblewoman",
"a idiotic madman",
"a imaginative designer",
"an inept conjurer",
"an innovative architect",
"an inventive blacksmith",
"a judicious mayor",
"a masterful chef",
"a masterful woodworker",
"a melancholy clown",
"a melodic bard",
"a merciful guard",
"a mirthful jester",
"a nervous surgeon",
"a peaceful scholar",
"a prolific gardener",
"a quixotic knight",
"a regal aristocrat",
"a resourceful smith",
"a reticent alchemist",
"a sanctified priest",
"a scheming patrician",
"a shrewd mage",
"a singing minstrel",
"a skilled tailor",
"a squeamish assassin",
"a stoic swordsman",
"a studious scribe",
"a thought provoking writer",
"a treacherous scoundrel",
"a troubled poet",
"an unflappable wizard",
"a valiant warrior",
"a wayward fool"
};
public static string RandomName( Mobile from )
{
int index = Utility.Random( m_Names.Length );
if ( m_Names[index] == null )
return from.Name;
else
return m_Names[index];
}
private const int m_Partial = 2;
private const int m_Completed = 10;
private int m_Quantity;
private string m_StatueName;
[CommandProperty( AccessLevel.GameMaster )]
public int Quantity
{
get { return m_Quantity; }
set
{
if ( value <= 1 )
m_Quantity = 1;
else if ( value >= m_Completed )
m_Quantity = m_Completed;
else
m_Quantity = value;
if ( m_Quantity < m_Partial )
ItemID = 0x1EA7;
else if ( m_Quantity < m_Completed )
ItemID = 0x1F13;
else
ItemID = 0x12CB;
InvalidateProperties();
}
}
[CommandProperty( AccessLevel.GameMaster )]
public string StatueName
{
get { return m_StatueName; }
set { m_StatueName = value; InvalidateProperties(); }
}
public override bool ForceShowProperties { get { return ObjectPropertyList.Enabled; } }
[Constructable]
public Obsidian() : base( 0x1EA7 )
{
Hue = 0x497;
m_Quantity = 1;
m_StatueName = "";
}
public override void AddNameProperty( ObjectPropertyList list )
{
if ( m_Quantity < m_Partial )
list.Add( 1055137 ); // a section of an obsidian statue
else if ( m_Quantity < m_Completed )
list.Add( 1055138 ); // a partially reconstructed obsidian statue
else
list.Add( 1055139, m_StatueName ); // an obsidian statue of ~1_STATUE_NAME~
}
public override void OnSingleClick( Mobile from )
{
if ( m_Quantity < m_Partial )
LabelTo( from, 1055137 ); // a section of an obsidian statue
else if ( m_Quantity < m_Completed )
LabelTo( from, 1055138 ); // a partially reconstructed obsidian statue
else
LabelTo( from, 1055139, m_StatueName ); // an obsidian statue of ~1_STATUE_NAME~
}
public override void GetContextMenuEntries( Mobile from, List<ContextMenuEntry> list )
{
base.GetContextMenuEntries( from, list );
if ( from.Alive && m_Quantity >= m_Partial && m_Quantity < m_Completed && IsChildOf( from.Backpack ) )
list.Add( new DisassembleEntry( this ) );
}
private class DisassembleEntry : ContextMenuEntry
{
private Obsidian m_Obsidian;
public DisassembleEntry( Obsidian obsidian ) : base( 6142 )
{
m_Obsidian = obsidian;
}
public override void OnClick()
{
Mobile from = Owner.From;
if ( !m_Obsidian.Deleted && m_Obsidian.Quantity >= Obsidian.m_Partial && m_Obsidian.Quantity < Obsidian.m_Completed && m_Obsidian.IsChildOf( from.Backpack ) && from.CheckAlive() )
{
for ( int i = 0; i < m_Obsidian.Quantity - 1; i++ )
from.AddToBackpack( new Obsidian() );
m_Obsidian.Quantity = 1;
}
}
}
public override void OnDoubleClick( Mobile from )
{
if ( m_Quantity < m_Completed )
{
if ( !IsChildOf( from.Backpack ) )
from.Send( new MessageLocalized( Serial, ItemID, MessageType.Regular, 0x2C, 3, 500309, "", "" ) ); // Nothing Happens.
else
from.Target = new InternalTarget( this );
}
}
private class InternalTarget : Target
{
private Obsidian m_Obsidian;
public InternalTarget( Obsidian obsidian ) : base( -1, false, TargetFlags.None )
{
m_Obsidian = obsidian;
}
protected override void OnTarget( Mobile from, object targeted )
{
Item targ = targeted as Item;
if ( m_Obsidian.Deleted || m_Obsidian.Quantity >= Obsidian.m_Completed || targ == null )
return;
if ( m_Obsidian.IsChildOf( from.Backpack ) && targ.IsChildOf( from.Backpack ) && targ is Obsidian && targ != m_Obsidian )
{
Obsidian targObsidian = (Obsidian)targ;
if ( targObsidian.Quantity < Obsidian.m_Completed )
{
if ( targObsidian.Quantity + m_Obsidian.Quantity <= Obsidian.m_Completed )
{
targObsidian.Quantity += m_Obsidian.Quantity;
m_Obsidian.Delete();
}
else
{
int delta = Obsidian.m_Completed - targObsidian.Quantity;
targObsidian.Quantity += delta;
m_Obsidian.Quantity -= delta;
}
if ( targObsidian.Quantity >= Obsidian.m_Completed )
targObsidian.StatueName = Obsidian.RandomName( from );
from.Send( new AsciiMessage( targObsidian.Serial, targObsidian.ItemID, MessageType.Regular, 0x59, 3, m_Obsidian.Name, "Something Happened." ) );
return;
}
}
from.Send( new MessageLocalized( m_Obsidian.Serial, m_Obsidian.ItemID, MessageType.Regular, 0x2C, 3, 500309, m_Obsidian.Name, "" ) ); // Nothing Happens.
}
}
public Obsidian( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 0 ); // version
writer.WriteEncodedInt( m_Quantity );
writer.Write( (string) m_StatueName );
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
m_Quantity = reader.ReadEncodedInt();
m_StatueName = Utility.Intern( reader.ReadString() );
}
}
}

View file

@ -0,0 +1,86 @@
using System;
using Server;
using Server.Gumps;
using Server.Network;
namespace Server.Engines.Quests.Collector
{
public class PaintedImage : Item
{
private ImageType m_Image;
[CommandProperty( AccessLevel.GameMaster )]
public ImageType Image
{
get { return m_Image; }
set { m_Image = value; InvalidateProperties(); }
}
[Constructable]
public PaintedImage( ImageType image ) : base( 0xFF3 )
{
Weight = 1.0;
Hue = 0x8FD;
m_Image = image;
}
public override void AddNameProperty( ObjectPropertyList list )
{
ImageTypeInfo info = ImageTypeInfo.Get( m_Image );
list.Add( 1060847, "#1055126\t#" + info.Name ); // a painted image of:
}
public override void OnSingleClick( Mobile from )
{
ImageTypeInfo info = ImageTypeInfo.Get( m_Image );
LabelTo( from, 1060847, "#1055126\t#" + info.Name ); // a painted image of:
}
public override void OnDoubleClick( Mobile from )
{
if ( !from.InRange( GetWorldLocation(), 2 ) )
{
from.LocalOverheadMessage( MessageType.Regular, 0x3B2, 1019045 ); // I can't reach that.
return;
}
from.SendGump( new InternalGump( m_Image ) );
}
private class InternalGump : Gump
{
public InternalGump( ImageType image ) : base( 75, 25 )
{
ImageTypeInfo info = ImageTypeInfo.Get( image );
AddBackground( 45, 20, 100, 100, 0xA3C );
AddBackground( 52, 29, 86, 82, 0xBB8 );
AddItem( info.X, info.Y, info.Figurine );
}
}
public PaintedImage( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 0 ); // version
writer.WriteEncodedInt( (int) m_Image );
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
m_Image = (ImageType) reader.ReadEncodedInt();
}
}
}

View file

@ -0,0 +1,94 @@
using System;
using Server;
using Server.Mobiles;
using Server.Items;
using Server.Engines.Quests;
namespace Server.Engines.Quests.Collector
{
public class AlbertaGiacco : BaseQuester
{
[Constructable]
public AlbertaGiacco() : base( "the respected painter" )
{
}
public AlbertaGiacco( Serial serial ) : base( serial )
{
}
public override void InitBody()
{
InitStats( 100, 100, 25 );
Hue = 0x83F2;
Female = true;
Body = 0x191;
Name = "Alberta Giacco";
}
public override void InitOutfit()
{
AddItem( new FancyShirt() );
AddItem( new Skirt( 0x59B ) );
AddItem( new Boots() );
AddItem( new FeatheredHat( 0x59B ) );
AddItem( new FullApron( 0x59B ) );
HairItemID = 0x203D; // Pony Tail
HairHue = 0x457;
}
public override bool CanTalkTo( PlayerMobile to )
{
QuestSystem qs = to.Quest as CollectorQuest;
if ( qs == null )
return false;
return ( qs.IsObjectiveInProgress( typeof( FindAlbertaObjective ) )
|| qs.IsObjectiveInProgress( typeof( SitOnTheStoolObjective ) )
|| qs.IsObjectiveInProgress( typeof( ReturnPaintingObjective ) ) );
}
public override void OnTalk( PlayerMobile player, bool contextMenu )
{
QuestSystem qs = player.Quest;
if ( qs is CollectorQuest )
{
Direction = GetDirectionTo( player );
QuestObjective obj = qs.FindObjective( typeof( FindAlbertaObjective ) );
if ( obj != null && !obj.Completed )
{
obj.Complete();
}
else if ( qs.IsObjectiveInProgress( typeof( SitOnTheStoolObjective ) ) )
{
qs.AddConversation( new AlbertaStoolConversation() );
}
else if ( qs.IsObjectiveInProgress( typeof( ReturnPaintingObjective ) ) )
{
qs.AddConversation( new AlbertaAfterPaintingConversation() );
}
}
}
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,243 @@
using System;
using Server;
using Server.Mobiles;
using Server.Items;
using Server.Engines.Quests;
namespace Server.Engines.Quests.Collector
{
public class ElwoodMcCarrin : BaseQuester
{
[Constructable]
public ElwoodMcCarrin() : base( "the well-known collector" )
{
}
public ElwoodMcCarrin( Serial serial ) : base( serial )
{
}
public override void InitBody()
{
InitStats( 100, 100, 25 );
Hue = 0x83ED;
Female = false;
Body = 0x190;
Name = "Elwood McCarrin";
}
public override void InitOutfit()
{
AddItem( new FancyShirt() );
AddItem( new LongPants( 0x544 ) );
AddItem( new Shoes( 0x454 ) );
AddItem( new JesterHat( 0x4D2 ) );
AddItem( new FullApron( 0x4D2 ) );
HairItemID = 0x203D; // Pony Tail
HairHue = 0x47D;
FacialHairItemID = 0x2040; // Goatee
FacialHairHue = 0x47D;
}
public override void OnTalk( PlayerMobile player, bool contextMenu )
{
Direction = GetDirectionTo( player );
QuestSystem qs = player.Quest;
if ( qs is CollectorQuest )
{
if ( qs.IsObjectiveInProgress( typeof( FishPearlsObjective ) ) )
{
qs.AddConversation( new ElwoodDuringFishConversation() );
}
else
{
QuestObjective obj = qs.FindObjective( typeof( ReturnPearlsObjective ) );
if ( obj != null && !obj.Completed )
{
obj.Complete();
}
else if ( qs.IsObjectiveInProgress( typeof( FindAlbertaObjective ) ) )
{
qs.AddConversation( new ElwoodDuringPainting1Conversation() );
}
else if ( qs.IsObjectiveInProgress( typeof( SitOnTheStoolObjective ) ) )
{
qs.AddConversation( new ElwoodDuringPainting2Conversation() );
}
else
{
obj = qs.FindObjective( typeof( ReturnPaintingObjective ) );
if ( obj != null && !obj.Completed )
{
obj.Complete();
}
else if ( qs.IsObjectiveInProgress( typeof( FindGabrielObjective ) ) )
{
qs.AddConversation( new ElwoodDuringAutograph1Conversation() );
}
else if ( qs.IsObjectiveInProgress( typeof( FindSheetMusicObjective ) ) )
{
qs.AddConversation( new ElwoodDuringAutograph2Conversation() );
}
else if ( qs.IsObjectiveInProgress( typeof( ReturnSheetMusicObjective ) ) )
{
qs.AddConversation( new ElwoodDuringAutograph3Conversation() );
}
else
{
obj = qs.FindObjective( typeof( ReturnAutographObjective ) );
if ( obj != null && !obj.Completed )
{
obj.Complete();
}
else if ( qs.IsObjectiveInProgress( typeof( FindTomasObjective ) ) )
{
qs.AddConversation( new ElwoodDuringToys1Conversation() );
}
else if ( qs.IsObjectiveInProgress( typeof( CaptureImagesObjective ) ) )
{
qs.AddConversation( new ElwoodDuringToys2Conversation() );
}
else if ( qs.IsObjectiveInProgress( typeof( ReturnImagesObjective ) ) )
{
qs.AddConversation( new ElwoodDuringToys3Conversation() );
}
else
{
obj = qs.FindObjective( typeof( ReturnToysObjective ) );
if ( obj != null && !obj.Completed )
{
obj.Complete();
if ( GiveReward( player ) )
{
qs.AddConversation( new EndConversation() );
}
else
{
qs.AddConversation( new FullEndConversation( true ) );
}
}
else
{
obj = qs.FindObjective( typeof( MakeRoomObjective ) );
if ( obj != null && !obj.Completed )
{
if ( GiveReward( player ) )
{
obj.Complete();
qs.AddConversation( new EndConversation() );
}
else
{
qs.AddConversation( new FullEndConversation( false ) );
}
}
}
}
}
}
}
}
else
{
QuestSystem newQuest = new CollectorQuest( player );
if ( qs == null && QuestSystem.CanOfferQuest( player, typeof( CollectorQuest ) ) )
{
newQuest.SendOffer();
}
else
{
newQuest.AddConversation( new DontOfferConversation() );
}
}
}
public bool GiveReward( Mobile to )
{
Bag bag = new Bag();
bag.DropItem( new Gold( Utility.RandomMinMax( 500, 1000 ) ) );
if ( Utility.RandomBool() )
{
BaseWeapon weapon = Loot.RandomWeapon();
if ( Core.AOS )
{
BaseRunicTool.ApplyAttributesTo( weapon, 2, 20, 30 );
}
else
{
weapon.DamageLevel = (WeaponDamageLevel)BaseCreature.RandomMinMaxScaled( 2, 3 );
weapon.AccuracyLevel = (WeaponAccuracyLevel)BaseCreature.RandomMinMaxScaled( 2, 3 );
weapon.DurabilityLevel = (WeaponDurabilityLevel)BaseCreature.RandomMinMaxScaled( 2, 3 );
}
bag.DropItem( weapon );
}
else
{
Item item;
if ( Core.AOS )
{
item = Loot.RandomArmorOrShieldOrJewelry();
if ( item is BaseArmor )
BaseRunicTool.ApplyAttributesTo( (BaseArmor)item, 2, 20, 30 );
else if ( item is BaseJewel )
BaseRunicTool.ApplyAttributesTo( (BaseJewel)item, 2, 20, 30 );
}
else
{
BaseArmor armor = Loot.RandomArmorOrShield();
item = armor;
armor.ProtectionLevel = (ArmorProtectionLevel)BaseCreature.RandomMinMaxScaled( 2, 3 );
armor.Durability = (ArmorDurabilityLevel)BaseCreature.RandomMinMaxScaled( 2, 3 );
}
bag.DropItem( item );
}
bag.DropItem( new Obsidian() );
if ( to.PlaceInBackpack( bag ) )
{
return true;
}
else
{
bag.Delete();
return false;
}
}
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,105 @@
using System;
using Server;
using Server.Mobiles;
using Server.Items;
using Server.Engines.Quests;
namespace Server.Engines.Quests.Collector
{
public class GabrielPiete : BaseQuester
{
[Constructable]
public GabrielPiete() : base( "the renowned minstrel" )
{
}
public GabrielPiete( Serial serial ) : base( serial )
{
}
public override void InitBody()
{
InitStats( 100, 100, 25 );
Hue = 0x83EF;
Female = false;
Body = 0x190;
Name = "Gabriel Piete";
}
public override void InitOutfit()
{
AddItem( new FancyShirt() );
AddItem( new LongPants( 0x5F7 ) );
AddItem( new Shoes( 0x5F7 ) );
HairItemID = 0x2049; // Pig Tails
HairHue = 0x460;
FacialHairItemID = 0x2041; // Mustache
FacialHairHue = 0x460;
}
public override bool CanTalkTo( PlayerMobile to )
{
QuestSystem qs = to.Quest as CollectorQuest;
if ( qs == null )
return false;
return ( qs.IsObjectiveInProgress( typeof( FindGabrielObjective ) )
|| qs.IsObjectiveInProgress( typeof( FindSheetMusicObjective ) )
|| qs.IsObjectiveInProgress( typeof( ReturnSheetMusicObjective ) )
|| qs.IsObjectiveInProgress( typeof( ReturnAutographObjective ) ) );
}
public override void OnTalk( PlayerMobile player, bool contextMenu )
{
QuestSystem qs = player.Quest;
if ( qs is CollectorQuest )
{
Direction = GetDirectionTo( player );
QuestObjective obj = qs.FindObjective( typeof( FindGabrielObjective ) );
if ( obj != null && !obj.Completed )
{
obj.Complete();
}
else if ( qs.IsObjectiveInProgress( typeof( FindSheetMusicObjective ) ) )
{
qs.AddConversation( new GabrielNoSheetMusicConversation() );
}
else
{
obj = qs.FindObjective( typeof( ReturnSheetMusicObjective ) );
if ( obj != null && !obj.Completed )
{
obj.Complete();
}
else if ( qs.IsObjectiveInProgress( typeof( ReturnAutographObjective ) ) )
{
qs.AddConversation( new GabrielIgnoreConversation() );
}
}
}
}
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,175 @@
using System;
using Server;
using Server.Mobiles;
using Server.Items;
using Server.Gumps;
using Server.Network;
using Server.Engines.Quests;
namespace Server.Engines.Quests.Collector
{
public class Impresario : BaseQuester
{
[Constructable]
public Impresario() : base( "the impresario" )
{
}
public Impresario( Serial serial ) : base( serial )
{
}
public override void InitBody()
{
InitStats( 100, 100, 25 );
Hue = Utility.RandomSkinHue();
Female = false;
Body = 0x190;
Name = NameList.RandomName( "male" );
}
public override void InitOutfit()
{
AddItem( new FancyShirt( Utility.RandomDyedHue() ) );
AddItem( new LongPants( Utility.RandomNondyedHue() ) );
AddItem( new Shoes( Utility.RandomNeutralHue() ) );
Utility.AssignRandomHair( this );
Utility.AssignRandomFacialHair( this );
}
public override bool CanTalkTo( PlayerMobile to )
{
QuestSystem qs = to.Quest as CollectorQuest;
if ( qs == null )
return false;
return qs.IsObjectiveInProgress( typeof( FindSheetMusicObjective ) );
}
public override void OnTalk( PlayerMobile player, bool contextMenu )
{
QuestSystem qs = player.Quest;
if ( qs is CollectorQuest )
{
FindSheetMusicObjective obj = qs.FindObjective( typeof( FindSheetMusicObjective ) ) as FindSheetMusicObjective;
if ( obj != null && !obj.Completed )
{
Direction = GetDirectionTo( player );
if ( obj.IsInRightTheater() )
{
player.CloseGump( typeof( SheetMusicOfferGump ) );
player.SendGump( new SheetMusicOfferGump() );
}
else
{
qs.AddConversation( new NoSheetMusicConversation() );
}
}
}
}
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 SheetMusicOfferGump : BaseQuestGump
{
public SheetMusicOfferGump() : base( 75, 25 )
{
Closable = false;
AddImage( 349, 10, 0x24B0 );
AddImageTiled( 349, 130, 100, 120, 0x24B3 );
AddImageTiled( 149, 10, 200, 140, 0x24AF );
AddImageTiled( 149, 300, 200, 140, 0x24B5 );
AddImage( 349, 300, 0x24B6 );
AddImage( 35, 10, 0x24AE );
AddImageTiled( 35, 150, 120, 100, 0x24B1 );
AddImage( 35, 300, 0x24B4 );
AddHtmlLocalized( 110, 60, 200, 20, 1049069, White, false, false ); // <STRONG>Conversation Event</STRONG>
AddImage( 65, 14, 0x2776 );
AddImageTiled( 81, 14, 349, 17, 0x2775 );
AddImage( 426, 14, 0x2778 );
AddImageTiled( 50, 37, 400, 376, 0xA40 );
AddAlphaRegion( 50, 37, 400, 376 );
AddImage( 0, 0, 0x28C8 );
AddImageTiled( 75, 90, 200, 1, 0x238D );
AddImage( 75, 58, 0x2635 );
AddImage( 380, 45, 0xDF );
AddHtmlLocalized( 98, 140, 312, 200, 1055107, LightGreen, false, true ); // Sure, I have some sheet music for a Gabriel Piete song. I'd be happy to sell you a copy for 10 gold.
AddRadio( 85, 350, 0x25F8, 0x25FB, true, 1 );
AddHtmlLocalized( 120, 356, 280, 20, 1014088, White, false, false ); // I accept.
AddRadio( 85, 385, 0x25F8, 0x25FB, false, 0 );
AddHtmlLocalized( 120, 391, 280, 20, 1049012, White, false, false ); // No thanks, I decline.
AddButton( 340, 390, 0xF7, 0xF8, 1, GumpButtonType.Reply, 0 );
}
public override void OnResponse( NetState sender, RelayInfo info )
{
if ( info.ButtonID == 1 && info.IsSwitched( 1 ) )
{
PlayerMobile player = sender.Mobile as PlayerMobile;
if ( player != null )
{
QuestSystem qs = player.Quest;
if ( qs is CollectorQuest )
{
FindSheetMusicObjective obj = qs.FindObjective( typeof( FindSheetMusicObjective ) ) as FindSheetMusicObjective;
if ( obj != null && !obj.Completed )
{
if ( player.Backpack!= null && player.Backpack.ConsumeTotal( typeof( Gold ), 10 ) )
{
obj.Complete();
}
else
{
BankBox bank = player.FindBankNoCreate();
if ( bank != null && bank.ConsumeTotal( typeof( Gold ), 10 ) )
{
obj.Complete();
}
else
{
player.SendLocalizedMessage( 1055108 ); // You don't have enough gold to buy the sheet music.
}
}
}
}
}
}
}
}
}

View file

@ -0,0 +1,111 @@
using System;
using Server;
using Server.Mobiles;
using Server.Items;
using Server.Engines.Quests;
namespace Server.Engines.Quests.Collector
{
public class TomasONeerlan : BaseQuester
{
[Constructable]
public TomasONeerlan() : base( "the famed toymaker" )
{
}
public TomasONeerlan( Serial serial ) : base( serial )
{
}
public override void InitBody()
{
InitStats( 100, 100, 25 );
Hue = 0x83F8;
Female = false;
Body = 0x190;
Name = "Tomas O'Neerlan";
}
public override void InitOutfit()
{
AddItem( new FancyShirt() );
AddItem( new LongPants( 0x546 ) );
AddItem( new Boots( 0x452 ) );
AddItem( new FullApron( 0x455 ) );
HairItemID = 0x203B; //ShortHair
HairHue = 0x455;
}
public override bool CanTalkTo( PlayerMobile to )
{
QuestSystem qs = to.Quest as CollectorQuest;
if ( qs == null )
return false;
return ( qs.IsObjectiveInProgress( typeof( FindTomasObjective ) )
|| qs.IsObjectiveInProgress( typeof( CaptureImagesObjective ) )
|| qs.IsObjectiveInProgress( typeof( ReturnImagesObjective ) ) );
}
public override void OnTalk( PlayerMobile player, bool contextMenu )
{
QuestSystem qs = player.Quest;
if ( qs is CollectorQuest )
{
Direction = GetDirectionTo( player );
QuestObjective obj = qs.FindObjective( typeof( FindTomasObjective ) );
if ( obj != null && !obj.Completed )
{
Item paints = new EnchantedPaints();
if ( !player.PlaceInBackpack( paints ) )
{
paints.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 ( qs.IsObjectiveInProgress( typeof( CaptureImagesObjective ) ) )
{
qs.AddConversation( new TomasDuringCollectingConversation() );
}
else
{
obj = qs.FindObjective( typeof( ReturnImagesObjective ) );
if ( obj != null && !obj.Completed )
{
if ( player.Backpack != null )
player.Backpack.ConsumeUpTo( typeof( EnchantedPaints ), 1 );
obj.Complete();
}
}
}
}
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,533 @@
using System;
using Server;
using Server.Mobiles;
namespace Server.Engines.Quests.Collector
{
public class FishPearlsObjective : QuestObjective
{
public override object Message
{
get
{
// Fish up shellfish from Lake Haven and collect rainbow pearls.
return 1055084;
}
}
public override int MaxProgress{ get{ return 6; } }
public FishPearlsObjective()
{
}
public override void RenderProgress( BaseQuestGump gump )
{
if ( !Completed )
{
// Rainbow pearls collected:
gump.AddHtmlObject( 70, 260, 270, 100, 1055085, BaseQuestGump.Blue, false, false );
gump.AddLabel( 70, 280, 0x64, CurProgress.ToString() );
gump.AddLabel( 100, 280, 0x64, "/" );
gump.AddLabel( 130, 280, 0x64, MaxProgress.ToString() );
}
else
{
base.RenderProgress( gump );
}
}
public override void OnComplete()
{
System.AddObjective( new ReturnPearlsObjective() );
}
}
public class ReturnPearlsObjective : QuestObjective
{
public override object Message
{
get
{
/* You've collected enough rainbow pearls. Speak to
* Elwood to give them to him and get your next task.
*/
return 1055088;
}
}
public ReturnPearlsObjective()
{
}
public override void OnComplete()
{
System.AddConversation( new ReturnPearlsConversation() );
}
}
public class FindAlbertaObjective : QuestObjective
{
public override object Message
{
get
{
// Go to Vesper and speak to Alberta Giacco at the Colored Canvas.
return 1055091;
}
}
public FindAlbertaObjective()
{
}
public override void OnComplete()
{
System.AddConversation( new AlbertaPaintingConversation() );
}
}
public class SitOnTheStoolObjective : QuestObjective
{
private static readonly Point3D m_StoolLocation = new Point3D( 2899, 706, 0 );
private static readonly Map m_StoolMap = Map.Trammel;
private DateTime m_Begin;
public override object Message
{
get
{
/* Sit on the stool in front of Alberta's easel so that she can
* paint your portrait. You'll need to sit there for about 30 seconds.
*/
return 1055093;
}
}
public SitOnTheStoolObjective()
{
m_Begin = DateTime.MaxValue;
}
public override void CheckProgress()
{
PlayerMobile pm = System.From;
if ( pm.Map == m_StoolMap && pm.Location == m_StoolLocation )
{
if ( m_Begin == DateTime.MaxValue )
{
m_Begin = DateTime.UtcNow;
}
else if ( DateTime.UtcNow - m_Begin > TimeSpan.FromSeconds( 30.0 ) )
{
Complete();
}
}
else if ( m_Begin != DateTime.MaxValue )
{
m_Begin = DateTime.MaxValue;
pm.SendLocalizedMessage( 1055095, "", 0x26 ); // You must remain seated on the stool until the portrait is complete. Alberta will now have to start again with a fresh canvas.
}
}
public override void OnComplete()
{
System.AddConversation( new AlbertaEndPaintingConversation() );
}
}
public class ReturnPaintingObjective : QuestObjective
{
public override object Message
{
get
{
// Return to Elwood and let him know that the painting is complete.
return 1055099;
}
}
public ReturnPaintingObjective()
{
}
public override void OnComplete()
{
System.AddConversation( new ReturnPaintingConversation() );
}
}
public class FindGabrielObjective : QuestObjective
{
public override object Message
{
get
{
/* Go to Britain and obtain the autograph of renowned
* minstrel, Gabriel Piete. He is often found at the Conservatory of Music.
*/
return 1055101;
}
}
public FindGabrielObjective()
{
}
public override void OnComplete()
{
System.AddConversation( new GabrielAutographConversation() );
}
}
public enum Theater
{
Britain,
Nujelm,
Jhelom
}
public class FindSheetMusicObjective : QuestObjective
{
private Theater m_Theater;
public override object Message
{
get
{
/* Find some sheet music for one of Gabriel's songs.
* Try speaking to an impresario from one of the theaters in the land.
*/
return 1055104;
}
}
public FindSheetMusicObjective( bool init )
{
if ( init )
InitTheater();
}
public FindSheetMusicObjective()
{
}
public void InitTheater()
{
switch ( Utility.Random( 3 ) )
{
case 1: m_Theater = Theater.Britain; break;
case 2: m_Theater = Theater.Nujelm; break;
default: m_Theater = Theater.Jhelom; break;
}
}
public bool IsInRightTheater()
{
PlayerMobile player = System.From;
Region region = Region.Find( player.Location, player.Map );
if ( region == null )
return false;
switch ( m_Theater )
{
case Theater.Britain: return region.IsPartOf( "Britain" );
case Theater.Nujelm: return region.IsPartOf( "Nujel'm" );
case Theater.Jhelom: return region.IsPartOf( "Jhelom" );
default: return false;
}
}
public override void OnComplete()
{
System.AddConversation( new GetSheetMusicConversation() );
}
public override void ChildDeserialize( GenericReader reader )
{
int version = reader.ReadEncodedInt();
m_Theater = (Theater) reader.ReadEncodedInt();
}
public override void ChildSerialize( GenericWriter writer )
{
writer.WriteEncodedInt( (int) 0 ); // version
writer.WriteEncodedInt( (int) m_Theater );
}
}
public class ReturnSheetMusicObjective : QuestObjective
{
public override object Message
{
get
{
// Speak to Gabriel to have him autograph the sheet music.
return 1055110;
}
}
public ReturnSheetMusicObjective()
{
}
public override void OnComplete()
{
System.AddConversation( new GabrielSheetMusicConversation() );
}
}
public class ReturnAutographObjective : QuestObjective
{
public override object Message
{
get
{
// Speak to Elwood to give him the autographed sheet music.
return 1055114;
}
}
public ReturnAutographObjective()
{
}
public override void OnComplete()
{
System.AddConversation( new ReturnAutographConversation() );
}
}
public class FindTomasObjective : QuestObjective
{
public override object Message
{
get
{
// Go to Trinsic and speak to Tomas O'Neerlan, the famous toymaker.
return 1055117;
}
}
public FindTomasObjective()
{
}
public override void OnComplete()
{
System.AddConversation( new TomasToysConversation() );
}
}
public enum CaptureResponse
{
Valid,
AlreadyDone,
Invalid
}
public class CaptureImagesObjective : QuestObjective
{
private ImageType[] m_Images;
private bool[] m_Done;
public override object Message
{
get
{
// Use the enchanted paints to capture the image of all of the creatures listed below.
return 1055120;
}
}
public override bool Completed
{
get
{
for ( int i = 0; i < m_Done.Length; i++ )
{
if ( !m_Done[i] )
return false;
}
return true;
}
}
public CaptureImagesObjective( bool init )
{
if ( init )
{
m_Images = ImageTypeInfo.RandomList( 4 );
m_Done = new bool[4];
}
}
public CaptureImagesObjective()
{
}
public override bool IgnoreYoungProtection( Mobile from )
{
if ( Completed )
return false;
Type fromType = from.GetType();
for ( int i = 0; i < m_Images.Length; i++ )
{
ImageTypeInfo info = ImageTypeInfo.Get( m_Images[i] );
if ( info.Type == fromType )
return true;
}
return false;
}
public CaptureResponse CaptureImage( Type type, out ImageType image )
{
for ( int i = 0; i < m_Images.Length; i++ )
{
ImageTypeInfo info = ImageTypeInfo.Get( m_Images[i] );
if ( info.Type == type )
{
image = m_Images[i];
if ( m_Done[i] )
{
return CaptureResponse.AlreadyDone;
}
else
{
m_Done[i] = true;
CheckCompletionStatus();
return CaptureResponse.Valid;
}
}
}
image = (ImageType)0;
return CaptureResponse.Invalid;
}
public override void RenderProgress( BaseQuestGump gump )
{
if ( !Completed )
{
for ( int i = 0; i < m_Images.Length; i++ )
{
ImageTypeInfo info = ImageTypeInfo.Get( m_Images[i] );
gump.AddHtmlObject( 70, 260 + 20 * i, 200, 100, info.Name, BaseQuestGump.Blue, false, false );
gump.AddLabel( 200, 260 + 20 * i, 0x64, " : " );
gump.AddHtmlObject( 220, 260 + 20 * i, 100, 100, m_Done[i] ? 1055121 : 1055122, BaseQuestGump.Blue, false, false );
}
}
else
{
base.RenderProgress( gump );
}
}
public override void OnComplete()
{
System.AddObjective( new ReturnImagesObjective() );
}
public override void ChildDeserialize( GenericReader reader )
{
int version = reader.ReadEncodedInt();
int count = reader.ReadEncodedInt();
m_Images = new ImageType[count];
m_Done = new bool[count];
for ( int i = 0; i < count; i++ )
{
m_Images[i] = (ImageType) reader.ReadEncodedInt();
m_Done[i] = reader.ReadBool();
}
}
public override void ChildSerialize( GenericWriter writer )
{
writer.WriteEncodedInt( (int) 0 ); // version
writer.WriteEncodedInt( (int) m_Images.Length );
for ( int i = 0; i < m_Images.Length; i++ )
{
writer.WriteEncodedInt( (int) m_Images[i] );
writer.Write( (bool) m_Done[i] );
}
}
}
public class ReturnImagesObjective : QuestObjective
{
public override object Message
{
get
{
/* You now have all of the creature images you need.
* Return to Tomas O'Neerlan so that he can make the toy figurines.
*/
return 1055128;
}
}
public ReturnImagesObjective()
{
}
public override void OnComplete()
{
System.AddConversation( new ReturnImagesConversation() );
}
}
public class ReturnToysObjective : QuestObjective
{
public override object Message
{
get
{
// Return to Elwood with news that the toy figurines will be delivered when ready.
return 1055132;
}
}
public ReturnToysObjective()
{
}
}
public class MakeRoomObjective : QuestObjective
{
public override object Message
{
get
{
// Return to Elwood for your reward when you have some room in your backpack.
return 1055136;
}
}
public MakeRoomObjective()
{
}
}
}

View file

@ -0,0 +1,128 @@
using System;
using System.Collections;
using System.Collections.Generic;
using Server;
using Server.Items;
using Server.Mobiles;
using Server.ContextMenus;
namespace Server.Engines.Quests
{
public class TalkEntry : ContextMenuEntry
{
private BaseQuester m_Quester;
public TalkEntry( BaseQuester quester ) : base( quester.TalkNumber )
{
m_Quester = quester;
}
public override void OnClick()
{
Mobile from = Owner.From;
if ( from.CheckAlive() && from is PlayerMobile && m_Quester.CanTalkTo( (PlayerMobile)from ) )
m_Quester.OnTalk( (PlayerMobile)from, true );
}
}
public abstract class BaseQuester : BaseVendor
{
protected List<SBInfo> m_SBInfos = new List<SBInfo>();
protected override List<SBInfo> SBInfos{ get { return m_SBInfos; } }
public override bool IsActiveVendor{ get{ return false; } }
public override bool IsInvulnerable{ get{ return true; } }
public override bool DisallowAllMoves{ get{ return true; } }
public override bool ClickTitle{ get { return false; } }
public override bool CanTeach{ get{ return false; } }
public virtual int TalkNumber{ get{ return 6146; } } // Talk
public override void InitSBInfo()
{
}
public BaseQuester() : this( null )
{
}
public BaseQuester( string title ) : base( title )
{
}
public BaseQuester( Serial serial ) : base( serial )
{
}
public abstract void OnTalk( PlayerMobile player, bool contextMenu );
public virtual bool CanTalkTo( PlayerMobile to )
{
return true;
}
public virtual int GetAutoTalkRange( PlayerMobile m )
{
return -1;
}
public override bool CanBeDamaged()
{
return false;
}
protected Item SetHue( Item item, int hue )
{
item.Hue = hue;
return item;
}
public override void AddCustomContextEntries( Mobile from, List<ContextMenuEntry> list )
{
base.AddCustomContextEntries( from, list );
if ( from.Alive && from is PlayerMobile && TalkNumber > 0 && CanTalkTo( (PlayerMobile)from ) )
list.Add( new TalkEntry( this ) );
}
public override void OnMovement( Mobile m, Point3D oldLocation )
{
if ( m.Alive && m is PlayerMobile )
{
PlayerMobile pm = (PlayerMobile)m;
int range = GetAutoTalkRange( pm );
if ( m.Alive && range >= 0 && InRange( m, range ) && !InRange( oldLocation, range ) && CanTalkTo( pm ) )
OnTalk( pm, false );
}
}
public void FocusTo( Mobile to )
{
QuestSystem.FocusTo( this, to );
}
public static Container GetNewContainer()
{
Bag bag = new Bag();
bag.Hue = QuestSystem.RandomBrightHue();
return bag;
}
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,70 @@
using System;
using Server;
using Server.Mobiles;
namespace Server.Engines.Quests
{
public abstract class DynamicTeleporter : Item
{
public override int LabelNumber{ get{ return 1049382; } } // a magical teleporter
public DynamicTeleporter() : this( 0x1822, 0x482 )
{
}
public DynamicTeleporter( int itemID, int hue ) : base( itemID )
{
Movable = false;
Hue = hue;
}
public abstract bool GetDestination( PlayerMobile player, ref Point3D loc, ref Map map );
public virtual int NotWorkingMessage{ get{ return 500309; } } // Nothing Happens.
public override bool OnMoveOver( Mobile m )
{
PlayerMobile pm = m as PlayerMobile;
if ( pm != null )
{
Point3D loc = Point3D.Zero;
Map map = null;
if ( GetDestination( pm, ref loc, ref map ) )
{
BaseCreature.TeleportPets( pm, loc, map );
pm.PlaySound( 0x1FE );
pm.MoveToWorld( loc, map );
return false;
}
else
{
pm.SendLocalizedMessage( this.NotWorkingMessage );
}
}
return base.OnMoveOver( m );
}
public DynamicTeleporter( 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,193 @@
using System;
using Server;
using Server.Network;
namespace Server.Items
{
public class EnchantedSextant : Item
{
//TODO: Trammel/Haven
private static readonly Point2D[] m_TrammelBanks = new Point2D[]
{
new Point2D( 652, 820 ),
new Point2D( 1813, 2825 ),
new Point2D( 3734, 2149 ),
new Point2D( 2503, 552 ),
new Point2D( 3764, 1317 ),
new Point2D( 587, 2146 ),
new Point2D( 1655, 1606 ),
new Point2D( 1425, 1690 ),
new Point2D( 4471, 1156 ),
new Point2D( 1317, 3773 ),
new Point2D( 2881, 684 ),
new Point2D( 2731, 2192 ),
new Point2D( 3620, 2617 ),
new Point2D( 2880, 3472 ),
new Point2D( 1897, 2684 ),
new Point2D( 5346, 74 ),
new Point2D( 5275, 3977 ),
new Point2D( 5669, 3131 )
};
private static readonly Point2D[] m_FeluccaBanks = new Point2D[]
{
new Point2D( 652, 820 ),
new Point2D( 1813, 2825 ),
new Point2D( 3734, 2149 ),
new Point2D( 2503, 552 ),
new Point2D( 3764, 1317 ),
new Point2D( 3695, 2511 ),
new Point2D( 587, 2146 ),
new Point2D( 1655, 1606 ),
new Point2D( 1425, 1690 ),
new Point2D( 4471, 1156 ),
new Point2D( 1317, 3773 ),
new Point2D( 2881, 684 ),
new Point2D( 2731, 2192 ),
new Point2D( 2880, 3472 ),
new Point2D( 1897, 2684 ),
new Point2D( 5346, 74 ),
new Point2D( 5275, 3977 ),
new Point2D( 5669, 3131 )
};
private static readonly Point2D[] m_IlshenarBanks = new Point2D[]
{
new Point2D( 854, 680 ),
new Point2D( 855, 603 ),
new Point2D( 1226, 554 ),
new Point2D( 1610, 556 )
};
private static readonly Point2D[] m_MalasBanks = new Point2D[]
{
new Point2D( 996, 519 ),
new Point2D( 2048, 1345 )
};
private const double m_LongDistance = 300.0;
private const double m_ShortDistance = 5.0;
public override int LabelNumber { get { return 1046226; } } // an enchanted sextant
[Constructable]
public EnchantedSextant() : base( 0x1058 )
{
Weight = 2.0;
}
public override void OnDoubleClick( Mobile from )
{
if ( !from.InRange( GetWorldLocation(), 2 ) )
{
from.LocalOverheadMessage( MessageType.Regular, 0x3B2, 1019045 ); // I can't reach that.
return;
}
Point2D[] banks;
PMList moongates;
if ( from.Map == Map.Trammel )
{
banks = m_TrammelBanks;
moongates = PMList.Trammel;
}
else if ( from.Map == Map.Felucca )
{
banks = m_FeluccaBanks;
moongates = PMList.Felucca;
}
else if ( from.Map == Map.Ilshenar )
{
#if false
banks = m_IlshenarBanks;
moongates = PMList.Ilshenar;
#else
from.Send( new MessageLocalized( Serial, ItemID, MessageType.Label, 0x482, 3, 1061684, "", "" ) ); // The magic of the sextant fails...
return;
#endif
}
else if ( from.Map == Map.Malas )
{
banks = m_MalasBanks;
moongates = PMList.Malas;
}
else
{
banks = null;
moongates = null;
}
Point3D closestMoongate = Point3D.Zero;
double moongateDistance = double.MaxValue;
if ( moongates != null )
{
foreach ( PMEntry entry in moongates.Entries )
{
double dist = from.GetDistanceToSqrt( entry.Location );
if ( moongateDistance > dist )
{
closestMoongate = entry.Location;
moongateDistance = dist;
}
}
}
Point2D closestBank = Point2D.Zero;
double bankDistance = double.MaxValue;
if ( banks != null )
{
foreach ( Point2D p in banks )
{
double dist = from.GetDistanceToSqrt( p );
if ( bankDistance > dist )
{
closestBank = p;
bankDistance = dist;
}
}
}
int moonMsg;
if ( moongateDistance == double.MaxValue )
moonMsg = 1048021; // The sextant fails to find a Moongate nearby.
else if ( moongateDistance > m_LongDistance )
moonMsg = 1046449 + (int)from.GetDirectionTo( closestMoongate ); // A moongate is * from here
else if ( moongateDistance > m_ShortDistance )
moonMsg = 1048010 + (int)from.GetDirectionTo( closestMoongate ); // There is a Moongate * of here.
else
moonMsg = 1048018; // You are next to a Moongate at the moment.
from.Send( new MessageLocalized( Serial, ItemID, MessageType.Label, 0x482, 3, moonMsg, "", "" ) );
int bankMsg;
if ( bankDistance == double.MaxValue )
bankMsg = 1048020; // The sextant fails to find a Bank nearby.
else if ( bankDistance > m_LongDistance )
bankMsg = 1046462 + (int)from.GetDirectionTo( closestBank ); // A town is * from here
else if ( bankDistance > m_ShortDistance )
bankMsg = 1048002 + (int)from.GetDirectionTo( closestBank ); // There is a city Bank * of here.
else
bankMsg = 1048019; // You are next to a Bank at the moment.
from.Send( new MessageLocalized( Serial, ItemID, MessageType.Label, 0x5AA, 3, bankMsg, "", "" ) );
}
public EnchantedSextant( 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,206 @@
using System;
using Server;
using Server.Items;
using Server.Mobiles;
using Server.Engines.Quests;
using Server.Engines.Quests.Necro;
namespace Server.Engines.Quests
{
public class HornOfRetreat : Item
{
private Point3D m_DestLoc;
private Map m_DestMap;
private int m_Charges;
[CommandProperty( AccessLevel.GameMaster )]
public Point3D DestLoc
{
get{ return m_DestLoc; }
set{ m_DestLoc = value; }
}
[CommandProperty( AccessLevel.GameMaster )]
public Map DestMap
{
get{ return m_DestMap; }
set{ m_DestMap = value; }
}
[CommandProperty( AccessLevel.GameMaster )]
public int Charges
{
get{ return m_Charges; }
set{ m_Charges = value; InvalidateProperties(); }
}
public override int LabelNumber{ get{ return 1049117; } } // Horn of Retreat
[Constructable]
public HornOfRetreat() : base( 0xFC4 )
{
Hue = 0x482;
Weight = 1.0;
Charges = 10;
}
public virtual bool ValidateUse( Mobile from )
{
return true;
}
public override void GetProperties( ObjectPropertyList list )
{
base.GetProperties( list );
list.Add( 1060741, m_Charges.ToString() ); // charges: ~1_val~
}
private Timer m_PlayTimer;
public override void OnDoubleClick( Mobile from )
{
if ( IsChildOf( from.Backpack ) )
{
if ( !ValidateUse( from ) )
{
SendLocalizedMessageTo( from, 500309 ); // Nothing Happens.
}
else if( Core.ML && from.Map != Map.Trammel && from.Map != Map.Malas )
{
from.SendLocalizedMessage( 1076154 ); // You can only use this in Trammel and Malas.
}
else if( m_PlayTimer != null )
{
SendLocalizedMessageTo( from, 1042144 ); // This is currently in use.
}
else if( Charges > 0 )
{
from.Animate( 34, 7, 1, true, false, 0 );
from.PlaySound( 0xFF );
from.SendLocalizedMessage( 1049115 ); // You play the horn and a sense of peace overcomes you...
--Charges;
m_PlayTimer = Timer.DelayCall( TimeSpan.FromSeconds( 5.0 ), new TimerStateCallback( PlayTimer_Callback ), from );
}
else
{
SendLocalizedMessageTo( from, 1042544 ); // This item is out of charges.
}
}
else
{
SendLocalizedMessageTo( from, 1042001 ); // That must be in your pack for you to use it.
}
}
public virtual void PlayTimer_Callback( object state )
{
Mobile from = (Mobile)state;
m_PlayTimer = null;
HornOfRetreatMoongate gate = new HornOfRetreatMoongate( this.DestLoc, this.DestMap, from, this.Hue );
gate.MoveToWorld( from.Location, from.Map );
from.PlaySound( 0x20E );
gate.SendLocalizedMessageTo( from, 1049102, from.Name ); // Quickly ~1_NAME~! Onward through the gate!
}
public HornOfRetreat( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 0 ); // version
writer.Write( m_DestLoc );
writer.Write( m_DestMap );
writer.Write( m_Charges );
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
switch ( version )
{
case 0:
{
m_DestLoc = reader.ReadPoint3D();
m_DestMap = reader.ReadMap();
m_Charges = reader.ReadInt();
break;
}
}
}
}
public class HornOfRetreatMoongate : Moongate
{
public override int LabelNumber{ get{ return 1049114; } } // Sanctuary Gate
private Mobile m_Caster;
public HornOfRetreatMoongate( Point3D destLoc, Map destMap, Mobile caster, int hue )
{
m_Caster = caster;
Target = destLoc;
TargetMap = destMap;
Hue = hue;
Light = LightType.Circle300;
Dispellable = false;
Timer.DelayCall( TimeSpan.FromSeconds( 10.0 ), new TimerCallback( Delete ) );
}
public override void BeginConfirmation( Mobile from )
{
EndConfirmation( from );
}
public override void UseGate( Mobile m )
{
if ( m.Region.IsPartOf( typeof( Regions.Jail ) ) )
{
m.SendLocalizedMessage( 1114345 ); // You'll need a better jailbreak plan than that!
}
else if ( m == m_Caster )
{
base.UseGate( m );
Delete();
}
}
public HornOfRetreatMoongate( 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,121 @@
using System;
using Server;
using Server.Mobiles;
namespace Server.Engines.Quests
{
public abstract class QuestItem : Item
{
public QuestItem( int itemID ) : base( itemID )
{
}
public QuestItem( Serial serial ) : base( serial )
{
}
public abstract bool CanDrop( PlayerMobile pm );
public virtual bool Accepted { get { return Deleted; } }
public override bool DropToWorld( Mobile from, Point3D p )
{
bool ret = base.DropToWorld( from, p );
if ( ret && !Accepted && Parent != from.Backpack )
{
if ( from.AccessLevel > AccessLevel.Player )
{
return true;
}
else if ( !(from is PlayerMobile) || CanDrop( (PlayerMobile)from ) )
{
return true;
}
else
{
from.SendLocalizedMessage( 1049343 ); // You can only drop quest items into the top-most level of your backpack while you still need them for your quest.
return false;
}
}
else
{
return ret;
}
}
public override bool DropToMobile( Mobile from, Mobile target, Point3D p )
{
bool ret = base.DropToMobile( from, target, p );
if ( ret && !Accepted && Parent != from.Backpack )
{
if ( from.AccessLevel > AccessLevel.Player )
{
return true;
}
else if ( !(from is PlayerMobile) || CanDrop( (PlayerMobile)from ) )
{
return true;
}
else
{
from.SendLocalizedMessage( 1049344 ); // You decide against trading the item. You still need it for your quest.
return false;
}
}
else
{
return ret;
}
}
public override bool DropToItem( Mobile from, Item target, Point3D p )
{
bool ret = base.DropToItem( from, target, p );
if ( ret && !Accepted && Parent != from.Backpack )
{
if ( from.AccessLevel > AccessLevel.Player )
{
return true;
}
else if ( !(from is PlayerMobile) || CanDrop( (PlayerMobile)from ) )
{
return true;
}
else
{
from.SendLocalizedMessage( 1049343 ); // You can only drop quest items into the top-most level of your backpack while you still need them for your quest.
return false;
}
}
else
{
return ret;
}
}
public override DeathMoveResult OnParentDeath( Mobile parent )
{
if ( parent is PlayerMobile && !CanDrop( (PlayerMobile)parent ) )
return DeathMoveResult.MoveToBackpack;
else
return base.OnParentDeath( parent );
}
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,26 @@
using System;
using Server;
using Server.ContextMenus;
namespace Server.Engines.Quests
{
public class QuestCallbackEntry : ContextMenuEntry
{
private QuestCallback m_Callback;
public QuestCallbackEntry( int number, QuestCallback callback ) : this( number, -1, callback )
{
}
public QuestCallbackEntry( int number, int range, QuestCallback callback ) : base( number, range )
{
m_Callback = callback;
}
public override void OnClick()
{
if ( m_Callback != null )
m_Callback();
}
}
}

View file

@ -0,0 +1,156 @@
using System;
using System.Collections;
using Server;
using Server.Gumps;
using Server.Mobiles;
using Server.Network;
namespace Server.Engines.Quests
{
public abstract class QuestConversation
{
private QuestSystem m_System;
private bool m_HasBeenRead;
public abstract object Message{ get; }
public virtual QuestItemInfo[] Info{ get{ return null; } }
public virtual bool Logged{ get{ return true; } }
public QuestSystem System
{
get{ return m_System; }
set{ m_System = value; }
}
public bool HasBeenRead
{
get{ return m_HasBeenRead; }
set{ m_HasBeenRead = value; }
}
public QuestConversation()
{
}
public virtual void BaseDeserialize( GenericReader reader )
{
int version = reader.ReadEncodedInt();
switch ( version )
{
case 0:
{
m_HasBeenRead = reader.ReadBool();
break;
}
}
ChildDeserialize( reader );
}
public virtual void ChildDeserialize( GenericReader reader )
{
int version = reader.ReadEncodedInt();
}
public virtual void BaseSerialize( GenericWriter writer )
{
writer.WriteEncodedInt( (int) 0 ); // version
writer.Write( (bool) m_HasBeenRead );
ChildSerialize( writer );
}
public virtual void ChildSerialize( GenericWriter writer )
{
writer.WriteEncodedInt( (int) 0 ); // version
}
public virtual void OnRead()
{
}
}
public class QuestConversationsGump : BaseQuestGump
{
private ArrayList m_Conversations;
public QuestConversationsGump( QuestConversation conv ) : this( BuildList( conv ) )
{
}
public QuestConversationsGump( ArrayList conversations ) : base( 30, 50 )
{
m_Conversations = conversations;
Closable = false;
AddPage( 0 );
AddImage( 349, 10, 9392 );
AddImageTiled( 349, 130, 100, 120, 9395 );
AddImageTiled( 149, 10, 200, 140, 9391 );
AddImageTiled( 149, 250, 200, 140, 9397 );
AddImage( 349, 250, 9398 );
AddImage( 35, 10, 9390 );
AddImageTiled( 35, 150, 120, 100, 9393 );
AddImage( 35, 250, 9396 );
AddHtmlLocalized( 110, 60, 200, 20, 1049069, White, false, false ); // <STRONG>Conversation Event</STRONG>
AddImage( 65, 14, 10102 );
AddImageTiled( 81, 14, 349, 17, 10101 );
AddImage( 426, 14, 10104 );
AddImageTiled( 55, 40, 388, 323, 2624 );
AddAlphaRegion( 55, 40, 388, 323 );
AddImageTiled( 75, 90, 200, 1, 9101 );
AddImage( 75, 58, 9781 );
AddImage( 380, 45, 223 );
AddButton( 220, 335, 2313, 2312, 1, GumpButtonType.Reply, 0 );
AddImage( 0, 0, 10440 );
AddPage( 1 );
for ( int i = 0; i < conversations.Count; ++i )
{
QuestConversation conv = (QuestConversation)conversations[conversations.Count - 1 - i];
if ( i > 0 )
{
AddButton( 65, 366, 9909, 9911, 0, GumpButtonType.Page, 1 + i );
AddHtmlLocalized( 90, 367, 50, 20, 1043354, Black, false, false ); // Previous
AddPage( 1 + i );
}
AddHtmlObject( 70, 110, 365, 220, conv.Message, LightGreen, false, true );
if ( i > 0 )
{
AddButton( 420, 366, 9903, 9905, 0, GumpButtonType.Page, i );
AddHtmlLocalized( 370, 367, 50, 20, 1043353, Black, false, false ); // Next
}
}
}
public override void OnResponse( NetState sender, RelayInfo info )
{
for ( int i = m_Conversations.Count - 1; i >= 0; --i )
{
QuestConversation qc = (QuestConversation)m_Conversations[i];
if ( !qc.HasBeenRead )
{
qc.HasBeenRead = true;
qc.OnRead();
}
}
}
}
}

View file

@ -0,0 +1,72 @@
using System;
using Server;
using Server.Gumps;
namespace Server.Engines.Quests
{
public class QuestItemInfo
{
private object m_Name;
private int m_ItemID;
public object Name
{
get{ return m_Name; }
set{ m_Name = value; }
}
public int ItemID
{
get{ return m_ItemID; }
set{ m_ItemID = value; }
}
public QuestItemInfo( object name, int itemID )
{
m_Name = name;
m_ItemID = itemID;
}
}
public class QuestItemInfoGump : BaseQuestGump
{
public QuestItemInfoGump( QuestItemInfo[] info ) : base( 485, 75 )
{
int height = 100 + (info.Length * 75);
AddPage( 0 );
AddBackground( 5, 10, 145, height, 5054 );
AddImageTiled( 13, 20, 125, 10, 2624 );
AddAlphaRegion( 13, 20, 125, 10 );
AddImageTiled( 13, height - 10, 128, 10, 2624 );
AddAlphaRegion( 13, height - 10, 128, 10 );
AddImageTiled( 13, 20, 10, height - 30, 2624 );
AddAlphaRegion( 13, 20, 10, height - 30 );
AddImageTiled( 131, 20, 10, height - 30, 2624 );
AddAlphaRegion( 131, 20, 10, height - 30 );
AddHtmlLocalized( 67, 35, 120, 20, 1011233, White, false, false ); // INFO
AddImage( 62, 52, 9157 );
AddImage( 72, 52, 9157 );
AddImage( 82, 52, 9157 );
AddButton( 25, 31, 1209, 1210, 777, GumpButtonType.Reply, 0 );
AddPage( 1 );
for ( int i = 0; i < info.Length; ++i )
{
QuestItemInfo cur = info[i];
AddHtmlObject( 25, 65 + (i * 75), 110, 20, cur.Name, 1153, false, false );
AddItem( 45, 85 + (i * 75), cur.ItemID );
}
}
}
}

View file

@ -0,0 +1,278 @@
using System;
using System.Collections;
using Server;
using Server.Gumps;
using Server.Mobiles;
using Server.Network;
using Server.Items;
namespace Server.Engines.Quests
{
public abstract class QuestObjective
{
private QuestSystem m_System;
private bool m_HasBeenRead;
private int m_CurProgress;
private bool m_HasCompleted;
public abstract object Message{ get; }
public virtual int MaxProgress{ get{ return 1; } }
public virtual QuestItemInfo[] Info{ get{ return null; } }
public QuestSystem System
{
get{ return m_System; }
set{ m_System = value; }
}
public bool HasBeenRead
{
get{ return m_HasBeenRead; }
set{ m_HasBeenRead = value; }
}
public int CurProgress
{
get{ return m_CurProgress; }
set{ m_CurProgress = value; CheckCompletionStatus(); }
}
public bool HasCompleted
{
get{ return m_HasCompleted; }
set{ m_HasCompleted = value; }
}
public virtual bool Completed
{
get{ return m_CurProgress >= MaxProgress; }
}
public bool IsSingleObjective
{
get{ return ( MaxProgress == 1 ); }
}
public QuestObjective()
{
}
public virtual void BaseDeserialize( GenericReader reader )
{
int version = reader.ReadEncodedInt();
switch ( version )
{
case 1:
{
m_HasBeenRead = reader.ReadBool();
goto case 0;
}
case 0:
{
m_CurProgress = reader.ReadEncodedInt();
m_HasCompleted = reader.ReadBool();
break;
}
}
ChildDeserialize( reader );
}
public virtual void ChildDeserialize( GenericReader reader )
{
int version = reader.ReadEncodedInt();
}
public virtual void BaseSerialize( GenericWriter writer )
{
writer.WriteEncodedInt( (int) 1 ); // version
writer.Write( (bool) m_HasBeenRead );
writer.WriteEncodedInt( (int) m_CurProgress );
writer.Write( (bool) m_HasCompleted );
ChildSerialize( writer );
}
public virtual void ChildSerialize( GenericWriter writer )
{
writer.WriteEncodedInt( (int) 0 ); // version
}
public virtual void Complete()
{
CurProgress = MaxProgress;
}
public virtual void RenderMessage( BaseQuestGump gump )
{
gump.AddHtmlObject( 70, 130, 300, 100, this.Message, BaseQuestGump.Blue, false, false );
}
public virtual void RenderProgress( BaseQuestGump gump )
{
gump.AddHtmlObject( 70, 260, 270, 100, this.Completed ? 1049077 : 1049078, BaseQuestGump.Blue, false, false );
}
public virtual void CheckCompletionStatus()
{
if ( Completed && !HasCompleted )
{
HasCompleted = true;
OnComplete();
}
}
public virtual void OnRead()
{
}
public virtual bool GetTimerEvent()
{
return !Completed;
}
public virtual void CheckProgress()
{
}
public virtual void OnComplete()
{
}
public virtual bool GetKillEvent( BaseCreature creature, Container corpse )
{
return !Completed;
}
public virtual void OnKill( BaseCreature creature, Container corpse )
{
}
public virtual bool IgnoreYoungProtection( Mobile from )
{
return false;
}
}
public class QuestLogUpdatedGump : BaseQuestGump
{
private QuestSystem m_System;
public QuestLogUpdatedGump( QuestSystem system ) : base( 3, 30 )
{
m_System = system;
AddPage( 0 );
AddImage( 20, 5, 1417 );
AddHtmlLocalized( 0, 78, 120, 40, 1049079, White, false, false ); // Quest Log Updated
AddImageTiled( 0, 78, 120, 40, 2624 );
AddAlphaRegion( 0, 78, 120, 40 );
AddButton( 30, 15, 5575, 5576, 1, GumpButtonType.Reply, 0 );
}
public override void OnResponse( NetState sender, RelayInfo info )
{
if ( info.ButtonID == 1 )
m_System.ShowQuestLog();
}
}
public class QuestObjectivesGump : BaseQuestGump
{
private ArrayList m_Objectives;
public QuestObjectivesGump( QuestObjective obj ) : this( BuildList( obj ) )
{
}
public QuestObjectivesGump( ArrayList objectives ) : base( 90, 50 )
{
m_Objectives = objectives;
Closable = false;
AddPage( 0 );
AddImage( 0, 0, 3600 );
AddImageTiled( 0, 14, 15, 375, 3603 );
AddImageTiled( 380, 14, 14, 375, 3605 );
AddImage( 0, 376, 3606 );
AddImageTiled( 15, 376, 370, 16, 3607 );
AddImageTiled( 15, 0, 370, 16, 3601 );
AddImage( 380, 0, 3602 );
AddImage( 380, 376, 3608 );
AddImageTiled( 15, 15, 365, 365, 2624 );
AddAlphaRegion( 15, 15, 365, 365 );
AddImage( 20, 87, 1231 );
AddImage( 75, 62, 9307 );
AddHtmlLocalized( 117, 35, 230, 20, 1046026, Blue, false, false ); // Quest Log
AddImage( 77, 33, 9781 );
AddImage( 65, 110, 2104 );
AddHtmlLocalized( 79, 106, 230, 20, 1049073, Blue, false, false ); // Objective:
AddImageTiled( 68, 125, 120, 1, 9101 );
AddImage( 65, 240, 2104 );
AddHtmlLocalized( 79, 237, 230, 20, 1049076, Blue, false, false ); // Progress details:
AddImageTiled( 68, 255, 120, 1, 9101 );
AddButton( 175, 355, 2313, 2312, 1, GumpButtonType.Reply, 0 );
AddImage( 341, 15, 10450 );
AddImage( 341, 330, 10450 );
AddImage( 15, 330, 10450 );
AddImage( 15, 15, 10450 );
AddPage( 1 );
for ( int i = 0; i < objectives.Count; ++i )
{
QuestObjective obj = (QuestObjective)objectives[objectives.Count - 1 - i];
if ( i > 0 )
{
AddButton( 55, 346, 9909, 9911, 0, GumpButtonType.Page, 1 + i );
AddHtmlLocalized( 82, 347, 50, 20, 1043354, White, false, false ); // Previous
AddPage( 1 + i );
}
obj.RenderMessage( this );
obj.RenderProgress( this );
if ( i > 0 )
{
AddButton( 317, 346, 9903, 9905, 0, GumpButtonType.Page, i );
AddHtmlLocalized( 278, 347, 50, 20, 1043353, White, false, false ); // Next
}
}
}
public override void OnResponse( NetState sender, RelayInfo info )
{
for ( int i = m_Objectives.Count - 1; i >= 0; --i )
{
QuestObjective obj = (QuestObjective)m_Objectives[i];
if ( !obj.HasBeenRead )
{
obj.HasBeenRead = true;
obj.OnRead();
}
}
}
}
}

View file

@ -0,0 +1,42 @@
using System;
namespace Server.Engines.Quests
{
public class QuestRestartInfo
{
private Type m_QuestType;
private DateTime m_RestartTime;
public Type QuestType
{
get{ return m_QuestType; }
set{ m_QuestType = value; }
}
public DateTime RestartTime
{
get{ return m_RestartTime; }
set{ m_RestartTime = value; }
}
public void Reset( TimeSpan restartDelay )
{
if ( restartDelay < TimeSpan.MaxValue )
m_RestartTime = DateTime.UtcNow + restartDelay;
else
m_RestartTime = DateTime.MaxValue;
}
public QuestRestartInfo( Type questType, TimeSpan restartDelay )
{
m_QuestType = questType;
Reset( restartDelay );
}
public QuestRestartInfo( Type questType, DateTime restartTime )
{
m_QuestType = questType;
m_RestartTime = restartTime;
}
}
}

View file

@ -0,0 +1,197 @@
using System;
namespace Server.Engines.Quests
{
public class QuestSerializer
{
public static object Construct( Type type )
{
try
{
return Activator.CreateInstance( type );
}
catch
{
return null;
}
}
public static void Write( Type type, Type[] referenceTable, GenericWriter writer )
{
if ( type == null )
{
writer.WriteEncodedInt( (int) 0x00 );
}
else
{
for ( int i = 0; i < referenceTable.Length; ++i )
{
if ( referenceTable[i] == type )
{
writer.WriteEncodedInt( (int) 0x01 );
writer.WriteEncodedInt( (int) i );
return;
}
}
writer.WriteEncodedInt( (int) 0x02 );
writer.Write( type.FullName );
}
}
public static Type ReadType( Type[] referenceTable, GenericReader reader )
{
int encoding = reader.ReadEncodedInt();
switch ( encoding )
{
default:
case 0x00: // null
{
return null;
}
case 0x01: // indexed
{
int index = reader.ReadEncodedInt();
if ( index >= 0 && index < referenceTable.Length )
return referenceTable[index];
return null;
}
case 0x02: // by name
{
string fullName = reader.ReadString();
if ( fullName == null )
return null;
return ScriptCompiler.FindTypeByFullName( fullName, false );
}
}
}
public static QuestSystem DeserializeQuest( GenericReader reader )
{
int encoding = reader.ReadEncodedInt();
switch ( encoding )
{
default:
case 0x00: // null
{
return null;
}
case 0x01:
{
Type type = ReadType( QuestSystem.QuestTypes, reader );
QuestSystem qs = Construct( type ) as QuestSystem;
if ( qs != null )
qs.BaseDeserialize( reader );
return qs;
}
}
}
public static void Serialize( QuestSystem qs, GenericWriter writer )
{
if ( qs == null )
{
writer.WriteEncodedInt( 0x00 );
}
else
{
writer.WriteEncodedInt( 0x01 );
Write( qs.GetType(), QuestSystem.QuestTypes, writer );
qs.BaseSerialize( writer );
}
}
public static QuestObjective DeserializeObjective( Type[] referenceTable, GenericReader reader )
{
int encoding = reader.ReadEncodedInt();
switch ( encoding )
{
default:
case 0x00: // null
{
return null;
}
case 0x01:
{
Type type = ReadType( referenceTable, reader );
QuestObjective obj = Construct( type ) as QuestObjective;
if ( obj != null )
obj.BaseDeserialize( reader );
return obj;
}
}
}
public static void Serialize( Type[] referenceTable, QuestObjective obj, GenericWriter writer )
{
if ( obj == null )
{
writer.WriteEncodedInt( 0x00 );
}
else
{
writer.WriteEncodedInt( 0x01 );
Write( obj.GetType(), referenceTable, writer );
obj.BaseSerialize( writer );
}
}
public static QuestConversation DeserializeConversation( Type[] referenceTable, GenericReader reader )
{
int encoding = reader.ReadEncodedInt();
switch ( encoding )
{
default:
case 0x00: // null
{
return null;
}
case 0x01:
{
Type type = ReadType( referenceTable, reader );
QuestConversation conv = Construct( type ) as QuestConversation;
if ( conv != null )
conv.BaseDeserialize( reader );
return conv;
}
}
}
public static void Serialize( Type[] referenceTable, QuestConversation conv, GenericWriter writer )
{
if ( conv == null )
{
writer.WriteEncodedInt( 0x00 );
}
else
{
writer.WriteEncodedInt( 0x01 );
Write( conv.GetType(), referenceTable, writer );
conv.BaseSerialize( writer );
}
}
}
}

View file

@ -0,0 +1,686 @@
using System;
using System.Collections;
using System.Collections.Generic;
using Server;
using Server.Items;
using Server.Gumps;
using Server.Mobiles;
using Server.Network;
using Server.ContextMenus;
namespace Server.Engines.Quests
{
public delegate void QuestCallback();
public abstract class QuestSystem
{
public static readonly Type[] QuestTypes = new Type[]
{
typeof( Doom.TheSummoningQuest ),
typeof( Necro.DarkTidesQuest ),
typeof( Haven.UzeraanTurmoilQuest ),
typeof( Collector.CollectorQuest ),
typeof( Hag.WitchApprenticeQuest ),
typeof( Naturalist.StudyOfSolenQuest ),
typeof( Matriarch.SolenMatriarchQuest ),
typeof( Ambitious.AmbitiousQueenQuest ),
typeof( Ninja.EminosUndertakingQuest ),
typeof( Samurai.HaochisTrialsQuest ),
typeof( Zento.TerribleHatchlingsQuest )
};
public abstract object Name{ get; }
public abstract object OfferMessage{ get; }
public abstract int Picture{ get; }
public abstract bool IsTutorial{ get; }
public abstract TimeSpan RestartDelay{ get; }
public abstract Type[] TypeReferenceTable{ get; }
private PlayerMobile m_From;
private ArrayList m_Objectives;
private ArrayList m_Conversations;
public PlayerMobile From
{
get{ return m_From; }
set{ m_From = value; }
}
public ArrayList Objectives
{
get{ return m_Objectives; }
set{ m_Objectives = value; }
}
public ArrayList Conversations
{
get{ return m_Conversations; }
set{ m_Conversations = value; }
}
private Timer m_Timer;
public virtual void StartTimer()
{
if ( m_Timer != null )
return;
m_Timer = Timer.DelayCall( TimeSpan.FromSeconds( 0.5 ), TimeSpan.FromSeconds( 0.5 ), new TimerCallback( Slice ) );
}
public virtual void StopTimer()
{
if ( m_Timer != null )
m_Timer.Stop();
m_Timer = null;
}
public virtual void Slice()
{
for ( int i = m_Objectives.Count - 1; i >= 0; --i )
{
QuestObjective obj = (QuestObjective)m_Objectives[i];
if ( obj.GetTimerEvent() )
obj.CheckProgress();
}
}
public virtual void OnKill( BaseCreature creature, Container corpse )
{
for ( int i = m_Objectives.Count - 1; i >= 0; --i )
{
QuestObjective obj = (QuestObjective)m_Objectives[i];
if ( obj.GetKillEvent( creature, corpse ) )
obj.OnKill( creature, corpse );
}
}
public virtual bool IgnoreYoungProtection( Mobile from )
{
for ( int i = m_Objectives.Count - 1; i >= 0; --i )
{
QuestObjective obj = (QuestObjective)m_Objectives[i];
if ( obj.IgnoreYoungProtection( from ) )
return true;
}
return false;
}
public QuestSystem( PlayerMobile from )
{
m_From = from;
m_Objectives = new ArrayList();
m_Conversations = new ArrayList();
}
public QuestSystem()
{
}
public virtual void BaseDeserialize( GenericReader reader )
{
Type[] referenceTable = this.TypeReferenceTable;
int version = reader.ReadEncodedInt();
switch ( version )
{
case 0:
{
int count = reader.ReadEncodedInt();
m_Objectives = new ArrayList( count );
for ( int i = 0; i < count; ++i )
{
QuestObjective obj = QuestSerializer.DeserializeObjective( referenceTable, reader );
if ( obj != null )
{
obj.System = this;
m_Objectives.Add( obj );
}
}
count = reader.ReadEncodedInt();
m_Conversations = new ArrayList( count );
for ( int i = 0; i < count; ++i )
{
QuestConversation conv = QuestSerializer.DeserializeConversation( referenceTable, reader );
if ( conv != null )
{
conv.System = this;
m_Conversations.Add( conv );
}
}
break;
}
}
ChildDeserialize( reader );
}
public virtual void ChildDeserialize( GenericReader reader )
{
int version = reader.ReadEncodedInt();
}
public virtual void BaseSerialize( GenericWriter writer )
{
Type[] referenceTable = this.TypeReferenceTable;
writer.WriteEncodedInt( (int) 0 ); // version
writer.WriteEncodedInt( (int) m_Objectives.Count );
for ( int i = 0; i < m_Objectives.Count; ++i )
QuestSerializer.Serialize( referenceTable, (QuestObjective) m_Objectives[i], writer );
writer.WriteEncodedInt( (int) m_Conversations.Count );
for ( int i = 0; i < m_Conversations.Count; ++i )
QuestSerializer.Serialize( referenceTable, (QuestConversation) m_Conversations[i], writer );
ChildSerialize( writer );
}
public virtual void ChildSerialize( GenericWriter writer )
{
writer.WriteEncodedInt( (int) 0 ); // version
}
public bool IsObjectiveInProgress( Type type )
{
QuestObjective obj = FindObjective( type );
return ( obj != null && !obj.Completed );
}
public QuestObjective FindObjective( Type type )
{
for ( int i = m_Objectives.Count - 1; i >= 0; --i )
{
QuestObjective obj = (QuestObjective)m_Objectives[i];
if ( obj.GetType() == type )
return obj;
}
return null;
}
public virtual void SendOffer()
{
m_From.SendGump( new QuestOfferGump( this ) );
}
public virtual void GetContextMenuEntries( List<ContextMenuEntry> list )
{
if ( m_Objectives.Count > 0 )
list.Add( new QuestCallbackEntry( 6154, new QuestCallback( ShowQuestLog ) ) ); // View Quest Log
if ( m_Conversations.Count > 0 )
list.Add( new QuestCallbackEntry( 6156, new QuestCallback( ShowQuestConversation ) ) ); // Quest Conversation
list.Add( new QuestCallbackEntry( 6155, new QuestCallback( BeginCancelQuest ) ) ); // Cancel Quest
}
public virtual void ShowQuestLogUpdated()
{
m_From.CloseGump( typeof( QuestLogUpdatedGump ) );
m_From.SendGump( new QuestLogUpdatedGump( this ) );
}
public virtual void ShowQuestLog()
{
if ( m_Objectives.Count > 0 )
{
m_From.CloseGump( typeof( QuestItemInfoGump ) );
m_From.CloseGump( typeof( QuestLogUpdatedGump ) );
m_From.CloseGump( typeof( QuestObjectivesGump ) );
m_From.CloseGump( typeof( QuestConversationsGump ) );
m_From.SendGump( new QuestObjectivesGump( m_Objectives ) );
QuestObjective last = (QuestObjective)m_Objectives[m_Objectives.Count - 1];
if ( last.Info != null )
m_From.SendGump( new QuestItemInfoGump( last.Info ) );
}
}
public virtual void ShowQuestConversation()
{
if ( m_Conversations.Count > 0 )
{
m_From.CloseGump( typeof( QuestItemInfoGump ) );
m_From.CloseGump( typeof( QuestObjectivesGump ) );
m_From.CloseGump( typeof( QuestConversationsGump ) );
m_From.SendGump( new QuestConversationsGump( m_Conversations ) );
QuestConversation last = (QuestConversation)m_Conversations[m_Conversations.Count - 1];
if ( last.Info != null )
m_From.SendGump( new QuestItemInfoGump( last.Info ) );
}
}
public virtual void BeginCancelQuest()
{
m_From.SendGump( new QuestCancelGump( this ) );
}
public virtual void EndCancelQuest( bool shouldCancel )
{
if ( m_From.Quest != this )
return;
if ( shouldCancel )
{
m_From.SendLocalizedMessage( 1049015 ); // You have canceled your quest.
Cancel();
}
else
{
m_From.SendLocalizedMessage( 1049014 ); // You have chosen not to cancel your quest.
}
}
public virtual void Cancel()
{
ClearQuest( false );
}
public virtual void Complete()
{
ClearQuest( true );
}
public virtual void ClearQuest( bool completed )
{
StopTimer();
if ( m_From.Quest == this )
{
m_From.Quest = null;
TimeSpan restartDelay = this.RestartDelay;
if ( ( completed && restartDelay > TimeSpan.Zero ) || ( !completed && restartDelay == TimeSpan.MaxValue ) )
{
List<QuestRestartInfo> doneQuests = m_From.DoneQuests;
if ( doneQuests == null )
m_From.DoneQuests = doneQuests = new List<QuestRestartInfo>();
bool found = false;
Type ourQuestType = this.GetType();
for ( int i = 0; i < doneQuests.Count; ++i )
{
QuestRestartInfo restartInfo = doneQuests[i];
if ( restartInfo.QuestType == ourQuestType )
{
restartInfo.Reset( restartDelay );
found = true;
break;
}
}
if ( !found )
doneQuests.Add( new QuestRestartInfo( ourQuestType, restartDelay ) );
}
}
}
public virtual void AddConversation( QuestConversation conv )
{
conv.System = this;
if ( conv.Logged )
m_Conversations.Add( conv );
m_From.CloseGump( typeof( QuestItemInfoGump ) );
m_From.CloseGump( typeof( QuestObjectivesGump ) );
m_From.CloseGump( typeof( QuestConversationsGump ) );
if ( conv.Logged )
m_From.SendGump( new QuestConversationsGump( m_Conversations ) );
else
m_From.SendGump( new QuestConversationsGump( conv ) );
if ( conv.Info != null )
m_From.SendGump( new QuestItemInfoGump( conv.Info ) );
}
public virtual void AddObjective( QuestObjective obj )
{
obj.System = this;
m_Objectives.Add( obj );
ShowQuestLogUpdated();
}
public virtual void Accept()
{
if ( m_From.Quest != null )
return;
m_From.Quest = this;
m_From.SendLocalizedMessage( 1049019 ); // You have accepted the Quest.
StartTimer();
}
public virtual void Decline()
{
m_From.SendLocalizedMessage( 1049018 ); // You have declined the Quest.
}
public static bool CanOfferQuest( Mobile check, Type questType )
{
bool inRestartPeriod;
return CanOfferQuest( check, questType, out inRestartPeriod );
}
public static bool CanOfferQuest( Mobile check, Type questType, out bool inRestartPeriod )
{
inRestartPeriod = false;
PlayerMobile pm = check as PlayerMobile;
if ( pm == null )
return false;
if ( pm.HasGump( typeof( QuestOfferGump ) ) )
return false;
if ( questType == typeof( Necro.DarkTidesQuest ) && pm.Profession != 4 ) // necromancer
return false;
if ( questType == typeof( Haven.UzeraanTurmoilQuest ) && pm.Profession != 1 && pm.Profession != 2 && pm.Profession != 5 ) // warrior / magician / paladin
return false;
if ( questType == typeof( Samurai.HaochisTrialsQuest ) && pm.Profession != 6 ) // samurai
return false;
if ( questType == typeof( Ninja.EminosUndertakingQuest ) && pm.Profession != 7 ) // ninja
return false;
List<QuestRestartInfo> doneQuests = pm.DoneQuests;
if ( doneQuests != null )
{
for ( int i = 0; i < doneQuests.Count; ++i )
{
QuestRestartInfo restartInfo = doneQuests[i];
if ( restartInfo.QuestType == questType )
{
DateTime endTime = restartInfo.RestartTime;
if ( DateTime.UtcNow < endTime )
{
inRestartPeriod = true;
return false;
}
doneQuests.RemoveAt( i-- );
return true;
}
}
}
return true;
}
public static void FocusTo( Mobile who, Mobile to )
{
if ( Utility.RandomBool() )
{
who.Animate( 17, 7, 1, true, false, 0 );
}
else
{
switch ( Utility.Random( 3 ) )
{
case 0: who.Animate( 32, 7, 1, true, false, 0 ); break;
case 1: who.Animate( 33, 7, 1, true, false, 0 ); break;
case 2: who.Animate( 34, 7, 1, true, false, 0 ); break;
}
}
who.Direction = who.GetDirectionTo( to );
}
public static int RandomBrightHue()
{
if ( 0.1 > Utility.RandomDouble() )
return Utility.RandomList( 0x62, 0x71 );
return Utility.RandomList( 0x03, 0x0D, 0x13, 0x1C, 0x21, 0x30, 0x37, 0x3A, 0x44, 0x59 );
}
}
public class QuestCancelGump : BaseQuestGump
{
private QuestSystem m_System;
public QuestCancelGump( QuestSystem system ) : base( 120, 50 )
{
m_System = system;
Closable = false;
AddPage( 0 );
AddImageTiled( 0, 0, 348, 262, 2702 );
AddAlphaRegion( 0, 0, 348, 262 );
AddImage( 0, 15, 10152 );
AddImageTiled( 0, 30, 17, 200, 10151 );
AddImage( 0, 230, 10154 );
AddImage( 15, 0, 10252 );
AddImageTiled( 30, 0, 300, 17, 10250 );
AddImage( 315, 0, 10254 );
AddImage( 15, 244, 10252 );
AddImageTiled( 30, 244, 300, 17, 10250 );
AddImage( 315, 244, 10254 );
AddImage( 330, 15, 10152 );
AddImageTiled( 330, 30, 17, 200, 10151 );
AddImage( 330, 230, 10154 );
AddImage( 333, 2, 10006 );
AddImage( 333, 248, 10006 );
AddImage( 2, 248, 10006 );
AddImage( 2, 2, 10006 );
AddHtmlLocalized( 25, 22, 200, 20, 1049000, 32000, false, false ); // Confirm Quest Cancellation
AddImage( 25, 40, 3007 );
if ( system.IsTutorial )
{
AddHtmlLocalized( 25, 55, 300, 120, 1060836, White, false, false ); // This quest will give you valuable information, skills and equipment that will help you advance in the game at a quicker pace.<BR><BR>Are you certain you wish to cancel at this time?
}
else
{
AddHtmlLocalized( 25, 60, 300, 20, 1049001, White, false, false ); // You have chosen to abort your quest:
AddImage( 25, 81, 0x25E7 );
AddHtmlObject( 48, 80, 280, 20, system.Name, DarkGreen, false, false );
AddHtmlLocalized( 25, 120, 280, 20, 1049002, White, false, false ); // Can this quest be restarted after quitting?
AddImage( 25, 141, 0x25E7 );
AddHtmlLocalized( 48, 140, 280, 20, (system.RestartDelay < TimeSpan.MaxValue) ? 1049016 : 1049017, DarkGreen, false, false ); // Yes/No
}
AddRadio( 25, 175, 9720, 9723, true, 1 );
AddHtmlLocalized( 60, 180, 280, 20, 1049005, White, false, false ); // Yes, I really want to quit!
AddRadio( 25, 210, 9720, 9723, false, 0 );
AddHtmlLocalized( 60, 215, 280, 20, 1049006, White, false, false ); // No, I don't want to quit.
AddButton( 265, 220, 247, 248, 1, GumpButtonType.Reply, 0 );
}
public override void OnResponse( NetState sender, RelayInfo info )
{
if ( info.ButtonID == 1 )
m_System.EndCancelQuest( info.IsSwitched( 1 ) );
}
}
public class QuestOfferGump : BaseQuestGump
{
private QuestSystem m_System;
public QuestOfferGump( QuestSystem system ) : base( 75, 25 )
{
m_System = system;
Closable = false;
AddPage( 0 );
AddImageTiled( 50, 20, 400, 400, 2624 );
AddAlphaRegion( 50, 20, 400, 400 );
AddImage( 90, 33, 9005 );
AddHtmlLocalized( 130, 45, 270, 20, 1049010, White, false, false ); // Quest Offer
AddImageTiled( 130, 65, 175, 1, 9101 );
AddImage( 140, 110, 1209 );
AddHtmlObject( 160, 108, 250, 20, system.Name, DarkGreen, false, false );
AddHtmlObject( 98, 140, 312, 200, system.OfferMessage, LightGreen, false, true );
AddRadio( 85, 350, 9720, 9723, true, 1 );
AddHtmlLocalized( 120, 356, 280, 20, 1049011, White, false, false ); // I accept!
AddRadio( 85, 385, 9720, 9723, false, 0 );
AddHtmlLocalized( 120, 391, 280, 20, 1049012, White, false, false ); // No thanks, I decline.
AddButton( 340, 390, 247, 248, 1, GumpButtonType.Reply, 0 );
AddImageTiled( 50, 29, 30, 390, 10460 );
AddImageTiled( 34, 140, 17, 279, 9263 );
AddImage( 48, 135, 10411 );
AddImage( -16, 285, 10402 );
AddImage( 0, 10, 10421 );
AddImage( 25, 0, 10420 );
AddImageTiled( 83, 15, 350, 15, 10250 );
AddImage( 34, 419, 10306 );
AddImage( 442, 419, 10304 );
AddImageTiled( 51, 419, 392, 17, 10101 );
AddImageTiled( 415, 29, 44, 390, 2605 );
AddImageTiled( 415, 29, 30, 390, 10460 );
AddImage( 425, 0, 10441 );
AddImage( 370, 50, 1417 );
AddImage( 379, 60, system.Picture );
}
public override void OnResponse( NetState sender, RelayInfo info )
{
if ( info.ButtonID == 1 )
{
if ( info.IsSwitched( 1 ) )
m_System.Accept();
else
m_System.Decline();
}
}
}
public abstract class BaseQuestGump : Gump
{
public const int Black = 0x0000;
public const int White = 0x7FFF;
public const int DarkGreen = 10000;
public const int LightGreen = 90000;
public const int Blue = 19777215;
public static int C16232( int c16 )
{
c16 &= 0x7FFF;
int r = ( ((c16 >> 10) & 0x1F) << 3 );
int g = ( ((c16 >> 05) & 0x1F) << 3 );
int b = ( ((c16 >> 00) & 0x1F) << 3 );
return (r << 16) | (g << 8) | (b << 0);
}
public static int C16216( int c16 )
{
return c16 & 0x7FFF;
}
public static int C32216( int c32 )
{
c32 &= 0xFFFFFF;
int r = ( ((c32 >> 16) & 0xFF) >> 3 );
int g = ( ((c32 >> 08) & 0xFF) >> 3 );
int b = ( ((c32 >> 00) & 0xFF) >> 3 );
return (r << 10) | (g << 5) | (b << 0);
}
public static string Color( string text, int color )
{
return String.Format( "<BASEFONT COLOR=#{0:X6}>{1}</BASEFONT>", color, text );
}
public static ArrayList BuildList( object obj )
{
ArrayList list = new ArrayList();
list.Add( obj );
return list;
}
public void AddHtmlObject( int x, int y, int width, int height, object message, int color, bool back, bool scroll )
{
if ( message is string )
{
string html = (string)message;
AddHtml( x, y, width, height, Color( html, C16232( color ) ), back, scroll );
}
else if ( message is int )
{
int html = (int)message;
AddHtmlLocalized( x, y, width, height, html, C16216( color ), back, scroll );
}
}
public BaseQuestGump( int x, int y ) : base( x, y )
{
}
}
}

View file

@ -0,0 +1,44 @@
using System;
using System.Xml;
using Server;
using Server.Regions;
using Server.Mobiles;
namespace Server.Engines.Quests
{
public class CancelQuestRegion : BaseRegion
{
private Type m_Quest;
public Type Quest{ get{ return m_Quest; } }
public CancelQuestRegion( XmlElement xml, Map map, Region parent ) : base( xml, map, parent )
{
ReadType( xml["quest"], "type", ref m_Quest );
}
public override bool OnMoveInto( Mobile m, Direction d, Point3D newLocation, Point3D oldLocation )
{
if ( !base.OnMoveInto ( m, d, newLocation, oldLocation ) )
return false;
if ( m.AccessLevel > AccessLevel.Player )
return true;
if ( m_Quest == null )
return true;
PlayerMobile player = m as PlayerMobile;
if ( player != null && player.Quest != null && player.Quest.GetType() == m_Quest )
{
if ( !player.HasGump( typeof( QuestCancelGump ) ) )
player.Quest.BeginCancelQuest();
return false;
}
return true;
}
}
}

View file

@ -0,0 +1,43 @@
using System;
using System.Xml;
using Server;
using Server.Regions;
using Server.Mobiles;
namespace Server.Engines.Quests
{
public class QuestCompleteObjectiveRegion : BaseRegion
{
private Type m_Quest;
private Type m_Objective;
public Type Quest{ get{ return m_Quest ; } }
public Type Objective{ get{ return m_Objective; } }
public QuestCompleteObjectiveRegion( XmlElement xml, Map map, Region parent ) : base( xml, map, parent )
{
XmlElement questEl = xml["quest"];
ReadType( questEl, "type", ref m_Quest );
ReadType( questEl, "complete", ref m_Objective );
}
public override void OnEnter( Mobile m )
{
base.OnEnter( m );
if ( m_Quest != null && m_Objective != null )
{
PlayerMobile player = m as PlayerMobile;
if ( player != null && player.Quest != null && player.Quest.GetType() == m_Quest )
{
QuestObjective obj = player.Quest.FindObjective( m_Objective );
if ( obj != null && !obj.Completed )
obj.Complete();
}
}
}
}
}

View file

@ -0,0 +1,67 @@
using System;
using System.Xml;
using Server;
using Server.Regions;
using Server.Mobiles;
namespace Server.Engines.Quests
{
public class QuestNoEntryRegion : BaseRegion
{
private Type m_Quest;
private Type m_MinObjective;
private Type m_MaxObjective;
private int m_Message;
public Type Quest{ get{ return m_Quest; } }
public Type MinObjective{ get{ return m_MinObjective; } }
public Type MaxObjective{ get{ return m_MaxObjective; } }
public int Message{ get{ return m_Message; } }
public QuestNoEntryRegion( XmlElement xml, Map map, Region parent ) : base( xml, map, parent )
{
XmlElement questEl = xml["quest"];
ReadType( questEl, "type", ref m_Quest );
ReadType( questEl, "min", ref m_MinObjective, false );
ReadType( questEl, "max", ref m_MaxObjective, false );
ReadInt32( questEl, "message", ref m_Message, false );
}
public override bool OnMoveInto( Mobile m, Direction d, Point3D newLocation, Point3D oldLocation )
{
if ( !base.OnMoveInto ( m, d, newLocation, oldLocation ) )
return false;
if ( m.AccessLevel > AccessLevel.Player )
return true;
if( m is BaseCreature )
{
BaseCreature bc = m as BaseCreature;
if( !bc.Controlled && !bc.Summoned )
return true;
}
if ( m_Quest == null )
return true;
PlayerMobile player = m as PlayerMobile;
if ( player != null && player.Quest != null && player.Quest.GetType() == m_Quest
&& ( m_MinObjective == null || player.Quest.FindObjective( m_MinObjective ) != null )
&& ( m_MaxObjective == null || player.Quest.FindObjective( m_MaxObjective ) == null ) )
{
return true;
}
else
{
if ( m_Message != 0 )
m.SendLocalizedMessage( m_Message );
return false;
}
}
}
}

View file

@ -0,0 +1,43 @@
using System;
using System.Xml;
using Server;
using Server.Regions;
using Server.Mobiles;
namespace Server.Engines.Quests
{
public class QuestOfferRegion : BaseRegion
{
private Type m_Quest;
public Type Quest{ get{ return m_Quest ; } }
public QuestOfferRegion( XmlElement xml, Map map, Region parent ) : base( xml, map, parent )
{
ReadType( xml["quest"], "type", ref m_Quest );
}
public override void OnEnter( Mobile m )
{
base.OnEnter( m );
if ( m_Quest == null )
return;
PlayerMobile player = m as PlayerMobile;
if ( player != null && player.Quest == null && QuestSystem.CanOfferQuest( m, m_Quest ) )
{
try
{
QuestSystem qs = (QuestSystem) Activator.CreateInstance( m_Quest, new object[] { player } );
qs.SendOffer();
}
catch ( Exception ex )
{
Console.WriteLine( "Error creating quest {0}: {1}", m_Quest, ex );
}
}
}
}
}

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() );
}
}
}

View file

@ -0,0 +1,610 @@
using System;
using Server;
using Server.Items;
using Server.Mobiles;
namespace Server.Engines.Quests.Ninja
{
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()
{
System.AddObjective( new FindEminoBeginObjective() );
}
}
public class FindZoelConversation : QuestConversation
{
public override object Message
{
get
{
/* Ah, another fledgling unfurls its wings. Welcome to my
* home young one. <BR><BR>
*
* I am Daimyo Emino, a passionate collector of sorts.
* One who is vengeful towards those impeding my reign. <BR><BR>
*
* You have the look of someone who could help me but
* your skills are untested. Are you willing to prove
* your mettle as my hireling? <BR><BR>
*
* Elite Ninja Zoel awaits you in the backyard. He will
* lead you to the first trial. You will be directed
* further when you arrive at your destination. You
* should speak to him before exploring the yard or cave entrance.
*/
return 1063175;
}
}
public FindZoelConversation()
{
}
public override void OnRead()
{
System.AddObjective( new FindZoelObjective() );
}
}
public class RadarConversation : QuestConversation
{
public override object Message
{
get
{
/* To view the surrounding area, 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 1063033;
}
}
public override bool Logged{ get{ return false; } }
public RadarConversation()
{
}
}
public class EnterCaveConversation : QuestConversation
{
public override object Message
{
get
{
/* <I>Zoel studies your face as you approach him. Wryly, he says:</I><BR><BR>
*
* Daimyo Emino has sent another already? The stains from the
* last have not yet dried! <BR><BR>
*
* No matter, we’ll finish you off and clean it all at once, eh? <BR><BR>
*
* Now to the point, your only task is to survive in the abandoned inn.<BR><BR>
*
* You will be instructed when you need to act and when you should
* return to one of us. <BR><BR>
*
* Only a true Ninja is deft enough to finish and remain alive.<BR><BR>
*
* Your future... or your demise... lies in this cave beyond. <BR><BR>
*
* Now go.
*/
return 1063177;
}
}
public EnterCaveConversation()
{
}
public override void OnRead()
{
System.AddObjective( new EnterCaveObjective() );
}
}
public class SneakPastGuardiansConversation : QuestConversation
{
public override object Message
{
get
{
/* A glowing archway stands before you. <BR><BR>
*
* To either side of its frame are mounted demon heads,
* breathing fire and watching your every move. <BR><BR>
*
* To pass through, you must first vanish from the demons’
* sight. Only then can you slowly traverse the entryway.
*/
return 1063180;
}
}
public SneakPastGuardiansConversation()
{
}
public override void OnRead()
{
System.AddObjective( new SneakPastGuardiansObjective() );
}
}
public class NeedToHideConversation : QuestConversation
{
public override object Message
{
get
{
/* You’ll need to hide in order to pass through the door. <BR><BR>
*
* To find out how to use active skills, visit the
* <a href = "?ForceTopic73">Codex of Wisdom</a>.
* To activate a skill, locate it on your skills
* list and click the blue button located to the
* left of the skill's name.<br><br>Once you have
* successfully hidden, you may move slowly through the door.
*
*/
return 1063181;
}
}
public NeedToHideConversation()
{
}
}
public class UseTeleporterConversation : QuestConversation
{
public override object Message
{
get
{
/*
* Through the door lies a short passageway.
* The path ends abruptly at a strange tile on the floor.
* The special tile is known as a teleporter.
* Step on the teleporter tile and you will be transported
* to a new location.
*/
return 1063182;
}
}
public UseTeleporterConversation()
{
}
public override void OnRead()
{
System.AddObjective( new UseTeleporterObjective() );
}
}
public class GiveZoelNoteConversation : QuestConversation
{
public override object Message
{
get
{
/* <I>Daimyo Emino smiles as you approach him:</I> <BR><BR>
*
* I see that you have survived both the first trial and Zoel’s temper. <BR><BR>
*
* For that you have been rewarded with Leggings and Gloves
* befitting your occupation. The material is the only armor
* a <b><I>True Ninja</i></b> needs. <BR><BR>
*
* You have yet to prove yourself fully, young hireling.
* Another trial must be met. Off to Zoel you go.
* Bring him this note so he knows we have spoken.
*/
return 1063184;
}
}
public GiveZoelNoteConversation()
{
}
public override void OnRead()
{
System.AddObjective( new GiveZoelNoteObjective() );
}
}
public class LostNoteConversation : QuestConversation
{
public override object Message
{
get
{
// You have lost my note? I will scribe another for you. Try not to lose this one.
return 1063187;
}
}
public override bool Logged{ get{ return false; } }
public LostNoteConversation()
{
}
}
public class GainInnInformationConversation : QuestConversation
{
public override object Message
{
get
{
/* <I>Zoel quickly grabs the scroll from your
* hand and reads the note:</i> <BR><BR>
*
* Still alive then? You’ll have to impress me
* further before I will give my approval of
* you to Daimyo Emino. <BR><BR>
*
* You must return to the inn and begin the next trial. <BR><BR>
*
* We believe an associate has, shall we say,
* inadvertently negated our contract. <BR><BR>
*
* Find out what information you can and return
* to Daimyo Emino with the news. And be careful
* not to lose your head.<BR><BR>
*
* The Blue Teleporter Tile in Daimyo Emino’s
* residence will lead you to your fate.
* I suggest you hurry. <BR><BR>
*
* ...And take care to tread softly. There
* is no greater traitor than a heavy footfall upon a path.
*/
return 1063189;
}
}
public GainInnInformationConversation()
{
}
public override void OnRead()
{
System.AddObjective( new GainInnInformationObjective() );
}
}
public class ReturnFromInnConversation : QuestConversation
{
public override object Message
{
get
{
/* You quietly approach the door and see
* a woman named Jedah Entille speaking
* to a shady figure in dark clothing.
* You move closer so you can overhear
* the conversation. Fortunately, your
* entrance did not alert the preoccupied party. <BR><BR>
*
* Jedah’s brash voice permeates the air:<I><BR><BR>
*
* Now that it is hidden, we’ll hide out here
* until Daimyo Emino forgets about us.
* Once he realizes his beloved sword is missing,
* he’ll surely start looking for the thieves.
* We will be long gone by that time. </I><BR><BR>
*
* After overhearing the conversation,
* you understand why you were sent on
* this trial. You must immediately tell
* Daimyo Emino what you have learned.
* */
return 1063196;
}
}
public ReturnFromInnConversation()
{
}
public override void OnRead()
{
System.AddObjective( new ReturnFromInnObjective() );
}
}
public class SearchForSwordConversation : QuestConversation
{
public override object Message
{
get
{
/* <I>Daimyo Emino frowns as you relay the information.
* He pauses for a moment before speaking to you:</i> <BR><BR>
*
* Jedah was once one of my most promising students,
* but her greed will be her downfall. <BR><BR>
*
* I will send one of my disciples to deal with her later.
* It is more important to get that sword back first. <BR><BR>
*
* I’m counting on you to find it. She would have kept it
* close to her. Take the White Teleporter, located in my
* backyard, and check inside boxes and chests around the
* treasure room of the inn and return it to me when you
* find it.<BR><BR>
*
* Be very careful. Jedah was an expert with traps and no
* doubt she’s protecting the sword with them. <BR><BR>
*
* If you find a trap, try timing it and you may be able
* to avoid damage. <BR><BR>
*
* I’ve provided you with several heal potions in case you
* become injured. <BR><BR>
*
* In the bag you will also find more clothing appropriate
* to your new found profession. <BR><BR>
*
* Please return the sword to me. I implore you not to take
* anything else that may be hidden in the Inn. <BR><BR>
*
* Thank you.
*/
return 1063199;
}
}
public SearchForSwordConversation()
{
}
public override void OnRead()
{
System.AddObjective( new SearchForSwordObjective() );
}
}
public class HallwayWalkConversation : QuestConversation
{
public override object Message
{
get
{
/* A narrow hallway greets the teleporter.
* The enclosed space is the perfect setting
* for dangerous traps. Walk through the
* hallway being careful to avoid the traps.
* You may be able to time the traps to avoid injury.
*/
return 1063201;
}
}
public HallwayWalkConversation()
{
}
public override void OnRead()
{
System.AddObjective( new HallwayWalkObjective() );
}
}
public class ReturnSwordConversation : QuestConversation
{
public override object Message
{
get
{
/* The lid of the chest refuses to budge at first,
* but slowly you are able to pry the lid open. <BR><BR>
*
* Inside lies the sword you have been in search of.
* You quickly take the sword and stash it in your backpack.
* Bring the sword back to Daimyo Emino.
*/
return 1063203;
}
}
public ReturnSwordConversation()
{
}
public override void OnRead()
{
System.AddObjective( new ReturnSwordObjective() );
}
}
public class SlayHenchmenConversation : QuestConversation
{
public override object Message
{
get
{
/* Screams echo through the chamber as you walk
* away from the chest. Jedah’s Henchmen have
* become cognizant of your presence. <BR><BR>
*
* It is time for your Ninja Spirit to come alive.
* Slay 3 of the Henchmen before returning to Daimyo Emino.
*/
return 1063205;
}
}
public SlayHenchmenConversation()
{
}
public override void OnRead()
{
System.AddObjective( new SlayHenchmenObjective() );
}
}
public class ContinueSlayHenchmenConversation : QuestConversation
{
public override object Message
{
get
{
// Continue killing the henchmen!
return 1063208;
}
}
public override bool Logged{ get{ return false; } }
public ContinueSlayHenchmenConversation()
{
}
}
public class GiveEminoSwordConversation : QuestConversation
{
public override object Message
{
get
{
/* Go to Daimyo Emino. Go back through the chamber the way you came.<BR><BR>
*
* Give Daimyo Emino the sword when you've returned to his side.
*/
return 1063211;
}
}
public GiveEminoSwordConversation()
{
}
public override void OnRead()
{
System.AddObjective( new GiveEminoSwordObjective() );
}
}
public class LostSwordConversation : QuestConversation
{
public override object Message
{
get
{
// What? You have returned without the sword? You need to go back and get it again!
return 1063212;
}
}
public override bool Logged{ get{ return false; } }
public LostSwordConversation()
{
}
}
public class EarnGiftsConversation : QuestConversation
{
public override object Message
{
get
{
/* Beyond this path lies Zento City, your future home.
* To the right of the cave entrance you will find a luminous oval
* object known as a Moongate, step through it and you'll
* find yourself in Zento.<BR><BR>
*
* You may want to visit Ansella Gryen when you arrive. <BR><BR>
*
* Please accept the gifts I have placed in your pack. You
* have earned them. Farewell for now.
*/
return 1063216;
}
}
public EarnGiftsConversation()
{
}
public override void OnRead()
{
System.Complete();
}
}
public class EarnLessGiftsConversation : QuestConversation
{
public override object Message
{
get
{
/* You have earned these gifts for returning the sword.
* For that I thank you. <BR><BR>
*
* However, your reward has been lessened by your greed
* in the treasure room. Do not think I did not notice your full pockets.
*/
return 1063217;
}
}
public EarnLessGiftsConversation()
{
}
public override void OnRead()
{
System.Complete();
}
}
}

View file

@ -0,0 +1,159 @@
using System;
using Server;
using Server.Items;
using Server.Mobiles;
namespace Server.Engines.Quests.Ninja
{
public class EminosUndertakingQuest : QuestSystem
{
private static Type[] m_TypeReferenceTable = new Type[]
{
typeof( Ninja.AcceptConversation ),
typeof( Ninja.FindZoelConversation ),
typeof( Ninja.RadarConversation ),
typeof( Ninja.EnterCaveConversation ),
typeof( Ninja.SneakPastGuardiansConversation ),
typeof( Ninja.NeedToHideConversation ),
typeof( Ninja.UseTeleporterConversation ),
typeof( Ninja.GiveZoelNoteConversation ),
typeof( Ninja.LostNoteConversation ),
typeof( Ninja.GainInnInformationConversation ),
typeof( Ninja.ReturnFromInnConversation ),
typeof( Ninja.SearchForSwordConversation ),
typeof( Ninja.HallwayWalkConversation ),
typeof( Ninja.ReturnSwordConversation ),
typeof( Ninja.SlayHenchmenConversation ),
typeof( Ninja.ContinueSlayHenchmenConversation ),
typeof( Ninja.GiveEminoSwordConversation ),
typeof( Ninja.LostSwordConversation ),
typeof( Ninja.EarnGiftsConversation ),
typeof( Ninja.EarnLessGiftsConversation ),
typeof( Ninja.FindEminoBeginObjective ),
typeof( Ninja.FindZoelObjective ),
typeof( Ninja.EnterCaveObjective ),
typeof( Ninja.SneakPastGuardiansObjective ),
typeof( Ninja.UseTeleporterObjective ),
typeof( Ninja.GiveZoelNoteObjective ),
typeof( Ninja.GainInnInformationObjective ),
typeof( Ninja.ReturnFromInnObjective ),
typeof( Ninja.SearchForSwordObjective ),
typeof( Ninja.HallwayWalkObjective ),
typeof( Ninja.ReturnSwordObjective ),
typeof( Ninja.SlayHenchmenObjective ),
typeof( Ninja.GiveEminoSwordObjective )
};
public override Type[] TypeReferenceTable{ get{ return m_TypeReferenceTable; } }
public override object Name
{
get
{
// Emino's Undertaking
return 1063173;
}
}
public override object OfferMessage
{
get
{
// Your value as a Ninja must be proven. Find Daimyo Emino and accept the test he offers.
return 1063174;
}
}
public override TimeSpan RestartDelay{ get{ return TimeSpan.MaxValue; } }
public override bool IsTutorial{ get{ return true; } }
public override int Picture{ get{ return 0x15D5; } }
public EminosUndertakingQuest( PlayerMobile from ) : base( from )
{
}
// Serialization
public EminosUndertakingQuest()
{
}
public override void Accept()
{
base.Accept();
AddConversation( new AcceptConversation() );
}
private bool m_SentRadarConversion;
public override void Slice()
{
if ( !m_SentRadarConversion && ( From.Map != Map.Malas || From.X < 407 || From.X > 431 || From.Y < 801 || From.Y > 830 ) )
{
m_SentRadarConversion = true;
AddConversation( new RadarConversation() );
}
base.Slice();
}
public override void ChildDeserialize( GenericReader reader )
{
int version = reader.ReadEncodedInt();
m_SentRadarConversion = reader.ReadBool();
}
public override void ChildSerialize( GenericWriter writer )
{
writer.WriteEncodedInt( (int) 0 ); // version
writer.Write( (bool) m_SentRadarConversion );
}
public static bool HasLostNoteForZoel( Mobile from )
{
PlayerMobile pm = from as PlayerMobile;
if ( pm == null )
return false;
QuestSystem qs = pm.Quest;
if ( qs is EminosUndertakingQuest )
{
if ( qs.IsObjectiveInProgress( typeof( GiveZoelNoteObjective ) ) )
{
Container pack = from.Backpack;
return ( pack == null || pack.FindItemByType( typeof( NoteForZoel ) ) == null );
}
}
return false;
}
public static bool HasLostEminosKatana( Mobile from )
{
PlayerMobile pm = from as PlayerMobile;
if ( pm == null )
return false;
QuestSystem qs = pm.Quest;
if ( qs is EminosUndertakingQuest )
{
if ( qs.IsObjectiveInProgress( typeof( GiveEminoSwordObjective ) ) )
{
Container pack = from.Backpack;
return ( pack == null || pack.FindItemByType( typeof( EminosKatana ) ) == null );
}
}
return false;
}
}
}

View file

@ -0,0 +1,51 @@
using System;
using Server;
using Server.Mobiles;
namespace Server.Engines.Quests.Ninja
{
public class BlueNinjaQuestTeleporter : DynamicTeleporter
{
public override int LabelNumber{ get{ return 1026157; } } // teleporter
[Constructable]
public BlueNinjaQuestTeleporter() : base( 0x51C, 0x2 )
{
}
public override int NotWorkingMessage{ get{ return 1063198; } } // You stand on the strange floor tile but nothing happens.
public override bool GetDestination( PlayerMobile player, ref Point3D loc, ref Map map )
{
QuestSystem qs = player.Quest;
if ( qs is EminosUndertakingQuest && qs.FindObjective( typeof( GainInnInformationObjective ) ) != null )
{
loc = new Point3D( 411, 1116, 0 );
map = Map.Malas;
return true;
}
return false;
}
public BlueNinjaQuestTeleporter( 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,48 @@
using System;
using Server.Mobiles;
using Server.Items;
namespace Server.Engines.Quests.Ninja
{
public class EminosKatana : QuestItem
{
public override int LabelNumber{ get{ return 1063214; } } // Daimyo Emino's Katana
[Constructable]
public EminosKatana() : base( 0x13FF )
{
Weight = 1.0;
}
public EminosKatana( Serial serial ) : base( serial )
{
}
public override bool CanDrop( PlayerMobile player )
{
EminosUndertakingQuest qs = player.Quest as EminosUndertakingQuest;
if ( qs == null )
return true;
/*return !qs.IsObjectiveInProgress( typeof( ReturnSwordObjective ) )
&& !qs.IsObjectiveInProgress( typeof( SlayHenchmenObjective ) )
&& !qs.IsObjectiveInProgress( typeof( GiveEminoSwordObjective ) );*/
return false;
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.WriteEncodedInt( 0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadEncodedInt();
}
}
}

View file

@ -0,0 +1,148 @@
using System;
using Server;
using Server.Items;
using Server.Mobiles;
using Server.Network;
namespace Server.Engines.Quests.Ninja
{
public class EminosKatanaChest : WoodenChest
{
[Constructable]
public EminosKatanaChest()
{
Movable = false;
ItemID = 0xE42;
GenerateTreasure();
}
public EminosKatanaChest( Serial serial ) : base( serial )
{
}
public override bool IsDecoContainer{ get{ return false; } }
private void GenerateTreasure()
{
for ( int i = this.Items.Count - 1; i >= 0; i-- )
this.Items[i].Delete();
for ( int i = 0; i < 75; i++ )
{
switch ( Utility.Random( 3 ) )
{
case 0: DropItem( new GoldBracelet() ); break;
case 1: DropItem( new GoldRing() ); break;
case 2: DropItem( Loot.RandomGem() ); break;
}
}
}
public override void OnDoubleClick( Mobile from )
{
PlayerMobile player = from as PlayerMobile;
if ( player != null && player.InRange( GetWorldLocation(), 2 ) )
{
QuestSystem qs = player.Quest;
if ( qs is EminosUndertakingQuest )
{
if ( EminosUndertakingQuest.HasLostEminosKatana( from ) )
{
Item katana = new EminosKatana();
if ( !player.PlaceInBackpack( katana ) )
{
katana.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
{
QuestObjective obj = qs.FindObjective( typeof( HallwayWalkObjective ) );
if ( obj != null && !obj.Completed )
{
Item katana = new EminosKatana();
if ( player.PlaceInBackpack( katana ) )
{
GenerateTreasure();
obj.Complete();
}
else
{
katana.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.
}
}
}
}
}
base.OnDoubleClick( from );
}
public override bool CheckHold( Mobile m, Item item, bool message, bool checkItems, int plusItems, int plusWeight )
{
return false;
}
public override bool CheckItemUse( Mobile from, Item item )
{
return item == this;
}
public override bool CheckLift( Mobile from, Item item, ref LRReason reject )
{
if ( from.AccessLevel >= AccessLevel.GameMaster )
return true;
PlayerMobile player = from as PlayerMobile;
if ( player != null && player.Quest is EminosUndertakingQuest )
{
HallwayWalkObjective obj = player.Quest.FindObjective( typeof( HallwayWalkObjective ) ) as HallwayWalkObjective;
if ( obj != null )
{
if ( obj.StolenTreasure )
from.SendLocalizedMessage( 1063247 ); // The guard is watching you carefully! It would be unwise to remove another item from here.
else
return true;
}
}
return false;
}
public override void OnItemLifted( Mobile from, Item item )
{
PlayerMobile player = from as PlayerMobile;
if ( player != null && player.Quest is EminosUndertakingQuest )
{
HallwayWalkObjective obj = player.Quest.FindObjective( typeof( HallwayWalkObjective ) ) as HallwayWalkObjective;
if ( obj != null )
obj.StolenTreasure = true;
}
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.WriteEncodedInt( 0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadEncodedInt();
}
}
}

View file

@ -0,0 +1,51 @@
using System;
using Server;
using Server.Mobiles;
namespace Server.Engines.Quests.Ninja
{
public class GreenNinjaQuestTeleporter : DynamicTeleporter
{
public override int LabelNumber{ get{ return 1026157; } } // teleporter
[Constructable]
public GreenNinjaQuestTeleporter() : base( 0x51C, 0x17E )
{
}
public override int NotWorkingMessage{ get{ return 1063198; } } // You stand on the strange floor tile but nothing happens.
public override bool GetDestination( PlayerMobile player, ref Point3D loc, ref Map map )
{
QuestSystem qs = player.Quest;
if ( qs is EminosUndertakingQuest && qs.FindObjective( typeof( UseTeleporterObjective ) ) != null )
{
loc = new Point3D( 410, 1125, 0 );
map = Map.Malas;
return true;
}
return false;
}
public GreenNinjaQuestTeleporter( 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,82 @@
using System;
using Server;
using Server.Items;
using Server.Mobiles;
namespace Server.Engines.Quests.Ninja
{
public class GuardianBarrier : Item
{
[Constructable]
public GuardianBarrier() : base( 0x3967 )
{
Movable = false;
Visible = false;
}
public override bool OnMoveOver( Mobile m )
{
if ( m.AccessLevel > AccessLevel.Player )
return true;
// If the mobile is to the north of the barrier, allow him to pass
if ( this.Y >= m.Y )
return true;
if ( m is BaseCreature )
{
Mobile master = ((BaseCreature)m).GetMaster();
// Allow creatures to cross from the south to the north only if their master is near to the north
if ( master != null && this.Y >= master.Y && master.InRange( this, 4 ) )
return true;
else
return false;
}
PlayerMobile pm = m as PlayerMobile;
if ( pm != null )
{
EminosUndertakingQuest qs = pm.Quest as EminosUndertakingQuest;
if ( qs != null )
{
SneakPastGuardiansObjective obj = qs.FindObjective( typeof( SneakPastGuardiansObjective ) ) as SneakPastGuardiansObjective;
if ( obj != null )
{
if ( m.Hidden )
return true; // Hidden ninjas can pass
if ( !obj.TaughtHowToUseSkills )
{
obj.TaughtHowToUseSkills = true;
qs.AddConversation( new NeedToHideConversation() );
}
}
}
}
return false;
}
public GuardianBarrier( 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,48 @@
using System;
using Server;
using Server.Mobiles;
using Server.Engines.Quests;
namespace Server.Engines.Quests.Ninja
{
public class NoteForZoel : QuestItem
{
public override int LabelNumber{ get{ return 1063186; } } // A Note for Zoel
[Constructable]
public NoteForZoel() : base( 0x14EF )
{
Weight = 1.0;
Hue = 0x6B9;
}
public NoteForZoel( Serial serial ) : base( serial )
{
}
public override bool CanDrop( PlayerMobile player )
{
EminosUndertakingQuest qs = player.Quest as EminosUndertakingQuest;
if ( qs == null )
return true;
//return !qs.IsObjectiveInProgress( typeof( GiveZoelNoteObjective ) );
return false;
}
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,59 @@
using System;
using Server;
using Server.Mobiles;
namespace Server.Engines.Quests.Ninja
{
public class WhiteNinjaQuestTeleporter : DynamicTeleporter
{
public override int LabelNumber{ get{ return 1026157; } } // teleporter
[Constructable]
public WhiteNinjaQuestTeleporter() : base( 0x51C, 0x47E )
{
}
public override int NotWorkingMessage{ get{ return 1063198; } } // You stand on the strange floor tile but nothing happens.
public override bool GetDestination( PlayerMobile player, ref Point3D loc, ref Map map )
{
QuestSystem qs = player.Quest;
if ( qs is EminosUndertakingQuest )
{
QuestObjective obj = qs.FindObjective( typeof( SearchForSwordObjective ) );
if ( obj != null )
{
if ( !obj.Completed )
obj.Complete();
loc = new Point3D( 411, 1085, 0 );
map = Map.Malas;
return true;
}
}
return false;
}
public WhiteNinjaQuestTeleporter( 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,227 @@
using System;
using Server;
using Server.Mobiles;
using Server.Gumps;
using Server.Items;
namespace Server.Engines.Quests.Ninja
{
public class Emino : BaseQuester
{
[Constructable]
public Emino() : base( "the Notorious" )
{
}
public override void InitBody()
{
InitStats( 100, 100, 25 );
Hue = 0x83FE;
Female = false;
Body = 0x190;
Name = "Daimyo Emino";
}
public override void InitOutfit()
{
HairItemID = 0x203B;
HairHue = 0x901;
AddItem( new MaleKimono() );
AddItem( new SamuraiTabi() );
AddItem( new Bandana() );
AddItem( new PlateHaidate() );
AddItem( new PlateDo() );
AddItem( new PlateHiroSode() );
Nunchaku nunchaku = new Nunchaku();
nunchaku.Movable = false;
AddItem( nunchaku );
}
public override int GetAutoTalkRange( PlayerMobile pm )
{
return 2;
}
public override int TalkNumber{ get { return -1; } }
public override void OnTalk( PlayerMobile player, bool contextMenu )
{
QuestSystem qs = player.Quest;
if ( qs is EminosUndertakingQuest )
{
if ( EminosUndertakingQuest.HasLostNoteForZoel( player ) )
{
Item note = new NoteForZoel();
if ( player.PlaceInBackpack( note ) )
{
qs.AddConversation( new LostNoteConversation() );
}
else
{
note.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 if ( EminosUndertakingQuest.HasLostEminosKatana( player ) )
{
qs.AddConversation( new LostSwordConversation() );
}
else
{
QuestObjective obj = qs.FindObjective( typeof( FindEminoBeginObjective ) );
if ( obj != null && !obj.Completed )
{
obj.Complete();
}
else
{
obj = qs.FindObjective( typeof( UseTeleporterObjective ) );
if ( obj != null && !obj.Completed )
{
Item note = new NoteForZoel();
if ( player.PlaceInBackpack( note ) )
{
obj.Complete();
player.AddToBackpack( new LeatherNinjaPants() );
player.AddToBackpack( new LeatherNinjaMitts() );
}
else
{
note.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 = qs.FindObjective( typeof( ReturnFromInnObjective ) );
if ( obj != null && !obj.Completed )
{
Container cont = GetNewContainer();
for ( int i = 0; i < 10; i++ )
cont.DropItem( new LesserHealPotion() );
cont.DropItem( new LeatherNinjaHood() );
cont.DropItem( new LeatherNinjaJacket() );
if ( player.PlaceInBackpack( cont ) )
{
obj.Complete();
}
else
{
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
{
if ( qs.IsObjectiveInProgress( typeof( SlayHenchmenObjective ) ) )
{
qs.AddConversation( new ContinueSlayHenchmenConversation() );
}
else
{
obj = qs.FindObjective( typeof( GiveEminoSwordObjective ) );
if ( obj != null && !obj.Completed )
{
Item katana = null;
if ( player.Backpack != null )
katana = player.Backpack.FindItemByType( typeof( EminosKatana ) );
if ( katana != null )
{
bool stolenTreasure = false;
HallwayWalkObjective walk = qs.FindObjective( typeof( HallwayWalkObjective ) ) as HallwayWalkObjective;
if ( walk != null )
stolenTreasure = walk.StolenTreasure;
Kama kama = new Kama();
if ( stolenTreasure )
BaseRunicTool.ApplyAttributesTo( kama, 1, 10, 20 );
else
BaseRunicTool.ApplyAttributesTo( kama, 1, 10, 30 );
if ( player.PlaceInBackpack( kama ) )
{
katana.Delete();
obj.Complete();
if ( stolenTreasure )
qs.AddConversation( new EarnLessGiftsConversation() );
else
qs.AddConversation( new EarnGiftsConversation() );
}
else
{
kama.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.
}
}
}
}
}
}
}
}
}
}
public override void OnMovement( Mobile m, Point3D oldLocation )
{
base.OnMovement( m, oldLocation );
if ( !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 Emino( 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,56 @@
using System;
using Server;
using Server.Mobiles;
using Server.Items;
using Server.Network;
namespace Server.Engines.Quests.Ninja
{
public class EnshroudedFigure : BaseQuester
{
[Constructable]
public EnshroudedFigure()
{
}
public override void InitBody()
{
InitStats( 100, 100, 25 );
Hue = 0x8401;
Female = false;
Body = 0x190;
Name = "enshrouded figure";
}
public override void InitOutfit()
{
AddItem( new DeathShroud() );
AddItem( new ThighBoots() );
}
public override int TalkNumber{ get{ return -1; } }
public override void OnTalk( PlayerMobile player, bool contextMenu )
{
}
public EnshroudedFigure( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.WriteEncodedInt( 0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadEncodedInt();
}
}
}

View file

@ -0,0 +1,55 @@
using System;
using Server;
using Server.Mobiles;
using Server.Items;
namespace Server.Engines.Quests.Ninja
{
public class Henchman : BaseCreature
{
[Constructable]
public Henchman() : base( AIType.AI_Melee, FightMode.Aggressor, 10, 1, 0.2, 0.4 )
{
InitStats( 45, 30, 5 );
Hue = Utility.RandomSkinHue();
Body = 0x190;
Name = "a henchman";
Utility.AssignRandomHair( this );
Utility.AssignRandomFacialHair( this );
AddItem( new LeatherNinjaJacket() );
AddItem( new LeatherNinjaPants() );
AddItem( new NinjaTabi() );
if ( Utility.RandomBool() )
AddItem( new Kama() );
else
AddItem( new Tessen() );
SetSkill( SkillName.Swords, 50.0 );
SetSkill( SkillName.Tactics, 50.0 );
}
public override bool AlwaysMurderer{ get{ return true; } }
public Henchman( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.WriteEncodedInt( 0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadEncodedInt();
}
}
}

View file

@ -0,0 +1,96 @@
using System;
using Server;
using Server.Mobiles;
using Server.Items;
using Server.Network;
namespace Server.Engines.Quests.Ninja
{
public class HiddenFigure : BaseQuester
{
public static int[] Messages = new int[]
{
1063191, // They won’t find me here.
1063192 // Ah, a quiet hideout.
};
private int m_Message;
[CommandProperty( AccessLevel.GameMaster )]
public int Message{ get{ return m_Message; } set{ m_Message = value; } }
[Constructable]
public HiddenFigure()
{
m_Message = Utility.RandomList( Messages );
}
public override void InitBody()
{
InitStats( 100, 100, 25 );
Hue = Utility.RandomSkinHue();
Female = Utility.RandomBool();
if ( Female )
{
Body = 0x191;
Name = NameList.RandomName( "female" );
}
else
{
Body = 0x190;
Name = NameList.RandomName( "male" );
}
}
public override void InitOutfit()
{
Utility.AssignRandomHair( this );
AddItem( new TattsukeHakama( GetRandomHue() ) );
AddItem( new Kasa() );
AddItem( new HakamaShita( GetRandomHue() ) );
if ( Utility.RandomBool() )
AddItem( new Shoes( GetShoeHue() ) );
else
AddItem( new Sandals( GetShoeHue() ) );
}
public override int GetAutoTalkRange( PlayerMobile pm )
{
return 3;
}
public override int TalkNumber{ get{ return -1; } }
public override void OnTalk( PlayerMobile player, bool contextMenu )
{
PrivateOverheadMessage( MessageType.Regular, 0x3B2, m_Message, player.NetState );
}
public HiddenFigure( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.WriteEncodedInt( 0 ); // version
writer.Write( (int) m_Message );
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadEncodedInt();
m_Message = reader.ReadInt();
}
}
}

View file

@ -0,0 +1,60 @@
using System;
using Server;
using Server.Mobiles;
using Server.Items;
using Server.Network;
namespace Server.Engines.Quests.Ninja
{
public class JedahEntille : BaseQuester
{
[Constructable]
public JedahEntille() : base( "the Silent" )
{
}
public override void InitBody()
{
InitStats( 100, 100, 25 );
Hue = 0x83FE;
Female = true;
Body = 0x191;
Name = "Jedah Entille";
}
public override void InitOutfit()
{
HairItemID = 0x203C;
HairHue = 0x6BE;
AddItem( new PlainDress( 0x528 ) );
AddItem( new ThighBoots() );
AddItem( new FloppyHat() );
}
public override int TalkNumber{ get{ return -1; } }
public override void OnTalk( PlayerMobile player, bool contextMenu )
{
}
public JedahEntille( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.WriteEncodedInt( 0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadEncodedInt();
}
}
}

View file

@ -0,0 +1,138 @@
using System;
using Server;
using Server.Mobiles;
using Server.Items;
using Server.Gumps;
using Server.Engines.Quests;
namespace Server.Engines.Quests.Ninja
{
public class Zoel : BaseQuester
{
[Constructable]
public Zoel() : base( "the Masterful Tactician" )
{
}
public override void InitBody()
{
InitStats( 100, 100, 25 );
Hue = 0x83FE;
Female = false;
Body = 0x190;
Name = "Elite Ninja Zoel";
}
public override void InitOutfit()
{
HairItemID = 0x203B;
HairHue = 0x901;
AddItem( new HakamaShita( 0x1 ) );
AddItem( new NinjaTabi() );
AddItem( new TattsukeHakama() );
AddItem( new Bandana() );
AddItem( new LeatherNinjaBelt() );
Tekagi tekagi = new Tekagi();
tekagi.Movable = false;
AddItem( tekagi );
}
public override int TalkNumber{ get { return -1; } }
public override int GetAutoTalkRange( PlayerMobile pm )
{
return 2;
}
public override bool CanTalkTo( PlayerMobile to )
{
return to.Quest is EminosUndertakingQuest;
}
public override void OnTalk( PlayerMobile player, bool contextMenu )
{
QuestSystem qs = player.Quest;
if ( qs is EminosUndertakingQuest )
{
QuestObjective obj = qs.FindObjective( typeof( FindZoelObjective ) );
if ( obj != null && !obj.Completed )
obj.Complete();
}
}
public override bool OnDragDrop( Mobile from, Item dropped )
{
PlayerMobile player = from as PlayerMobile;
if ( player != null )
{
QuestSystem qs = player.Quest;
if ( qs is EminosUndertakingQuest )
{
if ( dropped is NoteForZoel )
{
QuestObjective obj = qs.FindObjective( typeof( GiveZoelNoteObjective ) );
if ( obj != null && !obj.Completed )
{
dropped.Delete();
obj.Complete();
return true;
}
}
}
}
return base.OnDragDrop( from, dropped );
}
public override void OnMovement( Mobile m, Point3D oldLocation )
{
base.OnMovement( m, oldLocation );
if ( !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 Zoel( 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,393 @@
using System;
using Server;
using Server.Items;
using Server.Mobiles;
namespace Server.Engines.Quests.Ninja
{
public class FindEminoBeginObjective : QuestObjective
{
public override object Message
{
get
{
// Your value as a Ninja must be proven. Find Daimyo Emino and accept the test he offers.
return 1063174;
}
}
public FindEminoBeginObjective()
{
}
public override void OnComplete()
{
System.AddConversation( new FindZoelConversation() );
}
}
public class FindZoelObjective : QuestObjective
{
public override object Message
{
get
{
// Find Elite Ninja Zoel immediately!
return 1063176;
}
}
public FindZoelObjective()
{
}
public override void OnComplete()
{
System.AddConversation( new EnterCaveConversation() );
}
}
public class EnterCaveObjective : QuestObjective
{
public override object Message
{
get
{
// Enter the cave and walk through it. You will be tested as you travel along the path.
return 1063179;
}
}
public EnterCaveObjective()
{
}
public override void CheckProgress()
{
if ( System.From.Map == Map.Malas && System.From.InRange( new Point3D( 406, 1141, 0 ), 2 ) )
Complete();
}
public override void OnComplete()
{
System.AddConversation( new SneakPastGuardiansConversation() );
}
}
public class SneakPastGuardiansObjective : QuestObjective
{
private bool m_TaughtHowToUseSkills;
public bool TaughtHowToUseSkills
{
get{ return m_TaughtHowToUseSkills; }
set{ m_TaughtHowToUseSkills = value; }
}
public override object Message
{
get
{
// Use your Ninja training to move invisibly past the magical guardians.
return 1063261;
}
}
public SneakPastGuardiansObjective()
{
}
public override void CheckProgress()
{
if ( System.From.Map == Map.Malas && System.From.InRange( new Point3D( 412, 1123, 0 ), 3 ) )
Complete();
}
public override void OnComplete()
{
System.AddConversation( new UseTeleporterConversation() );
}
public override void ChildDeserialize( GenericReader reader )
{
int version = reader.ReadEncodedInt();
m_TaughtHowToUseSkills = reader.ReadBool();
}
public override void ChildSerialize( GenericWriter writer )
{
writer.WriteEncodedInt( (int) 0 ); // version
writer.Write( (bool) m_TaughtHowToUseSkills );
}
}
public class UseTeleporterObjective : QuestObjective
{
public override object Message
{
get
{
/* The special tile is known as a teleporter.
* Step on the teleporter tile and you will be transported to a new location.
*/
return 1063183;
}
}
public UseTeleporterObjective()
{
}
public override void OnComplete()
{
System.AddConversation( new GiveZoelNoteConversation() );
}
}
public class GiveZoelNoteObjective : QuestObjective
{
public override object Message
{
get
{
/* Bring the note to Elite Ninja Zoel and speak with him again.
* He is near the cave entrance. You can hand the note to Zoel
* by dragging it and dropping it on his body.
*/
return 1063185;
}
}
public GiveZoelNoteObjective()
{
}
public override void OnComplete()
{
System.AddConversation( new GainInnInformationConversation() );
}
}
public class GainInnInformationObjective : QuestObjective
{
public override object Message
{
get
{
/* Take the Blue Teleporter Tile from Daimyo Emino's
* house to the Abandoned Inn. Quietly look around
* to gain information.
*/
return 1063190;
}
}
public GainInnInformationObjective()
{
}
public override void CheckProgress()
{
Mobile from = System.From;
if ( from.Map == Map.Malas && from.X > 399 && from.X < 408 && from.Y > 1091 && from.Y < 1099 )
Complete();
}
public override void OnComplete()
{
System.AddConversation( new ReturnFromInnConversation() );
}
}
public class ReturnFromInnObjective : QuestObjective
{
public override object Message
{
get
{
// Go back through the blue teleporter and tell Daimyo Emino what you’ve overheard.
return 1063197;
}
}
public ReturnFromInnObjective()
{
}
public override void OnComplete()
{
System.AddConversation( new SearchForSwordConversation() );
}
}
public class SearchForSwordObjective : QuestObjective
{
public override object Message
{
get
{
/* Take the white teleporter and check the chests for the sword.
* Leave everything else behind. Avoid damage from traps you may
* encounter. To use a potion, make sure at least one hand is
* free and double click on the bottle.
*/
return 1063200;
}
}
public SearchForSwordObjective()
{
}
public override void OnComplete()
{
System.AddConversation( new HallwayWalkConversation() );
}
}
public class HallwayWalkObjective : QuestObjective
{
private bool m_StolenTreasure;
public bool StolenTreasure
{
get{ return m_StolenTreasure; }
set{ m_StolenTreasure = value; }
}
public override object Message
{
get
{
/* Walk through the hallway being careful
* to avoid the traps. You may be able to
* time the traps to avoid injury.
*/
return 1063202;
}
}
public HallwayWalkObjective()
{
}
public override void OnComplete()
{
System.AddConversation( new ReturnSwordConversation() );
}
public override void ChildDeserialize( GenericReader reader )
{
int version = reader.ReadEncodedInt();
m_StolenTreasure = reader.ReadBool();
}
public override void ChildSerialize( GenericWriter writer )
{
writer.WriteEncodedInt( (int) 0 ); // version
writer.Write( (bool) m_StolenTreasure );
}
}
public class ReturnSwordObjective : QuestObjective
{
public override object Message
{
get
{
// Take the sword and bring it back to Daimyo Emino.
return 1063204;
}
}
public ReturnSwordObjective()
{
}
public override void CheckProgress()
{
Mobile from = System.From;
if ( from.Map != Map.Malas || from.Y > 992 )
Complete();
}
public override void OnComplete()
{
System.AddConversation( new SlayHenchmenConversation() );
}
}
public class SlayHenchmenObjective : QuestObjective
{
public override object Message
{
get
{
// Kill three henchmen.
return 1063206;
}
}
public SlayHenchmenObjective()
{
}
public override int MaxProgress{ get{ return 3; } }
public override void RenderProgress( BaseQuestGump gump )
{
if ( !Completed )
{
// Henchmen killed:
gump.AddHtmlLocalized( 70, 260, 270, 100, 1063207, BaseQuestGump.Blue, false, false );
gump.AddLabel( 70, 280, 0x64, CurProgress.ToString() );
gump.AddLabel( 100, 280, 0x64, "/" );
gump.AddLabel( 130, 280, 0x64, MaxProgress.ToString() );
}
else
{
base.RenderProgress( gump );
}
}
public override void OnKill( BaseCreature creature, Container corpse )
{
if ( creature is Henchman )
CurProgress++;
}
public override void OnComplete()
{
System.AddConversation( new GiveEminoSwordConversation() );
}
}
public class GiveEminoSwordObjective : QuestObjective
{
public override object Message
{
get
{
/* You have proven your fighting skills. Bring the Sword to
* Daimyo Emino immediately. Be sure to follow the
* path back to the teleporter.
*/
return 1063210;
}
}
public GiveEminoSwordObjective()
{
}
public override void OnComplete()
{
}
}
}

View file

@ -0,0 +1,713 @@
using System;
using Server;
using Server.Items;
using Server.Mobiles;
namespace Server.Engines.Quests.Samurai
{
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()
{
System.AddObjective( new FindHaochiObjective() );
}
}
public class RadarConversation : QuestConversation
{
public override object Message
{
get
{
/* To view the surrounding area, 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 1063033;
}
}
public override bool Logged{ get{ return false; } }
public RadarConversation()
{
}
}
public class FirstTrialIntroConversation : QuestConversation
{
public override object Message
{
get
{
/* Greetings. I am Daimyo Haochi, the Feudal Lord of this region. <BR><BR>
*
* Since you are here at my side, you must wish to learn the ways of the Samurai.<BR><BR>
*
* Wielding a blade is easy, anyone can grasp a sword’s hilt. Learning how to
* fight properly and skillfully is to become an Armsman.<BR><BR>
*
* Learning how to master weapons, and even more importantly when not to use
* them, is the Way of the Warrior. The Way of the Samurai. The Code of the
* Bushido. That is why you are here. <BR><BR>
*
* You will go through 7 trials to prove your adherence to the Samurai code. <BR><BR>
*
* The first trial will test your decision making skills. You only have to enter
* the area beyond the green passageway. <BR><BR>
*
* Do not attempt to hurry your trials. The guards will only let you through
* to each trial when I have deemed you ready.<br><br>
*
* As a last resort you may use the golden teleporter tiles in each trial area
* but do so at your own risk. You may not be able to return and complete your
* trials once you have chosen to escape.
*/
return 1063029;
}
}
public FirstTrialIntroConversation()
{
}
public override void OnRead()
{
System.AddObjective( new FirstTrialIntroObjective() );
}
}
public class FirstTrialKillConversation : QuestConversation
{
public override object Message
{
get
{
/* Beyond you are two troubled groups.<BR><BR>
*
* The Cursed Souls were once proud warriors that were ensorcelled
* by an evil mage. The mage trapped and killed them later but the spell
* has not lifted from their souls in death. <BR><BR>
*
* The Young Ronin were former Samurai in training who lost their way.
* They are loyal only to those with enough coin in their pocket. <BR><BR>
*
* You must decide who needs to be fought to the death. You may wish to
* <a href="?ForceTopic27">review combat techniques</a> as well as
* <a href = "?ForceTopic29">information on healing yourself</a>. <BR><BR>
*
* Return to Daimyo Haochi after you have finished with your trial.<br><br>
*
* If you should die during any of your trials, visit one of the Ankh Shrines
* and you will be resurrected. You should retrieve your belongings from your
* body before returning to the Daimyo or you may not be able to return to your corpse.
*/
return 1063031;
}
}
public FirstTrialKillConversation()
{
}
public override void OnRead()
{
System.AddObjective( new FirstTrialKillObjective() );
}
}
public class GainKarmaConversation : QuestConversation
{
public override object Message
{
get
{
if ( m_CursedSoul )
{
// You have just gained some <a href="?ForceTopic45">Karma</a> for killing a Cursed Soul.
return 1063040;
}
else
{
// You have just gained some <a href="?ForceTopic45">Karma</a> for killing a Young Ronin.
return 1063041;
}
}
}
public override bool Logged{ get{ return false; } }
private bool m_CursedSoul;
public GainKarmaConversation( bool cursedSoul )
{
m_CursedSoul = cursedSoul;
}
public GainKarmaConversation()
{
}
public override void ChildDeserialize( GenericReader reader )
{
int version = reader.ReadEncodedInt();
m_CursedSoul = reader.ReadBool();
}
public override void ChildSerialize( GenericWriter writer )
{
writer.WriteEncodedInt( (int) 0 ); // version
writer.Write( (bool) m_CursedSoul );
}
}
public class SecondTrialIntroConversation : QuestConversation
{
public override object Message
{
get
{
if ( m_CursedSoul )
{
/* It is good that you rid the land of the Cursed Souls so they can
* be at peace in death. They had been cursed for doing what they
* thought was an honorable deed. Now they can have respect in their death.<BR><BR>
*
* I have placed a reward in your pack. <BR><BR>
*
* The second trial will test your courage. You only have to follow the yellow
* path to see what awaits you.
*/
return 1063045;
}
else
{
/* It is good that you rid the land of those dishonorable Samurai.
* Perhaps they will learn a greater lesson in death.<BR><BR>
*
* I have placed a reward in your pack.<BR><BR>
*
* The second trial will test your courage. You only have to follow
* the yellow path to see what awaits you.
*/
return 1063046;
}
}
}
private bool m_CursedSoul;
public SecondTrialIntroConversation( bool cursedSoul )
{
m_CursedSoul = cursedSoul;
}
public SecondTrialIntroConversation()
{
}
public override void OnRead()
{
System.AddObjective( new SecondTrialIntroObjective() );
}
public override void ChildDeserialize( GenericReader reader )
{
int version = reader.ReadEncodedInt();
m_CursedSoul = reader.ReadBool();
}
public override void ChildSerialize( GenericWriter writer )
{
writer.WriteEncodedInt( (int) 0 ); // version
writer.Write( (bool) m_CursedSoul );
}
}
public class SecondTrialAttackConversation : QuestConversation
{
public override object Message
{
get
{
/* Beyond the guards is a test of courage. You must face your fear and attack a
* great beast. You must choose which beast to slay for there is more than
* one beyond the courtyard doors. <BR><BR>
*
* The imp entered the courtyard unaware of its surroundings. The dragon came
* knowingly, hunting for the flesh of humans – A feast for the beast. <BR><BR>
*
* You must rid the courtyard of these beasts but you may only choose one to
* attack. Go and choose wisely.
*/
return 1063057;
}
}
public SecondTrialAttackConversation()
{
}
public override void OnRead()
{
System.AddObjective( new SecondTrialAttackObjective() );
}
}
public class ThirdTrialIntroConversation : QuestConversation
{
public override object Message
{
get
{
if ( m_Dragon )
{
/* You faced the dragon knowing it would be your certain death.
* That is the courage of a Samurai. <BR><BR>
*
* Your spirit speaks as a Samurai already. <BR><BR>
*
* In these lands, death is not forever. The shrines can make you whole
* again as can a helpful mage or healer. <BR><BR>
*
* Seek them out when you have been mortally wounded. <BR><BR>
*
* The next trial will test your benevolence. You only have to walk the blue path.
*/
return 1063060;
}
else
{
/* Fear remains in your eyes but you have learned that not all is
* what it appears to be. <BR><BR>
*
* You must have known the dragon would slay you instantly.
* You elected the weaker opponent though the imp did not come
* here to destroy. You have much to learn. <BR><BR>
*
* In these lands, death is not forever. The shrines can make you whole
* again as can a helpful mage or healer. <BR><BR>
*
* Seek them out when you have been mortally wounded. <BR><BR>
*
* The next trial will test your benevolence. You only have to walk the blue path.
*/
return 1063059;
}
}
}
private bool m_Dragon;
public ThirdTrialIntroConversation( bool dragon )
{
m_Dragon = dragon;
}
public ThirdTrialIntroConversation()
{
}
public override void OnRead()
{
System.AddObjective( new ThirdTrialIntroObjective() );
}
public override void ChildDeserialize( GenericReader reader )
{
int version = reader.ReadEncodedInt();
m_Dragon = reader.ReadBool();
}
public override void ChildSerialize( GenericWriter writer )
{
writer.WriteEncodedInt( (int) 0 ); // version
writer.Write( (bool) m_Dragon );
}
}
public class ThirdTrialKillConversation : QuestConversation
{
public override object Message
{
get
{
/* A pack of wolves circle your feet. They have been injured and are in pain.
* A quick death will end their suffering.<br><br>
*
* Use your Honorable Execution skill or other means to finish off a wounded wolf.
* Do so and return to Daimyo Haochi.
*/
return 1063062;
}
}
public ThirdTrialKillConversation()
{
}
public override void OnRead()
{
System.AddObjective( new ThirdTrialKillObjective() );
}
}
public class FourthTrialIntroConversation : QuestConversation
{
public override object Message
{
get
{
/* <I>Daimyo Haochi smiles as you walk up to him. Quietly he says:</I><BR><BR>
*
* A Samurai understands the need to help others even as he wields a blade against
* them. <BR><BR>
*
* You have shown compassion. A true Samurai is benevolent even to an enemy.
* For this you have been rewarded. <BR><BR>
*
* And now you must prove yourself again. Walk the red path.
* We will talk again later.
*/
return 1063065;
}
}
public FourthTrialIntroConversation()
{
}
public override void OnRead()
{
System.AddObjective( new FourthTrialIntroObjective() );
}
}
public class FourthTrialCatsConversation : QuestConversation
{
public override object Message
{
get
{
/* <I>You approach a disheveled gypsy standing near a small shed.
* You sense that she has not eaten nor bathed in quite some time. <BR><BR>
*
* Around her is a large colony of mangy and diseased cats. It appears
* she has spent what little money she’s earned to feed the cats instead
* of herself. <BR><BR>
*
* You have a decision to make. You can give her gold so she can buy some
* food for her animals and herself. You can also remove the necessity
* of the extra mouths to feed so she may concentrate on saving herself.</i><br><br>
*
* If you elect to give the gypsy money, you can do so by clicking your stack
* of gold and selecting ‘1’. Then dragging it and dropping it on the Gypsy.
*/
return 1063067;
}
}
public FourthTrialCatsConversation()
{
}
public override void OnRead()
{
System.AddObjective( new FourthTrialCatsObjective() );
}
}
public class FifthTrialIntroConversation : QuestConversation
{
public override object Message
{
get
{
if ( m_KilledCat )
{
/* Respect comes from allowing another to make their own decisions.
* By denying the gypsy her animals, you negate the respect she is due.
* Perhaps you will have learned something to use next time a similar
* situation arises. <BR><BR>
*
* And now you must prove yourself again. Please retrieve my katana
* from the treasure room and return it to me.
*/
return 1063071;
}
else
{
/* You showed respect by helping another out while allowing the gypsy
* what little dignity she has left. <BR><BR>
*
* Now she will be able to feed herself and gain enough energy to walk
* to her camp. <BR><BR>
*
* The cats are her family members– cursed by an evil mage. <BR><BR>
*
* Once she has enough strength to walk back to the camp, she will be
* able to undo the spell. <BR><BR>
*
* You have been rewarded for completing your trial. And now you must
* prove yourself again. <BR><BR>Please retrieve my katana from the
* treasure room and return it to me.
*/
return 1063070;
}
}
}
private bool m_KilledCat;
public FifthTrialIntroConversation( bool killedCat )
{
m_KilledCat = killedCat;
}
public FifthTrialIntroConversation()
{
}
public override void OnRead()
{
System.AddObjective( new FifthTrialIntroObjective() );
}
public override void ChildDeserialize( GenericReader reader )
{
int version = reader.ReadEncodedInt();
m_KilledCat = reader.ReadBool();
}
public override void ChildSerialize( GenericWriter writer )
{
writer.WriteEncodedInt( (int) 0 ); // version
writer.Write( (bool) m_KilledCat );
}
}
public class FifthTrialReturnConversation : QuestConversation
{
public override object Message
{
get
{
/* <i>The guards let you through without question, and pay you no mind as
* you walk into the Daimyo's treasure cache. A vast fortune in gold,
* gemstones, and jewelry is stored here! Surely, the Daimyo wouldn't
* miss a single small item...<br><br>
*
* You spot the sword quickly amongst the cache of gemstones and other valuables.
* In one quick motion you retrieve it and stash it in your pack.</i>
*/
return 1063248;
}
}
public FifthTrialReturnConversation()
{
}
public override void OnRead()
{
System.AddObjective( new FifthTrialReturnObjective() );
}
}
public class LostSwordConversation : QuestConversation
{
public override object Message
{
get
{
// What? You have returned without the sword? Go back and look for it again.
return 1063074;
}
}
public override bool Logged{ get{ return false; } }
public LostSwordConversation()
{
}
}
public class SixthTrialIntroConversation : QuestConversation
{
public override object Message
{
get
{
if ( m_StolenTreasure )
{
/* I thank you for returning this sword. However, you should admonished
* for also taking treasure that was not asked for nor given back. <BR><BR>
*
* Think about your actions youngling. <BR><BR>
*
* Your training is nearly complete. Before you have your final trial,
* you should pay homage to Samurai who came before you. <BR><BR>
*
* Go into the Altar Room and light a candle for them.
* Afterwards, return to me.
*/
return 1063077;
}
else
{
/* Thank you for returning this sword to me and leaving the remaining
* treasure alone. <BR><BR>
*
* Your training is nearly complete. Before you have your final trial,
* you should pay homage to Samurai who came before you. <BR><BR>
*
* Go into the Altar Room and light a candle for them. Afterwards, return to me.
*/
return 1063076;
}
}
}
private bool m_StolenTreasure;
public SixthTrialIntroConversation( bool stolenTreasure )
{
m_StolenTreasure = stolenTreasure;
}
public SixthTrialIntroConversation()
{
}
public override void OnRead()
{
System.AddObjective( new SixthTrialIntroObjective() );
}
public override void ChildDeserialize( GenericReader reader )
{
int version = reader.ReadEncodedInt();
m_StolenTreasure = reader.ReadBool();
}
public override void ChildSerialize( GenericWriter writer )
{
writer.WriteEncodedInt( (int) 0 ); // version
writer.Write( (bool) m_StolenTreasure );
}
}
public class SeventhTrialIntroConversation : QuestConversation
{
public override object Message
{
get
{
/* You have done well young Samurai. There is but one thing left to do. <BR><BR>
*
* In the final room is the holding cell containing young Ninjas who came to
* take my life. They were caught and placed in my custody. <BR><BR>
*
* Take care of these miscreants and show them where your loyalty lies. <BR><BR>
*
* This is your final act as a Samurai in training.
*/
return 1063079;
}
}
public SeventhTrialIntroConversation()
{
}
public override void OnRead()
{
System.AddObjective( new SeventhTrialIntroObjective() );
}
}
public class EndConversation : QuestConversation
{
public override object Message
{
get
{
/* You have proven yourself young one. You will continue to improve as your skills
* are honed with age. <BR><BR>
*
* Now it is time for you to explore the lands. Beyond this path lies Zento
* City, your future home. On these grounds you will find a golden oval object
* known as a Moongate, step through it and you'll find yourself in Zento.<BR><BR>
*
* You may want to visit Ansella Gryen when you arrive. <BR><BR>
*
* You have learned the ways. You are an honorable warrior, a Samurai in
* the highest regards. <BR><BR>
*
* Please accept the gifts I have placed in your pack. You have earned them.
* Farewell for now.
*/
return 1063125;
}
}
public EndConversation()
{
}
public override void OnRead()
{
System.Complete();
}
}
}

View file

@ -0,0 +1,151 @@
using System;
using Server;
using Server.Items;
using Server.Mobiles;
namespace Server.Engines.Quests.Samurai
{
public class HaochisTrialsQuest : QuestSystem
{
private static Type[] m_TypeReferenceTable = new Type[]
{
typeof( Samurai.AcceptConversation ),
typeof( Samurai.RadarConversation ),
typeof( Samurai.FirstTrialIntroConversation ),
typeof( Samurai.FirstTrialKillConversation ),
typeof( Samurai.GainKarmaConversation ),
typeof( Samurai.SecondTrialIntroConversation ),
typeof( Samurai.SecondTrialAttackConversation ),
typeof( Samurai.ThirdTrialIntroConversation ),
typeof( Samurai.ThirdTrialKillConversation ),
typeof( Samurai.FourthTrialIntroConversation ),
typeof( Samurai.FourthTrialCatsConversation ),
typeof( Samurai.FifthTrialIntroConversation ),
typeof( Samurai.FifthTrialReturnConversation ),
typeof( Samurai.LostSwordConversation ),
typeof( Samurai.SixthTrialIntroConversation ),
typeof( Samurai.SeventhTrialIntroConversation ),
typeof( Samurai.EndConversation ),
typeof( Samurai.FindHaochiObjective ),
typeof( Samurai.FirstTrialIntroObjective ),
typeof( Samurai.FirstTrialKillObjective ),
typeof( Samurai.FirstTrialReturnObjective ),
typeof( Samurai.SecondTrialIntroObjective ),
typeof( Samurai.SecondTrialAttackObjective ),
typeof( Samurai.SecondTrialReturnObjective ),
typeof( Samurai.ThirdTrialIntroObjective ),
typeof( Samurai.ThirdTrialKillObjective ),
typeof( Samurai.ThirdTrialReturnObjective ),
typeof( Samurai.FourthTrialIntroObjective ),
typeof( Samurai.FourthTrialCatsObjective ),
typeof( Samurai.FourthTrialReturnObjective ),
typeof( Samurai.FifthTrialIntroObjective ),
typeof( Samurai.FifthTrialReturnObjective ),
typeof( Samurai.SixthTrialIntroObjective ),
typeof( Samurai.SixthTrialReturnObjective ),
typeof( Samurai.SeventhTrialIntroObjective ),
typeof( Samurai.SeventhTrialReturnObjective )
};
public override Type[] TypeReferenceTable{ get{ return m_TypeReferenceTable; } }
public override object Name
{
get
{
// Haochi's Trials
return 1063022;
}
}
public override object OfferMessage
{
get
{
/* <i>As you enter the courtyard you notice a faded sign.
* It reads: </i><br><br>
*
* Welcome to your new home, Samurai.<br><br>
*
* Though your skills are only a shadow of what they can be some day,
* you must prove your adherence to the code of the Bushido.<br><br>
*
* Seek Daimyo Haochi for guidance.<br><br>
*
* <i>Will you accept the challenge?</i>
*/
return 1063023;
}
}
public override TimeSpan RestartDelay{ get{ return TimeSpan.MaxValue; } }
public override bool IsTutorial{ get{ return true; } }
public override int Picture{ get{ return 0x15D7; } }
public HaochisTrialsQuest( PlayerMobile from ) : base( from )
{
}
// Serialization
public HaochisTrialsQuest()
{
}
public override void Accept()
{
base.Accept();
AddConversation( new AcceptConversation() );
}
private bool m_SentRadarConversion;
public override void Slice()
{
if ( !m_SentRadarConversion && ( From.Map != Map.Malas || From.X < 360 || From.X > 400 || From.Y < 760 || From.Y > 780 ) )
{
m_SentRadarConversion = true;
AddConversation( new RadarConversation() );
}
base.Slice();
}
public override void ChildDeserialize( GenericReader reader )
{
int version = reader.ReadEncodedInt();
m_SentRadarConversion = reader.ReadBool();
}
public override void ChildSerialize( GenericWriter writer )
{
writer.WriteEncodedInt( 0 ); // version
writer.Write( (bool) m_SentRadarConversion );
}
public static bool HasLostHaochisKatana( Mobile from )
{
PlayerMobile pm = from as PlayerMobile;
if ( pm == null )
return false;
QuestSystem qs = pm.Quest;
if ( qs is HaochisTrialsQuest )
{
if ( qs.IsObjectiveInProgress( typeof( FifthTrialReturnObjective ) ) )
{
Container pack = from.Backpack;
return ( pack == null || pack.FindItemByType( typeof( HaochisKatana ) ) == null );
}
}
return false;
}
}
}

View file

@ -0,0 +1,46 @@
using System;
using Server.Mobiles;
using Server.Items;
namespace Server.Engines.Quests.Samurai
{
public class HaochisKatana : QuestItem
{
public override int LabelNumber{ get{ return 1063165; } } // Daimyo Haochi's Katana
[Constructable]
public HaochisKatana() : base( 0x13FF )
{
Weight = 1.0;
}
public HaochisKatana( Serial serial ) : base( serial )
{
}
public override bool CanDrop( PlayerMobile player )
{
HaochisTrialsQuest qs = player.Quest as HaochisTrialsQuest;
if ( qs == null )
return true;
//return !qs.IsObjectiveInProgress( typeof( FifthTrialReturnObjective ) );
return false;
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.WriteEncodedInt( 0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadEncodedInt();
}
}
}

View file

@ -0,0 +1,80 @@
using System;
using Server;
using Server.Mobiles;
namespace Server.Engines.Quests.Samurai
{
public class HaochisKatanaGenerator : Item
{
[Constructable]
public HaochisKatanaGenerator() : base( 0x1B7B )
{
Visible = false;
Name = "Haochi's katana generator";
Movable = false;
}
public override bool OnMoveOver( Mobile m )
{
PlayerMobile player = m as PlayerMobile;
if ( player != null )
{
QuestSystem qs = player.Quest;
if ( qs is HaochisTrialsQuest )
{
if ( HaochisTrialsQuest.HasLostHaochisKatana( player ) )
{
Item katana = new HaochisKatana();
if ( !player.PlaceInBackpack( katana ) )
{
katana.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
{
QuestObjective obj = qs.FindObjective( typeof( FifthTrialIntroObjective ) );
if ( obj != null && !obj.Completed )
{
Item katana = new HaochisKatana();
if ( player.PlaceInBackpack( katana ) )
{
obj.Complete();
}
else
{
katana.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.
}
}
}
}
}
return base.OnMoveOver( m );
}
public HaochisKatanaGenerator( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.WriteEncodedInt( 0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadEncodedInt();
}
}
}

View file

@ -0,0 +1,105 @@
using System;
using Server;
using Server.Items;
using Server.Mobiles;
using Server.Network;
namespace Server.Engines.Quests.Samurai
{
public class HaochisTreasureChest : WoodenFootLocker
{
[Constructable]
public HaochisTreasureChest()
{
Movable = false;
GenerateTreasure();
}
public HaochisTreasureChest( Serial serial ) : base( serial )
{
}
public override bool IsDecoContainer{ get{ return false; } }
private void GenerateTreasure()
{
for ( int i = this.Items.Count - 1; i >= 0; i-- )
this.Items[i].Delete();
for ( int i = 0; i < 75; i++ )
{
switch ( Utility.Random( 3 ) )
{
case 0: DropItem( new GoldBracelet() ); break;
case 1: DropItem( new GoldRing() ); break;
case 2: DropItem( Loot.RandomGem() ); break;
}
}
}
public override bool CheckHold( Mobile m, Item item, bool message, bool checkItems, int plusItems, int plusWeight )
{
return false;
}
public override bool CheckItemUse( Mobile from, Item item )
{
return item == this;
}
public override bool CheckLift( Mobile from, Item item, ref LRReason reject )
{
if ( from.AccessLevel >= AccessLevel.GameMaster )
return true;
PlayerMobile player = from as PlayerMobile;
if ( player != null && player.Quest is HaochisTrialsQuest )
{
FifthTrialIntroObjective obj = player.Quest.FindObjective( typeof( FifthTrialIntroObjective ) ) as FifthTrialIntroObjective;
if ( obj != null )
{
if ( obj.StolenTreasure )
from.SendLocalizedMessage( 1063247 ); // The guard is watching you carefully! It would be unwise to remove another item from here.
else
return true;
}
}
return false;
}
public override void OnItemLifted( Mobile from, Item item )
{
PlayerMobile player = from as PlayerMobile;
if ( player != null && player.Quest is HaochisTrialsQuest )
{
FifthTrialIntroObjective obj = player.Quest.FindObjective( typeof( FifthTrialIntroObjective ) ) as FifthTrialIntroObjective;
if ( obj != null )
obj.StolenTreasure = true;
}
Timer.DelayCall( TimeSpan.FromMinutes( 2.0 ), new TimerCallback( GenerateTreasure ) );
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.WriteEncodedInt( 0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadEncodedInt();
Timer.DelayCall( TimeSpan.Zero, new TimerCallback( GenerateTreasure ) );
}
}
}

View file

@ -0,0 +1,79 @@
using System;
using Server;
using Server.Items;
using Server.Mobiles;
namespace Server.Engines.Quests.Samurai
{
public class HonorCandle : CandleLong
{
private static readonly TimeSpan LitDuration = TimeSpan.FromSeconds( 20.0 );
public override int LitSound{ get{ return 0; } }
public override int UnlitSound{ get{ return 0; } }
[Constructable]
public HonorCandle()
{
Movable = false;
Duration = LitDuration;
}
public HonorCandle( Serial serial ) : base( serial )
{
}
public override void OnDoubleClick( Mobile from )
{
bool wasBurning = Burning;
base.OnDoubleClick( from );
if ( !wasBurning && Burning )
{
PlayerMobile player = from as PlayerMobile;
if ( player == null )
return;
QuestSystem qs = player.Quest;
if ( qs != null && qs is HaochisTrialsQuest )
{
QuestObjective obj = qs.FindObjective( typeof( SixthTrialIntroObjective ) );
if ( obj != null && !obj.Completed )
obj.Complete();
this.SendLocalizedMessageTo( from, 1063251 ); // You light a candle in honor.
}
}
}
public override void Burn()
{
Douse();
}
public override void Douse()
{
base.Douse();
Duration = LitDuration;
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.WriteEncodedInt( 0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadEncodedInt();
}
}
}

View file

@ -0,0 +1,70 @@
using System;
using Server.Mobiles;
using Server.Items;
namespace Server.Engines.Quests.Samurai
{
[CorpseName( "a cursed soul corpse" )]
public class CursedSoul : BaseCreature
{
[Constructable]
public CursedSoul() : base( AIType.AI_Melee, FightMode.Aggressor, 10, 1, 0.2, 0.4 )
{
Name = "a cursed soul";
Body = 3;
BaseSoundID = 471;
SetStr( 20, 40 );
SetDex( 40, 60 );
SetInt( 15, 25 );
SetHits( 10, 20 );
SetDamage( 3, 7 );
SetDamageType( ResistanceType.Physical, 100 );
SetResistance( ResistanceType.Physical, 15, 20 );
SetResistance( ResistanceType.Fire, 8, 12 );
SetSkill( SkillName.Wrestling, 35.0, 39.0 );
SetSkill( SkillName.Tactics, 5.0, 15.0 );
SetSkill( SkillName.MagicResist, 10.0 );
Fame = 200;
Karma = -200;
switch ( Utility.Random( 10 ) )
{
case 0: PackItem( new LeftArm() ); break;
case 1: PackItem( new RightArm() ); break;
case 2: PackItem( new Torso() ); break;
case 3: PackItem( new Bone() ); break;
case 4: PackItem( new RibCage() ); break;
case 5: PackItem( new RibCage() ); break;
case 6: PackItem( new BonePile() ); break;
case 7: PackItem( new BonePile() ); break;
case 8: PackItem( new BonePile() ); break;
case 9: PackItem( new BonePile() ); break;
}
}
public CursedSoul( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.WriteEncodedInt( 0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadEncodedInt();
}
}
}

View file

@ -0,0 +1,80 @@
using System;
using Server.Mobiles;
namespace Server.Engines.Quests.Samurai
{
public class DeadlyImp : BaseCreature
{
[Constructable]
public DeadlyImp() : base( AIType.AI_Melee, FightMode.Aggressor, 10, 1, 0.2, 0.4 )
{
Name = "a deadly imp";
Body = 74;
BaseSoundID = 422;
Hue = 0x66A;
SetStr( 91, 115 );
SetDex( 61, 80 );
SetInt( 86, 105 );
SetHits( 1000 );
SetDamage( 50, 80 );
SetDamageType( ResistanceType.Fire, 100 );
SetResistance( ResistanceType.Physical, 95, 98 );
SetResistance( ResistanceType.Fire, 95, 98 );
SetResistance( ResistanceType.Cold, 95, 98 );
SetResistance( ResistanceType.Poison, 95, 98 );
SetResistance( ResistanceType.Energy, 95, 98 );
SetSkill( SkillName.Magery, 120.0 );
SetSkill( SkillName.Tactics, 120.0 );
SetSkill( SkillName.Wrestling, 120.0 );
Fame = 2500;
Karma = -2500;
CantWalk = true;
}
public override void AggressiveAction( Mobile aggressor, bool criminal )
{
base.AggressiveAction( aggressor, criminal );
PlayerMobile player = aggressor as PlayerMobile;
if ( player != null )
{
QuestSystem qs = player.Quest;
if ( qs is HaochisTrialsQuest )
{
QuestObjective obj = qs.FindObjective( typeof( SecondTrialAttackObjective ) );
if ( obj != null && !obj.Completed )
{
obj.Complete();
qs.AddObjective( new SecondTrialReturnObjective( false ) );
}
}
}
}
public DeadlyImp( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.WriteEncodedInt( 0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadEncodedInt();
}
}
}

View file

@ -0,0 +1,59 @@
using System;
using Server.Mobiles;
namespace Server.Engines.Quests.Samurai
{
public class DiseasedCat : BaseCreature
{
[Constructable]
public DiseasedCat() : base( AIType.AI_Animal, FightMode.Aggressor, 10, 1, 0.2, 0.4 )
{
Name = "a diseased cat";
Body = 0xC9;
Hue = Utility.RandomAnimalHue();
BaseSoundID = 0x69;
SetStr( 9 );
SetDex( 35 );
SetInt( 5 );
SetHits( 6 );
SetMana( 0 );
SetDamage( 1 );
SetDamageType( ResistanceType.Physical, 100 );
SetResistance( ResistanceType.Physical, 5, 10 );
SetSkill( SkillName.MagicResist, 5.0 );
SetSkill( SkillName.Tactics, 4.0 );
SetSkill( SkillName.Wrestling, 5.0 );
VirtualArmor = 8;
}
public override bool AlwaysMurderer{ get{ return true; } }
public DiseasedCat( Serial serial ) : base( serial )
{
}
public override void Serialize(GenericWriter writer)
{
base.Serialize( writer );
writer.WriteEncodedInt( 0 ); // version
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize( reader );
int version = reader.ReadEncodedInt();
if( Name == "a deseased cat" )
Name = "a diseased cat";
}
}
}

View file

@ -0,0 +1,102 @@
using System;
using Server.Mobiles;
namespace Server.Engines.Quests.Samurai
{
public class FierceDragon : BaseCreature
{
[Constructable]
public FierceDragon() : base( AIType.AI_Melee, FightMode.Aggressor, 10, 1, 0.2, 0.4 )
{
Name = "a fierce dragon";
Body = 103;
BaseSoundID = 362;
SetStr( 6000, 6020 );
SetDex( 0 );
SetInt( 850, 870 );
SetDamage( 50, 80 );
SetDamageType( ResistanceType.Fire, 100 );
SetResistance( ResistanceType.Physical, 95, 98 );
SetResistance( ResistanceType.Fire, 95, 98 );
SetResistance( ResistanceType.Cold, 95, 98 );
SetResistance( ResistanceType.Poison, 95, 98 );
SetResistance( ResistanceType.Energy, 95, 98 );
SetSkill( SkillName.Tactics, 120.0 );
SetSkill( SkillName.Wrestling, 120.0 );
SetSkill( SkillName.Magery, 120.0 );
Fame = 15000;
Karma = 15000;
CantWalk = true;
}
public override int GetIdleSound()
{
return 0x2C4;
}
public override int GetAttackSound()
{
return 0x2C0;
}
public override int GetDeathSound()
{
return 0x2C1;
}
public override int GetAngerSound()
{
return 0x2C4;
}
public override int GetHurtSound()
{
return 0x2C3;
}
public override void AggressiveAction( Mobile aggressor, bool criminal )
{
base.AggressiveAction( aggressor, criminal );
PlayerMobile player = aggressor as PlayerMobile;
if ( player != null )
{
QuestSystem qs = player.Quest;
if ( qs is HaochisTrialsQuest )
{
QuestObjective obj = qs.FindObjective( typeof( SecondTrialAttackObjective ) );
if ( obj != null && !obj.Completed )
{
obj.Complete();
qs.AddObjective( new SecondTrialReturnObjective( true ) );
}
}
}
}
public FierceDragon( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.WriteEncodedInt( 0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadEncodedInt();
}
}
}

View file

@ -0,0 +1,182 @@
using System;
using Server;
using Server.Mobiles;
using Server.Gumps;
using Server.Items;
namespace Server.Engines.Quests.Samurai
{
public class Haochi : BaseQuester
{
[Constructable]
public Haochi() : base( "the Honorable Samurai Legend" )
{
}
public override void InitBody()
{
InitStats( 100, 100, 25 );
Hue = 0x8403;
Female = false;
Body = 0x190;
Name = "Daimyo Haochi";
}
public override void InitOutfit()
{
HairItemID = 0x204A;
HairHue = 0x901;
AddItem( new SamuraiTabi() );
AddItem( new JinBaori() );
AddItem( new PlateHaidate() );
AddItem( new StandardPlateKabuto() );
AddItem( new PlateMempo() );
AddItem( new PlateDo() );
AddItem( new PlateHiroSode() );
}
public override int GetAutoTalkRange( PlayerMobile pm )
{
return 2;
}
public override int TalkNumber{ get { return -1; } }
public override void OnTalk( PlayerMobile player, bool contextMenu )
{
QuestSystem qs = player.Quest;
if ( qs is HaochisTrialsQuest )
{
if ( HaochisTrialsQuest.HasLostHaochisKatana( player ) )
{
qs.AddConversation( new LostSwordConversation() );
return;
}
QuestObjective obj = qs.FindObjective( typeof( FindHaochiObjective ) );
if ( obj != null && !obj.Completed )
{
obj.Complete();
return;
}
obj = qs.FindObjective( typeof( FirstTrialReturnObjective ) );
if ( obj != null && !obj.Completed )
{
player.AddToBackpack( new LeatherDo() );
obj.Complete();
return;
}
obj = qs.FindObjective( typeof( SecondTrialReturnObjective ) );
if ( obj != null && !obj.Completed )
{
if ( ((SecondTrialReturnObjective)obj).Dragon )
player.AddToBackpack( new LeatherSuneate() );
obj.Complete();
return;
}
obj = qs.FindObjective( typeof( ThirdTrialReturnObjective ) );
if ( obj != null && !obj.Completed )
{
player.AddToBackpack( new LeatherHiroSode() );
obj.Complete();
return;
}
obj = qs.FindObjective( typeof( FourthTrialReturnObjective ) );
if ( obj != null && !obj.Completed )
{
if ( !((FourthTrialReturnObjective)obj).KilledCat )
{
Container cont = GetNewContainer();
cont.DropItem( new LeatherHiroSode() );
cont.DropItem( new JinBaori() );
player.AddToBackpack( cont );
}
obj.Complete();
return;
}
obj = qs.FindObjective( typeof( FifthTrialReturnObjective ) );
if ( obj != null && !obj.Completed )
{
Container pack = player.Backpack;
if ( pack != null )
{
Item katana = pack.FindItemByType( typeof( HaochisKatana ) );
if ( katana != null )
{
katana.Delete();
obj.Complete();
obj = qs.FindObjective( typeof( FifthTrialIntroObjective ) );
if ( obj != null && ((FifthTrialIntroObjective)obj).StolenTreasure )
qs.AddConversation( new SixthTrialIntroConversation( true ) );
else
qs.AddConversation( new SixthTrialIntroConversation( false ) );
}
}
return;
}
obj = qs.FindObjective( typeof( SixthTrialReturnObjective ) );
if ( obj != null && !obj.Completed )
{
obj.Complete();
return;
}
obj = qs.FindObjective( typeof( SeventhTrialReturnObjective ) );
if ( obj != null && !obj.Completed )
{
BaseWeapon weapon = new Daisho();
BaseRunicTool.ApplyAttributesTo( weapon, Utility.Random( 1,3 ), 10, 30 );
player.AddToBackpack( weapon );
BaseArmor armor = new LeatherDo();
BaseRunicTool.ApplyAttributesTo( armor, Utility.Random( 1,3 ), 10, 20 );
player.AddToBackpack( armor );
obj.Complete();
return;
}
}
}
public Haochi( 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,85 @@
using System;
using Server;
using Server.Mobiles;
using Server.Gumps;
using Server.Items;
namespace Server.Engines.Quests.Samurai
{
public class HaochisGuardsman : BaseQuester
{
[Constructable]
public HaochisGuardsman() : base( "the Guardsman of Daimyo Haochi" )
{
}
public override void InitBody()
{
InitStats( 100, 100, 25 );
Hue = Race.Human.RandomSkinHue();
Female = false;
Body = 0x190;
Name = NameList.RandomName( "male" );
}
public override void InitOutfit()
{
Utility.AssignRandomHair( this );
AddItem( new LeatherDo() );
AddItem( new LeatherHiroSode() );
AddItem( new SamuraiTabi( Utility.RandomNondyedHue() ) );
switch ( Utility.Random( 3 ) )
{
case 0: AddItem( new StuddedHaidate() ); break;
case 1: AddItem( new PlateSuneate() ); break;
default: AddItem( new LeatherSuneate() ); break;
}
switch ( Utility.Random( 4 ) )
{
case 0: AddItem( new DecorativePlateKabuto() ); break;
case 1: AddItem( new ChainHatsuburi() ); break;
case 2: AddItem( new LightPlateJingasa() ); break;
default: AddItem( new LeatherJingasa() ); break;
}
Item weapon;
switch ( Utility.Random( 3 ) )
{
case 0: weapon = new NoDachi(); break;
case 1: weapon = new Lajatang(); break;
default: weapon = new Wakizashi(); break;
}
weapon.Movable = false;
AddItem( weapon );
}
public override int TalkNumber{ get { return -1; } }
public override void OnTalk( PlayerMobile player, bool contextMenu )
{
}
public HaochisGuardsman( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.WriteEncodedInt( 0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadEncodedInt();
}
}
}

View file

@ -0,0 +1,59 @@
using System;
using Server.Mobiles;
namespace Server.Engines.Quests.Samurai
{
[CorpseName( "an injured wolf corpse" )]
public class InjuredWolf : BaseCreature
{
[Constructable]
public InjuredWolf() : base( AIType.AI_Animal, FightMode.Aggressor, 10, 1, 0.2, 0.4 )
{
Body = 0xE1;
Name = "an injured wolf";
BaseSoundID = 0xE5;
Hue = Utility.RandomAnimalHue();
SetStr( 10, 20 );
SetDex( 45, 65 );
SetInt( 10, 15 );
SetHits( 1 );
SetDamage( 1, 3 );
SetDamageType( ResistanceType.Physical, 100 );
SetResistance( ResistanceType.Physical, 15 );
SetResistance( ResistanceType.Fire, 5, 10 );
SetSkill( SkillName.MagicResist, 10.0 );
SetSkill( SkillName.Tactics, 0.0, 5.0 );
SetSkill( SkillName.Wrestling, 20.0, 30.0 );
}
public override int GetIdleSound()
{
return 0xE9;
}
public InjuredWolf( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.WriteEncodedInt( 0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadEncodedInt();
}
}
}

View file

@ -0,0 +1,96 @@
using System;
using Server;
using Server.Mobiles;
using Server.Gumps;
using Server.Items;
namespace Server.Engines.Quests.Samurai
{
public class Relnia : BaseQuester
{
[Constructable]
public Relnia() : base( "the Gypsy" )
{
}
public override void InitBody()
{
InitStats( 100, 100, 25 );
Hue = 0x83FF;
Female = true;
Body = 0x191;
Name = "Disheveled Relnia";
}
public override void InitOutfit()
{
HairItemID = 0x203C;
HairHue = 0x654;
AddItem( new ThighBoots( 0x901 ) );
AddItem( new FancyShirt( 0x5F3 ) );
AddItem( new SkullCap( 0x6A7 ) );
AddItem( new Skirt( 0x544 ) );
}
public override int TalkNumber{ get { return -1; } }
public override void OnTalk( PlayerMobile player, bool contextMenu )
{
}
public override bool OnDragDrop( Mobile from, Item dropped )
{
PlayerMobile player = from as PlayerMobile;
if ( player != null )
{
QuestSystem qs = player.Quest;
if ( qs is HaochisTrialsQuest )
{
QuestObjective obj = qs.FindObjective( typeof( FourthTrialCatsObjective ) );
if ( obj != null && !obj.Completed )
{
Gold gold = dropped as Gold;
if ( gold != null )
{
obj.Complete();
qs.AddObjective( new FourthTrialReturnObjective( false ) );
SayTo( from, 1063241 ); // I thank thee. This gold will be a great help to me and mine!
gold.Consume(); // Intentional difference from OSI: don't take all the gold of poor newbies!
return gold.Deleted;
}
}
}
}
return base.OnDragDrop( from, dropped );
}
public Relnia( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.WriteEncodedInt( 0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadEncodedInt();
}
}
}

View file

@ -0,0 +1,62 @@
using System;
using Server;
using Server.Mobiles;
using Server.Items;
namespace Server.Engines.Quests.Samurai
{
[CorpseName( "a young ninja's corpse" )]
public class YoungNinja : BaseCreature
{
[Constructable]
public YoungNinja() : base( AIType.AI_Melee, FightMode.Aggressor, 10, 1, 0.2, 0.4 )
{
InitStats( 45, 30, 5 );
SetHits( 20, 30 );
Hue = Utility.RandomSkinHue();
Body = 0x190;
Name = "a young ninja";
Utility.AssignRandomHair( this );
Utility.AssignRandomFacialHair( this );
AddItem( new NinjaTabi() );
AddItem( new LeatherNinjaPants() );
AddItem( new LeatherNinjaJacket() );
AddItem( new LeatherNinjaBelt() );
AddItem( new Bandana( Utility.RandomNondyedHue() ) );
switch ( Utility.Random( 3 ) )
{
case 0: AddItem( new Tessen() ); break;
case 1: AddItem( new Kama() ); break;
default: AddItem( new Lajatang() ); break;
}
SetSkill( SkillName.Swords, 50.0 );
SetSkill( SkillName.Tactics, 50.0 );
}
public override bool AlwaysMurderer{ get{ return true; } }
public YoungNinja( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.WriteEncodedInt( 0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadEncodedInt();
}
}
}

View file

@ -0,0 +1,68 @@
using System;
using Server;
using Server.Mobiles;
using Server.Items;
namespace Server.Engines.Quests.Samurai
{
[CorpseName( "a young ronin's corpse" )]
public class YoungRonin : BaseCreature
{
[Constructable]
public YoungRonin() : base( AIType.AI_Melee, FightMode.Aggressor, 10, 1, 0.2, 0.4 )
{
InitStats( 45, 30, 5 );
SetHits( 10, 20 );
Hue = Utility.RandomSkinHue();
Body = 0x190;
Name = "a young ronin";
Utility.AssignRandomHair( this );
Utility.AssignRandomFacialHair( this );
AddItem( new LeatherDo() );
AddItem( new LeatherHiroSode() );
AddItem( new SamuraiTabi() );
switch ( Utility.Random( 3 ) )
{
case 0: AddItem( new StuddedHaidate() ); break;
case 1: AddItem( new PlateSuneate() ); break;
default: AddItem( new LeatherSuneate() ); break;
}
AddItem( new Bandana( Utility.RandomNondyedHue() ) );
switch ( Utility.Random( 3 ) )
{
case 0: AddItem( new NoDachi() ); break;
case 1: AddItem( new Lajatang() ); break;
default: AddItem( new Wakizashi() ); break;
}
SetSkill( SkillName.Swords, 50.0 );
SetSkill( SkillName.Tactics, 50.0 );
}
public override bool AlwaysMurderer{ get{ return true; } }
public YoungRonin( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.WriteEncodedInt( 0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadEncodedInt();
}
}
}

View file

@ -0,0 +1,555 @@
using System;
using Server;
using Server.Items;
using Server.Mobiles;
namespace Server.Engines.Quests.Samurai
{
public class FindHaochiObjective : QuestObjective
{
public override object Message
{
get
{
// Speak to Daimyo Haochi.
return 1063026;
}
}
public FindHaochiObjective()
{
}
public override void OnComplete()
{
System.AddConversation( new FirstTrialIntroConversation() );
}
}
public class FirstTrialIntroObjective : QuestObjective
{
public override object Message
{
get
{
// Follow the green path. The guards will now let you through.
return 1063030;
}
}
public FirstTrialIntroObjective()
{
}
public override void OnComplete()
{
System.AddConversation( new FirstTrialKillConversation() );
}
}
public class FirstTrialKillObjective : QuestObjective
{
public override object Message
{
get
{
// Kill 3 Young Ronin or 3 Cursed Souls. Return to Daimyo Haochi when you have finished.
return 1063032;
}
}
public FirstTrialKillObjective()
{
}
private int m_CursedSoulsKilled;
private int m_YoungRoninKilled;
public override int MaxProgress{ get{ return 3; } }
public override void OnKill( BaseCreature creature, Container corpse )
{
if ( creature is CursedSoul )
{
if ( m_CursedSoulsKilled == 0 )
System.AddConversation( new GainKarmaConversation( true ) );
m_CursedSoulsKilled++;
// Cursed Souls killed: ~1_COUNT~
System.From.SendLocalizedMessage( 1063038, m_CursedSoulsKilled.ToString() );
}
else if ( creature is YoungRonin )
{
if ( m_YoungRoninKilled == 0 )
System.AddConversation( new GainKarmaConversation( false ) );
m_YoungRoninKilled++;
// Young Ronin killed: ~1_COUNT~
System.From.SendLocalizedMessage( 1063039, m_YoungRoninKilled.ToString() );
}
CurProgress = Math.Max( m_CursedSoulsKilled, m_YoungRoninKilled );
}
public override void OnComplete()
{
System.AddObjective( new FirstTrialReturnObjective( m_CursedSoulsKilled > m_YoungRoninKilled ) );
}
public override void ChildDeserialize( GenericReader reader )
{
int version = reader.ReadEncodedInt();
m_CursedSoulsKilled = reader.ReadEncodedInt();
m_YoungRoninKilled = reader.ReadEncodedInt();
}
public override void ChildSerialize( GenericWriter writer )
{
writer.WriteEncodedInt( (int) 0 ); // version
writer.WriteEncodedInt( m_CursedSoulsKilled );
writer.WriteEncodedInt( m_YoungRoninKilled );
}
}
public class FirstTrialReturnObjective : QuestObjective
{
public override object Message
{
get
{
// The first trial is complete. Return to Daimyo Haochi.
return 1063044;
}
}
bool m_CursedSoul;
public FirstTrialReturnObjective( bool cursedSoul )
{
m_CursedSoul = cursedSoul;
}
public FirstTrialReturnObjective()
{
}
public override void OnComplete()
{
System.AddConversation( new SecondTrialIntroConversation( m_CursedSoul ) );
}
public override void ChildDeserialize( GenericReader reader )
{
int version = reader.ReadEncodedInt();
m_CursedSoul = reader.ReadBool();
}
public override void ChildSerialize( GenericWriter writer )
{
writer.WriteEncodedInt( (int) 0 ); // version
writer.Write( (bool) m_CursedSoul );
}
}
public class SecondTrialIntroObjective : QuestObjective
{
public override object Message
{
get
{
// Follow the yellow path. The guards will now let you through.
return 1063047;
}
}
public SecondTrialIntroObjective()
{
}
public override void OnComplete()
{
System.AddConversation( new SecondTrialAttackConversation() );
}
}
public class SecondTrialAttackObjective : QuestObjective
{
public override object Message
{
get
{
// Choose your opponent and attack one with all your skill.
return 1063058;
}
}
public SecondTrialAttackObjective()
{
}
}
public class SecondTrialReturnObjective : QuestObjective
{
public override object Message
{
get
{
// The second trial is complete. Return to Daimyo Haochi.
return 1063229;
}
}
private bool m_Dragon;
public bool Dragon{ get{ return m_Dragon; } }
public SecondTrialReturnObjective( bool dragon )
{
m_Dragon = dragon;
}
public SecondTrialReturnObjective()
{
}
public override void OnComplete()
{
System.AddConversation( new ThirdTrialIntroConversation( m_Dragon ) );
}
public override void ChildDeserialize( GenericReader reader )
{
int version = reader.ReadEncodedInt();
m_Dragon = reader.ReadBool();
}
public override void ChildSerialize( GenericWriter writer )
{
writer.WriteEncodedInt( (int) 0 ); // version
writer.Write( (bool) m_Dragon );
}
}
public class ThirdTrialIntroObjective : QuestObjective
{
public override object Message
{
get
{
/* The next trial will test your benevolence. Follow the blue path.
* The guards will now let you through.
*/
return 1063061;
}
}
public ThirdTrialIntroObjective()
{
}
public override void OnComplete()
{
System.AddConversation( new ThirdTrialKillConversation() );
}
}
public class ThirdTrialKillObjective : QuestObjective
{
public override object Message
{
get
{
/* Use your Honorable Execution skill to finish off the wounded wolf.
* Double click the icon in your Book of Bushido to activate the skill.
* When you are done, return to Daimyo Haochi.
*/
return 1063063;
}
}
public ThirdTrialKillObjective()
{
}
public override void OnKill( BaseCreature creature, Container corpse )
{
if ( creature is InjuredWolf )
Complete();
}
public override void OnComplete()
{
System.AddObjective( new ThirdTrialReturnObjective() );
}
}
public class ThirdTrialReturnObjective : QuestObjective
{
public override object Message
{
get
{
// Return to Daimyo Haochi.
return 1063064;
}
}
public ThirdTrialReturnObjective()
{
}
public override void OnComplete()
{
System.AddConversation( new FourthTrialIntroConversation() );
}
}
public class FourthTrialIntroObjective : QuestObjective
{
public override object Message
{
get
{
// Follow the red path and pass through the guards to the entrance of the fourth trial.
return 1063066;
}
}
public FourthTrialIntroObjective()
{
}
public override void OnComplete()
{
System.AddConversation( new FourthTrialCatsConversation() );
}
}
public class FourthTrialCatsObjective : QuestObjective
{
public override object Message
{
get
{
/* Give the gypsy gold or hunt one of the cats to eliminate the undue
* need it has placed on the gypsy.
*/
return 1063068;
}
}
public FourthTrialCatsObjective()
{
}
public override void OnKill( BaseCreature creature, Container corpse )
{
if ( creature is DiseasedCat )
{
Complete();
System.AddObjective( new FourthTrialReturnObjective( true ) );
}
}
}
public class FourthTrialReturnObjective : QuestObjective
{
public override object Message
{
get
{
// You have made your choice. Return now to Daimyo Haochi.
return 1063242;
}
}
private bool m_KilledCat;
public bool KilledCat{ get{ return m_KilledCat; } }
public FourthTrialReturnObjective( bool killedCat )
{
m_KilledCat = killedCat;
}
public FourthTrialReturnObjective()
{
}
public override void OnComplete()
{
System.AddConversation( new FifthTrialIntroConversation( m_KilledCat ) );
}
public override void ChildDeserialize( GenericReader reader )
{
int version = reader.ReadEncodedInt();
m_KilledCat = reader.ReadBool();
}
public override void ChildSerialize( GenericWriter writer )
{
writer.WriteEncodedInt( (int) 0 ); // version
writer.Write( (bool) m_KilledCat );
}
}
public class FifthTrialIntroObjective : QuestObjective
{
public override object Message
{
get
{
// Retrieve Daimyo Haochi’s katana from the treasure room.
return 1063072;
}
}
private bool m_StolenTreasure;
public bool StolenTreasure{ get{ return m_StolenTreasure; } set{ m_StolenTreasure = value; } }
public FifthTrialIntroObjective()
{
}
public override void OnComplete()
{
System.AddConversation( new FifthTrialReturnConversation() );
}
public override void ChildDeserialize( GenericReader reader )
{
int version = reader.ReadEncodedInt();
m_StolenTreasure = reader.ReadBool();
}
public override void ChildSerialize( GenericWriter writer )
{
writer.WriteEncodedInt( (int) 0 ); // version
writer.Write( (bool) m_StolenTreasure );
}
}
public class FifthTrialReturnObjective : QuestObjective
{
public override object Message
{
get
{
// Give the sword to Daimyo Haochi.
return 1063073;
}
}
public FifthTrialReturnObjective()
{
}
}
public class SixthTrialIntroObjective : QuestObjective
{
public override object Message
{
get
{
// Light one of the candles near the altar and return to Daimyo Haochi.
return 1063078;
}
}
public SixthTrialIntroObjective()
{
}
public override void OnComplete()
{
System.AddObjective( new SixthTrialReturnObjective() );
}
}
public class SixthTrialReturnObjective : QuestObjective
{
public override object Message
{
get
{
// You have done as requested. Return to Daimyo Haochi.
return 1063252;
}
}
public SixthTrialReturnObjective()
{
}
public override void OnComplete()
{
System.AddConversation( new SeventhTrialIntroConversation() );
}
}
public class SeventhTrialIntroObjective : QuestObjective
{
public override object Message
{
get
{
/* Three young Ninja must be dealt with. Your job is to kill them.
* When you have done so, return to Daimyo Haochi.
*/
return 1063080;
}
}
public override int MaxProgress{ get{ return 3; } }
public SeventhTrialIntroObjective()
{
}
public override void OnKill( BaseCreature creature, Container corpse )
{
if ( creature is YoungNinja )
CurProgress++;
}
public override void OnComplete()
{
System.AddObjective( new SeventhTrialReturnObjective() );
}
}
public class SeventhTrialReturnObjective : QuestObjective
{
public override object Message
{
get
{
// The executions are complete. Return to the Daimyo.
return 1063253;
}
}
public SeventhTrialReturnObjective()
{
}
public override void OnComplete()
{
System.AddConversation( new EndConversation() );
}
}
}

View file

@ -0,0 +1,330 @@
using System;
using Server;
namespace Server.Engines.Quests.Matriarch
{
public class DontOfferConversation : QuestConversation
{
private bool m_Friend;
public override object Message
{
get
{
if ( m_Friend )
{
/* <I>The Solen Matriarch smiles as you greet her.</I><BR><BR>
*
* It is good to see you again. I would offer to process some zoogi fungus for you,
* but you seem to be busy with another task at the moment. Perhaps you should
* finish whatever is occupying your attention at the moment and return to me once
* you're done.
*/
return 1054081;
}
else
{
/* <I>The Solen Matriarch smiles as she eats the seed you offered.</I><BR><BR>
*
* Thank you for that seed. It was quite delicious. <BR><BR>
*
* I would offer to make you a friend of my colony, but you seem to be busy with
* another task at the moment. Perhaps you should finish whatever is occupying
* your attention at the moment and return to me once you're done.
*/
return 1054079;
}
}
}
public override bool Logged{ get{ return false; } }
public DontOfferConversation( bool friend )
{
m_Friend = friend;
}
public DontOfferConversation()
{
}
public override void ChildDeserialize( GenericReader reader )
{
int version = reader.ReadEncodedInt();
m_Friend = reader.ReadBool();
}
public override void ChildSerialize( GenericWriter writer )
{
writer.WriteEncodedInt( (int) 0 ); // version
writer.Write( (bool) m_Friend );
}
}
public class AcceptConversation : QuestConversation
{
public override object Message
{
get
{
/* <I>The Solen Matriarch looks pleased that you've accepted.</I><BR><BR>
*
* Very good. Please start by hunting some infiltrators from the other solen
* colony and eliminating them. Slay 7 of them and then return to me.<BR><BR>
*
* Farewell for now and good hunting.
*/
return 1054084;
}
}
public AcceptConversation()
{
}
public override void OnRead()
{
System.AddObjective( new KillInfiltratorsObjective() );
}
}
public class DuringKillInfiltratorsConversation : QuestConversation
{
public override object Message
{
get
{
/* <I>The Solen Matriarch looks up as you approach.</I><BR><BR>
*
* You're back, but you have not yet eliminated 7 infiltrators from the enemy
* colony. Return when you have completed this task.<BR><BR>
*
* Carry on. I'll be waiting for your return.
*/
return 1054089;
}
}
public override bool Logged{ get{ return false; } }
public DuringKillInfiltratorsConversation()
{
}
}
public class GatherWaterConversation : QuestConversation
{
public override object Message
{
get
{
/* <I>The Solen Matriarch nods favorably as you approach her.</I><BR><BR>
*
* Marvelous! I'm impressed at your ability to hunt and kill enemies for me.
* My colony is thankful.<BR><BR>
*
* Now I must ask that you gather some water for me. A standard pitcher of water
* holds approximately one gallon. Please decant 8 gallons of fresh water
* into our water vats.<BR><BR>
*
* Farewell for now.
*/
return 1054091;
}
}
public GatherWaterConversation()
{
}
public override void OnRead()
{
System.AddObjective( new GatherWaterObjective() );
}
}
public class DuringWaterGatheringConversation : QuestConversation
{
public override object Message
{
get
{
/* <I>The Solen Matriarch looks up as you approach.</I><BR><BR>
*
* You're back, but you have not yet gathered 8 gallons of water. Return when
* you have completed this task.<BR><BR>
*
* Carry on. I'll be waiting for your return.
*/
return 1054094;
}
}
public override bool Logged{ get{ return false; } }
public DuringWaterGatheringConversation()
{
}
}
public class ProcessFungiConversation : QuestConversation
{
private bool m_Friend;
public override object Message
{
get
{
if ( m_Friend )
{
/* <I>The Solen Matriarch listens as you report the completion of your
* tasks to her.</I><BR><BR>
*
* I give you my thanks for your help, and I will gladly process some zoogi
* fungus into powder of translocation for you. Two of the zoogi fungi are
* required for each measure of the powder. I will process up to 200 zoogi fungi
* into 100 measures of powder of translocation.<BR><BR>
*
* I will also give you some gold for assisting me and my colony, but first let's
* take care of your zoogi fungus.
*/
return 1054097;
}
else
{
/* <I>The Solen Matriarch listens as you report the completion of your
* tasks to her.</I><BR><BR>
*
* I give you my thanks for your help, and I will gladly make you a friend of my
* solen colony. My warriors, workers, and queens will not longer look at you
* as an intruder and attack you when you enter our lair.<BR><BR>
*
* I will also process some zoogi fungus into powder of translocation for you.
* Two of the zoogi fungi are required for each measure of the powder. I will
* process up to 200 zoogi fungi into 100 measures of powder of translocation.<BR><BR>
*
* I will also give you some gold for assisting me and my colony, but first let's
* take care of your zoogi fungus.
*/
return 1054096;
}
}
}
public ProcessFungiConversation( bool friend )
{
m_Friend = friend;
}
public override void OnRead()
{
System.AddObjective( new ProcessFungiObjective() );
}
public ProcessFungiConversation()
{
}
public override void ChildDeserialize( GenericReader reader )
{
int version = reader.ReadEncodedInt();
m_Friend = reader.ReadBool();
}
public override void ChildSerialize( GenericWriter writer )
{
writer.WriteEncodedInt( (int) 0 ); // version
writer.Write( (bool) m_Friend );
}
}
public class DuringFungiProcessConversation : QuestConversation
{
public override object Message
{
get
{
/* <I>The Solen Matriarch smiles as you greet her.</I><BR><BR>
*
* I will gladly process some zoogi fungus into powder of translocation for you.
* Two of the zoogi fungi are required for each measure of the powder.
* I will process up to 200 zoogi fungi into 100 measures of powder of translocation.
*/
return 1054099;
}
}
public override bool Logged{ get{ return false; } }
public DuringFungiProcessConversation()
{
}
}
public class FullBackpackConversation : QuestConversation
{
public override object Message
{
get
{
/* <I>The Solen Matriarch looks at you with a smile.</I><BR><BR>
*
* While I'd like to finish conducting our business, it seems that you're a
* bit overloaded with equipment at the moment.<BR><BR>
*
* Perhaps you should free some room in your backpack before we proceed.
*/
return 1054102;
}
}
private bool m_Logged;
public override bool Logged{ get{ return m_Logged; } }
public FullBackpackConversation( bool logged )
{
m_Logged = logged;
}
public FullBackpackConversation()
{
m_Logged = true;
}
public override void OnRead()
{
if ( m_Logged )
System.AddObjective( new GetRewardObjective() );
}
}
public class EndConversation : QuestConversation
{
public override object Message
{
get
{
/* <I>The Solen Matriarch smiles as you greet her.</I><BR><BR>
*
* Ah good, you've returned. I will conclude our business by giving you
* gold I owe you for aiding me.
*/
return 1054101;
}
}
public EndConversation()
{
}
public override void OnRead()
{
System.Complete();
}
}
}

View file

@ -0,0 +1,339 @@
using System;
using System.Collections;
using System.Collections.Generic;
using Server;
using Server.Items;
using Server.Mobiles;
using Server.Targeting;
using Server.ContextMenus;
using Server.Engines.Plants;
using Server.Engines.Quests;
namespace Server.Engines.Quests.Matriarch
{
public abstract class BaseSolenMatriarch : BaseQuester
{
public abstract bool RedSolen{ get; }
public override bool DisallowAllMoves{ get{ return false; } }
public BaseSolenMatriarch()
{
Name = "the solen matriarch";
Body = 0x328;
if ( !RedSolen )
Hue = 0x44E;
SpeechHue = 0;
}
public override int GetIdleSound()
{
return 0x10D;
}
public override bool CanTalkTo( PlayerMobile to )
{
if ( SolenMatriarchQuest.IsFriend( to, this.RedSolen ) )
return true;
SolenMatriarchQuest qs = to.Quest as SolenMatriarchQuest;
return qs != null && qs.RedSolen == this.RedSolen;
}
public override void OnTalk( PlayerMobile player, bool contextMenu )
{
this.Direction = GetDirectionTo( player );
SolenMatriarchQuest qs = player.Quest as SolenMatriarchQuest;
if ( qs != null && qs.RedSolen == this.RedSolen )
{
if ( qs.IsObjectiveInProgress( typeof( KillInfiltratorsObjective ) ) )
{
qs.AddConversation( new DuringKillInfiltratorsConversation() );
}
else
{
QuestObjective obj = qs.FindObjective( typeof( ReturnAfterKillsObjective ) );
if ( obj != null && !obj.Completed )
{
obj.Complete();
}
else if ( qs.IsObjectiveInProgress( typeof( GatherWaterObjective ) ) )
{
qs.AddConversation( new DuringWaterGatheringConversation() );
}
else
{
obj = qs.FindObjective( typeof( ReturnAfterWaterObjective ) );
if ( obj != null && !obj.Completed )
{
obj.Complete();
}
else if ( qs.IsObjectiveInProgress( typeof( ProcessFungiObjective ) ) )
{
qs.AddConversation( new DuringFungiProcessConversation() );
}
else
{
obj = qs.FindObjective( typeof( GetRewardObjective ) );
if ( obj != null && !obj.Completed )
{
if ( SolenMatriarchQuest.GiveRewardTo( player ) )
{
obj.Complete();
}
else
{
qs.AddConversation( new FullBackpackConversation( false ) );
}
}
}
}
}
}
else if ( SolenMatriarchQuest.IsFriend( player, this.RedSolen ) )
{
QuestSystem newQuest = new SolenMatriarchQuest( player, this.RedSolen );
if ( player.Quest == null && QuestSystem.CanOfferQuest( player, typeof( SolenMatriarchQuest ) ) )
{
newQuest.SendOffer();
}
else
{
newQuest.AddConversation( new DontOfferConversation( true ) );
}
}
}
public override bool OnDragDrop( Mobile from, Item dropped )
{
PlayerMobile player = from as PlayerMobile;
if ( player != null )
{
if ( dropped is Seed )
{
SolenMatriarchQuest qs = player.Quest as SolenMatriarchQuest;
if ( qs != null && qs.RedSolen == this.RedSolen )
{
SayTo( player, 1054080 ); // Thank you for that plant seed. Those have such wonderful flavor.
}
else
{
QuestSystem newQuest = new SolenMatriarchQuest( player, this.RedSolen );
if ( player.Quest == null && QuestSystem.CanOfferQuest( player, typeof( SolenMatriarchQuest ) ) )
{
newQuest.SendOffer();
}
else
{
newQuest.AddConversation( new DontOfferConversation( SolenMatriarchQuest.IsFriend( player, this.RedSolen ) ) );
}
}
dropped.Delete();
return true;
}
else if ( dropped is ZoogiFungus )
{
OnGivenFungi( player, (ZoogiFungus)dropped );
return dropped.Deleted;
}
}
return base.OnDragDrop( from, dropped );
}
public override void GetContextMenuEntries( Mobile from, List<ContextMenuEntry> list )
{
base.GetContextMenuEntries( from, list );
if ( from.Alive )
{
PlayerMobile pm = from as PlayerMobile;
if ( pm != null )
{
SolenMatriarchQuest qs = pm.Quest as SolenMatriarchQuest;
if ( qs != null && qs.RedSolen == this.RedSolen )
{
if ( qs.IsObjectiveInProgress( typeof( ProcessFungiObjective ) ) )
{
list.Add( new ProcessZoogiFungusEntry( this, pm ) );
}
}
}
}
}
private class ProcessZoogiFungusEntry : ContextMenuEntry
{
private BaseSolenMatriarch m_Matriarch;
private PlayerMobile m_From;
public ProcessZoogiFungusEntry( BaseSolenMatriarch matriarch, PlayerMobile from ) : base( 6184 )
{
m_Matriarch = matriarch;
m_From = from;
}
public override void OnClick()
{
if ( m_From.Alive )
m_From.Target = new ProcessFungiTarget( m_Matriarch, m_From );
}
}
private class ProcessFungiTarget : Target
{
private BaseSolenMatriarch m_Matriarch;
private PlayerMobile m_From;
public ProcessFungiTarget( BaseSolenMatriarch matriarch, PlayerMobile from ) : base( -1, false, TargetFlags.None )
{
m_Matriarch = matriarch;
m_From = from;
}
protected override void OnTargetCancel( Mobile from, TargetCancelType cancelType )
{
from.SendLocalizedMessage( 1042021, "", 0x59 ); // Cancelled.
}
protected override void OnTarget( Mobile from, object targeted )
{
if ( targeted is ZoogiFungus )
{
ZoogiFungus fungus = (ZoogiFungus)targeted;
if ( fungus.IsChildOf( m_From.Backpack ) )
m_Matriarch.OnGivenFungi( m_From, (ZoogiFungus)targeted );
else
m_From.SendLocalizedMessage( 1042001 ); // That must be in your pack for you to use it.
}
}
}
public void OnGivenFungi( PlayerMobile player, ZoogiFungus fungi )
{
this.Direction = GetDirectionTo( player );
SolenMatriarchQuest qs = player.Quest as SolenMatriarchQuest;
if ( qs != null && qs.RedSolen == this.RedSolen )
{
QuestObjective obj = qs.FindObjective( typeof( ProcessFungiObjective ) );
if ( obj != null && !obj.Completed )
{
int amount = fungi.Amount / 2;
if ( amount > 100 )
amount = 100;
if ( amount > 0 )
{
if ( amount * 2 >= fungi.Amount )
fungi.Delete();
else
fungi.Amount -= amount * 2;
PowderOfTranslocation powder = new PowderOfTranslocation( amount );
player.AddToBackpack( powder );
player.SendLocalizedMessage( 1054100 ); // You receive some powder of translocation.
obj.Complete();
}
}
}
}
public BaseSolenMatriarch( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.WriteEncodedInt( (int) 0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadEncodedInt();
}
}
public class RedSolenMatriarch : BaseSolenMatriarch
{
public override bool RedSolen{ get{ return true; } }
[Constructable]
public RedSolenMatriarch()
{
}
public RedSolenMatriarch( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.WriteEncodedInt( (int) 0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadEncodedInt();
}
}
public class BlackSolenMatriarch : BaseSolenMatriarch
{
public override bool RedSolen{ get{ return false; } }
[Constructable]
public BlackSolenMatriarch()
{
}
public BlackSolenMatriarch( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.WriteEncodedInt( (int) 0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadEncodedInt();
}
}
}

View file

@ -0,0 +1,216 @@
using System;
using Server;
using Server.Mobiles;
using Server.Items;
namespace Server.Engines.Quests.Matriarch
{
public class KillInfiltratorsObjective : QuestObjective
{
public override object Message
{
get
{
// Kill 7 black/red solen infiltrators.
return ((SolenMatriarchQuest)System).RedSolen ? 1054086 : 1054085;
}
}
public override int MaxProgress{ get{ return 7; } }
public KillInfiltratorsObjective()
{
}
public override void RenderProgress( BaseQuestGump gump )
{
if ( !Completed )
{
// Black/Red Solen Infiltrators killed:
gump.AddHtmlLocalized( 70, 260, 270, 100, ((SolenMatriarchQuest)System).RedSolen ? 1054088 : 1054087, BaseQuestGump.Blue, false, false );
gump.AddLabel( 70, 280, 0x64, CurProgress.ToString() );
gump.AddLabel( 100, 280, 0x64, "/" );
gump.AddLabel( 130, 280, 0x64, MaxProgress.ToString() );
}
else
{
base.RenderProgress( gump );
}
}
public override bool IgnoreYoungProtection( Mobile from )
{
if ( Completed )
return false;
bool redSolen = ((SolenMatriarchQuest)System).RedSolen;
if ( redSolen )
return from is BlackSolenInfiltratorWarrior || from is BlackSolenInfiltratorQueen;
else
return from is RedSolenInfiltratorWarrior || from is RedSolenInfiltratorQueen;
}
public override void OnKill( BaseCreature creature, Container corpse )
{
bool redSolen = ((SolenMatriarchQuest)System).RedSolen;
if ( redSolen )
{
if ( creature is BlackSolenInfiltratorWarrior || creature is BlackSolenInfiltratorQueen )
CurProgress++;
}
else
{
if ( creature is RedSolenInfiltratorWarrior || creature is RedSolenInfiltratorQueen )
CurProgress++;
}
}
public override void OnComplete()
{
System.AddObjective( new ReturnAfterKillsObjective() );
}
}
public class ReturnAfterKillsObjective : QuestObjective
{
public override object Message
{
get
{
/* You've completed your task of slaying solen infiltrators. Return to the
* Matriarch who gave you this task.
*/
return 1054090;
}
}
public ReturnAfterKillsObjective()
{
}
public override void OnComplete()
{
System.AddConversation( new GatherWaterConversation() );
}
}
public class GatherWaterObjective : QuestObjective
{
public override object Message
{
get
{
// Gather 8 gallons of water for the water vats of the solen ant lair.
return 1054092;
}
}
public override int MaxProgress{ get{ return 40; } }
public GatherWaterObjective()
{
}
public override void RenderProgress( BaseQuestGump gump )
{
if ( !Completed )
{
gump.AddHtmlLocalized( 70, 260, 270, 100, 1054093, BaseQuestGump.Blue, false, false ); // Gallons of Water gathered:
gump.AddLabel( 70, 280, 0x64, (CurProgress / 5).ToString() );
gump.AddLabel( 100, 280, 0x64, "/" );
gump.AddLabel( 130, 280, 0x64, (MaxProgress / 5).ToString() );
}
else
{
base.RenderProgress( gump );
}
}
public override void OnComplete()
{
System.AddObjective( new ReturnAfterWaterObjective() );
}
}
public class ReturnAfterWaterObjective : QuestObjective
{
public override object Message
{
get
{
// You've completed your task of gathering water. Return to the Matriarch who gave you this task.
return 1054095;
}
}
public ReturnAfterWaterObjective()
{
}
public override void OnComplete()
{
PlayerMobile player = System.From;
bool redSolen = ((SolenMatriarchQuest)System).RedSolen;
bool friend = SolenMatriarchQuest.IsFriend( player, redSolen );
System.AddConversation( new ProcessFungiConversation( friend ) );
if ( redSolen )
player.SolenFriendship = SolenFriendship.Red;
else
player.SolenFriendship = SolenFriendship.Black;
}
}
public class ProcessFungiObjective : QuestObjective
{
public override object Message
{
get
{
// Give the Solen Matriarch a stack of zoogi fungus to process into powder of translocation.
return 1054098;
}
}
public ProcessFungiObjective()
{
}
public override void OnComplete()
{
if ( SolenMatriarchQuest.GiveRewardTo( System.From ) )
{
System.Complete();
}
else
{
System.AddConversation( new FullBackpackConversation( true ) );
}
}
}
public class GetRewardObjective : QuestObjective
{
public override object Message
{
get
{
// Return to the solen matriarch for your reward.
return 1054149;
}
}
public GetRewardObjective()
{
}
public override void OnComplete()
{
System.AddConversation( new EndConversation() );
}
}
}

View file

@ -0,0 +1,160 @@
using System;
using Server;
using Server.Mobiles;
using Server.Items;
namespace Server.Engines.Quests.Matriarch
{
public class SolenMatriarchQuest : QuestSystem
{
private static Type[] m_TypeReferenceTable = new Type[]
{
typeof( Matriarch.DontOfferConversation ),
typeof( Matriarch.AcceptConversation ),
typeof( Matriarch.DuringKillInfiltratorsConversation ),
typeof( Matriarch.GatherWaterConversation ),
typeof( Matriarch.DuringWaterGatheringConversation ),
typeof( Matriarch.ProcessFungiConversation ),
typeof( Matriarch.DuringFungiProcessConversation ),
typeof( Matriarch.FullBackpackConversation ),
typeof( Matriarch.EndConversation ),
typeof( Matriarch.KillInfiltratorsObjective ),
typeof( Matriarch.ReturnAfterKillsObjective ),
typeof( Matriarch.GatherWaterObjective ),
typeof( Matriarch.ReturnAfterWaterObjective ),
typeof( Matriarch.ProcessFungiObjective ),
typeof( Matriarch.GetRewardObjective )
};
public override Type[] TypeReferenceTable{ get{ return m_TypeReferenceTable; } }
public override object Name
{
get
{
// Solen Matriarch Quest
return 1054147;
}
}
public override object OfferMessage
{
get
{
if ( IsFriend( From, RedSolen ) )
{
/* <I>The Solen Matriarch smiles happily as you greet her.</I><BR><BR>
*
* Hello again. It is always good to see a friend of our colony.<BR><BR>
*
* Would you like me to process some zoogi fungus into powder of translocation
* for you? I would be happy to do so if you will first undertake a couple
* tasks for me.<BR><BR>
*
* First, I would like for you to eliminate some infiltrators from the other
* solen colony. They are spying on my colony, and I fear for the safety of my
* people. They must be slain.<BR><BR>
*
* After that, I must ask that you gather some water for me. Our water supplies
* are inadequate, so we must try to supplement our reserve using water vats here
* in our lair.<BR><BR>
*
* Will you accept my offer?
*/
return 1054083;
}
else
{
/* <I>The Solen Matriarch smiles happily as she eats the seed you offered.</I><BR><BR>
*
* I think you for that seed. I was quite delicious. So full of flavor.<BR><BR>
*
* Hmm... if you would like, I could make you a friend of my colony. This would stop
* the warriors, workers, and queens of my colony from thinking you are an intruder,
* thus they would not attack you. In addition, as a friend of my colony I will process
* zoogi fungus into powder of translocation for you.<BR><BR>
*
* To become a friend of my colony, I ask that you complete a couple tasks for me. These
* are the same tasks I will ask of you when you wish me to process zoogi fungus,
* by the way.<BR><BR>
*
* First, I would like for you to eliminate some infiltrators from the other solen colony.
* They are spying on my colony, and I fear for the safety of my people. They must
* be slain.<BR><BR>
*
* After that, I must ask that you gather some water for me. Our water supplies are
* inadequate, so we must try to supplement our reserve using water vats here in our
* lair.<BR><BR>
*
* Will you accept my offer?
*/
return 1054082;
}
}
}
public override TimeSpan RestartDelay{ get{ return TimeSpan.Zero; } }
public override bool IsTutorial{ get{ return false; } }
public override int Picture{ get{ return 0x15C9; } }
private bool m_RedSolen;
public bool RedSolen{ get{ return m_RedSolen; } }
public SolenMatriarchQuest( PlayerMobile from, bool redSolen ) : base( from )
{
m_RedSolen = redSolen;
}
// Serialization
public SolenMatriarchQuest()
{
}
public override void ChildDeserialize( GenericReader reader )
{
int version = reader.ReadEncodedInt();
m_RedSolen = reader.ReadBool();
}
public override void ChildSerialize( GenericWriter writer )
{
writer.WriteEncodedInt( (int) 0 ); // version
writer.Write( (bool) m_RedSolen );
}
public override void Accept()
{
base.Accept();
AddConversation( new AcceptConversation() );
}
public static bool IsFriend( PlayerMobile player, bool redSolen )
{
if ( redSolen )
return player.SolenFriendship == SolenFriendship.Red;
else
return player.SolenFriendship == SolenFriendship.Black;
}
public static bool GiveRewardTo( PlayerMobile player )
{
Gold gold = new Gold( Utility.RandomMinMax( 250, 350 ) );
if ( player.PlaceInBackpack( gold ) )
{
player.SendLocalizedMessage( 1054076 ); // You have been given some gold.
return true;
}
else
{
gold.Delete();
return false;
}
}
}
}

View file

@ -0,0 +1,205 @@
using System;
using Server;
namespace Server.Engines.Quests.Naturalist
{
public class DontOfferConversation : QuestConversation
{
public override object Message
{
get
{
/* <I>The Naturalist looks up from his scribbled notes.</I><BR><BR>
*
* Greetings!<BR><BR>
*
* If you're interested in helping out a scholar of some repute, I do have some
* work that I could use some assistance with.<BR><BR>
*
* You seem a little preoccupied with another task right now, however. Perhaps
* you should finish whatever it is that has your attention at the moment and
* return to me once you're done.
*/
return 1054052;
}
}
public override bool Logged{ get{ return false; } }
public DontOfferConversation()
{
}
}
public class AcceptConversation : QuestConversation
{
public override object Message
{
get
{
/* Ah! This is splendid news! Each time an assistant travels into the
* Solen Hive to gather information for me, I feel as if I am one step
* closer to some grand discovery. Though I felt the same way when I was
* certain that Terathans had the ability to change their shape to resemble
* various fruits and vegetables - a point on which I am certain further
* study of the beasts will prove correct.<BR><BR>
*
* In any case, I cannot thank you enough! Please return to me when you have
* studied all the Solen Egg Nests hidden within the Solen Hive.
*/
return 1054043;
}
}
public AcceptConversation()
{
}
public override void OnRead()
{
System.AddObjective( new StudyNestsObjective() );
}
}
public class NaturalistDuringStudyConversation : QuestConversation
{
public override object Message
{
get
{
/* <I>The Naturalist looks up from his notes with a frustrated look
* on his face.</I><BR><BR>
*
* Haven't you finished the task I appointed you yet? Gah! It's so
* difficult to find a good apprentice these days.<BR><BR>
*
* Remember, you must first find an entrance to the Solen Hive. Once inside,
* I need you to examine the Solen Egg Nests for me. When you have studied
* all four nests, you should have enough information to earn yourself a
* reward.<BR><BR>
*
* Now go on, away with you! I have piles of notes from other more helpful
* apprentices that I still need to study!
*/
return 1054049;
}
}
public override bool Logged{ get{ return false; } }
public NaturalistDuringStudyConversation()
{
}
}
public class EndConversation : QuestConversation
{
public override object Message
{
get
{
/* <I>The Naturalist looks up from his notes with a pleased expression
* on his face.</I><BR><BR>
*
* Ah! Thank you, my goodly apprentice! These notes you have gathered will
* no doubt assist me in my understanding of these fascinating Solen creatures.<BR><BR>
*
* Now, since you've done such a fine job, I feel that I should give you a little
* reward.<BR><BR>
*
* I have a botanist friend who has discovered a strange mutation in the plants
* she has grown. Through science and sorcery, she has managed to produce a mutant
* strain of colored seeds the like of which no gardener has laid eyes upon.<BR><BR>
*
* As a reward for your fine efforts, I present you with this strange rare seed.
* Which reminds me, I still need to compile my notes on Solen dietary habits. They
* are voracious seed eaters, those Solen Matriarchs!<BR><BR>
*
* In any case, I must get back to my notes now. I give you my thanks once more,
* and bid a good day to you my little apprentice! If you wish to help me out again,
* just say the word.
*/
return 1054050;
}
}
public EndConversation()
{
}
public override void OnRead()
{
System.Complete();
}
}
public class SpecialEndConversation : QuestConversation
{
public override object Message
{
get
{
/* <I>The Naturalist looks up from his notes with an ecstatic look upon
* his face.</I><BR><BR>
*
* Oh my! These notes you've brought me - they say you have information on the
* Secret Solen Egg Nest? I've heard many tales of this secret store of special
* Solen Eggs, but there are many missing gaps in my notes concerning it.<BR><BR>
*
* The notes you've made here will most certainly advance my understanding of
* this mysterious breed of creatures!<BR><BR>
*
* Considering the amazing effort you put into your work, I feel as if I should
* give you something extra special as a bonus. Hrmm...<BR><BR>
*
* I have a botanist friend who has discovered a strange mutation in the plants
* she has grown. Through science and sorcery, she has managed to produce a rare
* mutant strain of colored seeds the like of which no gardener has laid
* eyes upon.<BR><BR>
*
* I've given a few of her seeds out to various apprentices - but I usually keep
* her very rare stock all for myself. They're quite amazing looking! However,
* since you've done such a fine job for me, I'll present you with one of
* these rare fire-red seeds.<BR><BR>
*
* Once again, my thanks to you! Now I really must get back to studying these notes!
* Take care, my fine apprentice, and come back if you wish to help me further!
*/
return 1054051;
}
}
public SpecialEndConversation()
{
}
public override void OnRead()
{
System.Complete();
}
}
public class FullBackpackConversation : QuestConversation
{
public override object Message
{
get
{
/* <I>The Naturalist looks at you with a friendly expression.</I><BR><BR>
*
* I see you've returned with information for me. While I'd like to finish
* conducting our business, it seems that you're a bit overloaded with
* equipment at the moment. Perhaps you'd better free up some room before
* we get to discussing your reward.
*/
return 1054053;
}
}
public override bool Logged{ get{ return false; } }
public FullBackpackConversation()
{
}
}
}

View file

@ -0,0 +1,158 @@
using System;
using Server;
using Server.Mobiles;
using Server.Items;
using Server.Engines.Plants;
using Server.Engines.Quests;
namespace Server.Engines.Quests.Naturalist
{
public class Naturalist : BaseQuester
{
[Constructable]
public Naturalist() : base( "the Naturalist" )
{
}
public override void InitBody()
{
InitStats( 100, 100, 25 );
Hue = Utility.RandomSkinHue();
Female = false;
Body = 0x190;
Name = NameList.RandomName( "male" );
}
public override void InitOutfit()
{
AddItem( new Tunic( 0x598 ) );
AddItem( new LongPants( 0x59B ) );
AddItem( new Boots() );
Utility.AssignRandomHair( this );
Utility.AssignRandomFacialHair( this, HairHue );
}
public override void OnTalk( PlayerMobile player, bool contextMenu )
{
StudyOfSolenQuest qs = player.Quest as StudyOfSolenQuest;
if ( qs != null && qs.Naturalist == this )
{
StudyNestsObjective study = qs.FindObjective( typeof( StudyNestsObjective ) ) as StudyNestsObjective;
if ( study != null )
{
if ( !study.Completed )
{
PlaySound( 0x41F );
qs.AddConversation( new NaturalistDuringStudyConversation() );
}
else
{
QuestObjective obj = qs.FindObjective( typeof( ReturnToNaturalistObjective ) );
if ( obj != null && !obj.Completed )
{
Seed reward;
PlantType type;
switch ( Utility.Random( 17 ) )
{
case 0: type = PlantType.CampionFlowers; break;
case 1: type = PlantType.Poppies; break;
case 2: type = PlantType.Snowdrops; break;
case 3: type = PlantType.Bulrushes; break;
case 4: type = PlantType.Lilies; break;
case 5: type = PlantType.PampasGrass; break;
case 6: type = PlantType.Rushes; break;
case 7: type = PlantType.ElephantEarPlant; break;
case 8: type = PlantType.Fern; break;
case 9: type = PlantType.PonytailPalm; break;
case 10: type = PlantType.SmallPalm; break;
case 11: type = PlantType.CenturyPlant; break;
case 12: type = PlantType.WaterPlant; break;
case 13: type = PlantType.SnakePlant; break;
case 14: type = PlantType.PricklyPearCactus; break;
case 15: type = PlantType.BarrelCactus; break;
default: type = PlantType.TribarrelCactus; break;
}
if ( study.StudiedSpecialNest )
{
reward = new Seed( type, PlantHue.FireRed, false );
}
else
{
PlantHue hue;
switch ( Utility.Random( 3 ) )
{
case 0: hue = PlantHue.Pink; break;
case 1: hue = PlantHue.Magenta; break;
default: hue = PlantHue.Aqua; break;
}
reward = new Seed( type, hue, false );
}
if ( player.PlaceInBackpack( reward ) )
{
obj.Complete();
PlaySound( 0x449 );
PlaySound( 0x41B );
if ( study.StudiedSpecialNest )
qs.AddConversation( new SpecialEndConversation() );
else
qs.AddConversation( new EndConversation() );
}
else
{
reward.Delete();
qs.AddConversation( new FullBackpackConversation() );
}
}
}
}
}
else
{
QuestSystem newQuest = new StudyOfSolenQuest( player, this );
if ( player.Quest == null && QuestSystem.CanOfferQuest( player, typeof( StudyOfSolenQuest ) ) )
{
PlaySound( 0x42F );
newQuest.SendOffer();
}
else
{
PlaySound( 0x448 );
newQuest.AddConversation( new DontOfferConversation() );
}
}
}
public Naturalist( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.WriteEncodedInt( (int) 0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadEncodedInt();
}
}
}

View file

@ -0,0 +1,91 @@
using System;
using Server;
namespace Server.Engines.Quests.Naturalist
{
public class NestArea
{
private static readonly NestArea[] m_Areas = new NestArea[]
{
new NestArea( false, new Rectangle2D( 5861, 1787, 26, 25 ) ),
new NestArea( false, new Rectangle2D( 5734, 1788, 14, 50 ),
new Rectangle2D( 5748, 1800, 3, 34 ),
new Rectangle2D( 5751, 1808, 2, 20 ) ),
new NestArea( false, new Rectangle2D( 5907, 1908, 19, 43 ) ),
new NestArea( false, new Rectangle2D( 5721, 1926, 24, 29 ),
new Rectangle2D( 5745, 1935, 7, 22 ) ),
new NestArea( true, new Rectangle2D( 5651, 1853, 21, 32 ),
new Rectangle2D( 5672, 1857, 6, 20 ) )
};
public static int NonSpecialCount
{
get
{
int n = 0;
foreach ( NestArea area in m_Areas )
{
if ( !area.Special )
n++;
}
return n;
}
}
public static NestArea Find( IPoint2D p )
{
foreach ( NestArea area in m_Areas )
{
if ( area.Contains( p ) )
return area;
}
return null;
}
public static NestArea GetByID( int id )
{
if ( id >= 0 && id < m_Areas.Length )
return m_Areas[id];
else
return null;
}
private bool m_Special;
private Rectangle2D[] m_Rects;
public bool Special{ get{ return m_Special; } }
public int ID
{
get
{
for ( int i = 0; i < m_Areas.Length; i++ )
{
if ( m_Areas[i] == this )
return i;
}
return 0;
}
}
private NestArea( bool special, params Rectangle2D[] rects )
{
m_Special = special;
m_Rects = rects;
}
public bool Contains( IPoint2D p )
{
foreach ( Rectangle2D rect in m_Rects )
{
if ( rect.Contains( p ) )
return true;
}
return false;
}
}
}

View file

@ -0,0 +1,203 @@
using System;
using System.Collections;
using Server;
using Server.Mobiles;
namespace Server.Engines.Quests.Naturalist
{
public class StudyNestsObjective : QuestObjective
{
public override object Message
{
get
{
/* Find an entrance to the Solen Hive, and search within for the Solen
* Egg Nests. Each Nest must be studied for some time without a break in
* concentration in order to gather useful information.<BR><BR>
*
* Once you have completed your study of the Nests, return to the Naturalist
* who gave you this task.
*/
return 1054044;
}
}
public override int MaxProgress{ get{ return NestArea.NonSpecialCount; } }
private NestArea m_CurrentNest;
private DateTime m_StudyBegin;
private enum StudyState { Inactive, FirstStep, SecondStep }
private StudyState m_StudyState;
private ArrayList m_StudiedNests;
private bool m_StudiedSpecialNest;
public bool StudiedSpecialNest{ get{ return m_StudiedSpecialNest; } }
public StudyNestsObjective()
{
m_StudiedNests = new ArrayList();
}
public override bool GetTimerEvent()
{
return true;
}
public override void CheckProgress()
{
PlayerMobile from = System.From;
if ( m_CurrentNest != null )
{
NestArea nest = m_CurrentNest;
if ( ( from.Map == Map.Trammel || from.Map == Map.Felucca ) && nest.Contains( from ) )
{
if ( m_StudyState != StudyState.Inactive )
{
TimeSpan time = DateTime.UtcNow - m_StudyBegin;
if ( time > TimeSpan.FromSeconds( 30.0 ) )
{
m_StudiedNests.Add( nest );
m_StudyState = StudyState.Inactive;
if ( m_CurrentNest.Special )
{
from.SendLocalizedMessage( 1054057 ); // You complete your examination of this bizarre Egg Nest. The Naturalist will undoubtedly be quite interested in these notes!
m_StudiedSpecialNest = true;
}
else
{
from.SendLocalizedMessage( 1054054 ); // You have completed your study of this Solen Egg Nest. You put your notes away.
CurProgress++;
}
}
else if ( m_StudyState == StudyState.FirstStep && time > TimeSpan.FromSeconds( 15.0 ) )
{
if ( !nest.Special )
from.SendLocalizedMessage( 1054058 ); // You begin recording your completed notes on a bit of parchment.
m_StudyState = StudyState.SecondStep;
}
}
}
else
{
if ( m_StudyState != StudyState.Inactive )
from.SendLocalizedMessage( 1054046 ); // You abandon your study of the Solen Egg Nest without gathering the needed information.
m_CurrentNest = null;
}
}
else if ( from.Map == Map.Trammel || from.Map == Map.Felucca )
{
NestArea nest = NestArea.Find( from );
if ( nest != null )
{
m_CurrentNest = nest;
m_StudyBegin = DateTime.UtcNow;
if ( m_StudiedNests.Contains( nest ) )
{
m_StudyState = StudyState.Inactive;
from.SendLocalizedMessage( 1054047 ); // You glance at the Egg Nest, realizing you've already studied this one.
}
else
{
m_StudyState = StudyState.FirstStep;
if ( nest.Special )
from.SendLocalizedMessage( 1054056 ); // You notice something very odd about this Solen Egg Nest. You begin taking notes.
else
from.SendLocalizedMessage( 1054045 ); // You begin studying the Solen Egg Nest to gather information.
if ( from.Female )
from.PlaySound( 0x30B );
else
from.PlaySound( 0x419 );
}
}
}
}
public override void RenderProgress( BaseQuestGump gump )
{
if ( !Completed )
{
gump.AddHtmlLocalized( 70, 260, 270, 100, 1054055, BaseQuestGump.Blue, false, false ); // Solen Nests Studied :
gump.AddLabel( 70, 280, 0x64, CurProgress.ToString() );
gump.AddLabel( 100, 280, 0x64, "/" );
gump.AddLabel( 130, 280, 0x64, MaxProgress.ToString() );
}
else
{
base.RenderProgress( gump );
}
}
public override void OnComplete()
{
System.AddObjective( new ReturnToNaturalistObjective() );
}
public override void ChildDeserialize( GenericReader reader )
{
int version = reader.ReadEncodedInt();
int count = reader.ReadEncodedInt();
for ( int i = 0; i < count; i++ )
{
NestArea nest = NestArea.GetByID( reader.ReadEncodedInt() );
m_StudiedNests.Add( nest );
}
m_StudiedSpecialNest = reader.ReadBool();
}
public override void ChildSerialize( GenericWriter writer )
{
writer.WriteEncodedInt( (int) 0 ); // version
writer.WriteEncodedInt( (int) m_StudiedNests.Count );
foreach ( NestArea nest in m_StudiedNests )
{
writer.WriteEncodedInt( (int) nest.ID );
}
writer.Write( (bool) m_StudiedSpecialNest );
}
}
public class ReturnToNaturalistObjective : QuestObjective
{
public override object Message
{
get
{
/* You have studied enough Solen Egg Nests to gather a fair amount of
* useful information. Return to the Naturalist who gave you this task.
*/
return 1054048;
}
}
public ReturnToNaturalistObjective()
{
}
public override void RenderProgress( BaseQuestGump gump )
{
string count = NestArea.NonSpecialCount.ToString();
gump.AddHtmlLocalized( 70, 260, 270, 100, 1054055, BaseQuestGump.Blue, false, false ); // Solen Nests Studied :
gump.AddLabel( 70, 280, 0x64, count );
gump.AddLabel( 100, 280, 0x64, "/" );
gump.AddLabel( 130, 280, 0x64, count );
}
}
}

View file

@ -0,0 +1,111 @@
using System;
using Server;
using Server.Mobiles;
namespace Server.Engines.Quests.Naturalist
{
public class StudyOfSolenQuest : QuestSystem
{
private static Type[] m_TypeReferenceTable = new Type[]
{
typeof( StudyNestsObjective ),
typeof( ReturnToNaturalistObjective ),
typeof( DontOfferConversation ),
typeof( AcceptConversation ),
typeof( NaturalistDuringStudyConversation ),
typeof( EndConversation ),
typeof( SpecialEndConversation ),
typeof( FullBackpackConversation )
};
public override Type[] TypeReferenceTable{ get{ return m_TypeReferenceTable; } }
public override object Name
{
get
{
// "Study of the Solen Hive"
return 1054041;
}
}
public override object OfferMessage
{
get
{
/* <I>The Naturalist looks up from his notes, regarding you with a hopeful
* look in his eyes.</I><BR><BR>
*
* Um..yes..excuse me. I was wondering if you could offer me a bit of assistance.
* You see, I'm a naturalist of some repute - a gentleman and a scholar if you
* will - primarily interested in the study of insects and arachnids. While I've
* written a few interesting books on the marvelous Terathan race and their bizarre
* culture, now I've heard tales of a truly significant new discovery!<BR><BR>
*
* Apparently a race of ant-like creatures known as the Solen have appeared in
* our world, scuttling up from some previously hidden home. Can you believe it?
* Truly these are amazing times! To a scholar such as myself this is indeed
* an exciting opportunity.<BR><BR>
*
* That said, while I may be a genius of some reknown, sharp as a tack and quick
* with the quill, I'm afraid I'm not much of the adventuring type. Though I have
* gained assistance before, I still have many unanswered questions.<BR><BR>
*
* I am particularly interested in the Solen Egg Nests that are studiously
* protected by the Solen workers. If you would be so kind as to assist me,
* I would ask that you travel into the Solen Hive and inspect each of the
* Solen Egg Nests that reside within. You will have to spend some time examining
* each Nest before you have gathered enough information. Once you are done,
* report back to me and I will reward you as best as I can for your valiant
* efforts!<BR><BR>
*
* Will you accept my offer?
*/
return 1054042;
}
}
public override TimeSpan RestartDelay{ get{ return TimeSpan.Zero; } }
public override bool IsTutorial{ get{ return false; } }
public override int Picture{ get{ return 0x15C7; } }
private Naturalist m_Naturalist;
public Naturalist Naturalist{ get{ return m_Naturalist; } }
public StudyOfSolenQuest( PlayerMobile from, Naturalist naturalist ) : base( from )
{
m_Naturalist = naturalist;
}
// Serialization
public StudyOfSolenQuest()
{
}
public override void ChildDeserialize( GenericReader reader )
{
int version = reader.ReadEncodedInt();
m_Naturalist = (Naturalist) reader.ReadMobile();
}
public override void ChildSerialize( GenericWriter writer )
{
writer.WriteEncodedInt( (int) 0 ); // version
writer.Write( (Mobile) m_Naturalist );
}
public override void Accept()
{
base.Accept();
if ( m_Naturalist != null )
m_Naturalist.PlaySound( 0x431 );
AddConversation( new AcceptConversation() );
}
}
}

View file

@ -0,0 +1,111 @@
using System;
using Server;
using Server.Items;
using Server.Mobiles;
namespace Server.Engines.Quests.Zento
{
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()
{
System.AddObjective( new FirstKillObjective() );
}
}
public class DirectionConversation : QuestConversation
{
public override object Message
{
get
{
// The Deathwatch Beetle Hatchlings live in The Waste - the desert close to this city.
return 1063323;
}
}
public override bool Logged{ get{ return false; } }
public DirectionConversation()
{
}
}
public class TakeCareConversation : QuestConversation
{
public override object Message
{
get
{
// I know you can take care of those nasty Deathwatch Beetle Hatchlings! No get to it!
return 1063324;
}
}
public override bool Logged{ get{ return false; } }
public TakeCareConversation()
{
}
}
public class EndConversation : QuestConversation
{
public override object Message
{
get
{
/* Thank you for helping me get rid of these vile beasts!
* You have been rewarded for your good deeds. If you wish to
* help me in the future, visit me again.<br><br>
*
* Farewell.
*/
return 1063321;
}
}
public EndConversation()
{
}
public override void OnRead()
{
System.Complete();
}
}
}

View file

@ -0,0 +1,146 @@
using System;
using Server;
using Server.Mobiles;
using Server.Gumps;
using Server.Items;
namespace Server.Engines.Quests.Zento
{
public class AnsellaGryen : BaseQuester
{
[Constructable]
public AnsellaGryen()
{
}
public override void InitBody()
{
InitStats( 100, 100, 25 );
Hue = 0x83EA;
Female = true;
Body = 0x191;
Name = "Ansella Gryen";
}
public override void InitOutfit()
{
HairItemID = 0x203B;
HairHue = 0x1BB;
AddItem( new SamuraiTabi( 0x8FD ) );
AddItem( new FemaleKimono( 0x4B6 ) );
AddItem( new Obi( 0x526 ) );
AddItem( new GoldBracelet() );
}
public override int GetAutoTalkRange( PlayerMobile m )
{
if ( m.Quest == null )
return 3;
else
return -1;
}
public override void OnTalk( PlayerMobile player, bool contextMenu )
{
QuestSystem qs = player.Quest;
if ( qs is TerribleHatchlingsQuest )
{
if ( qs.IsObjectiveInProgress( typeof( FirstKillObjective ) ) )
{
qs.AddConversation( new DirectionConversation() );
}
else if ( qs.IsObjectiveInProgress( typeof( SecondKillObjective ) )
|| qs.IsObjectiveInProgress( typeof( ThirdKillObjective ) ) )
{
qs.AddConversation( new TakeCareConversation() );
}
else
{
QuestObjective obj = qs.FindObjective( typeof( ReturnObjective ) );
if ( obj != null && !obj.Completed )
{
Container cont = GetNewContainer();
cont.DropItem( new Gold( Utility.RandomMinMax( 100, 200 ) ) );
if ( Utility.RandomBool() )
{
BaseWeapon weapon = Loot.Construct( Loot.SEWeaponTypes ) as BaseWeapon;
if ( weapon != null )
{
BaseRunicTool.ApplyAttributesTo( weapon, 3, 10, 30 );
cont.DropItem( weapon );
}
}
else
{
BaseArmor armor = Loot.Construct( Loot.SEArmorTypes ) as BaseArmor;
if ( armor != null )
{
BaseRunicTool.ApplyAttributesTo( armor, 1, 10, 20 );
cont.DropItem( armor );
}
}
if ( player.PlaceInBackpack( cont ) )
{
obj.Complete();
}
else
{
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
{
TerribleHatchlingsQuest newQuest = new TerribleHatchlingsQuest( player );
bool inRestartPeriod = false;
if ( qs != null )
{
if ( contextMenu )
SayTo( player, 1063322 ); // Before you can help me with the Terrible Hatchlings, you'll need to finish the quest you've already taken!
}
else if ( QuestSystem.CanOfferQuest( player, typeof( TerribleHatchlingsQuest ), out inRestartPeriod ) )
{
newQuest.SendOffer();
}
else if ( inRestartPeriod && contextMenu )
{
SayTo( player, 1049357 ); // I have nothing more for you at this time.
}
}
}
public AnsellaGryen( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.WriteEncodedInt( 0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadEncodedInt();
}
public override void TurnToTokuno() { }
}
}

View file

@ -0,0 +1,178 @@
using System;
using Server;
using Server.Items;
using Server.Mobiles;
namespace Server.Engines.Quests.Zento
{
public class FirstKillObjective : QuestObjective
{
public override object Message
{
get
{
// Kill 10 Deathwatch Beetle Hatchlings and return to Ansella Gryen.
return 1063316;
}
}
public override void RenderProgress( BaseQuestGump gump )
{
if ( !Completed )
{
// Deathwatch Beetle Hatchlings killed:
gump.AddHtmlLocalized( 70, 260, 270, 100, 1063318, 0x12DC6BF, false, false );
gump.AddLabel( 70, 280, 0x64, "0" );
gump.AddLabel( 100, 280, 0x64, "/" );
gump.AddLabel( 130, 280, 0x64, "10" );
}
else
{
base.RenderProgress( gump );
}
}
public FirstKillObjective()
{
}
public override void OnKill( BaseCreature creature, Container corpse )
{
if ( creature is DeathwatchBeetleHatchling )
Complete();
}
public override void OnComplete()
{
System.AddObjective( new SecondKillObjective() );
}
}
public class SecondKillObjective : QuestObjective
{
public override object Message
{
get
{
/* Great job! One less terrible hatchling in the Waste!<BR><BR>
*
* Once you've killed 10 of the Deathwatch Beetle Hatchlings,
* return to Ansella for your reward!
*/
return 1063320;
}
}
public override void RenderProgress( BaseQuestGump gump )
{
if ( !Completed )
{
// Deathwatch Beetle Hatchlings killed:
gump.AddHtmlLocalized( 70, 260, 270, 100, 1063318, 0x12DC6BF, false, false );
gump.AddLabel( 70, 280, 0x64, "1" );
gump.AddLabel( 100, 280, 0x64, "/" );
gump.AddLabel( 130, 280, 0x64, "10" );
}
else
{
base.RenderProgress( gump );
}
}
public SecondKillObjective()
{
}
public override void OnKill( BaseCreature creature, Container corpse )
{
if ( creature is DeathwatchBeetleHatchling )
{
Complete();
System.AddObjective( new ThirdKillObjective( 2 ) );
}
}
public override void OnRead()
{
if ( !Completed )
{
Complete();
System.AddObjective( new ThirdKillObjective( 1 ) );
}
}
}
public class ThirdKillObjective : QuestObjective
{
public override object Message
{
get
{
// Continue killing Deathwatch Beetle Hatchlings.
return 1063319;
}
}
public override void RenderProgress( BaseQuestGump gump )
{
if ( !Completed )
{
// Deathwatch Beetle Hatchlings killed:
gump.AddHtmlLocalized( 70, 260, 270, 100, 1063318, 0x12DC6BF, false, false );
gump.AddLabel( 70, 280, 0x64, CurProgress.ToString() );
gump.AddLabel( 100, 280, 0x64, "/" );
gump.AddLabel( 130, 280, 0x64, "10" );
}
else
{
base.RenderProgress( gump );
}
}
public override int MaxProgress{ get{ return 10; } }
public ThirdKillObjective( int startingProgress )
{
CurProgress = startingProgress;
}
public ThirdKillObjective()
{
}
public override void OnKill( BaseCreature creature, Container corpse )
{
if ( creature is DeathwatchBeetleHatchling )
CurProgress++;
}
public override void OnComplete()
{
System.AddObjective( new ReturnObjective() );
}
}
public class ReturnObjective : QuestObjective
{
public override object Message
{
get
{
// Return to Ansella Gryen for your reward.
return 1063313;
}
}
public ReturnObjective()
{
}
public override void OnComplete()
{
System.AddConversation( new EndConversation() );
}
}
}

View file

@ -0,0 +1,70 @@
using System;
using Server;
using Server.Items;
using Server.Mobiles;
namespace Server.Engines.Quests.Zento
{
public class TerribleHatchlingsQuest : QuestSystem
{
private static Type[] m_TypeReferenceTable = new Type[]
{
typeof( AcceptConversation ),
typeof( DirectionConversation ),
typeof( TakeCareConversation ),
typeof( EndConversation ),
typeof( FirstKillObjective ),
typeof( SecondKillObjective ),
typeof( ThirdKillObjective ),
typeof( ReturnObjective )
};
public override Type[] TypeReferenceTable{ get{ return m_TypeReferenceTable; } }
public override object Name
{
get
{
// Terrible Hatchlings
return 1063314;
}
}
public override object OfferMessage
{
get
{
/* The Deathwatch Beetle Hatchlings have trampled through my fields
* again, what a nuisance! Please help me get rid of the terrible
* hatchlings. If you kill 10 of them, you will be rewarded.
* The Deathwatch Beetle Hatchlings live in The Waste -
* the desert close to this city.<BR><BR>
*
* Will you accept this challenge?
*/
return 1063315;
}
}
public override TimeSpan RestartDelay{ get{ return TimeSpan.MaxValue; } }
public override bool IsTutorial{ get{ return true; } }
public override int Picture{ get{ return 0x15CF; } }
public TerribleHatchlingsQuest( PlayerMobile from ) : base( from )
{
}
// Serialization
public TerribleHatchlingsQuest()
{
}
public override void Accept()
{
base.Accept();
AddConversation( new AcceptConversation() );
}
}
}

View file

@ -0,0 +1,93 @@
using System;
using Server;
using Server.Items;
using Server.Mobiles;
namespace Server.Engines.Quests.Doom
{
public class AcceptConversation : QuestConversation
{
public override object Message
{
get
{
/* You have accepted Victoria's help. She requires 1000 Daemon
* bones to summon the devourer.<BR><BR>
*
* You may hand Victoria the bones as you collect them and she
* will keep count of how many you have brought her.<BR><BR>
*
* Daemon bones can be collected via various means throughout
* Dungeon Doom.<BR><BR>
*
* Good luck.
*/
return 1050027;
}
}
public AcceptConversation()
{
}
public override void OnRead()
{
System.AddObjective( new CollectBonesObjective() );
}
}
public class VanquishDaemonConversation : QuestConversation
{
public override object Message
{
get
{
/* Well done brave soul. I shall summon the beast to the circle
* of stones just South-East of here. Take great care - the beast
* takes many forms. Now hurry...
*/
return 1050021;
}
}
public VanquishDaemonConversation()
{
}
public override void OnRead()
{
Victoria victoria = ((TheSummoningQuest)System).Victoria;
if ( victoria == null )
{
System.From.SendMessage( "Internal error: unable to find Victoria. Quest unable to continue." );
System.Cancel();
}
else
{
SummoningAltar altar = victoria.Altar;
if ( altar == null )
{
System.From.SendMessage( "Internal error: unable to find summoning altar. Quest unable to continue." );
System.Cancel();
}
else if ( altar.Daemon == null || !altar.Daemon.Alive )
{
BoneDemon daemon = new BoneDemon();
daemon.MoveToWorld( altar.Location, altar.Map );
altar.Daemon = daemon;
System.AddObjective( new VanquishDaemonObjective( daemon ) );
}
else
{
victoria.SayTo( System.From, "The devourer has already been summoned." );
((TheSummoningQuest)System).WaitForSummon = true;
}
}
}
}
}

View file

@ -0,0 +1,135 @@
using System;
using Server;
using Server.Items;
using Server.Mobiles;
using Server.Network;
namespace Server.Engines.Quests.Doom
{
public class BellOfTheDead : Item
{
public override int LabelNumber{ get{ return 1050018; } } // bell of the dead
[Constructable]
public BellOfTheDead() : base( 0x91A )
{
Hue = 0x835;
Movable = false;
}
private Chyloth m_Chyloth;
private SkeletalDragon m_Dragon;
private bool m_Summoning;
[CommandProperty( AccessLevel.GameMaster, AccessLevel.Administrator )]
public Chyloth Chyloth
{
get{ return m_Chyloth; }
set{ m_Chyloth = value; }
}
[CommandProperty( AccessLevel.GameMaster, AccessLevel.Administrator )]
public SkeletalDragon Dragon
{
get{ return m_Dragon; }
set{ m_Dragon = value; }
}
[CommandProperty( AccessLevel.GameMaster, AccessLevel.Administrator )]
public bool Summoning
{
get{ return m_Summoning; }
set{ m_Summoning = value; }
}
public override void OnDoubleClick( Mobile from )
{
if ( from.InRange( GetWorldLocation(), 2 ) )
BeginSummon( from );
else
from.LocalOverheadMessage( MessageType.Regular, 0x3B2, 1019045 ); // I can't reach that.
}
public virtual void BeginSummon( Mobile from )
{
if ( m_Chyloth != null && !m_Chyloth.Deleted )
{
from.SendLocalizedMessage( 1050010 ); // The ferry man has already been summoned. There is no need to ring for him again.
}
else if ( m_Dragon != null && !m_Dragon.Deleted )
{
from.SendLocalizedMessage( 1050017 ); // The ferryman has recently been summoned already. You decide against ringing the bell again so soon.
}
else if ( !m_Summoning )
{
m_Summoning = true;
Effects.PlaySound( GetWorldLocation(), Map, 0x100 );
Timer.DelayCall( TimeSpan.FromSeconds( 8.0 ), new TimerStateCallback( EndSummon ), from );
}
}
public virtual void EndSummon( object state )
{
Mobile from = (Mobile)state;
if ( m_Chyloth != null && !m_Chyloth.Deleted )
{
from.SendLocalizedMessage( 1050010 ); // The ferry man has already been summoned. There is no need to ring for him again.
}
else if ( m_Dragon != null && !m_Dragon.Deleted )
{
from.SendLocalizedMessage( 1050017 ); // The ferryman has recently been summoned already. You decide against ringing the bell again so soon.
}
else if ( m_Summoning )
{
m_Summoning = false;
Point3D loc = GetWorldLocation();
loc.Z -= 16;
Effects.SendLocationParticles( EffectItem.Create( loc, Map, EffectItem.DefaultDuration ), 0x3728, 10, 10, 0, 0, 2023, 0 );
Effects.PlaySound( loc, Map, 0x1FE );
m_Chyloth = new Chyloth();
m_Chyloth.Direction = (Direction)(7 & (4 + (int)from.GetDirectionTo( loc )));
m_Chyloth.MoveToWorld( loc, Map );
m_Chyloth.Bell = this;
m_Chyloth.AngryAt = from;
m_Chyloth.BeginGiveWarning();
m_Chyloth.BeginRemove( TimeSpan.FromSeconds( 40.0 ) );
}
}
public BellOfTheDead( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 0 ); // version
writer.Write( (Mobile) m_Chyloth );
writer.Write( (Mobile) m_Dragon );
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
m_Chyloth = reader.ReadMobile() as Chyloth;
m_Dragon = reader.ReadMobile() as SkeletalDragon;
if ( m_Chyloth != null )
m_Chyloth.Delete();
}
}
}

View file

@ -0,0 +1,32 @@
using System;
namespace Server.Engines.Quests.Doom
{
public class ChylothShroud : Item
{
[Constructable]
public ChylothShroud() : base( 0x204E )
{
Hue = 0x846;
Layer = Layer.OuterTorso;
}
public ChylothShroud( 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,35 @@
using System;
using Server;
using Server.Items;
namespace Server.Engines.Quests.Doom
{
public class ChylothStaff : BlackStaff
{
public override int LabelNumber{ get{ return 1041111; } } // a magic staff
[Constructable]
public ChylothStaff()
{
Hue = 0x482;
}
public ChylothStaff( 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,35 @@
using System;
namespace Server.Engines.Quests.Doom
{
public class GoldenSkull : Item
{
public override int LabelNumber{ get{ return 1061619; } } // a golden skull
[Constructable]
public GoldenSkull() : base( Utility.Random( 0x1AE2, 3 ) )
{
Weight = 1.0;
Hue = 0x8A5;
LootType = LootType.Blessed;
}
public GoldenSkull( 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,36 @@
using System;
namespace Server.Engines.Quests.Doom
{
public class GrandGrimoire : Item
{
public override int LabelNumber{ get{ return 1060801; } } // The Grand Grimoire
[Constructable]
public GrandGrimoire() : base( 0xEFA )
{
Weight = 1.0;
Hue = 0x835;
Layer = Layer.OneHanded;
LootType = LootType.Blessed;
}
public GrandGrimoire( 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,64 @@
using System;
using Server;
using Server.Items;
using Server.Mobiles;
namespace Server.Engines.Quests.Doom
{
public class SummoningAltar : AbbatoirAddon
{
private BoneDemon m_Daemon;
public BoneDemon Daemon
{
get{ return m_Daemon; }
set
{
m_Daemon = value;
CheckDaemon();
}
}
public void CheckDaemon()
{
if ( m_Daemon == null || !m_Daemon.Alive )
{
m_Daemon = null;
Hue = 0;
}
else
{
Hue = 0x66D;
}
}
[Constructable]
public SummoningAltar()
{
}
public SummoningAltar( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 0 ); // version
writer.Write( (Mobile) m_Daemon );
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
m_Daemon = reader.ReadMobile() as BoneDemon;
CheckDaemon();
}
}
}

Some files were not shown because too many files have changed in this diff Show more