Ejemplo n.º 1
0
    public NpcScript GetCurrentScript()
    {
        if (DialogType == DialogType.Quest)
        {
            return(ScriptMetadataStorage.GetQuestScriptMetadata(QuestId)?.NpcScripts.First(x => x.Id == ScriptId));
        }

        return(ScriptMetadataStorage.GetNpcScriptMetadata(Npc.Id).NpcScripts.First(x => x.Id == ScriptId));
    }
Ejemplo n.º 2
0
        private static void HandleContinue(GameSession session, PacketReader packet)
        {
            NpcTalk npcTalk = session.Player.NpcTalk;

            if (npcTalk.Npc.IsBeauty())
            {
                HandleBeauty(session);
                return;
            }

            int index = packet.ReadInt(); // selection index

            // index is quest
            if (index <= npcTalk.Quests.Count - 1 && npcTalk.ScriptId == 0)
            {
                npcTalk.QuestId = npcTalk.Quests[index].Basic.Id;
                npcTalk.IsQuest = true;
            }

            ScriptMetadata scriptMetadata = npcTalk.IsQuest ? ScriptMetadataStorage.GetQuestScriptMetadata(npcTalk.QuestId) : ScriptMetadataStorage.GetNpcScriptMetadata(npcTalk.Npc.Id);
            ResponseType   responseType   = npcTalk.IsQuest ? ResponseType.Quest : ResponseType.Dialog;

            if (npcTalk.ScriptId != 0)
            {
                Option option = scriptMetadata.Options.First(x => x.Id == npcTalk.ScriptId);
                if (option.AmountContent <= npcTalk.ContentIndex && option.Goto.Count == 0)
                {
                    session.Send(NpcTalkPacket.Close());
                    return;
                }
            }

            // Find next script id
            int    nextScript = GetNextScript(scriptMetadata, npcTalk, index);
            Option option2    = scriptMetadata.Options.FirstOrDefault(x => x.Id == npcTalk.ScriptId);

            if (option2?.AmountContent > 1 && option2?.AmountContent > npcTalk.ContentIndex)
            {
                nextScript = npcTalk.ScriptId;
            }

            if (npcTalk.ScriptId != nextScript)
            {
                npcTalk.ContentIndex = 1;
            }
            else
            {
                npcTalk.ContentIndex++;
            }

            Option option1       = scriptMetadata.Options.First(x => x.Id == nextScript);
            bool   hasNextScript = option1.Goto.Count != 0;

            if (option1.AmountContent > npcTalk.ContentIndex)
            {
                hasNextScript = true;
            }
            npcTalk.ScriptId = nextScript;

            DialogType dialogType = GetDialogType(scriptMetadata, npcTalk, hasNextScript);

            session.Send(NpcTalkPacket.ContinueChat(nextScript, responseType, dialogType, npcTalk.ContentIndex - 1, npcTalk.QuestId));
        }
Ejemplo n.º 3
0
        private static void HandleContinue(GameSession session, int index)
        {
            NpcTalk npcTalk = session.Player.NpcTalk;

            if (npcTalk.Npc.IsBeauty())
            {
                HandleBeauty(session);
                return;
            }

            ScriptLoader scriptLoader = new ScriptLoader($"Npcs/{npcTalk.Npc.Id}", session);

            // index is quest
            if (index <= npcTalk.Quests.Count - 1 && npcTalk.ScriptId == 0)
            {
                npcTalk.QuestId = npcTalk.Quests[index].Basic.Id;
                npcTalk.IsQuest = true;
            }

            ScriptMetadata scriptMetadata = npcTalk.IsQuest ? ScriptMetadataStorage.GetQuestScriptMetadata(npcTalk.QuestId) : ScriptMetadataStorage.GetNpcScriptMetadata(npcTalk.Npc.Id);
            ResponseType   responseType   = npcTalk.IsQuest ? ResponseType.Quest : ResponseType.Dialog;

            if (npcTalk.ScriptId != 0)
            {
                Option option = scriptMetadata.Options.First(x => x.Id == npcTalk.ScriptId);

                // Find if player has quest condition for type "talk_in" and option id
                QuestHelper.UpdateQuest(session, npcTalk.Npc.Id.ToString(), "talk_in", option.Id.ToString());

                // If npc has no more options, close dialog
                if (option.Contents.Count <= npcTalk.ContentIndex + 1 && option.Contents[npcTalk.ContentIndex].Goto.Count == 0)
                {
                    session.Send(NpcTalkPacket.Close());
                    return;
                }
            }

            int nextScriptId = GetNextScript(scriptMetadata, npcTalk, index, scriptLoader);

            // If last script is different from next, reset content index, else increment content index
            if (npcTalk.ScriptId != nextScriptId)
            {
                npcTalk.ContentIndex = 0;
            }
            else
            {
                npcTalk.ContentIndex++;
            }

            Option nextScript    = scriptMetadata.Options.First(x => x.Id == nextScriptId);
            bool   hasNextScript = nextScript.Contents[npcTalk.ContentIndex].Goto.Count != 0;

            if (nextScript.Contents.Count > npcTalk.ContentIndex + 1)
            {
                hasNextScript = true;
            }
            npcTalk.ScriptId = nextScriptId;

            DialogType dialogType = GetDialogType(scriptMetadata, npcTalk, hasNextScript);

            session.Send(NpcTalkPacket.ContinueChat(nextScriptId, responseType, dialogType, npcTalk.ContentIndex, npcTalk.QuestId));
            // It appears if content has buttonset roulette, it's send again on every continue chat, unsure why since it doesn't break anything
        }
