mirror of
https://bitbucket.org/Ioncannon/project-meteor-server.git
synced 2025-07-20 09:35:56 +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
|
@ -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();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue