public static MLQuestInstance Deserialize(GenericReader reader, int version, PlayerMobile pm)
        {
            MLQuest quest = MLQuestSystem.ReadQuestRef(reader);

            // TODO: Serialize quester TYPE too, the quest giver reference then becomes optional (only for escorts)
            IQuestGiver quester = World.FindEntity(reader.ReadInt()) as IQuestGiver;

            bool claimReward = reader.ReadBool();
            int  objectives  = reader.ReadInt();

            MLQuestInstance instance;

            if (quest != null && quester != null && pm != null)
            {
                instance             = quest.CreateInstance(quester, pm);
                instance.ClaimReward = claimReward;
            }
            else
            {
                instance = null;
            }

            for (int i = 0; i < objectives; ++i)
            {
                BaseObjectiveInstance.Deserialize(reader, version, (instance != null && i < instance.Objectives.Length) ? instance.Objectives[i] : null);
            }

            if (instance != null)
            {
                instance.Slice();
            }

            return(instance);
        }
        public MLQuestInstance(MLQuest quest, IQuestGiver quester, PlayerMobile player)
        {
            m_Quest = quest;

            m_Quester     = quester;
            m_QuesterType = (quester == null) ? null : quester.GetType();
            m_Player      = player;

            m_Accepted = DateTime.UtcNow;
            m_Flags    = MLQuestInstanceFlags.None;

            m_ObjectiveInstances = new BaseObjectiveInstance[quest.Objectives.Count];

            BaseObjectiveInstance obj;
            bool timed = false;

            for (int i = 0; i < quest.Objectives.Count; ++i)
            {
                m_ObjectiveInstances[i] = obj = quest.Objectives[i].CreateInstance(this);

                if (obj.IsTimed)
                {
                    timed = true;
                }
            }

            Register();

            if (timed)
            {
                m_Timer = Timer.DelayCall(TimeSpan.FromSeconds(5), TimeSpan.FromSeconds(5), Slice);
            }
        }
        public static void Register(MLQuest quest, params Type[] questerTypes)
        {
            Register(quest.GetType(), quest);

            foreach (Type questerType in questerTypes)
            {
                RegisterQuestGiver(quest, questerType);
            }
        }
        private static void RegisterQuestGiver(MLQuest quest, Type questerType)
        {
            List <MLQuest> questList;

            if (!m_QuestGivers.TryGetValue(questerType, out questList))
            {
                m_QuestGivers[questerType] = questList = new List <MLQuest>();
            }

            questList.Add(quest);
        }
Exemple #5
0
            public static MLDoneQuestInfo Deserialize(GenericReader reader, int version)
            {
                MLQuest  quest         = MLQuestSystem.ReadQuestRef(reader);
                DateTime nextAvailable = reader.ReadDateTime();

                if (quest == null || !quest.RecordCompletion)
                {
                    return(null); // forget about this record
                }
                return(new MLDoneQuestInfo(quest, nextAvailable));
            }
Exemple #6
0
        public MLQuestInstance FindInstance(Type questType)
        {
            MLQuest quest = MLQuestSystem.FindQuest(questType);

            if (quest == null)
            {
                return(null);
            }

            return(FindInstance(quest));
        }
Exemple #7
0
        public bool HasDoneQuest(MLQuest quest)
        {
            foreach (MLDoneQuestInfo info in m_DoneQuests)
            {
                if (info.m_Quest == quest)
                {
                    return(true);
                }
            }

            return(false);
        }
        public static void Deserialize(GenericReader reader, int version)
        {
            MLQuest quest      = MLQuestSystem.ReadQuestRef(reader);
            int     oldVersion = reader.ReadInt();

            if (quest == null)
            {
                return; // not saved or no longer exists
            }
            quest.Refresh(oldVersion);
            quest.m_Deserialized = true;
        }
Exemple #9
0
        public MLQuestInstance FindInstance(MLQuest quest)
        {
            foreach (MLQuestInstance instance in m_QuestInstances)
            {
                if (instance.Quest == quest)
                {
                    return(instance);
                }
            }

            return(null);
        }
Exemple #10
0
        public void RemoveDoneQuest(MLQuest quest)
        {
            for (int i = m_DoneQuests.Count - 1; i >= 0; --i)
            {
                MLDoneQuestInfo info = m_DoneQuests[i];

                if (info.m_Quest == quest)
                {
                    m_DoneQuests.RemoveAt(i);
                }
            }
        }
