Example #1
0
        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);
        }
Example #2
0
        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?.IsDoingQuest(quest) == true)
                {
                    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.
                 */
                fallback ??= quest;

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

            return(m_EligiblePool.Count == 0 ? fallback : m_EligiblePool[Utility.Random(m_EligiblePool.Count)]);
        }
Example #3
0
        public MLQuestInstance(MLQuest quest, IQuestGiver quester, PlayerMobile player)
        {
            Quest = quest;

            m_Quester   = quester;
            QuesterType = quester?.GetType();
            Player      = player;

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

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

            BaseObjectiveInstance obj;
            var timed = false;

            for (var i = 0; i < quest.Objectives.Count; ++i)
            {
                Objectives[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);
            }
        }
Example #4
0
        public static void Register(MLQuest quest, params Type[] questerTypes)
        {
            Register(quest.GetType(), quest);

            foreach (Type questerType in questerTypes)
            {
                RegisterQuestGiver(quest, questerType);
            }
        }
Example #5
0
        private static void RegisterQuestGiver(MLQuest quest, Type questerType)
        {
            if (!QuestGivers.TryGetValue(questerType, out List <MLQuest> questList))
            {
                QuestGivers[questerType] = questList = new List <MLQuest>();
            }

            questList.Add(quest);
        }
Example #6
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));
            }
Example #7
0
        public MLQuestInstance FindInstance(Type questType)
        {
            MLQuest quest = MLQuestSystem.FindQuest(questType);

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

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

            return(false);
        }
Example #9
0
        private static bool FindQuest(
            IQuestGiver quester, PlayerMobile pm, MLQuestContext context, out MLQuest quest,
            out MLQuestInstance entry
            )
        {
            quest = null;
            entry = null;

            var quests      = quester.MLQuests;
            var questerType = quester.GetType();

            // 1. Check quests in progress with this NPC (overriding deliveries is intended)
            if (context != null)
            {
                foreach (var questEntry in quests)
                {
                    var 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 (var 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);
        }
Example #10
0
        public MLQuestInstance FindInstance(MLQuest quest)
        {
            foreach (MLQuestInstance instance in m_QuestInstances)
            {
                if (instance.Quest == quest)
                {
                    return(instance);
                }
            }

            return(null);
        }
Example #11
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);
                }
            }
        }
Example #12
0
        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;
        }
Example #13
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));
        }
Example #14
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);
        }
Example #15
0
        public MLQuestContext(IGenericReader reader, int version)
        {
            Owner          = reader.ReadMobile <PlayerMobile>();
            QuestInstances = new List <MLQuestInstance>();
            m_DoneQuests   = new List <MLDoneQuestInfo>();
            ChainOffers    = new List <MLQuest>();

            int instances = reader.ReadInt();

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

                if (instance != null)
                {
                    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?.IsChainTriggered == true)
                {
                    ChainOffers.Add(quest);
                }
            }

            m_Flags = (MLQuestFlag)reader.ReadEncodedInt();
        }
Example #16
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);
            }
        }
Example #17
0
        // 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));
            }
        }
Example #18
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);
            }
        }
Example #19
0
 private static void Register(Type type, MLQuest quest)
 {
     Quests[type] = quest;
 }
Example #20
0
 public static void Serialize(GenericWriter writer, MLQuest quest)
 {
     MLQuestSystem.WriteQuestRef(writer, quest);
     writer.Write(quest.Version);
 }
Example #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);
        }
Example #22
0
 public static void WriteQuestRef(GenericWriter writer, MLQuest quest)
 {
     writer.Write((quest != null && quest.SaveEnabled) ? quest.GetType().FullName : null);
 }
Example #23
0
        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();
        }
Example #24
0
 public MLDoneQuestInfo(MLQuest quest, DateTime nextAvailable)
 {
     m_Quest         = quest;
     m_NextAvailable = nextAvailable;
 }
Example #25
0
        public bool HasDoneQuest(Type questType)
        {
            MLQuest quest = MLQuestSystem.FindQuest(questType);

            return(quest != null && HasDoneQuest(quest));
        }
Example #26
0
 public void SetDoneQuest(MLQuest quest)
 {
     SetDoneQuest(quest, DateTime.MinValue);
 }
Example #27
0
        static MLQuestSystem()
        {
            Quests      = new Dictionary <Type, MLQuest>();
            QuestGivers = new Dictionary <Type, List <MLQuest> >();
            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 = AssemblyHandler.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
                    {
                        // ignored
                    }

                    if (quest == null)
                    {
                        continue;
                    }

                    Register(type, quest);

                    for (int i = 1; i < split.Length; ++i)
                    {
                        Type questerType = AssemblyHandler.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);
                    }
                }
            }
        }
Example #28
0
        public bool IsDoingQuest(Type questType)
        {
            MLQuest quest = MLQuestSystem.FindQuest(questType);

            return(quest != null && IsDoingQuest(quest));
        }
Example #29
0
 public static void WriteQuestRef(IGenericWriter writer, MLQuest quest)
 {
     writer.Write(quest?.SaveEnabled == true ? quest.GetType().FullName : null);
 }
Example #30
0
 public bool IsDoingQuest(MLQuest quest)
 {
     return(FindInstance(quest) != null);
 }