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,101 @@
using System;
using Server.Mobiles;
using Server.Network;
using Server.Items;
namespace Server.Engines.Quests
{
public sealed class HeritagePacket : Packet
{
public static readonly Packet Close = Packet.SetStatic(new HeritagePacket(false, 0xFF));
public HeritagePacket(bool female, short type)
: base(0xBF)
{
this.EnsureCapacity(7);
this.m_Stream.Write((short)0x2A);
this.m_Stream.Write((byte)(female ? 1 : 0));
this.m_Stream.Write((byte)type);
}
}
public class PacketOverrides
{
public static void Initialize()
{
Timer.DelayCall(TimeSpan.Zero, new TimerCallback(Override));
}
public static void Override()
{
PacketHandlers.RegisterEncoded(0x32, true, new OnEncodedPacketReceive(QuestButton));
PacketHandlers.RegisterExtended(0x2A, true, new OnPacketReceive(HeritageTransform));
}
public static void QuestButton(NetState state, IEntity e, EncodedReader reader)
{
if (state.Mobile is PlayerMobile)
{
PlayerMobile from = (PlayerMobile)state.Mobile;
from.CloseGump(typeof(MondainQuestGump));
from.SendGump(new MondainQuestGump(from));
}
}
public static void HeritageTransform(NetState state, PacketReader reader)
{
Mobile m = state.Mobile;
if (reader.Size == 5)
{
m.SendLocalizedMessage(1073645); // You may try this again later...
}
else if (reader.Size == 15 && HeritageQuester.Check(m))
{
bool proceed = false;
if (HeritageQuester.IsPending(m))
{
proceed = true;
HeritageQuester quester = HeritageQuester.Pending(m);
m.Race = quester.Race;
quester.CheckCompleted(m, true); // removes done quests
if (m.Race == Race.Elf)
m.SendLocalizedMessage(1073653); // You are now fully initiated into the Elven culture.
else if (m.Race == Race.Human)
m.SendLocalizedMessage(1073654); // You are now fully human.
}
else if (RaceChangeToken.IsPending(m))
{
var race = RaceChangeToken.GetPendingRace(m);
if (race != null)
{
m.Race = race;
proceed = true;
m.SendLocalizedMessage(1111914); // You have successfully changed your race.
RaceChangeToken.OnRaceChange(m);
}
}
if(proceed)
{
m.Hue = reader.ReadUInt16();
m.HairItemID = reader.ReadUInt16();
m.HairHue = reader.ReadUInt16();
m.FacialHairItemID = reader.ReadUInt16();
m.FacialHairHue = reader.ReadUInt16();
}
}
HeritageQuester.RemovePending(m);
RaceChangeToken.RemovePending(m);
}
}
}

View File

