mirror of
https://bitbucket.org/Ioncannon/project-meteor-server.git
synced 2025-06-12 07:24:37 +02:00
Refactored quest state system seems to work!
This commit is contained in:
parent
1523ae200b
commit
02cb0a3f43
14 changed files with 673 additions and 512 deletions
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue