/*
===========================================================================
Copyright (C) 2015-2019 Project Meteor Dev Team
This file is part of Project Meteor Server.
Project Meteor Server is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Project Meteor Server is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with Project Meteor Server. If not, see .
===========================================================================
*/
using Meteor.Map.lua;
using System;
using System.Collections.Generic;
namespace Meteor.Map.Actors.QuestNS
{
class Quest : Actor
{
public const ushort SEQ_NOT_STARTED = 65535;
public const ushort SEQ_COMPLETED = 65534;
private Player owner;
private ushort currentSequence;
private QuestState questState = null;
private QuestData data = null;
// 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);
}
public void UpdateENPCs()
{
if (data.Dirty)
{
if (questState != null)
questState.UpdateState();
data.ClearDirty();
}
}
public QuestState GetQuestState()
{
return questState;
}
#endregion
#region Script Callbacks
public void OnTalk(Player caller, Npc npc)
{
LuaEngine.GetInstance().CallLuaFunction(caller, this, "onTalk", true, npc);
}
public void OnEmote(Player caller, Npc npc, Command command)
{
LuaEngine.GetInstance().CallLuaFunction(caller, this, "onEmote", true, npc, command);
}
public void OnPush(Player caller, Npc npc)
{
LuaEngine.GetInstance().CallLuaFunction(caller, this, "onPush", true, npc);
}
public void OnNotice(Player caller)
{
LuaEngine.GetInstance().CallLuaFunction(caller, this, "onNotice", true);
}
public void OnNpcLS(Player caller, uint npcLSId)
{
LuaEngine.GetInstance().CallLuaFunction(caller, this, "onNpcLS", true, npcLSId);
}
public object[] GetJournalInformation()
{
List returned = LuaEngine.GetInstance().CallLuaFunctionForReturn(owner, this, "getJournalInformation", true);
if (returned != null && returned.Count != 0)
return LuaUtils.CreateLuaParamObjectList(returned);
else
return new object[0];
}
public object[] GetJournalMapMarkerList()
{
List 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 bool IsQuestENPC(Player caller, Npc npc)
{
List 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());
currentSequence = sequence;
questState.UpdateState();
}
public void OnAccept()
{
data = new QuestData(owner, this);
if (currentSequence == SEQ_NOT_STARTED)
LuaEngine.GetInstance().CallLuaFunction(owner, this, "onStart", false);
else
StartSequence(currentSequence);
}
public void OnComplete()
{
LuaEngine.GetInstance().CallLuaFunctionForReturn(owner, this, "onFinish", true);
currentSequence = SEQ_COMPLETED;
data = null;
questState.UpdateState();
}
public void OnAbandon()
{
LuaEngine.GetInstance().CallLuaFunctionForReturn(owner, this, "onFinish", false);
currentSequence = SEQ_NOT_STARTED;
data = null;
questState.UpdateState();
}
}
}