919 lines
22 KiB
C#
919 lines
22 KiB
C#
using System;
|
|
using Server.Mobiles;
|
|
using Server.Regions;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
|
|
namespace Server.Engines.Quests
|
|
{
|
|
public class BaseObjective
|
|
{
|
|
private BaseQuest m_Quest;
|
|
private int m_MaxProgress;
|
|
private int m_CurProgress;
|
|
private int m_Seconds;
|
|
private bool m_Timed;
|
|
public BaseObjective()
|
|
: this(1, 0)
|
|
{
|
|
}
|
|
|
|
public BaseObjective(int maxProgress)
|
|
: this(maxProgress, 0)
|
|
{
|
|
}
|
|
|
|
public BaseObjective(int maxProgress, int seconds)
|
|
{
|
|
m_MaxProgress = maxProgress;
|
|
m_Seconds = seconds;
|
|
|
|
if (seconds > 0)
|
|
Timed = true;
|
|
else
|
|
Timed = false;
|
|
}
|
|
|
|
public BaseQuest Quest
|
|
{
|
|
get
|
|
{
|
|
return m_Quest;
|
|
}
|
|
set
|
|
{
|
|
m_Quest = value;
|
|
}
|
|
}
|
|
public int MaxProgress
|
|
{
|
|
get
|
|
{
|
|
return m_MaxProgress;
|
|
}
|
|
set
|
|
{
|
|
m_MaxProgress = value;
|
|
}
|
|
}
|
|
public int CurProgress
|
|
{
|
|
get
|
|
{
|
|
return m_CurProgress;
|
|
}
|
|
set
|
|
{
|
|
m_CurProgress = value;
|
|
|
|
if (Completed)
|
|
OnCompleted();
|
|
|
|
if (m_CurProgress == -1)
|
|
OnFailed();
|
|
|
|
if (m_CurProgress < -1)
|
|
m_CurProgress = -1;
|
|
}
|
|
}
|
|
public int Seconds
|
|
{
|
|
get
|
|
{
|
|
return m_Seconds;
|
|
}
|
|
set
|
|
{
|
|
m_Seconds = value;
|
|
|
|
if (m_Seconds < 0)
|
|
m_Seconds = 0;
|
|
}
|
|
}
|
|
public bool Timed
|
|
{
|
|
get
|
|
{
|
|
return m_Timed;
|
|
}
|
|
set
|
|
{
|
|
m_Timed = value;
|
|
}
|
|
}
|
|
public bool Completed
|
|
{
|
|
get
|
|
{
|
|
return CurProgress >= MaxProgress;
|
|
}
|
|
}
|
|
public bool Failed
|
|
{
|
|
get
|
|
{
|
|
return CurProgress == -1;
|
|
}
|
|
}
|
|
|
|
public virtual object ObjectiveDescription
|
|
{
|
|
get { return null; }
|
|
}
|
|
|
|
public virtual void Complete()
|
|
{
|
|
CurProgress = MaxProgress;
|
|
}
|
|
|
|
public virtual void Fail()
|
|
{
|
|
CurProgress = -1;
|
|
}
|
|
|
|
public virtual void OnAccept()
|
|
{
|
|
}
|
|
|
|
public virtual void OnCompleted()
|
|
{
|
|
}
|
|
|
|
public virtual void OnFailed()
|
|
{
|
|
}
|
|
|
|
public virtual Type Type()
|
|
{
|
|
return null;
|
|
}
|
|
|
|
public virtual bool Update(object obj)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
public virtual void UpdateTime()
|
|
{
|
|
if (!Timed || Failed)
|
|
return;
|
|
|
|
if (Seconds > 0)
|
|
{
|
|
Seconds -= 1;
|
|
}
|
|
else if (!Completed)
|
|
{
|
|
m_Quest.Owner.SendLocalizedMessage(1072258); // You failed to complete an objective in time!
|
|
|
|
Fail();
|
|
}
|
|
}
|
|
|
|
public virtual void Serialize(GenericWriter writer)
|
|
{
|
|
writer.WriteEncodedInt((int)0); // version
|
|
|
|
writer.Write((int)m_CurProgress);
|
|
writer.Write((int)m_Seconds);
|
|
}
|
|
|
|
public virtual void Deserialize(GenericReader reader)
|
|
{
|
|
int version = reader.ReadEncodedInt();
|
|
|
|
m_CurProgress = reader.ReadInt();
|
|
m_Seconds = reader.ReadInt();
|
|
}
|
|
}
|
|
|
|
public class SlayObjective : BaseObjective
|
|
{
|
|
private Type[] m_Creatures;
|
|
private string m_Name;
|
|
private Region m_Region;
|
|
|
|
public SlayObjective(Type creature, string name, int amount)
|
|
: this(new Type[] { creature }, name, amount, null, 0)
|
|
{
|
|
}
|
|
|
|
public SlayObjective(Type creature, string name, int amount, string region)
|
|
: this(new Type[] { creature }, name, amount, region, 0)
|
|
{
|
|
}
|
|
|
|
public SlayObjective(Type creature, string name, int amount, int seconds)
|
|
: this(new Type[] { creature }, name, amount, null, seconds)
|
|
{
|
|
}
|
|
|
|
public SlayObjective(string name, int amount, params Type[] creatures)
|
|
: this(creatures, name, amount, null, 0)
|
|
{
|
|
}
|
|
|
|
public SlayObjective(string name, int amount, string region, params Type[] creatures)
|
|
: this(creatures, name, amount, region, 0)
|
|
{
|
|
}
|
|
|
|
public SlayObjective(string name, int amount, int seconds, params Type[] creatures)
|
|
: this(creatures, name, amount, null, seconds)
|
|
{
|
|
}
|
|
|
|
public SlayObjective(Type[] creatures, string name, int amount, string region, int seconds)
|
|
: base(amount, seconds)
|
|
{
|
|
m_Creatures = creatures;
|
|
m_Name = name;
|
|
|
|
if (region != null)
|
|
{
|
|
m_Region = QuestHelper.FindRegion(region);
|
|
|
|
if (m_Region == null)
|
|
Console.WriteLine(String.Format("Invalid region name ('{0}') in '{1}' objective!", region, GetType()));
|
|
}
|
|
}
|
|
|
|
public Type[] Creatures
|
|
{
|
|
get
|
|
{
|
|
return m_Creatures;
|
|
}
|
|
set
|
|
{
|
|
m_Creatures = value;
|
|
}
|
|
}
|
|
public string Name
|
|
{
|
|
get
|
|
{
|
|
return m_Name;
|
|
}
|
|
set
|
|
{
|
|
m_Name = value;
|
|
}
|
|
}
|
|
public Region Region
|
|
{
|
|
get
|
|
{
|
|
return m_Region;
|
|
}
|
|
set
|
|
{
|
|
m_Region = value;
|
|
}
|
|
}
|
|
|
|
public virtual void OnKill(Mobile killed)
|
|
{
|
|
if (Completed)
|
|
Quest.Owner.SendLocalizedMessage(1075050); // You have killed all the required quest creatures of this type.
|
|
else
|
|
Quest.Owner.SendLocalizedMessage(1075051, (MaxProgress - CurProgress).ToString()); // You have killed a quest creature. ~1_val~ more left.
|
|
}
|
|
|
|
public virtual bool IsObjective(Mobile mob)
|
|
{
|
|
if (m_Creatures == null)
|
|
return false;
|
|
|
|
foreach (var type in m_Creatures)
|
|
{
|
|
if (type.IsAssignableFrom(mob.GetType()))
|
|
{
|
|
if (m_Region != null && !m_Region.Contains(mob.Location))
|
|
return false;
|
|
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
public override bool Update(object obj)
|
|
{
|
|
if (obj is Mobile)
|
|
{
|
|
Mobile mob = (Mobile)obj;
|
|
|
|
if (IsObjective(mob))
|
|
{
|
|
if (!Completed)
|
|
CurProgress += 1;
|
|
|
|
OnKill(mob);
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
public override Type Type()
|
|
{
|
|
return m_Creatures != null && m_Creatures.Length > 0 ? m_Creatures[0] : null;
|
|
}
|
|
|
|
public override void Serialize(GenericWriter writer)
|
|
{
|
|
base.Serialize(writer);
|
|
|
|
writer.WriteEncodedInt((int)0); // version
|
|
}
|
|
|
|
public override void Deserialize(GenericReader reader)
|
|
{
|
|
base.Deserialize(reader);
|
|
|
|
int version = reader.ReadEncodedInt();
|
|
}
|
|
}
|
|
|
|
public class ObtainObjective : BaseObjective
|
|
{
|
|
private Type m_Obtain;
|
|
private string m_Name;
|
|
private int m_Image;
|
|
private int m_Hue;
|
|
|
|
public ObtainObjective(Type obtain, string name, int amount)
|
|
: this(obtain, name, amount, 0, 0)
|
|
{
|
|
}
|
|
|
|
public ObtainObjective(Type obtain, string name, int amount, int image)
|
|
: this(obtain, name, amount, image, 0)
|
|
{
|
|
}
|
|
|
|
public ObtainObjective(Type obtain, string name, int amount, int image, int seconds)
|
|
: this(obtain, name, amount, image, seconds, 0)
|
|
{
|
|
}
|
|
|
|
public ObtainObjective(Type obtain, string name, int amount, int image, int seconds, int hue)
|
|
: base(amount, seconds)
|
|
{
|
|
m_Obtain = obtain;
|
|
m_Name = name;
|
|
m_Image = image;
|
|
m_Hue = hue;
|
|
}
|
|
|
|
public Type Obtain
|
|
{
|
|
get
|
|
{
|
|
return m_Obtain;
|
|
}
|
|
set
|
|
{
|
|
m_Obtain = value;
|
|
}
|
|
}
|
|
public string Name
|
|
{
|
|
get
|
|
{
|
|
return m_Name;
|
|
}
|
|
set
|
|
{
|
|
m_Name = value;
|
|
}
|
|
}
|
|
public int Image
|
|
{
|
|
get
|
|
{
|
|
return m_Image;
|
|
}
|
|
set
|
|
{
|
|
m_Image = value;
|
|
}
|
|
}
|
|
public int Hue
|
|
{
|
|
get
|
|
{
|
|
return m_Hue;
|
|
}
|
|
set
|
|
{
|
|
m_Hue = value;
|
|
}
|
|
}
|
|
public override bool Update(object obj)
|
|
{
|
|
if (obj is Item)
|
|
{
|
|
Item obtained = (Item)obj;
|
|
|
|
if (IsObjective(obtained))
|
|
{
|
|
if (!obtained.QuestItem)
|
|
{
|
|
CurProgress += obtained.Amount;
|
|
|
|
obtained.QuestItem = true;
|
|
Quest.Owner.SendLocalizedMessage(1072353); // You set the item to Quest Item status
|
|
|
|
Quest.OnObjectiveUpdate(obtained);
|
|
}
|
|
else
|
|
{
|
|
CurProgress -= obtained.Amount;
|
|
|
|
obtained.QuestItem = false;
|
|
Quest.Owner.SendLocalizedMessage(1072354); // You remove Quest Item status from the item
|
|
}
|
|
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
public virtual bool IsObjective(Item item)
|
|
{
|
|
if (m_Obtain == null)
|
|
return false;
|
|
|
|
if (m_Obtain.IsAssignableFrom(item.GetType()))
|
|
return true;
|
|
|
|
return false;
|
|
}
|
|
|
|
public override Type Type()
|
|
{
|
|
return m_Obtain;
|
|
}
|
|
|
|
public override void Serialize(GenericWriter writer)
|
|
{
|
|
base.Serialize(writer);
|
|
|
|
writer.WriteEncodedInt((int)0); // version
|
|
}
|
|
|
|
public override void Deserialize(GenericReader reader)
|
|
{
|
|
base.Deserialize(reader);
|
|
|
|
int version = reader.ReadEncodedInt();
|
|
}
|
|
}
|
|
|
|
public class DeliverObjective : BaseObjective
|
|
{
|
|
private Type m_Delivery;
|
|
private string m_DeliveryName;
|
|
private Type m_Destination;
|
|
private string m_DestName;
|
|
|
|
public DeliverObjective(Type delivery, string deliveryName, int amount, Type destination, string destName)
|
|
: this(delivery, deliveryName, amount, destination, destName, 0)
|
|
{
|
|
}
|
|
|
|
public DeliverObjective(Type delivery, string deliveryName, int amount, Type destination, string destName, int seconds)
|
|
: base(amount, seconds)
|
|
{
|
|
m_Delivery = delivery;
|
|
m_DeliveryName = deliveryName;
|
|
|
|
m_Destination = destination;
|
|
m_DestName = destName;
|
|
}
|
|
|
|
public Type Delivery
|
|
{
|
|
get
|
|
{
|
|
return m_Delivery;
|
|
}
|
|
set
|
|
{
|
|
m_Delivery = value;
|
|
}
|
|
}
|
|
public string DeliveryName
|
|
{
|
|
get
|
|
{
|
|
return m_DeliveryName;
|
|
}
|
|
set
|
|
{
|
|
m_DeliveryName = value;
|
|
}
|
|
}
|
|
public Type Destination
|
|
{
|
|
get
|
|
{
|
|
return m_Destination;
|
|
}
|
|
set
|
|
{
|
|
m_Destination = value;
|
|
}
|
|
}
|
|
public string DestName
|
|
{
|
|
get
|
|
{
|
|
return m_DestName;
|
|
}
|
|
set
|
|
{
|
|
m_DestName = value;
|
|
}
|
|
}
|
|
public override void OnAccept()
|
|
{
|
|
if (Quest.StartingItem != null)
|
|
{
|
|
Quest.StartingItem.QuestItem = true;
|
|
return;
|
|
}
|
|
|
|
int amount = MaxProgress;
|
|
|
|
while (amount > 0 && !Failed)
|
|
{
|
|
Item item = QuestHelper.Construct(m_Delivery) as Item;
|
|
|
|
if (item == null)
|
|
{
|
|
Fail();
|
|
break;
|
|
}
|
|
|
|
if (item.Stackable)
|
|
{
|
|
item.Amount = amount;
|
|
amount = 1;
|
|
}
|
|
|
|
if (!Quest.Owner.PlaceInBackpack(item))
|
|
{
|
|
Quest.Owner.SendLocalizedMessage(503200); // You do not have room in your backpack for
|
|
Quest.Owner.SendLocalizedMessage(1075574); // Could not create all the necessary items. Your quest has not advanced.
|
|
|
|
Fail();
|
|
|
|
break;
|
|
}
|
|
else
|
|
item.QuestItem = true;
|
|
|
|
amount -= 1;
|
|
}
|
|
|
|
if (Failed)
|
|
{
|
|
QuestHelper.DeleteItems(Quest.Owner, m_Delivery, MaxProgress - amount, false);
|
|
|
|
Quest.RemoveQuest();
|
|
}
|
|
}
|
|
|
|
public override bool Update(object obj)
|
|
{
|
|
if (m_Delivery == null || m_Destination == null)
|
|
return false;
|
|
|
|
if (Failed)
|
|
{
|
|
Quest.Owner.SendLocalizedMessage(1074813); // You have failed to complete your delivery.
|
|
return false;
|
|
}
|
|
|
|
if (obj is BaseVendor)
|
|
{
|
|
if (Quest.StartingItem != null)
|
|
{
|
|
Complete();
|
|
return true;
|
|
}
|
|
else if (m_Destination.IsAssignableFrom(obj.GetType()))
|
|
{
|
|
if (MaxProgress < QuestHelper.CountQuestItems(Quest.Owner, Delivery))
|
|
{
|
|
Quest.Owner.SendLocalizedMessage(1074813); // You have failed to complete your delivery.
|
|
Fail();
|
|
}
|
|
else
|
|
Complete();
|
|
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
public override Type Type()
|
|
{
|
|
return m_Delivery;
|
|
}
|
|
|
|
public override void Serialize(GenericWriter writer)
|
|
{
|
|
base.Serialize(writer);
|
|
|
|
writer.WriteEncodedInt((int)0); // version
|
|
}
|
|
|
|
public override void Deserialize(GenericReader reader)
|
|
{
|
|
base.Deserialize(reader);
|
|
|
|
int version = reader.ReadEncodedInt();
|
|
}
|
|
}
|
|
|
|
public class EscortObjective : BaseObjective
|
|
{
|
|
public Region Region { get; set; }
|
|
public int Fame { get; set; }
|
|
public int Compassion { get; set; }
|
|
public int Label { get; set; }
|
|
|
|
public EscortObjective(string region)
|
|
: this(region, 10, 200, 0, 0)
|
|
{
|
|
}
|
|
|
|
public EscortObjective(int label, string region)
|
|
: this(region, 10, 200, 0, label)
|
|
{
|
|
}
|
|
|
|
public EscortObjective(string region, int fame)
|
|
: this(region, fame, 200)
|
|
{
|
|
}
|
|
|
|
public EscortObjective(string region, int fame, int compassion)
|
|
: this(region, fame, compassion, 0, 0)
|
|
{
|
|
}
|
|
|
|
public EscortObjective(string region, int fame, int compassion, int seconds, int label)
|
|
: base(1, seconds)
|
|
{
|
|
Region = QuestHelper.FindRegion(region);
|
|
Fame = fame;
|
|
Compassion = compassion;
|
|
Label = label;
|
|
|
|
if (Region == null)
|
|
Console.WriteLine(String.Format("Invalid region name ('{0}') in '{1}' objective!", region, GetType()));
|
|
}
|
|
|
|
public override void OnCompleted()
|
|
{
|
|
if (Quest != null && Quest.Owner != null && Quest.Owner.Murderer && Quest.Owner.DoneQuests.FirstOrDefault(info => info.QuestType == typeof(ResponsibilityQuest)) == null)
|
|
{
|
|
QuestHelper.Delay(Quest.Owner, typeof(ResponsibilityQuest), Quest.RestartDelay);
|
|
}
|
|
|
|
base.OnCompleted();
|
|
}
|
|
|
|
public override void Serialize(GenericWriter writer)
|
|
{
|
|
base.Serialize(writer);
|
|
|
|
writer.WriteEncodedInt((int)0); // version
|
|
}
|
|
|
|
public override void Deserialize(GenericReader reader)
|
|
{
|
|
base.Deserialize(reader);
|
|
|
|
int version = reader.ReadEncodedInt();
|
|
}
|
|
}
|
|
|
|
public class ApprenticeObjective : BaseObjective
|
|
{
|
|
private SkillName m_Skill;
|
|
private Region m_Region;
|
|
private object m_Enter;
|
|
private object m_Leave;
|
|
|
|
public ApprenticeObjective(SkillName skill, int cap)
|
|
: this(skill, cap, null, null, null)
|
|
{
|
|
}
|
|
|
|
public ApprenticeObjective(SkillName skill, int cap, string region, object enterRegion, object leaveRegion)
|
|
: base(cap)
|
|
{
|
|
m_Skill = skill;
|
|
|
|
if (region != null)
|
|
{
|
|
m_Region = QuestHelper.FindRegion(region);
|
|
m_Enter = enterRegion;
|
|
m_Leave = leaveRegion;
|
|
|
|
if (m_Region == null)
|
|
Console.WriteLine(String.Format("Invalid region name ('{0}') in '{1}' objective!", region, GetType()));
|
|
}
|
|
}
|
|
|
|
public SkillName Skill
|
|
{
|
|
get
|
|
{
|
|
return m_Skill;
|
|
}
|
|
set
|
|
{
|
|
m_Skill = value;
|
|
}
|
|
}
|
|
public Region Region
|
|
{
|
|
get
|
|
{
|
|
return m_Region;
|
|
}
|
|
set
|
|
{
|
|
m_Region = value;
|
|
}
|
|
}
|
|
public object Enter
|
|
{
|
|
get
|
|
{
|
|
return m_Enter;
|
|
}
|
|
set
|
|
{
|
|
m_Enter = value;
|
|
}
|
|
}
|
|
public object Leave
|
|
{
|
|
get
|
|
{
|
|
return m_Leave;
|
|
}
|
|
set
|
|
{
|
|
m_Leave = value;
|
|
}
|
|
}
|
|
public override bool Update(object obj)
|
|
{
|
|
if (Completed)
|
|
return false;
|
|
|
|
if (obj is Skill)
|
|
{
|
|
Skill skill = (Skill)obj;
|
|
|
|
if (skill.SkillName != m_Skill)
|
|
return false;
|
|
|
|
if (Quest.Owner.Skills[m_Skill].Base >= MaxProgress)
|
|
{
|
|
Complete();
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
public override void OnAccept()
|
|
{
|
|
Region region = Quest.Owner.Region;
|
|
|
|
while (region != null)
|
|
{
|
|
if (region is ApprenticeRegion)
|
|
region.OnEnter(Quest.Owner);
|
|
|
|
region = region.Parent;
|
|
}
|
|
}
|
|
|
|
public override void OnCompleted()
|
|
{
|
|
QuestHelper.RemoveAcceleratedSkillgain(Quest.Owner);
|
|
}
|
|
|
|
public override void Serialize(GenericWriter writer)
|
|
{
|
|
base.Serialize(writer);
|
|
|
|
writer.WriteEncodedInt((int)1); // version
|
|
}
|
|
|
|
public override void Deserialize(GenericReader reader)
|
|
{
|
|
base.Deserialize(reader);
|
|
|
|
int version = reader.ReadEncodedInt();
|
|
}
|
|
}
|
|
|
|
public class QuestionAndAnswerObjective : BaseObjective
|
|
{
|
|
private int _CurrentIndex;
|
|
|
|
private List<int> m_Done = new List<int>();
|
|
private QuestionAndAnswerEntry[] m_EntryTable;
|
|
|
|
public virtual QuestionAndAnswerEntry[] EntryTable { get { return m_EntryTable; } }
|
|
|
|
public QuestionAndAnswerObjective(int count, QuestionAndAnswerEntry[] table)
|
|
: base(count)
|
|
{
|
|
m_EntryTable = table;
|
|
_CurrentIndex = -1;
|
|
}
|
|
|
|
public QuestionAndAnswerEntry GetRandomQandA()
|
|
{
|
|
if (m_EntryTable == null || m_EntryTable.Length == 0 || m_EntryTable.Length - m_Done.Count <= 0)
|
|
return null;
|
|
|
|
if (_CurrentIndex >= 0 && _CurrentIndex < m_EntryTable.Length)
|
|
{
|
|
return m_EntryTable[_CurrentIndex];
|
|
}
|
|
|
|
int ran;
|
|
|
|
do
|
|
{
|
|
ran = Utility.Random(m_EntryTable.Length);
|
|
}
|
|
while (m_Done.Contains(ran));
|
|
|
|
_CurrentIndex = ran;
|
|
return m_EntryTable[ran];
|
|
}
|
|
|
|
public override bool Update(object obj)
|
|
{
|
|
m_Done.Add(_CurrentIndex);
|
|
_CurrentIndex = -1;
|
|
|
|
if (!Completed)
|
|
CurProgress++;
|
|
|
|
return true;
|
|
}
|
|
|
|
public override void Serialize(GenericWriter writer)
|
|
{
|
|
base.Serialize(writer);
|
|
|
|
writer.Write((int)1); // version
|
|
|
|
writer.Write(_CurrentIndex);
|
|
|
|
writer.Write(m_Done.Count);
|
|
for (int i = 0; i < m_Done.Count; i++)
|
|
writer.Write(m_Done[i]);
|
|
}
|
|
|
|
public override void Deserialize(GenericReader reader)
|
|
{
|
|
base.Deserialize(reader);
|
|
|
|
int version = reader.ReadInt();
|
|
|
|
if (version > 0)
|
|
{
|
|
_CurrentIndex = reader.ReadInt();
|
|
}
|
|
|
|
int c = reader.ReadInt();
|
|
for (int i = 0; i < c; i++)
|
|
m_Done.Add(reader.ReadInt());
|
|
}
|
|
}
|
|
}
|