private static void HandleBeauty(GameSession session) { MapPortal portal = MapEntityStorage.GetPortals(session.Player.MapId).FirstOrDefault(portal => portal.Id == 99); // unsure how the portalId is determined if (portal is null) { return; } session.Send(NpcTalkPacket.Action(ActionType.Portal, "", "", portal.Id)); NpcMetadata npcTarget = NpcMetadataStorage.GetNpcMetadata(session.Player.NpcTalk.Npc.Id); session.Player.ShopId = npcTarget.ShopId; switch (npcTarget.ShopId) { case 500: // Dr Dixon session.Send(NpcTalkPacket.Action(ActionType.OpenWindow, "BeautyShopDialog", "face")); // unsure how these strings are determined break; case 501: // Dr Zenko session.Send(NpcTalkPacket.Action(ActionType.OpenWindow, "BeautyShopDialog", "skin")); break; case 504: // Rosetta case 509: //Lolly session.Send(NpcTalkPacket.Action(ActionType.OpenWindow, "BeautyShopDialog", "hair,style")); break; case 505: // Ren session.Send(NpcTalkPacket.Action(ActionType.OpenWindow, "BeautyShopDialog", "makeup")); break; case 506: // Douglas session.Send(NpcTalkPacket.Action(ActionType.OpenWindow, "BeautyShopDialog", "itemcolor")); break; case 507: // Mirror session.Send(NpcTalkPacket.Action(ActionType.OpenWindow, "BeautyShopDialog", "mirror")); break; case 508: // Paulie session.Send(NpcTalkPacket.Action(ActionType.OpenWindow, "BeautyShopDialog", "hair,random")); break; case 510: // Mino session.Send(NpcTalkPacket.Action(ActionType.OpenWindow, "BeautyShopDialog", "hair,styleSave")); break; } session.Send(UserMoveByPortalPacket.Move(session.Player.FieldPlayer, portal.Coord.ToFloat(), portal.Rotation.ToFloat())); }
private static void HandleRespond(GameSession session, PacketReader packet) { List <QuestStatus> npcQuests = new List <QuestStatus>(); int objectId = packet.ReadInt(); // Find if npc object id exists in field manager if (!session.FieldManager.State.Npcs.TryGetValue(objectId, out IFieldObject <Npc> npc)) { return; } // Get all quests for this npc foreach (QuestStatus item in session.Player.QuestList.Where(x => !x.Completed)) { if (npc.Value.Id == item.StartNpcId) { npcQuests.Add(item); } if (item.Started && npc.Value.Id == item.CompleteNpcId && !npcQuests.Contains(item)) { npcQuests.Add(item); } } session.Player.NpcTalk = new NpcTalk(npc.Value, npcQuests); ScriptLoader scriptLoader = new ScriptLoader($"Npcs/{npc.Value.Id}", session); // If NPC is a shop, load and open the shop if (npc.Value.IsShop()) { ShopHandler.HandleOpen(session, npc); return; } else if (npc.Value.IsBank()) { session.Send(HomeBank.OpenBank()); return; } else if (npc.Value.IsBeauty()) { NpcMetadata npcTarget = NpcMetadataStorage.GetNpc(session.Player.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) { session.Player.NpcTalk.ScriptId = 0; session.Send(QuestPacket.SendDialogQuest(objectId, npcQuests)); session.Send(NpcTalkPacket.Respond(npc, NpcType.Unk2, DialogType.TalkOption, session.Player.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); session.Player.NpcTalk.ScriptId = firstScriptId; Option option = scriptMetadata.Options.First(x => x.Id == firstScriptId); DialogType dialogType = DialogType.None; if (option.Contents[0].Goto.Count == 0) { dialogType = DialogType.Close1; } else { dialogType = DialogType.CloseNextWithDistractor; } session.Send(NpcTalkPacket.Respond(npc, NpcType.Unk3, 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")); } }
public void TalkFunction(GameSession session, int functionId, string function) { if (functionId == 0) { return; } List <ActionType> actions = new(); Script npcScript = ScriptLoader.GetScript($"Npcs/{Npc.Id}"); DynValue actionResults = npcScript?.RunFunction(function); if (actionResults == null) { return; } switch (actionResults.Type) { case DataType.Number: actions.Add((ActionType)actionResults.Number); break; case DataType.Tuple: foreach (DynValue value in actionResults.Tuple) { actions.Add((ActionType)value.Number); } break; default: return; } MapPortal portal = new(); foreach (ActionType action in actions) { switch (action) { case ActionType.OpenWindow: DynValue windowResults = npcScript.RunFunction("actionWindow"); session.Send(NpcTalkPacket.Action(ActionType.OpenWindow, windowResults.Tuple[0].String, windowResults.Tuple[1].String)); break; case ActionType.Portal: DynValue portalResults = npcScript.RunFunction("actionPortal"); portal = MapEntityMetadataStorage.GetPortals(session.Player.MapId).FirstOrDefault(portal => portal.Id == portalResults.Number); if (portal is null) { return; } session.Send(NpcTalkPacket.Action(ActionType.Portal, "", "", portal.Id)); break; case ActionType.ItemReward: DynValue itemResults = npcScript.RunFunction("actionItemReward"); // TODO: Support > 1 item Item item = new(id : (int)itemResults.Tuple[0].Number, amount : (int)itemResults.Tuple[2].Number, rarity : (int)itemResults.Tuple[1].Number); session.Player.Inventory.AddItem(session, item, true); session.Send(NpcTalkPacket.Action(action, "", "", 0, item)); break; case ActionType.MoveMap: DynValue map = npcScript.RunFunction("actionMoveMap"); int mapId = (int)map.Tuple[0].Number; int portalId = (int)map.Tuple[1].Number; MapPortal portalDst = MapEntityMetadataStorage.GetPortals(mapId).FirstOrDefault(x => x.Id == portalId); if (portalDst is null) { session.Player.Warp(mapId); return; } session.Player.Warp(mapId, portalDst.Coord, portalDst.Rotation); break; } } // this needs to be sent after the UI window action if (actions.Contains(ActionType.Portal)) { session.Player.Move(portal.Coord.ToFloat(), portal.Rotation.ToFloat()); } }
public override void Handle(GameSession session, PacketReader packet) { byte function = packet.ReadByte(); switch (function) { case 0: // Cancel return; case 1: int objectId = packet.ReadInt(); if (!session.FieldManager.State.Npcs.TryGetValue(objectId, out IFieldObject <Npc> npc)) { return; // Invalid NPC } session.Player.NpcTalk = npc; // If NPC is a shop, load and open the shop if (npc.Value.IsShop()) { ShopHandler.HandleOpen(session, npc); return; } else if (npc.Value.IsBank()) { session.Send(HomeBank.OpenBank()); return; } else if (npc.Value.IsBeauty()) { session.Send(NpcTalkPacket.Respond(npc, NpcType.Default, DialogType.Beauty, 1)); return; } // Stellar Chest: 11004215 session.Send(NpcTalkPacket.Respond(npc, NpcType.Unk2, DialogType.TalkOption, 0)); break; case 2: // Continue chat? int index = packet.ReadInt(); // selection index if (session.Player.NpcTalk.Value.IsBeauty()) // This may need a cleaner method { MapPortal portal = MapEntityStorage.GetPortals(session.Player.MapId).FirstOrDefault(portal => portal.Id == 99); // unsure how the portalId is determined session.Send(NpcTalkPacket.Action(ActionType.Portal, "", "", portal.Id)); NpcMetadata npcTarget = NpcMetadataStorage.GetNpc(session.Player.NpcTalk.Value.Id); switch (npcTarget.ShopId) { case 500: // Dr Dixon session.Send(NpcTalkPacket.Action(ActionType.OpenWindow, "BeautyShopDialog", "face")); // unsure how these strings are determined break; case 501: // Dr Zenko session.Send(NpcTalkPacket.Action(ActionType.OpenWindow, "BeautyShopDialog", "skin")); break; case 504: // Rosetta case 509: //Lolly session.Send(NpcTalkPacket.Action(ActionType.OpenWindow, "BeautyShopDialog", "hair,style")); break; case 505: // Ren session.Send(NpcTalkPacket.Action(ActionType.OpenWindow, "BeautyShopDialog", "makeup")); break; case 506: // Douglas session.Send(NpcTalkPacket.Action(ActionType.OpenWindow, "BeautyShopDialog", "itemcolor")); break; case 507: // Mirror session.Send(NpcTalkPacket.Action(ActionType.OpenWindow, "BeautyShopDialog", "mirror")); break; case 508: // Paulie session.Send(NpcTalkPacket.Action(ActionType.OpenWindow, "BeautyShopDialog", "hair,random")); break; case 510: // Mino session.Send(NpcTalkPacket.Action(ActionType.OpenWindow, "BeautyShopDialog", "hair,styleSave")); break; } session.Send(UserMoveByPortalPacket.Move(session, portal.Coord.ToFloat(), portal.Rotation.ToFloat())); } session.Send(NpcTalkPacket.Close()); session.Player.NpcTalk = null; break; } }