@@ -0,0 +1,147 @@
using System;
using System.Collections.Generic;
using System.IO;
using Server;
using Server.Mobiles;
namespace Server.Engines.Quests
{
public static class MondainQuestData
{
public static string FilePath = Path.Combine("Saves/Quests", "MLQuests.bin");
public static Dictionary<PlayerMobile, List<BaseQuest>> QuestData { get; set; }
public static Dictionary<PlayerMobile, Dictionary<QuestChain, BaseChain>> ChainData { get; set; }
public static List<BaseQuest> GetQuests(PlayerMobile pm)
{
if (!QuestData.ContainsKey(pm))
{
QuestData[pm] = new List<BaseQuest>();
}
return QuestData[pm];
}
public static Dictionary<QuestChain, BaseChain> GetChains(PlayerMobile pm)
{
if (!ChainData.ContainsKey(pm))
{
ChainData[pm] = new Dictionary<QuestChain, BaseChain>();
}
return ChainData[pm];
}
public static void AddQuest(PlayerMobile pm, BaseQuest q)
{
if (!QuestData.ContainsKey(pm) || QuestData[pm] == null)
QuestData[pm] = new List<BaseQuest>();
QuestData[pm].Add(q);
}
public static void AddChain(PlayerMobile pm, QuestChain id, BaseChain chain)
{
if (pm == null)
return;
if (!ChainData.ContainsKey(pm) || ChainData[pm] == null)
ChainData[pm] = new Dictionary<QuestChain, BaseChain>();
ChainData[pm].Add(id, chain);
}
public static void RemoveQuest(PlayerMobile pm, BaseQuest quest)
{
if (QuestData.ContainsKey(pm) && QuestData[pm].Contains(quest))
{
QuestData[pm].Remove(quest);
if (QuestData[pm].Count == 0)
QuestData.Remove(pm);
}
}
public static void RemoveChain(PlayerMobile pm, QuestChain chain)
{
if (ChainData.ContainsKey(pm) && ChainData[pm].ContainsKey(chain))
{
ChainData[pm].Remove(chain);
if(ChainData[pm].Count == 0)
ChainData.Remove(pm);
}
}
public static void Configure()
{
EventSink.WorldSave += OnSave;
EventSink.WorldLoad += OnLoad;
QuestData = new Dictionary<PlayerMobile, List<BaseQuest>>();
ChainData = new Dictionary<PlayerMobile, Dictionary<QuestChain, BaseChain>>();
}
public static void OnSave(WorldSaveEventArgs e)
{
Persistence.Serialize(
FilePath,
writer =>
{
writer.Write(0);
writer.Write(QuestData.Count);
foreach (var kvp in QuestData)
{
writer.Write(kvp.Key);
QuestWriter.Quests(writer, kvp.Value);
}
writer.Write(ChainData.Count);
foreach (var kvp in ChainData)
{
writer.Write(kvp.Key);
QuestWriter.Chains(writer, kvp.Value);
}
TierQuestInfo.Save(writer);
});
}
public static void OnLoad()
{
Persistence.Deserialize(
FilePath,
reader =>
{
int version = reader.ReadInt();
int count = reader.ReadInt();
for (int i = 0; i < count; i++)
{
PlayerMobile pm = reader.ReadMobile() as PlayerMobile;
List<BaseQuest> quests = QuestReader.Quests(reader, pm);
if (pm != null)
QuestData[pm] = quests;
}
count = reader.ReadInt();
for (int i = 0; i < count; i++)
{
PlayerMobile pm = reader.ReadMobile() as PlayerMobile;
Dictionary<QuestChain, BaseChain> dic = QuestReader.Chains(reader);
if (pm != null)
ChainData[pm] = dic;
}
TierQuestInfo.Load(reader);
});
}
}
}

View File

