Overwrite

Complete Overwrite of the Folder with the free shard. ServUO 57.3 has been added.
This commit is contained in:
Unstable Kitsune
2023-11-28 23:20:26 -05:00
parent 3cd54811de
commit b918192e4e
11608 changed files with 2644205 additions and 47 deletions

View File

@@ -0,0 +1,173 @@
using System;
using System.Collections.Generic;
using Server.ContextMenus;
using Server.Items;
using Server.Mobiles;
namespace Server.Engines.Quests
{
public class TalkEntry : ContextMenuEntry
{
private readonly BaseQuester m_Quester;
public TalkEntry(BaseQuester quester)
: base(quester.TalkNumber)
{
this.m_Quester = quester;
}
public override void OnClick()
{
Mobile from = this.Owner.From;
if (from.CheckAlive() && from is PlayerMobile && this.m_Quester.CanTalkTo((PlayerMobile)from))
this.m_Quester.OnTalk((PlayerMobile)from, true);
}
}
public abstract class BaseQuester : BaseVendor
{
protected List<SBInfo> m_SBInfos = new List<SBInfo>();
public BaseQuester()
: this(null)
{
}
public BaseQuester(string title)
: base(title)
{
}
public BaseQuester(Serial serial)
: base(serial)
{
}
public override void CheckMorph()
{
// Don't morph me!
}
public override bool IsActiveVendor
{
get
{
return false;
}
}
public override bool IsInvulnerable
{
get
{
return true;
}
}
public override bool DisallowAllMoves
{
get
{
return true;
}
}
public override bool ClickTitle
{
get
{
return false;
}
}
public override bool CanTeach
{
get
{
return false;
}
}
public virtual int TalkNumber
{
get
{
return 6146;
}
}// Talk
protected override List<SBInfo> SBInfos
{
get
{
return this.m_SBInfos;
}
}
public static Container GetNewContainer()
{
Bag bag = new Bag();
bag.Hue = QuestSystem.RandomBrightHue();
return bag;
}
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;
}
public override void AddCustomContextEntries(Mobile from, List<ContextMenuEntry> list)
{
base.AddCustomContextEntries(from, list);
if (from.Alive && from is PlayerMobile && this.TalkNumber > 0 && this.CanTalkTo((PlayerMobile)from))
list.Add(new TalkEntry(this));
}
public override void OnMovement(Mobile m, Point3D oldLocation)
{
if (m.Alive && m is PlayerMobile)
{
PlayerMobile pm = (PlayerMobile)m;
int range = this.GetAutoTalkRange(pm);
if (m.Alive && range >= 0 && this.InRange(m, range) && !this.InRange(oldLocation, range) && this.CanTalkTo(pm))
this.OnTalk(pm, false);
}
}
public void FocusTo(Mobile to)
{
QuestSystem.FocusTo(this, to);
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write((int)0); // version
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
protected Item SetHue(Item item, int hue)
{
item.Hue = hue;
return item;
}
}
}

View File