Exemple #11
0
        public void SetDoneQuest(MLQuest quest, DateTime nextAvailable)
        {
            foreach (MLDoneQuestInfo info in m_DoneQuests)
            {
                if (info.m_Quest == quest)
                {
                    info.m_NextAvailable = nextAvailable;
                    return;
                }
            }

            m_DoneQuests.Add(new MLDoneQuestInfo(quest, nextAvailable));
        }
Exemple #12
0
        public bool HasDoneQuest(MLQuest quest, out DateTime nextAvailable)
        {
            nextAvailable = DateTime.MinValue;

            foreach (MLDoneQuestInfo info in m_DoneQuests)
            {
                if (info.m_Quest == quest)
                {
                    nextAvailable = info.m_NextAvailable;
                    return(true);
                }
            }

            return(false);
        }
Exemple #13
0
        public MLQuestContext(GenericReader reader, int version)
        {
            m_Owner          = reader.ReadMobile <PlayerMobile>();
            m_QuestInstances = new List <MLQuestInstance>();
            m_DoneQuests     = new List <MLDoneQuestInfo>();
            m_ChainOffers    = new List <MLQuest>();

            int instances = reader.ReadInt();

            for (int i = 0; i < instances; ++i)
            {
                MLQuestInstance instance = MLQuestInstance.Deserialize(reader, version, m_Owner);

                if (instance != null)
                {
                    m_QuestInstances.Add(instance);
                }
            }

            int doneQuests = reader.ReadInt();

            for (int i = 0; i < doneQuests; ++i)
            {
                MLDoneQuestInfo info = MLDoneQuestInfo.Deserialize(reader, version);

                if (info != null)
                {
                    m_DoneQuests.Add(info);
                }
            }

            int chainOffers = reader.ReadInt();

            for (int i = 0; i < chainOffers; ++i)
            {
                MLQuest quest = MLQuestSystem.ReadQuestRef(reader);

                if (quest != null && quest.IsChainTriggered)
                {
                    m_ChainOffers.Add(quest);
                }
            }

            m_Flags = (MLQuestFlag)reader.ReadEncodedInt();
        }
Exemple #14
0
        public override void Serialize(GenericWriter writer)
        {
            base.Serialize(writer);

            writer.Write((int)2); // version
            writer.Write(MLQuestSystem.Contexts.Count);

            foreach (MLQuestContext context in MLQuestSystem.Contexts.Values)
            {
                context.Serialize(writer);
            }

            writer.Write(MLQuestSystem.Quests.Count);

            foreach (MLQuest quest in MLQuestSystem.Quests.Values)
            {
                MLQuest.Serialize(writer, quest);
            }
        }
        public static MLQuest RandomStarterQuest(IQuestGiver quester, PlayerMobile pm, MLQuestContext context)
        {
            List <MLQuest> quests = quester.MLQuests;

            if (quests.Count == 0)
            {
                return(null);
            }

            m_EligiblePool.Clear();
            MLQuest fallback = null;

            foreach (MLQuest quest in quests)
            {
                if (quest.IsChainTriggered || (context != null && context.IsDoingQuest(quest)))
                {
                    continue;
                }

                /*
                 * Save first quest that reaches the CanOffer call.
                 * If no quests are valid at all, return this quest for displaying the CanOffer error message.
                 */
                if (fallback == null)
                {
                    fallback = quest;
                }

                if (quest.CanOffer(quester, pm, context, false))
                {
                    m_EligiblePool.Add(quest);
                }
            }

            if (m_EligiblePool.Count == 0)
            {
                return(fallback);
            }

            return(m_EligiblePool[Utility.Random(m_EligiblePool.Count)]);
        }
        // TODO: Split next quest stuff from SendRewardGump stuff?
        public void SendRewardGump()
        {
            Type nextQuestType = m_Quest.NextQuest;

            if (nextQuestType != null)
            {
                ClaimRewards(); // skip reward gump

                if (Removed)    // rewards were claimed successfully
                {
                    MLQuest nextQuest = MLQuestSystem.FindQuest(nextQuestType);

                    if (nextQuest != null)
                    {
                        nextQuest.SendOffer(m_Quester, m_Player);
                    }
                }
            }
            else
            {
                m_Player.SendGump(new QuestRewardGump(this));
            }
        }
Exemple #17
0
        public override void Deserialize(GenericReader reader)
        {
            base.Deserialize(reader);

            int version  = reader.ReadInt();
            int contexts = reader.ReadInt();

            for (int i = 0; i < contexts; ++i)
            {
                MLQuestContext context = new MLQuestContext(reader, version);

                if (context.Owner != null)
                {
                    MLQuestSystem.Contexts[context.Owner] = context;
                }
            }

            int quests = reader.ReadInt();

            for (int i = 0; i < quests; ++i)
            {
                MLQuest.Deserialize(reader, version);
            }
        }
