Reorganizes Project (#41)
This commit is contained in:
parent
08bf44af9a
commit
3614a66aee
3499 changed files with 79 additions and 55 deletions
|
|
@ -0,0 +1,118 @@
|
|||
using System;
|
||||
using Server.Items;
|
||||
using Server.Mobiles;
|
||||
|
||||
namespace Server.Engines.Quests.Ambitious
|
||||
{
|
||||
public class AmbitiousQueenQuest : QuestSystem
|
||||
{
|
||||
private static Type[] m_TypeReferenceTable =
|
||||
{
|
||||
typeof(DontOfferConversation),
|
||||
typeof(AcceptConversation),
|
||||
typeof(DuringKillQueensConversation),
|
||||
typeof(GatherFungiConversation),
|
||||
typeof(DuringFungiGatheringConversation),
|
||||
typeof(EndConversation),
|
||||
typeof(FullBackpackConversation),
|
||||
typeof(End2Conversation),
|
||||
typeof(KillQueensObjective),
|
||||
typeof(ReturnAfterKillsObjective),
|
||||
typeof(GatherFungiObjective),
|
||||
typeof(GetRewardObjective)
|
||||
};
|
||||
|
||||
public AmbitiousQueenQuest(PlayerMobile from, bool redSolen) : base(from)
|
||||
{
|
||||
RedSolen = redSolen;
|
||||
}
|
||||
|
||||
// Serialization
|
||||
public AmbitiousQueenQuest()
|
||||
{
|
||||
}
|
||||
|
||||
public override Type[] TypeReferenceTable => m_TypeReferenceTable;
|
||||
|
||||
public override object Name => 1054146;
|
||||
|
||||
public override object OfferMessage => 1054060;
|
||||
|
||||
public override TimeSpan RestartDelay => TimeSpan.Zero;
|
||||
public override bool IsTutorial => false;
|
||||
|
||||
public override int Picture => 0x15C9;
|
||||
|
||||
public bool RedSolen{ get; private set; }
|
||||
|
||||
public override void ChildDeserialize(GenericReader reader)
|
||||
{
|
||||
int version = reader.ReadEncodedInt();
|
||||
|
||||
RedSolen = reader.ReadBool();
|
||||
}
|
||||
|
||||
public override void ChildSerialize(GenericWriter writer)
|
||||
{
|
||||
writer.WriteEncodedInt(0); // version
|
||||
|
||||
writer.Write(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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,123 @@
|
|||
namespace Server.Engines.Quests.Ambitious
|
||||
{
|
||||
public class DontOfferConversation : QuestConversation
|
||||
{
|
||||
public override object Message => 1054059;
|
||||
|
||||
public override bool Logged => false;
|
||||
}
|
||||
|
||||
public class AcceptConversation : QuestConversation
|
||||
{
|
||||
public override object Message => 1054061;
|
||||
|
||||
public override void OnRead()
|
||||
{
|
||||
System.AddObjective(new KillQueensObjective());
|
||||
}
|
||||
}
|
||||
|
||||
public class DuringKillQueensConversation : QuestConversation
|
||||
{
|
||||
public override object Message => 1054066;
|
||||
|
||||
public override bool Logged => false;
|
||||
}
|
||||
|
||||
public class GatherFungiConversation : QuestConversation
|
||||
{
|
||||
public override object Message => 1054068;
|
||||
|
||||
public override void OnRead()
|
||||
{
|
||||
System.AddObjective(new GatherFungiObjective());
|
||||
}
|
||||
}
|
||||
|
||||
public class DuringFungiGatheringConversation : QuestConversation
|
||||
{
|
||||
public override object Message => 1054070;
|
||||
|
||||
public override bool Logged => false;
|
||||
}
|
||||
|
||||
public class EndConversation : QuestConversation
|
||||
{
|
||||
public override object Message => 1054073;
|
||||
|
||||
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
|
||||
{
|
||||
private bool m_BagOfSending;
|
||||
private bool m_Gold;
|
||||
|
||||
private bool m_Logged;
|
||||
private bool m_PowderOfTranslocation;
|
||||
|
||||
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 object Message => 1054077;
|
||||
|
||||
public override bool Logged => m_Logged;
|
||||
|
||||
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(0); // version
|
||||
|
||||
writer.Write(m_BagOfSending);
|
||||
writer.Write(m_PowderOfTranslocation);
|
||||
writer.Write(m_Gold);
|
||||
}
|
||||
}
|
||||
|
||||
public class End2Conversation : QuestConversation
|
||||
{
|
||||
public override object Message => 1054078;
|
||||
|
||||
public override void OnRead()
|
||||
{
|
||||
System.Complete();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,199 @@
|
|||
using Server.Items;
|
||||
using Server.Mobiles;
|
||||
|
||||
namespace Server.Engines.Quests.Ambitious
|
||||
{
|
||||
public abstract class BaseAmbitiousSolenQueen : BaseQuester
|
||||
{
|
||||
public BaseAmbitiousSolenQueen()
|
||||
{
|
||||
}
|
||||
|
||||
public BaseAmbitiousSolenQueen(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public abstract bool RedSolen{ get; }
|
||||
public override string DefaultName => "an ambitious solen queen";
|
||||
public override bool DisallowAllMoves => false;
|
||||
|
||||
public override void InitBody()
|
||||
{
|
||||
Body = 0x30F;
|
||||
|
||||
if (!RedSolen)
|
||||
Hue = 0x453;
|
||||
|
||||
SpeechHue = 0;
|
||||
}
|
||||
|
||||
public override int GetIdleSound()
|
||||
{
|
||||
return 0x10D;
|
||||
}
|
||||
|
||||
public override void OnTalk(PlayerMobile player, bool contextMenu)
|
||||
{
|
||||
Direction = GetDirectionTo(player);
|
||||
|
||||
if (player.Quest is AmbitiousQueenQuest qs && qs.RedSolen == RedSolen)
|
||||
{
|
||||
if (qs.IsObjectiveInProgress(typeof(KillQueensObjective)))
|
||||
{
|
||||
qs.AddConversation(new DuringKillQueensConversation());
|
||||
}
|
||||
else
|
||||
{
|
||||
QuestObjective obj = qs.FindObjective<ReturnAfterKillsObjective>();
|
||||
|
||||
if (obj?.Completed == false)
|
||||
{
|
||||
obj.Complete();
|
||||
}
|
||||
else if (qs.IsObjectiveInProgress(typeof(GatherFungiObjective)))
|
||||
{
|
||||
qs.AddConversation(new DuringFungiGatheringConversation());
|
||||
}
|
||||
else
|
||||
{
|
||||
GetRewardObjective lastObj = qs.FindObjective<GetRewardObjective>();
|
||||
|
||||
if (lastObj?.Completed == false)
|
||||
{
|
||||
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, 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)
|
||||
{
|
||||
Direction = GetDirectionTo(from);
|
||||
|
||||
if (from is PlayerMobile player)
|
||||
if (player.Quest is AmbitiousQueenQuest qs && qs.RedSolen == RedSolen)
|
||||
{
|
||||
QuestObjective obj = qs.FindObjective<GatherFungiObjective>();
|
||||
|
||||
if (obj?.Completed == false)
|
||||
if (dropped is ZoogiFungus fungi)
|
||||
{
|
||||
if (fungi.Amount >= 50)
|
||||
{
|
||||
obj.Complete();
|
||||
|
||||
fungi.Amount -= 50;
|
||||
|
||||
if (fungi.Amount == 0)
|
||||
{
|
||||
fungi.Delete();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
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 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 class RedAmbitiousSolenQueen : BaseAmbitiousSolenQueen
|
||||
{
|
||||
[Constructible]
|
||||
public RedAmbitiousSolenQueen()
|
||||
{
|
||||
}
|
||||
|
||||
public RedAmbitiousSolenQueen(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override bool RedSolen => 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();
|
||||
}
|
||||
}
|
||||
|
||||
public class BlackAmbitiousSolenQueen : BaseAmbitiousSolenQueen
|
||||
{
|
||||
[Constructible]
|
||||
public BlackAmbitiousSolenQueen()
|
||||
{
|
||||
}
|
||||
|
||||
public BlackAmbitiousSolenQueen(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override bool RedSolen => 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,127 @@
|
|||
using Server.Items;
|
||||
using Server.Mobiles;
|
||||
|
||||
namespace Server.Engines.Quests.Ambitious
|
||||
{
|
||||
public class KillQueensObjective : QuestObjective
|
||||
{
|
||||
public override object Message => ((AmbitiousQueenQuest)System).RedSolen ? 1054062 : 1054063;
|
||||
|
||||
public override int MaxProgress => 5;
|
||||
|
||||
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);
|
||||
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;
|
||||
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 => 1054067;
|
||||
|
||||
public override void OnComplete()
|
||||
{
|
||||
System.AddConversation(new GatherFungiConversation());
|
||||
}
|
||||
}
|
||||
|
||||
public class GatherFungiObjective : QuestObjective
|
||||
{
|
||||
public override object Message => 1054069;
|
||||
|
||||
public override void OnComplete()
|
||||
{
|
||||
System.AddConversation(new EndConversation());
|
||||
}
|
||||
}
|
||||
|
||||
public class GetRewardObjective : QuestObjective
|
||||
{
|
||||
public GetRewardObjective(bool bagOfSending, bool powderOfTranslocation, bool gold)
|
||||
{
|
||||
BagOfSending = bagOfSending;
|
||||
PowderOfTranslocation = powderOfTranslocation;
|
||||
Gold = gold;
|
||||
}
|
||||
|
||||
public GetRewardObjective()
|
||||
{
|
||||
}
|
||||
|
||||
public override object Message => 1054148;
|
||||
|
||||
public bool BagOfSending{ get; set; }
|
||||
|
||||
public bool PowderOfTranslocation{ get; set; }
|
||||
|
||||
public bool Gold{ get; set; }
|
||||
|
||||
public override void OnComplete()
|
||||
{
|
||||
System.AddConversation(new End2Conversation());
|
||||
}
|
||||
|
||||
public override void ChildDeserialize(GenericReader reader)
|
||||
{
|
||||
int version = reader.ReadEncodedInt();
|
||||
|
||||
BagOfSending = reader.ReadBool();
|
||||
PowderOfTranslocation = reader.ReadBool();
|
||||
Gold = reader.ReadBool();
|
||||
}
|
||||
|
||||
public override void ChildSerialize(GenericWriter writer)
|
||||
{
|
||||
writer.WriteEncodedInt(0); // version
|
||||
|
||||
writer.Write(BagOfSending);
|
||||
writer.Write(PowderOfTranslocation);
|
||||
writer.Write(Gold);
|
||||
}
|
||||
}
|
||||
}
|
||||
89
Projects/Scripts/Engines/Quests/Collector/CollectorQuest.cs
Normal file
89
Projects/Scripts/Engines/Quests/Collector/CollectorQuest.cs
Normal file
|
|
@ -0,0 +1,89 @@
|
|||
using System;
|
||||
using Server.Mobiles;
|
||||
|
||||
namespace Server.Engines.Quests.Collector
|
||||
{
|
||||
public class CollectorQuest : QuestSystem
|
||||
{
|
||||
private static Type[] m_TypeReferenceTable =
|
||||
{
|
||||
typeof(DontOfferConversation),
|
||||
typeof(DeclineConversation),
|
||||
typeof(AcceptConversation),
|
||||
typeof(ElwoodDuringFishConversation),
|
||||
typeof(ReturnPearlsConversation),
|
||||
typeof(AlbertaPaintingConversation),
|
||||
typeof(AlbertaStoolConversation),
|
||||
typeof(AlbertaEndPaintingConversation),
|
||||
typeof(AlbertaAfterPaintingConversation),
|
||||
typeof(ElwoodDuringPainting1Conversation),
|
||||
typeof(ElwoodDuringPainting2Conversation),
|
||||
typeof(ReturnPaintingConversation),
|
||||
typeof(GabrielAutographConversation),
|
||||
typeof(GabrielNoSheetMusicConversation),
|
||||
typeof(NoSheetMusicConversation),
|
||||
typeof(GetSheetMusicConversation),
|
||||
typeof(GabrielSheetMusicConversation),
|
||||
typeof(GabrielIgnoreConversation),
|
||||
typeof(ElwoodDuringAutograph1Conversation),
|
||||
typeof(ElwoodDuringAutograph2Conversation),
|
||||
typeof(ElwoodDuringAutograph3Conversation),
|
||||
typeof(ReturnAutographConversation),
|
||||
typeof(TomasToysConversation),
|
||||
typeof(TomasDuringCollectingConversation),
|
||||
typeof(ReturnImagesConversation),
|
||||
typeof(ElwoodDuringToys1Conversation),
|
||||
typeof(ElwoodDuringToys2Conversation),
|
||||
typeof(ElwoodDuringToys3Conversation),
|
||||
typeof(FullEndConversation),
|
||||
typeof(FishPearlsObjective),
|
||||
typeof(ReturnPearlsObjective),
|
||||
typeof(FindAlbertaObjective),
|
||||
typeof(SitOnTheStoolObjective),
|
||||
typeof(ReturnPaintingObjective),
|
||||
typeof(FindGabrielObjective),
|
||||
typeof(FindSheetMusicObjective),
|
||||
typeof(ReturnSheetMusicObjective),
|
||||
typeof(ReturnAutographObjective),
|
||||
typeof(FindTomasObjective),
|
||||
typeof(CaptureImagesObjective),
|
||||
typeof(ReturnImagesObjective),
|
||||
typeof(ReturnToysObjective),
|
||||
typeof(MakeRoomObjective)
|
||||
};
|
||||
|
||||
public CollectorQuest(PlayerMobile from) : base(from)
|
||||
{
|
||||
}
|
||||
|
||||
// Serialization
|
||||
public CollectorQuest()
|
||||
{
|
||||
}
|
||||
|
||||
public override Type[] TypeReferenceTable => m_TypeReferenceTable;
|
||||
|
||||
public override object Name => "Collector's Quest";
|
||||
|
||||
public override object OfferMessage => 1055081;
|
||||
|
||||
public override TimeSpan RestartDelay => TimeSpan.Zero;
|
||||
public override bool IsTutorial => false;
|
||||
|
||||
public override int Picture => 0x15A9;
|
||||
|
||||
public override void Accept()
|
||||
{
|
||||
base.Accept();
|
||||
|
||||
AddConversation(new AcceptConversation());
|
||||
}
|
||||
|
||||
public override void Decline()
|
||||
{
|
||||
base.Decline();
|
||||
|
||||
AddConversation(new DeclineConversation());
|
||||
}
|
||||
}
|
||||
}
|
||||
266
Projects/Scripts/Engines/Quests/Collector/Conversations.cs
Normal file
266
Projects/Scripts/Engines/Quests/Collector/Conversations.cs
Normal file
|
|
@ -0,0 +1,266 @@
|
|||
namespace Server.Engines.Quests.Collector
|
||||
{
|
||||
public class DontOfferConversation : QuestConversation
|
||||
{
|
||||
public override object Message => 1055080;
|
||||
|
||||
public override bool Logged => false;
|
||||
}
|
||||
|
||||
public class DeclineConversation : QuestConversation
|
||||
{
|
||||
public override object Message => 1055082;
|
||||
|
||||
public override bool Logged => false;
|
||||
}
|
||||
|
||||
public class AcceptConversation : QuestConversation
|
||||
{
|
||||
public override object Message => 1055083;
|
||||
|
||||
public override void OnRead()
|
||||
{
|
||||
System.AddObjective(new FishPearlsObjective());
|
||||
}
|
||||
}
|
||||
|
||||
public class ElwoodDuringFishConversation : QuestConversation
|
||||
{
|
||||
public override object Message => 1055089;
|
||||
|
||||
public override bool Logged => false;
|
||||
}
|
||||
|
||||
public class ReturnPearlsConversation : QuestConversation
|
||||
{
|
||||
public override object Message => 1055090;
|
||||
|
||||
public override void OnRead()
|
||||
{
|
||||
System.AddObjective(new FindAlbertaObjective());
|
||||
}
|
||||
}
|
||||
|
||||
public class AlbertaPaintingConversation : QuestConversation
|
||||
{
|
||||
public override object Message => 1055092;
|
||||
|
||||
public override void OnRead()
|
||||
{
|
||||
System.AddObjective(new SitOnTheStoolObjective());
|
||||
}
|
||||
}
|
||||
|
||||
public class AlbertaStoolConversation : QuestConversation
|
||||
{
|
||||
public override object Message => 1055096;
|
||||
|
||||
public override bool Logged => false;
|
||||
}
|
||||
|
||||
public class AlbertaEndPaintingConversation : QuestConversation
|
||||
{
|
||||
public override object Message => 1055098;
|
||||
|
||||
public override void OnRead()
|
||||
{
|
||||
System.AddObjective(new ReturnPaintingObjective());
|
||||
}
|
||||
}
|
||||
|
||||
public class AlbertaAfterPaintingConversation : QuestConversation
|
||||
{
|
||||
public override object Message => 1055102;
|
||||
|
||||
public override bool Logged => false;
|
||||
}
|
||||
|
||||
public class ElwoodDuringPainting1Conversation : QuestConversation
|
||||
{
|
||||
public override object Message => 1055094;
|
||||
|
||||
public override bool Logged => false;
|
||||
}
|
||||
|
||||
public class ElwoodDuringPainting2Conversation : QuestConversation
|
||||
{
|
||||
public override object Message => 1055097;
|
||||
|
||||
public override bool Logged => false;
|
||||
}
|
||||
|
||||
public class ReturnPaintingConversation : QuestConversation
|
||||
{
|
||||
public override object Message => 1055100;
|
||||
|
||||
public override void OnRead()
|
||||
{
|
||||
System.AddObjective(new FindGabrielObjective());
|
||||
}
|
||||
}
|
||||
|
||||
public class GabrielAutographConversation : QuestConversation
|
||||
{
|
||||
public override object Message => 1055103;
|
||||
|
||||
public override void OnRead()
|
||||
{
|
||||
System.AddObjective(new FindSheetMusicObjective(true));
|
||||
}
|
||||
}
|
||||
|
||||
public class GabrielNoSheetMusicConversation : QuestConversation
|
||||
{
|
||||
public override object Message => 1055111;
|
||||
|
||||
public override bool Logged => false;
|
||||
}
|
||||
|
||||
public class NoSheetMusicConversation : QuestConversation
|
||||
{
|
||||
public override object Message => 1055106;
|
||||
|
||||
public override bool Logged => false;
|
||||
}
|
||||
|
||||
public class GetSheetMusicConversation : QuestConversation
|
||||
{
|
||||
public override object Message => 1055109;
|
||||
|
||||
public override void OnRead()
|
||||
{
|
||||
System.AddObjective(new ReturnSheetMusicObjective());
|
||||
}
|
||||
}
|
||||
|
||||
public class GabrielSheetMusicConversation : QuestConversation
|
||||
{
|
||||
public override object Message => 1055113;
|
||||
|
||||
public override void OnRead()
|
||||
{
|
||||
System.AddObjective(new ReturnAutographObjective());
|
||||
}
|
||||
}
|
||||
|
||||
public class GabrielIgnoreConversation : QuestConversation
|
||||
{
|
||||
public override object Message => 1055118;
|
||||
|
||||
public override bool Logged => false;
|
||||
}
|
||||
|
||||
public class ElwoodDuringAutograph1Conversation : QuestConversation
|
||||
{
|
||||
public override object Message => 1055105;
|
||||
|
||||
public override bool Logged => false;
|
||||
}
|
||||
|
||||
public class ElwoodDuringAutograph2Conversation : QuestConversation
|
||||
{
|
||||
public override object Message => 1055112;
|
||||
|
||||
public override bool Logged => false;
|
||||
}
|
||||
|
||||
public class ElwoodDuringAutograph3Conversation : QuestConversation
|
||||
{
|
||||
public override object Message => 1055115;
|
||||
|
||||
public override bool Logged => false;
|
||||
}
|
||||
|
||||
public class ReturnAutographConversation : QuestConversation
|
||||
{
|
||||
public override object Message => 1055116;
|
||||
|
||||
public override void OnRead()
|
||||
{
|
||||
System.AddObjective(new FindTomasObjective());
|
||||
}
|
||||
}
|
||||
|
||||
public class TomasToysConversation : QuestConversation
|
||||
{
|
||||
public override object Message => 1055119;
|
||||
|
||||
public override void OnRead()
|
||||
{
|
||||
System.AddObjective(new CaptureImagesObjective(true));
|
||||
}
|
||||
}
|
||||
|
||||
public class TomasDuringCollectingConversation : QuestConversation
|
||||
{
|
||||
public override object Message => 1055129;
|
||||
|
||||
public override bool Logged => false;
|
||||
}
|
||||
|
||||
public class ReturnImagesConversation : QuestConversation
|
||||
{
|
||||
public override object Message => 1055131;
|
||||
|
||||
public override void OnRead()
|
||||
{
|
||||
System.AddObjective(new ReturnToysObjective());
|
||||
}
|
||||
}
|
||||
|
||||
public class ElwoodDuringToys1Conversation : QuestConversation
|
||||
{
|
||||
public override object Message => 1055123;
|
||||
|
||||
public override bool Logged => false;
|
||||
}
|
||||
|
||||
public class ElwoodDuringToys2Conversation : QuestConversation
|
||||
{
|
||||
public override object Message => 1055130;
|
||||
|
||||
public override bool Logged => false;
|
||||
}
|
||||
|
||||
public class ElwoodDuringToys3Conversation : QuestConversation
|
||||
{
|
||||
public override object Message => 1055133;
|
||||
|
||||
public override bool Logged => false;
|
||||
}
|
||||
|
||||
public class EndConversation : QuestConversation
|
||||
{
|
||||
public override object Message => 1055134;
|
||||
|
||||
public override void OnRead()
|
||||
{
|
||||
System.Complete();
|
||||
}
|
||||
}
|
||||
|
||||
public class FullEndConversation : QuestConversation
|
||||
{
|
||||
private bool m_Logged;
|
||||
|
||||
public FullEndConversation(bool logged)
|
||||
{
|
||||
m_Logged = logged;
|
||||
}
|
||||
|
||||
public FullEndConversation()
|
||||
{
|
||||
m_Logged = true;
|
||||
}
|
||||
|
||||
public override object Message => 1055135;
|
||||
|
||||
public override bool Logged => m_Logged;
|
||||
|
||||
public override void OnRead()
|
||||
{
|
||||
if (m_Logged)
|
||||
System.AddObjective(new MakeRoomObjective());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,133 @@
|
|||
using Server.Mobiles;
|
||||
using Server.Targeting;
|
||||
|
||||
namespace Server.Engines.Quests.Collector
|
||||
{
|
||||
public class EnchantedPaints : QuestItem
|
||||
{
|
||||
[Constructible]
|
||||
public EnchantedPaints() : base(0xFC1)
|
||||
{
|
||||
LootType = LootType.Blessed;
|
||||
|
||||
Weight = 1.0;
|
||||
}
|
||||
|
||||
public EnchantedPaints(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override bool CanDrop(PlayerMobile player)
|
||||
{
|
||||
return !(player.Quest is CollectorQuest);
|
||||
|
||||
/*return !( qs.IsObjectiveInProgress( typeof( CaptureImagesObjective ) )
|
||||
|| qs.IsObjectiveInProgress( typeof( ReturnImagesObjective ) ) );*/
|
||||
}
|
||||
|
||||
public override void OnDoubleClick(Mobile from)
|
||||
{
|
||||
if (from is PlayerMobile player)
|
||||
{
|
||||
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.
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
|
||||
private class 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;
|
||||
|
||||
if (from is PlayerMobile player)
|
||||
{
|
||||
QuestSystem qs = player.Quest;
|
||||
|
||||
if (!(qs is CollectorQuest))
|
||||
return;
|
||||
|
||||
CaptureImagesObjective obj = qs.FindObjective<CaptureImagesObjective>();
|
||||
|
||||
if (obj?.Completed != false)
|
||||
return;
|
||||
|
||||
if (targeted is Mobile)
|
||||
{
|
||||
CaptureResponse response = obj.CaptureImage(
|
||||
targeted.GetType().Name == "GreaterMongbat"
|
||||
? new Mongbat().GetType()
|
||||
: targeted.GetType(), out ImageType 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.
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,97 @@
|
|||
using System;
|
||||
using System.Linq;
|
||||
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(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)
|
||||
};
|
||||
|
||||
private static ImageType[] m_ImageTypeList;
|
||||
|
||||
public ImageTypeInfo(int figurine, Type type, int x, int y)
|
||||
{
|
||||
Figurine = figurine;
|
||||
Type = type;
|
||||
X = x;
|
||||
Y = y;
|
||||
}
|
||||
|
||||
public int Figurine{ get; }
|
||||
|
||||
public Type Type{ get; }
|
||||
|
||||
public int Name => Figurine < 0x4000 ? 1020000 + Figurine : 1078872 + Figurine;
|
||||
public int X{ get; }
|
||||
public int Y{ get; }
|
||||
|
||||
public static ImageTypeInfo Get(ImageType image)
|
||||
{
|
||||
int index = (int)image;
|
||||
return m_Table[index >= 0 && index < m_Table.Length ? index : 0];
|
||||
}
|
||||
|
||||
public static ImageType[] RandomList(int count)
|
||||
{
|
||||
if (m_ImageTypeList == null)
|
||||
{
|
||||
m_ImageTypeList = new ImageType[m_Table.Length];
|
||||
for (int i = 0; i < m_Table.Length; i++)
|
||||
m_ImageTypeList[i] = (ImageType)i;
|
||||
}
|
||||
|
||||
ImageType[] array = m_ImageTypeList.ToArray();
|
||||
Utility.Shuffle(array);
|
||||
return array.Take(count).ToArray();
|
||||
}
|
||||
}
|
||||
}
|
||||
265
Projects/Scripts/Engines/Quests/Collector/Items/Obsidian.cs
Normal file
265
Projects/Scripts/Engines/Quests/Collector/Items/Obsidian.cs
Normal file
|
|
@ -0,0 +1,265 @@
|
|||
using System.Collections.Generic;
|
||||
using Server.ContextMenus;
|
||||
using Server.Network;
|
||||
using Server.Targeting;
|
||||
|
||||
namespace Server.Engines.Quests.Collector
|
||||
{
|
||||
public class Obsidian : Item
|
||||
{
|
||||
private const int m_Partial = 2;
|
||||
private const int m_Completed = 10;
|
||||
|
||||
private static readonly string[] m_Names =
|
||||
{
|
||||
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"
|
||||
};
|
||||
|
||||
private int m_Quantity;
|
||||
private string m_StatueName;
|
||||
|
||||
[Constructible]
|
||||
public Obsidian() : base(0x1EA7)
|
||||
{
|
||||
Hue = 0x497;
|
||||
|
||||
m_Quantity = 1;
|
||||
m_StatueName = "";
|
||||
}
|
||||
|
||||
public Obsidian(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int Quantity
|
||||
{
|
||||
get => 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 => m_StatueName;
|
||||
set
|
||||
{
|
||||
m_StatueName = value;
|
||||
InvalidateProperties();
|
||||
}
|
||||
}
|
||||
|
||||
public override bool ForceShowProperties => ObjectPropertyList.Enabled;
|
||||
|
||||
public static string RandomName(Mobile from)
|
||||
{
|
||||
int index = Utility.Random(m_Names.Length);
|
||||
if (m_Names[index] == null)
|
||||
return from.Name;
|
||||
return m_Names[index];
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
|
||||
writer.WriteEncodedInt(m_Quantity);
|
||||
writer.Write(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());
|
||||
}
|
||||
|
||||
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 >= m_Partial && m_Obsidian.Quantity < 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
if (m_Obsidian.Deleted || m_Obsidian.Quantity >= m_Completed || !(targeted is Item targ))
|
||||
return;
|
||||
|
||||
if (m_Obsidian.IsChildOf(from.Backpack) && targ.IsChildOf(from.Backpack) && targ is Obsidian targObsidian &&
|
||||
targ != m_Obsidian)
|
||||
if (targObsidian.Quantity < m_Completed)
|
||||
{
|
||||
if (targObsidian.Quantity + m_Obsidian.Quantity <= m_Completed)
|
||||
{
|
||||
targObsidian.Quantity += m_Obsidian.Quantity;
|
||||
m_Obsidian.Delete();
|
||||
}
|
||||
else
|
||||
{
|
||||
int delta = m_Completed - targObsidian.Quantity;
|
||||
targObsidian.Quantity += delta;
|
||||
m_Obsidian.Quantity -= delta;
|
||||
}
|
||||
|
||||
if (targObsidian.Quantity >= m_Completed)
|
||||
targObsidian.StatueName = 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.
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,88 @@
|
|||
using Server.Gumps;
|
||||
using Server.Network;
|
||||
|
||||
namespace Server.Engines.Quests.Collector
|
||||
{
|
||||
public class PaintedImage : Item
|
||||
{
|
||||
private ImageType m_Image;
|
||||
|
||||
[Constructible]
|
||||
public PaintedImage(ImageType image) : base(0xFF3)
|
||||
{
|
||||
Weight = 1.0;
|
||||
Hue = 0x8FD;
|
||||
|
||||
m_Image = image;
|
||||
}
|
||||
|
||||
public PaintedImage(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public ImageType Image
|
||||
{
|
||||
get => m_Image;
|
||||
set
|
||||
{
|
||||
m_Image = value;
|
||||
InvalidateProperties();
|
||||
}
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(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();
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,86 @@
|
|||
using Server.Items;
|
||||
using Server.Mobiles;
|
||||
|
||||
namespace Server.Engines.Quests.Collector
|
||||
{
|
||||
public class AlbertaGiacco : BaseQuester
|
||||
{
|
||||
[Constructible]
|
||||
public AlbertaGiacco() : base("the respected painter")
|
||||
{
|
||||
}
|
||||
|
||||
public AlbertaGiacco(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override string DefaultName => "Alberta Giacco";
|
||||
|
||||
public override void InitBody()
|
||||
{
|
||||
InitStats(100, 100, 25);
|
||||
|
||||
Hue = 0x83F2;
|
||||
|
||||
Female = true;
|
||||
Body = 0x191;
|
||||
}
|
||||
|
||||
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<FindAlbertaObjective>();
|
||||
|
||||
if (obj?.Completed == false)
|
||||
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(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,228 @@
|
|||
using Server.Items;
|
||||
using Server.Mobiles;
|
||||
|
||||
namespace Server.Engines.Quests.Collector
|
||||
{
|
||||
public class ElwoodMcCarrin : BaseQuester
|
||||
{
|
||||
[Constructible]
|
||||
public ElwoodMcCarrin() : base("the well-known collector")
|
||||
{
|
||||
}
|
||||
|
||||
public ElwoodMcCarrin(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override string DefaultName => "Elwood McCarrin";
|
||||
|
||||
public override void InitBody()
|
||||
{
|
||||
InitStats(100, 100, 25);
|
||||
|
||||
Hue = 0x83ED;
|
||||
|
||||
Female = false;
|
||||
Body = 0x190;
|
||||
}
|
||||
|
||||
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<ReturnPearlsObjective>();
|
||||
|
||||
if (obj?.Completed == false)
|
||||
{
|
||||
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<ReturnPaintingObjective>();
|
||||
|
||||
if (obj?.Completed == false)
|
||||
{
|
||||
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<ReturnAutographObjective>();
|
||||
|
||||
if (obj?.Completed == false)
|
||||
{
|
||||
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<ReturnToysObjective>();
|
||||
|
||||
if (obj?.Completed == false)
|
||||
{
|
||||
obj.Complete();
|
||||
|
||||
if (GiveReward(player))
|
||||
qs.AddConversation(new EndConversation());
|
||||
else
|
||||
qs.AddConversation(new FullEndConversation(true));
|
||||
}
|
||||
else
|
||||
{
|
||||
obj = qs.FindObjective<MakeRoomObjective>();
|
||||
|
||||
if (obj?.Completed == false)
|
||||
{
|
||||
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)RandomMinMaxScaled(2, 3);
|
||||
weapon.AccuracyLevel = (WeaponAccuracyLevel)RandomMinMaxScaled(2, 3);
|
||||
weapon.DurabilityLevel = (WeaponDurabilityLevel)RandomMinMaxScaled(2, 3);
|
||||
}
|
||||
|
||||
bag.DropItem(weapon);
|
||||
}
|
||||
else
|
||||
{
|
||||
Item item;
|
||||
|
||||
if (Core.AOS)
|
||||
{
|
||||
item = Loot.RandomArmorOrShieldOrJewelry();
|
||||
|
||||
if (item is BaseArmor armor)
|
||||
BaseRunicTool.ApplyAttributesTo(armor, 2, 20, 30);
|
||||
else if (item is BaseJewel jewel)
|
||||
BaseRunicTool.ApplyAttributesTo(jewel, 2, 20, 30);
|
||||
}
|
||||
else
|
||||
{
|
||||
BaseArmor armor = Loot.RandomArmorOrShield();
|
||||
item = armor;
|
||||
|
||||
armor.ProtectionLevel = (ArmorProtectionLevel)RandomMinMaxScaled(2, 3);
|
||||
armor.Durability = (ArmorDurabilityLevel)RandomMinMaxScaled(2, 3);
|
||||
}
|
||||
|
||||
bag.DropItem(item);
|
||||
}
|
||||
|
||||
bag.DropItem(new Obsidian());
|
||||
|
||||
if (to.PlaceInBackpack(bag)) return true;
|
||||
|
||||
bag.Delete();
|
||||
return false;
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,99 @@
|
|||
using Server.Items;
|
||||
using Server.Mobiles;
|
||||
|
||||
namespace Server.Engines.Quests.Collector
|
||||
{
|
||||
public class GabrielPiete : BaseQuester
|
||||
{
|
||||
[Constructible]
|
||||
public GabrielPiete() : base("the renowned minstrel")
|
||||
{
|
||||
}
|
||||
|
||||
public GabrielPiete(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override string DefaultName => "Gabriel Piete";
|
||||
|
||||
public override void InitBody()
|
||||
{
|
||||
InitStats(100, 100, 25);
|
||||
|
||||
Hue = 0x83EF;
|
||||
|
||||
Female = false;
|
||||
Body = 0x190;
|
||||
}
|
||||
|
||||
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<FindGabrielObjective>();
|
||||
|
||||
if (obj?.Completed == false)
|
||||
{
|
||||
obj.Complete();
|
||||
}
|
||||
else if (qs.IsObjectiveInProgress(typeof(FindSheetMusicObjective)))
|
||||
{
|
||||
qs.AddConversation(new GabrielNoSheetMusicConversation());
|
||||
}
|
||||
else
|
||||
{
|
||||
obj = qs.FindObjective<ReturnSheetMusicObjective>();
|
||||
|
||||
if (obj?.Completed == false)
|
||||
obj.Complete();
|
||||
else if (qs.IsObjectiveInProgress(typeof(ReturnAutographObjective)))
|
||||
qs.AddConversation(new GabrielIgnoreConversation());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
163
Projects/Scripts/Engines/Quests/Collector/Mobiles/Impresario.cs
Normal file
163
Projects/Scripts/Engines/Quests/Collector/Mobiles/Impresario.cs
Normal file
|
|
@ -0,0 +1,163 @@
|
|||
using Server.Gumps;
|
||||
using Server.Items;
|
||||
using Server.Mobiles;
|
||||
using Server.Network;
|
||||
|
||||
namespace Server.Engines.Quests.Collector
|
||||
{
|
||||
public class Impresario : BaseQuester
|
||||
{
|
||||
[Constructible]
|
||||
public Impresario() : base("the impresario")
|
||||
{
|
||||
}
|
||||
|
||||
public Impresario(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void InitBody()
|
||||
{
|
||||
InitStats(100, 100, 25);
|
||||
|
||||
Hue = Race.Human.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))
|
||||
return;
|
||||
|
||||
FindSheetMusicObjective obj = qs.FindObjective<FindSheetMusicObjective>();
|
||||
|
||||
if (obj?.Completed == false)
|
||||
{
|
||||
Direction = GetDirectionTo(player);
|
||||
|
||||
if (obj.IsInRightTheater())
|
||||
{
|
||||
player.CloseGump<SheetMusicOfferGump>();
|
||||
player.SendGump(new SheetMusicOfferGump());
|
||||
}
|
||||
else
|
||||
{
|
||||
qs.AddConversation(new NoSheetMusicConversation());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
|
||||
public 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); // <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); // I accept.
|
||||
|
||||
AddRadio(85, 385, 0x25F8, 0x25FB, false, 0);
|
||||
AddHtmlLocalized(120, 391, 280, 20, 1049012, White); // No thanks, I decline.
|
||||
|
||||
AddButton(340, 390, 0xF7, 0xF8, 1);
|
||||
}
|
||||
|
||||
public override void OnResponse(NetState sender, RelayInfo info)
|
||||
{
|
||||
if (info.ButtonID == 1 && info.IsSwitched(1))
|
||||
if (sender.Mobile is PlayerMobile player)
|
||||
{
|
||||
QuestSystem qs = player.Quest;
|
||||
|
||||
if (!(qs is CollectorQuest))
|
||||
return;
|
||||
|
||||
FindSheetMusicObjective obj = qs.FindObjective<FindSheetMusicObjective>();
|
||||
|
||||
if (obj?.Completed != false)
|
||||
return;
|
||||
|
||||
if (player.Backpack?.ConsumeTotal(typeof(Gold), 10) == true)
|
||||
{
|
||||
obj.Complete();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (player.FindBankNoCreate()?.ConsumeTotal(typeof(Gold), 10) == true)
|
||||
obj.Complete();
|
||||
|
||||
else
|
||||
player.SendLocalizedMessage(
|
||||
1055108); // You don't have enough gold to buy the sheet music.
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,109 @@
|
|||
using Server.Items;
|
||||
using Server.Mobiles;
|
||||
|
||||
namespace Server.Engines.Quests.Collector
|
||||
{
|
||||
public class TomasONeerlan : BaseQuester
|
||||
{
|
||||
[Constructible]
|
||||
public TomasONeerlan() : base("the famed toymaker")
|
||||
{
|
||||
}
|
||||
|
||||
public TomasONeerlan(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override string DefaultName => "Tomas O'Neerlan";
|
||||
|
||||
public override void InitBody()
|
||||
{
|
||||
InitStats(100, 100, 25);
|
||||
|
||||
Hue = 0x83F8;
|
||||
|
||||
Female = false;
|
||||
Body = 0x190;
|
||||
}
|
||||
|
||||
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<FindTomasObjective>();
|
||||
|
||||
if (obj?.Completed == false)
|
||||
{
|
||||
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<ReturnImagesObjective>();
|
||||
|
||||
if (obj?.Completed == false)
|
||||
{
|
||||
player.Backpack?.ConsumeUpTo(typeof(EnchantedPaints), 1);
|
||||
|
||||
obj.Complete();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
372
Projects/Scripts/Engines/Quests/Collector/Objectives.cs
Normal file
372
Projects/Scripts/Engines/Quests/Collector/Objectives.cs
Normal file
|
|
@ -0,0 +1,372 @@
|
|||
using System;
|
||||
using Server.Mobiles;
|
||||
|
||||
namespace Server.Engines.Quests.Collector
|
||||
{
|
||||
public class FishPearlsObjective : QuestObjective
|
||||
{
|
||||
public override object Message => 1055084;
|
||||
|
||||
public override int MaxProgress => 6;
|
||||
|
||||
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 => 1055088;
|
||||
|
||||
public override void OnComplete()
|
||||
{
|
||||
System.AddConversation(new ReturnPearlsConversation());
|
||||
}
|
||||
}
|
||||
|
||||
public class FindAlbertaObjective : QuestObjective
|
||||
{
|
||||
public override object Message => 1055091;
|
||||
|
||||
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 SitOnTheStoolObjective()
|
||||
{
|
||||
m_Begin = DateTime.MaxValue;
|
||||
}
|
||||
|
||||
public override object Message => 1055093;
|
||||
|
||||
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 => 1055099;
|
||||
|
||||
public override void OnComplete()
|
||||
{
|
||||
System.AddConversation(new ReturnPaintingConversation());
|
||||
}
|
||||
}
|
||||
|
||||
public class FindGabrielObjective : QuestObjective
|
||||
{
|
||||
public override object Message => 1055101;
|
||||
|
||||
public override void OnComplete()
|
||||
{
|
||||
System.AddConversation(new GabrielAutographConversation());
|
||||
}
|
||||
}
|
||||
|
||||
public enum Theater
|
||||
{
|
||||
Britain,
|
||||
Nujelm,
|
||||
Jhelom
|
||||
}
|
||||
|
||||
public class FindSheetMusicObjective : QuestObjective
|
||||
{
|
||||
private Theater m_Theater;
|
||||
|
||||
public FindSheetMusicObjective(bool init)
|
||||
{
|
||||
if (init)
|
||||
InitTheater();
|
||||
}
|
||||
|
||||
public FindSheetMusicObjective()
|
||||
{
|
||||
}
|
||||
|
||||
public override object Message => 1055104;
|
||||
|
||||
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(0); // version
|
||||
|
||||
writer.WriteEncodedInt((int)m_Theater);
|
||||
}
|
||||
}
|
||||
|
||||
public class ReturnSheetMusicObjective : QuestObjective
|
||||
{
|
||||
public override object Message => 1055110;
|
||||
|
||||
public override void OnComplete()
|
||||
{
|
||||
System.AddConversation(new GabrielSheetMusicConversation());
|
||||
}
|
||||
}
|
||||
|
||||
public class ReturnAutographObjective : QuestObjective
|
||||
{
|
||||
public override object Message => 1055114;
|
||||
|
||||
public override void OnComplete()
|
||||
{
|
||||
System.AddConversation(new ReturnAutographConversation());
|
||||
}
|
||||
}
|
||||
|
||||
public class FindTomasObjective : QuestObjective
|
||||
{
|
||||
public override object Message => 1055117;
|
||||
|
||||
public override void OnComplete()
|
||||
{
|
||||
System.AddConversation(new TomasToysConversation());
|
||||
}
|
||||
}
|
||||
|
||||
public enum CaptureResponse
|
||||
{
|
||||
Valid,
|
||||
AlreadyDone,
|
||||
Invalid
|
||||
}
|
||||
|
||||
public class CaptureImagesObjective : QuestObjective
|
||||
{
|
||||
private bool[] m_Done;
|
||||
private ImageType[] m_Images;
|
||||
|
||||
public CaptureImagesObjective(bool init)
|
||||
{
|
||||
if (init)
|
||||
{
|
||||
m_Images = ImageTypeInfo.RandomList(4);
|
||||
m_Done = new bool[4];
|
||||
}
|
||||
}
|
||||
|
||||
public CaptureImagesObjective()
|
||||
{
|
||||
}
|
||||
|
||||
public override object Message => 1055120;
|
||||
|
||||
public override bool Completed
|
||||
{
|
||||
get
|
||||
{
|
||||
for (int i = 0; i < m_Done.Length; i++)
|
||||
if (!m_Done[i])
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
m_Done[i] = true;
|
||||
|
||||
CheckCompletionStatus();
|
||||
|
||||
return CaptureResponse.Valid;
|
||||
}
|
||||
}
|
||||
|
||||
image = 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(0); // version
|
||||
|
||||
writer.WriteEncodedInt(m_Images.Length);
|
||||
|
||||
for (int i = 0; i < m_Images.Length; i++)
|
||||
{
|
||||
writer.WriteEncodedInt((int)m_Images[i]);
|
||||
writer.Write(m_Done[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class ReturnImagesObjective : QuestObjective
|
||||
{
|
||||
public override object Message => 1055128;
|
||||
|
||||
public override void OnComplete()
|
||||
{
|
||||
System.AddConversation(new ReturnImagesConversation());
|
||||
}
|
||||
}
|
||||
|
||||
public class ReturnToysObjective : QuestObjective
|
||||
{
|
||||
public override object Message => 1055132;
|
||||
}
|
||||
|
||||
public class MakeRoomObjective : QuestObjective
|
||||
{
|
||||
public override object Message => 1055136;
|
||||
}
|
||||
}
|
||||
121
Projects/Scripts/Engines/Quests/Core/BaseQuester.cs
Normal file
121
Projects/Scripts/Engines/Quests/Core/BaseQuester.cs
Normal file
|
|
@ -0,0 +1,121 @@
|
|||
using System.Collections.Generic;
|
||||
using Server.ContextMenus;
|
||||
using Server.Items;
|
||||
using Server.Mobiles;
|
||||
|
||||
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 mobile && m_Quester.CanTalkTo(mobile))
|
||||
m_Quester.OnTalk(mobile, true);
|
||||
}
|
||||
}
|
||||
|
||||
public abstract class BaseQuester : BaseVendor
|
||||
{
|
||||
protected List<SBInfo> m_SBInfos = new List<SBInfo>();
|
||||
|
||||
public BaseQuester(string title = null) : base(title)
|
||||
{
|
||||
}
|
||||
|
||||
public BaseQuester(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
protected override List<SBInfo> SBInfos => m_SBInfos;
|
||||
|
||||
public override bool IsActiveVendor => false;
|
||||
public override bool IsInvulnerable => true;
|
||||
public override bool DisallowAllMoves => true;
|
||||
public override bool ClickTitle => false;
|
||||
public override bool CanTeach => false;
|
||||
|
||||
public virtual int TalkNumber // Talk
|
||||
=> 6146;
|
||||
|
||||
public override void InitSBInfo()
|
||||
{
|
||||
}
|
||||
|
||||
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 mobile && TalkNumber > 0 && CanTalkTo(mobile))
|
||||
list.Add(new TalkEntry(this));
|
||||
}
|
||||
|
||||
public override void OnMovement(Mobile m, Point3D oldLocation)
|
||||
{
|
||||
if (m.Alive && m is PlayerMobile pm)
|
||||
{
|
||||
int range = GetAutoTalkRange(pm);
|
||||
|
||||
if (pm.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(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
using Server.Mobiles;
|
||||
|
||||
namespace Server.Engines.Quests
|
||||
{
|
||||
public abstract class DynamicTeleporter : Item
|
||||
{
|
||||
public DynamicTeleporter(int itemID = 0x1822, int hue = 0x482) : base(itemID)
|
||||
{
|
||||
Movable = false;
|
||||
Hue = hue;
|
||||
}
|
||||
|
||||
public DynamicTeleporter(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override int LabelNumber => 1049382; // a magical teleporter
|
||||
|
||||
public virtual int NotWorkingMessage // Nothing Happens.
|
||||
=> 500309;
|
||||
|
||||
public abstract bool GetDestination(PlayerMobile player, ref Point3D loc, ref Map map);
|
||||
|
||||
public override bool OnMoveOver(Mobile m)
|
||||
{
|
||||
if (m is PlayerMobile pm)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
pm.SendLocalizedMessage(NotWorkingMessage);
|
||||
}
|
||||
|
||||
return base.OnMoveOver(m);
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
189
Projects/Scripts/Engines/Quests/Core/Items/EnchantedSextant.cs
Normal file
189
Projects/Scripts/Engines/Quests/Core/Items/EnchantedSextant.cs
Normal file
|
|
@ -0,0 +1,189 @@
|
|||
using Server.Network;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class EnchantedSextant : Item
|
||||
{
|
||||
private const double m_LongDistance = 300.0;
|
||||
|
||||
private const double m_ShortDistance = 5.0;
|
||||
|
||||
//TODO: Trammel/Haven
|
||||
private static readonly Point2D[] m_TrammelBanks =
|
||||
{
|
||||
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(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(854, 680),
|
||||
new Point2D(855, 603),
|
||||
new Point2D(1226, 554),
|
||||
new Point2D(1610, 556)
|
||||
};
|
||||
|
||||
private static readonly Point2D[] m_MalasBanks =
|
||||
{
|
||||
new Point2D(996, 519),
|
||||
new Point2D(2048, 1345)
|
||||
};
|
||||
|
||||
[Constructible]
|
||||
public EnchantedSextant() : base(0x1058)
|
||||
{
|
||||
Weight = 2.0;
|
||||
}
|
||||
|
||||
public EnchantedSextant(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override int LabelNumber => 1046226; // an enchanted sextant
|
||||
|
||||
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 override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
195
Projects/Scripts/Engines/Quests/Core/Items/HornOfRetreat.cs
Normal file
195
Projects/Scripts/Engines/Quests/Core/Items/HornOfRetreat.cs
Normal file
|
|
@ -0,0 +1,195 @@
|
|||
using System;
|
||||
using Server.Items;
|
||||
using Server.Regions;
|
||||
|
||||
namespace Server.Engines.Quests
|
||||
{
|
||||
public class HornOfRetreat : Item
|
||||
{
|
||||
private int m_Charges;
|
||||
|
||||
private Timer m_PlayTimer;
|
||||
|
||||
[Constructible]
|
||||
public HornOfRetreat() : base(0xFC4)
|
||||
{
|
||||
Hue = 0x482;
|
||||
Weight = 1.0;
|
||||
Charges = 10;
|
||||
}
|
||||
|
||||
public HornOfRetreat(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public Point3D DestLoc{ get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public Map DestMap{ get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int Charges
|
||||
{
|
||||
get => m_Charges;
|
||||
set
|
||||
{
|
||||
m_Charges = value;
|
||||
InvalidateProperties();
|
||||
}
|
||||
}
|
||||
|
||||
public override int LabelNumber => 1049117; // Horn of Retreat
|
||||
|
||||
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~
|
||||
}
|
||||
|
||||
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), () => 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(Mobile from)
|
||||
{
|
||||
m_PlayTimer = null;
|
||||
|
||||
HornOfRetreatMoongate gate = new HornOfRetreatMoongate(DestLoc, DestMap, from, Hue);
|
||||
|
||||
gate.MoveToWorld(from.Location, from.Map);
|
||||
|
||||
from.PlaySound(0x20E);
|
||||
|
||||
gate.SendLocalizedMessageTo(from, 1049102, from.Name); // Quickly ~1_NAME~! Onward through the gate!
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
|
||||
writer.Write(DestLoc);
|
||||
writer.Write(DestMap);
|
||||
writer.Write(m_Charges);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
DestLoc = reader.ReadPoint3D();
|
||||
DestMap = reader.ReadMap();
|
||||
m_Charges = reader.ReadInt();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class HornOfRetreatMoongate : Moongate
|
||||
{
|
||||
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), Delete);
|
||||
}
|
||||
|
||||
public HornOfRetreatMoongate(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override int LabelNumber => 1049114; // Sanctuary Gate
|
||||
|
||||
public override void BeginConfirmation(Mobile from)
|
||||
{
|
||||
EndConfirmation(from);
|
||||
}
|
||||
|
||||
public override void UseGate(Mobile m)
|
||||
{
|
||||
if (m.Region.IsPartOf<Jail>())
|
||||
{
|
||||
m.SendLocalizedMessage(1114345); // You'll need a better jailbreak plan than that!
|
||||
}
|
||||
else if (m == m_Caster)
|
||||
{
|
||||
base.UseGate(m);
|
||||
Delete();
|
||||
}
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
|
||||
Delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
92
Projects/Scripts/Engines/Quests/Core/Items/QuestItem.cs
Normal file
92
Projects/Scripts/Engines/Quests/Core/Items/QuestItem.cs
Normal file
|
|
@ -0,0 +1,92 @@
|
|||
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 virtual bool Accepted => Deleted;
|
||||
|
||||
public abstract bool CanDrop(PlayerMobile pm);
|
||||
|
||||
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;
|
||||
|
||||
if (!(from is PlayerMobile) || CanDrop((PlayerMobile)from)) return true;
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
if (!(from is PlayerMobile) || CanDrop((PlayerMobile)from)) return true;
|
||||
from.SendLocalizedMessage(
|
||||
1049344); // You decide against trading the item. You still need it for your quest.
|
||||
return false;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
if (!(from is PlayerMobile) || CanDrop((PlayerMobile)from)) return true;
|
||||
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;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
public override DeathMoveResult OnParentDeath(Mobile parent)
|
||||
{
|
||||
if (parent is PlayerMobile mobile && !CanDrop(mobile))
|
||||
return DeathMoveResult.MoveToBackpack;
|
||||
|
||||
return base.OnParentDeath(parent);
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
23
Projects/Scripts/Engines/Quests/Core/QuestCallbackEntry.cs
Normal file
23
Projects/Scripts/Engines/Quests/Core/QuestCallbackEntry.cs
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
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()
|
||||
{
|
||||
m_Callback?.Invoke();
|
||||
}
|
||||
}
|
||||
}
|
||||
138
Projects/Scripts/Engines/Quests/Core/QuestConversation.cs
Normal file
138
Projects/Scripts/Engines/Quests/Core/QuestConversation.cs
Normal file
|
|
@ -0,0 +1,138 @@
|
|||
using System.Collections.Generic;
|
||||
using Server.Gumps;
|
||||
using Server.Network;
|
||||
|
||||
namespace Server.Engines.Quests
|
||||
{
|
||||
public abstract class QuestConversation
|
||||
{
|
||||
public abstract object Message{ get; }
|
||||
|
||||
public virtual QuestItemInfo[] Info => null;
|
||||
public virtual bool Logged => true;
|
||||
|
||||
public QuestSystem System{ get; set; }
|
||||
|
||||
public bool HasBeenRead{ get; set; }
|
||||
|
||||
public virtual void BaseDeserialize(GenericReader reader)
|
||||
{
|
||||
int version = reader.ReadEncodedInt();
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
HasBeenRead = reader.ReadBool();
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ChildDeserialize(reader);
|
||||
}
|
||||
|
||||
public virtual void ChildDeserialize(GenericReader reader)
|
||||
{
|
||||
int version = reader.ReadEncodedInt();
|
||||
}
|
||||
|
||||
public virtual void BaseSerialize(GenericWriter writer)
|
||||
{
|
||||
writer.WriteEncodedInt(0); // version
|
||||
|
||||
writer.Write(HasBeenRead);
|
||||
|
||||
ChildSerialize(writer);
|
||||
}
|
||||
|
||||
public virtual void ChildSerialize(GenericWriter writer)
|
||||
{
|
||||
writer.WriteEncodedInt(0); // version
|
||||
}
|
||||
|
||||
public virtual void OnRead()
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public class QuestConversationsGump : BaseQuestGump
|
||||
{
|
||||
private List<QuestConversation> m_Conversations;
|
||||
|
||||
public QuestConversationsGump(QuestConversation conv) : this(new List<QuestConversation>{ conv })
|
||||
{
|
||||
}
|
||||
|
||||
public QuestConversationsGump(List<QuestConversation> 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); // <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);
|
||||
AddImage(0, 0, 10440);
|
||||
|
||||
AddPage(1);
|
||||
|
||||
for (int i = 0; i < conversations.Count; ++i)
|
||||
{
|
||||
QuestConversation conv = 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); // 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); // Next
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnResponse(NetState sender, RelayInfo info)
|
||||
{
|
||||
for (int i = m_Conversations.Count - 1; i >= 0; --i)
|
||||
{
|
||||
QuestConversation qc = m_Conversations[i];
|
||||
|
||||
if (!qc.HasBeenRead)
|
||||
{
|
||||
qc.HasBeenRead = true;
|
||||
qc.OnRead();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
57
Projects/Scripts/Engines/Quests/Core/QuestItemInfo.cs
Normal file
57
Projects/Scripts/Engines/Quests/Core/QuestItemInfo.cs
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
namespace Server.Engines.Quests
|
||||
{
|
||||
public class QuestItemInfo
|
||||
{
|
||||
public QuestItemInfo(object name, int itemID)
|
||||
{
|
||||
Name = name;
|
||||
ItemID = itemID;
|
||||
}
|
||||
|
||||
public object Name{ get; set; }
|
||||
|
||||
public int ItemID{ get; set; }
|
||||
}
|
||||
|
||||
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); // INFO
|
||||
|
||||
AddImage(62, 52, 9157);
|
||||
AddImage(72, 52, 9157);
|
||||
AddImage(82, 52, 9157);
|
||||
|
||||
AddButton(25, 31, 1209, 1210, 777);
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
255
Projects/Scripts/Engines/Quests/Core/QuestObjective.cs
Normal file
255
Projects/Scripts/Engines/Quests/Core/QuestObjective.cs
Normal file
|
|
@ -0,0 +1,255 @@
|
|||
using System.Collections.Generic;
|
||||
using Server.Gumps;
|
||||
using Server.Items;
|
||||
using Server.Mobiles;
|
||||
using Server.Network;
|
||||
|
||||
namespace Server.Engines.Quests
|
||||
{
|
||||
public abstract class QuestObjective
|
||||
{
|
||||
private int m_CurProgress;
|
||||
|
||||
public abstract object Message{ get; }
|
||||
|
||||
public virtual int MaxProgress => 1;
|
||||
public virtual QuestItemInfo[] Info => null;
|
||||
|
||||
public QuestSystem System{ get; set; }
|
||||
|
||||
public bool HasBeenRead{ get; set; }
|
||||
|
||||
public int CurProgress
|
||||
{
|
||||
get => m_CurProgress;
|
||||
set
|
||||
{
|
||||
m_CurProgress = value;
|
||||
CheckCompletionStatus();
|
||||
}
|
||||
}
|
||||
|
||||
public bool HasCompleted{ get; set; }
|
||||
|
||||
public virtual bool Completed => m_CurProgress >= MaxProgress;
|
||||
|
||||
public bool IsSingleObjective => MaxProgress == 1;
|
||||
|
||||
public virtual void BaseDeserialize(GenericReader reader)
|
||||
{
|
||||
int version = reader.ReadEncodedInt();
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
HasBeenRead = reader.ReadBool();
|
||||
goto case 0;
|
||||
}
|
||||
case 0:
|
||||
{
|
||||
m_CurProgress = reader.ReadEncodedInt();
|
||||
HasCompleted = reader.ReadBool();
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ChildDeserialize(reader);
|
||||
}
|
||||
|
||||
public virtual void ChildDeserialize(GenericReader reader)
|
||||
{
|
||||
int version = reader.ReadEncodedInt();
|
||||
}
|
||||
|
||||
public virtual void BaseSerialize(GenericWriter writer)
|
||||
{
|
||||
writer.WriteEncodedInt(1); // version
|
||||
|
||||
writer.Write(HasBeenRead);
|
||||
writer.WriteEncodedInt(m_CurProgress);
|
||||
writer.Write(HasCompleted);
|
||||
|
||||
ChildSerialize(writer);
|
||||
}
|
||||
|
||||
public virtual void ChildSerialize(GenericWriter writer)
|
||||
{
|
||||
writer.WriteEncodedInt(0); // version
|
||||
}
|
||||
|
||||
public virtual void Complete()
|
||||
{
|
||||
CurProgress = MaxProgress;
|
||||
}
|
||||
|
||||
public virtual void RenderMessage(BaseQuestGump gump)
|
||||
{
|
||||
gump.AddHtmlObject(70, 130, 300, 100, Message, BaseQuestGump.Blue, false, false);
|
||||
}
|
||||
|
||||
public virtual void RenderProgress(BaseQuestGump gump)
|
||||
{
|
||||
gump.AddHtmlObject(70, 260, 270, 100, 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); // Quest Log Updated
|
||||
|
||||
AddImageTiled(0, 78, 120, 40, 2624);
|
||||
AddAlphaRegion(0, 78, 120, 40);
|
||||
|
||||
AddButton(30, 15, 5575, 5576, 1);
|
||||
}
|
||||
|
||||
public override void OnResponse(NetState sender, RelayInfo info)
|
||||
{
|
||||
if (info.ButtonID == 1)
|
||||
m_System.ShowQuestLog();
|
||||
}
|
||||
}
|
||||
|
||||
public class QuestObjectivesGump : BaseQuestGump
|
||||
{
|
||||
private List<QuestObjective> m_Objectives;
|
||||
|
||||
public QuestObjectivesGump(QuestObjective obj) : this(new List<QuestObjective>{ obj })
|
||||
{
|
||||
}
|
||||
|
||||
public QuestObjectivesGump(List<QuestObjective> 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); // Quest Log
|
||||
|
||||
AddImage(77, 33, 9781);
|
||||
AddImage(65, 110, 2104);
|
||||
|
||||
AddHtmlLocalized(79, 106, 230, 20, 1049073, Blue); // Objective:
|
||||
|
||||
AddImageTiled(68, 125, 120, 1, 9101);
|
||||
AddImage(65, 240, 2104);
|
||||
|
||||
AddHtmlLocalized(79, 237, 230, 20, 1049076, Blue); // Progress details:
|
||||
|
||||
AddImageTiled(68, 255, 120, 1, 9101);
|
||||
AddButton(175, 355, 2313, 2312, 1);
|
||||
|
||||
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 = 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); // 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); // Next
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnResponse(NetState sender, RelayInfo info)
|
||||
{
|
||||
for (int i = m_Objectives.Count - 1; i >= 0; --i)
|
||||
{
|
||||
QuestObjective obj = m_Objectives[i];
|
||||
|
||||
if (!obj.HasBeenRead)
|
||||
{
|
||||
obj.HasBeenRead = true;
|
||||
obj.OnRead();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
31
Projects/Scripts/Engines/Quests/Core/QuestRestartInfo.cs
Normal file
31
Projects/Scripts/Engines/Quests/Core/QuestRestartInfo.cs
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
using System;
|
||||
|
||||
namespace Server.Engines.Quests
|
||||
{
|
||||
public class QuestRestartInfo
|
||||
{
|
||||
public QuestRestartInfo(Type questType, TimeSpan restartDelay)
|
||||
{
|
||||
QuestType = questType;
|
||||
Reset(restartDelay);
|
||||
}
|
||||
|
||||
public QuestRestartInfo(Type questType, DateTime restartTime)
|
||||
{
|
||||
QuestType = questType;
|
||||
RestartTime = restartTime;
|
||||
}
|
||||
|
||||
public Type QuestType{ get; set; }
|
||||
|
||||
public DateTime RestartTime{ get; set; }
|
||||
|
||||
public void Reset(TimeSpan restartDelay)
|
||||
{
|
||||
if (restartDelay < TimeSpan.MaxValue)
|
||||
RestartTime = DateTime.UtcNow + restartDelay;
|
||||
else
|
||||
RestartTime = DateTime.MaxValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
188
Projects/Scripts/Engines/Quests/Core/QuestSerializer.cs
Normal file
188
Projects/Scripts/Engines/Quests/Core/QuestSerializer.cs
Normal file
|
|
@ -0,0 +1,188 @@
|
|||
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(0x00);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < referenceTable.Length; ++i)
|
||||
if (referenceTable[i] == type)
|
||||
{
|
||||
writer.WriteEncodedInt(0x01);
|
||||
writer.WriteEncodedInt(i);
|
||||
return;
|
||||
}
|
||||
|
||||
writer.WriteEncodedInt(0x02);
|
||||
writer.Write(type.FullName);
|
||||
}
|
||||
}
|
||||
|
||||
public static Type ReadType(Type[] referenceTable, GenericReader reader)
|
||||
{
|
||||
int encoding = reader.ReadEncodedInt();
|
||||
|
||||
switch (encoding)
|
||||
{
|
||||
default:
|
||||
{
|
||||
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:
|
||||
{
|
||||
return null;
|
||||
}
|
||||
case 0x01:
|
||||
{
|
||||
Type type = ReadType(QuestSystem.QuestTypes, reader);
|
||||
|
||||
QuestSystem qs = Construct(type) as QuestSystem;
|
||||
|
||||
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:
|
||||
{
|
||||
return null;
|
||||
}
|
||||
case 0x01:
|
||||
{
|
||||
Type type = ReadType(referenceTable, reader);
|
||||
|
||||
QuestObjective obj = Construct(type) as QuestObjective;
|
||||
|
||||
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:
|
||||
{
|
||||
return null;
|
||||
}
|
||||
case 0x01:
|
||||
{
|
||||
Type type = ReadType(referenceTable, reader);
|
||||
|
||||
QuestConversation conv = Construct(type) as QuestConversation;
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
667
Projects/Scripts/Engines/Quests/Core/QuestSystem.cs
Normal file
667
Projects/Scripts/Engines/Quests/Core/QuestSystem.cs
Normal file
|
|
@ -0,0 +1,667 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Server.ContextMenus;
|
||||
using Server.Engines.Quests.Ambitious;
|
||||
using Server.Engines.Quests.Collector;
|
||||
using Server.Engines.Quests.Doom;
|
||||
using Server.Engines.Quests.Hag;
|
||||
using Server.Engines.Quests.Haven;
|
||||
using Server.Engines.Quests.Matriarch;
|
||||
using Server.Engines.Quests.Naturalist;
|
||||
using Server.Engines.Quests.Necro;
|
||||
using Server.Engines.Quests.Ninja;
|
||||
using Server.Engines.Quests.Samurai;
|
||||
using Server.Engines.Quests.Zento;
|
||||
using Server.Gumps;
|
||||
using Server.Items;
|
||||
using Server.Mobiles;
|
||||
using Server.Network;
|
||||
|
||||
namespace Server.Engines.Quests
|
||||
{
|
||||
public delegate void QuestCallback();
|
||||
|
||||
public abstract class QuestSystem
|
||||
{
|
||||
public static readonly Type[] QuestTypes =
|
||||
{
|
||||
typeof(TheSummoningQuest),
|
||||
typeof(DarkTidesQuest),
|
||||
typeof(UzeraanTurmoilQuest),
|
||||
typeof(CollectorQuest),
|
||||
typeof(WitchApprenticeQuest),
|
||||
typeof(StudyOfSolenQuest),
|
||||
typeof(SolenMatriarchQuest),
|
||||
typeof(AmbitiousQueenQuest),
|
||||
typeof(EminosUndertakingQuest),
|
||||
typeof(HaochisTrialsQuest),
|
||||
typeof(TerribleHatchlingsQuest)
|
||||
};
|
||||
|
||||
private Timer m_Timer;
|
||||
|
||||
public QuestSystem(PlayerMobile from)
|
||||
{
|
||||
From = from;
|
||||
Objectives = new List<QuestObjective>();
|
||||
Conversations = new List<QuestConversation>();
|
||||
}
|
||||
|
||||
public QuestSystem()
|
||||
{
|
||||
}
|
||||
|
||||
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; }
|
||||
|
||||
public PlayerMobile From{ get; set; }
|
||||
|
||||
public List<QuestObjective> Objectives{ get; set; }
|
||||
|
||||
public List<QuestConversation> Conversations{ get; set; }
|
||||
|
||||
public virtual void StartTimer()
|
||||
{
|
||||
if (m_Timer != null)
|
||||
return;
|
||||
|
||||
m_Timer = Timer.DelayCall(TimeSpan.FromSeconds(0.5), TimeSpan.FromSeconds(0.5), Slice);
|
||||
}
|
||||
|
||||
public virtual void StopTimer()
|
||||
{
|
||||
m_Timer?.Stop();
|
||||
|
||||
m_Timer = null;
|
||||
}
|
||||
|
||||
public virtual void Slice()
|
||||
{
|
||||
for (int i = Objectives.Count - 1; i >= 0; --i)
|
||||
{
|
||||
QuestObjective obj = Objectives[i];
|
||||
|
||||
if (obj.GetTimerEvent())
|
||||
obj.CheckProgress();
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void OnKill(BaseCreature creature, Container corpse)
|
||||
{
|
||||
for (int i = Objectives.Count - 1; i >= 0; --i)
|
||||
{
|
||||
QuestObjective obj = Objectives[i];
|
||||
|
||||
if (obj.GetKillEvent(creature, corpse))
|
||||
obj.OnKill(creature, corpse);
|
||||
}
|
||||
}
|
||||
|
||||
public virtual bool IgnoreYoungProtection(Mobile from)
|
||||
{
|
||||
for (int i = Objectives.Count - 1; i >= 0; --i)
|
||||
{
|
||||
QuestObjective obj = Objectives[i];
|
||||
|
||||
if (obj.IgnoreYoungProtection(from))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public virtual void BaseDeserialize(GenericReader reader)
|
||||
{
|
||||
Type[] referenceTable = TypeReferenceTable;
|
||||
|
||||
int version = reader.ReadEncodedInt();
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
int count = reader.ReadEncodedInt();
|
||||
|
||||
Objectives = new List<QuestObjective>(count);
|
||||
|
||||
for (int i = 0; i < count; ++i)
|
||||
{
|
||||
QuestObjective obj = QuestSerializer.DeserializeObjective(referenceTable, reader);
|
||||
|
||||
if (obj != null)
|
||||
{
|
||||
obj.System = this;
|
||||
Objectives.Add(obj);
|
||||
}
|
||||
}
|
||||
|
||||
count = reader.ReadEncodedInt();
|
||||
|
||||
Conversations = new List<QuestConversation>(count);
|
||||
|
||||
for (int i = 0; i < count; ++i)
|
||||
{
|
||||
QuestConversation conv = QuestSerializer.DeserializeConversation(referenceTable, reader);
|
||||
|
||||
if (conv != null)
|
||||
{
|
||||
conv.System = this;
|
||||
Conversations.Add(conv);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ChildDeserialize(reader);
|
||||
}
|
||||
|
||||
public virtual void ChildDeserialize(GenericReader reader)
|
||||
{
|
||||
int version = reader.ReadEncodedInt();
|
||||
}
|
||||
|
||||
public virtual void BaseSerialize(GenericWriter writer)
|
||||
{
|
||||
Type[] referenceTable = TypeReferenceTable;
|
||||
|
||||
writer.WriteEncodedInt(0); // version
|
||||
|
||||
writer.WriteEncodedInt(Objectives.Count);
|
||||
|
||||
for (int i = 0; i < Objectives.Count; ++i)
|
||||
QuestSerializer.Serialize(referenceTable, Objectives[i], writer);
|
||||
|
||||
writer.WriteEncodedInt(Conversations.Count);
|
||||
|
||||
for (int i = 0; i < Conversations.Count; ++i)
|
||||
QuestSerializer.Serialize(referenceTable, Conversations[i], writer);
|
||||
|
||||
ChildSerialize(writer);
|
||||
}
|
||||
|
||||
public virtual void ChildSerialize(GenericWriter writer)
|
||||
{
|
||||
writer.WriteEncodedInt(0); // version
|
||||
}
|
||||
|
||||
public bool IsObjectiveInProgress(Type type)
|
||||
{
|
||||
QuestObjective obj = FindObjective(type);
|
||||
|
||||
return obj?.Completed == false;
|
||||
}
|
||||
|
||||
public T FindObjective<T>() where T : QuestObjective
|
||||
{
|
||||
for (int i = Objectives.Count - 1; i >= 0; --i)
|
||||
{
|
||||
QuestObjective obj = Objectives[i];
|
||||
|
||||
if (obj is T t)
|
||||
return t;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public QuestObjective FindObjective(Type type)
|
||||
{
|
||||
for (int i = Objectives.Count - 1; i >= 0; --i)
|
||||
{
|
||||
QuestObjective obj = Objectives[i];
|
||||
|
||||
if (obj.GetType() == type)
|
||||
return obj;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public virtual void SendOffer()
|
||||
{
|
||||
From.SendGump(new QuestOfferGump(this));
|
||||
}
|
||||
|
||||
public virtual void GetContextMenuEntries(List<ContextMenuEntry> list)
|
||||
{
|
||||
if (Objectives.Count > 0)
|
||||
list.Add(new QuestCallbackEntry(6154, ShowQuestLog)); // View Quest Log
|
||||
|
||||
if (Conversations.Count > 0)
|
||||
list.Add(new QuestCallbackEntry(6156, ShowQuestConversation)); // Quest Conversation
|
||||
|
||||
list.Add(new QuestCallbackEntry(6155, BeginCancelQuest)); // Cancel Quest
|
||||
}
|
||||
|
||||
public virtual void ShowQuestLogUpdated()
|
||||
{
|
||||
From.CloseGump<QuestLogUpdatedGump>();
|
||||
From.SendGump(new QuestLogUpdatedGump(this));
|
||||
}
|
||||
|
||||
public virtual void ShowQuestLog()
|
||||
{
|
||||
if (Objectives.Count > 0)
|
||||
{
|
||||
From.CloseGump<QuestItemInfoGump>();
|
||||
From.CloseGump<QuestLogUpdatedGump>();
|
||||
From.CloseGump<QuestObjectivesGump>();
|
||||
From.CloseGump<QuestConversationsGump>();
|
||||
|
||||
From.SendGump(new QuestObjectivesGump(Objectives));
|
||||
|
||||
QuestObjective last = Objectives[Objectives.Count - 1];
|
||||
|
||||
if (last.Info != null)
|
||||
From.SendGump(new QuestItemInfoGump(last.Info));
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void ShowQuestConversation()
|
||||
{
|
||||
if (Conversations.Count > 0)
|
||||
{
|
||||
From.CloseGump<QuestItemInfoGump>();
|
||||
From.CloseGump<QuestObjectivesGump>();
|
||||
From.CloseGump<QuestConversationsGump>();
|
||||
|
||||
From.SendGump(new QuestConversationsGump(Conversations));
|
||||
|
||||
QuestConversation last = Conversations[Conversations.Count - 1];
|
||||
|
||||
if (last.Info != null)
|
||||
From.SendGump(new QuestItemInfoGump(last.Info));
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void BeginCancelQuest()
|
||||
{
|
||||
From.SendGump(new QuestCancelGump(this));
|
||||
}
|
||||
|
||||
public virtual void EndCancelQuest(bool shouldCancel)
|
||||
{
|
||||
if (From.Quest != this)
|
||||
return;
|
||||
|
||||
if (shouldCancel)
|
||||
{
|
||||
From.SendLocalizedMessage(1049015); // You have canceled your quest.
|
||||
Cancel();
|
||||
}
|
||||
else
|
||||
{
|
||||
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 (From.Quest == this)
|
||||
{
|
||||
From.Quest = null;
|
||||
|
||||
TimeSpan restartDelay = RestartDelay;
|
||||
|
||||
if (completed && restartDelay > TimeSpan.Zero || !completed && restartDelay == TimeSpan.MaxValue)
|
||||
{
|
||||
List<QuestRestartInfo> doneQuests = From.DoneQuests;
|
||||
|
||||
if (doneQuests == null)
|
||||
From.DoneQuests = doneQuests = new List<QuestRestartInfo>();
|
||||
|
||||
bool found = false;
|
||||
|
||||
Type ourQuestType = 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)
|
||||
Conversations.Add(conv);
|
||||
|
||||
From.CloseGump<QuestItemInfoGump>();
|
||||
From.CloseGump<QuestObjectivesGump>();
|
||||
From.CloseGump<QuestConversationsGump>();
|
||||
From.SendGump(conv.Logged ? new QuestConversationsGump(Conversations) : new QuestConversationsGump(conv));
|
||||
|
||||
if (conv.Info != null)
|
||||
From.SendGump(new QuestItemInfoGump(conv.Info));
|
||||
}
|
||||
|
||||
public virtual void AddObjective(QuestObjective obj)
|
||||
{
|
||||
obj.System = this;
|
||||
Objectives.Add(obj);
|
||||
|
||||
ShowQuestLogUpdated();
|
||||
}
|
||||
|
||||
public virtual void Accept()
|
||||
{
|
||||
if (From.Quest != null)
|
||||
return;
|
||||
|
||||
From.Quest = this;
|
||||
From.SendLocalizedMessage(1049019); // You have accepted the Quest.
|
||||
|
||||
StartTimer();
|
||||
}
|
||||
|
||||
public virtual void Decline()
|
||||
{
|
||||
From.SendLocalizedMessage(1049018); // You have declined the Quest.
|
||||
}
|
||||
|
||||
public static bool CanOfferQuest(Mobile check, Type questType)
|
||||
{
|
||||
return CanOfferQuest(check, questType, out _);
|
||||
}
|
||||
|
||||
public static bool CanOfferQuest(Mobile check, Type questType, out bool inRestartPeriod)
|
||||
{
|
||||
inRestartPeriod = false;
|
||||
|
||||
if (!(check is PlayerMobile pm))
|
||||
return false;
|
||||
|
||||
if (pm.HasGump<QuestOfferGump>())
|
||||
return false;
|
||||
|
||||
if (questType == typeof(DarkTidesQuest) && pm.Profession != 4) // necromancer
|
||||
return false;
|
||||
|
||||
if (questType == typeof(UzeraanTurmoilQuest) && pm.Profession != 1 && pm.Profession != 2 && pm.Profession != 5
|
||||
) // warrior / magician / paladin
|
||||
return false;
|
||||
|
||||
if (questType == typeof(HaochisTrialsQuest) && pm.Profession != 6) // samurai
|
||||
return false;
|
||||
|
||||
if (questType == typeof(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); // Confirm Quest Cancellation
|
||||
AddImage(25, 40, 3007);
|
||||
|
||||
if (system.IsTutorial)
|
||||
{
|
||||
AddHtmlLocalized(25, 55, 300, 120, 1060836, White); // 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); // 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); // Can this quest be restarted after quitting?
|
||||
AddImage(25, 141, 0x25E7);
|
||||
AddHtmlLocalized(48, 140, 280, 20, system.RestartDelay < TimeSpan.MaxValue ? 1049016 : 1049017, DarkGreen); // Yes/No
|
||||
}
|
||||
|
||||
AddRadio(25, 175, 9720, 9723, true, 1);
|
||||
AddHtmlLocalized(60, 180, 280, 20, 1049005, White); // Yes, I really want to quit!
|
||||
|
||||
AddRadio(25, 210, 9720, 9723, false, 0);
|
||||
AddHtmlLocalized(60, 215, 280, 20, 1049006, White); // No, I don't want to quit.
|
||||
|
||||
AddButton(265, 220, 247, 248, 1);
|
||||
}
|
||||
|
||||
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); // 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); // I accept!
|
||||
|
||||
AddRadio(85, 385, 9720, 9723, false, 0);
|
||||
AddHtmlLocalized(120, 391, 280, 20, 1049012, White); // No thanks, I decline.
|
||||
|
||||
AddButton(340, 390, 247, 248, 1);
|
||||
|
||||
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 BaseQuestGump(int x, int y) : base(x, y)
|
||||
{
|
||||
}
|
||||
|
||||
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 $"<BASEFONT COLOR=#{color:X6}>{text}</BASEFONT>";
|
||||
}
|
||||
|
||||
public void AddHtmlObject(int x, int y, int width, int height, object message, int color, bool back, bool scroll)
|
||||
{
|
||||
if (message is int html)
|
||||
AddHtmlLocalized(x, y, width, height, html, C16216(color), back, scroll);
|
||||
else
|
||||
AddHtml(x, y, width, height, Color(message.ToString(), C16232(color)), back, scroll);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
using System;
|
||||
using System.Xml;
|
||||
using Server.Mobiles;
|
||||
using Server.Regions;
|
||||
|
||||
namespace Server.Engines.Quests
|
||||
{
|
||||
public class CancelQuestRegion : BaseRegion
|
||||
{
|
||||
private Type m_Quest;
|
||||
|
||||
public CancelQuestRegion(XmlElement xml, Map map, Region parent) : base(xml, map, parent)
|
||||
{
|
||||
ReadType(xml["quest"], "type", ref m_Quest);
|
||||
}
|
||||
|
||||
public Type Quest => 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;
|
||||
|
||||
if (m is PlayerMobile player && player.Quest != null && player.Quest.GetType() == m_Quest)
|
||||
{
|
||||
if (!player.HasGump<QuestCancelGump>())
|
||||
player.Quest.BeginCancelQuest();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
using System;
|
||||
using System.Xml;
|
||||
using Server.Mobiles;
|
||||
using Server.Regions;
|
||||
|
||||
namespace Server.Engines.Quests
|
||||
{
|
||||
public class QuestCompleteObjectiveRegion : BaseRegion
|
||||
{
|
||||
private Type m_Objective;
|
||||
private Type m_Quest;
|
||||
|
||||
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 Type Quest => m_Quest;
|
||||
public Type Objective => m_Objective;
|
||||
|
||||
public override void OnEnter(Mobile m)
|
||||
{
|
||||
base.OnEnter(m);
|
||||
|
||||
if (m_Quest != null && m_Objective != null)
|
||||
if (m is PlayerMobile player && player.Quest != null && player.Quest.GetType() == m_Quest)
|
||||
{
|
||||
QuestObjective obj = player.Quest.FindObjective(m_Objective);
|
||||
|
||||
if (obj?.Completed == false)
|
||||
obj.Complete();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
using System;
|
||||
using System.Xml;
|
||||
using Server.Mobiles;
|
||||
using Server.Regions;
|
||||
|
||||
namespace Server.Engines.Quests
|
||||
{
|
||||
public class QuestNoEntryRegion : BaseRegion
|
||||
{
|
||||
private Type m_MaxObjective;
|
||||
private int m_Message;
|
||||
private Type m_MinObjective;
|
||||
private Type m_Quest;
|
||||
|
||||
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 Type Quest => m_Quest;
|
||||
public Type MinObjective => m_MinObjective;
|
||||
public Type MaxObjective => m_MaxObjective;
|
||||
public int Message => m_Message;
|
||||
|
||||
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 bc && !bc.Controlled && !bc.Summoned)
|
||||
return true;
|
||||
|
||||
if (m_Quest == null)
|
||||
return true;
|
||||
|
||||
if (m is PlayerMobile player && 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;
|
||||
|
||||
if (m_Message != 0)
|
||||
m.SendLocalizedMessage(m_Message);
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
using System;
|
||||
using System.Xml;
|
||||
using Server.Mobiles;
|
||||
using Server.Regions;
|
||||
|
||||
namespace Server.Engines.Quests
|
||||
{
|
||||
public class QuestOfferRegion : BaseRegion
|
||||
{
|
||||
private Type m_Quest;
|
||||
|
||||
public QuestOfferRegion(XmlElement xml, Map map, Region parent) : base(xml, map, parent)
|
||||
{
|
||||
ReadType(xml["quest"], "type", ref m_Quest);
|
||||
}
|
||||
|
||||
public Type Quest => m_Quest;
|
||||
|
||||
public override void OnEnter(Mobile m)
|
||||
{
|
||||
base.OnEnter(m);
|
||||
|
||||
if (m_Quest == null)
|
||||
return;
|
||||
|
||||
if (m is PlayerMobile player && player.Quest == null && QuestSystem.CanOfferQuest(m, m_Quest))
|
||||
try
|
||||
{
|
||||
QuestSystem qs = (QuestSystem)Activator.CreateInstance(m_Quest, player);
|
||||
qs.SendOffer();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine("Error creating quest {0}: {1}", m_Quest, ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
207
Projects/Scripts/Engines/Quests/Dark Tides/Conversations.cs
Normal file
207
Projects/Scripts/Engines/Quests/Dark Tides/Conversations.cs
Normal file
|
|
@ -0,0 +1,207 @@
|
|||
using Server.Items;
|
||||
|
||||
namespace Server.Engines.Quests.Necro
|
||||
{
|
||||
public class AcceptConversation : QuestConversation
|
||||
{
|
||||
public override object Message => 1049092;
|
||||
|
||||
public override void OnRead()
|
||||
{
|
||||
Container bag = BaseQuester.GetNewContainer();
|
||||
|
||||
bag.DropItem(new DarkTidesHorn());
|
||||
|
||||
System.From.AddToBackpack(bag);
|
||||
|
||||
System.AddConversation(new ReanimateMaabusConversation());
|
||||
}
|
||||
}
|
||||
|
||||
public class ReanimateMaabusConversation : QuestConversation
|
||||
{
|
||||
private static QuestItemInfo[] m_Info =
|
||||
{
|
||||
new QuestItemInfo(1026153, 6178), // teleporter
|
||||
new QuestItemInfo(1049117, 4036), // Horn of Retreat
|
||||
new QuestItemInfo(1048032, 3702) // a bag
|
||||
};
|
||||
|
||||
public override object Message => 1060099;
|
||||
|
||||
public override QuestItemInfo[] Info => m_Info;
|
||||
|
||||
public override void OnRead()
|
||||
{
|
||||
System.AddObjective(new FindMaabusTombObjective());
|
||||
}
|
||||
}
|
||||
|
||||
public class MaabasConversation : QuestConversation
|
||||
{
|
||||
private static QuestItemInfo[] m_Info =
|
||||
{
|
||||
new QuestItemInfo(1026153, 6178) // teleporter
|
||||
};
|
||||
|
||||
public override object Message => 1060103;
|
||||
|
||||
public override QuestItemInfo[] Info => m_Info;
|
||||
|
||||
public override void OnRead()
|
||||
{
|
||||
System.AddObjective(new FindCrystalCaveObjective());
|
||||
}
|
||||
}
|
||||
|
||||
public class HorusConversation : QuestConversation
|
||||
{
|
||||
public override object Message => 1060105;
|
||||
|
||||
public override void OnRead()
|
||||
{
|
||||
System.AddObjective(new FindMardothAboutVaultObjective());
|
||||
}
|
||||
}
|
||||
|
||||
public class MardothVaultConversation : QuestConversation
|
||||
{
|
||||
public override object Message => 1060107;
|
||||
|
||||
public override void OnRead()
|
||||
{
|
||||
System.AddObjective(new FindCityOfLightObjective());
|
||||
}
|
||||
}
|
||||
|
||||
public class VaultOfSecretsConversation : QuestConversation
|
||||
{
|
||||
private static QuestItemInfo[] m_Info =
|
||||
{
|
||||
new QuestItemInfo(1023643, 8787) // spellbook
|
||||
};
|
||||
|
||||
public override object Message => 1060110;
|
||||
|
||||
public override QuestItemInfo[] Info => m_Info;
|
||||
|
||||
public override void OnRead()
|
||||
{
|
||||
System.AddObjective(new FetchAbraxusScrollObjective());
|
||||
}
|
||||
}
|
||||
|
||||
public class ReadAbraxusScrollConversation : QuestConversation
|
||||
{
|
||||
public override object Message => 1060114;
|
||||
|
||||
public override void OnRead()
|
||||
{
|
||||
System.AddObjective(new ReadAbraxusScrollObjective());
|
||||
}
|
||||
}
|
||||
|
||||
public class SecondHorusConversation : QuestConversation
|
||||
{
|
||||
public override object Message => 1060118;
|
||||
|
||||
public override void OnRead()
|
||||
{
|
||||
System.AddObjective(new FindCallingScrollObjective());
|
||||
}
|
||||
}
|
||||
|
||||
public class HealConversation : QuestConversation
|
||||
{
|
||||
public override object Message => 1061610;
|
||||
}
|
||||
|
||||
public class HorusRewardConversation : QuestConversation
|
||||
{
|
||||
public override object Message => 1060717;
|
||||
|
||||
public override bool Logged => false;
|
||||
}
|
||||
|
||||
public class LostCallingScrollConversation : QuestConversation
|
||||
{
|
||||
private bool m_FromMardoth;
|
||||
|
||||
public LostCallingScrollConversation(bool fromMardoth)
|
||||
{
|
||||
m_FromMardoth = fromMardoth;
|
||||
}
|
||||
|
||||
// Serialization
|
||||
public LostCallingScrollConversation()
|
||||
{
|
||||
}
|
||||
|
||||
public override object Message
|
||||
{
|
||||
get
|
||||
{
|
||||
if (m_FromMardoth) return 1062058;
|
||||
|
||||
/* 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 => false;
|
||||
|
||||
public override void ChildDeserialize(GenericReader reader)
|
||||
{
|
||||
int version = reader.ReadEncodedInt();
|
||||
|
||||
m_FromMardoth = reader.ReadBool();
|
||||
}
|
||||
|
||||
public override void ChildSerialize(GenericWriter writer)
|
||||
{
|
||||
writer.WriteEncodedInt(0); // version
|
||||
|
||||
writer.Write(m_FromMardoth);
|
||||
}
|
||||
}
|
||||
|
||||
public class MardothKronusConversation : QuestConversation
|
||||
{
|
||||
public override object Message => 1060121;
|
||||
|
||||
public override void OnRead()
|
||||
{
|
||||
System.AddObjective(new FindWellOfTearsObjective());
|
||||
}
|
||||
}
|
||||
|
||||
public class MardothEndConversation : QuestConversation
|
||||
{
|
||||
public override object Message => 1060133;
|
||||
|
||||
public override void OnRead()
|
||||
{
|
||||
System.AddObjective(new FindBankObjective());
|
||||
}
|
||||
}
|
||||
|
||||
public class BankerConversation : QuestConversation
|
||||
{
|
||||
public override object Message => 1060137;
|
||||
|
||||
public override void OnRead()
|
||||
{
|
||||
System.Complete();
|
||||
}
|
||||
}
|
||||
|
||||
public class RadarConversation : QuestConversation
|
||||
{
|
||||
public override object Message => 1061692;
|
||||
|
||||
public override bool Logged => false;
|
||||
}
|
||||
}
|
||||
98
Projects/Scripts/Engines/Quests/Dark Tides/DarkTidesQuest.cs
Normal file
98
Projects/Scripts/Engines/Quests/Dark Tides/DarkTidesQuest.cs
Normal file
|
|
@ -0,0 +1,98 @@
|
|||
using System;
|
||||
using Server.Mobiles;
|
||||
|
||||
namespace Server.Engines.Quests.Necro
|
||||
{
|
||||
public class DarkTidesQuest : QuestSystem
|
||||
{
|
||||
private static Type[] m_TypeReferenceTable =
|
||||
{
|
||||
typeof(AcceptConversation),
|
||||
typeof(AnimateMaabusCorpseObjective),
|
||||
typeof(BankerConversation),
|
||||
typeof(CashBankCheckObjective),
|
||||
typeof(FetchAbraxusScrollObjective),
|
||||
typeof(FindBankObjective),
|
||||
typeof(FindCallingScrollObjective),
|
||||
typeof(FindCityOfLightObjective),
|
||||
typeof(FindCrystalCaveObjective),
|
||||
typeof(FindMaabusCorpseObjective),
|
||||
typeof(FindMaabusTombObjective),
|
||||
typeof(FindMardothAboutKronusObjective),
|
||||
typeof(FindMardothAboutVaultObjective),
|
||||
typeof(FindMardothEndObjective),
|
||||
typeof(FindVaultOfSecretsObjective),
|
||||
typeof(FindWellOfTearsObjective),
|
||||
typeof(HorusConversation),
|
||||
typeof(LostCallingScrollConversation),
|
||||
typeof(MaabasConversation),
|
||||
typeof(MardothEndConversation),
|
||||
typeof(MardothKronusConversation),
|
||||
typeof(MardothVaultConversation),
|
||||
typeof(RadarConversation),
|
||||
typeof(ReadAbraxusScrollConversation),
|
||||
typeof(ReadAbraxusScrollObjective),
|
||||
typeof(ReanimateMaabusConversation),
|
||||
typeof(RetrieveAbraxusScrollObjective),
|
||||
typeof(ReturnToCrystalCaveObjective),
|
||||
typeof(SecondHorusConversation),
|
||||
typeof(SpeakCavePasswordObjective),
|
||||
typeof(UseCallingScrollObjective),
|
||||
typeof(VaultOfSecretsConversation),
|
||||
typeof(FindHorusAboutRewardObjective),
|
||||
typeof(HealConversation),
|
||||
typeof(HorusRewardConversation)
|
||||
};
|
||||
|
||||
public DarkTidesQuest(PlayerMobile from) : base(from)
|
||||
{
|
||||
}
|
||||
|
||||
// Serialization
|
||||
public DarkTidesQuest()
|
||||
{
|
||||
}
|
||||
|
||||
public override Type[] TypeReferenceTable => m_TypeReferenceTable;
|
||||
|
||||
public override object Name => 1060095;
|
||||
|
||||
public override object OfferMessage => 1060094;
|
||||
|
||||
public override TimeSpan RestartDelay => TimeSpan.MaxValue;
|
||||
public override bool IsTutorial => true;
|
||||
|
||||
public override int Picture => 0x15B5;
|
||||
|
||||
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)
|
||||
{
|
||||
if (!(from is PlayerMobile pm))
|
||||
return false;
|
||||
|
||||
QuestSystem qs = pm.Quest;
|
||||
|
||||
if (qs is DarkTidesQuest)
|
||||
if (qs.IsObjectiveInProgress(typeof(FindMardothAboutKronusObjective)) ||
|
||||
qs.IsObjectiveInProgress(typeof(FindWellOfTearsObjective)) ||
|
||||
qs.IsObjectiveInProgress(typeof(UseCallingScrollObjective)))
|
||||
return from.Backpack?.FindItemByType<KronusScroll>() == null;
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
using Server.Mobiles;
|
||||
|
||||
namespace Server.Engines.Quests.Necro
|
||||
{
|
||||
public class CrystalCaveBarrier : Item
|
||||
{
|
||||
[Constructible]
|
||||
public CrystalCaveBarrier() : base(0x3967)
|
||||
{
|
||||
Movable = false;
|
||||
}
|
||||
|
||||
public CrystalCaveBarrier(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override bool OnMoveOver(Mobile m)
|
||||
{
|
||||
if (m.AccessLevel > AccessLevel.Player)
|
||||
return true;
|
||||
|
||||
Mobile mob = m;
|
||||
|
||||
if (m is BaseCreature creature)
|
||||
mob = creature.ControlMaster;
|
||||
|
||||
if (!(mob is PlayerMobile pm))
|
||||
return false;
|
||||
|
||||
QuestSystem qs = pm.Quest;
|
||||
|
||||
if (qs is DarkTidesQuest)
|
||||
{
|
||||
QuestObjective obj = qs.FindObjective<SpeakCavePasswordObjective>();
|
||||
|
||||
if (obj?.Completed == true)
|
||||
{
|
||||
m.SendLocalizedMessage(
|
||||
1060648); // With Horus' permission, you are able to pass through the barrier.
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
m.SendLocalizedMessage(1060649, "",
|
||||
0x66D); // Without the permission of the guardian Horus, the magic of the barrier prevents your passage.
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
using Server.Mobiles;
|
||||
|
||||
namespace Server.Engines.Quests.Necro
|
||||
{
|
||||
public class DarkTidesHorn : HornOfRetreat
|
||||
{
|
||||
[Constructible]
|
||||
public DarkTidesHorn()
|
||||
{
|
||||
DestLoc = new Point3D(2103, 1319, -68);
|
||||
DestMap = Map.Malas;
|
||||
}
|
||||
|
||||
public DarkTidesHorn(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override bool ValidateUse(Mobile from)
|
||||
{
|
||||
return from is PlayerMobile pm && pm.Quest is DarkTidesQuest;
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,76 @@
|
|||
using Server.Mobiles;
|
||||
|
||||
namespace Server.Engines.Quests.Necro
|
||||
{
|
||||
public class DarkTidesTeleporter : DynamicTeleporter
|
||||
{
|
||||
[Constructible]
|
||||
public DarkTidesTeleporter()
|
||||
{
|
||||
}
|
||||
|
||||
public DarkTidesTeleporter(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
if (qs.IsObjectiveInProgress(typeof(FindCrystalCaveObjective)))
|
||||
{
|
||||
loc = new Point3D(1194, 521, -90);
|
||||
map = Map.Malas;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (qs.IsObjectiveInProgress(typeof(FindCityOfLightObjective)))
|
||||
{
|
||||
loc = new Point3D(1091, 519, -90);
|
||||
map = Map.Malas;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (qs.IsObjectiveInProgress(typeof(ReturnToCrystalCaveObjective)))
|
||||
{
|
||||
loc = new Point3D(1194, 521, -90);
|
||||
map = Map.Malas;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (DarkTidesQuest.HasLostCallingScroll(player))
|
||||
{
|
||||
loc = new Point3D(1194, 521, -90);
|
||||
map = Map.Malas;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
166
Projects/Scripts/Engines/Quests/Dark Tides/Items/KronusScroll.cs
Normal file
166
Projects/Scripts/Engines/Quests/Dark Tides/Items/KronusScroll.cs
Normal file
|
|
@ -0,0 +1,166 @@
|
|||
using System;
|
||||
using Server.Items;
|
||||
using Server.Mobiles;
|
||||
using Server.Network;
|
||||
|
||||
namespace Server.Engines.Quests.Necro
|
||||
{
|
||||
public class KronusScroll : QuestItem
|
||||
{
|
||||
private static readonly Rectangle2D m_WellOfTearsArea = new Rectangle2D(2080, 1346, 10, 10);
|
||||
private static readonly Map m_WellOfTearsMap = Map.Malas;
|
||||
|
||||
[Constructible]
|
||||
public KronusScroll() : base(0x227A)
|
||||
{
|
||||
Weight = 1.0;
|
||||
Hue = 0x44E;
|
||||
}
|
||||
|
||||
public KronusScroll(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override int LabelNumber => 1060149; // Calling of Kronus
|
||||
|
||||
public override bool CanDrop(PlayerMobile player)
|
||||
{
|
||||
return !(player.Quest is DarkTidesQuest);
|
||||
|
||||
/*return !( qs.IsObjectiveInProgress( typeof( FindCallingScrollObjective ) )
|
||||
|| qs.IsObjectiveInProgress( typeof( FindMardothAboutKronusObjective ) )
|
||||
|| qs.IsObjectiveInProgress( typeof( FindWellOfTearsObjective ) )
|
||||
|| qs.IsObjectiveInProgress( typeof( UseCallingScrollObjective ) ) );*/
|
||||
}
|
||||
|
||||
public override void OnDoubleClick(Mobile from)
|
||||
{
|
||||
if (!IsChildOf(from))
|
||||
return;
|
||||
|
||||
if (from is PlayerMobile pm)
|
||||
{
|
||||
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<UseCallingScrollObjective>();
|
||||
|
||||
if (obj?.Completed == false)
|
||||
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.
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
|
||||
private class 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 = m_WellOfTearsArea.X;
|
||||
int baseY = m_WellOfTearsArea.Y;
|
||||
int width = m_WellOfTearsArea.Width;
|
||||
int height = m_WellOfTearsArea.Height;
|
||||
Map map = 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++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,74 @@
|
|||
using Server.Items;
|
||||
using Server.Mobiles;
|
||||
|
||||
namespace Server.Engines.Quests.Necro
|
||||
{
|
||||
public class KronusScrollBox : MetalBox
|
||||
{
|
||||
[Constructible]
|
||||
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)
|
||||
{
|
||||
if (from is PlayerMobile pm && pm.InRange(GetWorldLocation(), 2))
|
||||
{
|
||||
QuestSystem qs = pm.Quest;
|
||||
|
||||
if (qs is DarkTidesQuest)
|
||||
{
|
||||
QuestObjective obj = qs.FindObjective<FindCallingScrollObjective>();
|
||||
|
||||
if (obj?.Completed == false || 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?.Completed == false)
|
||||
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(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
154
Projects/Scripts/Engines/Quests/Dark Tides/Items/MaabusCoffin.cs
Normal file
154
Projects/Scripts/Engines/Quests/Dark Tides/Items/MaabusCoffin.cs
Normal file
|
|
@ -0,0 +1,154 @@
|
|||
using System;
|
||||
using Server.Items;
|
||||
|
||||
namespace Server.Engines.Quests.Necro
|
||||
{
|
||||
public class MaabusCoffin : BaseAddon
|
||||
{
|
||||
[Constructible]
|
||||
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 MaabusCoffin(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public Maabus Maabus{ get; private set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public Point3D SpawnLocation{ get; set; }
|
||||
|
||||
public void Awake(Mobile caller)
|
||||
{
|
||||
if (Maabus != null || SpawnLocation == Point3D.Zero)
|
||||
return;
|
||||
|
||||
foreach (AddonComponent c in Components)
|
||||
(c as MaabusCoffinComponent)?.TurnToEmpty();
|
||||
|
||||
Maabus = new Maabus { Location = SpawnLocation, Map = Map };
|
||||
Maabus.Direction = Maabus.GetDirectionTo(caller);
|
||||
|
||||
Timer.DelayCall(TimeSpan.FromSeconds(7.5), BeginSleep);
|
||||
}
|
||||
|
||||
public void BeginSleep()
|
||||
{
|
||||
if (Maabus == null)
|
||||
return;
|
||||
|
||||
Effects.PlaySound(Maabus.Location, Maabus.Map, 0x48E);
|
||||
|
||||
Timer.DelayCall(TimeSpan.FromSeconds(2.5), Sleep);
|
||||
}
|
||||
|
||||
public void Sleep()
|
||||
{
|
||||
if (Maabus == null)
|
||||
return;
|
||||
|
||||
Effects.SendLocationParticles(EffectItem.Create(Maabus.Location, Maabus.Map, EffectItem.DefaultDuration), 0x3728,
|
||||
10, 10, 0x7E7);
|
||||
Effects.PlaySound(Maabus.Location, Maabus.Map, 0x1FE);
|
||||
|
||||
Maabus.Delete();
|
||||
Maabus = null;
|
||||
|
||||
foreach (MaabusCoffinComponent c in Components)
|
||||
c.TurnToFull();
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
|
||||
writer.Write(Maabus);
|
||||
writer.Write(SpawnLocation);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
|
||||
Maabus = reader.ReadMobile() as Maabus;
|
||||
SpawnLocation = reader.ReadPoint3D();
|
||||
|
||||
Sleep();
|
||||
}
|
||||
}
|
||||
|
||||
public class MaabusCoffinComponent : AddonComponent
|
||||
{
|
||||
private int m_EmptyItemID;
|
||||
private int m_FullItemID;
|
||||
|
||||
public MaabusCoffinComponent(int itemID) : this(itemID, itemID)
|
||||
{
|
||||
}
|
||||
|
||||
public MaabusCoffinComponent(int fullItemID, int emptyItemID) : base(fullItemID)
|
||||
{
|
||||
m_FullItemID = fullItemID;
|
||||
m_EmptyItemID = emptyItemID;
|
||||
}
|
||||
|
||||
public MaabusCoffinComponent(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public Point3D SpawnLocation
|
||||
{
|
||||
get => Addon is MaabusCoffin coffin ? coffin.SpawnLocation : Point3D.Zero;
|
||||
set
|
||||
{
|
||||
if (Addon is MaabusCoffin coffin) coffin.SpawnLocation = value;
|
||||
}
|
||||
}
|
||||
|
||||
public void TurnToEmpty()
|
||||
{
|
||||
ItemID = m_EmptyItemID;
|
||||
}
|
||||
|
||||
public void TurnToFull()
|
||||
{
|
||||
ItemID = m_FullItemID;
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
|
||||
writer.Write(m_FullItemID);
|
||||
writer.Write(m_EmptyItemID);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
|
||||
m_FullItemID = reader.ReadInt();
|
||||
m_EmptyItemID = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,133 @@
|
|||
using Server.Gumps;
|
||||
using Server.Mobiles;
|
||||
|
||||
namespace Server.Engines.Quests.Necro
|
||||
{
|
||||
public class ScrollOfAbraxus : QuestItem
|
||||
{
|
||||
[Constructible]
|
||||
public ScrollOfAbraxus() : base(0x227B)
|
||||
{
|
||||
Weight = 1.0;
|
||||
}
|
||||
|
||||
public ScrollOfAbraxus(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override int LabelNumber => 1028827; // Scroll of Abraxus
|
||||
|
||||
public override bool CanDrop(PlayerMobile player)
|
||||
{
|
||||
return !(player.Quest is DarkTidesQuest);
|
||||
|
||||
//return !( qs.IsObjectiveInProgress( typeof( RetrieveAbraxusScrollObjective ) ) || qs.IsObjectiveInProgress( typeof( ReadAbraxusScrollObjective ) ) );
|
||||
}
|
||||
|
||||
public override void OnAdded(IEntity parent)
|
||||
{
|
||||
base.OnAdded(parent);
|
||||
|
||||
if (RootParent is PlayerMobile pm)
|
||||
{
|
||||
QuestSystem qs = pm.Quest;
|
||||
|
||||
if (qs is DarkTidesQuest)
|
||||
{
|
||||
QuestObjective obj = qs.FindObjective<RetrieveAbraxusScrollObjective>();
|
||||
|
||||
if (obj?.Completed == false)
|
||||
obj.Complete();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnDoubleClick(Mobile from)
|
||||
{
|
||||
if (IsChildOf(from.Backpack))
|
||||
{
|
||||
from.SendGump(new ScrollOfAbraxusGump());
|
||||
|
||||
if (from is PlayerMobile pm)
|
||||
{
|
||||
QuestSystem qs = pm.Quest;
|
||||
|
||||
if (qs is DarkTidesQuest)
|
||||
{
|
||||
QuestObjective obj = qs.FindObjective<ReadAbraxusScrollObjective>();
|
||||
|
||||
if (obj?.Completed == false)
|
||||
obj.Complete();
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
from.SendLocalizedMessage(1042001); // That must be in your pack for you to use it.
|
||||
}
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
|
||||
public 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 <EFBFBD> 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
using Server.Mobiles;
|
||||
|
||||
namespace Server.Engines.Quests.Necro
|
||||
{
|
||||
public class VaultOfSecretsBarrier : Item
|
||||
{
|
||||
[Constructible]
|
||||
public VaultOfSecretsBarrier() : base(0x49E)
|
||||
{
|
||||
Movable = false;
|
||||
Visible = false;
|
||||
}
|
||||
|
||||
public VaultOfSecretsBarrier(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override bool OnMoveOver(Mobile m)
|
||||
{
|
||||
if (m.AccessLevel > AccessLevel.Player)
|
||||
return true;
|
||||
|
||||
if (m is PlayerMobile pm && pm.Profession == 4)
|
||||
{
|
||||
m.SendLocalizedMessage(1060188, "", 0x24); // The wicked may not enter!
|
||||
return false;
|
||||
}
|
||||
|
||||
return base.OnMoveOver(m);
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
191
Projects/Scripts/Engines/Quests/Dark Tides/Mobiles/Horus.cs
Normal file
191
Projects/Scripts/Engines/Quests/Dark Tides/Mobiles/Horus.cs
Normal file
|
|
@ -0,0 +1,191 @@
|
|||
using System.Collections.Generic;
|
||||
using Server.ContextMenus;
|
||||
using Server.Items;
|
||||
using Server.Mobiles;
|
||||
using Server.Network;
|
||||
|
||||
namespace Server.Engines.Quests.Necro
|
||||
{
|
||||
public class Horus : BaseQuester
|
||||
{
|
||||
[Constructible]
|
||||
public Horus() : base("the Guardian")
|
||||
{
|
||||
}
|
||||
|
||||
public Horus(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override string DefaultName => "Horus";
|
||||
|
||||
public override void InitBody()
|
||||
{
|
||||
InitStats(100, 100, 25);
|
||||
|
||||
Hue = 0x83F3;
|
||||
Body = 0x190;
|
||||
}
|
||||
|
||||
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<FindCrystalCaveObjective>();
|
||||
|
||||
if (obj?.Completed == false)
|
||||
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 pm)
|
||||
{
|
||||
QuestSystem qs = pm.Quest;
|
||||
|
||||
if (qs is DarkTidesQuest)
|
||||
{
|
||||
QuestObjective obj = qs.FindObjective<ReturnToCrystalCaveObjective>();
|
||||
|
||||
if (obj?.Completed == false)
|
||||
{
|
||||
obj.Complete();
|
||||
}
|
||||
else
|
||||
{
|
||||
obj = qs.FindObjective<FindHorusAboutRewardObjective>();
|
||||
|
||||
if (obj?.Completed == false)
|
||||
{
|
||||
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)
|
||||
if (from is PlayerMobile pm)
|
||||
{
|
||||
QuestSystem qs = pm.Quest;
|
||||
|
||||
if (qs is DarkTidesQuest)
|
||||
{
|
||||
QuestObjective obj = qs.FindObjective<SpeakCavePasswordObjective>();
|
||||
bool enabled = obj?.Completed == false;
|
||||
|
||||
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<SpeakCavePasswordObjective>();
|
||||
|
||||
if (obj?.Completed == false)
|
||||
{
|
||||
obj.Complete();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
from.SendLocalizedMessage(1060185); // Horus ignores you.
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
|
||||
private class SpeakPasswordEntry : ContextMenuEntry
|
||||
{
|
||||
private PlayerMobile m_From;
|
||||
private Horus m_Horus;
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
45
Projects/Scripts/Engines/Quests/Dark Tides/Mobiles/Maabus.cs
Normal file
45
Projects/Scripts/Engines/Quests/Dark Tides/Mobiles/Maabus.cs
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
using Server.Mobiles;
|
||||
|
||||
namespace Server.Engines.Quests.Necro
|
||||
{
|
||||
public class Maabus : BaseQuester
|
||||
{
|
||||
public Maabus()
|
||||
{
|
||||
}
|
||||
|
||||
public Maabus(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override string DefaultName => "Maabus";
|
||||
|
||||
public override void InitBody()
|
||||
{
|
||||
Body = 0x94;
|
||||
}
|
||||
|
||||
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(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
219
Projects/Scripts/Engines/Quests/Dark Tides/Mobiles/Mardoth.cs
Normal file
219
Projects/Scripts/Engines/Quests/Dark Tides/Mobiles/Mardoth.cs
Normal file
|
|
@ -0,0 +1,219 @@
|
|||
using Server.Gumps;
|
||||
using Server.Items;
|
||||
using Server.Mobiles;
|
||||
|
||||
namespace Server.Engines.Quests.Necro
|
||||
{
|
||||
public class Mardoth : BaseQuester
|
||||
{
|
||||
[Constructible]
|
||||
public Mardoth() : base("the Ancient Necromancer")
|
||||
{
|
||||
}
|
||||
|
||||
public Mardoth(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override string DefaultName => "Mardoth";
|
||||
|
||||
public override void InitBody()
|
||||
{
|
||||
InitStats(100, 100, 25);
|
||||
|
||||
Hue = 0x8849;
|
||||
Body = 0x190;
|
||||
}
|
||||
|
||||
public override bool OnDragDrop(Mobile from, Item dropped)
|
||||
{
|
||||
if (from is PlayerMobile player)
|
||||
{
|
||||
QuestSystem qs = player.Quest;
|
||||
|
||||
if (qs is DarkTidesQuest)
|
||||
if (dropped is DarkTidesHorn horn)
|
||||
{
|
||||
if (player.Young)
|
||||
{
|
||||
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)
|
||||
{
|
||||
if (!(to.Quest is DarkTidesQuest qs))
|
||||
return to.Quest == null && QuestSystem.CanOfferQuest(to, typeof(DarkTidesQuest));
|
||||
|
||||
return qs.FindObjective<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<FindMardothAboutVaultObjective>();
|
||||
|
||||
if (obj?.Completed == false)
|
||||
{
|
||||
obj.Complete();
|
||||
}
|
||||
else
|
||||
{
|
||||
obj = qs.FindObjective<FindMardothAboutKronusObjective>();
|
||||
|
||||
if (obj?.Completed == false)
|
||||
{
|
||||
obj.Complete();
|
||||
}
|
||||
else
|
||||
{
|
||||
obj = qs.FindObjective<FindMardothEndObjective>();
|
||||
|
||||
if (obj?.Completed == false)
|
||||
{
|
||||
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)RandomMinMaxScaled(2, 4);
|
||||
weapon.AccuracyLevel = (WeaponAccuracyLevel)RandomMinMaxScaled(2, 4);
|
||||
weapon.DurabilityLevel = (WeaponDurabilityLevel)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<ResurrectGump>();
|
||||
m.SendGump(new ResurrectGump(m, ResurrectMessage.Healer));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,243 @@
|
|||
using System;
|
||||
using Server.Items;
|
||||
using Server.Mobiles;
|
||||
|
||||
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 SummonedPaladin(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override bool ClickTitle => false;
|
||||
|
||||
public override bool PlayerRangeSensitive => false;
|
||||
|
||||
public override bool IsHarmfulCriminal(Mobile target)
|
||||
{
|
||||
if (target == m_Necromancer)
|
||||
return false;
|
||||
|
||||
return base.IsHarmfulCriminal(target);
|
||||
}
|
||||
|
||||
public override void OnThink()
|
||||
{
|
||||
if (!m_ToDelete && !Frozen)
|
||||
{
|
||||
if (m_Necromancer?.Deleted != false || 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<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), 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<FindMardothEndObjective>() == null)
|
||||
qs.AddObjective(new FindMardothEndObjective(true));
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
|
||||
writer.Write(m_Necromancer);
|
||||
writer.Write(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 SummonedPaladin m_Paladin;
|
||||
private PlayerMobile m_Player;
|
||||
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), Delete);
|
||||
}
|
||||
|
||||
public SummonedPaladinMoongate(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
|
||||
Delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
379
Projects/Scripts/Engines/Quests/Dark Tides/Objectives.cs
Normal file
379
Projects/Scripts/Engines/Quests/Dark Tides/Objectives.cs
Normal file
|
|
@ -0,0 +1,379 @@
|
|||
using Server.Items;
|
||||
using Server.Mobiles;
|
||||
using Server.Spells.Necromancy;
|
||||
|
||||
namespace Server.Engines.Quests.Necro
|
||||
{
|
||||
public class AnimateMaabusCorpseObjective : QuestObjective
|
||||
{
|
||||
private static QuestItemInfo[] m_Info =
|
||||
{
|
||||
new QuestItemInfo(1023643, 8787) // spellbook
|
||||
};
|
||||
|
||||
public override object Message => 1060102;
|
||||
|
||||
public override QuestItemInfo[] Info => m_Info;
|
||||
|
||||
public override void OnComplete()
|
||||
{
|
||||
System.AddConversation(new MaabasConversation());
|
||||
}
|
||||
}
|
||||
|
||||
public class FindCrystalCaveObjective : QuestObjective
|
||||
{
|
||||
public override object Message => 1060104;
|
||||
|
||||
public override void OnComplete()
|
||||
{
|
||||
System.AddConversation(new HorusConversation());
|
||||
}
|
||||
}
|
||||
|
||||
public class FindMardothAboutVaultObjective : QuestObjective
|
||||
{
|
||||
public override object Message => 1060106;
|
||||
|
||||
public override void OnComplete()
|
||||
{
|
||||
System.AddConversation(new MardothVaultConversation());
|
||||
}
|
||||
}
|
||||
|
||||
public class FindMaabusTombObjective : QuestObjective
|
||||
{
|
||||
public override object Message => 1060124;
|
||||
|
||||
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 => 1061142;
|
||||
|
||||
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 => 1060108;
|
||||
|
||||
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
|
||||
{
|
||||
private static QuestItemInfo[] m_Info =
|
||||
{
|
||||
new QuestItemInfo(1023676, 3679) // glowing rune
|
||||
};
|
||||
|
||||
public override object Message => 1060109;
|
||||
|
||||
public override QuestItemInfo[] Info => m_Info;
|
||||
|
||||
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 => 1060196;
|
||||
|
||||
public override void CheckProgress()
|
||||
{
|
||||
if (System.From.Map != Map.Malas || !System.From.InRange(new Point3D(1076, 450, -84), 5) ||
|
||||
!SummonFamiliarSpell.Table.TryGetValue(System.From, out BaseCreature bc) || !(bc is HordeMinionFamiliar hmf) ||
|
||||
!hmf.InRange(System.From, 5) || hmf.TargetLocation != null)
|
||||
return;
|
||||
|
||||
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 => 1060199;
|
||||
|
||||
public override void OnComplete()
|
||||
{
|
||||
System.AddConversation(new ReadAbraxusScrollConversation());
|
||||
}
|
||||
}
|
||||
|
||||
public class ReadAbraxusScrollObjective : QuestObjective
|
||||
{
|
||||
public override object Message => 1060125;
|
||||
|
||||
public override void OnComplete()
|
||||
{
|
||||
System.AddObjective(new ReturnToCrystalCaveObjective());
|
||||
}
|
||||
}
|
||||
|
||||
public class ReturnToCrystalCaveObjective : QuestObjective
|
||||
{
|
||||
private static QuestItemInfo[] m_Info =
|
||||
{
|
||||
new QuestItemInfo(1026153, 6178) // teleporter
|
||||
};
|
||||
|
||||
public override object Message => 1060115;
|
||||
|
||||
public override QuestItemInfo[] Info => m_Info;
|
||||
|
||||
public override void OnComplete()
|
||||
{
|
||||
System.AddObjective(new SpeakCavePasswordObjective());
|
||||
}
|
||||
}
|
||||
|
||||
public class SpeakCavePasswordObjective : QuestObjective
|
||||
{
|
||||
public override object Message => 1060117;
|
||||
|
||||
public override void OnComplete()
|
||||
{
|
||||
System.AddConversation(new SecondHorusConversation());
|
||||
}
|
||||
}
|
||||
|
||||
public class FindCallingScrollObjective : QuestObjective
|
||||
{
|
||||
private bool m_HealConversationShown;
|
||||
private bool m_SkitteringHoppersDisposed;
|
||||
|
||||
private int m_SkitteringHoppersKilled;
|
||||
|
||||
public override object Message => 1060119;
|
||||
|
||||
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(0); // version
|
||||
|
||||
writer.WriteEncodedInt(m_SkitteringHoppersKilled);
|
||||
writer.Write(m_HealConversationShown);
|
||||
writer.Write(m_SkitteringHoppersDisposed);
|
||||
}
|
||||
}
|
||||
|
||||
public class FindHorusAboutRewardObjective : QuestObjective
|
||||
{
|
||||
public override object Message => 1060126;
|
||||
|
||||
public override void OnComplete()
|
||||
{
|
||||
System.AddConversation(new HorusRewardConversation());
|
||||
}
|
||||
}
|
||||
|
||||
public class FindMardothAboutKronusObjective : QuestObjective
|
||||
{
|
||||
public override object Message => 1060127;
|
||||
|
||||
public override void OnComplete()
|
||||
{
|
||||
System.AddConversation(new MardothKronusConversation());
|
||||
}
|
||||
}
|
||||
|
||||
public class FindWellOfTearsObjective : QuestObjective
|
||||
{
|
||||
private static readonly Rectangle2D m_WellOfTearsArea = new Rectangle2D(2080, 1346, 10, 10);
|
||||
|
||||
private bool m_Inside;
|
||||
|
||||
public override object Message => 1060128;
|
||||
|
||||
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 => 1060130;
|
||||
}
|
||||
|
||||
public class FindMardothEndObjective : QuestObjective
|
||||
{
|
||||
private bool m_Victory;
|
||||
|
||||
public FindMardothEndObjective(bool victory)
|
||||
{
|
||||
m_Victory = victory;
|
||||
}
|
||||
|
||||
// Serialization
|
||||
public FindMardothEndObjective()
|
||||
{
|
||||
}
|
||||
|
||||
public override object Message
|
||||
{
|
||||
get
|
||||
{
|
||||
if (m_Victory) return 1060131;
|
||||
|
||||
/* Although you were slain by the cowardly paladin,
|
||||
* you managed to complete the rite of calling as
|
||||
* instructed. Return to Mardoth.
|
||||
*/
|
||||
return 1060132;
|
||||
}
|
||||
}
|
||||
|
||||
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(0); // version
|
||||
|
||||
writer.Write(m_Victory);
|
||||
}
|
||||
}
|
||||
|
||||
public class FindBankObjective : QuestObjective
|
||||
{
|
||||
public override object Message => 1060134;
|
||||
|
||||
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 => 1060644;
|
||||
|
||||
public override void OnComplete()
|
||||
{
|
||||
System.AddConversation(new BankerConversation());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,185 @@
|
|||
namespace Server.Engines.Quests.Ninja
|
||||
{
|
||||
public class AcceptConversation : QuestConversation
|
||||
{
|
||||
public override object Message => 1049092;
|
||||
|
||||
public override void OnRead()
|
||||
{
|
||||
System.AddObjective(new FindEminoBeginObjective());
|
||||
}
|
||||
}
|
||||
|
||||
public class FindZoelConversation : QuestConversation
|
||||
{
|
||||
public override object Message => 1063175;
|
||||
|
||||
public override void OnRead()
|
||||
{
|
||||
System.AddObjective(new FindZoelObjective());
|
||||
}
|
||||
}
|
||||
|
||||
public class RadarConversation : QuestConversation
|
||||
{
|
||||
public override object Message => 1063033;
|
||||
|
||||
public override bool Logged => false;
|
||||
}
|
||||
|
||||
public class EnterCaveConversation : QuestConversation
|
||||
{
|
||||
public override object Message => 1063177;
|
||||
|
||||
public override void OnRead()
|
||||
{
|
||||
System.AddObjective(new EnterCaveObjective());
|
||||
}
|
||||
}
|
||||
|
||||
public class SneakPastGuardiansConversation : QuestConversation
|
||||
{
|
||||
public override object Message => 1063180;
|
||||
|
||||
public override void OnRead()
|
||||
{
|
||||
System.AddObjective(new SneakPastGuardiansObjective());
|
||||
}
|
||||
}
|
||||
|
||||
public class NeedToHideConversation : QuestConversation
|
||||
{
|
||||
public override object Message => 1063181;
|
||||
}
|
||||
|
||||
public class UseTeleporterConversation : QuestConversation
|
||||
{
|
||||
public override object Message => 1063182;
|
||||
|
||||
public override void OnRead()
|
||||
{
|
||||
System.AddObjective(new UseTeleporterObjective());
|
||||
}
|
||||
}
|
||||
|
||||
public class GiveZoelNoteConversation : QuestConversation
|
||||
{
|
||||
public override object Message => 1063184;
|
||||
|
||||
public override void OnRead()
|
||||
{
|
||||
System.AddObjective(new GiveZoelNoteObjective());
|
||||
}
|
||||
}
|
||||
|
||||
public class LostNoteConversation : QuestConversation
|
||||
{
|
||||
public override object Message => 1063187;
|
||||
|
||||
public override bool Logged => false;
|
||||
}
|
||||
|
||||
public class GainInnInformationConversation : QuestConversation
|
||||
{
|
||||
public override object Message => 1063189;
|
||||
|
||||
public override void OnRead()
|
||||
{
|
||||
System.AddObjective(new GainInnInformationObjective());
|
||||
}
|
||||
}
|
||||
|
||||
public class ReturnFromInnConversation : QuestConversation
|
||||
{
|
||||
public override object Message => 1063196;
|
||||
|
||||
public override void OnRead()
|
||||
{
|
||||
System.AddObjective(new ReturnFromInnObjective());
|
||||
}
|
||||
}
|
||||
|
||||
public class SearchForSwordConversation : QuestConversation
|
||||
{
|
||||
public override object Message => 1063199;
|
||||
|
||||
public override void OnRead()
|
||||
{
|
||||
System.AddObjective(new SearchForSwordObjective());
|
||||
}
|
||||
}
|
||||
|
||||
public class HallwayWalkConversation : QuestConversation
|
||||
{
|
||||
public override object Message => 1063201;
|
||||
|
||||
public override void OnRead()
|
||||
{
|
||||
System.AddObjective(new HallwayWalkObjective());
|
||||
}
|
||||
}
|
||||
|
||||
public class ReturnSwordConversation : QuestConversation
|
||||
{
|
||||
public override object Message => 1063203;
|
||||
|
||||
public override void OnRead()
|
||||
{
|
||||
System.AddObjective(new ReturnSwordObjective());
|
||||
}
|
||||
}
|
||||
|
||||
public class SlayHenchmenConversation : QuestConversation
|
||||
{
|
||||
public override object Message => 1063205;
|
||||
|
||||
public override void OnRead()
|
||||
{
|
||||
System.AddObjective(new SlayHenchmenObjective());
|
||||
}
|
||||
}
|
||||
|
||||
public class ContinueSlayHenchmenConversation : QuestConversation
|
||||
{
|
||||
public override object Message => 1063208;
|
||||
|
||||
public override bool Logged => false;
|
||||
}
|
||||
|
||||
public class GiveEminoSwordConversation : QuestConversation
|
||||
{
|
||||
public override object Message => 1063211;
|
||||
|
||||
public override void OnRead()
|
||||
{
|
||||
System.AddObjective(new GiveEminoSwordObjective());
|
||||
}
|
||||
}
|
||||
|
||||
public class LostSwordConversation : QuestConversation
|
||||
{
|
||||
public override object Message => 1063212;
|
||||
|
||||
public override bool Logged => false;
|
||||
}
|
||||
|
||||
public class EarnGiftsConversation : QuestConversation
|
||||
{
|
||||
public override object Message => 1063216;
|
||||
|
||||
public override void OnRead()
|
||||
{
|
||||
System.Complete();
|
||||
}
|
||||
}
|
||||
|
||||
public class EarnLessGiftsConversation : QuestConversation
|
||||
{
|
||||
public override object Message => 1063217;
|
||||
|
||||
public override void OnRead()
|
||||
{
|
||||
System.Complete();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,128 @@
|
|||
using System;
|
||||
using Server.Mobiles;
|
||||
|
||||
namespace Server.Engines.Quests.Ninja
|
||||
{
|
||||
public class EminosUndertakingQuest : QuestSystem
|
||||
{
|
||||
private static Type[] m_TypeReferenceTable =
|
||||
{
|
||||
typeof(AcceptConversation),
|
||||
typeof(FindZoelConversation),
|
||||
typeof(RadarConversation),
|
||||
typeof(EnterCaveConversation),
|
||||
typeof(SneakPastGuardiansConversation),
|
||||
typeof(NeedToHideConversation),
|
||||
typeof(UseTeleporterConversation),
|
||||
typeof(GiveZoelNoteConversation),
|
||||
typeof(LostNoteConversation),
|
||||
typeof(GainInnInformationConversation),
|
||||
typeof(ReturnFromInnConversation),
|
||||
typeof(SearchForSwordConversation),
|
||||
typeof(HallwayWalkConversation),
|
||||
typeof(ReturnSwordConversation),
|
||||
typeof(SlayHenchmenConversation),
|
||||
typeof(ContinueSlayHenchmenConversation),
|
||||
typeof(GiveEminoSwordConversation),
|
||||
typeof(LostSwordConversation),
|
||||
typeof(EarnGiftsConversation),
|
||||
typeof(EarnLessGiftsConversation),
|
||||
typeof(FindEminoBeginObjective),
|
||||
typeof(FindZoelObjective),
|
||||
typeof(EnterCaveObjective),
|
||||
typeof(SneakPastGuardiansObjective),
|
||||
typeof(UseTeleporterObjective),
|
||||
typeof(GiveZoelNoteObjective),
|
||||
typeof(GainInnInformationObjective),
|
||||
typeof(ReturnFromInnObjective),
|
||||
typeof(SearchForSwordObjective),
|
||||
typeof(HallwayWalkObjective),
|
||||
typeof(ReturnSwordObjective),
|
||||
typeof(SlayHenchmenObjective),
|
||||
typeof(GiveEminoSwordObjective)
|
||||
};
|
||||
|
||||
private bool m_SentRadarConversion;
|
||||
|
||||
public EminosUndertakingQuest(PlayerMobile from) : base(from)
|
||||
{
|
||||
}
|
||||
|
||||
// Serialization
|
||||
public EminosUndertakingQuest()
|
||||
{
|
||||
}
|
||||
|
||||
public override Type[] TypeReferenceTable => m_TypeReferenceTable;
|
||||
|
||||
public override object Name => 1063173;
|
||||
|
||||
public override object OfferMessage => 1063174;
|
||||
|
||||
public override TimeSpan RestartDelay => TimeSpan.MaxValue;
|
||||
public override bool IsTutorial => true;
|
||||
|
||||
public override int Picture => 0x15D5;
|
||||
|
||||
public override void Accept()
|
||||
{
|
||||
base.Accept();
|
||||
|
||||
AddConversation(new AcceptConversation());
|
||||
}
|
||||
|
||||
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(0); // version
|
||||
|
||||
writer.Write(m_SentRadarConversion);
|
||||
}
|
||||
|
||||
public static bool HasLostNoteForZoel(Mobile from)
|
||||
{
|
||||
if (!(from is PlayerMobile pm))
|
||||
return false;
|
||||
|
||||
QuestSystem qs = pm.Quest;
|
||||
|
||||
if (qs is EminosUndertakingQuest)
|
||||
if (qs.IsObjectiveInProgress(typeof(GiveZoelNoteObjective)))
|
||||
return from.Backpack?.FindItemByType<NoteForZoel>() == null;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static bool HasLostEminosKatana(Mobile from)
|
||||
{
|
||||
if (!(from is PlayerMobile pm))
|
||||
return false;
|
||||
|
||||
QuestSystem qs = pm.Quest;
|
||||
|
||||
if (qs is EminosUndertakingQuest)
|
||||
if (qs.IsObjectiveInProgress(typeof(GiveEminoSwordObjective)))
|
||||
return from.Backpack?.FindItemByType<EminosKatana>() == null;
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
using Server.Mobiles;
|
||||
|
||||
namespace Server.Engines.Quests.Ninja
|
||||
{
|
||||
public class BlueNinjaQuestTeleporter : DynamicTeleporter
|
||||
{
|
||||
[Constructible]
|
||||
public BlueNinjaQuestTeleporter() : base(0x51C, 0x2)
|
||||
{
|
||||
}
|
||||
|
||||
public BlueNinjaQuestTeleporter(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override int LabelNumber => 1026157; // teleporter
|
||||
|
||||
public override int NotWorkingMessage => 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<GainInnInformationObjective>() != null)
|
||||
{
|
||||
loc = new Point3D(411, 1116, 0);
|
||||
map = Map.Malas;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
using Server.Mobiles;
|
||||
|
||||
namespace Server.Engines.Quests.Ninja
|
||||
{
|
||||
public class EminosKatana : QuestItem
|
||||
{
|
||||
[Constructible]
|
||||
public EminosKatana() : base(0x13FF)
|
||||
{
|
||||
Weight = 1.0;
|
||||
}
|
||||
|
||||
public EminosKatana(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override int LabelNumber => 1063214; // Daimyo Emino's Katana
|
||||
|
||||
public override bool CanDrop(PlayerMobile player)
|
||||
{
|
||||
return !(player.Quest is EminosUndertakingQuest);
|
||||
|
||||
/*return !qs.IsObjectiveInProgress( typeof( ReturnSwordObjective ) )
|
||||
&& !qs.IsObjectiveInProgress( typeof( SlayHenchmenObjective ) )
|
||||
&& !qs.IsObjectiveInProgress( typeof( GiveEminoSwordObjective ) );*/
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,142 @@
|
|||
using Server.Items;
|
||||
using Server.Mobiles;
|
||||
using Server.Network;
|
||||
|
||||
namespace Server.Engines.Quests.Ninja
|
||||
{
|
||||
public class EminosKatanaChest : WoodenChest
|
||||
{
|
||||
[Constructible]
|
||||
public EminosKatanaChest()
|
||||
{
|
||||
Movable = false;
|
||||
ItemID = 0xE42;
|
||||
|
||||
GenerateTreasure();
|
||||
}
|
||||
|
||||
public EminosKatanaChest(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override bool IsDecoContainer => false;
|
||||
|
||||
private void GenerateTreasure()
|
||||
{
|
||||
for (int i = Items.Count - 1; i >= 0; i--)
|
||||
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)
|
||||
{
|
||||
if (from is PlayerMobile player && 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<HallwayWalkObjective>();
|
||||
|
||||
if (obj?.Completed == false)
|
||||
{
|
||||
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;
|
||||
|
||||
if (from is PlayerMobile player && player.Quest is EminosUndertakingQuest)
|
||||
{
|
||||
HallwayWalkObjective obj = player.Quest.FindObjective<HallwayWalkObjective>();
|
||||
if (obj?.StolenTreasure == true)
|
||||
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)
|
||||
{
|
||||
if (from is PlayerMobile player && player.Quest is EminosUndertakingQuest)
|
||||
{
|
||||
HallwayWalkObjective obj = player.Quest.FindObjective<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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
using Server.Mobiles;
|
||||
|
||||
namespace Server.Engines.Quests.Ninja
|
||||
{
|
||||
public class GreenNinjaQuestTeleporter : DynamicTeleporter
|
||||
{
|
||||
[Constructible]
|
||||
public GreenNinjaQuestTeleporter() : base(0x51C, 0x17E)
|
||||
{
|
||||
}
|
||||
|
||||
public GreenNinjaQuestTeleporter(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override int LabelNumber => 1026157; // teleporter
|
||||
|
||||
public override int NotWorkingMessage => 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<UseTeleporterObjective>() != null)
|
||||
{
|
||||
loc = new Point3D(410, 1125, 0);
|
||||
map = Map.Malas;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
using Server.Mobiles;
|
||||
|
||||
namespace Server.Engines.Quests.Ninja
|
||||
{
|
||||
public class GuardianBarrier : Item
|
||||
{
|
||||
[Constructible]
|
||||
public GuardianBarrier() : base(0x3967)
|
||||
{
|
||||
Movable = false;
|
||||
Visible = false;
|
||||
}
|
||||
|
||||
public GuardianBarrier(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
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 (Y >= m.Y)
|
||||
return true;
|
||||
|
||||
if (m is BaseCreature creature)
|
||||
{
|
||||
Mobile master = creature.GetMaster();
|
||||
|
||||
// Allow creatures to cross from the south to the north only if their master is near to the north
|
||||
return master != null && Y >= master.Y && master.InRange(this, 4);
|
||||
}
|
||||
|
||||
if (m is PlayerMobile pm && pm.Quest is EminosUndertakingQuest qs)
|
||||
{
|
||||
SneakPastGuardiansObjective obj = qs.FindObjective<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 override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
using Server.Mobiles;
|
||||
|
||||
namespace Server.Engines.Quests.Ninja
|
||||
{
|
||||
public class NoteForZoel : QuestItem
|
||||
{
|
||||
[Constructible]
|
||||
public NoteForZoel() : base(0x14EF)
|
||||
{
|
||||
Weight = 1.0;
|
||||
Hue = 0x6B9;
|
||||
}
|
||||
|
||||
public NoteForZoel(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override int LabelNumber => 1063186; // A Note for Zoel
|
||||
|
||||
public override bool CanDrop(PlayerMobile player)
|
||||
{
|
||||
return !(player.Quest is EminosUndertakingQuest);
|
||||
|
||||
//return !qs.IsObjectiveInProgress( typeof( GiveZoelNoteObjective ) );
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
using Server.Mobiles;
|
||||
|
||||
namespace Server.Engines.Quests.Ninja
|
||||
{
|
||||
public class WhiteNinjaQuestTeleporter : DynamicTeleporter
|
||||
{
|
||||
[Constructible]
|
||||
public WhiteNinjaQuestTeleporter() : base(0x51C, 0x47E)
|
||||
{
|
||||
}
|
||||
|
||||
public WhiteNinjaQuestTeleporter(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override int LabelNumber => 1026157; // teleporter
|
||||
|
||||
public override int NotWorkingMessage => 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<SearchForSwordObjective>();
|
||||
|
||||
if (obj != null)
|
||||
{
|
||||
if (!obj.Completed)
|
||||
obj.Complete();
|
||||
|
||||
loc = new Point3D(411, 1085, 0);
|
||||
map = Map.Malas;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,231 @@
|
|||
using Server.Gumps;
|
||||
using Server.Items;
|
||||
using Server.Mobiles;
|
||||
|
||||
namespace Server.Engines.Quests.Ninja
|
||||
{
|
||||
public class Emino : BaseQuester
|
||||
{
|
||||
[Constructible]
|
||||
public Emino() : base("the Notorious")
|
||||
{
|
||||
}
|
||||
|
||||
public Emino(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override string DefaultName => "Daimyo Emino";
|
||||
|
||||
public override int TalkNumber => -1;
|
||||
|
||||
public override void InitBody()
|
||||
{
|
||||
InitStats(100, 100, 25);
|
||||
|
||||
Hue = 0x83FE;
|
||||
|
||||
Female = false;
|
||||
Body = 0x190;
|
||||
}
|
||||
|
||||
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 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<FindEminoBeginObjective>();
|
||||
|
||||
if (obj?.Completed == false)
|
||||
{
|
||||
obj.Complete();
|
||||
}
|
||||
else
|
||||
{
|
||||
obj = qs.FindObjective<UseTeleporterObjective>();
|
||||
|
||||
if (obj?.Completed == false)
|
||||
{
|
||||
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<ReturnFromInnObjective>();
|
||||
|
||||
if (obj?.Completed == false)
|
||||
{
|
||||
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<GiveEminoSwordObjective>();
|
||||
|
||||
if (obj?.Completed == false)
|
||||
{
|
||||
Item katana = null;
|
||||
|
||||
if (player.Backpack != null)
|
||||
katana = player.Backpack.FindItemByType<EminosKatana>();
|
||||
|
||||
if (katana != null)
|
||||
{
|
||||
bool stolenTreasure = false;
|
||||
|
||||
HallwayWalkObjective walk = qs.FindObjective<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<ResurrectGump>();
|
||||
m.SendGump(new ResurrectGump(m, ResurrectMessage.Healer));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
using Server.Items;
|
||||
using Server.Mobiles;
|
||||
|
||||
namespace Server.Engines.Quests.Ninja
|
||||
{
|
||||
public class EnshroudedFigure : BaseQuester
|
||||
{
|
||||
[Constructible]
|
||||
public EnshroudedFigure()
|
||||
{
|
||||
}
|
||||
|
||||
public EnshroudedFigure(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override string DefaultName => "an enshrouded figure";
|
||||
|
||||
public override int TalkNumber => -1;
|
||||
|
||||
public override void InitBody()
|
||||
{
|
||||
InitStats(100, 100, 25);
|
||||
|
||||
Hue = 0x8401;
|
||||
Female = false;
|
||||
Body = 0x190;
|
||||
}
|
||||
|
||||
public override void InitOutfit()
|
||||
{
|
||||
AddItem(new DeathShroud());
|
||||
AddItem(new ThighBoots());
|
||||
}
|
||||
|
||||
public override void OnTalk(PlayerMobile player, bool contextMenu)
|
||||
{
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
using Server.Items;
|
||||
using Server.Mobiles;
|
||||
|
||||
namespace Server.Engines.Quests.Ninja
|
||||
{
|
||||
public class Henchman : BaseCreature
|
||||
{
|
||||
[Constructible]
|
||||
public Henchman() : base(AIType.AI_Melee, FightMode.Aggressor, 10, 1, 0.2, 0.4)
|
||||
{
|
||||
InitStats(45, 30, 5);
|
||||
|
||||
Hue = Race.Human.RandomSkinHue();
|
||||
Body = 0x190;
|
||||
|
||||
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 Henchman(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override string DefaultName => "a henchman";
|
||||
|
||||
public override bool AlwaysMurderer => 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,92 @@
|
|||
using Server.Items;
|
||||
using Server.Mobiles;
|
||||
using Server.Network;
|
||||
|
||||
namespace Server.Engines.Quests.Ninja
|
||||
{
|
||||
public class HiddenFigure : BaseQuester
|
||||
{
|
||||
public static int[] Messages =
|
||||
{
|
||||
1063191, // They won<6F>t find me here.
|
||||
1063192 // Ah, a quiet hideout.
|
||||
};
|
||||
|
||||
[Constructible]
|
||||
public HiddenFigure()
|
||||
{
|
||||
Message = Utility.RandomList(Messages);
|
||||
}
|
||||
|
||||
public HiddenFigure(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int Message{ get; set; }
|
||||
|
||||
public override int TalkNumber => -1;
|
||||
|
||||
public override void InitBody()
|
||||
{
|
||||
InitStats(100, 100, 25);
|
||||
|
||||
Hue = Race.Human.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 void OnTalk(PlayerMobile player, bool contextMenu)
|
||||
{
|
||||
PrivateOverheadMessage(MessageType.Regular, 0x3B2, Message, player.NetState);
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.WriteEncodedInt(0); // version
|
||||
|
||||
writer.Write(Message);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadEncodedInt();
|
||||
|
||||
Message = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
using Server.Items;
|
||||
using Server.Mobiles;
|
||||
|
||||
namespace Server.Engines.Quests.Ninja
|
||||
{
|
||||
public class JedahEntille : BaseQuester
|
||||
{
|
||||
[Constructible]
|
||||
public JedahEntille() : base("the Silent")
|
||||
{
|
||||
}
|
||||
|
||||
public JedahEntille(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override string DefaultName => "Jedah Entille";
|
||||
|
||||
public override int TalkNumber => -1;
|
||||
|
||||
public override void InitBody()
|
||||
{
|
||||
InitStats(100, 100, 25);
|
||||
|
||||
Hue = 0x83FE;
|
||||
Female = true;
|
||||
Body = 0x191;
|
||||
}
|
||||
|
||||
public override void InitOutfit()
|
||||
{
|
||||
HairItemID = 0x203C;
|
||||
HairHue = 0x6BE;
|
||||
|
||||
AddItem(new PlainDress(0x528));
|
||||
AddItem(new ThighBoots());
|
||||
AddItem(new FloppyHat());
|
||||
}
|
||||
|
||||
public override void OnTalk(PlayerMobile player, bool contextMenu)
|
||||
{
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,132 @@
|
|||
using Server.Gumps;
|
||||
using Server.Items;
|
||||
using Server.Mobiles;
|
||||
|
||||
namespace Server.Engines.Quests.Ninja
|
||||
{
|
||||
public class Zoel : BaseQuester
|
||||
{
|
||||
[Constructible]
|
||||
public Zoel() : base("the Masterful Tactician")
|
||||
{
|
||||
}
|
||||
|
||||
public Zoel(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override string DefaultName => "Elite Ninja Zoel";
|
||||
|
||||
public override int TalkNumber => -1;
|
||||
|
||||
public override void InitBody()
|
||||
{
|
||||
InitStats(100, 100, 25);
|
||||
|
||||
Hue = 0x83FE;
|
||||
|
||||
Female = false;
|
||||
Body = 0x190;
|
||||
}
|
||||
|
||||
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 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<FindZoelObjective>();
|
||||
|
||||
if (obj?.Completed == false)
|
||||
obj.Complete();
|
||||
}
|
||||
}
|
||||
|
||||
public override bool OnDragDrop(Mobile from, Item dropped)
|
||||
{
|
||||
if (from is PlayerMobile player)
|
||||
{
|
||||
QuestSystem qs = player.Quest;
|
||||
|
||||
if (qs is EminosUndertakingQuest)
|
||||
if (dropped is NoteForZoel)
|
||||
{
|
||||
QuestObjective obj = qs.FindObjective<GiveZoelNoteObjective>();
|
||||
|
||||
if (obj?.Completed == false)
|
||||
{
|
||||
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<ResurrectGump>();
|
||||
m.SendGump(new ResurrectGump(m, ResurrectMessage.Healer));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,218 @@
|
|||
using Server.Items;
|
||||
using Server.Mobiles;
|
||||
|
||||
namespace Server.Engines.Quests.Ninja
|
||||
{
|
||||
public class FindEminoBeginObjective : QuestObjective
|
||||
{
|
||||
public override object Message => 1063174;
|
||||
|
||||
public override void OnComplete()
|
||||
{
|
||||
System.AddConversation(new FindZoelConversation());
|
||||
}
|
||||
}
|
||||
|
||||
public class FindZoelObjective : QuestObjective
|
||||
{
|
||||
public override object Message => 1063176;
|
||||
|
||||
public override void OnComplete()
|
||||
{
|
||||
System.AddConversation(new EnterCaveConversation());
|
||||
}
|
||||
}
|
||||
|
||||
public class EnterCaveObjective : QuestObjective
|
||||
{
|
||||
public override object Message => 1063179;
|
||||
|
||||
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
|
||||
{
|
||||
public bool TaughtHowToUseSkills{ get; set; }
|
||||
|
||||
public override object Message => 1063261;
|
||||
|
||||
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();
|
||||
|
||||
TaughtHowToUseSkills = reader.ReadBool();
|
||||
}
|
||||
|
||||
public override void ChildSerialize(GenericWriter writer)
|
||||
{
|
||||
writer.WriteEncodedInt(0); // version
|
||||
|
||||
writer.Write(TaughtHowToUseSkills);
|
||||
}
|
||||
}
|
||||
|
||||
public class UseTeleporterObjective : QuestObjective
|
||||
{
|
||||
public override object Message => 1063183;
|
||||
|
||||
public override void OnComplete()
|
||||
{
|
||||
System.AddConversation(new GiveZoelNoteConversation());
|
||||
}
|
||||
}
|
||||
|
||||
public class GiveZoelNoteObjective : QuestObjective
|
||||
{
|
||||
public override object Message => 1063185;
|
||||
|
||||
public override void OnComplete()
|
||||
{
|
||||
System.AddConversation(new GainInnInformationConversation());
|
||||
}
|
||||
}
|
||||
|
||||
public class GainInnInformationObjective : QuestObjective
|
||||
{
|
||||
public override object Message => 1063190;
|
||||
|
||||
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 => 1063197;
|
||||
|
||||
public override void OnComplete()
|
||||
{
|
||||
System.AddConversation(new SearchForSwordConversation());
|
||||
}
|
||||
}
|
||||
|
||||
public class SearchForSwordObjective : QuestObjective
|
||||
{
|
||||
public override object Message => 1063200;
|
||||
|
||||
public override void OnComplete()
|
||||
{
|
||||
System.AddConversation(new HallwayWalkConversation());
|
||||
}
|
||||
}
|
||||
|
||||
public class HallwayWalkObjective : QuestObjective
|
||||
{
|
||||
public bool StolenTreasure{ get; set; }
|
||||
|
||||
public override object Message => 1063202;
|
||||
|
||||
public override void OnComplete()
|
||||
{
|
||||
System.AddConversation(new ReturnSwordConversation());
|
||||
}
|
||||
|
||||
public override void ChildDeserialize(GenericReader reader)
|
||||
{
|
||||
int version = reader.ReadEncodedInt();
|
||||
|
||||
StolenTreasure = reader.ReadBool();
|
||||
}
|
||||
|
||||
public override void ChildSerialize(GenericWriter writer)
|
||||
{
|
||||
writer.WriteEncodedInt(0); // version
|
||||
|
||||
writer.Write(StolenTreasure);
|
||||
}
|
||||
}
|
||||
|
||||
public class ReturnSwordObjective : QuestObjective
|
||||
{
|
||||
public override object Message => 1063204;
|
||||
|
||||
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 => 1063206;
|
||||
|
||||
public override int MaxProgress => 3;
|
||||
|
||||
public override void RenderProgress(BaseQuestGump gump)
|
||||
{
|
||||
if (!Completed)
|
||||
{
|
||||
// Henchmen killed:
|
||||
gump.AddHtmlLocalized(70, 260, 270, 100, 1063207, BaseQuestGump.Blue);
|
||||
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 => 1063210;
|
||||
|
||||
public override void OnComplete()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
374
Projects/Scripts/Engines/Quests/Haochi's Trials/Conversations.cs
Normal file
374
Projects/Scripts/Engines/Quests/Haochi's Trials/Conversations.cs
Normal file
|
|
@ -0,0 +1,374 @@
|
|||
namespace Server.Engines.Quests.Samurai
|
||||
{
|
||||
public class AcceptConversation : QuestConversation
|
||||
{
|
||||
public override object Message => 1049092;
|
||||
|
||||
public override void OnRead()
|
||||
{
|
||||
System.AddObjective(new FindHaochiObjective());
|
||||
}
|
||||
}
|
||||
|
||||
public class RadarConversation : QuestConversation
|
||||
{
|
||||
public override object Message => 1063033;
|
||||
|
||||
public override bool Logged => false;
|
||||
}
|
||||
|
||||
public class FirstTrialIntroConversation : QuestConversation
|
||||
{
|
||||
public override object Message => 1063029;
|
||||
|
||||
public override void OnRead()
|
||||
{
|
||||
System.AddObjective(new FirstTrialIntroObjective());
|
||||
}
|
||||
}
|
||||
|
||||
public class FirstTrialKillConversation : QuestConversation
|
||||
{
|
||||
public override object Message => 1063031;
|
||||
|
||||
public override void OnRead()
|
||||
{
|
||||
System.AddObjective(new FirstTrialKillObjective());
|
||||
}
|
||||
}
|
||||
|
||||
public class GainKarmaConversation : QuestConversation
|
||||
{
|
||||
private bool m_CursedSoul;
|
||||
|
||||
public GainKarmaConversation(bool cursedSoul)
|
||||
{
|
||||
m_CursedSoul = cursedSoul;
|
||||
}
|
||||
|
||||
public GainKarmaConversation()
|
||||
{
|
||||
}
|
||||
|
||||
public override object Message
|
||||
{
|
||||
get
|
||||
{
|
||||
if (m_CursedSoul) return 1063040;
|
||||
|
||||
// You have just gained some <a href="?ForceTopic45">Karma</a> for killing a Young Ronin.
|
||||
return 1063041;
|
||||
}
|
||||
}
|
||||
|
||||
public override bool Logged => false;
|
||||
|
||||
public override void ChildDeserialize(GenericReader reader)
|
||||
{
|
||||
int version = reader.ReadEncodedInt();
|
||||
|
||||
m_CursedSoul = reader.ReadBool();
|
||||
}
|
||||
|
||||
public override void ChildSerialize(GenericWriter writer)
|
||||
{
|
||||
writer.WriteEncodedInt(0); // version
|
||||
|
||||
writer.Write(m_CursedSoul);
|
||||
}
|
||||
}
|
||||
|
||||
public class SecondTrialIntroConversation : QuestConversation
|
||||
{
|
||||
private bool m_CursedSoul;
|
||||
|
||||
public SecondTrialIntroConversation(bool cursedSoul)
|
||||
{
|
||||
m_CursedSoul = cursedSoul;
|
||||
}
|
||||
|
||||
public SecondTrialIntroConversation()
|
||||
{
|
||||
}
|
||||
|
||||
public override object Message
|
||||
{
|
||||
get
|
||||
{
|
||||
if (m_CursedSoul) return 1063045;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
}
|
||||
|
||||
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(0); // version
|
||||
|
||||
writer.Write(m_CursedSoul);
|
||||
}
|
||||
}
|
||||
|
||||
public class SecondTrialAttackConversation : QuestConversation
|
||||
{
|
||||
public override object Message => 1063057;
|
||||
|
||||
public override void OnRead()
|
||||
{
|
||||
System.AddObjective(new SecondTrialAttackObjective());
|
||||
}
|
||||
}
|
||||
|
||||
public class ThirdTrialIntroConversation : QuestConversation
|
||||
{
|
||||
private bool m_Dragon;
|
||||
|
||||
public ThirdTrialIntroConversation(bool dragon)
|
||||
{
|
||||
m_Dragon = dragon;
|
||||
}
|
||||
|
||||
public ThirdTrialIntroConversation()
|
||||
{
|
||||
}
|
||||
|
||||
public override object Message
|
||||
{
|
||||
get
|
||||
{
|
||||
if (m_Dragon) return 1063060;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
}
|
||||
|
||||
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(0); // version
|
||||
|
||||
writer.Write(m_Dragon);
|
||||
}
|
||||
}
|
||||
|
||||
public class ThirdTrialKillConversation : QuestConversation
|
||||
{
|
||||
public override object Message => 1063062;
|
||||
|
||||
public override void OnRead()
|
||||
{
|
||||
System.AddObjective(new ThirdTrialKillObjective());
|
||||
}
|
||||
}
|
||||
|
||||
public class FourthTrialIntroConversation : QuestConversation
|
||||
{
|
||||
public override object Message => 1063065;
|
||||
|
||||
public override void OnRead()
|
||||
{
|
||||
System.AddObjective(new FourthTrialIntroObjective());
|
||||
}
|
||||
}
|
||||
|
||||
public class FourthTrialCatsConversation : QuestConversation
|
||||
{
|
||||
public override object Message => 1063067;
|
||||
|
||||
public override void OnRead()
|
||||
{
|
||||
System.AddObjective(new FourthTrialCatsObjective());
|
||||
}
|
||||
}
|
||||
|
||||
public class FifthTrialIntroConversation : QuestConversation
|
||||
{
|
||||
private bool m_KilledCat;
|
||||
|
||||
public FifthTrialIntroConversation(bool killedCat)
|
||||
{
|
||||
m_KilledCat = killedCat;
|
||||
}
|
||||
|
||||
public FifthTrialIntroConversation()
|
||||
{
|
||||
}
|
||||
|
||||
public override object Message
|
||||
{
|
||||
get
|
||||
{
|
||||
if (m_KilledCat) return 1063071;
|
||||
|
||||
/* 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<EFBFBD> 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;
|
||||
}
|
||||
}
|
||||
|
||||
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(0); // version
|
||||
|
||||
writer.Write(m_KilledCat);
|
||||
}
|
||||
}
|
||||
|
||||
public class FifthTrialReturnConversation : QuestConversation
|
||||
{
|
||||
public override object Message => 1063248;
|
||||
|
||||
public override void OnRead()
|
||||
{
|
||||
System.AddObjective(new FifthTrialReturnObjective());
|
||||
}
|
||||
}
|
||||
|
||||
public class LostSwordConversation : QuestConversation
|
||||
{
|
||||
public override object Message => 1063074;
|
||||
|
||||
public override bool Logged => false;
|
||||
}
|
||||
|
||||
public class SixthTrialIntroConversation : QuestConversation
|
||||
{
|
||||
private bool m_StolenTreasure;
|
||||
|
||||
public SixthTrialIntroConversation(bool stolenTreasure)
|
||||
{
|
||||
m_StolenTreasure = stolenTreasure;
|
||||
}
|
||||
|
||||
public SixthTrialIntroConversation()
|
||||
{
|
||||
}
|
||||
|
||||
public override object Message
|
||||
{
|
||||
get
|
||||
{
|
||||
if (m_StolenTreasure) return 1063077;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
}
|
||||
|
||||
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(0); // version
|
||||
|
||||
writer.Write(m_StolenTreasure);
|
||||
}
|
||||
}
|
||||
|
||||
public class SeventhTrialIntroConversation : QuestConversation
|
||||
{
|
||||
public override object Message => 1063079;
|
||||
|
||||
public override void OnRead()
|
||||
{
|
||||
System.AddObjective(new SeventhTrialIntroObjective());
|
||||
}
|
||||
}
|
||||
|
||||
public class EndConversation : QuestConversation
|
||||
{
|
||||
public override object Message => 1063125;
|
||||
|
||||
public override void OnRead()
|
||||
{
|
||||
System.Complete();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,117 @@
|
|||
using System;
|
||||
using Server.Mobiles;
|
||||
|
||||
namespace Server.Engines.Quests.Samurai
|
||||
{
|
||||
public class HaochisTrialsQuest : QuestSystem
|
||||
{
|
||||
private static Type[] m_TypeReferenceTable =
|
||||
{
|
||||
typeof(AcceptConversation),
|
||||
typeof(RadarConversation),
|
||||
typeof(FirstTrialIntroConversation),
|
||||
typeof(FirstTrialKillConversation),
|
||||
typeof(GainKarmaConversation),
|
||||
typeof(SecondTrialIntroConversation),
|
||||
typeof(SecondTrialAttackConversation),
|
||||
typeof(ThirdTrialIntroConversation),
|
||||
typeof(ThirdTrialKillConversation),
|
||||
typeof(FourthTrialIntroConversation),
|
||||
typeof(FourthTrialCatsConversation),
|
||||
typeof(FifthTrialIntroConversation),
|
||||
typeof(FifthTrialReturnConversation),
|
||||
typeof(LostSwordConversation),
|
||||
typeof(SixthTrialIntroConversation),
|
||||
typeof(SeventhTrialIntroConversation),
|
||||
typeof(EndConversation),
|
||||
typeof(FindHaochiObjective),
|
||||
typeof(FirstTrialIntroObjective),
|
||||
typeof(FirstTrialKillObjective),
|
||||
typeof(FirstTrialReturnObjective),
|
||||
typeof(SecondTrialIntroObjective),
|
||||
typeof(SecondTrialAttackObjective),
|
||||
typeof(SecondTrialReturnObjective),
|
||||
typeof(ThirdTrialIntroObjective),
|
||||
typeof(ThirdTrialKillObjective),
|
||||
typeof(ThirdTrialReturnObjective),
|
||||
typeof(FourthTrialIntroObjective),
|
||||
typeof(FourthTrialCatsObjective),
|
||||
typeof(FourthTrialReturnObjective),
|
||||
typeof(FifthTrialIntroObjective),
|
||||
typeof(FifthTrialReturnObjective),
|
||||
typeof(SixthTrialIntroObjective),
|
||||
typeof(SixthTrialReturnObjective),
|
||||
typeof(SeventhTrialIntroObjective),
|
||||
typeof(SeventhTrialReturnObjective)
|
||||
};
|
||||
|
||||
private bool m_SentRadarConversion;
|
||||
|
||||
public HaochisTrialsQuest(PlayerMobile from) : base(from)
|
||||
{
|
||||
}
|
||||
|
||||
// Serialization
|
||||
public HaochisTrialsQuest()
|
||||
{
|
||||
}
|
||||
|
||||
public override Type[] TypeReferenceTable => m_TypeReferenceTable;
|
||||
|
||||
public override object Name => 1063022;
|
||||
|
||||
public override object OfferMessage => 1063023;
|
||||
|
||||
public override TimeSpan RestartDelay => TimeSpan.MaxValue;
|
||||
public override bool IsTutorial => true;
|
||||
|
||||
public override int Picture => 0x15D7;
|
||||
|
||||
public override void Accept()
|
||||
{
|
||||
base.Accept();
|
||||
|
||||
AddConversation(new AcceptConversation());
|
||||
}
|
||||
|
||||
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(m_SentRadarConversion);
|
||||
}
|
||||
|
||||
public static bool HasLostHaochisKatana(Mobile from)
|
||||
{
|
||||
if (!(from is PlayerMobile pm))
|
||||
return false;
|
||||
|
||||
QuestSystem qs = pm.Quest;
|
||||
|
||||
if (qs is HaochisTrialsQuest)
|
||||
if (qs.IsObjectiveInProgress(typeof(FifthTrialReturnObjective)))
|
||||
return from.Backpack?.FindItemByType<HaochisKatana>() == null;
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
using Server.Mobiles;
|
||||
|
||||
namespace Server.Engines.Quests.Samurai
|
||||
{
|
||||
public class HaochisKatana : QuestItem
|
||||
{
|
||||
[Constructible]
|
||||
public HaochisKatana() : base(0x13FF)
|
||||
{
|
||||
Weight = 1.0;
|
||||
}
|
||||
|
||||
public HaochisKatana(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override int LabelNumber => 1063165; // Daimyo Haochi's Katana
|
||||
|
||||
public override bool CanDrop(PlayerMobile player)
|
||||
{
|
||||
return !(player.Quest is HaochisTrialsQuest);
|
||||
|
||||
//return !qs.IsObjectiveInProgress( typeof( FifthTrialReturnObjective ) );
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,79 @@
|
|||
using Server.Mobiles;
|
||||
|
||||
namespace Server.Engines.Quests.Samurai
|
||||
{
|
||||
public class HaochisKatanaGenerator : Item
|
||||
{
|
||||
[Constructible]
|
||||
public HaochisKatanaGenerator() : base(0x1B7B)
|
||||
{
|
||||
Visible = false;
|
||||
Movable = false;
|
||||
}
|
||||
|
||||
public HaochisKatanaGenerator(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override string DefaultName => "Haochi's katana generator";
|
||||
|
||||
public override bool OnMoveOver(Mobile m)
|
||||
{
|
||||
if (m is PlayerMobile player)
|
||||
{
|
||||
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<FifthTrialIntroObjective>();
|
||||
|
||||
if (obj?.Completed == false)
|
||||
{
|
||||
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 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,100 @@
|
|||
using System;
|
||||
using Server.Items;
|
||||
using Server.Mobiles;
|
||||
using Server.Network;
|
||||
|
||||
namespace Server.Engines.Quests.Samurai
|
||||
{
|
||||
public class HaochisTreasureChest : WoodenFootLocker
|
||||
{
|
||||
[Constructible]
|
||||
public HaochisTreasureChest()
|
||||
{
|
||||
Movable = false;
|
||||
|
||||
GenerateTreasure();
|
||||
}
|
||||
|
||||
public HaochisTreasureChest(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override bool IsDecoContainer => false;
|
||||
|
||||
private void GenerateTreasure()
|
||||
{
|
||||
for (int i = Items.Count - 1; i >= 0; i--)
|
||||
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;
|
||||
|
||||
if (from is PlayerMobile player && player.Quest is HaochisTrialsQuest)
|
||||
{
|
||||
FifthTrialIntroObjective obj = player.Quest.FindObjective<FifthTrialIntroObjective>();
|
||||
if (obj?.StolenTreasure == true)
|
||||
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)
|
||||
{
|
||||
if (from is PlayerMobile player && player.Quest is HaochisTrialsQuest)
|
||||
{
|
||||
FifthTrialIntroObjective obj = player.Quest.FindObjective<FifthTrialIntroObjective>();
|
||||
if (obj != null)
|
||||
obj.StolenTreasure = true;
|
||||
}
|
||||
|
||||
Timer.DelayCall(TimeSpan.FromMinutes(2.0), 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, GenerateTreasure);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,76 @@
|
|||
using System;
|
||||
using Server.Items;
|
||||
using Server.Mobiles;
|
||||
|
||||
namespace Server.Engines.Quests.Samurai
|
||||
{
|
||||
public class HonorCandle : CandleLong
|
||||
{
|
||||
private static readonly TimeSpan LitDuration = TimeSpan.FromSeconds(20.0);
|
||||
|
||||
[Constructible]
|
||||
public HonorCandle()
|
||||
{
|
||||
Movable = false;
|
||||
Duration = LitDuration;
|
||||
}
|
||||
|
||||
public HonorCandle(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override int LitSound => 0;
|
||||
public override int UnlitSound => 0;
|
||||
|
||||
public override void OnDoubleClick(Mobile from)
|
||||
{
|
||||
bool wasBurning = Burning;
|
||||
|
||||
base.OnDoubleClick(from);
|
||||
|
||||
if (!wasBurning && Burning)
|
||||
{
|
||||
if (!(from is PlayerMobile player))
|
||||
return;
|
||||
|
||||
QuestSystem qs = player.Quest;
|
||||
|
||||
if (qs is HaochisTrialsQuest)
|
||||
{
|
||||
QuestObjective obj = qs.FindObjective<SixthTrialIntroObjective>();
|
||||
|
||||
if (obj?.Completed == false)
|
||||
obj.Complete();
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,90 @@
|
|||
using Server.Items;
|
||||
using Server.Mobiles;
|
||||
|
||||
namespace Server.Engines.Quests.Samurai
|
||||
{
|
||||
public class CursedSoul : BaseCreature
|
||||
{
|
||||
[Constructible]
|
||||
public CursedSoul() : base(AIType.AI_Melee, FightMode.Aggressor, 10, 1, 0.2, 0.4)
|
||||
{
|
||||
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 string CorpseName => "a cursed soul corpse";
|
||||
public override string DefaultName => "a cursed soul";
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,79 @@
|
|||
using Server.Mobiles;
|
||||
|
||||
namespace Server.Engines.Quests.Samurai
|
||||
{
|
||||
public class DeadlyImp : BaseCreature
|
||||
{
|
||||
[Constructible]
|
||||
public DeadlyImp() : base(AIType.AI_Melee, FightMode.Aggressor, 10, 1, 0.2, 0.4)
|
||||
{
|
||||
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 DeadlyImp(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override string DefaultName => "a deadly imp";
|
||||
|
||||
public override void AggressiveAction(Mobile aggressor, bool criminal)
|
||||
{
|
||||
base.AggressiveAction(aggressor, criminal);
|
||||
|
||||
if (aggressor is PlayerMobile player)
|
||||
{
|
||||
QuestSystem qs = player.Quest;
|
||||
if (qs is HaochisTrialsQuest)
|
||||
{
|
||||
QuestObjective obj = qs.FindObjective<SecondTrialAttackObjective>();
|
||||
if (obj?.Completed == false)
|
||||
{
|
||||
obj.Complete();
|
||||
qs.AddObjective(new SecondTrialReturnObjective(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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
using Server.Mobiles;
|
||||
|
||||
namespace Server.Engines.Quests.Samurai
|
||||
{
|
||||
public class DiseasedCat : BaseCreature
|
||||
{
|
||||
[Constructible]
|
||||
public DiseasedCat() : base(AIType.AI_Animal, FightMode.Aggressor, 10, 1, 0.2, 0.4)
|
||||
{
|
||||
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 DiseasedCat(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override string DefaultName => "a diseased cat";
|
||||
|
||||
public override bool AlwaysMurderer => 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,101 @@
|
|||
using Server.Mobiles;
|
||||
|
||||
namespace Server.Engines.Quests.Samurai
|
||||
{
|
||||
public class FierceDragon : BaseCreature
|
||||
{
|
||||
[Constructible]
|
||||
public FierceDragon() : base(AIType.AI_Melee, FightMode.Aggressor, 10, 1, 0.2, 0.4)
|
||||
{
|
||||
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 FierceDragon(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override string DefaultName => "a fierce dragon";
|
||||
|
||||
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);
|
||||
|
||||
if (aggressor is PlayerMobile player)
|
||||
{
|
||||
QuestSystem qs = player.Quest;
|
||||
if (qs is HaochisTrialsQuest)
|
||||
{
|
||||
QuestObjective obj = qs.FindObjective<SecondTrialAttackObjective>();
|
||||
if (obj?.Completed == false)
|
||||
{
|
||||
obj.Complete();
|
||||
qs.AddObjective(new SecondTrialReturnObjective(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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,173 @@
|
|||
using Server.Items;
|
||||
using Server.Mobiles;
|
||||
|
||||
namespace Server.Engines.Quests.Samurai
|
||||
{
|
||||
public class Haochi : BaseQuester
|
||||
{
|
||||
[Constructible]
|
||||
public Haochi() : base("the Honorable Samurai Legend")
|
||||
{
|
||||
}
|
||||
|
||||
public Haochi(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override string DefaultName => "Daimyo Haochi";
|
||||
|
||||
public override int TalkNumber => -1;
|
||||
|
||||
public override void InitBody()
|
||||
{
|
||||
InitStats(100, 100, 25);
|
||||
|
||||
Hue = 0x8403;
|
||||
|
||||
Female = false;
|
||||
Body = 0x190;
|
||||
}
|
||||
|
||||
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 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<FindHaochiObjective>();
|
||||
|
||||
if (obj?.Completed == false)
|
||||
{
|
||||
obj.Complete();
|
||||
return;
|
||||
}
|
||||
|
||||
obj = qs.FindObjective<FirstTrialReturnObjective>();
|
||||
|
||||
if (obj?.Completed == false)
|
||||
{
|
||||
player.AddToBackpack(new LeatherDo());
|
||||
obj.Complete();
|
||||
return;
|
||||
}
|
||||
|
||||
obj = qs.FindObjective<SecondTrialReturnObjective>();
|
||||
|
||||
if (obj?.Completed == false)
|
||||
{
|
||||
if (((SecondTrialReturnObjective)obj).Dragon)
|
||||
player.AddToBackpack(new LeatherSuneate());
|
||||
|
||||
obj.Complete();
|
||||
return;
|
||||
}
|
||||
|
||||
obj = qs.FindObjective<ThirdTrialReturnObjective>();
|
||||
|
||||
if (obj?.Completed == false)
|
||||
{
|
||||
player.AddToBackpack(new LeatherHiroSode());
|
||||
obj.Complete();
|
||||
return;
|
||||
}
|
||||
|
||||
obj = qs.FindObjective<FourthTrialReturnObjective>();
|
||||
|
||||
if (obj?.Completed == false)
|
||||
{
|
||||
if (!((FourthTrialReturnObjective)obj).KilledCat)
|
||||
{
|
||||
Container cont = GetNewContainer();
|
||||
cont.DropItem(new LeatherHiroSode());
|
||||
cont.DropItem(new JinBaori());
|
||||
player.AddToBackpack(cont);
|
||||
}
|
||||
|
||||
obj.Complete();
|
||||
return;
|
||||
}
|
||||
|
||||
obj = qs.FindObjective<FifthTrialReturnObjective>();
|
||||
|
||||
if (obj?.Completed == false)
|
||||
{
|
||||
HaochisKatana katana = player.Backpack?.FindItemByType<HaochisKatana>();
|
||||
if (katana == null)
|
||||
return;
|
||||
|
||||
katana.Delete();
|
||||
obj.Complete();
|
||||
|
||||
obj = qs.FindObjective<FifthTrialIntroObjective>();
|
||||
if (obj != null && ((FifthTrialIntroObjective)obj).StolenTreasure)
|
||||
qs.AddConversation(new SixthTrialIntroConversation(true));
|
||||
else
|
||||
qs.AddConversation(new SixthTrialIntroConversation(false));
|
||||
}
|
||||
|
||||
obj = qs.FindObjective<SixthTrialReturnObjective>();
|
||||
|
||||
if (obj?.Completed == false)
|
||||
{
|
||||
obj.Complete();
|
||||
return;
|
||||
}
|
||||
|
||||
obj = qs.FindObjective<SeventhTrialReturnObjective>();
|
||||
|
||||
if (obj?.Completed == false)
|
||||
{
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,103 @@
|
|||
using Server.Items;
|
||||
using Server.Mobiles;
|
||||
|
||||
namespace Server.Engines.Quests.Samurai
|
||||
{
|
||||
public class HaochisGuardsman : BaseQuester
|
||||
{
|
||||
[Constructible]
|
||||
public HaochisGuardsman() : base("the Guardsman of Daimyo Haochi")
|
||||
{
|
||||
}
|
||||
|
||||
public HaochisGuardsman(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override int TalkNumber => -1;
|
||||
|
||||
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 void OnTalk(PlayerMobile player, bool contextMenu)
|
||||
{
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,59 @@
|
|||
using Server.Mobiles;
|
||||
|
||||
namespace Server.Engines.Quests.Samurai
|
||||
{
|
||||
public class InjuredWolf : BaseCreature
|
||||
{
|
||||
[Constructible]
|
||||
public InjuredWolf() : base(AIType.AI_Animal, FightMode.Aggressor, 10, 1, 0.2, 0.4)
|
||||
{
|
||||
Body = 0xE1;
|
||||
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 InjuredWolf(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override string CorpseName => "an injured wolf corpse";
|
||||
public override string DefaultName => "an injured wolf";
|
||||
|
||||
public override int GetIdleSound()
|
||||
{
|
||||
return 0xE9;
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,88 @@
|
|||
using Server.Items;
|
||||
using Server.Mobiles;
|
||||
|
||||
namespace Server.Engines.Quests.Samurai
|
||||
{
|
||||
public class Relnia : BaseQuester
|
||||
{
|
||||
[Constructible]
|
||||
public Relnia() : base("the Gypsy")
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
public Relnia(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override string DefaultName => "Disheveled Relnia";
|
||||
|
||||
public override int TalkNumber => -1;
|
||||
|
||||
public override void InitBody()
|
||||
{
|
||||
InitStats(100, 100, 25);
|
||||
|
||||
Hue = 0x83FF;
|
||||
|
||||
Female = true;
|
||||
Body = 0x191;
|
||||
}
|
||||
|
||||
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 void OnTalk(PlayerMobile player, bool contextMenu)
|
||||
{
|
||||
}
|
||||
|
||||
public override bool OnDragDrop(Mobile from, Item dropped)
|
||||
{
|
||||
if (from is PlayerMobile player)
|
||||
{
|
||||
QuestSystem qs = player.Quest;
|
||||
|
||||
if (qs is HaochisTrialsQuest)
|
||||
{
|
||||
QuestObjective obj = qs.FindObjective<FourthTrialCatsObjective>();
|
||||
|
||||
if (obj?.Completed == false)
|
||||
if (dropped is Gold gold)
|
||||
{
|
||||
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 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
using Server.Items;
|
||||
using Server.Mobiles;
|
||||
|
||||
namespace Server.Engines.Quests.Samurai
|
||||
{
|
||||
public class YoungNinja : BaseCreature
|
||||
{
|
||||
[Constructible]
|
||||
public YoungNinja() : base(AIType.AI_Melee, FightMode.Aggressor, 10, 1, 0.2, 0.4)
|
||||
{
|
||||
InitStats(45, 30, 5);
|
||||
SetHits(20, 30);
|
||||
|
||||
Hue = Race.Human.RandomSkinHue();
|
||||
Body = 0x190;
|
||||
|
||||
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 YoungNinja(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override string CorpseName => "a young ninja's corpse";
|
||||
public override string DefaultName => "a young ninja";
|
||||
|
||||
public override bool AlwaysMurderer => 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,79 @@
|
|||
using Server.Items;
|
||||
using Server.Mobiles;
|
||||
|
||||
namespace Server.Engines.Quests.Samurai
|
||||
{
|
||||
public class YoungRonin : BaseCreature
|
||||
{
|
||||
[Constructible]
|
||||
public YoungRonin() : base(AIType.AI_Melee, FightMode.Aggressor, 10, 1, 0.2, 0.4)
|
||||
{
|
||||
InitStats(45, 30, 5);
|
||||
SetHits(10, 20);
|
||||
|
||||
Hue = Race.Human.RandomSkinHue();
|
||||
Body = 0x190;
|
||||
|
||||
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 YoungRonin(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override string CorpseName => "a young ronin's corpse";
|
||||
public override string DefaultName => "a young ronin";
|
||||
|
||||
public override bool AlwaysMurderer => 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
342
Projects/Scripts/Engines/Quests/Haochi's Trials/Objectives.cs
Normal file
342
Projects/Scripts/Engines/Quests/Haochi's Trials/Objectives.cs
Normal file
|
|
@ -0,0 +1,342 @@
|
|||
using System;
|
||||
using Server.Items;
|
||||
using Server.Mobiles;
|
||||
|
||||
namespace Server.Engines.Quests.Samurai
|
||||
{
|
||||
public class FindHaochiObjective : QuestObjective
|
||||
{
|
||||
public override object Message => 1063026;
|
||||
|
||||
public override void OnComplete()
|
||||
{
|
||||
System.AddConversation(new FirstTrialIntroConversation());
|
||||
}
|
||||
}
|
||||
|
||||
public class FirstTrialIntroObjective : QuestObjective
|
||||
{
|
||||
public override object Message => 1063030;
|
||||
|
||||
public override void OnComplete()
|
||||
{
|
||||
System.AddConversation(new FirstTrialKillConversation());
|
||||
}
|
||||
}
|
||||
|
||||
public class FirstTrialKillObjective : QuestObjective
|
||||
{
|
||||
private int m_CursedSoulsKilled;
|
||||
private int m_YoungRoninKilled;
|
||||
|
||||
public override object Message => 1063032;
|
||||
|
||||
public override int MaxProgress => 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(0); // version
|
||||
|
||||
writer.WriteEncodedInt(m_CursedSoulsKilled);
|
||||
writer.WriteEncodedInt(m_YoungRoninKilled);
|
||||
}
|
||||
}
|
||||
|
||||
public class FirstTrialReturnObjective : QuestObjective
|
||||
{
|
||||
private bool m_CursedSoul;
|
||||
|
||||
public FirstTrialReturnObjective(bool cursedSoul)
|
||||
{
|
||||
m_CursedSoul = cursedSoul;
|
||||
}
|
||||
|
||||
public FirstTrialReturnObjective()
|
||||
{
|
||||
}
|
||||
|
||||
public override object Message => 1063044;
|
||||
|
||||
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(0); // version
|
||||
|
||||
writer.Write(m_CursedSoul);
|
||||
}
|
||||
}
|
||||
|
||||
public class SecondTrialIntroObjective : QuestObjective
|
||||
{
|
||||
public override object Message => 1063047;
|
||||
|
||||
public override void OnComplete()
|
||||
{
|
||||
System.AddConversation(new SecondTrialAttackConversation());
|
||||
}
|
||||
}
|
||||
|
||||
public class SecondTrialAttackObjective : QuestObjective
|
||||
{
|
||||
public override object Message => 1063058;
|
||||
}
|
||||
|
||||
public class SecondTrialReturnObjective : QuestObjective
|
||||
{
|
||||
public SecondTrialReturnObjective(bool dragon)
|
||||
{
|
||||
Dragon = dragon;
|
||||
}
|
||||
|
||||
public SecondTrialReturnObjective()
|
||||
{
|
||||
}
|
||||
|
||||
public override object Message => 1063229;
|
||||
|
||||
public bool Dragon{ get; private set; }
|
||||
|
||||
public override void OnComplete()
|
||||
{
|
||||
System.AddConversation(new ThirdTrialIntroConversation(Dragon));
|
||||
}
|
||||
|
||||
public override void ChildDeserialize(GenericReader reader)
|
||||
{
|
||||
int version = reader.ReadEncodedInt();
|
||||
|
||||
Dragon = reader.ReadBool();
|
||||
}
|
||||
|
||||
public override void ChildSerialize(GenericWriter writer)
|
||||
{
|
||||
writer.WriteEncodedInt(0); // version
|
||||
|
||||
writer.Write(Dragon);
|
||||
}
|
||||
}
|
||||
|
||||
public class ThirdTrialIntroObjective : QuestObjective
|
||||
{
|
||||
public override object Message => 1063061;
|
||||
|
||||
public override void OnComplete()
|
||||
{
|
||||
System.AddConversation(new ThirdTrialKillConversation());
|
||||
}
|
||||
}
|
||||
|
||||
public class ThirdTrialKillObjective : QuestObjective
|
||||
{
|
||||
public override object Message => 1063063;
|
||||
|
||||
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 => 1063064;
|
||||
|
||||
public override void OnComplete()
|
||||
{
|
||||
System.AddConversation(new FourthTrialIntroConversation());
|
||||
}
|
||||
}
|
||||
|
||||
public class FourthTrialIntroObjective : QuestObjective
|
||||
{
|
||||
public override object Message => 1063066;
|
||||
|
||||
public override void OnComplete()
|
||||
{
|
||||
System.AddConversation(new FourthTrialCatsConversation());
|
||||
}
|
||||
}
|
||||
|
||||
public class FourthTrialCatsObjective : QuestObjective
|
||||
{
|
||||
public override object Message => 1063068;
|
||||
|
||||
public override void OnKill(BaseCreature creature, Container corpse)
|
||||
{
|
||||
if (creature is DiseasedCat)
|
||||
{
|
||||
Complete();
|
||||
System.AddObjective(new FourthTrialReturnObjective(true));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class FourthTrialReturnObjective : QuestObjective
|
||||
{
|
||||
public FourthTrialReturnObjective(bool killedCat)
|
||||
{
|
||||
KilledCat = killedCat;
|
||||
}
|
||||
|
||||
public FourthTrialReturnObjective()
|
||||
{
|
||||
}
|
||||
|
||||
public override object Message => 1063242;
|
||||
|
||||
public bool KilledCat{ get; private set; }
|
||||
|
||||
public override void OnComplete()
|
||||
{
|
||||
System.AddConversation(new FifthTrialIntroConversation(KilledCat));
|
||||
}
|
||||
|
||||
public override void ChildDeserialize(GenericReader reader)
|
||||
{
|
||||
int version = reader.ReadEncodedInt();
|
||||
|
||||
KilledCat = reader.ReadBool();
|
||||
}
|
||||
|
||||
public override void ChildSerialize(GenericWriter writer)
|
||||
{
|
||||
writer.WriteEncodedInt(0); // version
|
||||
|
||||
writer.Write(KilledCat);
|
||||
}
|
||||
}
|
||||
|
||||
public class FifthTrialIntroObjective : QuestObjective
|
||||
{
|
||||
public override object Message => 1063072;
|
||||
|
||||
public bool StolenTreasure{ get; set; }
|
||||
|
||||
public override void OnComplete()
|
||||
{
|
||||
System.AddConversation(new FifthTrialReturnConversation());
|
||||
}
|
||||
|
||||
public override void ChildDeserialize(GenericReader reader)
|
||||
{
|
||||
int version = reader.ReadEncodedInt();
|
||||
|
||||
StolenTreasure = reader.ReadBool();
|
||||
}
|
||||
|
||||
public override void ChildSerialize(GenericWriter writer)
|
||||
{
|
||||
writer.WriteEncodedInt(0); // version
|
||||
|
||||
writer.Write(StolenTreasure);
|
||||
}
|
||||
}
|
||||
|
||||
public class FifthTrialReturnObjective : QuestObjective
|
||||
{
|
||||
public override object Message => 1063073;
|
||||
}
|
||||
|
||||
public class SixthTrialIntroObjective : QuestObjective
|
||||
{
|
||||
public override object Message => 1063078;
|
||||
|
||||
public override void OnComplete()
|
||||
{
|
||||
System.AddObjective(new SixthTrialReturnObjective());
|
||||
}
|
||||
}
|
||||
|
||||
public class SixthTrialReturnObjective : QuestObjective
|
||||
{
|
||||
public override object Message => 1063252;
|
||||
|
||||
public override void OnComplete()
|
||||
{
|
||||
System.AddConversation(new SeventhTrialIntroConversation());
|
||||
}
|
||||
}
|
||||
|
||||
public class SeventhTrialIntroObjective : QuestObjective
|
||||
{
|
||||
public override object Message => 1063080;
|
||||
|
||||
public override int MaxProgress => 3;
|
||||
|
||||
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 => 1063253;
|
||||
|
||||
public override void OnComplete()
|
||||
{
|
||||
System.AddConversation(new EndConversation());
|
||||
}
|
||||
}
|
||||
}
|
||||
183
Projects/Scripts/Engines/Quests/Solen Matriarch/Conversations.cs
Normal file
183
Projects/Scripts/Engines/Quests/Solen Matriarch/Conversations.cs
Normal file
|
|
@ -0,0 +1,183 @@
|
|||
namespace Server.Engines.Quests.Matriarch
|
||||
{
|
||||
public class DontOfferConversation : QuestConversation
|
||||
{
|
||||
private bool m_Friend;
|
||||
|
||||
public DontOfferConversation(bool friend)
|
||||
{
|
||||
m_Friend = friend;
|
||||
}
|
||||
|
||||
public DontOfferConversation()
|
||||
{
|
||||
}
|
||||
|
||||
public override object Message
|
||||
{
|
||||
get
|
||||
{
|
||||
if (m_Friend) return 1054081;
|
||||
|
||||
/* <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 => false;
|
||||
|
||||
public override void ChildDeserialize(GenericReader reader)
|
||||
{
|
||||
int version = reader.ReadEncodedInt();
|
||||
|
||||
m_Friend = reader.ReadBool();
|
||||
}
|
||||
|
||||
public override void ChildSerialize(GenericWriter writer)
|
||||
{
|
||||
writer.WriteEncodedInt(0); // version
|
||||
|
||||
writer.Write(m_Friend);
|
||||
}
|
||||
}
|
||||
|
||||
public class AcceptConversation : QuestConversation
|
||||
{
|
||||
public override object Message => 1054084;
|
||||
|
||||
public override void OnRead()
|
||||
{
|
||||
System.AddObjective(new KillInfiltratorsObjective());
|
||||
}
|
||||
}
|
||||
|
||||
public class DuringKillInfiltratorsConversation : QuestConversation
|
||||
{
|
||||
public override object Message => 1054089;
|
||||
|
||||
public override bool Logged => false;
|
||||
}
|
||||
|
||||
public class GatherWaterConversation : QuestConversation
|
||||
{
|
||||
public override object Message => 1054091;
|
||||
|
||||
public override void OnRead()
|
||||
{
|
||||
System.AddObjective(new GatherWaterObjective());
|
||||
}
|
||||
}
|
||||
|
||||
public class DuringWaterGatheringConversation : QuestConversation
|
||||
{
|
||||
public override object Message => 1054094;
|
||||
|
||||
public override bool Logged => false;
|
||||
}
|
||||
|
||||
public class ProcessFungiConversation : QuestConversation
|
||||
{
|
||||
private bool m_Friend;
|
||||
|
||||
public ProcessFungiConversation(bool friend)
|
||||
{
|
||||
m_Friend = friend;
|
||||
}
|
||||
|
||||
public ProcessFungiConversation()
|
||||
{
|
||||
}
|
||||
|
||||
public override object Message
|
||||
{
|
||||
get
|
||||
{
|
||||
if (m_Friend) return 1054097;
|
||||
|
||||
/* <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 override void OnRead()
|
||||
{
|
||||
System.AddObjective(new ProcessFungiObjective());
|
||||
}
|
||||
|
||||
public override void ChildDeserialize(GenericReader reader)
|
||||
{
|
||||
int version = reader.ReadEncodedInt();
|
||||
|
||||
m_Friend = reader.ReadBool();
|
||||
}
|
||||
|
||||
public override void ChildSerialize(GenericWriter writer)
|
||||
{
|
||||
writer.WriteEncodedInt(0); // version
|
||||
|
||||
writer.Write(m_Friend);
|
||||
}
|
||||
}
|
||||
|
||||
public class DuringFungiProcessConversation : QuestConversation
|
||||
{
|
||||
public override object Message => 1054099;
|
||||
|
||||
public override bool Logged => false;
|
||||
}
|
||||
|
||||
public class FullBackpackConversation : QuestConversation
|
||||
{
|
||||
private bool m_Logged;
|
||||
|
||||
public FullBackpackConversation(bool logged)
|
||||
{
|
||||
m_Logged = logged;
|
||||
}
|
||||
|
||||
public FullBackpackConversation()
|
||||
{
|
||||
m_Logged = true;
|
||||
}
|
||||
|
||||
public override object Message => 1054102;
|
||||
|
||||
public override bool Logged => m_Logged;
|
||||
|
||||
public override void OnRead()
|
||||
{
|
||||
if (m_Logged)
|
||||
System.AddObjective(new GetRewardObjective());
|
||||
}
|
||||
}
|
||||
|
||||
public class EndConversation : QuestConversation
|
||||
{
|
||||
public override object Message => 1054101;
|
||||
|
||||
public override void OnRead()
|
||||
{
|
||||
System.Complete();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,299 @@
|
|||
using System.Collections.Generic;
|
||||
using Server.ContextMenus;
|
||||
using Server.Engines.Plants;
|
||||
using Server.Items;
|
||||
using Server.Mobiles;
|
||||
using Server.Targeting;
|
||||
|
||||
namespace Server.Engines.Quests.Matriarch
|
||||
{
|
||||
public abstract class BaseSolenMatriarch : BaseQuester
|
||||
{
|
||||
public BaseSolenMatriarch()
|
||||
{
|
||||
Body = 0x328;
|
||||
|
||||
if (!RedSolen)
|
||||
Hue = 0x44E;
|
||||
|
||||
SpeechHue = 0;
|
||||
}
|
||||
|
||||
public BaseSolenMatriarch(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public abstract bool RedSolen{ get; }
|
||||
public override string DefaultName => "the solen matriarch";
|
||||
public override bool DisallowAllMoves => false;
|
||||
|
||||
public override int GetIdleSound()
|
||||
{
|
||||
return 0x10D;
|
||||
}
|
||||
|
||||
public override bool CanTalkTo(PlayerMobile to)
|
||||
{
|
||||
if (SolenMatriarchQuest.IsFriend(to, RedSolen))
|
||||
return true;
|
||||
|
||||
return to.Quest is SolenMatriarchQuest qs && qs.RedSolen == RedSolen;
|
||||
}
|
||||
|
||||
public override void OnTalk(PlayerMobile player, bool contextMenu)
|
||||
{
|
||||
Direction = GetDirectionTo(player);
|
||||
|
||||
if (player.Quest is SolenMatriarchQuest qs && qs.RedSolen == RedSolen)
|
||||
{
|
||||
if (qs.IsObjectiveInProgress(typeof(KillInfiltratorsObjective)))
|
||||
{
|
||||
qs.AddConversation(new DuringKillInfiltratorsConversation());
|
||||
}
|
||||
else
|
||||
{
|
||||
QuestObjective obj = qs.FindObjective<ReturnAfterKillsObjective>();
|
||||
|
||||
if (obj?.Completed == false)
|
||||
{
|
||||
obj.Complete();
|
||||
}
|
||||
else if (qs.IsObjectiveInProgress(typeof(GatherWaterObjective)))
|
||||
{
|
||||
qs.AddConversation(new DuringWaterGatheringConversation());
|
||||
}
|
||||
else
|
||||
{
|
||||
obj = qs.FindObjective<ReturnAfterWaterObjective>();
|
||||
|
||||
if (obj?.Completed == false)
|
||||
{
|
||||
obj.Complete();
|
||||
}
|
||||
else if (qs.IsObjectiveInProgress(typeof(ProcessFungiObjective)))
|
||||
{
|
||||
qs.AddConversation(new DuringFungiProcessConversation());
|
||||
}
|
||||
else
|
||||
{
|
||||
obj = qs.FindObjective<GetRewardObjective>();
|
||||
|
||||
if (obj?.Completed == false)
|
||||
{
|
||||
if (SolenMatriarchQuest.GiveRewardTo(player))
|
||||
obj.Complete();
|
||||
else
|
||||
qs.AddConversation(new FullBackpackConversation(false));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (SolenMatriarchQuest.IsFriend(player, RedSolen))
|
||||
{
|
||||
QuestSystem newQuest = new SolenMatriarchQuest(player, 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)
|
||||
{
|
||||
if (from is PlayerMobile player)
|
||||
{
|
||||
if (dropped is Seed)
|
||||
{
|
||||
if (player.Quest is SolenMatriarchQuest qs && qs.RedSolen == RedSolen)
|
||||
{
|
||||
SayTo(player, 1054080); // Thank you for that plant seed. Those have such wonderful flavor.
|
||||
}
|
||||
else
|
||||
{
|
||||
QuestSystem newQuest = new SolenMatriarchQuest(player, RedSolen);
|
||||
|
||||
if (player.Quest == null && QuestSystem.CanOfferQuest(player, typeof(SolenMatriarchQuest)))
|
||||
newQuest.SendOffer();
|
||||
else
|
||||
newQuest.AddConversation(
|
||||
new DontOfferConversation(SolenMatriarchQuest.IsFriend(player, RedSolen)));
|
||||
}
|
||||
|
||||
dropped.Delete();
|
||||
return true;
|
||||
}
|
||||
|
||||
if (dropped is ZoogiFungus fungus)
|
||||
{
|
||||
OnGivenFungi(player, fungus);
|
||||
|
||||
return fungus.Deleted;
|
||||
}
|
||||
}
|
||||
|
||||
return base.OnDragDrop(from, dropped);
|
||||
}
|
||||
|
||||
public override void GetContextMenuEntries(Mobile from, List<ContextMenuEntry> list)
|
||||
{
|
||||
base.GetContextMenuEntries(from, list);
|
||||
|
||||
if (from.Alive)
|
||||
if (from is PlayerMobile pm)
|
||||
if (pm.Quest is SolenMatriarchQuest qs && qs.RedSolen == RedSolen)
|
||||
if (qs.IsObjectiveInProgress(typeof(ProcessFungiObjective)))
|
||||
list.Add(new ProcessZoogiFungusEntry(this, pm));
|
||||
}
|
||||
|
||||
public void OnGivenFungi(PlayerMobile player, ZoogiFungus fungi)
|
||||
{
|
||||
Direction = GetDirectionTo(player);
|
||||
|
||||
if (player.Quest is SolenMatriarchQuest qs && qs.RedSolen == RedSolen)
|
||||
{
|
||||
QuestObjective obj = qs.FindObjective<ProcessFungiObjective>();
|
||||
|
||||
if (obj?.Completed == false)
|
||||
{
|
||||
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 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();
|
||||
}
|
||||
|
||||
private class ProcessZoogiFungusEntry : ContextMenuEntry
|
||||
{
|
||||
private PlayerMobile m_From;
|
||||
private BaseSolenMatriarch m_Matriarch;
|
||||
|
||||
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 PlayerMobile m_From;
|
||||
private BaseSolenMatriarch m_Matriarch;
|
||||
|
||||
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 fungus)
|
||||
{
|
||||
if (fungus.IsChildOf(m_From.Backpack))
|
||||
m_Matriarch.OnGivenFungi(m_From, fungus);
|
||||
else
|
||||
m_From.SendLocalizedMessage(1042001); // That must be in your pack for you to use it.
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class RedSolenMatriarch : BaseSolenMatriarch
|
||||
{
|
||||
[Constructible]
|
||||
public RedSolenMatriarch()
|
||||
{
|
||||
}
|
||||
|
||||
public RedSolenMatriarch(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override bool RedSolen => 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();
|
||||
}
|
||||
}
|
||||
|
||||
public class BlackSolenMatriarch : BaseSolenMatriarch
|
||||
{
|
||||
[Constructible]
|
||||
public BlackSolenMatriarch()
|
||||
{
|
||||
}
|
||||
|
||||
public BlackSolenMatriarch(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override bool RedSolen => 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
142
Projects/Scripts/Engines/Quests/Solen Matriarch/Objectives.cs
Normal file
142
Projects/Scripts/Engines/Quests/Solen Matriarch/Objectives.cs
Normal file
|
|
@ -0,0 +1,142 @@
|
|||
using Server.Items;
|
||||
using Server.Mobiles;
|
||||
|
||||
namespace Server.Engines.Quests.Matriarch
|
||||
{
|
||||
public class KillInfiltratorsObjective : QuestObjective
|
||||
{
|
||||
public override object Message => ((SolenMatriarchQuest)System).RedSolen ? 1054086 : 1054085;
|
||||
|
||||
public override int MaxProgress => 7;
|
||||
|
||||
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);
|
||||
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;
|
||||
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 => 1054090;
|
||||
|
||||
public override void OnComplete()
|
||||
{
|
||||
System.AddConversation(new GatherWaterConversation());
|
||||
}
|
||||
}
|
||||
|
||||
public class GatherWaterObjective : QuestObjective
|
||||
{
|
||||
public override object Message => 1054092;
|
||||
|
||||
public override int MaxProgress => 40;
|
||||
|
||||
public override void RenderProgress(BaseQuestGump gump)
|
||||
{
|
||||
if (!Completed)
|
||||
{
|
||||
gump.AddHtmlLocalized(70, 260, 270, 100, 1054093, BaseQuestGump.Blue); // 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 => 1054095;
|
||||
|
||||
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 => 1054098;
|
||||
|
||||
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 => 1054149;
|
||||
|
||||
public override void OnComplete()
|
||||
{
|
||||
System.AddConversation(new EndConversation());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,124 @@
|
|||
using System;
|
||||
using Server.Items;
|
||||
using Server.Mobiles;
|
||||
|
||||
namespace Server.Engines.Quests.Matriarch
|
||||
{
|
||||
public class SolenMatriarchQuest : QuestSystem
|
||||
{
|
||||
private static Type[] m_TypeReferenceTable =
|
||||
{
|
||||
typeof(DontOfferConversation),
|
||||
typeof(AcceptConversation),
|
||||
typeof(DuringKillInfiltratorsConversation),
|
||||
typeof(GatherWaterConversation),
|
||||
typeof(DuringWaterGatheringConversation),
|
||||
typeof(ProcessFungiConversation),
|
||||
typeof(DuringFungiProcessConversation),
|
||||
typeof(FullBackpackConversation),
|
||||
typeof(EndConversation),
|
||||
typeof(KillInfiltratorsObjective),
|
||||
typeof(ReturnAfterKillsObjective),
|
||||
typeof(GatherWaterObjective),
|
||||
typeof(ReturnAfterWaterObjective),
|
||||
typeof(ProcessFungiObjective),
|
||||
typeof(GetRewardObjective)
|
||||
};
|
||||
|
||||
public SolenMatriarchQuest(PlayerMobile from, bool redSolen) : base(from)
|
||||
{
|
||||
RedSolen = redSolen;
|
||||
}
|
||||
|
||||
// Serialization
|
||||
public SolenMatriarchQuest()
|
||||
{
|
||||
}
|
||||
|
||||
public override Type[] TypeReferenceTable => m_TypeReferenceTable;
|
||||
|
||||
public override object Name => 1054147;
|
||||
|
||||
public override object OfferMessage
|
||||
{
|
||||
get
|
||||
{
|
||||
if (IsFriend(From, RedSolen)) return 1054083;
|
||||
|
||||
/* <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 => TimeSpan.Zero;
|
||||
public override bool IsTutorial => false;
|
||||
|
||||
public override int Picture => 0x15C9;
|
||||
|
||||
public bool RedSolen{ get; private set; }
|
||||
|
||||
public override void ChildDeserialize(GenericReader reader)
|
||||
{
|
||||
int version = reader.ReadEncodedInt();
|
||||
|
||||
RedSolen = reader.ReadBool();
|
||||
}
|
||||
|
||||
public override void ChildSerialize(GenericWriter writer)
|
||||
{
|
||||
writer.WriteEncodedInt(0); // version
|
||||
|
||||
writer.Write(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;
|
||||
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;
|
||||
}
|
||||
|
||||
gold.Delete();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
namespace Server.Engines.Quests.Naturalist
|
||||
{
|
||||
public class DontOfferConversation : QuestConversation
|
||||
{
|
||||
public override object Message => 1054052;
|
||||
|
||||
public override bool Logged => false;
|
||||
}
|
||||
|
||||
public class AcceptConversation : QuestConversation
|
||||
{
|
||||
public override object Message => 1054043;
|
||||
|
||||
public override void OnRead()
|
||||
{
|
||||
System.AddObjective(new StudyNestsObjective());
|
||||
}
|
||||
}
|
||||
|
||||
public class NaturalistDuringStudyConversation : QuestConversation
|
||||
{
|
||||
public override object Message => 1054049;
|
||||
|
||||
public override bool Logged => false;
|
||||
}
|
||||
|
||||
public class EndConversation : QuestConversation
|
||||
{
|
||||
public override object Message => 1054050;
|
||||
|
||||
public override void OnRead()
|
||||
{
|
||||
System.Complete();
|
||||
}
|
||||
}
|
||||
|
||||
public class SpecialEndConversation : QuestConversation
|
||||
{
|
||||
public override object Message => 1054051;
|
||||
|
||||
public override void OnRead()
|
||||
{
|
||||
System.Complete();
|
||||
}
|
||||
}
|
||||
|
||||
public class FullBackpackConversation : QuestConversation
|
||||
{
|
||||
public override object Message => 1054053;
|
||||
|
||||
public override bool Logged => false;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,191 @@
|
|||
using Server.Engines.Plants;
|
||||
using Server.Items;
|
||||
using Server.Mobiles;
|
||||
|
||||
namespace Server.Engines.Quests.Naturalist
|
||||
{
|
||||
public class Naturalist : BaseQuester
|
||||
{
|
||||
[Constructible]
|
||||
public Naturalist() : base("the Naturalist")
|
||||
{
|
||||
}
|
||||
|
||||
public Naturalist(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void InitBody()
|
||||
{
|
||||
InitStats(100, 100, 25);
|
||||
|
||||
Hue = Race.Human.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)
|
||||
{
|
||||
if (player.Quest is StudyOfSolenQuest qs && qs.Naturalist == this)
|
||||
{
|
||||
StudyNestsObjective study = qs.FindObjective<StudyNestsObjective>();
|
||||
if (study == null)
|
||||
return;
|
||||
|
||||
if (!study.Completed)
|
||||
{
|
||||
PlaySound(0x41F);
|
||||
qs.AddConversation(new NaturalistDuringStudyConversation());
|
||||
return;
|
||||
}
|
||||
|
||||
QuestObjective obj = qs.FindObjective<ReturnToNaturalistObjective>();
|
||||
|
||||
if (obj?.Completed == false)
|
||||
{
|
||||
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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
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 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
using System.Linq;
|
||||
|
||||
namespace Server.Engines.Quests.Naturalist
|
||||
{
|
||||
public class NestArea
|
||||
{
|
||||
private static readonly NestArea[] m_Areas =
|
||||
{
|
||||
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))
|
||||
};
|
||||
|
||||
private Rectangle2D[] m_Rects;
|
||||
|
||||
private NestArea(bool special, params Rectangle2D[] rects)
|
||||
{
|
||||
Special = special;
|
||||
m_Rects = rects;
|
||||
}
|
||||
|
||||
public static int NonSpecialCount => m_Areas.Count(area => !area.Special);
|
||||
|
||||
public bool Special{ get; }
|
||||
|
||||
public int ID
|
||||
{
|
||||
get
|
||||
{
|
||||
for (int i = 0; i < m_Areas.Length; i++)
|
||||
if (m_Areas[i] == this)
|
||||
return i;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public static NestArea Find(IPoint2D p)
|
||||
{
|
||||
return m_Areas.FirstOrDefault(area => area.Contains(p));
|
||||
}
|
||||
|
||||
public static NestArea GetByID(int id)
|
||||
{
|
||||
if (id >= 0 && id < m_Areas.Length)
|
||||
return m_Areas[id];
|
||||
return null;
|
||||
}
|
||||
|
||||
public bool Contains(IPoint2D p)
|
||||
{
|
||||
return m_Rects.Any(rect => rect.Contains(p));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,180 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Server.Mobiles;
|
||||
|
||||
namespace Server.Engines.Quests.Naturalist
|
||||
{
|
||||
public class StudyNestsObjective : QuestObjective
|
||||
{
|
||||
private NestArea m_CurrentNest;
|
||||
|
||||
private List<NestArea> m_StudiedNests = new List<NestArea>();
|
||||
private DateTime m_StudyBegin;
|
||||
private StudyState m_StudyState;
|
||||
|
||||
public override object Message => 1054044;
|
||||
|
||||
public override int MaxProgress => NestArea.NonSpecialCount;
|
||||
|
||||
public bool StudiedSpecialNest{ get; private set; }
|
||||
|
||||
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!
|
||||
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); // 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);
|
||||
}
|
||||
|
||||
StudiedSpecialNest = reader.ReadBool();
|
||||
}
|
||||
|
||||
public override void ChildSerialize(GenericWriter writer)
|
||||
{
|
||||
writer.WriteEncodedInt(0); // version
|
||||
|
||||
writer.WriteEncodedInt(m_StudiedNests.Count);
|
||||
foreach (NestArea nest in m_StudiedNests)
|
||||
writer.WriteEncodedInt(nest.ID);
|
||||
|
||||
writer.Write(StudiedSpecialNest);
|
||||
}
|
||||
|
||||
private enum StudyState
|
||||
{
|
||||
Inactive,
|
||||
FirstStep,
|
||||
SecondStep
|
||||
}
|
||||
}
|
||||
|
||||
public class ReturnToNaturalistObjective : QuestObjective
|
||||
{
|
||||
public override object Message => 1054048;
|
||||
|
||||
public override void RenderProgress(BaseQuestGump gump)
|
||||
{
|
||||
string count = NestArea.NonSpecialCount.ToString();
|
||||
|
||||
gump.AddHtmlLocalized(70, 260, 270, 100, 1054055, BaseQuestGump.Blue); // Solen Nests Studied :
|
||||
gump.AddLabel(70, 280, 0x64, count);
|
||||
gump.AddLabel(100, 280, 0x64, "/");
|
||||
gump.AddLabel(130, 280, 0x64, count);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
using System;
|
||||
using Server.Mobiles;
|
||||
|
||||
namespace Server.Engines.Quests.Naturalist
|
||||
{
|
||||
public class StudyOfSolenQuest : QuestSystem
|
||||
{
|
||||
private static Type[] m_TypeReferenceTable =
|
||||
{
|
||||
typeof(StudyNestsObjective),
|
||||
typeof(ReturnToNaturalistObjective),
|
||||
typeof(DontOfferConversation),
|
||||
typeof(AcceptConversation),
|
||||
typeof(NaturalistDuringStudyConversation),
|
||||
typeof(EndConversation),
|
||||
typeof(SpecialEndConversation),
|
||||
typeof(FullBackpackConversation)
|
||||
};
|
||||
|
||||
public StudyOfSolenQuest(PlayerMobile from, Naturalist naturalist) : base(from)
|
||||
{
|
||||
Naturalist = naturalist;
|
||||
}
|
||||
|
||||
// Serialization
|
||||
public StudyOfSolenQuest()
|
||||
{
|
||||
}
|
||||
|
||||
public override Type[] TypeReferenceTable => m_TypeReferenceTable;
|
||||
|
||||
public override object Name => 1054041;
|
||||
|
||||
public override object OfferMessage => 1054042;
|
||||
|
||||
public override TimeSpan RestartDelay => TimeSpan.Zero;
|
||||
public override bool IsTutorial => false;
|
||||
|
||||
public override int Picture => 0x15C7;
|
||||
|
||||
public Naturalist Naturalist{ get; private set; }
|
||||
|
||||
public override void ChildDeserialize(GenericReader reader)
|
||||
{
|
||||
int version = reader.ReadEncodedInt();
|
||||
|
||||
Naturalist = (Naturalist)reader.ReadMobile();
|
||||
}
|
||||
|
||||
public override void ChildSerialize(GenericWriter writer)
|
||||
{
|
||||
writer.WriteEncodedInt(0); // version
|
||||
|
||||
writer.Write(Naturalist);
|
||||
}
|
||||
|
||||
public override void Accept()
|
||||
{
|
||||
base.Accept();
|
||||
|
||||
Naturalist?.PlaySound(0x431);
|
||||
|
||||
AddConversation(new AcceptConversation());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
namespace Server.Engines.Quests.Zento
|
||||
{
|
||||
public class AcceptConversation : QuestConversation
|
||||
{
|
||||
public override object Message => 1049092;
|
||||
|
||||
public override void OnRead()
|
||||
{
|
||||
System.AddObjective(new FirstKillObjective());
|
||||
}
|
||||
}
|
||||
|
||||
public class DirectionConversation : QuestConversation
|
||||
{
|
||||
public override object Message => 1063323;
|
||||
|
||||
public override bool Logged => false;
|
||||
}
|
||||
|
||||
public class TakeCareConversation : QuestConversation
|
||||
{
|
||||
public override object Message => 1063324;
|
||||
|
||||
public override bool Logged => false;
|
||||
}
|
||||
|
||||
public class EndConversation : QuestConversation
|
||||
{
|
||||
public override object Message => 1063321;
|
||||
|
||||
public override void OnRead()
|
||||
{
|
||||
System.Complete();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,142 @@
|
|||
using Server.Items;
|
||||
using Server.Mobiles;
|
||||
|
||||
namespace Server.Engines.Quests.Zento
|
||||
{
|
||||
public class AnsellaGryen : BaseQuester
|
||||
{
|
||||
[Constructible]
|
||||
public AnsellaGryen()
|
||||
{
|
||||
}
|
||||
|
||||
public AnsellaGryen(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override string DefaultName => "Ansella Gryen";
|
||||
|
||||
public override void InitBody()
|
||||
{
|
||||
InitStats(100, 100, 25);
|
||||
|
||||
Hue = 0x83EA;
|
||||
|
||||
Female = true;
|
||||
Body = 0x191;
|
||||
}
|
||||
|
||||
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;
|
||||
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<ReturnObjective>();
|
||||
|
||||
if (obj?.Completed == false)
|
||||
{
|
||||
Container cont = GetNewContainer();
|
||||
|
||||
cont.DropItem(new Gold(Utility.RandomMinMax(100, 200)));
|
||||
|
||||
if (Utility.RandomBool())
|
||||
{
|
||||
if (Loot.Construct(Loot.SEWeaponTypes) is BaseWeapon weapon)
|
||||
{
|
||||
BaseRunicTool.ApplyAttributesTo(weapon, 3, 10, 30);
|
||||
cont.DropItem(weapon);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Loot.Construct(Loot.SEArmorTypes) is BaseArmor armor)
|
||||
{
|
||||
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);
|
||||
|
||||
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 bool inRestartPeriod))
|
||||
{
|
||||
newQuest.SendOffer();
|
||||
}
|
||||
else if (inRestartPeriod && contextMenu)
|
||||
{
|
||||
SayTo(player, 1049357); // I have nothing more for you at this time.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,132 @@
|
|||
using Server.Items;
|
||||
using Server.Mobiles;
|
||||
|
||||
namespace Server.Engines.Quests.Zento
|
||||
{
|
||||
public class FirstKillObjective : QuestObjective
|
||||
{
|
||||
public override object Message => 1063316;
|
||||
|
||||
public override void RenderProgress(BaseQuestGump gump)
|
||||
{
|
||||
if (!Completed)
|
||||
{
|
||||
// Deathwatch Beetle Hatchlings killed:
|
||||
gump.AddHtmlLocalized(70, 260, 270, 100, 1063318, 0x12DC6BF);
|
||||
|
||||
gump.AddLabel(70, 280, 0x64, "0");
|
||||
gump.AddLabel(100, 280, 0x64, "/");
|
||||
gump.AddLabel(130, 280, 0x64, "10");
|
||||
}
|
||||
else
|
||||
{
|
||||
base.RenderProgress(gump);
|
||||
}
|
||||
}
|
||||
|
||||
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 => 1063320;
|
||||
|
||||
public override void RenderProgress(BaseQuestGump gump)
|
||||
{
|
||||
if (!Completed)
|
||||
{
|
||||
// Deathwatch Beetle Hatchlings killed:
|
||||
gump.AddHtmlLocalized(70, 260, 270, 100, 1063318, 0x12DC6BF);
|
||||
|
||||
gump.AddLabel(70, 280, 0x64, "1");
|
||||
gump.AddLabel(100, 280, 0x64, "/");
|
||||
gump.AddLabel(130, 280, 0x64, "10");
|
||||
}
|
||||
else
|
||||
{
|
||||
base.RenderProgress(gump);
|
||||
}
|
||||
}
|
||||
|
||||
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 ThirdKillObjective(int startingProgress)
|
||||
{
|
||||
CurProgress = startingProgress;
|
||||
}
|
||||
|
||||
public ThirdKillObjective()
|
||||
{
|
||||
}
|
||||
|
||||
public override object Message => 1063319;
|
||||
|
||||
public override int MaxProgress => 10;
|
||||
|
||||
public override void RenderProgress(BaseQuestGump gump)
|
||||
{
|
||||
if (!Completed)
|
||||
{
|
||||
// Deathwatch Beetle Hatchlings killed:
|
||||
gump.AddHtmlLocalized(70, 260, 270, 100, 1063318, 0x12DC6BF);
|
||||
|
||||
gump.AddLabel(70, 280, 0x64, CurProgress.ToString());
|
||||
gump.AddLabel(100, 280, 0x64, "/");
|
||||
gump.AddLabel(130, 280, 0x64, "10");
|
||||
}
|
||||
else
|
||||
{
|
||||
base.RenderProgress(gump);
|
||||
}
|
||||
}
|
||||
|
||||
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 => 1063313;
|
||||
|
||||
public override void OnComplete()
|
||||
{
|
||||
System.AddConversation(new EndConversation());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
using System;
|
||||
using Server.Mobiles;
|
||||
|
||||
namespace Server.Engines.Quests.Zento
|
||||
{
|
||||
public class TerribleHatchlingsQuest : QuestSystem
|
||||
{
|
||||
private static Type[] m_TypeReferenceTable =
|
||||
{
|
||||
typeof(AcceptConversation),
|
||||
typeof(DirectionConversation),
|
||||
typeof(TakeCareConversation),
|
||||
typeof(EndConversation),
|
||||
typeof(FirstKillObjective),
|
||||
typeof(SecondKillObjective),
|
||||
typeof(ThirdKillObjective),
|
||||
typeof(ReturnObjective)
|
||||
};
|
||||
|
||||
public TerribleHatchlingsQuest(PlayerMobile from) : base(from)
|
||||
{
|
||||
}
|
||||
|
||||
// Serialization
|
||||
public TerribleHatchlingsQuest()
|
||||
{
|
||||
}
|
||||
|
||||
public override Type[] TypeReferenceTable => m_TypeReferenceTable;
|
||||
|
||||
public override object Name => 1063314;
|
||||
|
||||
public override object OfferMessage => 1063315;
|
||||
|
||||
public override TimeSpan RestartDelay => TimeSpan.MaxValue;
|
||||
public override bool IsTutorial => true;
|
||||
|
||||
public override int Picture => 0x15CF;
|
||||
|
||||
public override void Accept()
|
||||
{
|
||||
base.Accept();
|
||||
|
||||
AddConversation(new AcceptConversation());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
using Server.Mobiles;
|
||||
|
||||
namespace Server.Engines.Quests.Doom
|
||||
{
|
||||
public class AcceptConversation : QuestConversation
|
||||
{
|
||||
public override object Message => 1050027;
|
||||
|
||||
public override void OnRead()
|
||||
{
|
||||
System.AddObjective(new CollectBonesObjective());
|
||||
}
|
||||
}
|
||||
|
||||
public class VanquishDaemonConversation : QuestConversation
|
||||
{
|
||||
public override object Message => 1050021;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,119 @@
|
|||
using System;
|
||||
using Server.Items;
|
||||
using Server.Mobiles;
|
||||
using Server.Network;
|
||||
|
||||
namespace Server.Engines.Quests.Doom
|
||||
{
|
||||
public class BellOfTheDead : Item
|
||||
{
|
||||
[Constructible]
|
||||
public BellOfTheDead() : base(0x91A)
|
||||
{
|
||||
Hue = 0x835;
|
||||
Movable = false;
|
||||
}
|
||||
|
||||
public BellOfTheDead(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override int LabelNumber => 1050018; // bell of the dead
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster, AccessLevel.Administrator)]
|
||||
public Chyloth Chyloth{ get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster, AccessLevel.Administrator)]
|
||||
public SkeletalDragon Dragon{ get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster, AccessLevel.Administrator)]
|
||||
public bool Summoning{ get; set; }
|
||||
|
||||
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 (Chyloth?.Deleted == false)
|
||||
{
|
||||
from.SendLocalizedMessage(
|
||||
1050010); // The ferry man has already been summoned. There is no need to ring for him again.
|
||||
}
|
||||
else if (Dragon?.Deleted == false)
|
||||
{
|
||||
from.SendLocalizedMessage(
|
||||
1050017); // The ferryman has recently been summoned already. You decide against ringing the bell again so soon.
|
||||
}
|
||||
else if (!Summoning)
|
||||
{
|
||||
Summoning = true;
|
||||
|
||||
Effects.PlaySound(GetWorldLocation(), Map, 0x100);
|
||||
|
||||
Timer.DelayCall(TimeSpan.FromSeconds(8.0), () => EndSummon(from));
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void EndSummon(Mobile from)
|
||||
{
|
||||
if (Chyloth?.Deleted == false)
|
||||
{
|
||||
from.SendLocalizedMessage(
|
||||
1050010); // The ferry man has already been summoned. There is no need to ring for him again.
|
||||
}
|
||||
else if (Dragon?.Deleted == false)
|
||||
{
|
||||
from.SendLocalizedMessage(
|
||||
1050017); // The ferryman has recently been summoned already. You decide against ringing the bell again so soon.
|
||||
}
|
||||
else if (Summoning)
|
||||
{
|
||||
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);
|
||||
|
||||
Chyloth = new Chyloth { Direction = (Direction)(7 & (4 + (int)from.GetDirectionTo(loc))) };
|
||||
|
||||
Chyloth.MoveToWorld(loc, Map);
|
||||
|
||||
Chyloth.Bell = this;
|
||||
Chyloth.AngryAt = from;
|
||||
Chyloth.BeginGiveWarning();
|
||||
Chyloth.BeginRemove(TimeSpan.FromSeconds(40.0));
|
||||
}
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
|
||||
writer.Write(Chyloth);
|
||||
writer.Write(Dragon);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
|
||||
Chyloth = reader.ReadMobile() as Chyloth;
|
||||
Dragon = reader.ReadMobile() as SkeletalDragon;
|
||||
|
||||
Chyloth?.Delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
namespace Server.Engines.Quests.Doom
|
||||
{
|
||||
public class ChylothShroud : Item
|
||||
{
|
||||
[Constructible]
|
||||
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(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
using Server.Items;
|
||||
|
||||
namespace Server.Engines.Quests.Doom
|
||||
{
|
||||
public class ChylothStaff : BlackStaff
|
||||
{
|
||||
[Constructible]
|
||||
public ChylothStaff()
|
||||
{
|
||||
Hue = 0x482;
|
||||
}
|
||||
|
||||
public ChylothStaff(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override int LabelNumber => 1041111; // a magic staff
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
namespace Server.Engines.Quests.Doom
|
||||
{
|
||||
public class GoldenSkull : Item
|
||||
{
|
||||
[Constructible]
|
||||
public GoldenSkull() : base(Utility.Random(0x1AE2, 3))
|
||||
{
|
||||
Weight = 1.0;
|
||||
Hue = 0x8A5;
|
||||
LootType = LootType.Blessed;
|
||||
}
|
||||
|
||||
public GoldenSkull(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override int LabelNumber => 1061619; // a golden skull
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
namespace Server.Engines.Quests.Doom
|
||||
{
|
||||
public class GrandGrimoire : Item
|
||||
{
|
||||
[Constructible]
|
||||
public GrandGrimoire() : base(0xEFA)
|
||||
{
|
||||
Weight = 1.0;
|
||||
Hue = 0x835;
|
||||
Layer = Layer.OneHanded;
|
||||
LootType = LootType.Blessed;
|
||||
}
|
||||
|
||||
public GrandGrimoire(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override int LabelNumber => 1060801; // The Grand Grimoire
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
using Server.Items;
|
||||
using Server.Mobiles;
|
||||
|
||||
namespace Server.Engines.Quests.Doom
|
||||
{
|
||||
public class SummoningAltar : AbbatoirAddon
|
||||
{
|
||||
private BoneDemon m_Daemon;
|
||||
|
||||
[Constructible]
|
||||
public SummoningAltar()
|
||||
{
|
||||
}
|
||||
|
||||
public SummoningAltar(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public BoneDemon Daemon
|
||||
{
|
||||
get => 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;
|
||||
}
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
|
||||
writer.Write(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
Loading…
Add table
Add a link
Reference in a new issue