diff --git a/Data/MLQuests.cfg b/Data/MLQuests.cfg
index 694d6ccae..51a7d9fe6 100644
--- a/Data/MLQuests.cfg
+++ b/Data/MLQuests.cfg
@@ -302,3 +302,6 @@ TuitionReimbursement MasterGnosos
# Malas
PointyEars Gorrow Drithen Sledge
+
+# Lost items
+LostAndFound BatteredBucket
diff --git a/Scripts/Engines/MLQuests/Definitions/AGhostOfCovetous.cs b/Scripts/Engines/MLQuests/Definitions/AGhostOfCovetous.cs
index bb107a127..42e557daa 100644
--- a/Scripts/Engines/MLQuests/Definitions/AGhostOfCovetous.cs
+++ b/Scripts/Engines/MLQuests/Definitions/AGhostOfCovetous.cs
@@ -26,7 +26,7 @@ namespace Server.Engines.MLQuests.Definitions
CompletionMessage = 1075291; // (As you try to use the Spirit Bottle, the ghost snatches it out of your hand and smashes it on the rocks) Please, don't be frightened. I need your help!
CompletionNotice = CompletionNoticeShort;
- Objectives.Add( new DeliverObjective( typeof( SpiritBottle ), 1, "Spirit Bottle", typeof( Frederic ), "The Ghost of Frederic Smithson" ) );
+ Objectives.Add( new DeliverObjective( typeof( SpiritBottle ), 1, "Spirit Bottle", typeof( Frederic ) ) );
Rewards.Add( new DummyReward( 1075284 ) ); // Return the filled Spirit Bottle to Griswolt the Master Necromancer to receive a reward.
}
@@ -55,7 +55,7 @@ namespace Server.Engines.MLQuests.Definitions
CompletionMessage = 1075342; // How may I help thee? You have the silk of a dread spider? Of course I can make you a bandage, but what happened to Frederic?
CompletionNotice = CompletionNoticeShort;
- Objectives.Add( new TimedDeliverObjective( TimeSpan.FromSeconds( 600 ), typeof( DreadSpiderSilk ), 1, "Dread Spider Silk", typeof( Leon ), "Leon" ) );
+ Objectives.Add( new TimedDeliverObjective( TimeSpan.FromSeconds( 600 ), typeof( DreadSpiderSilk ), 1, "Dread Spider Silk", typeof( Leon ) ) );
Rewards.Add( new DummyReward( 1075339 ) ); // Hurry! You must get the silk to Leon the Alchemist quickly, or it will crumble and become useless!
}
@@ -84,7 +84,7 @@ namespace Server.Engines.MLQuests.Definitions
CompletionMessage = 1075348; // Sorry, I’m not accepting commissions at the moment. What? You have the bandage I need from Leon? Thank you so much! But why didn’t my son bring this to me himself? . . . Oh, no! You can't be serious! *sag* My Freddie, my son! Thank you for carrying out his last wish. Here -- I made this for my son, to give to him when he became a journeyman. I want you to have it.
CompletionNotice = CompletionNoticeShort;
- Objectives.Add( new DeliverObjective( typeof( AlchemistsBandage ), 1, "Alchemist's Bandage", typeof( Andros ), "Andros" ) );
+ Objectives.Add( new DeliverObjective( typeof( AlchemistsBandage ), 1, "Alchemist's Bandage", typeof( Andros ) ) );
Rewards.Add( new ItemReward( 1075345, typeof( AndrosGratitude ) ) ); // Andros’ Gratitude
}
@@ -150,6 +150,7 @@ namespace Server.Engines.MLQuests.Definitions
}
}
+ [QuesterName( "The Ghost of Frederic Smithson" )]
public class Frederic : BaseCreature
{
public override bool IsInvulnerable { get { return true; } }
diff --git a/Scripts/Engines/MLQuests/Definitions/Bedlam.cs b/Scripts/Engines/MLQuests/Definitions/Bedlam.cs
index a003a5ec0..d297bdbfe 100644
--- a/Scripts/Engines/MLQuests/Definitions/Bedlam.cs
+++ b/Scripts/Engines/MLQuests/Definitions/Bedlam.cs
@@ -83,6 +83,7 @@ namespace Server.Engines.MLQuests.Definitions
#region Mobiles
+ [QuesterName( "Kia (Bedlam)" )]
public class Kia : BaseCreature
{
public override bool IsInvulnerable { get { return true; } }
@@ -126,6 +127,7 @@ namespace Server.Engines.MLQuests.Definitions
}
}
+ [QuesterName( "Emerillo (Bedlam)" )]
public class Emerillo : BaseCreature
{
public override bool IsInvulnerable { get { return true; } }
diff --git a/Scripts/Engines/MLQuests/Definitions/BlightedGrove.cs b/Scripts/Engines/MLQuests/Definitions/BlightedGrove.cs
index f107e58a2..beb0a0707 100644
--- a/Scripts/Engines/MLQuests/Definitions/BlightedGrove.cs
+++ b/Scripts/Engines/MLQuests/Definitions/BlightedGrove.cs
@@ -23,7 +23,7 @@ namespace Server.Engines.MLQuests.Definitions
InProgressMessage = 1074968; // My friend, Iosep, is a weaponsmith in Jhelom. If anyone can help us, he can!
CompletionMessage = 1074991; // Greetings. What have you there? Ah, a sample from a poisonous tree, you say? My friend Jamal sent you? Well, let me see that then, and we'll get to work.
- Objectives.Add( new DeliverObjective( typeof( TaintedTreeSample ), 1, "tainted tree sample", typeof( Iosep ), "Iosep (Jhelom)" ) );
+ Objectives.Add( new DeliverObjective( typeof( TaintedTreeSample ), 1, "tainted tree sample", typeof( Iosep ) ) );
Rewards.Add( new DummyReward( 1074962 ) ); // A step closer to entering Blighted Grove.
}
@@ -126,7 +126,7 @@ namespace Server.Engines.MLQuests.Definitions
InProgressMessage = 1074972; // I'm sure Jamal is eager to get this information. He's probably still hanging around near that big old blighted tree.
CompletionMessage = 1074995; // Heya! You're back. Was Iosep able to help? Let me see what he's sent.
- Objectives.Add( new DeliverObjective( typeof( SealedNotesForJamal ), 1, "sealed note for Jamal", typeof( Jamal ), "Jamal (near Blighted Grove)" ) );
+ Objectives.Add( new DeliverObjective( typeof( SealedNotesForJamal ), 1, "sealed note for Jamal", typeof( Jamal ) ) );
Rewards.Add( new DummyReward( 1074962 ) ); // A step closer to entering Blighted Grove.
}
@@ -175,6 +175,7 @@ namespace Server.Engines.MLQuests.Definitions
#region Mobiles
+ [QuesterName( "Jamal (near Blighted Grove)" )]
public class Jamal : BaseCreature
{
public override bool IsInvulnerable { get { return true; } }
@@ -218,6 +219,7 @@ namespace Server.Engines.MLQuests.Definitions
}
}
+ [QuesterName( "Iosep (Jhelom)" )]
public class Iosep : BaseCreature
{
public override bool IsInvulnerable { get { return true; } }
diff --git a/Scripts/Engines/MLQuests/Definitions/Britannia.cs b/Scripts/Engines/MLQuests/Definitions/Britannia.cs
index 0cdb398a3..41c4b0024 100644
--- a/Scripts/Engines/MLQuests/Definitions/Britannia.cs
+++ b/Scripts/Engines/MLQuests/Definitions/Britannia.cs
@@ -26,7 +26,7 @@ namespace Server.Engines.MLQuests.Definitions
CompletionMessage = 1075326; // What is this you give me? A basin of water?
CompletionNotice = CompletionNoticeShort;
- Objectives.Add( new DeliverObjective( typeof( BasinOfCrystalClearWater ), 1, 1075303, typeof( SkeletonOfSzandor ), "Szandor" ) );
+ Objectives.Add( new DeliverObjective( typeof( BasinOfCrystalClearWater ), 1, "Basin of Crystal Clear Water", typeof( SkeletonOfSzandor ) ) );
Rewards.Add( new DummyReward( 1075323 ) ); // Aurelia's gratitude.
}
@@ -55,9 +55,9 @@ namespace Server.Engines.MLQuests.Definitions
CompletionMessage = 1075332; // Thank goodness! Now we can honor my father for the great man he was while he lived, rather than the horror he became.
CompletionNotice = CompletionNoticeShort;
- Objectives.Add( new DeliverObjective( typeof( BasinOfCrystalClearWater ), 1, 1075303, typeof( Aurelia ), "Aurelia" ) );
+ Objectives.Add( new DeliverObjective( typeof( BasinOfCrystalClearWater ), 1, "Basin of Crystal Clear Water", typeof( Aurelia ) ) );
- Rewards.Add( new ItemReward( 1075304, typeof( MirrorOfPurification ) ) );
+ Rewards.Add( new ItemReward( 1075304, typeof( MirrorOfPurification ) ) ); // Mirror of Purification
}
public override void Generate()
@@ -98,7 +98,7 @@ namespace Server.Engines.MLQuests.Definitions
InProgressMessage = 1074460; // If I knew where my cousin was, I'd make the delivery myself.
CompletionMessage = 1074461; // Oh, hello there. What do you have for me?
- Objectives.Add( new DeliverObjective( typeof( SpecialTreatForDrithen ), 1, "treat for Drithen", typeof( Drithen ), "Drithen (Umbra)" ) );
+ Objectives.Add( new DeliverObjective( typeof( SpecialTreatForDrithen ), 1, "treat for Drithen", typeof( Drithen ) ) );
Rewards.Add( ItemReward.BagOfTreasure );
}
@@ -157,6 +157,7 @@ namespace Server.Engines.MLQuests.Definitions
}
}
+ [QuesterName( "Szandor" )]
public class SkeletonOfSzandor : BaseCreature
{
public override bool IsInvulnerable { get { return true; } }
diff --git a/Scripts/Engines/MLQuests/Definitions/Heartwood.cs b/Scripts/Engines/MLQuests/Definitions/Heartwood.cs
index e6edc4107..76b9a653b 100644
--- a/Scripts/Engines/MLQuests/Definitions/Heartwood.cs
+++ b/Scripts/Engines/MLQuests/Definitions/Heartwood.cs
@@ -1110,7 +1110,7 @@ namespace Server.Engines.MLQuests.Definitions
InProgressMessage = 1073948; // I will be in your debt if you bring me kilts.
CompletionMessage = 1073974; // I say truly - that is a magnificent garment! You have more than earned a reward.
- Objectives.Add( new CollectObjective( 10, typeof( Kilt ), 1015281 ) ); // kilt
+ Objectives.Add( new CollectObjective( 10, typeof( Kilt ), 1025431 ) ); // kilt
Rewards.Add( ItemReward.TailorSatchel );
}
@@ -1128,7 +1128,7 @@ namespace Server.Engines.MLQuests.Definitions
InProgressMessage = 1073949; // I will be in your debt if you bring me fancy shirts.
CompletionMessage = 1073973; // I appreciate your service. Now, see what elven hands can create.
- Objectives.Add( new CollectObjective( 10, typeof( FancyShirt ), 1015272 ) ); // fancy shirt
+ Objectives.Add( new CollectObjective( 10, typeof( FancyShirt ), 1027933 ) ); // fancy shirt
Rewards.Add( ItemReward.TailorSatchel );
}
@@ -1146,7 +1146,7 @@ namespace Server.Engines.MLQuests.Definitions
InProgressMessage = 1073951; // I will be in your debt if you bring me studded bustiers.
CompletionMessage = 1073976; // Truly, it is worse than I feared. Still, I appreciate your efforts on my behalf.
- Objectives.Add( new CollectObjective( 10, typeof( FemaleStuddedChest ), 1015310 ) ); // studded bustier
+ Objectives.Add( new CollectObjective( 10, typeof( FemaleStuddedChest ), 1027180 ) ); // studded bustier
Rewards.Add( ItemReward.TailorSatchel );
}
@@ -1236,7 +1236,7 @@ namespace Server.Engines.MLQuests.Definitions
InProgressMessage = 1073952; // I will be in your debt if you bring me tinker's tools.
CompletionMessage = 1073977; // Now, I shall see what an elf can invent!
- Objectives.Add( new CollectObjective( 10, typeof( TinkerTools ), 1011218 ) ); // tinker's tools
+ Objectives.Add( new CollectObjective( 10, typeof( TinkerTools ), 1027868 ) ); // tinker's tools
Rewards.Add( ItemReward.TinkerSatchel );
}
@@ -1438,7 +1438,7 @@ namespace Server.Engines.MLQuests.Definitions
InProgressMessage = 1073959; // I will be in your debt if you bring me broadswords.
CompletionMessage = 1073978; // Enjoy my thanks for your service.
- Objectives.Add( new CollectObjective( 12, typeof( Broadsword ), 1015055 ) ); // broadsword
+ Objectives.Add( new CollectObjective( 12, typeof( Broadsword ), 1023934 ) ); // broadsword
Rewards.Add( ItemReward.BlacksmithSatchel );
}
@@ -1474,7 +1474,7 @@ namespace Server.Engines.MLQuests.Definitions
InProgressMessage = 1073957; // I will be in your debt if you bring me bascinets.
CompletionMessage = 1073978; // Enjoy my thanks for your service.
- Objectives.Add( new CollectObjective( 15, typeof( Bascinet ), 1015040 ) ); // bascinet
+ Objectives.Add( new CollectObjective( 15, typeof( Bascinet ), 1025132 ) ); // bascinet
Rewards.Add( ItemReward.BlacksmithSatchel );
}
@@ -1821,6 +1821,7 @@ namespace Server.Engines.MLQuests.Definitions
#region Mobiles
+ [QuesterName( "Saril (The Heartwood)" )]
public class Saril : BaseCreature
{
public override bool IsInvulnerable { get { return true; } }
@@ -1881,6 +1882,7 @@ namespace Server.Engines.MLQuests.Definitions
}
}
+ [QuesterName( "Cailla (The Heartwood)" )]
public class Cailla : BaseCreature
{
public override bool IsInvulnerable { get { return true; } }
@@ -1942,6 +1944,7 @@ namespace Server.Engines.MLQuests.Definitions
}
}
+ [QuesterName( "Tamm (The Heartwood)" )]
public class Tamm : BaseCreature
{
public override bool IsInvulnerable { get { return true; } }
@@ -2001,6 +2004,7 @@ namespace Server.Engines.MLQuests.Definitions
}
}
+ [QuesterName( "Landy (The Heartwood)" )]
public class Landy : BaseCreature
{
public override bool IsInvulnerable { get { return true; } }
@@ -2061,6 +2065,7 @@ namespace Server.Engines.MLQuests.Definitions
}
}
+ [QuesterName( "Elder Alejaha (The Heartwood)" )]
public class Alejaha : BaseCreature
{
public override bool IsInvulnerable { get { return true; } }
@@ -2120,6 +2125,7 @@ namespace Server.Engines.MLQuests.Definitions
}
}
+ [QuesterName( "Mielan (The Heartwood)" )]
public class Mielan : BaseCreature
{
public override bool IsInvulnerable { get { return true; } }
@@ -2177,6 +2183,7 @@ namespace Server.Engines.MLQuests.Definitions
}
}
+ [QuesterName( "Ciala (The Heartwood)" )]
public class Ciala : BaseCreature
{
public override bool IsInvulnerable { get { return true; } }
@@ -2238,6 +2245,7 @@ namespace Server.Engines.MLQuests.Definitions
}
}
+ [QuesterName( "Aniel (The Heartwood)" )]
public class Aniel : BaseCreature
{
public override bool IsInvulnerable { get { return true; } }
@@ -2295,6 +2303,7 @@ namespace Server.Engines.MLQuests.Definitions
}
}
+ [QuesterName( "Aulan (The Heartwood)" )]
public class Aulan : BaseCreature
{
public override bool IsInvulnerable { get { return true; } }
@@ -2366,6 +2375,7 @@ namespace Server.Engines.MLQuests.Definitions
}
}
+ [QuesterName( "Brinnae (The Heartwood)" )]
public class Brinnae : BaseCreature
{
public override bool IsInvulnerable { get { return true; } }
@@ -2420,6 +2430,7 @@ namespace Server.Engines.MLQuests.Definitions
}
}
+ [QuesterName( "Elder Caelas (The Heartwood)" )]
public class Caelas : BaseCreature
{
public override bool IsInvulnerable { get { return true; } }
@@ -2477,6 +2488,7 @@ namespace Server.Engines.MLQuests.Definitions
}
}
+ [QuesterName( "Clehin (The Heartwood)" )]
public class Clehin : BaseCreature
{
public override bool IsInvulnerable { get { return true; } }
@@ -2603,6 +2615,7 @@ namespace Server.Engines.MLQuests.Definitions
}
}
+ [QuesterName( "Salaenih (The Heartwood)" )]
public class Salaenih : BaseCreature
{
public override bool IsInvulnerable { get { return true; } }
@@ -2680,6 +2693,7 @@ namespace Server.Engines.MLQuests.Definitions
}
}
+ [QuesterName( "Vilo (The Heartwood)" )]
public class Vilo : BaseCreature
{
public override bool IsInvulnerable { get { return true; } }
@@ -2741,6 +2755,7 @@ namespace Server.Engines.MLQuests.Definitions
}
}
+ [QuesterName( "Tholef (The Heartwood)" )]
public class Tholef : BaseCreature
{
public override bool IsInvulnerable { get { return true; } }
@@ -2804,6 +2819,7 @@ namespace Server.Engines.MLQuests.Definitions
}
}
+ [QuesterName( "Tillanil (The Heartwood)" )]
public class Tillanil : BaseCreature
{
public override bool IsInvulnerable { get { return true; } }
@@ -2860,6 +2876,7 @@ namespace Server.Engines.MLQuests.Definitions
}
}
+ [QuesterName( "Waelian (The Heartwood)" )]
public class Waelian : BaseCreature
{
public override bool IsInvulnerable { get { return true; } }
@@ -2923,6 +2940,7 @@ namespace Server.Engines.MLQuests.Definitions
}
}
+ [QuesterName( "Sleen (The Heartwood)" )]
public class Sleen : BaseCreature
{
public override bool IsInvulnerable { get { return true; } }
@@ -2980,6 +2998,7 @@ namespace Server.Engines.MLQuests.Definitions
}
}
+ [QuesterName( "Unoelil (The Heartwood)" )]
public class Unoelil : BaseCreature
{
public override bool IsInvulnerable { get { return true; } }
@@ -3036,6 +3055,7 @@ namespace Server.Engines.MLQuests.Definitions
}
}
+ [QuesterName( "Anolly (The Heartwood)" )]
public class Anolly : BaseCreature
{
public override bool IsInvulnerable { get { return true; } }
@@ -3084,6 +3104,7 @@ namespace Server.Engines.MLQuests.Definitions
}
}
+ [QuesterName( "Jusae (The Heartwood)" )]
public class Jusae : BaseCreature
{
public override bool IsInvulnerable { get { return true; } }
@@ -3150,6 +3171,7 @@ namespace Server.Engines.MLQuests.Definitions
}
}
+ [QuesterName( "Cillitha (The Heartwood)" )]
public class Cillitha : BaseCreature
{
public override bool IsInvulnerable { get { return true; } }
@@ -3206,6 +3228,7 @@ namespace Server.Engines.MLQuests.Definitions
}
}
+ [QuesterName( "Lohn (The Heartwood)" )]
public class Lohn : BaseCreature
{
public override bool IsInvulnerable { get { return true; } }
@@ -3269,6 +3292,7 @@ namespace Server.Engines.MLQuests.Definitions
}
}
+ [QuesterName( "Olla (The Heartwood)" )]
public class Olla : BaseCreature
{
public override bool IsInvulnerable { get { return true; } }
@@ -3328,6 +3352,7 @@ namespace Server.Engines.MLQuests.Definitions
}
}
+ [QuesterName( "Thallary (The Heartwood)" )]
public class Thallary : BaseCreature
{
public override bool IsInvulnerable { get { return true; } }
@@ -3386,6 +3411,7 @@ namespace Server.Engines.MLQuests.Definitions
}
}
+ [QuesterName( "Ahie (The Heartwood)" )]
public class Ahie : BaseCreature
{
public override bool IsInvulnerable { get { return true; } }
@@ -4195,6 +4221,7 @@ namespace Server.Engines.MLQuests.Definitions
}
}
+ [QuesterName( "Nillaen (The Heartwood)" )]
public class LorekeeperNillaen : BaseCreature
{
public override bool IsInvulnerable { get { return true; } }
@@ -4245,6 +4272,7 @@ namespace Server.Engines.MLQuests.Definitions
}
}
+ [QuesterName( "Ryal (The Heartwood)" )]
public class LorekeeperRyal : BaseCreature
{
public override bool IsInvulnerable { get { return true; } }
@@ -4303,6 +4331,7 @@ namespace Server.Engines.MLQuests.Definitions
}
}
+ [QuesterName( "Braen (The Heartwood)" )]
public class Braen : BaseCreature
{
public override bool IsInvulnerable { get { return true; } }
@@ -4356,6 +4385,7 @@ namespace Server.Engines.MLQuests.Definitions
}
}
+ [QuesterName( "Elder Acob (The Heartwood)" )]
public class ElderAcob : BaseCreature
{
public override bool IsInvulnerable { get { return true; } }
diff --git a/Scripts/Engines/MLQuests/Definitions/Heritage.cs b/Scripts/Engines/MLQuests/Definitions/Heritage.cs
index 41df7df0d..772e3eb83 100644
--- a/Scripts/Engines/MLQuests/Definitions/Heritage.cs
+++ b/Scripts/Engines/MLQuests/Definitions/Heritage.cs
@@ -243,6 +243,7 @@ namespace Server.Engines.MLQuests.Definitions
#region Human To Elf Mobiles
+ [QuesterName( "Maul" )]
public class MaulTheBear : GrizzlyBear
{
public override bool IsInvulnerable { get { return true; } }
@@ -569,7 +570,7 @@ namespace Server.Engines.MLQuests.Definitions
CompletionMessage = 1074523; // Hey, if you have cargo for me, you can start unloading over here.
CompletionNotice = CompletionNoticeShort;
- Objectives.Add( new TimedDeliverObjective( TimeSpan.FromHours( 1 ), typeof( CrateForSledge ), 5, "Crates for Sledge", typeof( Sledge ), "Sledge (Buc's Den)" ) );
+ Objectives.Add( new TimedDeliverObjective( TimeSpan.FromHours( 1 ), typeof( CrateForSledge ), 5, "Crates for Sledge", typeof( Sledge ) ) );
Rewards.Add( new DummyReward( 1074875 ) ); // Another step closer to becoming human.
}
@@ -647,6 +648,7 @@ namespace Server.Engines.MLQuests.Definitions
#region Elf To Human Mobiles
+ [QuesterName( "Sledge (Buc's Den)" )]
public class Sledge : BaseCreature
{
public override bool IsInvulnerable { get { return true; } }
@@ -697,6 +699,7 @@ namespace Server.Engines.MLQuests.Definitions
}
}
+ [QuesterName( "Patricus (Vesper)" )]
public class Patricus : BaseCreature
{
public override bool IsInvulnerable { get { return true; } }
@@ -738,6 +741,7 @@ namespace Server.Engines.MLQuests.Definitions
}
}
+ [QuesterName( "Belulah (Nujel'm)" )] // On OSI it's "Belulah (Nu'Jelm)" (incorrect spelling)
public class Belulah : BaseCreature
{
public override bool IsInvulnerable { get { return true; } }
diff --git a/Scripts/Engines/MLQuests/Definitions/HonestBeggar.cs b/Scripts/Engines/MLQuests/Definitions/HonestBeggar.cs
index 5c8fa7596..ec13653b4 100644
--- a/Scripts/Engines/MLQuests/Definitions/HonestBeggar.cs
+++ b/Scripts/Engines/MLQuests/Definitions/HonestBeggar.cs
@@ -26,7 +26,7 @@ namespace Server.Engines.MLQuests.Definitions
CompletionMessage = 1075397; // Didst thou find my ring? I thank thee very much! It is an old ring, and a gift from my husband. I was most distraught when I realized it was missing.
CompletionNotice = CompletionNoticeShort;
- Objectives.Add( new DeliverObjective( typeof( ReginasRing ), 1, "Regina's Ring", typeof( Regina ), "Regina" ) );
+ Objectives.Add( new DeliverObjective( typeof( ReginasRing ), 1, "Regina's Ring", typeof( Regina ) ) );
Rewards.Add( new DummyReward( 1075394 ) ); // Find the ring’s owner.
}
@@ -55,7 +55,7 @@ namespace Server.Engines.MLQuests.Definitions
CompletionMessage = 1075403; // What? For me? Let me see . . . these sapphire earrings are for you, it says. Oh, she wants to offer me a job! This is the most wonderful thing that ever happened to me!
CompletionNotice = CompletionNoticeShort;
- Objectives.Add( new DeliverObjective( typeof( ReginasLetter ), 1, "Regina's Letter", typeof( Evan ), "Evan" ) );
+ Objectives.Add( new DeliverObjective( typeof( ReginasLetter ), 1, "Regina's Letter", typeof( Evan ) ) );
Rewards.Add( new ItemReward( 1075400, typeof( TransparentHeart ) ) ); // Transparent Heart
}
diff --git a/Scripts/Engines/MLQuests/Definitions/Ilshenar.cs b/Scripts/Engines/MLQuests/Definitions/Ilshenar.cs
index 4729475fd..441b2028e 100644
--- a/Scripts/Engines/MLQuests/Definitions/Ilshenar.cs
+++ b/Scripts/Engines/MLQuests/Definitions/Ilshenar.cs
@@ -232,6 +232,7 @@ namespace Server.Engines.MLQuests.Definitions
}
}
+ [QuesterName( "Jelrice (Ilshenar)" )]
public class Jelrice : BaseCreature
{
public override bool IsInvulnerable { get { return true; } }
@@ -281,6 +282,7 @@ namespace Server.Engines.MLQuests.Definitions
}
}
+ [QuesterName( "Yorus (Ilshenar)" )]
public class Yorus : BaseCreature
{
public override bool IsInvulnerable { get { return true; } }
diff --git a/Scripts/Engines/MLQuests/Definitions/LostItems.cs b/Scripts/Engines/MLQuests/Definitions/LostItems.cs
new file mode 100644
index 000000000..34b5b7d17
--- /dev/null
+++ b/Scripts/Engines/MLQuests/Definitions/LostItems.cs
@@ -0,0 +1,70 @@
+using System;
+using Server;
+using Server.Engines.MLQuests;
+using Server.Engines.MLQuests.Items;
+using Server.Engines.MLQuests.Objectives;
+using Server.Engines.MLQuests.Rewards;
+
+namespace Server.Engines.MLQuests.Definitions
+{
+ // TODO: Assassination Contract, Evidence, Lost in Transit, Last Words
+
+ #region Quests
+
+ public class LostAndFound : MLQuest
+ {
+ public LostAndFound()
+ {
+ Activated = true;
+ Title = 1072370; // Lost and Found
+ Description = 1072589; // The battered, old bucket is inscribed with barely legible writing that indicates it belongs to someone named "Dallid". Maybe they'd pay for its return?
+ RefusalMessage = 1072590; // You're right, who cares if Dallid might pay for his battered old bucket back. This way you can carry it around with you!
+ InProgressMessage = 1072591; // Whoever this "Dallid" might be, he's probably looking for his bucket.
+ CompletionMessage = 1074580; // Is that my bucket? I had to ditch my favorite bucket when a group of ratmen jumped me!
+
+ Objectives.Add( new TimedDeliverObjective( TimeSpan.FromSeconds( 600 ), typeof( BatteredBucket ), 1, "battered bucket", typeof( Dallid ), false ) );
+
+ Rewards.Add( ItemReward.BagOfTrinkets );
+ }
+ }
+
+ #endregion
+
+ #region Items
+
+ public class BatteredBucket : TransientQuestGiverItem
+ {
+ // Original label, doesn't fit the expiration message well
+ //public override int LabelNumber { get { return 1073129; } } // A battered bucket.
+
+ public override string DefaultName { get { return "battered bucket"; } }
+
+ [Constructable]
+ public BatteredBucket()
+ : base( 0x2004, TimeSpan.FromMinutes( 10 ) )
+ {
+ LootType = LootType.Blessed;
+ }
+
+ public BatteredBucket( 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();
+ }
+ }
+
+ #endregion
+}
diff --git a/Scripts/Engines/MLQuests/Definitions/Malas.cs b/Scripts/Engines/MLQuests/Definitions/Malas.cs
index 7b41775c8..443769d04 100644
--- a/Scripts/Engines/MLQuests/Definitions/Malas.cs
+++ b/Scripts/Engines/MLQuests/Definitions/Malas.cs
@@ -23,7 +23,7 @@ namespace Server.Engines.MLQuests.Definitions
InProgressMessage = 1074643; // I can't pay a bounty if you don't bring bag the ears.
CompletionMessage = 1074644; // Here to collect on a bounty?
- Objectives.Add( new CollectObjective( 20, typeof( SeveredElfEars ), "severed elf ears" ) );
+ Objectives.Add( new CollectObjective( 20, typeof( SeveredElfEars ), 1032590 ) ); // severed elf ears
Rewards.Add( ItemReward.BagOfTrinkets );
}
@@ -40,6 +40,7 @@ namespace Server.Engines.MLQuests.Definitions
#region Mobiles
+ [QuesterName( "Drithen (Umbra)" )]
public class Drithen : BaseCreature
{
public override bool IsInvulnerable { get { return true; } }
diff --git a/Scripts/Engines/MLQuests/Definitions/MistakenIdentity.cs b/Scripts/Engines/MLQuests/Definitions/MistakenIdentity.cs
index 96658c9a0..a83a32559 100644
--- a/Scripts/Engines/MLQuests/Definitions/MistakenIdentity.cs
+++ b/Scripts/Engines/MLQuests/Definitions/MistakenIdentity.cs
@@ -27,7 +27,7 @@ namespace Server.Engines.MLQuests.Definitions
CompletionMessage = 1074607; // Oh blast! Not another of those forms. I'm so sick of this endless paperwork.
CompletionNotice = CompletionNoticeShort;
- Objectives.Add( new DeliverObjective( typeof( TuitionReimbursementForm ), 1, "Tuition Reimbursement Form", typeof( Gorrow ), "Gorrow (Luna)" ) );
+ Objectives.Add( new DeliverObjective( typeof( TuitionReimbursementForm ), 1, "Tuition Reimbursement Form", typeof( Gorrow ) ) );
Rewards.Add( new DummyReward( 1074634 ) ); // Tuition Reimbursement
}
@@ -85,7 +85,7 @@ namespace Server.Engines.MLQuests.Definitions
CompletionMessage = 1074622; // What? Hrmph. Gorrow signed your form did he? Let me see that. *squint*
CompletionNotice = CompletionNoticeShort;
- Objectives.Add( new DeliverObjective( typeof( SignedTuitionReimbursementForm ), 1, "Signed Tuition Reimbursement Form", typeof( Aernya ), "Aernya (Umbra)" ) );
+ Objectives.Add( new DeliverObjective( typeof( SignedTuitionReimbursementForm ), 1, "Signed Tuition Reimbursement Form", typeof( Aernya ) ) );
Rewards.Add( new DummyReward( 1074634 ) ); // Tuition Reimbursement
}
@@ -106,7 +106,7 @@ namespace Server.Engines.MLQuests.Definitions
CompletionMessage = 1074628; // Made it through did you? Did you happen to see Red Death out there? Big horse, skeletal ... burning eyes? No? What's this? Forms? FORMS? I'm up to my eyebrows in ravenous out-of-control undead and you want a signature?
CompletionNotice = CompletionNoticeShort;
- Objectives.Add( new DeliverObjective( typeof( SignedTuitionReimbursementForm ), 1, "Signed Tuition Reimbursement Form", typeof( MasterGnosos ), "Master Gnosos (Bedlam)" ) );
+ Objectives.Add( new DeliverObjective( typeof( SignedTuitionReimbursementForm ), 1, "Signed Tuition Reimbursement Form", typeof( MasterGnosos ) ) );
Rewards.Add( new DummyReward( 1074634 ) ); // Tuition Reimbursement
}
@@ -170,7 +170,7 @@ namespace Server.Engines.MLQuests.Definitions
CompletionMessage = 1074638; // *disinterested stare* What? Oh, you've gotten your form filled in. How nice. *glare* And I'd hoped you'd drop this charade before I was forced to rub your nose in it. *nasty smile* You're not even a student and as such, you're not eligible for a refund -- you've never paid tuition. For your services, Master Gnosos has recommended you receive pay. So here. Now go away.
CompletionNotice = CompletionNoticeShort;
- Objectives.Add( new DeliverObjective( typeof( CompletedTuitionReimbursementForm ), 1, "Completed Tuition Reimbursement Form", typeof( Aernya ), "Aernya (Umbra)" ) );
+ Objectives.Add( new DeliverObjective( typeof( CompletedTuitionReimbursementForm ), 1, "Completed Tuition Reimbursement Form", typeof( Aernya ) ) );
Rewards.Add( ItemReward.Strongbox );
}
@@ -180,6 +180,7 @@ namespace Server.Engines.MLQuests.Definitions
#region Mobiles
+ [QuesterName( "Aernya (Umbra)" )]
public class Aernya : BaseCreature
{
public override bool IsInvulnerable { get { return true; } }
@@ -225,6 +226,7 @@ namespace Server.Engines.MLQuests.Definitions
}
}
+ [QuesterName( "Gorrow (Luna)" )]
public class Gorrow : BaseCreature
{
public override bool IsInvulnerable { get { return true; } }
@@ -277,6 +279,7 @@ namespace Server.Engines.MLQuests.Definitions
}
}
+ [QuesterName( "Master Gnosos (Bedlam)" )]
public class MasterGnosos : BaseCreature
{
public override bool IsInvulnerable { get { return true; } }
diff --git a/Scripts/Engines/MLQuests/Definitions/NewHavenTraining.cs b/Scripts/Engines/MLQuests/Definitions/NewHavenTraining.cs
index 1ca419915..caf4c648e 100644
--- a/Scripts/Engines/MLQuests/Definitions/NewHavenTraining.cs
+++ b/Scripts/Engines/MLQuests/Definitions/NewHavenTraining.cs
@@ -123,7 +123,7 @@ namespace Server.Engines.MLQuests.Definitions
InProgressMessage = 1075515; // Come On! Whats that... a bucket? We need ten bucklers... not spitoons.
CompletionMessage = 1075516; // Thanks for the help. Here's something for ya to remember me by.
- Objectives.Add( new CollectObjective( 10, typeof( Buckler ), 1015044 ) ); // buckler
+ Objectives.Add( new CollectObjective( 10, typeof( Buckler ), 1027027 ) ); // buckler
Rewards.Add( new ItemReward( 1074282, typeof( GervisSatchel ) ) ); // Craftsmans's Satchel
}
@@ -148,7 +148,7 @@ namespace Server.Engines.MLQuests.Definitions
InProgressMessage = 1075532; // Hmmm… we need some more Ore. Try finding a mountain or cave, and give it a whack.
CompletionMessage = 1075533; // I see you found a good vien! Great! This will help get this order out on time. Good work!
- Objectives.Add( new CollectObjective( 5, typeof( IronOre ), 1042853 ) ); // iron ore
+ Objectives.Add( new InternalObjective() );
Rewards.Add( new ItemReward( 1074282, typeof( MuggSatchel ) ) ); // Craftsmans's Satchel
}
@@ -159,6 +159,20 @@ namespace Server.Engines.MLQuests.Definitions
PutSpawner( new Spawner( 1, 5, 10, 0, 0, "Mugg" ), new Point3D( 3507, 2747, 0 ), Map.Trammel );
}
+
+ private class InternalObjective : CollectObjective
+ {
+ // Any type of ore is allowed
+ public InternalObjective()
+ : base( 5, typeof( BaseOre ), 1026585 ) // ore
+ {
+ }
+
+ public override bool CheckItem( Item item )
+ {
+ return ( item.ItemID == 6585 ); // Only large pieces count
+ }
+ }
}
public class ComfortableSeating : MLQuest
@@ -173,7 +187,7 @@ namespace Server.Engines.MLQuests.Definitions
InProgressMessage = 1075509; // Is all going well? I look forward to the simple comforts in my very own home.
CompletionMessage = 1074720; // This is perfect!
- Objectives.Add( new CollectObjective( 1, typeof( BambooChair ), 1044300 ) ); // straw chair
+ Objectives.Add( new CollectObjective( 1, typeof( BambooChair ), "straw chair" ) );
Rewards.Add( new ItemReward( 1074282, typeof( LowelSatchel ) ) ); // Craftsmans's Satchel
}
@@ -223,7 +237,7 @@ namespace Server.Engines.MLQuests.Definitions
InProgressMessage = 1072271; // You're not quite done yet. Get back to work!
CompletionMessage = 1075536; // Wonderful! Tick tock, tick tock, soon all shall be well with grandfather's clock!
- Objectives.Add( new CollectObjective( 5, typeof( ClockParts ), 1011205 ) ); // clock parts
+ Objectives.Add( new CollectObjective( 5, typeof( ClockParts ), 1024175 ) ); // clock parts
Rewards.Add( new ItemReward( 1074282, typeof( NibbetSatchel ) ) ); // Craftsmans's Satchel
}
@@ -273,7 +287,7 @@ namespace Server.Engines.MLQuests.Definitions
InProgressMessage = 1075490; // Just remember you need to use your mortar and pestle while you have empty bottles and some black pearl. Refresh potions are what I need.
CompletionMessage = 1075491; // *glug* *glug* Ahh... Yes! Yes! That feels great! Those lizardmen will never know what hit 'em! Here, take this, I can get more from the lizards.
- Objectives.Add( new CollectObjective( 10, typeof( RefreshPotion ), 1048029 ) ); // refresh potion
+ Objectives.Add( new CollectObjective( 10, typeof( RefreshPotion ), "refresh potions" ) );
Rewards.Add( new ItemReward( 1074282, typeof( SadrahSatchel ) ) ); // Craftsmans's Satchel
}
@@ -506,6 +520,7 @@ namespace Server.Engines.MLQuests.Definitions
}
}
+ //[QuesterName( "Clarisse" )] // On OSI the gumps refer to her as this, different from actual name
public class Clairesse : BaseCreature
{
public override bool IsInvulnerable { get { return true; } }
diff --git a/Scripts/Engines/MLQuests/Definitions/Sanctuary.cs b/Scripts/Engines/MLQuests/Definitions/Sanctuary.cs
index db645ba9d..746bfd2a4 100644
--- a/Scripts/Engines/MLQuests/Definitions/Sanctuary.cs
+++ b/Scripts/Engines/MLQuests/Definitions/Sanctuary.cs
@@ -140,7 +140,7 @@ namespace Server.Engines.MLQuests.Definitions
InProgressMessage = 1074064; // Hurry up! I don't have all day to wait for you to bring what I desire!
CompletionMessage = 1074065; // These human made goods are laughable! It offends so -- I must show you what elven skill is capable of!
- Objectives.Add( new CollectObjective( 12, typeof( Broadsword ), 1015055 ) ); // broadsword
+ Objectives.Add( new CollectObjective( 12, typeof( Broadsword ), 1023934 ) ); // broadsword
Rewards.Add( ItemReward.BlacksmithSatchel );
}
@@ -230,7 +230,7 @@ namespace Server.Engines.MLQuests.Definitions
InProgressMessage = 1074064; // Hurry up! I don't have all day to wait for you to bring what I desire!
CompletionMessage = 1074065; // These human made goods are laughable! It offends so -- I must show you what elven skill is capable of!
- Objectives.Add( new CollectObjective( 10, typeof( TinkerTools ), 1011218 ) ); // tinker's tools
+ Objectives.Add( new CollectObjective( 10, typeof( TinkerTools ), 1027868 ) ); // tinker's tools
Rewards.Add( ItemReward.TinkerSatchel );
}
@@ -264,7 +264,7 @@ namespace Server.Engines.MLQuests.Definitions
InProgressMessage = 1074064; // Hurry up! I don't have all day to wait for you to bring what I desire!
CompletionMessage = 1074065; // These human made goods are laughable! It offends so -- I must show you what elven skill is capable of!
- Objectives.Add( new CollectObjective( 10, typeof( Kilt ), 1015281 ) ); // kilt
+ Objectives.Add( new CollectObjective( 10, typeof( Kilt ), 1025431 ) ); // kilt
Rewards.Add( ItemReward.TailorSatchel );
}
@@ -282,7 +282,7 @@ namespace Server.Engines.MLQuests.Definitions
InProgressMessage = 1074064; // Hurry up! I don't have all day to wait for you to bring what I desire!
CompletionMessage = 1074065; // These human made goods are laughable! It offends so -- I must show you what elven skill is capable of!
- Objectives.Add( new CollectObjective( 10, typeof( FancyShirt ), 1015272 ) ); // fancy shirt
+ Objectives.Add( new CollectObjective( 10, typeof( FancyShirt ), 1027933 ) ); // fancy shirt
Rewards.Add( ItemReward.TailorSatchel );
}
@@ -300,7 +300,7 @@ namespace Server.Engines.MLQuests.Definitions
InProgressMessage = 1074064; // Hurry up! I don't have all day to wait for you to bring what I desire!
CompletionMessage = 1074065; // These human made goods are laughable! It offends so -- I must show you what elven skill is capable of!
- Objectives.Add( new CollectObjective( 10, typeof( FemaleStuddedChest ), 1015310 ) ); // studded bustier
+ Objectives.Add( new CollectObjective( 10, typeof( FemaleStuddedChest ), 1027180 ) ); // studded bustier
Rewards.Add( ItemReward.TailorSatchel );
}
@@ -623,7 +623,7 @@ namespace Server.Engines.MLQuests.Definitions
CompletionMessage = 1074579; // Yes, can I help you?
CompletionNotice = CompletionNoticeShort;
- Objectives.Add( new DeliverObjective( typeof( APersonalLetterAddressedToAhie ), 1, "letter", typeof( Ahie ), "Ahie (The Heartwood)" ) );
+ Objectives.Add( new DeliverObjective( typeof( APersonalLetterAddressedToAhie ), 1, "letter", typeof( Ahie ) ) );
Rewards.Add( ItemReward.BagOfTrinkets );
}
@@ -639,7 +639,7 @@ namespace Server.Engines.MLQuests.Definitions
RefusalMessage = 1073580; // I hope you'll reconsider. Until then, farwell.
InProgressMessage = 1073592; // The Brigands still plague us. Have you killed 20 of their number?
- Objectives.Add( new KillObjective( 20, new Type[] { typeof( Brigand ) }, "common brigands" ) );
+ Objectives.Add( new KillObjective( 20, new Type[] { typeof( Brigand ) }, 1074894 ) ); // Common brigands
Rewards.Add( ItemReward.BagOfTreasure );
}
@@ -649,6 +649,7 @@ namespace Server.Engines.MLQuests.Definitions
#region Mobiles
+ [QuesterName( "Beotham (Sanctuary)" )]
public class Beotham : BaseCreature
{
public override bool IsInvulnerable { get { return true; } }
@@ -711,6 +712,7 @@ namespace Server.Engines.MLQuests.Definitions
}
}
+ [QuesterName( "Danoel (Sanctuary)" )]
public class Danoel : BaseCreature
{
// TODO: Add quests: Spring Cleaning
@@ -769,6 +771,7 @@ namespace Server.Engines.MLQuests.Definitions
}
}
+ [QuesterName( "Tallinin (Sanctuary)" )]
public class Tallinin : BaseCreature
{
public override bool IsInvulnerable { get { return true; } }
@@ -825,6 +828,7 @@ namespace Server.Engines.MLQuests.Definitions
}
}
+ [QuesterName( "Tiana (Sanctuary)" )]
public class Tiana : BaseCreature
{
public override bool IsInvulnerable { get { return true; } }
@@ -892,6 +896,7 @@ namespace Server.Engines.MLQuests.Definitions
}
}
+ [QuesterName( "Oolua (Sanctuary)" )]
public class LorekeeperOolua : BaseCreature
{
// TODO: Add quest Dreadhorn
@@ -949,6 +954,7 @@ namespace Server.Engines.MLQuests.Definitions
}
}
+ [QuesterName( "Rollarn (Sanctuary)" )]
public class LorekeeperRollarn : BaseCreature
{
public override bool IsInvulnerable { get { return true; } }
@@ -1012,6 +1018,7 @@ namespace Server.Engines.MLQuests.Definitions
}
}
+ [QuesterName( "Dallid (Sanctuary)" )]
public class Dallid : BaseCreature
{
public override bool IsInvulnerable { get { return true; } }
@@ -1070,6 +1077,7 @@ namespace Server.Engines.MLQuests.Definitions
}
}
+ [QuesterName( "Canir (Sanctuary)" )]
public class Canir : BaseCreature
{
public override bool IsInvulnerable { get { return true; } }
@@ -1172,6 +1180,7 @@ namespace Server.Engines.MLQuests.Definitions
}
}
+ [QuesterName( "Elder Onallan (Sanctuary)" )]
public class ElderOnallan : BaseCreature
{
public override bool IsInvulnerable { get { return true; } }
diff --git a/Scripts/Engines/MLQuests/Definitions/Spellweaving.cs b/Scripts/Engines/MLQuests/Definitions/Spellweaving.cs
index 43eb0bb3a..028996f47 100644
--- a/Scripts/Engines/MLQuests/Definitions/Spellweaving.cs
+++ b/Scripts/Engines/MLQuests/Definitions/Spellweaving.cs
@@ -328,7 +328,7 @@ namespace Server.Engines.MLQuests.Definitions
InProgressMessage = 1074315; // Arielle wanders quite a bit, so I'm not sure exactly where to find her. I'm sure she's going to love your gift.
CompletionMessage = 1074319; // *giggle* Oooh! For me?
- Objectives.Add( new DeliverObjective( typeof( GiftForArielle ), 1, "gift for Arielle", typeof( Arielle ), "Arielle" ) );
+ Objectives.Add( new DeliverObjective( typeof( GiftForArielle ), 1, "gift for Arielle", typeof( Arielle ) ) );
Rewards.Add( new DummyReward( 1074874 ) ); // The opportunity to prove yourself worthy of learning to Summon Fey. (Sufficient spellweaving skill is required to cast the spell)
}
@@ -445,6 +445,7 @@ namespace Server.Engines.MLQuests.Definitions
#region Mobiles
+ [QuesterName( "Aeluva (The Heartwood)" )]
public class Aeluva : BaseCreature
{
public override bool IsInvulnerable { get { return true; } }
@@ -503,6 +504,7 @@ namespace Server.Engines.MLQuests.Definitions
}
}
+ [QuesterName( "Koole (Sanctuary)" )]
public class Koole : BaseCreature
{
public override bool IsInvulnerable { get { return true; } }
@@ -568,6 +570,7 @@ namespace Server.Engines.MLQuests.Definitions
}
}
+ [QuesterName( "Synaeva (The Heartwood)" )]
public class Synaeva : BaseCreature
{
public override bool IsInvulnerable { get { return true; } }
@@ -627,6 +630,7 @@ namespace Server.Engines.MLQuests.Definitions
}
}
+ [QuesterName( "Elder Brae (Sanctuary)" )]
public class ElderBrae : BaseCreature
{
public override bool IsInvulnerable { get { return true; } }
diff --git a/Scripts/Engines/MLQuests/Definitions/TheAncientWorld.cs b/Scripts/Engines/MLQuests/Definitions/TheAncientWorld.cs
index ee6b34dc3..05db9075d 100644
--- a/Scripts/Engines/MLQuests/Definitions/TheAncientWorld.cs
+++ b/Scripts/Engines/MLQuests/Definitions/TheAncientWorld.cs
@@ -53,7 +53,7 @@ namespace Server.Engines.MLQuests.Definitions
InProgressMessage = 1074547; // Braen is nearby, run and speak with him.
CompletionMessage = 1074549; // Yes? What do you want? I'm very busy.
- Objectives.Add( new DeliverObjective( typeof( FragmentOfAMapDelivery ), 1, "fragment of a map", typeof( Braen ), "Braen (The Heartwood)" ) );
+ Objectives.Add( new DeliverObjective( typeof( FragmentOfAMapDelivery ), 1, "fragment of a map", typeof( Braen ) ) );
Rewards.Add( new DummyReward( 1074876 ) ); // Knowledge of the legendary minotaur.
}
@@ -102,6 +102,7 @@ namespace Server.Engines.MLQuests.Definitions
#region Mobiles
+ [QuesterName( "Broolol (The Heartwood)" )]
public class LorekeeperBroolol : BaseCreature
{
public override bool IsInvulnerable { get { return true; } }
diff --git a/Scripts/Engines/MLQuests/Definitions/UnfadingMemories.cs b/Scripts/Engines/MLQuests/Definitions/UnfadingMemories.cs
index d5afe6616..d14692868 100644
--- a/Scripts/Engines/MLQuests/Definitions/UnfadingMemories.cs
+++ b/Scripts/Engines/MLQuests/Definitions/UnfadingMemories.cs
@@ -55,7 +55,7 @@ namespace Server.Engines.MLQuests.Definitions
CompletionMessage = 1075372; // I’m sorry, I’m getting ready to be married. I don’t have time to . . . what’s that you say?
CompletionNotice = CompletionNoticeShort;
- Objectives.Add( new DeliverObjective( typeof( PortraitOfTheBride ), 1, "Portrait of the Bride", typeof( Thalia ), "Thalia (Nujel'm)" ) ); // OSI's description is "Bride"
+ Objectives.Add( new DeliverObjective( typeof( PortraitOfTheBride ), 1, "Portrait of the Bride", typeof( Thalia ) ) );
Rewards.Add( new DummyReward( 1075369 ) ); // The Artist’s gratitude.
}
@@ -76,7 +76,7 @@ namespace Server.Engines.MLQuests.Definitions
CompletionMessage = 1075378; // She said what? She thinks what of me? I . . . I can’t believe it! All this time, I never knew how she truly felt. Thank you, my friend. I believe now I will be able to paint once again. Here, take this bleach. I was going to use it to destroy all of my works. Perhaps you can find a better use for it now.
CompletionNotice = CompletionNoticeShort;
- Objectives.Add( new DeliverObjective( typeof( BridesLetter ), 1, "Bride's Letter", typeof( Emilio ), "Emilio (Britain)" ) ); // OSI's description is "Artist"
+ Objectives.Add( new DeliverObjective( typeof( BridesLetter ), 1, "Bride's Letter", typeof( Emilio ) ) );
Rewards.Add( new ItemReward( 1075375, typeof( Bleach ) ) ); // Bleach
}
@@ -94,6 +94,7 @@ namespace Server.Engines.MLQuests.Definitions
#region Mobiles
+ [QuesterName( "Emilio (Britain)" )] // OSI's description is "Artist", not very helpful
public class Emilio : BaseCreature
{
public override bool IsInvulnerable { get { return true; } }
@@ -141,6 +142,7 @@ namespace Server.Engines.MLQuests.Definitions
}
}
+ [QuesterName( "Thalia (Nujel'm)" )] // OSI's description is "Bride", not very helpful
public class Thalia : BaseCreature
{
public override bool IsInvulnerable { get { return true; } }
diff --git a/Scripts/Engines/MLQuests/Definitions/WarriorsOfTheGemKeeper.cs b/Scripts/Engines/MLQuests/Definitions/WarriorsOfTheGemKeeper.cs
index 2b9fb229f..b059fa0e7 100644
--- a/Scripts/Engines/MLQuests/Definitions/WarriorsOfTheGemKeeper.cs
+++ b/Scripts/Engines/MLQuests/Definitions/WarriorsOfTheGemKeeper.cs
@@ -43,7 +43,7 @@ namespace Server.Engines.MLQuests.Definitions
InProgressMessage = 1074548; // Canir is nearby, run and speak with her.
CompletionMessage = 1074549; // Yes? What do you want? I'm very busy.
- Objectives.Add( new DeliverObjective( typeof( FragmentOfAMapDelivery ), 1, "fragment of a map", typeof( Canir ), "Canir (Sanctuary)" ) );
+ Objectives.Add( new DeliverObjective( typeof( FragmentOfAMapDelivery ), 1, "fragment of a map", typeof( Canir ) ) );
Rewards.Add( new DummyReward( 1074876 ) ); // Knowledge of the legendary minotaur.
}
diff --git a/Scripts/Engines/MLQuests/Gumps/QuestOfferGump.cs b/Scripts/Engines/MLQuests/Gumps/QuestOfferGump.cs
index 0f256d93c..8da954378 100644
--- a/Scripts/Engines/MLQuests/Gumps/QuestOfferGump.cs
+++ b/Scripts/Engines/MLQuests/Gumps/QuestOfferGump.cs
@@ -10,9 +10,9 @@ namespace Server.Engines.MLQuests.Gumps
public class QuestOfferGump : BaseQuestGump
{
private MLQuest m_Quest;
- private BaseCreature m_Quester;
+ private IQuestGiver m_Quester;
- public QuestOfferGump( MLQuest quest, BaseCreature quester, PlayerMobile pm )
+ public QuestOfferGump( MLQuest quest, IQuestGiver quester, PlayerMobile pm )
: base( 1049010 ) // Quest Offer
{
m_Quest = quest;
diff --git a/Scripts/Engines/MLQuests/IQuestGiver.cs b/Scripts/Engines/MLQuests/IQuestGiver.cs
new file mode 100644
index 000000000..cffa4901b
--- /dev/null
+++ b/Scripts/Engines/MLQuests/IQuestGiver.cs
@@ -0,0 +1,16 @@
+using System;
+using System.Collections.Generic;
+using Server;
+
+namespace Server.Engines.MLQuests
+{
+ public interface IQuestGiver
+ {
+ List MLQuests { get; }
+
+ Serial Serial { get; }
+ bool Deleted { get; }
+
+ Type GetType();
+ }
+}
diff --git a/Scripts/Engines/MLQuests/Items/QuestGiverItem.cs b/Scripts/Engines/MLQuests/Items/QuestGiverItem.cs
new file mode 100644
index 000000000..e562e713c
--- /dev/null
+++ b/Scripts/Engines/MLQuests/Items/QuestGiverItem.cs
@@ -0,0 +1,167 @@
+using System;
+using System.Collections.Generic;
+using Server;
+using Server.Items;
+using Server.Mobiles;
+using Server.Network;
+
+namespace Server.Engines.MLQuests.Items
+{
+ public abstract class QuestGiverItem : Item, IQuestGiver
+ {
+ private List m_MLQuests;
+
+ public List MLQuests
+ {
+ get
+ {
+ if ( m_MLQuests == null )
+ {
+ m_MLQuests = MLQuestSystem.FindQuestList( GetType() );
+
+ if ( m_MLQuests == null )
+ m_MLQuests = MLQuestSystem.EmptyList;
+ }
+
+ return m_MLQuests;
+ }
+ }
+
+ public bool CanGiveMLQuest { get { return ( MLQuests.Count != 0 ); } }
+
+ public QuestGiverItem( int itemId )
+ : base( itemId )
+ {
+ }
+
+ public override bool Nontransferable { get { return true; } }
+
+ public override void AddNameProperties( ObjectPropertyList list )
+ {
+ base.AddNameProperties( list );
+
+ AddQuestItemProperty( list );
+
+ if ( CanGiveMLQuest )
+ list.Add( 1072269 ); // Quest Giver
+ }
+
+ public override void OnDoubleClick( Mobile from )
+ {
+ if ( !from.InRange( GetWorldLocation(), 2 ) )
+ from.LocalOverheadMessage( MessageType.Regular, 0x3B2, 1019045 ); // I can't reach that.
+ else if ( !IsChildOf( from.Backpack ) )
+ from.SendLocalizedMessage( 1042593 ); // That is not in your backpack.
+ else if ( MLQuestSystem.Enabled && CanGiveMLQuest && from is PlayerMobile )
+ MLQuestSystem.OnDoubleClick( this, (PlayerMobile)from );
+ }
+
+ public override void OnAfterDelete()
+ {
+ base.OnAfterDelete();
+
+ if ( MLQuestSystem.Enabled )
+ MLQuestSystem.HandleDeletion( this );
+ }
+
+ public QuestGiverItem( 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 abstract class TransientQuestGiverItem : TransientItem, IQuestGiver
+ {
+ private List m_MLQuests;
+
+ public List MLQuests
+ {
+ get
+ {
+ if ( m_MLQuests == null )
+ {
+ m_MLQuests = MLQuestSystem.FindQuestList( GetType() );
+
+ if ( m_MLQuests == null )
+ m_MLQuests = MLQuestSystem.EmptyList;
+ }
+
+ return m_MLQuests;
+ }
+ }
+
+ public bool CanGiveMLQuest { get { return ( MLQuests.Count != 0 ); } }
+
+ public TransientQuestGiverItem( int itemId, TimeSpan lifeSpan )
+ : base( itemId, lifeSpan )
+ {
+ }
+
+ public override bool Nontransferable { get { return true; } }
+
+ public override void HandleInvalidTransfer( Mobile from )
+ {
+ }
+
+ public override void AddNameProperties( ObjectPropertyList list )
+ {
+ base.AddNameProperties( list );
+
+ AddQuestItemProperty( list );
+
+ if ( CanGiveMLQuest )
+ list.Add( 1072269 ); // Quest Giver
+ }
+
+ public override void OnDoubleClick( Mobile from )
+ {
+ if ( !from.InRange( GetWorldLocation(), 2 ) )
+ from.LocalOverheadMessage( MessageType.Regular, 0x3B2, 1019045 ); // I can't reach that.
+ else if ( !IsChildOf( from.Backpack ) )
+ from.SendLocalizedMessage( 1042593 ); // That is not in your backpack.
+ else if ( MLQuestSystem.Enabled && CanGiveMLQuest && from is PlayerMobile )
+ MLQuestSystem.OnDoubleClick( this, (PlayerMobile)from );
+ }
+
+ public override void OnAfterDelete()
+ {
+ base.OnAfterDelete();
+
+ if ( MLQuestSystem.Enabled )
+ MLQuestSystem.HandleDeletion( this );
+ }
+
+ public TransientQuestGiverItem( 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();
+ }
+ }
+}
diff --git a/Scripts/Engines/MLQuests/MLQuest.cs b/Scripts/Engines/MLQuests/MLQuest.cs
index 68d455b41..072c6aa2f 100644
--- a/Scripts/Engines/MLQuests/MLQuest.cs
+++ b/Scripts/Engines/MLQuests/MLQuest.cs
@@ -35,7 +35,6 @@ namespace Server.Engines.MLQuests
private List m_Objectives;
private ObjectiveType m_ObjectiveType;
private List m_Rewards;
- private List m_Questers;
private List m_Instances;
@@ -74,12 +73,6 @@ namespace Server.Engines.MLQuests
set { m_Rewards = value; }
}
- public List Questers
- {
- get { return m_Questers; }
- set { m_Questers = value; }
- }
-
public List Instances
{
get { return m_Instances; }
@@ -152,36 +145,11 @@ namespace Server.Engines.MLQuests
m_Rewards = new List();
m_CompletionNotice = CompletionNoticeDefault;
- m_Questers = new List();
m_Instances = new List();
m_SaveEnabled = true;
}
- public void Register( BaseCreature quester )
- {
- if ( MLQuestSystem.Debug )
- Console.WriteLine( "INFO: Registering quester: {0} => {1}", quester.Serial, GetType().Name );
-
- m_Questers.Add( quester );
- }
-
- public void Unregister( BaseCreature quester )
- {
- if ( MLQuestSystem.Debug )
- Console.WriteLine( "INFO: Unregistering quester: {0} => {1}", quester.Serial, GetType().Name );
-
- m_Questers.Remove( quester );
-
- for ( int i = m_Instances.Count - 1; i >= 0; --i )
- {
- MLQuestInstance instance = m_Instances[i];
-
- if ( instance.Quester == quester )
- instance.OnQuesterDeleted();
- }
- }
-
public virtual void Generate()
{
if ( MLQuestSystem.Debug )
@@ -229,19 +197,19 @@ namespace Server.Engines.MLQuests
#endregion
- public MLQuestInstance CreateInstance( BaseCreature quester, PlayerMobile pm )
+ public MLQuestInstance CreateInstance( IQuestGiver quester, PlayerMobile pm )
{
return new MLQuestInstance( this, quester, pm );
}
- public bool CanOffer( BaseCreature quester, PlayerMobile pm, bool message )
+ public bool CanOffer( IQuestGiver quester, PlayerMobile pm, bool message )
{
return CanOffer( quester, pm, MLQuestSystem.GetContext( pm ), message );
}
- public virtual bool CanOffer( BaseCreature quester, PlayerMobile pm, MLQuestContext context, bool message )
+ public virtual bool CanOffer( IQuestGiver quester, PlayerMobile pm, MLQuestContext context, bool message )
{
- if ( !m_Activated || quester.Deleted || !m_Questers.Contains( quester ) )
+ if ( !m_Activated || quester.Deleted )
return false;
if ( context != null )
@@ -294,12 +262,12 @@ namespace Server.Engines.MLQuests
return true;
}
- public virtual void SendOffer( BaseCreature quester, PlayerMobile pm )
+ public virtual void SendOffer( IQuestGiver quester, PlayerMobile pm )
{
pm.SendGump( new QuestOfferGump( this, quester, pm ) );
}
- public virtual void OnAccept( BaseCreature quester, PlayerMobile pm )
+ public virtual void OnAccept( IQuestGiver quester, PlayerMobile pm )
{
if ( !CanOffer( quester, pm, true ) )
return;
@@ -319,7 +287,7 @@ namespace Server.Engines.MLQuests
{
}
- public virtual void OnRefuse( BaseCreature quester, PlayerMobile pm )
+ public virtual void OnRefuse( IQuestGiver quester, PlayerMobile pm )
{
pm.SendGump( new QuestConversationGump( this, pm, RefusalMessage ) );
}
diff --git a/Scripts/Engines/MLQuests/MLQuestEntry.cs b/Scripts/Engines/MLQuests/MLQuestEntry.cs
index de2d522f4..689a0cf88 100644
--- a/Scripts/Engines/MLQuests/MLQuestEntry.cs
+++ b/Scripts/Engines/MLQuests/MLQuestEntry.cs
@@ -22,7 +22,7 @@ namespace Server.Engines.MLQuests
{
private MLQuest m_Quest;
- private BaseCreature m_Quester;
+ private IQuestGiver m_Quester;
private Type m_QuesterType;
private PlayerMobile m_Player;
@@ -33,7 +33,7 @@ namespace Server.Engines.MLQuests
private Timer m_Timer;
- public MLQuestInstance( MLQuest quest, BaseCreature quester, PlayerMobile player )
+ public MLQuestInstance( MLQuest quest, IQuestGiver quester, PlayerMobile player )
{
m_Quest = quest;
@@ -89,7 +89,7 @@ namespace Server.Engines.MLQuests
set { m_Quest = value; }
}
- public BaseCreature Quester
+ public IQuestGiver Quester
{
get { return m_Quester; }
set
@@ -292,9 +292,10 @@ namespace Server.Engines.MLQuests
if ( m_Quest.ObjectiveType == ObjectiveType.All )
{
+ // TODO: 1115877 - You no longer have the required items to complete this quest.
foreach ( BaseObjectiveInstance objective in m_ObjectiveInstances )
{
- if ( !objective.IsCompleted() ) // Checking this isn't enough, Delivery is "complete" but claiming the items may not be possible
+ if ( !objective.IsCompleted() )
return;
}
@@ -309,9 +310,10 @@ namespace Server.Engines.MLQuests
}
else
{
- // The following behavior is unverified, as OSI (currently) has no collect quest requiring
- // only one objective to be completed. It is assumed that only one objective is claimed
- // (the first completed one), even when multiple are complete.
+ /* The following behavior is unverified, as OSI (currently) has no collect quest requiring
+ * only one objective to be completed. It is assumed that only one objective is claimed
+ * (the first completed one), even when multiple are complete.
+ */
bool complete = false;
foreach ( BaseObjectiveInstance objective in m_ObjectiveInstances )
@@ -467,14 +469,6 @@ namespace Server.Engines.MLQuests
m_Quest.OnPlayerDeath( this );
}
- public string GetReturnTo()
- {
- if ( m_Quester == null )
- return "";
-
- return ( m_Quester.Region.Name == null ) ? m_Quester.Name : String.Format( "{0} ({1})", m_Quester.Name, m_Quester.Region.Name );
- }
-
private bool GetFlag( MLQuestInstanceFlags flag )
{
return ( ( m_Flags & flag ) != 0 );
@@ -493,7 +487,11 @@ namespace Server.Engines.MLQuests
// Version info is written in MLQuestPersistence.Serialize
MLQuestSystem.WriteQuestRef( writer, m_Quest );
- writer.WriteMobile( m_Quester );
+
+ if ( m_Quester == null || m_Quester.Deleted )
+ writer.Write( Serial.MinusOne );
+ else
+ writer.Write( m_Quester.Serial );
writer.Write( ClaimReward );
writer.Write( m_ObjectiveInstances.Length );
@@ -505,7 +503,9 @@ namespace Server.Engines.MLQuests
public static MLQuestInstance Deserialize( GenericReader reader, int version, PlayerMobile pm )
{
MLQuest quest = MLQuestSystem.ReadQuestRef( reader );
- BaseCreature quester = reader.ReadMobile();
+
+ // TODO: Serialize quester TYPE too, the quest giver reference then becomes optional (only for escorts)
+ IQuestGiver quester = World.FindEntity( reader.ReadInt() ) as IQuestGiver;
bool claimReward = reader.ReadBool();
int objectives = reader.ReadInt();
diff --git a/Scripts/Engines/MLQuests/MLQuestSystem.cs b/Scripts/Engines/MLQuests/MLQuestSystem.cs
index 3163a0990..84ae9cab6 100644
--- a/Scripts/Engines/MLQuests/MLQuestSystem.cs
+++ b/Scripts/Engines/MLQuests/MLQuestSystem.cs
@@ -54,7 +54,9 @@ namespace Server.Engines.MLQuests
m_Contexts = new Dictionary();
string cfgPath = Path.Combine( Core.BaseDirectory, Path.Combine( "Data", "MLQuests.cfg" ) );
- Type baseType = typeof( MLQuest );
+
+ Type baseQuestType = typeof( MLQuest );
+ Type baseQuesterType = typeof( IQuestGiver );
if ( File.Exists( cfgPath ) )
{
@@ -71,8 +73,13 @@ namespace Server.Engines.MLQuests
Type type = ScriptCompiler.FindTypeByName( split[0] );
- if ( type == null || !baseType.IsAssignableFrom( type ) )
+ if ( type == null || !baseQuestType.IsAssignableFrom( type ) )
+ {
+ if ( Debug )
+ Console.WriteLine( "Warning: {1} quest type '{0}'", split[0], ( type == null ) ? "Unknown" : "Invalid" );
+
continue;
+ }
MLQuest quest = null;
@@ -91,8 +98,13 @@ namespace Server.Engines.MLQuests
{
Type questerType = ScriptCompiler.FindTypeByName( split[i] );
- if ( questerType == null )
+ if ( questerType == null || !baseQuesterType.IsAssignableFrom( questerType ) )
+ {
+ if ( Debug )
+ Console.WriteLine( "Warning: {1} quester type '{0}'", split[i], ( questerType == null ) ? "Unknown" : "Invalid" );
+
continue;
+ }
RegisterQuestGiver( quest, questerType );
}
@@ -175,7 +187,7 @@ namespace Server.Engines.MLQuests
m.SendMessage( "Activated: {0}", quest.Activated );
m.SendMessage( "Number of objectives: {0}", quest.Objectives.Count );
m.SendMessage( "Objective type: {0}", quest.ObjectiveType );
- m.SendMessage( "Number of registered questers: {0}", quest.Questers.Count );
+ m.SendMessage( "Number of active instances: {0}", quest.Instances.Count );
}
public class ViewQuestsCommand : BaseCommand
@@ -314,7 +326,7 @@ namespace Server.Engines.MLQuests
m.SendGump( new InterfaceGump( m, new string[] { "Object" }, found, 0, null ) );
}
- private static bool FindQuest( BaseCreature quester, PlayerMobile pm, MLQuestContext context, out MLQuest quest, out MLQuestInstance entry )
+ private static bool FindQuest( IQuestGiver quester, PlayerMobile pm, MLQuestContext context, out MLQuest quest, out MLQuestInstance entry )
{
quest = null;
entry = null;
@@ -364,9 +376,9 @@ namespace Server.Engines.MLQuests
return ( quest != null );
}
- public static void OnDoubleClick( BaseCreature quester, PlayerMobile pm )
+ public static void OnDoubleClick( IQuestGiver quester, PlayerMobile pm )
{
- if ( quester.Deleted || !quester.CanGiveMLQuest || !pm.Alive )
+ if ( quester.Deleted || !pm.Alive )
return;
MLQuestContext context = GetContext( pm );
@@ -528,7 +540,7 @@ namespace Server.Engines.MLQuests
}
}
- public static MLQuestInstance HandleDelivery( PlayerMobile pm, BaseCreature quester, Type questerType )
+ public static MLQuestInstance HandleDelivery( PlayerMobile pm, IQuestGiver quester, Type questerType )
{
MLQuestContext context = GetContext( pm );
@@ -613,6 +625,22 @@ namespace Server.Engines.MLQuests
}
}
+ public static void HandleDeletion( IQuestGiver quester )
+ {
+ foreach ( MLQuest quest in quester.MLQuests )
+ {
+ List instances = quest.Instances;
+
+ for ( int i = instances.Count - 1; i >= 0; --i )
+ {
+ MLQuestInstance instance = instances[i];
+
+ if ( instance.Quester == quester )
+ instance.OnQuesterDeleted();
+ }
+ }
+ }
+
public static void EventSink_QuestGumpRequest( QuestGumpRequestArgs args )
{
PlayerMobile pm = args.Mobile as PlayerMobile;
@@ -625,7 +653,7 @@ namespace Server.Engines.MLQuests
private static List m_EligiblePool = new List();
- public static MLQuest RandomStarterQuest( BaseCreature quester, PlayerMobile pm, MLQuestContext context )
+ public static MLQuest RandomStarterQuest( IQuestGiver quester, PlayerMobile pm, MLQuestContext context )
{
List quests = quester.MLQuests;
@@ -657,30 +685,52 @@ namespace Server.Engines.MLQuests
return m_EligiblePool[Utility.Random( m_EligiblePool.Count )];
}
- public static void TurnToFace( BaseCreature quester, Mobile mob )
+ public static void TurnToFace( IQuestGiver quester, Mobile mob )
{
- quester.Direction = quester.GetDirectionTo( mob );
+ if ( quester is Mobile )
+ {
+ Mobile m = (Mobile)quester;
+ m.Direction = m.GetDirectionTo( mob );
+ }
}
- public static void Tell( BaseCreature quester, PlayerMobile pm, int cliloc )
+ public static void Tell( IQuestGiver quester, PlayerMobile pm, int cliloc )
{
TurnToFace( quester, pm );
- quester.PrivateOverheadMessage( MessageType.Regular, SpeechColor, cliloc, pm.NetState );
+
+ if ( quester is Mobile )
+ ((Mobile)quester).PrivateOverheadMessage( MessageType.Regular, SpeechColor, cliloc, pm.NetState );
+ else if ( quester is Item )
+ MessageHelper.SendLocalizedMessageTo( (Item)quester, pm, cliloc, SpeechColor );
+ else
+ pm.SendLocalizedMessage( cliloc, "", SpeechColor );
}
- public static void Tell( BaseCreature quester, PlayerMobile pm, int cliloc, string args )
+ public static void Tell( IQuestGiver quester, PlayerMobile pm, int cliloc, string args )
{
TurnToFace( quester, pm );
- quester.PrivateOverheadMessage( MessageType.Regular, SpeechColor, cliloc, args, pm.NetState );
+
+ if ( quester is Mobile )
+ ((Mobile)quester).PrivateOverheadMessage( MessageType.Regular, SpeechColor, cliloc, args, pm.NetState );
+ else if ( quester is Item )
+ MessageHelper.SendLocalizedMessageTo( (Item)quester, pm, cliloc, args, SpeechColor );
+ else
+ pm.SendLocalizedMessage( cliloc, args, SpeechColor );
}
- public static void Tell( BaseCreature quester, PlayerMobile pm, string message )
+ public static void Tell( IQuestGiver quester, PlayerMobile pm, string message )
{
TurnToFace( quester, pm );
- quester.PrivateOverheadMessage( MessageType.Regular, SpeechColor, false, message, pm.NetState );
+
+ if ( quester is Mobile )
+ ((Mobile)quester).PrivateOverheadMessage( MessageType.Regular, SpeechColor, false, message, pm.NetState );
+ else if ( quester is Item )
+ MessageHelper.SendMessageTo( (Item)quester, pm, message, SpeechColor );
+ else
+ pm.SendMessage( SpeechColor, message );
}
- public static void TellDef( BaseCreature quester, PlayerMobile pm, TextDefinition def )
+ public static void TellDef( IQuestGiver quester, PlayerMobile pm, TextDefinition def )
{
if ( def == null )
return;
diff --git a/Scripts/Engines/MLQuests/Objectives/BaseObjective.cs b/Scripts/Engines/MLQuests/Objectives/BaseObjective.cs
index b1d139b62..bd5daa8d2 100644
--- a/Scripts/Engines/MLQuests/Objectives/BaseObjective.cs
+++ b/Scripts/Engines/MLQuests/Objectives/BaseObjective.cs
@@ -16,7 +16,7 @@ namespace Server.Engines.MLQuests.Objectives
{
}
- public virtual bool CanOffer( BaseCreature quester, PlayerMobile pm, bool message )
+ public virtual bool CanOffer( IQuestGiver quester, PlayerMobile pm, bool message )
{
return true;
}
diff --git a/Scripts/Engines/MLQuests/Objectives/CollectObjective.cs b/Scripts/Engines/MLQuests/Objectives/CollectObjective.cs
index 14ad28872..0b05f5904 100644
--- a/Scripts/Engines/MLQuests/Objectives/CollectObjective.cs
+++ b/Scripts/Engines/MLQuests/Objectives/CollectObjective.cs
@@ -46,6 +46,14 @@ namespace Server.Engines.MLQuests.Objectives
m_DesiredAmount = amount;
m_AcceptedType = type;
m_Name = name;
+
+ if ( MLQuestSystem.Debug && ShowDetailed && name.Number > 0 )
+ {
+ int itemid = LabelToItemID( name.Number );
+
+ if ( itemid <= 0 || itemid > 0x4000 )
+ Console.WriteLine( "Warning: cliloc {0} is likely giving the wrong item ID", name.Number );
+ }
}
public bool CheckType( Type type )
@@ -60,17 +68,10 @@ namespace Server.Engines.MLQuests.Objectives
public static int LabelToItemID( int label )
{
- int result;
-
if ( label < 1078872 )
- result = ( label - 1020000 );
+ return ( label - 1020000 );
else
- result = ( label - 1078872 );
-
- if ( MLQuestSystem.Debug && ( result <= 0 || result > 0x4000 ) )
- Console.WriteLine( "Warning: cliloc {0} is likely giving the wrong item ID", label );
-
- return result;
+ return ( label - 1078872 );
}
public override void WriteToGump( Gump g, ref int y )
@@ -250,7 +251,7 @@ namespace Server.Engines.MLQuests.Objectives
y += 16;
g.AddHtmlLocalized( 103, y, 120, 16, 1074782, 0x15F90, false, false ); // Return to
- g.AddLabel( 223, y, 0x481, Instance.GetReturnTo() );
+ g.AddLabel( 223, y, 0x481, QuesterNameAttribute.GetQuesterNameFor( Instance.QuesterType ) );
y += 16;
}
}
diff --git a/Scripts/Engines/MLQuests/Objectives/DeliverObjective.cs b/Scripts/Engines/MLQuests/Objectives/DeliverObjective.cs
index 2b70a2f02..4fe2edb5d 100644
--- a/Scripts/Engines/MLQuests/Objectives/DeliverObjective.cs
+++ b/Scripts/Engines/MLQuests/Objectives/DeliverObjective.cs
@@ -13,7 +13,7 @@ namespace Server.Engines.MLQuests.Objectives
private int m_Amount;
private TextDefinition m_Name;
private Type m_Destination;
- private TextDefinition m_DestinationName;
+ private bool m_SpawnsDelivery;
public Type Delivery
{
@@ -39,19 +39,59 @@ namespace Server.Engines.MLQuests.Objectives
set { m_Destination = value; }
}
- public TextDefinition DestinationName
+ public bool SpawnsDelivery
{
- get { return m_DestinationName; }
- set { m_DestinationName = value; }
+ get { return m_SpawnsDelivery; }
+ set { m_SpawnsDelivery = value; }
}
- public DeliverObjective( Type delivery, int amount, TextDefinition name, Type destination, TextDefinition destinationName )
+ public DeliverObjective( Type delivery, int amount, TextDefinition name, Type destination )
+ : this( delivery, amount, name, destination, true )
+ {
+ }
+
+ public DeliverObjective( Type delivery, int amount, TextDefinition name, Type destination, bool spawnsDelivery )
{
m_Delivery = delivery;
m_Amount = amount;
m_Name = name;
m_Destination = destination;
- m_DestinationName = destinationName;
+ m_SpawnsDelivery = spawnsDelivery;
+
+ if ( MLQuestSystem.Debug && name.Number > 0 )
+ {
+ int itemid = CollectObjective.LabelToItemID( name.Number );
+
+ if ( itemid <= 0 || itemid > 0x4000 )
+ Console.WriteLine( "Warning: cliloc {0} is likely giving the wrong item ID", name.Number );
+ }
+ }
+
+ public virtual void SpawnDelivery( Container pack )
+ {
+ if ( !m_SpawnsDelivery || pack == null )
+ return;
+
+ List- delivery = new List
- ();
+
+ for ( int i = 0; i < m_Amount; ++i )
+ {
+ Item item = Activator.CreateInstance( m_Delivery ) as Item;
+
+ if ( item == null )
+ continue;
+
+ delivery.Add( item );
+
+ if ( item.Stackable && m_Amount > 1 )
+ {
+ item.Amount = m_Amount;
+ break;
+ }
+ }
+
+ foreach ( Item item in delivery )
+ pack.DropItem( item ); // Confirmed: on OSI items are added even if your pack is full
}
public override void WriteToGump( Gump g, ref int y )
@@ -74,11 +114,7 @@ namespace Server.Engines.MLQuests.Objectives
y += 32;
g.AddHtmlLocalized( 103, y, 120, 16, 1072379, 0x15F90, false, false ); // Deliver to
-
- if ( m_DestinationName.Number > 0 )
- g.AddHtmlLocalized( 223, y, 190, 18, m_DestinationName.Number, false, false );
- else
- g.AddLabel( 223, y, 0x481, m_DestinationName.String );
+ g.AddLabel( 223, y, 0x481, QuesterNameAttribute.GetQuesterNameFor( m_Destination ) );
y += 16;
}
@@ -98,8 +134,13 @@ namespace Server.Engines.MLQuests.Objectives
public override bool IsTimed { get { return true; } }
public override TimeSpan Duration { get { return m_Duration; } }
- public TimedDeliverObjective( TimeSpan duration, Type delivery, int amount, TextDefinition name, Type destination, TextDefinition destinationName )
- : base( delivery, amount, name, destination, destinationName )
+ public TimedDeliverObjective( TimeSpan duration, Type delivery, int amount, TextDefinition name, Type destination )
+ : this( duration, delivery, amount, name, destination, true )
+ {
+ }
+
+ public TimedDeliverObjective( TimeSpan duration, Type delivery, int amount, TextDefinition name, Type destination, bool spawnsDelivery )
+ : base( delivery, amount, name, destination, spawnsDelivery )
{
m_Duration = duration;
}
@@ -130,7 +171,7 @@ namespace Server.Engines.MLQuests.Objectives
m_Objective = objective;
}
- public virtual bool IsDestination( BaseCreature quester, Type type )
+ public virtual bool IsDestination( IQuestGiver quester, Type type )
{
Type destType = m_Objective.Destination;
@@ -144,34 +185,7 @@ namespace Server.Engines.MLQuests.Objectives
public override void OnQuestAccepted()
{
- Container pack = Instance.Player.Backpack;
-
- if ( pack == null )
- return; // where are we supposed to put them?
-
- Type type = m_Objective.Delivery;
- int amount = m_Objective.Amount;
-
- List
- delivery = new List
- ();
-
- for ( int i = 0; i < amount; ++i )
- {
- Item item = Activator.CreateInstance( type ) as Item;
-
- if ( item == null )
- continue;
-
- delivery.Add( item );
-
- if ( item.Stackable && amount > 1 )
- {
- item.Amount = amount;
- break;
- }
- }
-
- foreach ( Item item in delivery )
- pack.DropItem( item ); // Confirmed: on OSI items are added even if your pack is full
+ m_Objective.SpawnDelivery( Instance.Player.Backpack );
}
// This is VERY similar to CollectObjective.GetCurrentTotal
diff --git a/Scripts/Engines/MLQuests/Objectives/EscortObjective.cs b/Scripts/Engines/MLQuests/Objectives/EscortObjective.cs
index 9d21fad00..f0777b007 100644
--- a/Scripts/Engines/MLQuests/Objectives/EscortObjective.cs
+++ b/Scripts/Engines/MLQuests/Objectives/EscortObjective.cs
@@ -29,11 +29,9 @@ namespace Server.Engines.MLQuests.Objectives
m_Destination = destination;
}
- public override bool CanOffer( BaseCreature quester, PlayerMobile pm, bool message )
+ public override bool CanOffer( IQuestGiver quester, PlayerMobile pm, bool message )
{
- BaseEscortable escortable = quester as BaseEscortable;
-
- if ( quester.Controlled || ( escortable != null && escortable.IsBeingDeleted ) )
+ if ( ( quester is BaseCreature && ( (BaseCreature)quester ).Controlled ) || ( quester is BaseEscortable && ( (BaseEscortable)quester ).IsBeingDeleted ) )
return false;
MLQuestContext context = MLQuestSystem.GetContext( pm );
@@ -54,7 +52,6 @@ namespace Server.Engines.MLQuests.Objectives
DateTime nextEscort = pm.LastEscortTime + BaseEscortable.EscortDelay;
- // Note: On OSI Bravehorn doesn't check the time limit, but it does SET the last escort time... bug!
if ( nextEscort > DateTime.Now )
{
if ( message )
@@ -100,6 +97,7 @@ namespace Server.Engines.MLQuests.Objectives
private bool m_HasCompleted;
private Timer m_Timer;
private DateTime m_LastSeenEscorter;
+ private BaseCreature m_Escort;
public bool HasCompleted
{
@@ -114,43 +112,56 @@ namespace Server.Engines.MLQuests.Objectives
m_HasCompleted = false;
m_Timer = Timer.DelayCall( TimeSpan.FromSeconds( 5 ), TimeSpan.FromSeconds( 5 ), new TimerCallback( CheckDestination ) );
m_LastSeenEscorter = DateTime.Now;
+ m_Escort = instance.Quester as BaseCreature;
+
+ if ( MLQuestSystem.Debug && m_Escort == null && instance.Quester != null )
+ Console.WriteLine( "Warning: EscortObjective is not supported for type '{0}'", instance.Quester.GetType().Name );
}
public override bool IsCompleted()
{
- // Once complete, it stays complete
return m_HasCompleted;
}
private void CheckDestination()
{
- if ( m_HasCompleted ) // Completed by deserialization
+ if ( m_Escort == null || m_HasCompleted ) // Completed by deserialization
{
StopTimer();
return;
}
MLQuestInstance instance = Instance;
- BaseCreature escort = instance.Quester;
PlayerMobile pm = instance.Player;
- if ( instance.Removed ) // Player cancelled or player died
+ if ( instance.Removed )
{
Abandon();
}
- else if ( m_Objective.Destination.Contains( escort ) ) // We've arrived!
+ else if ( m_Objective.Destination.Contains( m_Escort ) )
{
+ m_Escort.Say( 1042809, pm.Name ); // We have arrived! I thank thee, ~1_PLAYER_NAME~! I have no further need of thy services. Here is thy pay.
+
+ if ( pm.Young || m_Escort.Region.IsPartOf( "Haven Island" ) )
+ Titles.AwardFame( pm, 10, true );
+ else
+ VirtueHelper.AwardVirtue( pm, VirtueName.Compassion, ( m_Escort is BaseEscortable && ( (BaseEscortable)m_Escort ).IsPrisoner ) ? 400 : 200 );
+
+ EndFollow( m_Escort );
+ StopTimer();
+
m_HasCompleted = true;
CheckComplete();
- InternalOnQuestCompleted();
- StopTimer();
+
+ // Auto claim reward
+ MLQuestSystem.OnDoubleClick( m_Escort, pm );
}
- else if ( pm.Map != escort.Map || !pm.InRange( escort, 30 ) ) // Player abandoned us (range not verified)
+ else if ( pm.Map != m_Escort.Map || !pm.InRange( m_Escort, 30 ) ) // TODO: verify range
{
if ( m_LastSeenEscorter + BaseEscortable.AbandonDelay <= DateTime.Now )
Abandon();
}
- else // Player is still with us
+ else
{
m_LastSeenEscorter = DateTime.Now;
}
@@ -203,7 +214,8 @@ namespace Server.Engines.MLQuests.Objectives
pm.LastEscortTime = DateTime.Now;
- BeginFollow( instance.Quester, pm );
+ if ( m_Escort != null )
+ BeginFollow( m_Escort, pm );
}
public void Abandon()
@@ -211,17 +223,16 @@ namespace Server.Engines.MLQuests.Objectives
StopTimer();
MLQuestInstance instance = Instance;
- BaseCreature quester = instance.Quester;
PlayerMobile pm = instance.Player;
- if ( !quester.Deleted )
+ if ( m_Escort != null && !m_Escort.Deleted )
{
if ( !pm.Alive )
- quester.Say( 500901 ); // Ack! My escort has come to haunt me!
+ m_Escort.Say( 500901 ); // Ack! My escort has come to haunt me!
else
- quester.Say( 500902 ); // My escort seems to have abandoned me!
+ m_Escort.Say( 500902 ); // My escort seems to have abandoned me!
- EndFollow( quester );
+ EndFollow( m_Escort );
}
// Note: this sound is sent twice on OSI (once here and once in Cancel())
@@ -232,25 +243,6 @@ namespace Server.Engines.MLQuests.Objectives
instance.Cancel();
}
- private void InternalOnQuestCompleted() // To make sure it's never executed twice (when combined with a CollectObjective for example)
- {
- MLQuestInstance instance = Instance;
- PlayerMobile pm = instance.Player;
- BaseCreature quester = instance.Quester;
-
- quester.Say( 1042809, pm.Name ); // We have arrived! I thank thee, ~1_PLAYER_NAME~! I have no further need of thy services. Here is thy pay.
-
- // Verified: auto double click goes here
- MLQuestSystem.OnDoubleClick( quester, pm ); // Auto claim reward
-
- if ( pm.Young || quester.Region.IsPartOf( "Haven Island" ) )
- Titles.AwardFame( pm, 10, true );
- else
- VirtueHelper.AwardVirtue( pm, VirtueName.Compassion, ( quester is BaseEscortable && ( (BaseEscortable)quester ).IsPrisoner ) ? 400 : 200 );
-
- EndFollow( quester );
- }
-
public override void OnQuesterDeleted()
{
if ( IsCompleted() || Instance.Removed )
diff --git a/Scripts/Engines/MLQuests/Objectives/GainSkillObjective.cs b/Scripts/Engines/MLQuests/Objectives/GainSkillObjective.cs
index 4c9634781..44859d2ac 100644
--- a/Scripts/Engines/MLQuests/Objectives/GainSkillObjective.cs
+++ b/Scripts/Engines/MLQuests/Objectives/GainSkillObjective.cs
@@ -66,7 +66,7 @@ namespace Server.Engines.MLQuests.Objectives
m_Flags |= GainSkillObjectiveFlags.Accelerate;
}
- public override bool CanOffer( BaseCreature quester, PlayerMobile pm, bool message )
+ public override bool CanOffer( IQuestGiver quester, PlayerMobile pm, bool message )
{
Skill skill = pm.Skills[m_Skill];
diff --git a/Scripts/Engines/MLQuests/Objectives/KillObjective.cs b/Scripts/Engines/MLQuests/Objectives/KillObjective.cs
index 05772adfc..7b3fef9e2 100644
--- a/Scripts/Engines/MLQuests/Objectives/KillObjective.cs
+++ b/Scripts/Engines/MLQuests/Objectives/KillObjective.cs
@@ -178,7 +178,7 @@ namespace Server.Engines.MLQuests.Objectives
y += 16;
g.AddHtmlLocalized( 103, y, 120, 16, 1074782, 0x15F90, false, false ); // Return to
- g.AddLabel( 223, y, 0x481, Instance.GetReturnTo() );
+ g.AddLabel( 223, y, 0x481, QuesterNameAttribute.GetQuesterNameFor( Instance.QuesterType ) );
y += 16;
}
diff --git a/Scripts/Engines/MLQuests/QuesterNameAttribute.cs b/Scripts/Engines/MLQuests/QuesterNameAttribute.cs
new file mode 100644
index 000000000..cf9da3c70
--- /dev/null
+++ b/Scripts/Engines/MLQuests/QuesterNameAttribute.cs
@@ -0,0 +1,42 @@
+using System;
+using System.Collections.Generic;
+using Server;
+
+namespace Server.Engines.MLQuests
+{
+ [AttributeUsage( AttributeTargets.Class )]
+ public class QuesterNameAttribute : Attribute
+ {
+ private string m_QuesterName;
+
+ public string QuesterName { get { return m_QuesterName; } }
+
+ public QuesterNameAttribute( string questerName )
+ {
+ m_QuesterName = questerName;
+ }
+
+ private static readonly Type m_Type = typeof( QuesterNameAttribute );
+ private static readonly Dictionary m_Cache = new Dictionary();
+
+ public static string GetQuesterNameFor( Type t )
+ {
+ if ( t == null )
+ return "";
+
+ string result;
+
+ if ( m_Cache.TryGetValue( t, out result ) )
+ return result;
+
+ object[] attributes = t.GetCustomAttributes( m_Type, false );
+
+ if ( attributes.Length != 0 )
+ result = ( (QuesterNameAttribute)attributes[0] ).QuesterName;
+ else
+ result = t.Name;
+
+ return ( m_Cache[t] = result );
+ }
+ }
+}
diff --git a/Scripts/Items/Special/Solen Items/BagOfSending.cs b/Scripts/Items/Special/Solen Items/BagOfSending.cs
index 06599434e..66c2f905d 100644
--- a/Scripts/Items/Special/Solen Items/BagOfSending.cs
+++ b/Scripts/Items/Special/Solen Items/BagOfSending.cs
@@ -216,7 +216,7 @@ namespace Server.Items
{
MessageHelper.SendLocalizedMessageTo( m_Bag, from, 1054108, 0x59 ); // The bag of sending rejects the cursed item.
}
- else if ( !item.VerifyMove( from ) || item is Server.Engines.Quests.QuestItem )
+ else if ( !item.VerifyMove( from ) || item is Server.Engines.Quests.QuestItem || item.Nontransferable )
{
MessageHelper.SendLocalizedMessageTo( m_Bag, from, 1054109, 0x59 ); // The bag of sending rejects that item.
}
diff --git a/Scripts/Items/Special/Solen Items/MessageHelper.cs b/Scripts/Items/Special/Solen Items/MessageHelper.cs
index 16d9addbf..f17307204 100644
--- a/Scripts/Items/Special/Solen Items/MessageHelper.cs
+++ b/Scripts/Items/Special/Solen Items/MessageHelper.cs
@@ -14,5 +14,10 @@ namespace Server
{
to.Send( new MessageLocalized( from.Serial, from.ItemID, MessageType.Regular, hue, 3, number, "", args ) );
}
+
+ public static void SendMessageTo( Item from, Mobile to, string text, int hue )
+ {
+ to.Send( new UnicodeMessage( from.Serial, from.ItemID, MessageType.Regular, hue, 3, "ENU", "", text ) );
+ }
}
-}
\ No newline at end of file
+}
diff --git a/Scripts/Mobiles/BaseCreature.cs b/Scripts/Mobiles/BaseCreature.cs
index 48c5f2bf2..3b022d16b 100644
--- a/Scripts/Mobiles/BaseCreature.cs
+++ b/Scripts/Mobiles/BaseCreature.cs
@@ -165,7 +165,7 @@ namespace Server.Mobiles
}
}
- public partial class BaseCreature : Mobile, IHonorTarget
+ public partial class BaseCreature : Mobile, IHonorTarget, IQuestGiver
{
public const int MaxLoyalty = 100;
@@ -336,14 +336,14 @@ namespace Server.Mobiles
}
}
+ public virtual bool CanGiveMLQuest { get { return ( MLQuests.Count != 0 ); } }
public virtual bool StaticMLQuester { get { return true; } }
protected virtual List ConstructQuestList()
{
return null;
}
-
- public virtual bool CanGiveMLQuest { get { return ( MLQuests.Count != 0 ); } }
+
public virtual bool CanShout { get { return false; } }
public const int ShoutRange = 8;
@@ -379,18 +379,6 @@ namespace Server.Mobiles
{
}
- private void RegisterQuests()
- {
- foreach ( MLQuest quest in MLQuests )
- quest.Register( this );
- }
-
- private void UnregisterQuests()
- {
- foreach ( MLQuest quest in MLQuests )
- quest.Unregister( this );
- }
-
#endregion
#region Bonding
@@ -1751,9 +1739,6 @@ namespace Server.Mobiles
NameHue = 0x35;
GenerateLoot( true );
-
- if ( MLQuestSystem.Enabled && StaticMLQuester )
- RegisterQuests();
}
public BaseCreature( Serial serial ) : base( serial )
@@ -2127,9 +2112,6 @@ namespace Server.Mobiles
if ( IsAnimatedDead )
Spells.Necromancy.AnimateDeadSpell.Register( m_SummonMaster, this );
-
- if ( MLQuestSystem.Enabled && StaticMLQuester )
- RegisterQuests();
}
public virtual bool IsHumanInTown()
@@ -3007,7 +2989,7 @@ namespace Server.Mobiles
Spells.Necromancy.AnimateDeadSpell.Unregister( m_SummonMaster, this );
if ( MLQuestSystem.Enabled )
- UnregisterQuests();
+ MLQuestSystem.HandleDeletion( this );
base.OnAfterDelete();
}
diff --git a/Scripts/Mobiles/Townfolk/BaseEscortable.cs b/Scripts/Mobiles/Townfolk/BaseEscortable.cs
index 05fa582dd..d306e7e89 100644
--- a/Scripts/Mobiles/Townfolk/BaseEscortable.cs
+++ b/Scripts/Mobiles/Townfolk/BaseEscortable.cs
@@ -29,9 +29,6 @@ namespace Server.Mobiles
Region reg = Region;
Type[] list = reg.IsPartOf( "Haven Island" ) ? m_MLQuestTypesNH : m_MLQuestTypes;
- if ( MLQuestSystem.Debug )
- Console.WriteLine( "DEBUG: Assigning quest to BaseEscortable {0}, Region = {1}", Serial, ( reg == null ) ? "-null-" : reg.Name );
-
int randomIdx = Utility.Random( list.Length );
for ( int i = 0; i < list.Length; ++i )
@@ -55,13 +52,13 @@ namespace Server.Mobiles
if ( okay )
{
- SetMLQuest( quest );
+ m_MLQuest = quest;
break;
}
}
else if ( MLQuestSystem.Debug )
{
- Console.WriteLine( "WARNING: Type {0} should not be eligible as it is not a registered quest", questType.Name );
+ Console.WriteLine( "Warning: Escortable cannot be assigned quest type '{0}', it is not registered", questType.Name );
}
randomIdx = ( randomIdx + 1 ) % list.Length;
@@ -70,7 +67,7 @@ namespace Server.Mobiles
if ( m_MLQuest == null )
{
if ( MLQuestSystem.Debug )
- Console.WriteLine( "WARNING: No suitable quest found for escort {0}", Serial );
+ Console.WriteLine( "Warning: No suitable quest found for escort {0}", Serial );
return null;
}
@@ -174,12 +171,6 @@ namespace Server.Mobiles
typeof( EscortToNHBank )
};
- public void SetMLQuest( MLQuest quest )
- {
- m_MLQuest = quest;
- quest.Register( this );
- }
-
[Constructable]
public BaseEscortable()
: base(AIType.AI_Melee, FightMode.Aggressor, 22, 1, 0.2, 1.0)
@@ -571,7 +562,7 @@ namespace Server.Mobiles
MLQuest quest = MLQuestSystem.ReadQuestRef( reader );
if ( MLQuestSystem.Enabled && quest != null && !StaticMLQuester )
- SetMLQuest( quest );
+ m_MLQuest = quest;
}
}
diff --git a/Server/Item.cs b/Server/Item.cs
index 14109da78..7e0c04c9d 100644
--- a/Server/Item.cs
+++ b/Server/Item.cs
@@ -1541,16 +1541,7 @@ namespace Server
public virtual bool StackWith( Mobile from, Item dropped, bool playSound )
{
- // TODO: OSI actually just ignores the stacking attempt and places the item over it, can we do that?
- if( Nontransferable || dropped.Nontransferable )
- {
- if ( dropped.Nontransferable )
- HandleInvalidTransfer( from );
-
- return false;
- }
-
- if ( dropped.Stackable && Stackable && dropped.GetType() == GetType() && dropped.ItemID == ItemID && dropped.Hue == Hue && dropped.Name == Name && (dropped.Amount + Amount) <= 60000 && dropped != this )
+ if ( dropped.Stackable && Stackable && dropped.GetType() == GetType() && dropped.ItemID == ItemID && dropped.Hue == Hue && dropped.Name == Name && (dropped.Amount + Amount) <= 60000 && dropped != this && !dropped.Nontransferable && !Nontransferable )
{
if ( m_LootType != dropped.m_LootType )
m_LootType = LootType.Regular;
@@ -3858,7 +3849,7 @@ namespace Server
return false;
else if ( !from.OnDroppedItemOnto( this, target ) )
return false;
- else if( Nontransferable && from.Player )
+ else if( Nontransferable && from.Player && target != from.Backpack )
{
HandleInvalidTransfer( from );
return false;