Beispiel #1
0
        /// <summary>
        ///  Sends NewQuest to creature's client.
        /// </summary>
        /// <param name="character"></param>
        /// <param name="quest"></param>
        public static void NewQuest(Creature character, Quest quest)
        {
            var packet = new Packet(Op.NewQuest, character.EntityId);
            packet.AddQuest(quest);

            character.Client.Send(packet);
        }
Beispiel #2
0
		/// <summary>
		/// Broadcasts QuestUpdate in party.
		/// </summary>
		/// <param name="creature"></param>
		/// <param name="quest"></param>
		public static void QuestUpdate(Party party, Quest quest)
		{
			var packet = new Packet(Op.QuestUpdate, 0);
			packet.AddQuestUpdate(quest);

			party.Broadcast(packet, true);
		}
Beispiel #3
0
		/// <summary>
		/// Sends QuestUpdate to creature's client.
		/// </summary>
		/// <param name="creature"></param>
		/// <param name="quest"></param>
		public static void QuestUpdate(Creature creature, Quest quest)
		{
			var packet = new Packet(Op.QuestUpdate, creature.EntityId);
			packet.AddQuestUpdate(quest);

			creature.Client.Send(packet);
		}
Beispiel #4
0
		/// <summary>
		/// Adds quest to manager and informs the client about it.
		/// </summary>
		/// <param name="quest"></param>
		public void Add(Quest quest)
		{
			// Check quest item
			if (quest.QuestItem == null)
				throw new InvalidOperationException("Quest item can't be null.");

			if (!_creature.Inventory.Has(quest.QuestItem))
				throw new InvalidOperationException("The quest item needs to be in the creature's inventory first.");

			this.AddSilent(quest);

			// Quest info
			Send.NewQuest(_creature, quest);

			// Start PTJ clock
			if (quest.Data.Type == QuestType.Deliver)
				Send.QuestStartPtj(_creature, quest.UniqueId);

			// Initial objective check, for things like collect and reach rank,
			// that may be done already.
			quest.Data.CheckCurrentObjective(_creature);

			// Give item to deliver for first deliver objective
			var deliverObjective = quest.Data.Objectives[quest.CurrentObjectiveOrLast.Ident] as QuestObjectiveDeliver;
			if (deliverObjective != null)
			{
				var item = new Item(deliverObjective.ItemId);
				item.Amount = Math.Min(1, deliverObjective.Amount);

				_creature.Inventory.Add(item, true);
			}
		}
Beispiel #5
0
        /// <summary>
        /// Completes and removes quest, if it exists.
        /// </summary>
        /// <param name="questId"></param>
        public bool Complete(Quest quest)
        {
            var success = this.Complete(quest, true);
            if (success)
            {
                quest.State = QuestState.Complete;

                ChannelServer.Instance.Events.OnPlayerCompletesQuest(_creature, quest.Id);
            }
            return success;
        }
Beispiel #6
0
		/// <summary>
		/// Adds quest to manager and informs the client about it.
		/// </summary>
		/// <param name="quest"></param>
		public void Add(Quest quest)
		{
			// Check quest item
			if (quest.QuestItem == null)
				throw new InvalidOperationException("Quest item can't be null.");

			if (!_creature.Inventory.Has(quest.QuestItem))
				throw new InvalidOperationException("The quest item needs to be in the creature's inventory first.");

			this.AddSilent(quest);

			// Quest info
			Send.NewQuest(_creature, quest);

			// Start PTJ clock
			if (quest.Data.Type == QuestType.Deliver)
				Send.QuestStartPtj(_creature, quest.UniqueId);

			// Initial objective check, for things like collect and reach rank,
			// that may be done already.
			quest.Data.CheckCurrentObjective(_creature);
		}
