private static void UpdateQuestKills(Mob item, Character owner) { if (owner == null) { return; } foreach (var loopStarted in owner.Quests.Started) { if (!loopStarted.Value.ContainsKey(item.MapleId)) { continue; } if (loopStarted.Value[item.MapleId] >= CachedData.Quests.Data[loopStarted.Key].PostRequiredKills[item.MapleId]) { continue; } loopStarted.Value[item.MapleId]++; var kills = string.Empty; foreach (int kill in loopStarted.Value.Values) { kills += kill.ToString().PadLeft(3, '0'); } owner.Send(GamePackets.ShowStatusInfo(MessageType.QuestRecord, mapleId: loopStarted.Key, questStatus: QuestStatus.InProgress, questString: kills)); if (owner.Quests.CanComplete(loopStarted.Key, true)) { owner.Quests.NotifyComplete(loopStarted.Key); } } }
public void Complete(QuestReference quest, int selection, GameClient client) { foreach (var item in quest.PostRequiredItems) { Parent.Items.Remove(item.Key, item.Value); } var mesoReward = quest.MesoReward[1] * client.Server.World.MesoRate; Parent.PrimaryStats.Experience += quest.ExperienceReward[1]; Parent.PrimaryStats.Fame += (short)quest.FameReward[1]; Parent.PrimaryStats.Meso += mesoReward; Parent.Send(GamePackets.ShowStatusInfo(MessageType.IncreaseExp, amount: quest.ExperienceReward[1], isWhite: true, inChat: true)); Parent.Send(GamePackets.ShowStatusInfo(MessageType.IncreaseFame, amount: quest.FameReward[1])); Parent.Send(GamePackets.ShowStatusInfo(MessageType.IncreaseMeso, amount: mesoReward)); foreach (var skill in quest.PostSkillRewards) { if (Parent.PrimaryStats.Job == skill.Value) { if (!Parent.Skills.Contains(skill.Key)) { Parent.Skills.Add(new Skill(skill.Key)); } } } // TODO: Pet rewards. if (selection != -1) // NOTE: Selective reward. { //if (selection == -1) // NOTE: Randomized reward. //{ // KeyValuePair<int, short> item = quest.PostItemRewards.ElementAt(Constants.Random.Next(0, quest.PostItemRewards.Count)); // this.Parent.Items.Add(new Item(item.Key, item.Value)); // using (var pw = new PacketWriter(ServerOperationCode.Effect)) // { // pw // pw.WriteByte((byte)UserEffect.Quest) // pw.WriteByte(1) // pw.WriteInt(item.Key) // pw.WriteInt(item.Value); // this.Parent.Send(pw); // } //} //else //{ // // TODO: Selective reward based on selection. //} } else { foreach (var item in quest.PostItemRewards) { if (item.Value > 0) { Parent.Items.Add(new Item(item.Key, item.Value)); } else if (item.Value < 0) { Parent.Items.Remove(item.Key, Math.Abs(item.Value)); } using var pw = new PacketWriter(ServerOperationCode.Effect); pw.WriteByte(UserEffect.Quest); pw.WriteByte(1); pw.WriteInt(item.Key); pw.WriteInt(item.Value); Parent.Send(pw); } } Update(quest.MapleId, QuestStatus.Complete); Delete(quest.MapleId); Completed.Add(quest.MapleId, DateTime.UtcNow); Parent.ShowLocalUserEffect(UserEffect.QuestComplete); Parent.ShowRemoteUserEffect(UserEffect.QuestComplete, true); }
public override void HandlePacket(PacketReader packet, GameClient client) { var slot = packet.ReadShort(); var itemId = packet.ReadInt(); var item = client.GameCharacter.Items[ItemType.Usable, slot]; if (item == null || itemId != item.MapleId) { client.GameCharacter.LogCheatWarning(CheatType.InvalidItem); return; } var used = false; switch (item.MapleId) { case 2170000: // NOTE: Teleport Rock. used = UseTeleportRock(client, packet); break; case 2180001: // NOTE: 1st Job SP Reset. case 2180002: // NOTE: 2nd Job SP Reset. case 2180003: // NOTE: 3rd Job SP Reset. { } break; case 2180000: // NOTE: AP Reset. { var statDestination = (StatisticType)packet.ReadInt(); var statSource = (StatisticType)packet.ReadInt(); client.GameCharacter.PrimaryStats.AddAbility(statDestination, 1, true); client.GameCharacter.PrimaryStats.AddAbility(statSource, -1, true); used = true; } break; case 2090000: case 2090001: case 2090002: case 2090003: case 2090004: case 2090005: case 2090006: case 2090007: case 2090008: { var message = packet.ReadString(); client.GameCharacter.Map.SendWeatherEffect(item.MapleId, message); used = true; break; } case 2081000: { var text = packet.ReadString(); var message = $"{client.GameCharacter.Name} : {text}"; using var pw = new PacketWriter(ServerOperationCode.Notice); pw.WriteByte(NoticeType.Megaphone); pw.WriteString(message); client.GameCharacter.Map.Send(pw); used = true; } break; case 2082000: { var text = packet.ReadString(); var whisper = packet.ReadBool(); var message = $"{client.GameCharacter.Name} : {text}"; using var pw = new PacketWriter(ServerOperationCode.Notice); pw.WriteByte(NoticeType.SuperMegaphone); pw.WriteString(message); pw.WriteByte(client.GameCharacter.Client.Server.ChannelId); pw.WriteBool(whisper); client.GameCharacter.Client.Server.World.Send(pw); used = true; } break; case 2110000: // NOTE: Pet Name Tag. { //// TODO: Get the summoned pet. //string name = iPacket.ReadString(); //using (var pw = new PacketWriter(ServerOperationCode.PetNameChanged)) //{ // pw // pw.WriteInt(this.client.Character.Id) // pw.WriteByte() // NOTE: Index. // pw.WriteString(name) // pw.WriteByte(); // this.client.Character.Map.Send(pw); //} } break; case 2140000: // NOTE: Bronze Sack of Meso. case 2140001: // NOTE: Silver Sack of Meso. case 2140002: // NOTE: Gold Sack of Meso. { client.GameCharacter.PrimaryStats.Meso += item.Meso; client.Send(GamePackets.ShowStatusInfo(MessageType.IncreaseMeso, true, item.Meso)); used = true; break; } case 2150000: { client.GameCharacter.Map.SendJukeboxSong(item.MapleId, client.GameCharacter.Name); used = true; } break; } if (used) { client.GameCharacter.Items.Remove(itemId, 1); } else { client.GameCharacter.Release(); } }
private void Update(int questId, QuestStatus status, string progress = "") { Parent.Send(GamePackets.ShowStatusInfo(MessageType.QuestRecord, mapleId: questId, questStatus: status, questString: progress)); }