@@ -0,0 +1,966 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Server.ContextMenus;
using Server.Mobiles;
using Server.Regions;
using Server.Targeting;
namespace Server.Engines.Quests
{
public class QuestHelper
{
public static void Initialize()
{
EventSink.OnKilledBy += OnKilledBy;
}
public static void RemoveAcceleratedSkillgain(PlayerMobile from)
{
Region region = from.Region;
while (region != null)
{
if (region is ApprenticeRegion && ((ApprenticeRegion)region).Table[from] is BuffInfo)
{
BuffInfo.RemoveBuff(from, (BuffInfo)((ApprenticeRegion)region).Table[from]);
((ApprenticeRegion)region).Table[from] = null;
}
region = region.Parent;
}
}
public static BaseQuest RandomQuest(PlayerMobile from, Type[] quests, object quester)
{
return RandomQuest(from, quests, quester, quests != null && quests.Length == 1);
}
public static BaseQuest RandomQuest(PlayerMobile from, Type[] quests, object quester, bool message)
{
if (quests == null)
return null;
BaseQuest quest = null;
if (quester is ITierQuester)
{
quest = TierQuestInfo.RandomQuest(from, (ITierQuester)quester);
}
else if (quests.Length > 0)
{
// give it 10 tries to generate quest
for (int i = 0; i < 10; i++)
{
quest = Construct(quests[Utility.Random(quests.Length)]) as BaseQuest;
}
}
if (quest != null)
{
quest.Owner = from;
quest.Quester = quester;
if (CanOffer(from, quest, quester, message))
{
return quest;
}
else if (quester is Mobile && message)
{
if (quester is MondainQuester)
{
((MondainQuester)quester).OnOfferFailed();
}
else if (quester is Mobile)
{
((Mobile)quester).Say(1080107); // I'm sorry, I have nothing for you at this time.
}
}
}
return null;
}
public static bool CanOffer(PlayerMobile from, BaseQuest quest, object quester, bool message)
{
if (!quest.CanOffer())
return false;
if (quest.ChainID != QuestChain.None)
{
// if a player wants to start quest chain (already started) again (not osi)
if (from.Chains.ContainsKey(quest.ChainID) && FirstChainQuest(quest, quest.Quester))
{
return false;
}
// if player already has an active quest from the chain
else if (InChainProgress(from, quest))
{
return false;
}
}
if (!Delayed(from, quest, quester, message))
return false;
for (int i = quest.Objectives.Count - 1; i >= 0; i --)
{
Type type = quest.Objectives[i].Type();
if (type == null)
continue;
for (int j = from.Quests.Count - 1; j >= 0; j --)
{
BaseQuest pQuest = from.Quests[j];
for (int k = pQuest.Objectives.Count - 1; k >= 0; k --)
{
BaseObjective obj = pQuest.Objectives[k];
if (type == obj.Type() && (quest.ChainID == QuestChain.None || quest.ChainID == pQuest.ChainID))
return false;
}
}
}
return true;
}
public static bool Delayed(PlayerMobile player, BaseQuest quest, object quester, bool message)
{
var restartInfo = GetRestartInfo(player, quest.GetType());
if (restartInfo != null)
{
if (quest.DoneOnce)
{
if (message && quester is Mobile)
{
((Mobile)quester).Say(1075454); // I can not offer you the quest again.
}
return false;
}
DateTime endTime = restartInfo.RestartTime;
if (DateTime.UtcNow < endTime)
{
if (message && quester is Mobile)
{
var ts = endTime - DateTime.UtcNow;
string str;
if (ts.TotalDays > 1)
str = String.Format("I cannot offer this quest again for about {0} more days.", ts.TotalDays);
else if (ts.TotalHours > 1)
str = String.Format("I cannot offer this quest again for about {0} more hours.", ts.TotalHours);
else if (ts.TotalMinutes > 1)
str = String.Format("I cannot offer this quest again for about {0} more minutes.", ts.TotalMinutes);
else
str = "I can offer this quest again very soon.";
((Mobile)quester).SayTo(player, false, str);
}
return false;
}
if (quest.RestartDelay > TimeSpan.Zero)
{
player.DoneQuests.Remove(restartInfo);
}
return true;
}
return true;
}
public static QuestRestartInfo GetRestartInfo(PlayerMobile pm, Type quest)
{
return pm.DoneQuests.FirstOrDefault(ri => ri.QuestType == quest);
}
public static bool CheckDoneOnce(PlayerMobile player, BaseQuest quest, Mobile quester, bool message)
{
return quest.DoneOnce && CheckDoneOnce(player, quest.GetType(), quester, message);
}
public static bool CheckDoneOnce(PlayerMobile player, Type questType, Mobile quester, bool message)
{
if (player.DoneQuests.Any(x => x.QuestType == questType))
{
if (message && quester != null)
{
quester.SayTo(player, 1075454, 0x3B2); // I can not offer you the quest again.
}
return true;
}
return false;
}
public static bool TryReceiveQuestItem(PlayerMobile player, Type type, TimeSpan delay)
{
if (type.IsSubclassOf(typeof(Item)))
{
var info = player.DoneQuests.FirstOrDefault(x => x.QuestType == type);
if (info != null)
{
DateTime endTime = info.RestartTime;
if (DateTime.UtcNow < endTime)
{
TimeSpan ts = endTime - DateTime.UtcNow;
if (ts.Days > 0)
{
player.SendLocalizedMessage(1158377, String.Format("{0}\t{1}", ts.Days.ToString(), "day[s]"));
}
else if (ts.Hours > 0)
{
player.SendLocalizedMessage(1158377, String.Format("{0}\t{1}", ts.Hours.ToString(), "hour[s]"));
}
else
{
player.SendLocalizedMessage(1158377, String.Format("{0}\t{1}", ts.Minutes.ToString(), "minute[s]"));
}
return false;
}
else
{
info.Reset(delay);
}
}
else
{
player.DoneQuests.Add(new QuestRestartInfo(type, delay));
}
return true;
}
return false;
}
public static void Delay(PlayerMobile player, Type type, TimeSpan delay)
{
var restartInfo = GetRestartInfo(player, type);
if (restartInfo != null)
{
restartInfo.Reset(delay);
return;
}
player.DoneQuests.Add(new QuestRestartInfo(type, delay));
}
/// <summary>
/// Called in BaseQuestItem.cs
/// </summary>
/// <param name="player"></param>
/// <param name="quests"></param>
/// <returns></returns>
public static bool InProgress(PlayerMobile player, Type[] quests)
{
if (quests == null)
return false;
var quest = player.Quests.FirstOrDefault(q => quests.Any(questerType => questerType == q.GetType()));
if (quest != null)
{
if (quest.Completed)
{
player.SendGump(new MondainQuestGump(quest, MondainQuestGump.Section.Complete, false, true));
}
else
{
player.SendGump(new MondainQuestGump(quest, MondainQuestGump.Section.InProgress, false));
quest.InProgress();
}
return true;
}
/*for (int i = 0; i < quests.Length; i ++)
{
for (int j = 0; j < player.Quests.Count; j ++)
{
BaseQuest quest = player.Quests[j];
if (quests[i].IsAssignableFrom(quest.GetType()))
{
if (quest.Completed)
{
player.SendGump(new MondainQuestGump(quest, MondainQuestGump.Section.Complete, false, true));
}
else
{
player.SendGump(new MondainQuestGump(quest, MondainQuestGump.Section.InProgress, false));
quest.InProgress();
}
return true;
}
}
}*/
return false;
}
/// <summary>
/// Called in MondainQuester.cs
/// </summary>
/// <param name="player"></param>
/// <param name="quester"></param>
/// <returns></returns>
public static bool InProgress(PlayerMobile player, Mobile quester)
{
var quest = player.Quests.FirstOrDefault(q => q.QuesterType == quester.GetType());
if (quest != null)
{
if (quest.Completed)
{
if (quest.Complete == null && !AnyRewards(quest))
quest.GiveRewards();
else
player.SendGump(new MondainQuestGump(quest, MondainQuestGump.Section.Complete, false, true));
}
else
{
player.SendGump(new MondainQuestGump(quest, MondainQuestGump.Section.InProgress, false));
quest.InProgress();
}
return true;
}
/*for (int i = 0; i < player.Quests.Count; i ++)
{
BaseQuest quest = player.Quests[i];
if (quest.Quester == null && quest.QuesterType == null)
continue;
if (quest.QuesterType == quester.GetType())
{
if (quest.Completed)
{
if (quest.Complete == null && !AnyRewards(quest))
quest.GiveRewards();
else
player.SendGump(new MondainQuestGump(quest, MondainQuestGump.Section.Complete, false, true));
}
else
{
player.SendGump(new MondainQuestGump(quest, MondainQuestGump.Section.InProgress, false));
quest.InProgress();
}
return true;
}
}*/
return false;
}
public static bool AnyRewards(BaseQuest quest)
{
for (int i = 0; i < quest.Rewards.Count; i ++)
{
BaseReward reward = quest.Rewards[i];
if (reward.Type != null)
return true;
}
return false;
}
public static bool DeliveryArrived(PlayerMobile player, BaseVendor vendor)
{
for (int i = 0; i < player.Quests.Count; i ++)
{
BaseQuest quest = player.Quests[i];
for (int j = 0; j < quest.Objectives.Count; j ++)
{
BaseObjective objective = quest.Objectives[j];
if (objective is DeliverObjective)
{
DeliverObjective deliver = (DeliverObjective)objective;
if (deliver.Update(vendor))
{
if (quest.Completed)
{
player.SendLocalizedMessage(1046258, null, 0x23); // Your quest is complete.
player.PlaySound(quest.CompleteSound);
quest.OnCompleted();
if (vendor is MondainQuester)
player.SendGump(new MondainQuestGump(player, quest, MondainQuestGump.Section.Complete, false, true, (MondainQuester)vendor));
else
player.SendGump(new MondainQuestGump(quest, MondainQuestGump.Section.Complete, false, true));
}
return true;
}
}
}
}
return false;
}
public static bool QuestLimitReached(PlayerMobile player)
{
if (player.Quests.Count >= 10)
{
player.SendLocalizedMessage(1075141); // You are too busy with other tasks at this time.
return true;
}
return false;
}
public static bool FirstChainQuest(BaseQuest quest, object quester)
{
return quest != null && BaseChain.Chains[(int)quest.ChainID] != null && BaseChain.Chains[(int)quest.ChainID].Length > 0 && BaseChain.Chains[(int)quest.ChainID][0] == quest.GetType();
}
public static Type FindFirstChainQuest(BaseQuest quest)
{
if (quest == null || quest.ChainID == QuestChain.None || BaseChain.Chains[(int)quest.ChainID] == null || BaseChain.Chains[(int)quest.ChainID].Length == 0)
return null;
return BaseChain.Chains[(int)quest.ChainID][0];
}
public static bool InChainProgress(PlayerMobile pm, BaseQuest quest)
{
return pm.Quests.Any(q => q.ChainID != QuestChain.None && q.ChainID == quest.ChainID && q.GetType() != quest.GetType());
}
public static Region FindRegion(string name)
{
if (name == null)
return null;
Region reg = null;
if (Map.Trammel.Regions.TryGetValue(name, out reg))
return reg;
if (Map.Felucca.Regions.TryGetValue(name, out reg))
return reg;
if (Map.Ilshenar.Regions.TryGetValue(name, out reg))
return reg;
if (Map.Malas.Regions.TryGetValue(name, out reg))
return reg;
if (Map.Tokuno.Regions.TryGetValue(name, out reg))
return reg;
if (Map.TerMur.Regions.TryGetValue(name, out reg))
return reg;
return reg;
}
public static void CompleteQuest(PlayerMobile from, BaseQuest quest)
{
if (quest == null)
return;
for (int i = 0; i < quest.Objectives.Count; i ++)
{
BaseObjective obj = quest.Objectives[i];
obj.Complete();
}
from.SendLocalizedMessage(1046258, null, 0x23); // Your quest is complete.
from.SendGump(new MondainQuestGump(quest, MondainQuestGump.Section.Complete, false, true));
from.PlaySound(quest.CompleteSound);
quest.OnCompleted();
}
public static void DeleteItems(PlayerMobile from, Type itemType, int amount, bool questItem)
{
if (from.Backpack == null || itemType == null || amount <= 0)
return;
Item[] items = from.Backpack.FindItemsByType(itemType);
int deleted = 0;
for (int i = items.Length - 1; i >= 0 && deleted < amount; i --)
{
Item item = items[i];
if (item.QuestItem || !questItem)
{
item.QuestItem = false;
if (deleted + item.Amount > amount)
{
item.Amount -= amount - deleted;
deleted += amount - deleted;
}
else
{
item.Delete();
deleted += item.Amount;
}
}
}
if (deleted < amount)
{
for (int i = from.Items.Count - 1; i >= 0 && deleted < amount; i --)
{
Item item = from.Items[i];
if (item.QuestItem || !questItem)
{
if (itemType.IsAssignableFrom(item.GetType()))
{
deleted += item.Amount;
item.Delete();
}
}
}
}
}
public static void DeleteItems(BaseQuest quest)
{
for (int i = 0; i < quest.Objectives.Count; i ++)
{
BaseObjective objective = quest.Objectives[i];
DeleteItems(quest.Owner, objective.Type(), objective.MaxProgress, true);
RemoveStatus(quest.Owner, objective.Type());
}
}
public static bool TryDeleteItems(BaseQuest quest)
{
if (quest == null)
return false;
bool complete = false;
for (int i = 0; i < quest.Objectives.Count && !complete; i ++)
{
if (quest.Objectives[i] is ObtainObjective)
{
ObtainObjective obtain = (ObtainObjective)quest.Objectives[i];
if (CountQuestItems(quest.Owner, obtain.Obtain) >= obtain.MaxProgress)
{
if (!quest.AllObjectives)
{
complete = true;
}
}
else
{
return false;
}
}
else if (quest.Objectives[i] is DeliverObjective)
{
DeliverObjective deliver = (DeliverObjective)quest.Objectives[i];
if (quest.StartingItem != null)
continue;
else if (deliver.MaxProgress > CountQuestItems(quest.Owner, deliver.Delivery))
{
quest.Owner.SendLocalizedMessage(1074813); // You have failed to complete your delivery.
deliver.Fail();
return false;
}
}
}
DeleteItems(quest);
return true;
}
public static int CountQuestItems(PlayerMobile from, Type type)
{
int count = 0;
if (from.Backpack == null)
return count;
Item[] items = from.Backpack.FindItemsByType(type);
for (int i = 0; i < items.Length; i ++)
{
Item item = items[i];
if (item.QuestItem)
count += item.Amount;
}
return count;
}
public static int RemoveStatus(PlayerMobile from, Type type)
{
if (type == null)
return 0;
Item[] items = from.Backpack.FindItemsByType(type);
int count = 0;
for (int i = 0; i < items.Length; i ++)
{
Item item = items[i];
if (item.QuestItem)
{
count += 1;
item.QuestItem = false;
}
}
return count;
}
public static void RemoveStatus(PlayerMobile from, Item item)
{
for (int i = from.Quests.Count - 1; i >= 0; i --)
{
BaseQuest quest = from.Quests[i];
for (int j = quest.Objectives.Count - 1; j >= 0; j --)
{
if (quest.Objectives[j] is ObtainObjective)
{
ObtainObjective obtain = (ObtainObjective)quest.Objectives[j];
if (obtain.Obtain != null && obtain.Obtain.IsAssignableFrom(item.GetType()))
{
obtain.CurProgress -= item.Amount;
item.QuestItem = false;
from.SendLocalizedMessage(1074769); // An item must be in your backpack (and not in a container within) to be toggled as a quest item.
return;
}
}
else if (quest.Objectives[j] is DeliverObjective)
{
DeliverObjective deliver = (DeliverObjective)quest.Objectives[j];
if (deliver.Delivery != null && deliver.Delivery.IsAssignableFrom(item.GetType()))
{
from.SendLocalizedMessage(1074813); // You have failed to complete your delivery.
DeleteItems(from, deliver.Delivery, deliver.MaxProgress, false);
deliver.Fail();
item.Delete();
return;
}
}
}
}
}
public static void OnKilledBy(OnKilledByEventArgs e)
{
if (e.KilledBy is PlayerMobile)
{
CheckCreature((PlayerMobile)e.KilledBy, e.Killed);
}
}
public static bool CheckCreature(PlayerMobile player, Mobile creature)
{
for (int i = player.Quests.Count - 1; i >= 0; i --)
{
BaseQuest quest = player.Quests[i];
for (int j = quest.Objectives.Count - 1; j >= 0; j --)
{
if (quest.Objectives[j] is SlayObjective)
{
SlayObjective slay = (SlayObjective)quest.Objectives[j];
if (slay.Update(creature))
{
if (quest.Completed)
quest.OnCompleted();
else if (slay.Completed)
player.PlaySound(quest.UpdateSound);
return true;
}
}
}
}
return false;
}
public static bool CheckItem(PlayerMobile player, Item item)
{
for (int i = player.Quests.Count - 1; i >= 0; i --)
{
BaseQuest quest = player.Quests[i];
for (int j = quest.Objectives.Count - 1; j >= 0; j --)
{
BaseObjective objective = quest.Objectives[j];
if (objective is ObtainObjective)
{
ObtainObjective obtain = (ObtainObjective)objective;
if (obtain.Update(item))
{
if (quest.Completed)
quest.OnCompleted();
else if (obtain.Completed)
player.PlaySound(quest.UpdateSound);
return true;
}
}
}
}
return false;
}
public static bool CheckRewardItem(PlayerMobile player, Item item)
{
foreach(var quest in player.Quests.Where(q => q.Objectives.Any(obj => obj is ObtainObjective)))
{
foreach (var obtain in quest.Objectives.OfType<ObtainObjective>())
{
if (obtain.IsObjective(item))
{
obtain.CurProgress += item.Amount;
quest.OnObjectiveUpdate(item);
return true;
}
}
}
return false;
}
public static bool CheckSkill(PlayerMobile player, Skill skill)
{
for (int i = player.Quests.Count - 1; i >= 0; i --)
{
BaseQuest quest = player.Quests[i];
for (int j = quest.Objectives.Count - 1; j >= 0; j --)
{
BaseObjective objective = quest.Objectives[j];
if (objective is ApprenticeObjective)
{
ApprenticeObjective apprentice = (ApprenticeObjective)objective;
if (apprentice.Update(skill))
{
if (quest.Completed)
quest.OnCompleted();
else if (apprentice.Completed)
player.PlaySound(quest.UpdateSound);
}
}
}
}
return false;
}
public static bool EnhancedSkill(PlayerMobile player, Skill skill)
{
if (player == null || player.Region == null || skill == null)
return false;
for (int i = player.Quests.Count - 1; i >= 0; i --)
{
BaseQuest quest = player.Quests[i];
for (int j = quest.Objectives.Count - 1; j >= 0; j --)
{
BaseObjective objective = quest.Objectives[j];
if (objective is ApprenticeObjective && !objective.Completed)
{
ApprenticeObjective apprentice = (ApprenticeObjective)objective;
if (apprentice.Region != null)
{
if (player.Region.IsPartOf(apprentice.Region) && skill.SkillName == apprentice.Skill)
return true;
}
}
}
}
return false;
}
public static object Construct(Type type)
{
if (type == null)
return null;
try
{
return Activator.CreateInstance(type);
}
catch
{
return null;
}
}
public static void StartTimer(PlayerMobile player)
{
if (player == null || player.Quests == null)
return;
for (int i = player.Quests.Count - 1; i >= 0; i --)
player.Quests[i].StartTimer();
}
public static void StopTimer(PlayerMobile player)
{
if (player == null || player.Quests == null)
return;
for (int i = player.Quests.Count - 1; i >= 0; i --)
player.Quests[i].StopTimer();
}
public static void GetContextMenuEntries(List<ContextMenuEntry> list)
{
if (list == null)
return;
list.Add(new SelectQuestItem());
}
public static bool FindCompletedQuest(PlayerMobile from, Type type, bool delete)
{
if (type == null)
return false;
for (int i = from.DoneQuests.Count - 1; i >= 0; i --)
{
QuestRestartInfo restartInfo = from.DoneQuests[i];
if (restartInfo.QuestType == type)
{
if (delete)
from.DoneQuests.RemoveAt(i);
return true;
}
}
return false;
}
public static bool HasQuest<T>( PlayerMobile from ) where T : BaseQuest
{
return GetQuest( from, typeof( T ) ) != null;
}
public static bool HasQuest(PlayerMobile from, Type t)
{
return GetQuest(from, t) != null;
}
public static BaseQuest GetQuest(PlayerMobile from, Type type)
{
if (type == null)
return null;
for (int i = from.Quests.Count - 1; i >= 0; i --)
{
BaseQuest quest = from.Quests[i];
if (quest.GetType() == type)
return quest;
}
return null;
}
public static T GetQuest<T>(PlayerMobile pm) where T : BaseQuest
{
return pm.Quests.FirstOrDefault(quest => quest.GetType() == typeof(T)) as T;
}
}
public class SelectQuestItem : ContextMenuEntry
{
public SelectQuestItem()
: base(6169)
{
}
public override void OnClick()
{
if (!Owner.From.Alive)
return;
Owner.From.SendLocalizedMessage(1072352); // Target the item you wish to toggle Quest Item status on <ESC> to cancel
Owner.From.BeginTarget(-1, false, TargetFlags.None, new TargetCallback(ToggleQuestItem_Callback));
}
private void ToggleQuestItem_Callback(Mobile from, object obj)
{
if (from is PlayerMobile)
{
PlayerMobile player = (PlayerMobile)from;
if (obj is Item)
{
Item item = (Item)obj;
if (item.Parent != null && item.Parent == player.Backpack)
{
if (!QuestHelper.CheckItem(player, item))
player.SendLocalizedMessage(1072355, null, 0x23); // That item does not match any of your quest criteria
}
else
player.SendLocalizedMessage(1074769); // An item must be in your backpack (and not in a container within) to be toggled as a quest item.
}
else
player.SendLocalizedMessage(1074769); // An item must be in your backpack (and not in a container within) to be toggled as a quest item.
player.BeginTarget(-1, false, TargetFlags.None, new TargetCallback(ToggleQuestItem_Callback));
}
}
}
}