Exemple #18
0
        public bool HasDoneQuest(Type questType)
        {
            MLQuest quest = MLQuestSystem.FindQuest(questType);

            return(quest != null && HasDoneQuest(quest));
        }
Exemple #19
0
        public bool IsDoingQuest(Type questType)
        {
            MLQuest quest = MLQuestSystem.FindQuest(questType);

            return(quest != null && IsDoingQuest(quest));
        }
Exemple #20
0
 public void SetDoneQuest(MLQuest quest)
 {
     SetDoneQuest(quest, DateTime.MinValue);
 }
Exemple #21
0
        public virtual bool CanOffer(IQuestGiver quester, PlayerMobile pm, MLQuestContext context, bool message)
        {
            if (!m_Activated || quester.Deleted)
            {
                return(false);
            }

            if (context != null)
            {
                if (context.IsFull)
                {
                    if (message)
                    {
                        MLQuestSystem.Tell(quester, pm, 1080107); // I'm sorry, I have nothing for you at this time.
                    }
                    return(false);
                }

                MLQuest checkQuest = this;

                while (checkQuest != null)
                {
                    DateTime nextAvailable;

                    if (context.HasDoneQuest(checkQuest, out nextAvailable))
                    {
                        if (checkQuest.OneTimeOnly)
                        {
                            if (message)
                            {
                                MLQuestSystem.Tell(quester, pm, 1075454); // I cannot offer you the quest again.
                            }
                            return(false);
                        }
                        else if (nextAvailable > DateTime.UtcNow)
                        {
                            if (message)
                            {
                                MLQuestSystem.Tell(quester, pm, 1075575); // I'm sorry, but I don't have anything else for you right now. Could you check back with me in a few minutes?
                            }
                            return(false);
                        }
                    }

                    if (checkQuest.NextQuest == null)
                    {
                        break;
                    }

                    checkQuest = MLQuestSystem.FindQuest(checkQuest.NextQuest);
                }
            }

            foreach (BaseObjective obj in m_Objectives)
            {
                if (!obj.CanOffer(quester, pm, message))
                {
                    return(false);
                }
            }

            return(true);
        }
Exemple #22
0
 public static void Serialize(GenericWriter writer, MLQuest quest)
 {
     MLQuestSystem.WriteQuestRef(writer, quest);
     writer.Write(quest.Version);
 }
Exemple #23
0
 public bool IsDoingQuest(MLQuest quest)
 {
     return(FindInstance(quest) != null);
 }
 public static void WriteQuestRef(GenericWriter writer, MLQuest quest)
 {
     writer.Write((quest != null && quest.SaveEnabled) ? quest.GetType().FullName : null);
 }
        static MLQuestSystem()
        {
            m_Quests      = new Dictionary <Type, MLQuest>();
            m_QuestGivers = new Dictionary <Type, List <MLQuest> >();
            m_Contexts    = new Dictionary <PlayerMobile, MLQuestContext>();

            string cfgPath = Path.Combine(Core.BaseDirectory, Path.Combine("Data", "MLQuests.cfg"));

            Type baseQuestType   = typeof(MLQuest);
            Type baseQuesterType = typeof(IQuestGiver);

            if (File.Exists(cfgPath))
            {
                using (StreamReader sr = new StreamReader(cfgPath))
                {
                    string line;

                    while ((line = sr.ReadLine()) != null)
                    {
                        if (line.Length == 0 || line.StartsWith("#"))
                        {
                            continue;
                        }

                        string[] split = line.Split('\t');

                        Type type = ScriptCompiler.FindTypeByName(split[0]);

                        if (type == null || !baseQuestType.IsAssignableFrom(type))
                        {
                            if (Debug)
                            {
                                Console.WriteLine("Warning: {1} quest type '{0}'", split[0], (type == null) ? "Unknown" : "Invalid");
                            }

                            continue;
                        }

                        MLQuest quest = null;

                        try
                        {
                            quest = Activator.CreateInstance(type) as MLQuest;
                        }
                        catch { }

                        if (quest == null)
                        {
                            continue;
                        }

                        Register(type, quest);

                        for (int i = 1; i < split.Length; ++i)
                        {
                            Type questerType = ScriptCompiler.FindTypeByName(split[i]);

                            if (questerType == null || !baseQuesterType.IsAssignableFrom(questerType))
                            {
                                if (Debug)
                                {
                                    Console.WriteLine("Warning: {1} quester type '{0}'", split[i], (questerType == null) ? "Unknown" : "Invalid");
                                }

                                continue;
                            }

                            RegisterQuestGiver(quest, questerType);
                        }
                    }
                }
            }
        }
        private static bool FindQuest(IQuestGiver quester, PlayerMobile pm, MLQuestContext context, out MLQuest quest, out MLQuestInstance entry)
        {
            quest = null;
            entry = null;

            List <MLQuest> quests      = quester.MLQuests;
            Type           questerType = quester.GetType();

            // 1. Check quests in progress with this NPC (overriding deliveries is intended)
            if (context != null)
            {
                foreach (MLQuest questEntry in quests)
                {
                    MLQuestInstance instance = context.FindInstance(questEntry);

                    if (instance != null && (instance.Quester == quester || (!questEntry.IsEscort && instance.QuesterType == questerType)))
                    {
                        entry = instance;
                        quest = questEntry;
                        return(true);
                    }
                }
            }

            // 2. Check deliveries (overriding chain offers is intended)
            if ((entry = HandleDelivery(pm, quester, questerType)) != null)
            {
                quest = entry.Quest;
                return(true);
            }

            // 3. Check chain quest offers
            if (context != null)
            {
                foreach (MLQuest questEntry in quests)
                {
                    if (questEntry.IsChainTriggered && context.ChainOffers.Contains(questEntry))
                    {
                        quest = questEntry;
                        return(true);
                    }
                }
            }

            // 4. Random quest
            quest = RandomStarterQuest(quester, pm, context);

            return(quest != null);
        }