Beispiel #7
0
		/// <summary>
		/// Adds quest to manager and informs the client about it.
		/// </summary>
		/// <param name="quest"></param>
		public void Add(Quest quest)
		{
			// Check quest item
			if (quest.QuestItem == null)
				throw new InvalidOperationException("Quest item can't be null.");

			if (!_creature.Inventory.Has(quest.QuestItem))
				throw new InvalidOperationException("The quest item needs to be in the creature's inventory first.");

			this.AddSilent(quest);

			// Quest info
			Send.NewQuest(_creature, quest);

			// Start PTJ clock
			if (quest.Data.Type == QuestType.Deliver)
				Send.QuestStartPtj(_creature, quest.UniqueId);

			// Initial objective check, for things like collect and reach rank,
			// that may be done already.
			quest.Data.CheckCurrentObjective(_creature);

			// Give item to deliver for first deliver objective
			var deliverObjective = quest.Data.Objectives[quest.CurrentObjectiveOrLast.Ident] as QuestObjectiveDeliver;
			if (deliverObjective != null)
			{
				var item = new Item(deliverObjective.ItemId);
				item.Amount = Math.Min(1, deliverObjective.Amount);

				_creature.Inventory.Add(item, true);
			}

			// Receive event
			// XXX: Could be used for the deliver objectives above as well?
			//   It would make more sense to always give delvier items
			//   automatically though, not only on start.
			quest.Data.OnReceive(_creature);
		}
Beispiel #8
0
		/// <summary>
		/// Sends QuestUpdate to creature's client.
		/// </summary>
		/// <param name="creature"></param>
		/// <param name="quest"></param>
		public static void QuestUpdate(Creature creature, Quest quest)
		{
			var progress = quest.GetList();

			var packet = new Packet(Op.QuestUpdate, creature.EntityId);
			packet.PutLong(quest.UniqueId);
			packet.PutByte(1);
			packet.PutInt(progress.Count);
			foreach (var p in progress)
			{
				packet.PutInt(p.Count);
				// [180600, NA187 (25.06.2014)] ?
				{
					packet.PutFloat(0);
				}
				packet.PutByte(p.Done);
				packet.PutByte(p.Unlocked);
			}
			packet.PutByte(0);
			packet.PutByte(0);

			creature.Client.Send(packet);
		}
Beispiel #9
0
		/// <summary>
		/// Creates quest scroll for the given quest id.
		/// </summary>
		/// <remarks>
		/// During the creation, a quest is created and included with the item.
		/// </remarks>
		/// <param name="questId"></param>
		/// <returns></returns>
		public static Item CreateQuestScroll(int questId)
		{
			// Get quest information
			var questScript = ChannelServer.Instance.ScriptManager.QuestScripts.Get(questId);
			if (questScript == null)
				throw new ArgumentException("Quest '" + questId + "' not found.");

			var quest = new Quest(questId);

			var item = new Item(questScript.ScrollId);
			item.MetaData1.Parse(quest.Data.MetaData.ToString());

			item.Quest = quest;
			quest.QuestItem = item;

			return item;
		}
Beispiel #10
0
		public override void Reward(Creature creature, Quest quest)
		{
			creature.Inventory.Add(this.ItemId, this.Amount);
			Send.AcquireItemInfo(creature, this.ItemId, this.Amount);
		}
Beispiel #11
0
		/// <summary>
		/// Completes and removes quest without rewards, if it exists.
		/// </summary>
		/// <param name="quest"></param>
		/// <returns></returns>
		public bool GiveUp(Quest quest)
		{
			if (!this.Has(quest))
				throw new ArgumentException("Quest not found in this manager.");

			var success = this.EndQuest(quest, -1, false);

			// Remove quest item on success, which will also remove the
			// quest from the manager.
			if (success)
				_creature.Inventory.Remove(quest.QuestItem);

			return success;
		}
Beispiel #12
0
Datei: Party.cs Projekt: Rai/aura
		/// <summary>
		/// Sets party quest, removing previous ones and updating all members.
		/// </summary>
		/// <param name="quest"></param>
		public void SetPartyQuest(Quest quest)
		{
			if (this.Quest != null)
				this.UnsetPartyQuest();

			this.Quest = quest;

			// Give quest to other members
			lock (_sync)
			{
				foreach (var member in _members.Where(a => a != this.Leader))
				{
					member.Quests.AddSilent(quest);
					Send.NewQuest(member, quest);
				}
			}

			Send.PartySetActiveQuest(this, quest.UniqueId);
		}