View File

@@ -0,0 +1,204 @@
#region References
using System;
using System.Collections.Generic;
using System.IO;
using Server.Mobiles;
#endregion
namespace Server.Engines.Quests
{
public class QuestReader
{
public static int Version(GenericReader reader)
{
if (reader == null)
{
return -1;
}
if (reader.PeekInt() == 0x7FFFFFFF)
{
reader.ReadInt(); // Preamble 0x7FFFFFFF
return reader.ReadInt();
}
return -1;
}
public static bool SubRead(GenericReader reader, Action<GenericReader> deserializer)
{
if (reader == null)
{
return false;
}
using (var s = new MemoryStream())
{
var length = reader.ReadLong();
while (s.Length < length)
{
s.WriteByte(reader.ReadByte());
}
if (deserializer != null)
{
s.Position = 0;
var r = new BinaryFileReader(new BinaryReader(s));
try
{
deserializer(r);
}
catch (Exception e)
{
Console.WriteLine("Quest Load Failure: {0}", Utility.FormatDelegate(deserializer));
Console.WriteLine(e);
return false;
}
finally
{
r.Close();
}
}
}
return true;
}
public static List<BaseQuest> Quests(GenericReader reader, PlayerMobile player)
{
var quests = new List<BaseQuest>();
if (reader == null)
{
return quests;
}
var version = Version(reader);
var count = reader.ReadInt();
for (var i = 0; i < count; i++)
{
var quest = Construct(reader) as BaseQuest;
if (quest == null)
{
if (version >= 0)
{
SubRead(reader, null);
}
continue;
}
quest.Owner = player;
if (version < 0)
{
quest.Deserialize(reader);
}
else if (!SubRead(reader, quest.Deserialize))
{
continue;
}
quests.Add(quest);
}
return quests;
}
public static Dictionary<QuestChain, BaseChain> Chains(GenericReader reader)
{
var chains = new Dictionary<QuestChain, BaseChain>();
if (reader == null)
{
return chains;
}
Version(reader);
var count = reader.ReadInt();
for (var i = 0; i < count; i++)
{
var chain = reader.ReadInt();
var quest = Type(reader);
var quester = Type(reader);
if (Enum.IsDefined(typeof(QuestChain), chain) && quest != null && quester != null)
{
chains[(QuestChain)chain] = new BaseChain(quest, quester);
}
}
return chains;
}
public static object Object(GenericReader reader)
{
if (reader == null)
{
return null;
}
Version(reader);
var type = reader.ReadByte();
switch (type)
{
case 0x0:
return null; // invalid
case 0x1:
return reader.ReadInt();
case 0x2:
return reader.ReadString();
case 0x3:
return reader.ReadItem();
case 0x4:
return reader.ReadMobile();
}
return null;
}
public static Type Type(GenericReader reader)
{
if (reader == null)
{
return null;
}
var type = reader.ReadString();
if (type != null)
{
return ScriptCompiler.FindTypeByFullName(type, false);
}
return null;
}
public static object Construct(GenericReader reader)
{
var type = Type(reader);
try
{
return Activator.CreateInstance(type);
}
catch
{
return null;
}
}
}
}

