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:
		| @@ -37,6 +37,7 @@ using Meteor.Map.actors.chara.ai.controllers; | ||||
| using Meteor.Map.actors.chara.ai.utils; | ||||
| using Meteor.Map.actors.chara.ai.state; | ||||
| using Meteor.Map.actors.chara; | ||||
| using Meteor.Map.Actors.QuestNS; | ||||
| using Meteor.Map.packets.send; | ||||
| using Meteor.Map.packets.send.actor; | ||||
| using Meteor.Map.packets.send.events; | ||||
| @@ -277,7 +278,7 @@ namespace Meteor.Map.Actors | ||||
|             CalculateBaseStats(); | ||||
|  | ||||
|             questStateManager = new QuestStateManager(this); | ||||
|             questStateManager.Init(); | ||||
|             questStateManager.Init(questScenario); | ||||
|         } | ||||
|  | ||||
|         public List<SubPacket> Create0x132Packets() | ||||
| @@ -806,7 +807,7 @@ namespace Meteor.Map.Actors | ||||
|             foreach (Quest quest in questScenario) | ||||
|             { | ||||
|                 if (quest != null) | ||||
|                     quest.SaveData(); | ||||
|                     quest.GetData().Save(); | ||||
|             }     | ||||
|         } | ||||
|  | ||||
| @@ -1418,33 +1419,253 @@ namespace Meteor.Map.Actors | ||||
|             return -1; | ||||
|         } | ||||
|  | ||||
|         //For Lua calls, cause MoonSharp goes retard with uint | ||||
|         public void AddQuest(int id, bool isSilent = false) | ||||
|         #region Quests - Script Related | ||||
|         // Add quest from an active quest in the player's quest state. Quest scripts will use this to add a quest. | ||||
|         public bool AcceptQuest(Quest instance, bool isSilent = false) | ||||
|         { | ||||
|             AddQuest((uint)id, isSilent); | ||||
|         }        | ||||
|         public void CompleteQuest(int id) | ||||
|         { | ||||
|             CompleteQuest((uint)id); | ||||
|         } | ||||
|         public bool HasQuest(int id) | ||||
|         { | ||||
|             return HasQuest((uint)id); | ||||
|         } | ||||
|         public Quest GetQuest(int id) | ||||
|         { | ||||
|             return GetQuest((uint)id); | ||||
|         } | ||||
|         public bool IsQuestCompleted(int id) | ||||
|         { | ||||
|             return IsQuestCompleted((uint)id); | ||||
|         } | ||||
|         public bool CanAcceptQuest(int id) | ||||
|         { | ||||
|             return CanAcceptQuest((uint)id); | ||||
|         } | ||||
|         //For Lua calls, cause MoonSharp goes retard with uint | ||||
|             if (instance == null) | ||||
|                 return false; | ||||
|  | ||||
|             int freeSlot = GetFreeQuestSlot(); | ||||
|  | ||||
|             if (freeSlot == -1) | ||||
|             { | ||||
|                 SendGameMessage(Server.GetWorldManager().GetActor(), 25234, 0x20); // "You cannot accept any more quests at this time." | ||||
|                 return false; | ||||
|             } | ||||
|  | ||||
|             playerWork.questScenario[freeSlot] = instance.Id; | ||||
|             questScenario[freeSlot] = instance; | ||||
|             Database.SaveQuest(this, questScenario[freeSlot]); | ||||
|             SendQuestClientUpdate(freeSlot); | ||||
|  | ||||
|             if (!isSilent) | ||||
|             { | ||||
|                 SendGameMessage(Server.GetWorldManager().GetActor(), 25224, 0x20, (object)questScenario[freeSlot].GetQuestId()); // "<Quest> accepted." | ||||
|             } | ||||
|  | ||||
|             instance.OnAccept(); | ||||
|  | ||||
|             return true; | ||||
|         } | ||||
|  | ||||
|         // Replace a quest with another quest in the player's quest state. | ||||
|         public void ReplaceQuest(Quest oldQuestInstance, Quest newQuestInstance) | ||||
|         { | ||||
|             for (int i = 0; i < questScenario.Length; i++) | ||||
|             { | ||||
|                 if (questScenario[i] != null && questScenario[i].Equals(oldQuestInstance)) | ||||
|                 { | ||||
|                     questScenario[i] = newQuestInstance; | ||||
|                     playerWork.questScenario[i] = questScenario[i].Id; | ||||
|                     Database.SaveQuest(this, questScenario[i]); | ||||
|                     SendQuestClientUpdate(i); | ||||
|                     break; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         public void CompleteQuest(Quest completed) | ||||
|         { | ||||
|             int slot = GetQuestSlot(completed); | ||||
|             if (slot >= 0) | ||||
|             { | ||||
|                 // Remove the quest from the DB and update client work values | ||||
|                 playerWork.questScenarioComplete[completed.GetQuestId() - 110001] = true; | ||||
|                 Database.CompleteQuest(playerSession.GetActor(), completed.Id); | ||||
|                 Database.RemoveQuest(this, completed.Id); | ||||
|                 questScenario[slot] = null; | ||||
|                 playerWork.questScenario[slot] = 0; | ||||
|                 SendQuestClientUpdate(slot); | ||||
|  | ||||
|                 // Reset active quest and quest state | ||||
|                 completed.OnComplete(); | ||||
|                 questStateManager.UpdateQuestCompleted(completed); | ||||
|  | ||||
|                 // Msg Player | ||||
|                 SendGameMessage(Server.GetWorldManager().GetActor(), 25086, 0x20, (object)completed.GetQuestId()); // "<Quest> complete!" | ||||
|             } | ||||
|  | ||||
|         } | ||||
|  | ||||
|         public bool AbandonQuest(uint questId) | ||||
|         { | ||||
|             // Check if in an instance | ||||
|             if (CurrentArea.IsPrivate()) | ||||
|             { | ||||
|                 SendGameMessage(Server.GetWorldManager().GetActor(), 25235, 0x20); // "Quests cannot be abandoned while from within an instance." | ||||
|                 return false; | ||||
|             } | ||||
|  | ||||
|             // Get the quest object | ||||
|             int slot = GetQuestSlot(questId); | ||||
|             Quest abandoned = questScenario[slot]; | ||||
|  | ||||
|             if (abandoned == null) | ||||
|                 return false; | ||||
|  | ||||
|             // Check if Main Scenario | ||||
|             if (abandoned.IsMainScenario()) | ||||
|             { | ||||
|                 SendGameMessage(Server.GetWorldManager().GetActor(), 25233, 0x20); // "Main scenario quests cannot be abandoned." | ||||
|                 return false; | ||||
|             } | ||||
|  | ||||
|             // Remove the quest from the DB and update client work values | ||||
|             Database.RemoveQuest(this, abandoned.Id); | ||||
|             questScenario[slot] = null; | ||||
|             playerWork.questScenario[slot] = 0; | ||||
|             SendQuestClientUpdate(slot); | ||||
|  | ||||
|             // Reset active quest and quest state | ||||
|             abandoned.OnAbandon(); | ||||
|             questStateManager.UpdateQuestAbandoned(); | ||||
|  | ||||
|             // Msg Player | ||||
|             SendGameMessage(this, Server.GetWorldManager().GetActor(), 25236, 0x20, (object)abandoned.GetQuestId()); // "<Quest> abandoned." | ||||
|             return true; | ||||
|         } | ||||
|  | ||||
|         public bool HasQuest(Quest questInstance) | ||||
|         { | ||||
|             return GetQuestSlot(questInstance) != -1; | ||||
|         } | ||||
|         #endregion | ||||
|  | ||||
|         #region Quests - Debug/Misc Related | ||||
|         // Force-Add a quest by Id. Called be debug scripts. | ||||
|         public void AddQuest(uint id, bool isSilent = false) | ||||
|         { | ||||
|             Actor actor = Server.GetStaticActors((0xA0F00000 | id)); | ||||
|             AddQuest(actor.Name, isSilent); | ||||
|         } | ||||
|  | ||||
|         // Force-Add a quest by Name. Called be debug scripts. Will try to use an active quest, otherwise adds a new instance. | ||||
|         public void AddQuest(string name, bool isSilent = false) | ||||
|         { | ||||
|             Quest baseQuest = (Quest)Server.GetStaticActors(name); | ||||
|             Quest activeQuest = questStateManager.GetActiveQuest(baseQuest.GetQuestId()); | ||||
|  | ||||
|             int freeSlot = GetFreeQuestSlot(); | ||||
|  | ||||
|             if (freeSlot == -1) | ||||
|                 return; | ||||
|  | ||||
|             playerWork.questScenario[freeSlot] = baseQuest.Id; | ||||
|             questScenario[freeSlot] = activeQuest ?? new Quest(this, baseQuest); | ||||
|  | ||||
|             if (activeQuest == null) | ||||
|                 questStateManager.ForceAddActiveQuest(questScenario[freeSlot]); | ||||
|  | ||||
|             Database.SaveQuest(this, questScenario[freeSlot]); | ||||
|             SendQuestClientUpdate(freeSlot); | ||||
|  | ||||
|             if (!isSilent) | ||||
|             { | ||||
|                 SendGameMessage(Server.GetWorldManager().GetActor(), 25224, 0x20, (object)questScenario[freeSlot].GetQuestId()); | ||||
|             } | ||||
|  | ||||
|             questScenario[freeSlot].OnAccept(); | ||||
|         } | ||||
|  | ||||
|         public void RemoveQuest(uint id) | ||||
|         { | ||||
|             for (int i = 0; i < questScenario.Length; i++) | ||||
|             { | ||||
|                 if (questScenario[i] != null && questScenario[i].Id == (0xA0F00000 | id)) | ||||
|                 { | ||||
|                     Database.RemoveQuest(this, questScenario[i].Id); | ||||
|                     questScenario[i] = null; | ||||
|                     playerWork.questScenario[i] = 0; | ||||
|                     SendQuestClientUpdate(i); | ||||
|                     break; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         public void RemoveQuest(string name) | ||||
|         { | ||||
|             for (int i = 0; i < questScenario.Length; i++) | ||||
|             { | ||||
|                 if (questScenario[i] != null && questScenario[i].Name.ToLower().Equals(name.ToLower())) | ||||
|                 { | ||||
|                     Database.RemoveQuest(this, questScenario[i].Id); | ||||
|                     questScenario[i] = null; | ||||
|                     playerWork.questScenario[i] = 0; | ||||
|                     SendQuestClientUpdate(i); | ||||
|                     break; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         public bool HasQuest(string name) | ||||
|         { | ||||
|             for (int i = 0; i < questScenario.Length; i++) | ||||
|             { | ||||
|                 if (questScenario[i] != null && questScenario[i].Name.ToLower().Equals(name.ToLower())) | ||||
|                     return true; | ||||
|             } | ||||
|  | ||||
|             return false; | ||||
|         } | ||||
|  | ||||
|         public bool HasQuest(uint id) | ||||
|         { | ||||
|             for (int i = 0; i < questScenario.Length; i++) | ||||
|             { | ||||
|                 if (questScenario[i] != null && questScenario[i].Id == (0xA0F00000 | id)) | ||||
|                     return true; | ||||
|             } | ||||
|  | ||||
|             return false; | ||||
|         } | ||||
|  | ||||
|         public Quest GetQuest(uint id) | ||||
|         { | ||||
|             for (int i = 0; i < questScenario.Length; i++) | ||||
|             { | ||||
|                 if (questScenario[i] != null && questScenario[i].Id == (0xA0F00000 | id)) | ||||
|                     return questScenario[i]; | ||||
|             } | ||||
|  | ||||
|             return null; | ||||
|         } | ||||
|  | ||||
|         public Quest GetQuest(string name) | ||||
|         { | ||||
|             for (int i = 0; i < questScenario.Length; i++) | ||||
|             { | ||||
|                 if (questScenario[i] != null && questScenario[i].Name.ToLower().Equals(name.ToLower())) | ||||
|                     return questScenario[i]; | ||||
|             } | ||||
|  | ||||
|             return null; | ||||
|         } | ||||
|  | ||||
|         public int GetQuestSlot(Quest quest) | ||||
|         { | ||||
|             for (int slot = 0; slot < questScenario.Length; slot++) | ||||
|             { | ||||
|                 if (questScenario[slot] != null && questScenario[slot].Id == quest.Id) | ||||
|                     return slot; | ||||
|             } | ||||
|  | ||||
|             return -1; | ||||
|         } | ||||
|  | ||||
|         public int GetQuestSlot(uint id) | ||||
|         { | ||||
|             for (int slot = 0; slot < questScenario.Length; slot++) | ||||
|             { | ||||
|                 if (questScenario[slot] != null && questScenario[slot].GetQuestId() == id) | ||||
|                     return slot; | ||||
|             } | ||||
|  | ||||
|             return -1; | ||||
|         } | ||||
|         #endregion | ||||
|  | ||||
|         #region Guildleves | ||||
|         public void AddGuildleve(uint id) | ||||
|         { | ||||
|             int freeSlot = GetFreeGuildleveSlot(); | ||||
| @@ -1489,179 +1710,7 @@ namespace Meteor.Map.Actors | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         public void AddQuest(uint id, bool isSilent = false) | ||||
|         { | ||||
|             Actor actor = Server.GetStaticActors((0xA0F00000 | id)); | ||||
|             AddQuest(actor.Name, isSilent); | ||||
|         } | ||||
|  | ||||
|         public void AddQuest(string name, bool isSilent = false) | ||||
|         { | ||||
|             Quest baseQuest = (Quest) Server.GetStaticActors(name); | ||||
|  | ||||
|             if (baseQuest == null) | ||||
|                 return; | ||||
|  | ||||
|             int freeSlot = GetFreeQuestSlot(); | ||||
|  | ||||
|             if (freeSlot == -1) | ||||
|                 return; | ||||
|  | ||||
|             playerWork.questScenario[freeSlot] = baseQuest.Id; | ||||
|             questScenario[freeSlot] = new Quest(this, baseQuest); | ||||
|             Database.SaveQuest(this, questScenario[freeSlot]); | ||||
|             SendQuestClientUpdate(freeSlot); | ||||
|  | ||||
|             if (!isSilent) | ||||
|             { | ||||
|                 SendGameMessage(Server.GetWorldManager().GetActor(), 25224, 0x20, (object)questScenario[freeSlot].GetQuestId()); | ||||
|             } | ||||
|         }         | ||||
|  | ||||
|         public void CompleteQuest(uint id) | ||||
|         { | ||||
|             Actor actor = Server.GetStaticActors((0xA0F00000 | id)); | ||||
|             CompleteQuest(actor.Name); | ||||
|         } | ||||
|  | ||||
|         public void CompleteQuest(string name) | ||||
|         { | ||||
|             Actor actor = Server.GetStaticActors(name); | ||||
|  | ||||
|             if (actor == null) | ||||
|                 return; | ||||
|  | ||||
|             uint id = actor.Id; | ||||
|             if (HasQuest(id)) | ||||
|             { | ||||
|                 Database.CompleteQuest(playerSession.GetActor(), id); | ||||
|                 SendGameMessage(Server.GetWorldManager().GetActor(), 25086, 0x20, (object)GetQuest(id).GetQuestId()); | ||||
|                 RemoveQuest(id); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         //TODO: Add checks for you being in an instance or main scenario | ||||
|         public void AbandonQuest(uint id) | ||||
|         { | ||||
|             Quest quest = GetQuest(id); | ||||
|             RemoveQuestByQuestId(id); | ||||
|             quest.DoAbandon();        | ||||
|         } | ||||
|  | ||||
|         public void RemoveQuestByQuestId(uint id) | ||||
|         { | ||||
|             RemoveQuest((0xA0F00000 | id)); | ||||
|         } | ||||
|  | ||||
|         public void RemoveQuest(uint id) | ||||
|         { | ||||
|             if (HasQuest(id)) | ||||
|             { | ||||
|                 for (int i = 0; i < questScenario.Length; i++) | ||||
|                 { | ||||
|                     if (questScenario[i] != null && questScenario[i].Id == id) | ||||
|                     { | ||||
|                         Database.RemoveQuest(this, questScenario[i].Id); | ||||
|                         questScenario[i] = null; | ||||
|                         playerWork.questScenario[i] = 0; | ||||
|                         SendQuestClientUpdate(i); | ||||
|                         break; | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         public void ReplaceQuest(Quest oldQuest, string questCode) | ||||
|         { | ||||
|             for (int i = 0; i < questScenario.Length; i++) | ||||
|             { | ||||
|                 if (questScenario[i] != null && questScenario[i].Equals(oldQuest)) | ||||
|                 { | ||||
|                     Quest baseQuest = (Quest) Server.GetStaticActors(questCode); | ||||
|                     questScenario[i] = new Quest(this, baseQuest); | ||||
|                     playerWork.questScenario[i] = questScenario[i].Id; | ||||
|                     Database.SaveQuest(this, questScenario[i]); | ||||
|                     SendQuestClientUpdate(i); | ||||
|                     break; | ||||
|                 } | ||||
|             }             | ||||
|         } | ||||
|  | ||||
|         public bool CanAcceptQuest(string name) | ||||
|         { | ||||
|             if (!IsQuestCompleted(name) && !HasQuest(name)) | ||||
|                 return true; | ||||
|             else | ||||
|                 return false; | ||||
|         } | ||||
|  | ||||
|         public bool CanAcceptQuest(uint id) | ||||
|         { | ||||
|             Actor actor = Server.GetStaticActors((0xA0F00000 | id)); | ||||
|             return CanAcceptQuest(actor.Name); | ||||
|         } | ||||
|  | ||||
|         public bool IsQuestCompleted(string questName) | ||||
|         { | ||||
|             Actor actor = Server.GetStaticActors(questName); | ||||
|             return IsQuestCompleted(actor.Id); | ||||
|         } | ||||
|  | ||||
|         public bool IsQuestCompleted(uint questId) | ||||
|         { | ||||
|             return Database.IsQuestCompleted(this, 0xFFFFF & questId); | ||||
|         } | ||||
|  | ||||
|         public Quest GetQuest(uint id) | ||||
|         { | ||||
|             for (int i = 0; i < questScenario.Length; i++) | ||||
|             { | ||||
|                 if (questScenario[i] != null && questScenario[i].Id == (0xA0F00000 | id)) | ||||
|                     return questScenario[i]; | ||||
|             } | ||||
|  | ||||
|             return null; | ||||
|         } | ||||
|  | ||||
|         public Quest GetQuest(string name) | ||||
|         { | ||||
|             for (int i = 0; i < questScenario.Length; i++) | ||||
|             { | ||||
|                 if (questScenario[i] != null && questScenario[i].Name.ToLower().Equals(name.ToLower())) | ||||
|                     return questScenario[i]; | ||||
|             } | ||||
|  | ||||
|             return null; | ||||
|         } | ||||
|  | ||||
|         public bool HasQuest(string name) | ||||
|         { | ||||
|             for (int i = 0; i < questScenario.Length; i++) | ||||
|             { | ||||
|                 if (questScenario[i] != null && questScenario[i].Name.ToLower().Equals(name.ToLower())) | ||||
|                     return true; | ||||
|             } | ||||
|  | ||||
|             return false; | ||||
|         } | ||||
|  | ||||
|         public bool HasQuest(uint id) | ||||
|         { | ||||
|             for (int i = 0; i < questScenario.Length; i++) | ||||
|             { | ||||
|                 if (questScenario[i] != null && questScenario[i].Id == (0xA0F00000 | id)) | ||||
|                     return true; | ||||
|             } | ||||
|  | ||||
|             return false; | ||||
|         } | ||||
|  | ||||
|         public bool HasQuest(Quest quest) | ||||
|         { | ||||
|             return HasQuest(quest.className); | ||||
|         } | ||||
|         }       | ||||
|  | ||||
|         public bool HasGuildleve(uint id) | ||||
|         { | ||||
| @@ -1673,17 +1722,7 @@ namespace Meteor.Map.Actors | ||||
|  | ||||
|             return false; | ||||
|         } | ||||
|  | ||||
|         public int GetQuestSlot(uint id) | ||||
|         { | ||||
|             for (int i = 0; i < questScenario.Length; i++) | ||||
|             { | ||||
|                 if (questScenario[i] != null && questScenario[i].Id == (0xA0F00000 | id)) | ||||
|                     return i; | ||||
|             } | ||||
|  | ||||
|             return -1; | ||||
|         } | ||||
|         #endregion | ||||
|  | ||||
|         public Quest GetDefaultTalkQuest(Npc npc) | ||||
|         { | ||||
| @@ -1735,14 +1774,11 @@ namespace Meteor.Map.Actors | ||||
|             return null; | ||||
|         } | ||||
|  | ||||
|         public Quest[] GetJournalQuestsForNpc(Npc npc) | ||||
|         { | ||||
|             return Array.FindAll(questScenario, e => e != null && e.IsQuestENPC(this, npc)); | ||||
|         } | ||||
|  | ||||
|         public Quest[] GetQuestsForNpc(Npc npc) | ||||
|         { | ||||
|             return questStateManager.GetQuestsForNpc(npc); | ||||
|             Quest[] quests = questStateManager.GetQuestsForNpc(npc); | ||||
|             Array.Sort(quests, (q1, q2) => (q1.HasData() ? 1 : 0) - (q2.HasData() ? 1 : 0)); | ||||
|             return quests; | ||||
|         } | ||||
|  | ||||
|         public void HandleNpcLS(uint id) | ||||
| @@ -2765,6 +2801,7 @@ namespace Meteor.Map.Actors | ||||
|                     actionList.Add(new CommandResult(Id, 33909, 0, (ushort)charaWork.battleSave.skillLevel[classId - 1])); | ||||
|  | ||||
|                 EquipAbilitiesAtLevel(classId, GetLevel(), actionList); | ||||
|                 questStateManager.UpdateLevel(GetHighestLevel()); | ||||
|             } | ||||
|         } | ||||
|          | ||||
|   | ||||
		Reference in New Issue
	
	Block a user