PageRenderTime 42ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/src/Mooege/Core/GS/Games/Quest.cs

http://github.com/mooege/mooege
C# | 228 lines | 170 code | 25 blank | 33 comment | 21 complexity | d53bc91a0d8381ef7f54097b5482cec8 MD5 | raw file
Possible License(s): BSD-3-Clause, CC-BY-SA-3.0, MPL-2.0-no-copyleft-exception, LGPL-3.0, GPL-2.0
  1. /*
  2. * Copyright (C) 2011 mooege project
  3. *
  4. * This program is free software; you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License as published by
  6. * the Free Software Foundation; either version 2 of the License, or
  7. * (at your option) any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program; if not, write to the Free Software
  16. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  17. */
  18. using System;
  19. using System.Collections.Generic;
  20. using System.Linq;
  21. using System.Text;
  22. using Mooege.Common.MPQ;
  23. using Mooege.Net.GS.Message.Definitions.Quest;
  24. using Mooege.Core.GS.Common.Types.SNO;
  25. using Mooege.Core.GS.Games;
  26. using Mooege.Common;
  27. namespace Mooege.Core.GS.Games
  28. {
  29. public interface QuestProgressHandler
  30. {
  31. void Notify(Mooege.Common.MPQ.FileFormats.QuestStepObjectiveType type, int value);
  32. }
  33. public class Quest : QuestProgressHandler
  34. {
  35. /// <summary>
  36. /// Keeps track of a single quest step
  37. /// </summary>
  38. public class QuestStep : QuestProgressHandler
  39. {
  40. /// <summary>
  41. /// Keeps track of a single quest step objective
  42. /// </summary>
  43. public class QuestObjective : QuestProgressHandler
  44. {
  45. public int Counter { get; private set; }
  46. public bool Done { get { return (objective.CounterTarget == 0 && Counter > 0) || Counter == objective.CounterTarget; } }
  47. public int ID { get; private set; }
  48. // these are only needed to show information in console
  49. public Mooege.Common.MPQ.FileFormats.QuestStepObjectiveType ObjectiveType { get { return objective.ObjectiveType; } }
  50. public int ObjectiveValue { get { return objective.SNOName1.Id; } }
  51. private Mooege.Common.MPQ.FileFormats.QuestStepObjective objective;
  52. private QuestStep questStep;
  53. public QuestObjective(Mooege.Common.MPQ.FileFormats.QuestStepObjective objective, QuestStep questStep, int id)
  54. {
  55. ID = id;
  56. this.objective = objective;
  57. this.questStep = questStep;
  58. }
  59. /// <summary>
  60. /// Notifies the objective, that an event occured. The objective checks if that event matches the event it waits for
  61. /// </summary>
  62. public void Notify(Mooege.Common.MPQ.FileFormats.QuestStepObjectiveType type, int value)
  63. {
  64. if (type != objective.ObjectiveType) return;
  65. switch (type)
  66. {
  67. case Mooege.Common.MPQ.FileFormats.QuestStepObjectiveType.EnterWorld:
  68. case Mooege.Common.MPQ.FileFormats.QuestStepObjectiveType.EnterScene:
  69. case Mooege.Common.MPQ.FileFormats.QuestStepObjectiveType.InteractWithActor:
  70. case Mooege.Common.MPQ.FileFormats.QuestStepObjectiveType.KillMonster:
  71. case Mooege.Common.MPQ.FileFormats.QuestStepObjectiveType.CompleteQuest:
  72. case Mooege.Common.MPQ.FileFormats.QuestStepObjectiveType.HadConversation:
  73. case Mooege.Common.MPQ.FileFormats.QuestStepObjectiveType.EnterLevelArea:
  74. if (value == objective.SNOName1.Id)
  75. {
  76. Counter++;
  77. questStep.UpdateCounter(this);
  78. }
  79. break;
  80. case Mooege.Common.MPQ.FileFormats.QuestStepObjectiveType.EnterTrigger:
  81. case Mooege.Common.MPQ.FileFormats.QuestStepObjectiveType.EventReceived:
  82. case Mooege.Common.MPQ.FileFormats.QuestStepObjectiveType.GameFlagSet:
  83. case Mooege.Common.MPQ.FileFormats.QuestStepObjectiveType.KillGroup:
  84. case Mooege.Common.MPQ.FileFormats.QuestStepObjectiveType.PlayerFlagSet:
  85. case Mooege.Common.MPQ.FileFormats.QuestStepObjectiveType.PossessItem:
  86. case Mooege.Common.MPQ.FileFormats.QuestStepObjectiveType.TimedEventExpired:
  87. throw new NotImplementedException();
  88. }
  89. }
  90. }
  91. // this is only public for GameCommand / Debug
  92. public struct ObjectiveSet
  93. {
  94. public List<QuestObjective> Objectives;
  95. public int FollowUpStepID;
  96. }
  97. public List<ObjectiveSet> ObjectivesSets = new List<ObjectiveSet>(); // this is only public for GameCommand / Debug
  98. private List<List<QuestObjective>> bonusObjectives = new List<List<QuestObjective>>();
  99. private Mooege.Common.MPQ.FileFormats.IQuestStep _questStep = null;
  100. private Quest _quest = null;
  101. public int QuestStepID { get { return _questStep.ID; } }
  102. private void UpdateCounter(QuestObjective objective)
  103. {
  104. if (_questStep is Mooege.Common.MPQ.FileFormats.QuestUnassignedStep == false)
  105. {
  106. foreach (var player in _quest.game.Players.Values)
  107. player.InGameClient.SendMessage(new QuestCounterMessage()
  108. {
  109. snoQuest = _quest.SNOHandle.Id,
  110. snoLevelArea = -1,
  111. StepID = _questStep.ID,
  112. TaskIndex = objective.ID,
  113. Counter = objective.Counter,
  114. Checked = objective.Done ? 1 : 0,
  115. });
  116. }
  117. var completedObjectiveList = from objectiveSet in ObjectivesSets
  118. where (from o in objectiveSet.Objectives select o.Done).Aggregate((r, o) => r && o)
  119. select objectiveSet.FollowUpStepID;
  120. if (completedObjectiveList.Count() > 0)
  121. _quest.StepCompleted(completedObjectiveList.First());
  122. }
  123. /// <summary>
  124. /// Debug method, completes a given objective set
  125. /// </summary>
  126. /// <param name="index"></param>
  127. public void CompleteObjectiveSet(int index)
  128. {
  129. _quest.StepCompleted(_questStep.StepObjectiveSets[index].FollowUpStepID);
  130. }
  131. public QuestStep(Mooege.Common.MPQ.FileFormats.IQuestStep assetQuestStep, Quest quest)
  132. {
  133. _questStep = assetQuestStep;
  134. _quest = quest;
  135. int c = 0;
  136. foreach (var objectiveSet in assetQuestStep.StepObjectiveSets)
  137. ObjectivesSets.Add(new ObjectiveSet()
  138. {
  139. FollowUpStepID = objectiveSet.FollowUpStepID,
  140. Objectives = new List<QuestObjective>(from objective in objectiveSet.StepObjectives select new QuestObjective(objective, this, c++))
  141. });
  142. c = 0;
  143. if (assetQuestStep is Mooege.Common.MPQ.FileFormats.QuestStep)
  144. {
  145. var step = assetQuestStep as Mooege.Common.MPQ.FileFormats.QuestStep;
  146. if (step.StepBonusObjectiveSets != null)
  147. foreach (var objectiveSet in step.StepBonusObjectiveSets)
  148. bonusObjectives.Add(new List<QuestObjective>(from objective in objectiveSet.StepBonusObjectives select new QuestObjective(objective, this, c++)));
  149. }
  150. }
  151. public void Notify(Mooege.Common.MPQ.FileFormats.QuestStepObjectiveType type, int value)
  152. {
  153. foreach (var objectiveSet in ObjectivesSets)
  154. foreach (var objective in objectiveSet.Objectives)
  155. objective.Notify(type, value);
  156. }
  157. }
  158. public delegate void QuestProgressDelegate(Quest quest);
  159. public event QuestProgressDelegate OnQuestProgress;
  160. private Mooege.Common.MPQ.FileFormats.Quest asset = null;
  161. public SNOHandle SNOHandle { get; set; }
  162. private Game game { get; set; }
  163. public QuestStep CurrentStep { get; set; }
  164. private List<int> completedSteps = new List<int>(); // this list has to be saved if quest progress should be saved. It is required to keep track of questranges
  165. public Quest(Game game, int SNOQuest)
  166. {
  167. this.game = game;
  168. SNOHandle = new SNOHandle(SNOGroup.Quest, SNOQuest);
  169. asset = SNOHandle.Target as Mooege.Common.MPQ.FileFormats.Quest;
  170. CurrentStep = new QuestStep(asset.QuestUnassignedStep, this);
  171. }
  172. //
  173. public bool HasStepCompleted(int stepID)
  174. {
  175. return completedSteps.Contains(stepID); // || CurrentStep.ObjectivesSets.Select(x => x.FollowUpStepID).Contains(stepID);
  176. }
  177. public void Advance()
  178. {
  179. CurrentStep.CompleteObjectiveSet(0);
  180. }
  181. public void StepCompleted(int FollowUpStepID)
  182. {
  183. foreach (var player in game.Players.Values)
  184. player.InGameClient.SendMessage(new QuestUpdateMessage()
  185. {
  186. snoQuest = SNOHandle.Id,
  187. snoLevelArea = -1,
  188. StepID = FollowUpStepID,
  189. Field3 = true,
  190. Failed = false
  191. });
  192. completedSteps.Add(CurrentStep.QuestStepID);
  193. CurrentStep = (from step in asset.QuestSteps where step.ID == FollowUpStepID select new QuestStep(step, this)).FirstOrDefault();
  194. if (OnQuestProgress != null)
  195. OnQuestProgress(this);
  196. }
  197. public void Notify(Mooege.Common.MPQ.FileFormats.QuestStepObjectiveType type, int value)
  198. {
  199. if (CurrentStep != null)
  200. CurrentStep.Notify(type, value);
  201. }
  202. }
  203. }