public static void HandleTaskDialog(Character pUser, MsgTaskDialog pMsg)
        {
            if (!pUser.IsAlive)
            {
                pUser.Send("You are dead.");
                return;
            }

            uint requestedId = pMsg.TaskId;
            byte controlId   = pMsg.OptionId;

            #region Direct NPC Dialogs
            if (pUser.Map.GameObjects.TryGetValue(pMsg.TaskId, out IScreenObject interactedNpc) || ServerKernel.Maps[5000].GameObjects.TryGetValue(pMsg.TaskId, out interactedNpc))
            {
                pUser.InteractingNpc = interactedNpc;
            }
            if (pUser.InteractingNpc != null && pUser.InteractingNpc.Identity >= 60001 && pUser.InteractingNpc.Identity <= 70000)
            {
                TQDialog dialog = new TQDialog(pUser);
                dialog.SetAvatar(0);
                switch (pUser.InteractingNpc.Identity)
                {
                case 60001:
                {
                    dialog.SetAvatar(50);
                    switch (controlId)
                    {
                    case 0:
                    {
                        dialog.AddText("Hello " + pUser.Name + ", I need help with some monsters in twin city. You can help me?");
                        dialog.AddOption("Oh yes of course.", 1);
                        dialog.AddOption("Sorry...", 255);
                        dialog.Show();
                        break;
                    }

                    case 1:
                    {
                        if (QuestJarManager.QuestsFinished(pUser).Count() >= 3)                 // Already completed 3 or more quests
                        {
                            dialog.AddText("Sorry but cannot help me more today. Come back tomorrow!");
                            dialog.AddOption("Oh...", 255);
                        }
                        else
                        {
                            dialog.AddText("Choose type of monster you can help me.");
                            dialog.AddOption("Pheasant (Lv1)", 2);
                            dialog.AddOption("Turtledove (Lv7)", 3);
                            dialog.AddOption("Robin (Lv12)", 4);
                            dialog.AddOption("Apparition (Lv17)", 5);
                            dialog.AddOption("In other time...", 255);
                        }
                        dialog.Show();
                        break;
                    }

                    case 2:
                    case 3:
                    case 4:
                    case 5:
                    {
                        ushort monsterType = System.Convert.ToUInt16(controlId);
                        monsterType--;
                        ushort requiredKills = 30;
                        if (monsterType > 1)
                        {
                            requiredKills = 100;
                        }

                        if (pUser.Level <= 20)
                        {
                            QuestJar quest          = QuestJarManager.CurrentQuest(pUser);
                            Item     cloudSaintsJar = pUser.Inventory.GetByType(SpecialItem.CLOUDSAINTS_JAIR);
                            if (quest == null)
                            {
                                if (cloudSaintsJar == null)
                                {
                                    if (pUser.Inventory.CreateJar(monsterType, requiredKills))
                                    {
                                        QuestJarManager.NewQuest(pUser, monsterType);
                                        dialog.AddText("Here is your CloudSaint's Jar for follow the quest!");
                                        dialog.AddOption("Oh Thanks", 255);
                                    }
                                }
                            }
                            else
                            {
                                if (quest.Finished)
                                {
                                    dialog.AddText("You cannot help more today. Thanks for your work!");
                                    dialog.AddOption("I come tomorrow.", 255);
                                }
                                else
                                {
                                    if (quest.IsFinished(true))
                                    {
                                        dialog.AddText("You finished. Thanks for you help.");
                                        dialog.AddOption("Thank you!", 255);
                                    }
                                    else
                                    {
                                        dialog.AddText("You have killed " + quest.Kills + "/" + quest.RequiredKills + " " + quest.Monster.Name);
                                        if (cloudSaintsJar == null)
                                        {
                                            dialog.AddOption("I Lost the CloudSaint'sJar", 6);
                                        }
                                        dialog.AddOption("Oh Thanks", 255);
                                    }
                                }
                            }
                        }
                        else
                        {
                            dialog.AddText("You can help my brother in Phoenix City. This monsters is for level 20 or less only.");
                            dialog.AddOption("Oh ok...", 255);
                        }
                        dialog.Show();
                        break;
                    }

                    case 6:
                    {
                        QuestJar quest = QuestJarManager.CurrentQuest(pUser);

                        pUser.Inventory.CreateJar((ushort)quest.Monster.Id, (ushort)quest.RequiredKills);
                        dialog.AddText("Here is your CloudSaint's Jar for follow the quest!");
                        dialog.AddOption("Oh Thanks", 255);
                        dialog.Show();
                        break;
                    }
                    }
                    break;
                }

                default:
                {
                    dialog.SetAvatar(1);
                    dialog.AddText("Sorry but this npc not have dialog");
                    dialog.AddOption(":(", 255);
                    dialog.Show();
                    break;
                }
                }
            }
            #endregion
            #region Database NPC Dialogs
            else
            {
                switch (pMsg.InteractType)
                {
                // The message box does have the options OK and Cancel
                case MsgTaskDialog.MESSAGE_BOX:
                {
                    if (pUser.CaptchaBox != null)
                    {
                        if (controlId == 0)
                        {
                            pUser.CaptchaBox.OnCancel(pUser);
                        }
                        else
                        {
                            pUser.CaptchaBox.OnOk(pUser);
                        }
                        pUser.CaptchaBox = null;
                    }
                    else if (pUser.RequestBox != null)
                    {
                        if (controlId == 0)         // cancel
                        {
                            pUser.RequestBox.OnCancel(pUser);
                        }
                        else if (controlId == 255)         // ok
                        {
                            pUser.RequestBox.OnOk(pUser);
                        }
                        pUser.RequestBox = null;
                    }
                    break;
                }

                // This is what we receive when we click on OK of a Input box on a NPC
                // Or a option of the NPC.
                case MsgTaskDialog.ANSWER:
                case MsgTaskDialog.TEXT_INPUT:
                {
                    if (pMsg.InteractType == 102)
                    {
                        if (pUser.SyndicateIdentity <= 0)
                        {
                            return;
                        }

                        pUser.Syndicate.ExpelMember(pUser, pMsg.Text, true);
                        return;
                    }

                    if (controlId == 255)
                    {
                        break;
                    }

                    INextAction action;
                    if (pUser.NextActions.TryGetValue(controlId, out action))
                    {
                        pUser.NextActions.Clear();
                        if (pUser.InteractingNpc != null &&
                            (pUser.InteractingNpc.MapIdentity == 5000 ||
                             Calculations.InScreen(pUser.MapX, pUser.MapY,
                                                   pUser.InteractingNpc.MapX, pUser.InteractingNpc.MapY)))
                        {
                            if (pUser.InteractingNpc is GameNpc)
                            {
                                var pNpc = pUser.InteractingNpc as GameNpc;
                                pUser.GameAction.ProcessAction(GetNextAction(pUser, action.Identity), pUser, pNpc, null,
                                                               action.IsInput ? pMsg.Text : null);
                            }
                            else if (pUser.InteractingNpc is DynamicNpc)
                            {
                                var pNpc = pUser.InteractingNpc as DynamicNpc;
                                pUser.GameAction.ProcessAction(GetNextAction(pUser, action.Identity), pUser, pNpc, null,
                                                               action.IsInput ? pMsg.Text : null);
                            }
                        }
                        else if (pUser.TaskItem != null)
                        {
                            pUser.GameAction.ProcessAction(GetNextAction(pUser, action.Identity), pUser, null, pUser.TaskItem,
                                                           action.IsInput ? pMsg.Text : null);
                            pUser.TaskItem = null;
                        }
                    }
                    break;
                }

                default:
                {
                    switch (controlId)
                    {
                    case 0:
                    {
                        pUser.NextActions.Clear();
                        IScreenObject pNpc = null;
                        if (pUser.Map.GameObjects.TryGetValue(pMsg.TaskId, out pNpc) ||
                            ServerKernel.Maps[5000].GameObjects.TryGetValue(pMsg.TaskId, out pNpc))
                        {
                            pUser.GameAction.ProcessAction(GetActionIdentity(pUser, pNpc), pUser, pNpc, null,
                                                           "");
                        }
                    }
                    break;

                    /*case 12:
                     * {
                     *  Dialog = new TQDialog(client);
                     *  NpcSpawn npc;
                     *  if (!client.Map.NPCs.TryGetValue(requestedId, out npc))
                     *      break;
                     *  ExecuteTask(client, npc);
                     *  break;
                     * }*/
                    case 255:
                    {
                        // Close Dialog
                        pUser.InteractingNpc = null;
                        pUser.NextActions.Clear();
                        break;
                    }

                    default:
                    {
                        pUser.InteractingNpc = null;
                        pUser.NextActions.Clear();
                        ServerKernel.Log.SaveLog(string.Format("Npc interact type default [{0}] not handled.", controlId), false, LogType.WARNING);
                        break;
                    }
                    }
                    break;
                }
                }
            }
            #endregion
        }
        public static void HandleInteract(Character pRole, MsgInteract pMsg)
        {
            if (pRole == null || pRole.BattleSystem == null)
            {
                return;
            }

            pRole.BattleSystem.DestroyAutoAttack();
            pRole.BattleSystem.ResetBattle();
            if (pRole.BattleSystem.QueryMagic() != null)
            {
                pRole.BattleSystem.QueryMagic().SetMagicState(0);
                pRole.BattleSystem.QueryMagic().BreakAutoAttack();
                pRole.BattleSystem.QueryMagic().AbortMagic(true);
            }

            if (!pRole.IsAlive)
            {
                return;
            }

            var obj = pRole.BattleSystem.FindRole(pMsg.TargetIdentity);

            if (obj == null &&
                pMsg.Action != InteractionType.ACT_ITR_MAGIC_ATTACK &&
                pMsg.Action != InteractionType.ACT_ITR_COUNTER_KILL_SWITCH &&
                pMsg.Action != InteractionType.ACT_ITR_PRESENT_EMONEY)
            {
                return;
            }

            switch (pMsg.Action)
            {
                #region 2/28 - Meele and Bow

            case InteractionType.ACT_ITR_SHOOT:
            case InteractionType.ACT_ITR_ATTACK:
            {
                pRole.BattleSystem.CreateBattle(pMsg.TargetIdentity);
                pRole.BattleSystem.SetAutoAttack();
                pRole.SetAttackTarget(obj);
                break;
            }

                #endregion
                #region 8 - Court

            case InteractionType.ACT_ITR_COURT:
            {
                if (pRole.Identity == pMsg.TargetIdentity)
                {
                    return;
                }

                Character pTarget;
                if (pRole.Map.Players.TryGetValue(pMsg.TargetIdentity, out pTarget))
                {
                    if (pTarget.Mate != ServerString.NOMATE_NAME)
                    {
                        pRole.Send(ServerString.TARGET_ALREADY_MARRIED);
                        return;
                    }
                    if (pRole.Mate != ServerString.NOMATE_NAME)
                    {
                        pRole.Send(ServerString.YOURE_ALREADY_MARRIED);
                        return;
                    }
                    if (pTarget.Gender == pRole.Gender)
                    {
                        pRole.Send(ServerString.NOT_ALLOWED_SAME_GENDER_MARRIAGE);
                        return;
                    }

                    pTarget.SetMarryRequest(pRole.Identity);
                    pTarget.Send(pMsg);
                }
                else
                {
                    pRole.Send(ServerString.MARRIAGE_NOT_APPLY);
                    return;
                }
                break;
            }

                #endregion
                #region 9 - Marry

            case InteractionType.ACT_ITR_MARRY:
            {
                if (pRole.Identity == pMsg.TargetIdentity)
                {
                    return;
                }

                Character pTarget;
                if (pRole.Map.Players.TryGetValue(pMsg.TargetIdentity, out pTarget))
                {
                    if (pTarget.Mate != ServerString.NOMATE_NAME)
                    {
                        pRole.Send(ServerString.TARGET_ALREADY_MARRIED);
                        return;
                    }
                    if (pRole.Mate != ServerString.NOMATE_NAME)
                    {
                        pRole.Send(ServerString.YOURE_ALREADY_MARRIED);
                        return;
                    }
                    if (pTarget.Gender == pRole.Gender)
                    {
                        pRole.Send(ServerString.NOT_ALLOWED_SAME_GENDER_MARRIAGE);
                        return;
                    }
                    if (!pRole.FetchMarryRequest(pTarget.Identity))
                    {
                        pRole.Send(ServerString.MARRIAGE_NOT_APPLY);
                        return;
                    }

                    pRole.Mate   = pTarget.Name;
                    pTarget.Mate = pRole.Name;
                    MsgName msg = new MsgName
                    {
                        Identity = pRole.Identity,
                        Action   = StringAction.MATE
                    };
                    msg.Append(pRole.Mate);
                    pRole.Send(msg);
                    msg = new MsgName
                    {
                        Identity = pTarget.Identity,
                        Action   = StringAction.MATE
                    };
                    msg.Append(pTarget.Mate);
                    pTarget.Send(msg);

                    if (pRole.Family != null && pTarget.Family == null)
                    {
                        pRole.Family.AppendMember(pRole, pTarget);
                    }
                    else if (pRole.Family == null && pTarget.Family != null)
                    {
                        pTarget.Family.AppendMember(pTarget, pRole);
                    }

                    ServerKernel.SendMessageToAll(string.Format(ServerString.STR_MARRY, pRole.Name, pTarget.Name),
                                                  ChatTone.CENTER);
                }
                else
                {
                    pRole.Send(ServerString.MARRIAGE_NOT_APPLY);
                    return;
                }
                break;
            }

                #endregion
                #region 24 - Magic Attack

            case InteractionType.ACT_ITR_MAGIC_ATTACK:
            {
                #region TemporaryDecryption

                ushort skillId = Convert.ToUInt16(((long)pMsg[24] & 0xFF) | (((long)pMsg[25] & 0xFF) << 8));
                skillId ^= 0x915d;
                skillId ^= (ushort)pRole.Identity;
                skillId  = (ushort)(skillId << 0x3 | skillId >> 0xd);
                skillId -= 0xeb42;

                uint Target = ((uint)pMsg[12] & 0xFF) | (((uint)pMsg[13] & 0xFF) << 8) |
                              (((uint)pMsg[14] & 0xFF) << 16) | (((uint)pMsg[15] & 0xFF) << 24);
                Target = ((((Target & 0xffffe000) >> 13) | ((Target & 0x1fff) << 19)) ^ 0x5F2D2463 ^ pRole.Identity) -
                         0x746F4AE6;

                pMsg.TargetIdentity = Target;

                ushort TargetX = 0;
                ushort TargetY = 0;
                long   xx      = (pMsg[16] & 0xFF) | ((pMsg[17] & 0xFF) << 8);
                long   yy      = (pMsg[18] & 0xFF) | ((pMsg[19] & 0xFF) << 8);
                xx             = xx ^ (pRole.Identity & 0xffff) ^ 0x2ed6;
                xx             = ((xx << 1) | ((xx & 0x8000) >> 15)) & 0xffff;
                xx            |= 0xffff0000;
                xx            -= 0xffff22ee;
                yy             = yy ^ (pRole.Identity & 0xffff) ^ 0xb99b;
                yy             = ((yy << 5) | ((yy & 0xF800) >> 11)) & 0xffff;
                yy            |= 0xffff0000;
                yy            -= 0xffff8922;
                TargetX        = Convert.ToUInt16(xx);
                TargetY        = Convert.ToUInt16(yy);
                pMsg.MagicType = skillId;
                pMsg.CellX     = TargetX;
                pMsg.CellY     = TargetY;

                #endregion

                if (pRole.IsAlive)
                {
                    pRole.ProcessMagicAttack(pMsg.MagicType, pMsg.TargetIdentity, pMsg.CellX, pMsg.CellY);
                }
                break;
            }

                #endregion
                #region 39 - Claim CPs

            case InteractionType.ACT_ITR_PRESENT_EMONEY:
                if (pRole.CoinMoney > 0)
                {
                    pRole.AwardEmoney(pRole.CoinMoney, true);
                    pMsg.Amount     = pRole.CoinMoney;
                    pRole.CoinMoney = 0;
                    pRole.Send(pMsg);
                }
                break;

                #endregion
                #region 44 - Counter Kill Switch

            case InteractionType.ACT_ITR_COUNTER_KILL_SWITCH:
            {
                if (pRole.Profession / 10 != 5 || !pRole.IsPureClass())
                {
                    pRole.Send(ServerString.STR_SCAPEGOAT_ONLY_PURE_NINJA);
                    return;
                }

                if (!pRole.IsAlive || pRole.IsWing())
                {
                    return;
                }

                if (pRole.Scapegoat)     // disable
                {
                    pMsg.TargetIdentity = pMsg.EntityIdentity = pRole.Identity;
                    pMsg.Damage         = 0;
                    pMsg.CellX          = pRole.MapX;
                    pMsg.CellY          = pRole.MapY;
                    pRole.Send(pMsg);
                    pRole.Scapegoat = false;
                }
                else
                {
                    pMsg.TargetIdentity = pMsg.EntityIdentity = pRole.Identity;
                    pMsg.Damage         = 1;
                    pMsg.CellX          = pRole.MapX;
                    pMsg.CellY          = pRole.MapY;
                    pRole.Send(pMsg);
                    pRole.Scapegoat = true;
                }
                break;
            }

                #endregion
                #region 36 - QuestJar
            case InteractionType.ACT_ITR_INCREASE_JAR:
            {
                // TODO Only temporal for now. But allowed login/logout the player.
                QuestJar quest = ServerKernel.PlayerQuests.Where(x => x.Player.Identity == pRole.Identity).FirstOrDefault();
                if (quest != null)
                {
                    pMsg.Amount = quest.Kills;
                }
                pRole.Send(pMsg);
                break;
            }
                #endregion

            default:
                ServerKernel.Log.SaveLog("Missing Interaction Type: " + pMsg.Action, true, "itr_msg",
                                         LogType.WARNING);
                break;
            }
        }