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