mirror of
				https://bitbucket.org/Ioncannon/project-meteor-server.git
				synced 2025-05-20 08:26:59 -04:00 
			
		
		
		
	Refactored quest state system seems to work!
This commit is contained in:
		| @@ -20,69 +20,127 @@ along with Project Meteor Server. If not, see <https:www.gnu.org/licenses/>. | ||||
| */ | ||||
|  | ||||
| using Meteor.Map.lua; | ||||
| using Newtonsoft.Json; | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
|  | ||||
| namespace Meteor.Map.Actors | ||||
| namespace Meteor.Map.Actors.QuestNS | ||||
| { | ||||
|     class Quest : Actor | ||||
|     { | ||||
|         public const ushort SEQ_NOT_STARTED = 65535; | ||||
|         public const ushort SEQ_COMPLETED = 65534; | ||||
|  | ||||
|         private struct QuestData | ||||
|         { | ||||
|             public UInt32 flags; | ||||
|             public UInt16 counter1; | ||||
|             public UInt16 counter2; | ||||
|             public UInt16 counter3; | ||||
|             public UInt16 counter4; | ||||
|  | ||||
|             public QuestData(uint flags, ushort counter1, ushort counter2, ushort counter3) : this() | ||||
|             { | ||||
|                 this.flags = flags; | ||||
|                 this.counter1 = counter1; | ||||
|                 this.counter2 = counter2; | ||||
|                 this.counter3 = counter3; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         // This is only set on instance quests (non static) | ||||
|         private Player Owner; | ||||
|         private Player owner; | ||||
|         private ushort currentSequence; | ||||
|         private QuestState QuestState; | ||||
|         private QuestData Data; | ||||
|         private QuestState questState = null; | ||||
|         private QuestData data = null; | ||||
|         private bool dataDirty = false; | ||||
|  | ||||
|         // Creates a Static Quest for the StaticActors list. | ||||
|         public Quest(uint actorID, string className, string classPath) | ||||
|             : base(actorID) | ||||
|         { | ||||
|             Name = className; | ||||
|             this.className = className; | ||||
|             this.classPath = classPath; | ||||
|         } | ||||
|  | ||||
|         // Creates a Static Quest from another Static Quest | ||||
|         public Quest(Quest staticQuest) | ||||
|             : this(staticQuest.Id, staticQuest.Name, staticQuest.classPath) | ||||
|         { } | ||||
|  | ||||
|         // Creates a Instance Quest that has been started. | ||||
|         public Quest(Player owner, Quest staticQuest, ushort sequence) : this(staticQuest) | ||||
|         { | ||||
|             this.owner = owner; | ||||
|             currentSequence = sequence; | ||||
|             questState = new QuestState(owner, this); | ||||
|             questState.UpdateState(); | ||||
|         } | ||||
|  | ||||
|         // Creates a Instance Quest that has not been started. | ||||
|         public Quest(Player owner, Quest staticQuest) : this(owner, staticQuest, SEQ_NOT_STARTED) | ||||
|         { } | ||||
|  | ||||
|         #region Getters | ||||
|         public uint GetQuestId() | ||||
|         { | ||||
|             return Id & 0xFFFFF; | ||||
|         } | ||||
|  | ||||
|         public override bool Equals(object obj) | ||||
|         { | ||||
|             if (obj != null && obj is Quest quest) | ||||
|                 return quest.Id == this.Id; | ||||
|             return false; | ||||
|         } | ||||
|  | ||||
|         public override int GetHashCode() | ||||
|         { | ||||
|             return base.GetHashCode(); | ||||
|         } | ||||
|  | ||||
|         public bool IsInstance() | ||||
|         { | ||||
|             return questState != null; | ||||
|         } | ||||
|  | ||||
|         public bool IsMainScenario() | ||||
|         { | ||||
|             uint id = GetQuestId(); | ||||
|             return id >= 110001 && id <= 110021; | ||||
|         } | ||||
|  | ||||
|         public ushort GetSequence() | ||||
|         { | ||||
|             return currentSequence; | ||||
|         } | ||||
|         #endregion | ||||
|  | ||||
|         #region Quest Data | ||||
|         public void SetData(uint flags, ushort counter1, ushort counter2, ushort counter3, ushort counter4) | ||||
|         { | ||||
|             data = new QuestData(owner, this, flags, counter1, counter2, counter3, counter4); | ||||
|         } | ||||
|  | ||||
|         public QuestData GetData() | ||||
|         { | ||||
|             return data; | ||||
|         } | ||||
|  | ||||
|         public bool HasData() | ||||
|         { | ||||
|             return data != null; | ||||
|         } | ||||
|         #endregion | ||||
|  | ||||
|         #region Quest State | ||||
|         public void SetENpc(uint classId, byte flagType = 0, bool isTalkEnabled = true, bool isPushEnabled = false, bool isEmoteEnabled = false, bool isSpawned = false) | ||||
|         { | ||||
|             if (QuestState != null) | ||||
|                 QuestState.AddENpc(classId, flagType, isTalkEnabled, isPushEnabled, isEmoteEnabled, isSpawned); | ||||
|             if (questState != null) | ||||
|                 questState.AddENpc(classId, flagType, isTalkEnabled, isPushEnabled, isEmoteEnabled, isSpawned); | ||||
|         } | ||||
|  | ||||
|         public void UpdateENPCs() | ||||
|         { | ||||
|             if (dataDirty) | ||||
|             { | ||||
|                 if (QuestState != null) | ||||
|                     QuestState.UpdateState(); | ||||
|                 if (questState != null) | ||||
|                     questState.UpdateState(); | ||||
|                 dataDirty = false; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         public QuestState GetQuestState() | ||||
|         { | ||||
|             return QuestState; | ||||
|         } | ||||
|  | ||||
|         public bool IsInstance() | ||||
|         { | ||||
|             return Owner != null; | ||||
|             return questState; | ||||
|         } | ||||
|         #endregion | ||||
|  | ||||
|         #region Script Callbacks | ||||
|         public void OnTalk(Player caller, Npc npc) | ||||
|         {         | ||||
|         { | ||||
|             LuaEngine.GetInstance().CallLuaFunction(caller, this, "onTalk", true, npc); | ||||
|         } | ||||
|  | ||||
| @@ -106,17 +164,9 @@ namespace Meteor.Map.Actors | ||||
|             LuaEngine.GetInstance().CallLuaFunction(caller, this, "onNpcLS", true, npcLSId); | ||||
|         } | ||||
|  | ||||
|         public bool IsQuestENPC(Player caller, Npc npc) | ||||
|         { | ||||
|             List<LuaParam> returned = LuaEngine.GetInstance().CallLuaFunctionForReturn(caller, this, "IsQuestENPC", true, npc, this); | ||||
|             bool scriptReturned = returned != null && returned.Count != 0 && returned[0].typeID == 3; | ||||
|             return scriptReturned || QuestState.HasENpc(npc.GetActorClassId()); | ||||
|         } | ||||
|  | ||||
|  | ||||
|         public object[] GetJournalInformation() | ||||
|         { | ||||
|             List<LuaParam> returned = LuaEngine.GetInstance().CallLuaFunctionForReturn(Owner, this, "getJournalInformation", true); | ||||
|             List<LuaParam> returned = LuaEngine.GetInstance().CallLuaFunctionForReturn(owner, this, "getJournalInformation", true); | ||||
|             if (returned != null && returned.Count != 0) | ||||
|                 return LuaUtils.CreateLuaParamObjectList(returned); | ||||
|             else | ||||
| @@ -125,212 +175,59 @@ namespace Meteor.Map.Actors | ||||
|  | ||||
|         public object[] GetJournalMapMarkerList() | ||||
|         { | ||||
|             List<LuaParam> returned = LuaEngine.GetInstance().CallLuaFunctionForReturn(Owner, this, "getJournalMapMarkerList", true); | ||||
|             List<LuaParam> returned = LuaEngine.GetInstance().CallLuaFunctionForReturn(owner, this, "getJournalMapMarkerList", true); | ||||
|             if (returned != null && returned.Count != 0) | ||||
|                 return LuaUtils.CreateLuaParamObjectList(returned); | ||||
|             else | ||||
|                 return new object[0]; | ||||
|         } | ||||
|         #endregion | ||||
|  | ||||
|         public ushort GetSequence() | ||||
|         public bool IsQuestENPC(Player caller, Npc npc) | ||||
|         { | ||||
|             return currentSequence; | ||||
|             List<LuaParam> returned = LuaEngine.GetInstance().CallLuaFunctionForReturn(caller, this, "IsQuestENPC", true, npc, this); | ||||
|             bool scriptReturned = returned != null && returned.Count != 0 && returned[0].typeID == 3; | ||||
|             return scriptReturned || questState.HasENpc(npc.GetActorClassId()); | ||||
|         } | ||||
|  | ||||
|         public void StartSequence(ushort sequence) | ||||
|         {             | ||||
|         { | ||||
|             if (sequence == SEQ_NOT_STARTED) | ||||
|                 return; | ||||
|  | ||||
|             // Send the message that the journal has been updated | ||||
|             if (currentSequence != SEQ_NOT_STARTED) | ||||
|                 Owner.SendGameMessage(Server.GetWorldManager().GetActor(), 25116, 0x20, (object)GetQuestId()); | ||||
|                 owner.SendGameMessage(Server.GetWorldManager().GetActor(), 25116, 0x20, (object)GetQuestId()); | ||||
|  | ||||
|             currentSequence = sequence; | ||||
|             dataDirty = true; | ||||
|             UpdateENPCs(); | ||||
|             questState.UpdateState(); | ||||
|         } | ||||
|  | ||||
|         public void ClearData() | ||||
|         { | ||||
|             Data.flags = Data.counter1 = Data.counter2 = Data.counter3 = Data.counter4 = 0; | ||||
|         } | ||||
|  | ||||
|         public void SetFlag(int index) | ||||
|         { | ||||
|             if (index >= 0 && index < 32) | ||||
|             { | ||||
|                 Data.flags |= (uint)(1 << index); | ||||
|                 dataDirty = true; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         public void ClearFlag(int index) | ||||
|         { | ||||
|             if (index >= 0 && index < 32) | ||||
|             { | ||||
|                 Data.flags &= (uint)~(1 << index); | ||||
|                 dataDirty = true; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         public void IncCounter(int num) | ||||
|         { | ||||
|             dataDirty = true; | ||||
|  | ||||
|             switch (num) | ||||
|             { | ||||
|                 case 0: | ||||
|                     Data.counter1++; | ||||
|                     return; | ||||
|                 case 1: | ||||
|                     Data.counter2++; | ||||
|                     return; | ||||
|                 case 2: | ||||
|                     Data.counter3++; | ||||
|                     return; | ||||
|                 case 3: | ||||
|                     Data.counter4++; | ||||
|                     return; | ||||
|             } | ||||
|  | ||||
|             dataDirty = false; | ||||
|         } | ||||
|  | ||||
|         public void DecCounter(int num) | ||||
|         { | ||||
|             dataDirty = true; | ||||
|  | ||||
|             switch (num) | ||||
|             { | ||||
|                 case 0: | ||||
|                     Data.counter1--; | ||||
|                     return; | ||||
|                 case 1: | ||||
|                     Data.counter2--; | ||||
|                     return; | ||||
|                 case 2: | ||||
|                     Data.counter3--; | ||||
|                     return; | ||||
|                 case 3: | ||||
|                     Data.counter4--; | ||||
|                     return; | ||||
|             } | ||||
|  | ||||
|             dataDirty = false; | ||||
|         } | ||||
|  | ||||
|         public void SetCounter(int num, ushort value) | ||||
|         { | ||||
|             dataDirty = true; | ||||
|  | ||||
|             switch (num) | ||||
|             { | ||||
|                 case 0: | ||||
|                     Data.counter1 = value; | ||||
|                     return; | ||||
|                 case 1: | ||||
|                     Data.counter2 = value; | ||||
|                     return; | ||||
|                 case 2: | ||||
|                     Data.counter3 = value; | ||||
|                     return; | ||||
|                 case 3: | ||||
|                     Data.counter4 = value; | ||||
|                     return; | ||||
|             } | ||||
|  | ||||
|             dataDirty = false; | ||||
|         } | ||||
|  | ||||
|         public bool GetFlag(int index) | ||||
|         { | ||||
|             if (index >= 0 && index < 32) | ||||
|                 return (Data.flags & (uint) (1 << index)) != 0; | ||||
|             return false; | ||||
|         } | ||||
|  | ||||
|         public uint GetFlags() | ||||
|         { | ||||
|             return Data.flags; | ||||
|         } | ||||
|  | ||||
|         public ushort GetCounter(int num) | ||||
|         { | ||||
|             switch (num) | ||||
|             { | ||||
|                 case 0: | ||||
|                     return Data.counter1; | ||||
|                 case 1: | ||||
|                     return Data.counter2; | ||||
|                 case 2: | ||||
|                     return Data.counter3; | ||||
|                 case 3: | ||||
|                     return Data.counter4; | ||||
|             } | ||||
|  | ||||
|             return 0; | ||||
|         } | ||||
|  | ||||
|         public void SaveData() | ||||
|         {             | ||||
|             Database.SaveQuest(Owner, this); | ||||
|         } | ||||
|  | ||||
|         public Quest(uint actorID, string name) | ||||
|             : base(actorID) | ||||
|         { | ||||
|             Name = name;             | ||||
|         } | ||||
|  | ||||
|         public Quest(Player owner, Quest baseQuest): this(owner, baseQuest, SEQ_NOT_STARTED, 0, 0, 0, 0) | ||||
|         {} | ||||
|  | ||||
|         public Quest(Player owner, Quest baseQuest, ushort sequence, uint flags, ushort counter1, ushort counter2, ushort counter3) | ||||
|             : base(baseQuest.Id) | ||||
|         { | ||||
|             Owner = owner; | ||||
|             Name = baseQuest.Name; | ||||
|             className = baseQuest.className; | ||||
|             classPath = baseQuest.classPath; | ||||
|             currentSequence = sequence; | ||||
|             QuestState = new QuestState(owner, this); | ||||
|             Data = new QuestData(flags, counter1, counter2, counter3); | ||||
|         } | ||||
|         | ||||
|         public uint GetQuestId() | ||||
|         { | ||||
|             return Id & 0xFFFFF; | ||||
|         } | ||||
|  | ||||
|         public void DoAccept() | ||||
|         public void OnAccept() | ||||
|         { | ||||
|             data = new QuestData(owner, this); | ||||
|             if (currentSequence == SEQ_NOT_STARTED) | ||||
|                 LuaEngine.GetInstance().CallLuaFunction(Owner, this, "onStart", false); | ||||
|                 LuaEngine.GetInstance().CallLuaFunction(owner, this, "onStart", false); | ||||
|             else | ||||
|                 StartSequence(currentSequence); | ||||
|         } | ||||
|  | ||||
|         public void DoComplete() | ||||
|         public void OnComplete() | ||||
|         { | ||||
|             LuaEngine.GetInstance().CallLuaFunctionForReturn(Owner, this, "onFinish", true); | ||||
|             Owner.SendDataPacket("attention", Server.GetWorldManager().GetActor(), "", 25225, (object)GetQuestId()); | ||||
|             Owner.SendGameMessage(Server.GetWorldManager().GetActor(), 25225, 0x20, (object)GetQuestId()); | ||||
|             LuaEngine.GetInstance().CallLuaFunctionForReturn(owner, this, "onFinish", true); | ||||
|             currentSequence = SEQ_COMPLETED; | ||||
|             data = null; | ||||
|             questState.UpdateState(); | ||||
|         } | ||||
|  | ||||
|         public void DoAbandon() | ||||
|         public void OnAbandon() | ||||
|         { | ||||
|             LuaEngine.GetInstance().CallLuaFunctionForReturn(Owner, this, "onFinish", false); | ||||
|             Owner.SendGameMessage(Owner, Server.GetWorldManager().GetActor(), 25236, 0x20, (object)GetQuestId()); | ||||
|             LuaEngine.GetInstance().CallLuaFunctionForReturn(owner, this, "onFinish", false); | ||||
|             currentSequence = SEQ_NOT_STARTED; | ||||
|             data = null; | ||||
|             questState.UpdateState(); | ||||
|         } | ||||
|  | ||||
|         public override bool Equals(object obj) | ||||
|         { | ||||
|             if (obj is Quest quest) | ||||
|                 return quest.Id == this.Id; | ||||
|             return false; | ||||
|         } | ||||
|     } | ||||
| } | ||||
|   | ||||
							
								
								
									
										167
									
								
								Map Server/Actors/Quest/QuestData.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										167
									
								
								Map Server/Actors/Quest/QuestData.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,167 @@ | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.Linq; | ||||
| using System.Text; | ||||
| using System.Threading.Tasks; | ||||
|  | ||||
| namespace Meteor.Map.Actors.QuestNS | ||||
| { | ||||
|     class QuestData | ||||
|     { | ||||
|         private Player owner; | ||||
|         private Quest parent; | ||||
|  | ||||
|         private uint flags; | ||||
|         private ushort counter1; | ||||
|         private ushort counter2; | ||||
|         private ushort counter3; | ||||
|         private ushort counter4; | ||||
|         private bool dataDirty = false; | ||||
|  | ||||
|         public QuestData(Player owner, Quest parent, uint flags, ushort counter1, ushort counter2, ushort counter3, ushort counter4) | ||||
|         { | ||||
|             this.owner = owner; | ||||
|             this.parent = parent; | ||||
|             this.flags = flags; | ||||
|             this.counter1 = counter1; | ||||
|             this.counter2 = counter2; | ||||
|             this.counter3 = counter3; | ||||
|             this.counter4 = counter4; | ||||
|         } | ||||
|  | ||||
|         public QuestData(Player owner, Quest parent) | ||||
|         { | ||||
|             this.owner = owner; | ||||
|             this.parent = parent; | ||||
|             flags = counter1 = counter2 = counter3 = counter4 = 0; | ||||
|         } | ||||
|  | ||||
|         public void ClearData() | ||||
|         { | ||||
|             flags = counter1 = counter2 = counter3 = counter4 = 0; | ||||
|         } | ||||
|  | ||||
|         public void SetFlag(int index) | ||||
|         { | ||||
|             if (index >= 0 && index < 32) | ||||
|             { | ||||
|                 flags |= (uint)(1 << index); | ||||
|                 dataDirty = true; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         public void ClearFlag(int index) | ||||
|         { | ||||
|             if (index >= 0 && index < 32) | ||||
|             { | ||||
|                 flags &= (uint)~(1 << index); | ||||
|                 dataDirty = true; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         public ushort IncCounter(int num) | ||||
|         { | ||||
|             dataDirty = true; | ||||
|  | ||||
|             switch (num) | ||||
|             { | ||||
|                 case 0: | ||||
|                     counter1++; | ||||
|                     return counter1; | ||||
|                 case 1: | ||||
|                     counter2++; | ||||
|                     return counter2; | ||||
|                 case 2: | ||||
|                     counter3++; | ||||
|                     return counter3; | ||||
|                 case 3: | ||||
|                     counter4++; | ||||
|                     return counter4; | ||||
|             } | ||||
|  | ||||
|             dataDirty = false; | ||||
|             return 0; | ||||
|         } | ||||
|  | ||||
|         public ushort DecCounter(int num) | ||||
|         { | ||||
|             dataDirty = true; | ||||
|  | ||||
|             switch (num) | ||||
|             { | ||||
|                 case 0: | ||||
|                     counter1--; | ||||
|                     return counter1; | ||||
|                 case 1: | ||||
|                     counter2--; | ||||
|                     return counter2; | ||||
|                 case 2: | ||||
|                     counter3--; | ||||
|                     return counter3; | ||||
|                 case 3: | ||||
|                     counter4--; | ||||
|                     return counter4; | ||||
|             } | ||||
|  | ||||
|             dataDirty = false; | ||||
|             return 0; | ||||
|         } | ||||
|  | ||||
|         public void SetCounter(int num, ushort value) | ||||
|         { | ||||
|             dataDirty = true; | ||||
|  | ||||
|             switch (num) | ||||
|             { | ||||
|                 case 0: | ||||
|                     counter1 = value; | ||||
|                     return; | ||||
|                 case 1: | ||||
|                     counter2 = value; | ||||
|                     return; | ||||
|                 case 2: | ||||
|                     counter3 = value; | ||||
|                     return; | ||||
|                 case 3: | ||||
|                     counter4 = value; | ||||
|                     return; | ||||
|             } | ||||
|  | ||||
|             dataDirty = false; | ||||
|         } | ||||
|  | ||||
|         public bool GetFlag(int index) | ||||
|         { | ||||
|             if (index >= 0 && index < 32) | ||||
|                 return (flags & (uint)(1 << index)) != 0; | ||||
|             return false; | ||||
|         } | ||||
|  | ||||
|         public uint GetFlags() | ||||
|         { | ||||
|             return flags; | ||||
|         } | ||||
|  | ||||
|         public ushort GetCounter(int num) | ||||
|         { | ||||
|             switch (num) | ||||
|             { | ||||
|                 case 0: | ||||
|                     return counter1; | ||||
|                 case 1: | ||||
|                     return counter2; | ||||
|                 case 2: | ||||
|                     return counter3; | ||||
|                 case 3: | ||||
|                     return counter4; | ||||
|             } | ||||
|  | ||||
|             return 0; | ||||
|         } | ||||
|  | ||||
|         public void Save() | ||||
|         { | ||||
|             Database.SaveQuest(owner, parent); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -5,7 +5,7 @@ using System.Linq; | ||||
| using System.Text; | ||||
| using System.Threading.Tasks; | ||||
|  | ||||
| namespace Meteor.Map.Actors | ||||
| namespace Meteor.Map.Actors.QuestNS | ||||
| { | ||||
|     class QuestState | ||||
|     { | ||||
| @@ -49,8 +49,8 @@ namespace Meteor.Map.Actors | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         private Player Owner; | ||||
|         private Quest Parent; | ||||
|         private readonly Player Owner; | ||||
|         private readonly Quest Parent; | ||||
|         private Dictionary<uint, QuestENpc> CurrentENPCs = new Dictionary<uint, QuestENpc>(); | ||||
|         private Dictionary<uint, QuestENpc> OldENPCs = new Dictionary<uint, QuestENpc>(); | ||||
|  | ||||
| @@ -58,7 +58,6 @@ namespace Meteor.Map.Actors | ||||
|         { | ||||
|             Owner = owner; | ||||
|             Parent = parent; | ||||
|             UpdateState(); | ||||
|         } | ||||
|  | ||||
|         public void AddENpc(uint classId, byte flagType = 0, bool isTalkEnabled = true, bool isPushEnabled = false, bool isEmoteEnabled = false, bool isSpawned = false) | ||||
| @@ -105,8 +104,15 @@ namespace Meteor.Map.Actors | ||||
|             CurrentENPCs = new Dictionary<uint, QuestENpc>(); | ||||
|             LuaEngine.GetInstance().CallLuaFunctionForReturn(Owner, Parent, "onStateChange", false, currentSeq); | ||||
|             foreach (var enpc in OldENPCs) | ||||
|                 Owner.playerSession.UpdateQuestNpcInInstance(enpc.Value); | ||||
|                 Owner.playerSession.UpdateQuestNpcInInstance(enpc.Value, true); | ||||
|             OldENPCs = null; | ||||
|         } | ||||
|  | ||||
|         public void DeleteState() | ||||
|         { | ||||
|             foreach (var enpc in CurrentENPCs) | ||||
|                 Owner.playerSession.UpdateQuestNpcInInstance(enpc.Value, true); | ||||
|             CurrentENPCs.Clear(); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -7,7 +7,7 @@ using System.Linq; | ||||
| using System.Text; | ||||
| using System.Threading.Tasks; | ||||
|  | ||||
| namespace Meteor.Map.Actors | ||||
| namespace Meteor.Map.Actors.QuestNS | ||||
| { | ||||
|     class QuestStateManager | ||||
|     { | ||||
| @@ -21,16 +21,30 @@ namespace Meteor.Map.Actors | ||||
|         private readonly Bitstream GCRankBitfield = new Bitstream(SCENARIO_MAX, true); | ||||
|  | ||||
|         private List<Quest> ActiveQuests = new List<Quest>(); | ||||
|         private Dictionary<uint, QuestState> QuestStateTable = new Dictionary<uint, QuestState>(); | ||||
|  | ||||
|         public QuestStateManager(Player player) | ||||
|         { | ||||
|             this.player = player; | ||||
|         } | ||||
|  | ||||
|         public void Init() | ||||
|         public void Init(Quest[] questScenario) | ||||
|         { | ||||
|             // Preload any quests that the player loaded | ||||
|             if (questScenario != null) | ||||
|             { | ||||
|                 foreach (var quest in questScenario) | ||||
|                 { | ||||
|                     if (quest != null) | ||||
|                     { | ||||
|                         ActiveQuests.Add(quest); | ||||
|                         AvailableQuestsBitfield.Set(quest.GetQuestId() - SCENARIO_START); | ||||
|                     } | ||||
|                 } | ||||
|             }                 | ||||
|  | ||||
|             // Init MinLv | ||||
|             QuestData[] minLvl = Server.GetQuestGamedataByMaxLvl(player.GetHighestLevel(), true); | ||||
|             QuestGameData[] minLvl = Server.GetQuestGamedataByMaxLvl(player.GetHighestLevel(), true); | ||||
|             foreach (var questData in minLvl) | ||||
|                 MinLevelBitfield.Set(questData.Id - SCENARIO_START); | ||||
|  | ||||
| @@ -43,28 +57,29 @@ namespace Meteor.Map.Actors | ||||
|                 else | ||||
|                     PrereqBitfield.Clear(questData.Id - SCENARIO_START); | ||||
|             } | ||||
|  | ||||
|             ComputeAvailable(); | ||||
|         } | ||||
|  | ||||
|         public void UpdateLevel(int level) | ||||
|         { | ||||
|             QuestData[] updated = Server.GetQuestGamedataByMaxLvl(level); | ||||
|             QuestGameData[] updated = Server.GetQuestGamedataByMaxLvl(level); | ||||
|             foreach (var questData in updated) | ||||
|                 MinLevelBitfield.Set(questData.Id - SCENARIO_START); | ||||
|             ComputeAvailable(); | ||||
|         } | ||||
|  | ||||
|         public void UpdateQuestComplete(Quest quest) | ||||
|         public void UpdateQuestCompleted(Quest quest) | ||||
|         { | ||||
|             QuestData[] updated = Server.GetQuestGamedataByPrerequisite(quest.GetQuestId()); | ||||
|             QuestGameData[] updated = Server.GetQuestGamedataByPrerequisite(quest.GetQuestId()); | ||||
|             foreach (var questData in updated) | ||||
|                 PrereqBitfield.Set(questData.Id - SCENARIO_START); | ||||
|             ComputeAvailable(); | ||||
|         } | ||||
|  | ||||
|         public void QuestAdded(Quest quest) | ||||
|         public void UpdateQuestAbandoned() | ||||
|         { | ||||
|             ActiveQuests.Remove(quest); | ||||
|             ComputeAvailable(); | ||||
|         } | ||||
|  | ||||
|         private void ComputeAvailable() | ||||
| @@ -90,9 +105,9 @@ namespace Meteor.Map.Actors | ||||
|                         int index = i * 8 + shift; | ||||
|                         Quest quest = (Quest)Server.GetStaticActors(0xA0F00000 | (SCENARIO_START + (uint)index)); | ||||
|                         if (!AvailableQuestsBitfield.Get(index)) | ||||
|                             ActiveQuests.Add(new Quest(player, quest)); | ||||
|                             AddActiveQuest(quest); | ||||
|                         else | ||||
|                             ActiveQuests.Remove(quest); | ||||
|                             RemoveActiveQuest(quest); | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
| @@ -100,6 +115,39 @@ namespace Meteor.Map.Actors | ||||
|             AvailableQuestsBitfield.SetTo(result); | ||||
|         } | ||||
|  | ||||
|         public void ForceAddActiveQuest(Quest questInstance) | ||||
|         { | ||||
|             ActiveQuests.Add(questInstance); | ||||
|             QuestStateTable.Add(questInstance.Id, questInstance.GetQuestState()); | ||||
|         } | ||||
|  | ||||
|         private void AddActiveQuest(Quest staticQuest) | ||||
|         { | ||||
|             Quest instance = new Quest(player, staticQuest); | ||||
|             ActiveQuests.Add(instance); | ||||
|             QuestStateTable.Add(staticQuest.Id, instance.GetQuestState()); | ||||
|         } | ||||
|  | ||||
|         private void RemoveActiveQuest(Quest staticQuest) | ||||
|         { | ||||
|             // Do not remove quests in the player's journal | ||||
|             if (player.HasQuest(staticQuest.GetQuestId())) | ||||
|                 return; | ||||
|  | ||||
|             ActiveQuests.Remove(staticQuest); | ||||
|  | ||||
|             if (QuestStateTable.ContainsKey(staticQuest.Id)) | ||||
|             { | ||||
|                 QuestStateTable[staticQuest.Id].DeleteState(); | ||||
|                 QuestStateTable.Remove(staticQuest.Id); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         public Quest GetActiveQuest(uint id) | ||||
|         { | ||||
|             return ActiveQuests.Find(quest => quest.GetQuestId() == id); | ||||
|         } | ||||
|  | ||||
|         public Quest[] GetQuestsForNpc(Npc npc) | ||||
|         { | ||||
|             return ActiveQuests.FindAll(quest => quest.IsQuestENPC(player, npc)).ToArray(); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user