Beispiel #13
0
Datei: Party.cs Projekt: Rai/aura
		/// <summary>
		/// Unsets party quest, removes it from all normal member's managers,
		/// and updates the clients. Returns false if no party quest was set.
		/// </summary>
		/// <param name="quest"></param>
		public bool UnsetPartyQuest()
		{
			var quest = this.Quest;
			if (quest == null)
				return false;

			this.Quest = null;

			// Remove quest from other members
			lock (_sync)
			{
				foreach (var member in _members.Where(a => a != this.Leader))
					member.Quests.Remove(quest);
			}

			Send.PartyUnsetActiveQuest(this, quest.UniqueId);
			return true;
		}
Beispiel #14
0
		/// <summary>
		/// Completes and removes quest, if it exists, giving the rewards
		/// in the process, if warranted.
		/// </summary>
		/// <param name="quest"></param>
		/// <param name="rewardGroup">Reward group to use, set to -1 for no rewards.</param>
		/// <param name="owl">Show owl delivering the rewards?</param>
		/// <returns></returns>
		private bool EndQuest(Quest quest, int rewardGroup, bool owl)
		{
			var result = quest.GetResult();

			// Increase PTJ done/success
			if (quest.Data.Type == QuestType.Deliver)
				this.ModifyPtjTrackRecord(quest.Data.PtjType, +1, (result == QuestResult.Perfect ? +1 : 0));

			// Rewards
			if (rewardGroup != -1)
			{
				var rewards = quest.Data.GetRewards(rewardGroup, result);
				if (rewards.Count == 0)
					Log.Warning("CreatureQuests.EndQuest: No rewards for group '{0}' at result '{1}' in quest '{2}'.", rewardGroup, result, quest.Id);
				else
					this.GiveRewards(quest, rewards, owl);
			}

			// Remove from quest log.
			Send.QuestClear(_creature, quest.UniqueId);

			// Update PTJ stuff and stop clock
			if (quest.Data.Type == QuestType.Deliver)
			{
				var record = this.GetPtjTrackRecord(quest.Data.PtjType);

				Send.QuestUpdatePtj(_creature, quest.Data.PtjType, record.Done, record.Success);
				Send.QuestEndPtj(_creature);
			}

			return true;
		}
Beispiel #15
0
		public static void AddQuestUpdate(this Packet packet, Quest quest)
		{
			var progress = quest.GetList();

			packet.PutLong(quest.UniqueId);
			packet.PutByte(1);
			packet.PutInt(progress.Count);
			foreach (var p in progress)
			{
				packet.PutInt(p.Count);
				// [180600, NA187 (25.06.2014)] ?
				{
					packet.PutFloat(0);
				}
				packet.PutByte(p.Done);
				packet.PutByte(p.Unlocked);
			}
			packet.PutByte(0);
			packet.PutByte(0);
		}
Beispiel #16
0
		public override void Reward(Creature creature, Quest quest)
		{
			creature.Inventory.AddGold(this.Amount);
			Send.AcquireInfo(creature, "gold", this.Amount);
		}
Beispiel #17
0
		public override void Reward(Creature creature, Quest quest)
		{
			creature.GiveAp(this.Amount);
			Send.AcquireInfo(creature, "ap", this.Amount);
		}
Beispiel #18
0
		public override void Reward(Creature creature, Quest quest)
		{
			creature.Inventory.Add(Item.CreateQuestScroll(this.QuestId), true);
		}
Beispiel #19
0
		public override void Reward(Creature creature, Quest quest)
		{
			creature.AcquireItem(Item.Create(this.ItemId, this.Amount));
		}
Beispiel #20
0
		/// <summary>
		/// Returns true if creature has the given quest.
		/// </summary>
		/// <param name="quest"></param>
		/// <returns></returns>
		public bool Has(Quest quest)
		{
			lock (_quests)
				return _quests.Contains(quest);
		}
