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)); }
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)); }
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 }
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")); } }