Ejemplo n.º 4
0
    private static void HandleRespond(GameSession session, PacketReader packet)
    {
        List <QuestStatus> npcQuests = new();
        int objectId = packet.ReadInt();

        // Find if npc object id exists in field manager
        if (!session.FieldManager.State.Npcs.TryGetValue(objectId, out IFieldActor <NpcMetadata> npc))
        {
            return;
        }

        // Get all quests for this npc
        foreach (QuestStatus item in session.Player.QuestData.Values.Where(x => x.State is not QuestState.Finished))
        {
            if (npc.Value.Id == item.StartNpcId)
            {
                npcQuests.Add(item);
            }

            if (item.State is QuestState.Started && npc.Value.Id == item.CompleteNpcId && !npcQuests.Contains(item))
            {
                npcQuests.Add(item);
            }
        }

        session.Player.NpcTalk = new(npc.Value, npcQuests);
        NpcTalk npcTalk = session.Player.NpcTalk;

        ScriptLoader scriptLoader = new($"Npcs/{npc.Value.Id}", session);

        // If NPC is a shop, load and open the shop
        if (npc.Value.IsShop())
        {
            ShopHandler.HandleOpen(session, npc);
            return;
        }

        if (npc.Value.IsBank())
        {
            session.Send(HomeBank.OpenBank());
            return;
        }

        if (npc.Value.IsBeauty())
        {
            NpcMetadata npcTarget = NpcMetadataStorage.GetNpcMetadata(npcTalk.Npc.Id);
            if (npcTarget.ShopId == 507) // mirror
            {
                session.Send(NpcTalkPacket.Respond(npc, NpcType.Default, DialogType.Beauty, 0));
                HandleBeauty(session);
                return;
            }

            session.Send(NpcTalkPacket.Respond(npc, NpcType.Default, DialogType.Beauty, 1));
            return;
        }

        // Check if npc has an exploration quest
        QuestHelper.UpdateExplorationQuest(session, npc.Value.Id.ToString(), "talk_in");

        // If npc has quests, send quests and talk option
        if (npcQuests.Count != 0)
        {
            // Check if npc has scripts available
            if (ScriptMetadataStorage.NpcHasScripts(npc.Value.Id))
            {
                npcTalk.ScriptId = 0;
                session.Send(QuestPacket.SendDialogQuest(objectId, npcQuests));
                session.Send(NpcTalkPacket.Respond(npc, NpcType.QuestOptions, DialogType.TalkOption, npcTalk.ScriptId));
                return;
            }

            // If npc has no scripts, send the quest script id
            npcTalk.IsQuest = true;
            npcTalk.QuestId = npcQuests.First().Id;

            ScriptMetadata questScript = ScriptMetadataStorage.GetQuestScriptMetadata(npcTalk.QuestId);
            npcTalk.ScriptId = GetNextScript(questScript, npcTalk, 0, scriptLoader, session.Player);

            session.Send(QuestPacket.SendDialogQuest(objectId, npcQuests));
            session.Send(NpcTalkPacket.Respond(npc, NpcType.Quest, DialogType.CloseNext, npcTalk.ScriptId));
            return;
        }

        ScriptMetadata scriptMetadata = ScriptMetadataStorage.GetNpcScriptMetadata(npc.Value.Id);

        if (!scriptMetadata.Options.Exists(x => x.Type == ScriptType.Script))
        {
            return;
        }

        int firstScriptId = GetFirstScriptId(scriptLoader, scriptMetadata);

        npcTalk.ScriptId = firstScriptId;

        Option option = scriptMetadata.Options.First(x => x.Id == firstScriptId);

        DialogType dialogType = option.Contents[0].Distractor is null ? DialogType.Close1 : DialogType.CloseNextWithDistractor;

        session.Send(NpcTalkPacket.Respond(npc, NpcType.NormalTalk, dialogType, firstScriptId));

        // If npc has buttonset roulette, send roulette id 13.
        // TODO: Send the correct roulette id
        if (scriptMetadata.Options.Any(x => x.ButtonSet == "roulette"))
        {
            session.Send(NpcTalkPacket.Action(ActionType.OpenWindow, "RouletteDialog", "13"));
        }
    }