View File

@@ -0,0 +1,161 @@
#region References
using System;
using System.Collections.Generic;
using System.IO;
#endregion
namespace Server.Engines.Quests
{
public class QuestWriter
{
public static int Version(GenericWriter writer, int version)
{
if (writer == null)
{
return -1;
}
writer.Write(0x7FFFFFFF); // Preamble
writer.Write(version);
return version;
}
public static bool SubWrite(GenericWriter writer, Action<GenericWriter> serializer)
{
if (writer == null)
{
return false;
}
using (var s = new MemoryStream())
{
var w = new BinaryFileWriter(s, true);
try
{
serializer(w);
}
catch (Exception e)
{
Console.WriteLine("Quest Save Failure: {0}", Utility.FormatDelegate(serializer));
Console.WriteLine(e);
writer.Write(0L);
return false;
}
finally
{
w.Flush();
}
writer.Write(s.Length);
s.Position = 0;
while (s.Position < s.Length)
{
writer.Write((byte)s.ReadByte());
}
}
return true;
}
public static void Quests(GenericWriter writer, List<BaseQuest> quests)
{
if (writer == null)
{
return;
}
Version(writer, 0);
if (quests == null)
{
writer.Write(0);
return;
}
writer.Write(quests.Count);
foreach (var quest in quests)
{
Type(writer, quest.GetType());
SubWrite(writer, quest.Serialize);
}
}
public static void Chains(GenericWriter writer, Dictionary<QuestChain, BaseChain> chains)
{
if (writer == null)
{
return;
}
Version(writer, 0);
if (chains == null)
{
writer.Write(0);
return;
}
writer.Write(chains.Count);
foreach (var pair in chains)
{
writer.Write((int)pair.Key);
Type(writer, pair.Value.CurrentQuest);
Type(writer, pair.Value.Quester);
}
}
public static void Object(GenericWriter writer, object obj)
{
if (writer == null)
{
return;
}
Version(writer, 0);
if (obj is int)
{
writer.Write((byte)0x1);
writer.Write((int)obj);
}
else if (obj is String)
{
writer.Write((byte)0x2);
writer.Write((String)obj);
}
else if (obj is Item)
{
writer.Write((byte)0x3);
writer.Write((Item)obj);
}
else if (obj is Mobile)
{
writer.Write((byte)0x4);
writer.Write((Mobile)obj);
}
else
{
writer.Write((byte)0x0); // invalid
}
}
public static void Type(GenericWriter writer, Type type)
{
if (writer != null)
{
writer.Write(type == null ? null : type.FullName);
}
}
}
}