Beispiel #21
0
		/// <summary>
		/// Gives quest rewards to creature.
		/// </summary>
		/// <param name="quest">Quest the rewards come from.</param>
		/// <param name="rewards">Rewards to give to the creature.</param>
		/// <param name="owl">Show owl delivering the rewards?</param>
		private void GiveRewards(Quest quest, ICollection<QuestReward> rewards, bool owl)
		{
			if (rewards.Count == 0)
				return;

			if (owl)
				Send.QuestOwlComplete(_creature, quest.UniqueId);

			foreach (var reward in rewards)
			{
				try
				{
					reward.Reward(_creature, quest);
				}
				catch (NotImplementedException)
				{
					Log.Unimplemented("Quest.Complete: Reward '{0}'.", reward.Type);
				}
			}
		}
Beispiel #22
0
		/// <summary>
		/// Adds quest to manager, does not update client, send owl,
		/// or anything else.
		/// </summary>
		/// <remarks>
		/// This method is for initialization, use Give during run-time.
		/// </remarks>
		/// <param name="quest"></param>
		public void AddSilent(Quest quest)
		{
			lock (_quests)
				_quests.Add(quest);
		}
Beispiel #23
0
		public override void Reward(Creature creature, Quest quest)
		{
			creature.AcquireItem(Item.CreateEnchant(OptionSetId));
		}
Beispiel #24
0
		/// <summary>
		/// Starts PTJ quest.
		/// </summary>
		/// <param name="questId"></param>
		public void StartPtj(int questId)
		{
			try
			{
				var quest = new Quest(questId);

				quest.MetaData.SetByte("QMRTCT", (byte)quest.Data.RewardGroups.Count);
				quest.MetaData.SetInt("QMRTBF", 0x4321); // (specifies which groups to display at which position, 1 group per hex char)
				quest.MetaData.SetString("QRQSTR", this.NPC.Name);
				quest.MetaData.SetBool("QMMABF", false);

				// Calculate deadline, based on current time and quest data
				var now = ErinnTime.Now;
				var diffHours = Math.Max(0, quest.Data.DeadlineHour - now.Hour - 1);
				var diffMins = Math.Max(0, 60 - now.Minute);
				var deadline = DateTime.Now.AddTicks(diffHours * ErinnTime.TicksPerHour + diffMins * ErinnTime.TicksPerMinute);
				quest.Deadline = deadline;

				this.Player.Quests.Start(quest, false);
			}
			catch (Exception ex)
			{
				Log.Exception(ex, "NpcScript.StartPtj: Quest '{0}'", questId);
				this.Msg("(Error)");
			}
		}
Beispiel #25
0
		public override void Reward(Creature creature, Quest quest)
		{
			// Only give skill if char doesn't have it or rank is lower.
			if (creature.Skills.Has(this.SkillId, this.Rank))
				return;

			creature.Skills.Give(this.SkillId, this.Rank);

			if (this.Training != 0)
				creature.Skills.Train(this.SkillId, this.Rank, this.Training);
		}
Beispiel #26
0
		/// <summary>
		/// Updates quest on client(s), depending on its type.
		/// </summary>
		/// <param name="creature"></param>
		/// <param name="quest"></param>
		private void UpdateQuest(Creature creature, Quest quest)
		{
			if (!this.IsPartyQuest)
				Send.QuestUpdate(creature, quest);
			else
				Send.QuestUpdate(creature.Party, quest);
		}
Beispiel #27
0
		public override void Reward(Creature creature, Quest quest)
		{
			throw new NotImplementedException();
		}
Beispiel #28
0
		/// <summary>
		/// Returns true if creature can make progress on this quest.
		/// </summary>
		/// <remarks>
		/// Used from objective event handlers, to see if the quest should
		/// receive the progress.
		/// </remarks>
		/// <param name="creature"></param>
		/// <param name="quest"></param>
		/// <returns></returns>
		private bool CanMakeProgress(Creature creature, Quest quest)
		{
			// Party quests can only make progress if they're active
			if (this.IsPartyQuest)
				return (creature.IsInParty && creature.Party.Quest == quest);

			// TODO: Guild quests, outside, delay

			return true;
		}