Exemple #27
0
 public MLDoneQuestInfo(MLQuest quest, DateTime nextAvailable)
 {
     m_Quest         = quest;
     m_NextAvailable = nextAvailable;
 }
        public void ClaimRewards()
        {
            if (m_Quest == null || m_Player == null || m_Player.Deleted || !ClaimReward || Removed)
            {
                return;
            }

            List <Item> rewards = new List <Item>();

            foreach (BaseReward reward in m_Quest.Rewards)
            {
                reward.AddRewardItems(m_Player, rewards);
            }

            if (rewards.Count != 0)
            {
                // On OSI a more naive method of checking is used.
                // For containers, only the actual container item counts.
                bool canFit = true;

                foreach (Item rewardItem in rewards)
                {
                    if (!m_Player.AddToBackpack(rewardItem))
                    {
                        canFit = false;
                        break;
                    }
                }

                if (!canFit)
                {
                    foreach (Item rewardItem in rewards)
                    {
                        rewardItem.Delete();
                    }

                    m_Player.SendLocalizedMessage(1078524); // Your backpack is full. You cannot complete the quest and receive your reward.
                    return;
                }

                foreach (Item rewardItem in rewards)
                {
                    string rewardName = (rewardItem.Name != null) ? rewardItem.Name : String.Concat("#", rewardItem.LabelNumber);

                    if (rewardItem.Stackable)
                    {
                        m_Player.SendLocalizedMessage(1115917, String.Concat(rewardItem.Amount, "\t", rewardName)); // You receive a reward: ~1_QUANTITY~ ~2_ITEM~
                    }
                    else
                    {
                        m_Player.SendLocalizedMessage(1074360, rewardName); // You receive a reward: ~1_REWARD~
                    }
                }
            }

            foreach (BaseObjectiveInstance objective in m_ObjectiveInstances)
            {
                objective.OnRewardClaimed();
            }

            m_Quest.OnRewardClaimed(this);

            MLQuestContext context = PlayerContext;

            if (m_Quest.RecordCompletion && !m_Quest.HasRestartDelay) // Quests with restart delays are logged earlier as per OSI
            {
                context.SetDoneQuest(m_Quest);
            }

            if (m_Quest.IsChainTriggered)
            {
                context.ChainOffers.Remove(m_Quest);
            }

            Type nextQuestType = m_Quest.NextQuest;

            if (nextQuestType != null)
            {
                MLQuest nextQuest = MLQuestSystem.FindQuest(nextQuestType);

                if (nextQuest != null && !context.ChainOffers.Contains(nextQuest))
                {
                    context.ChainOffers.Add(nextQuest);
                }
            }

            Remove();
        }
 private static void Register(Type type, MLQuest quest)
 {
     m_Quests[type] = quest;
 }