@@ -0,0 +1,82 @@
using System;
using Server.Mobiles;
namespace Server.Engines.Quests
{
public abstract class DynamicTeleporter : Item
{
public DynamicTeleporter()
: this(0x1822, 0x482)
{
}
public DynamicTeleporter(int itemID, int hue)
: base(itemID)
{
this.Movable = false;
this.Hue = hue;
}
public DynamicTeleporter(Serial serial)
: base(serial)
{
}
public override int LabelNumber
{
get
{
return 1049382;
}
}// a magical teleporter
public virtual int NotWorkingMessage
{
get
{
return 500309;
}
}// Nothing Happens.
public abstract bool GetDestination(PlayerMobile player, ref Point3D loc, ref Map map);
public override bool OnMoveOver(Mobile m)
{
PlayerMobile pm = m as PlayerMobile;
if (pm != null)
{
Point3D loc = Point3D.Zero;
Map map = null;
if (this.GetDestination(pm, ref loc, ref map))
{
BaseCreature.TeleportPets(pm, loc, map);
pm.PlaySound(0x1FE);
pm.MoveToWorld(loc, map);
return false;
}
else
{
pm.SendLocalizedMessage(this.NotWorkingMessage);
}
}
return base.OnMoveOver(m);
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write((int)0); // version
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

View File

@@ -0,0 +1,200 @@
using System;
using Server.Network;
namespace Server.Items
{
public class EnchantedSextant : Item
{
//TODO: Trammel/Haven
private static readonly Point2D[] m_TrammelBanks = new Point2D[]
{
new Point2D(652, 820),
new Point2D(1813, 2825),
new Point2D(3734, 2149),
new Point2D(2503, 552),
new Point2D(3764, 1317),
new Point2D(587, 2146),
new Point2D(1655, 1606),
new Point2D(1425, 1690),
new Point2D(4471, 1156),
new Point2D(1317, 3773),
new Point2D(2881, 684),
new Point2D(2731, 2192),
new Point2D(3620, 2617),
new Point2D(2880, 3472),
new Point2D(1897, 2684),
new Point2D(5346, 74),
new Point2D(5275, 3977),
new Point2D(5669, 3131)
};
private static readonly Point2D[] m_FeluccaBanks = new Point2D[]
{
new Point2D(652, 820),
new Point2D(1813, 2825),
new Point2D(3734, 2149),
new Point2D(2503, 552),
new Point2D(3764, 1317),
new Point2D(3695, 2511),
new Point2D(587, 2146),
new Point2D(1655, 1606),
new Point2D(1425, 1690),
new Point2D(4471, 1156),
new Point2D(1317, 3773),
new Point2D(2881, 684),
new Point2D(2731, 2192),
new Point2D(2880, 3472),
new Point2D(1897, 2684),
new Point2D(5346, 74),
new Point2D(5275, 3977),
new Point2D(5669, 3131)
};
private static readonly Point2D[] m_IlshenarBanks = new Point2D[]
{
new Point2D(854, 680),
new Point2D(855, 603),
new Point2D(1226, 554),
new Point2D(1610, 556)
};
private static readonly Point2D[] m_MalasBanks = new Point2D[]
{
new Point2D(996, 519),
new Point2D(2048, 1345)
};
private const double m_LongDistance = 300.0;
private const double m_ShortDistance = 5.0;
public override int LabelNumber
{
get
{
return 1046226;
}
}// an enchanted sextant
[Constructable]
public EnchantedSextant()
: base(0x1058)
{
this.Weight = 2.0;
}
public override void OnDoubleClick(Mobile from)
{
if (!from.InRange(this.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(this.Serial, this.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(this.Serial, this.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(this.Serial, this.ItemID, MessageType.Label, 0x5AA, 3, bankMsg, "", ""));
}
public EnchantedSextant(Serial serial)
: base(serial)
{
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write((int)0); // version
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

View File

@@ -0,0 +1,228 @@
using System;
using Server.Items;
namespace Server.Engines.Quests
{
public class HornOfRetreat : Item
{
private Point3D m_DestLoc;
private Map m_DestMap;
private int m_Charges;
private Timer m_PlayTimer;
[Constructable]
public HornOfRetreat()
: base(0xFC4)
{
this.Hue = 0x482;
this.Weight = 1.0;
this.Charges = 10;
}
public HornOfRetreat(Serial serial)
: base(serial)
{
}
[CommandProperty(AccessLevel.GameMaster)]
public Point3D DestLoc
{
get
{
return this.m_DestLoc;
}
set
{
this.m_DestLoc = value;
}
}
[CommandProperty(AccessLevel.GameMaster)]
public Map DestMap
{
get
{
return this.m_DestMap;
}
set
{
this.m_DestMap = value;
}
}
[CommandProperty(AccessLevel.GameMaster)]
public int Charges
{
get
{
return this.m_Charges;
}
set
{
this.m_Charges = value;
this.InvalidateProperties();
}
}
public override int LabelNumber
{
get
{
return 1049117;
}
}// Horn of Retreat
public virtual bool ValidateUse(Mobile from)
{
return true;
}
public override void GetProperties(ObjectPropertyList list)
{
base.GetProperties(list);
list.Add(1060741, this.m_Charges.ToString()); // charges: ~1_val~
}
public override void OnDoubleClick(Mobile from)
{
if (this.IsChildOf(from.Backpack))
{
if (!this.ValidateUse(from))
{
this.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 (this.m_PlayTimer != null)
{
this.SendLocalizedMessageTo(from, 1042144); // This is currently in use.
}
else if (this.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...
--this.Charges;
this.m_PlayTimer = Timer.DelayCall(TimeSpan.FromSeconds(5.0), new TimerStateCallback(PlayTimer_Callback), from);
}
else
{
this.SendLocalizedMessageTo(from, 1042544); // This item is out of charges.
}
}
else
{
this.SendLocalizedMessageTo(from, 1042001); // That must be in your pack for you to use it.
}
}
public virtual void PlayTimer_Callback(object state)
{
Mobile from = (Mobile)state;
this.m_PlayTimer = null;
HornOfRetreatMoongate gate = new HornOfRetreatMoongate(this.DestLoc, this.DestMap, from, this.Hue);
gate.MoveToWorld(from.Location, from.Map);
from.PlaySound(0x20E);
gate.SendLocalizedMessageTo(from, 1049102, from.Name); // Quickly ~1_NAME~! Onward through the gate!
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write((int)0); // version
writer.Write(this.m_DestLoc);
writer.Write(this.m_DestMap);
writer.Write(this.m_Charges);
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
switch ( version )
{
case 0:
{
this.m_DestLoc = reader.ReadPoint3D();
this.m_DestMap = reader.ReadMap();
this.m_Charges = reader.ReadInt();
break;
}
}
}
}
public class HornOfRetreatMoongate : Moongate
{
private readonly Mobile m_Caster;
public HornOfRetreatMoongate(Point3D destLoc, Map destMap, Mobile caster, int hue)
{
this.m_Caster = caster;
this.Target = destLoc;
this.TargetMap = destMap;
this.Hue = hue;
this.Light = LightType.Circle300;
this.Dispellable = false;
Timer.DelayCall(TimeSpan.FromSeconds(10.0), new TimerCallback(Delete));
}
public HornOfRetreatMoongate(Serial serial)
: base(serial)
{
}
public override int LabelNumber
{
get
{
return 1049114;
}
}// Sanctuary Gate
public override void BeginConfirmation(Mobile from)
{
this.EndConfirmation(from);
}
public override void UseGate(Mobile m)
{
if (m.Region.IsPartOf<Regions.Jail>())
{
m.SendLocalizedMessage(1114345); // You'll need a better jailbreak plan than that!
}
else if (m == this.m_Caster)
{
base.UseGate(m);
this.Delete();
}
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write((int)0); // version
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
this.Delete();
}
}
}

View File

@@ -0,0 +1,127 @@
using System;
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
{
get
{
return this.Deleted;
}
}
public abstract bool CanDrop(PlayerMobile pm);
public override bool DropToWorld(Mobile from, Point3D p)
{
bool ret = base.DropToWorld(from, p);
if (ret && !this.Accepted && this.Parent != from.Backpack)
{
if (from.IsStaff())
{
return true;
}
else if (!(from is PlayerMobile) || this.CanDrop((PlayerMobile)from))
{
return true;
}
else
{
from.SendLocalizedMessage(1049343); // You can only drop quest items into the top-most level of your backpack while you still need them for your quest.
return false;
}
}
else
{
return ret;
}
}
public override bool DropToMobile(Mobile from, Mobile target, Point3D p)
{
bool ret = base.DropToMobile(from, target, p);
if (ret && !this.Accepted && this.Parent != from.Backpack)
{
if (from.IsStaff())
{
return true;
}
else if (!(from is PlayerMobile) || this.CanDrop((PlayerMobile)from))
{
return true;
}
else
{
from.SendLocalizedMessage(1049344); // You decide against trading the item. You still need it for your quest.
return false;
}
}
else
{
return ret;
}
}
public override bool DropToItem(Mobile from, Item target, Point3D p)
{
bool ret = base.DropToItem(from, target, p);
if (ret && !this.Accepted && this.Parent != from.Backpack)
{
if (from.IsStaff())
{
return true;
}
else if (!(from is PlayerMobile) || this.CanDrop((PlayerMobile)from))
{
return true;
}
else
{
from.SendLocalizedMessage(1049343); // You can only drop quest items into the top-most level of your backpack while you still need them for your quest.
return false;
}
}
else
{
return ret;
}
}
public override DeathMoveResult OnParentDeath(Mobile parent)
{
if (parent is PlayerMobile && !this.CanDrop((PlayerMobile)parent))
return DeathMoveResult.MoveToBackpack;
else
return base.OnParentDeath(parent);
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write((int)0); // version
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

View File

@@ -0,0 +1,26 @@
using System;
using Server.ContextMenus;
namespace Server.Engines.Quests
{
public class QuestCallbackEntry : ContextMenuEntry
{
private readonly QuestCallback m_Callback;
public QuestCallbackEntry(int number, QuestCallback callback)
: this(number, -1, callback)
{
}
public QuestCallbackEntry(int number, int range, QuestCallback callback)
: base(number, range)
{
this.m_Callback = callback;
}
public override void OnClick()
{
if (this.m_Callback != null)
this.m_Callback();
}
}
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -0,0 +1,48 @@
using System;
using System.Xml;
using Server.Mobiles;
using Server.Regions;
namespace Server.Engines.Quests
{
public class CancelQuestRegion : BaseRegion
{
private readonly Type m_Quest;
public CancelQuestRegion(XmlElement xml, Map map, Region parent)
: base(xml, map, parent)
{
ReadType(xml["quest"], "type", ref this.m_Quest);
}
public Type Quest
{
get
{
return this.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.IsStaff())
return true;
if (this.m_Quest == null)
return true;
PlayerMobile player = m as PlayerMobile;
if (player != null && player.Quest != null && player.Quest.GetType() == this.m_Quest)
{
if (!player.HasGump(typeof(QuestCancelGump)))
player.Quest.BeginCancelQuest();
return false;
}
return true;
}
}
}

View File

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

View File

@@ -0,0 +1,89 @@
using System;
using System.Xml;
using Server.Mobiles;
using Server.Regions;
namespace Server.Engines.Quests
{
public class QuestNoEntryRegion : BaseRegion
{
private readonly Type m_Quest;
private readonly Type m_MinObjective;
private readonly Type m_MaxObjective;
private readonly int m_Message;
public QuestNoEntryRegion(XmlElement xml, Map map, Region parent)
: base(xml, map, parent)
{
XmlElement questEl = xml["quest"];
ReadType(questEl, "type", ref this.m_Quest);
ReadType(questEl, "min", ref this.m_MinObjective, false);
ReadType(questEl, "max", ref this.m_MaxObjective, false);
ReadInt32(questEl, "message", ref this.m_Message, false);
}
public Type Quest
{
get
{
return this.m_Quest;
}
}
public Type MinObjective
{
get
{
return this.m_MinObjective;
}
}
public Type MaxObjective
{
get
{
return this.m_MaxObjective;
}
}
public int Message
{
get
{
return this.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.IsStaff())
return true;
if (m is BaseCreature)
{
BaseCreature bc = m as BaseCreature;
if (!bc.Controlled && !bc.Summoned)
return true;
}
if (this.m_Quest == null)
return true;
PlayerMobile player = m as PlayerMobile;
if (player != null && player.Quest != null && player.Quest.GetType() == this.m_Quest &&
(this.m_MinObjective == null || player.Quest.FindObjective(this.m_MinObjective) != null) &&
(this.m_MaxObjective == null || player.Quest.FindObjective(this.m_MaxObjective) == null))
{
return true;
}
else
{
if (this.m_Message != 0)
m.SendLocalizedMessage(this.m_Message);
return false;
}
}
}
}

View File

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