Beispiel #29
0
		/// <summary>
		/// Gives reward to creature.
		/// </summary>
		/// <param name="creature"></param>
		/// <param name="quest"></param>
		public abstract void Reward(Creature creature, Quest quest);
Beispiel #30
0
		public static void AddQuest(this Packet packet, Quest quest)
		{
			if (quest.Data == null)
				throw new Exception("AddQuest: Missing quest data for '" + quest.Id.ToString() + "'.");

			packet.PutLong(quest.UniqueId);
			packet.PutByte(0);

			packet.PutLong(quest.QuestItem.EntityId);

			packet.PutByte((byte)quest.Data.Type); // 0 = blue icon, 2 = normal, 4 = exploration, 7 = shadow (changes structure slightly)
			// Client values that might make sense:
			// Delivery: 1? (id == 506401?)
			// Event: 1? ((this + 80) == 18?)
			// Homework: 1? ((this + 80) >= 10000?)
			// Exploration: 4|5
			// Escort: 6
			// Shadow: 7|8
			// Bingo: 9
			// GameQuest: 2|4|5
			// GuildQuest: 0 (id >= 110001 < 120000?)
			// PartyQuest: 0 (id >= 100000 < 110000?), blue icon with party symbol, turns yellow if active

			packet.PutInt(quest.Id); // Range is important for the tabs.
			// 201000~201999 : event
			// 202000~209999 : normal
			// 210000~239999 : goddess
			// 240000~289999 : normal
			// 290000~290599 : alchemist
			// 290600~291999 : normal
			// 292000~292599 : alchemist
			// 292600~292999 : normal
			// 293000~293599 : alchemist
			// 293600~293999 : shakespear (default)
			// 294000~294599 : shakespear (hamlet)
			// 294600~294999 : shakespear (default)
			// 295000~295599 : shakespear (romeo and juliet)
			// 295600~295999 : shakespear (default)
			// 296000~296599 : shakespear (merchant)
			// 296600~296999 : shakespear (default)
			// 297000~297599 : shakespear (macbeth)
			// 297600~______ : normal

			packet.PutString(quest.Data.Name);
			packet.PutString(quest.Data.Description);
			packet.PutString(quest.Data.AdditionalInfo);

			packet.PutInt(1);
			packet.PutInt(quest.QuestItem.Info.Id);
			packet.PutByte(quest.Data.Cancelable);
			packet.PutByte(0);
			packet.PutByte(0); // 1 = blue icon
			packet.PutByte(0);

			// [180300, NA166 (18.09.2013)] ?
			{
				packet.PutByte(0);
				packet.PutByte(0);
				packet.PutByte(0);
			}

			// [190200, NA203 (22.04.2015)] ?
			{
				packet.PutByte(0);
			}

			packet.PutString(""); // data\gfx\image\gui_temporary_quest.dds
			packet.PutInt(0);     // 4, x y ?
			packet.PutInt(0);
			packet.PutString(""); // <xml soundset="4" npc="GUI_NPCportrait_Lanier"/>
			packet.PutString(quest.MetaData.ToString());

			switch (quest.Data.Type)
			{
				case QuestType.Deliver:
					packet.PutInt((int)quest.Data.PtjType);
					packet.PutInt(quest.Data.StartHour);
					packet.PutInt(quest.Data.ReportHour);
					packet.PutInt(quest.Data.DeadlineHour);
					packet.PutLong(quest.Deadline);
					break;

				default:
					packet.PutInt(0);
					packet.PutInt(0);
					break;
			}

			packet.PutInt(quest.Data.Objectives.Count);
			foreach (var objectiveData in quest.Data.Objectives)
			{
				var objective = objectiveData.Value;
				var progress = quest.GetProgress(objectiveData.Key);

				// Objective
				packet.PutByte((byte)objective.Type);
				packet.PutString(objective.Description);
				packet.PutString(objective.MetaData.ToString());

				// 3  - TARGECHAR:s:shamala;TARGETCOUNT:4:1; - Ask Shamala about collecting transformations
				// 14 - TARGETITEM:4:40183;TARGETCOUNT:4:1; - Break a nearby tree
				// 1  - TGTSID:s:/brownphysisfoxkid/;TARGETCOUNT:4:10;TGTCLS:2:0; - Hunt 10 Young Brown Physis Foxes
				// 9  - TGTSKL:2:23002;TGTLVL:2:1;TARGETCOUNT:4:1; - Combat Mastery rank F reached
				// 19 - TGTCLS:2:3906;TARGETCOUNT:4:1; - Win at least one match in the preliminaries or the finals of the Jousting Tournament.
				// 18 - TGTCLS:2:3502;TARGETCOUNT:4:1; - Read the Author's Notebook.
				// 4  - TARGECHAR:s:duncan;TARGETITEM:4:75473;TARGETCOUNT:4:1; - Deliver the Author's Notebook to Duncan.
				// 15 - TGTLVL:2:15;TARGETCOUNT:4:1; - Reach Lv. 15
				// 2  - TARGETITEM:4:52027;TARGETCOUNT:4:10;QO_FLAG:4:1; - Harvest 10 Bundles of Wheat
				// 22 - TGTSID:s:/ski/start/;TARGETITEM:4:0;EXCNT:4:0;TGITM2:4:0;EXCNT2:4:0;TARGETCOUNT:4:1; - Click on the Start Flag.
				// 47 - TARGETCOUNT:4:1;TGTCLS:4:730205; - Clear the Monkey Mash Mission.
				// 52 - QO_FLAG:b:true;TARGETCOUNT:4:1; - Collect for the Transformation Diary
				// 50 - TARGETRACE:4:9;TARGETCOUNT:4:1; - Transform into a Kiwi.
				// 54 - TARGETRACE:4:9;TARGETCOUNT:4:1; - Collect Frail Green Kiwi perfectly.
				// 31 - TARGETCOUNT:4:1;TGTSID:s:/Gathering_Knife/; - Equip Gathering Knife
				// 32 - TARGETCOUNT:4:5;TARGETITEM:4:60009;TGTSID:s:/Gathering_Knife/; - Sheared 5 Sheep
				// 13 - TARGETCOUNT:4:1;TGTCLS:s:TirCho_Ciar_Low_Dungeon; - Clear Ciar Basic Dungeon

				// Type theory:
				// 1  : Kill x of y
				// 2  : Collect x of y
				// 3  : Talk to x
				// 4  : Bring x to y
				// 9  : Reach rank x on skill y
				// 13 : Clear dungeon
				// 14 : ?
				// 15 : Reach lvl x
				// 18 : Do something with item x ?
				// 19 : Clear something, like jousting or a dungeon?
				// 31 : Equip item, matching tag X
				// 32 : Gather item x, gather equipment doesn't seem to matter

				// Progress
				packet.PutInt(progress.Count);
				// [180600, NA187 (25.06.2014)] ?
				{
					packet.PutFloat(0);
				}
				packet.PutByte(progress.Done);
				packet.PutByte(progress.Unlocked);

				// Target location
				packet.PutByte(objective.RegionId > 0);
				if (objective.RegionId > 0)
				{
					packet.PutInt(objective.RegionId);
					packet.PutInt(objective.X);
					packet.PutInt(objective.Y);
				}
			}

			// Rewards
			packet.PutByte((byte)quest.Data.RewardGroups.Count);
			foreach (var group in quest.Data.RewardGroups.Values.OrderBy(a => a.Id))
			{
				// Group id has to be !0 for client to display rewards for PTJs
				packet.PutByte((byte)group.Id);
				packet.PutByte((byte)group.Type);
				packet.PutByte(group.PerfectOnly);

				packet.PutByte((byte)group.Rewards.Count);
				foreach (var reward in group.Rewards)
				{
					packet.PutByte((byte)reward.Type);
					packet.PutString(reward.ToString());
					packet.PutByte((byte)reward.Result);
					packet.PutByte(reward.Visible);

					// If false, displays "(시간초과시)" (timeout) after the
					// reward. Probably not used anymore, maybe players could
					// still get certain rewards after a timeout at some
					// point?
					packet.PutByte(true);
				}
			}

			packet.PutByte(0);
		}