mirror of
https://bitbucket.org/Ioncannon/project-meteor-server.git
synced 2025-06-10 06:24:38 +02:00
Started mass overhaul of quests and related components like small talk. Fixed some scripts. More fixes required.
This commit is contained in:
parent
df49eefadb
commit
2279ee7017
33 changed files with 1241 additions and 279 deletions
|
@ -256,7 +256,7 @@ namespace Meteor.Map.Actors
|
|||
return subpackets;
|
||||
}
|
||||
|
||||
public List<SubPacket> GetSetEventStatusPackets()
|
||||
public List<SubPacket> GetSetEventStatusPackets(bool talkEnabled = true, bool emoteEnabled = true, bool pushEnabled = true, bool noticeEnabled = true)
|
||||
{
|
||||
List<SubPacket> subpackets = new List<SubPacket>();
|
||||
|
||||
|
@ -267,37 +267,37 @@ namespace Meteor.Map.Actors
|
|||
if (eventConditions.talkEventConditions != null)
|
||||
{
|
||||
foreach (EventList.TalkEventCondition condition in eventConditions.talkEventConditions)
|
||||
subpackets.Add(SetEventStatusPacket.BuildPacket(actorId, true, 1, condition.conditionName));
|
||||
subpackets.Add(SetEventStatusPacket.BuildPacket(actorId, talkEnabled, 1, condition.conditionName));
|
||||
}
|
||||
|
||||
if (eventConditions.noticeEventConditions != null)
|
||||
{
|
||||
foreach (EventList.NoticeEventCondition condition in eventConditions.noticeEventConditions)
|
||||
subpackets.Add(SetEventStatusPacket.BuildPacket(actorId, true, 5, condition.conditionName));
|
||||
subpackets.Add(SetEventStatusPacket.BuildPacket(actorId, noticeEnabled, 5, condition.conditionName));
|
||||
}
|
||||
|
||||
if (eventConditions.emoteEventConditions != null)
|
||||
{
|
||||
foreach (EventList.EmoteEventCondition condition in eventConditions.emoteEventConditions)
|
||||
subpackets.Add(SetEventStatusPacket.BuildPacket(actorId, true, 3, condition.conditionName));
|
||||
subpackets.Add(SetEventStatusPacket.BuildPacket(actorId, emoteEnabled, 3, condition.conditionName));
|
||||
}
|
||||
|
||||
if (eventConditions.pushWithCircleEventConditions != null)
|
||||
{
|
||||
foreach (EventList.PushCircleEventCondition condition in eventConditions.pushWithCircleEventConditions)
|
||||
subpackets.Add(SetEventStatusPacket.BuildPacket(actorId, true, 2, condition.conditionName));
|
||||
subpackets.Add(SetEventStatusPacket.BuildPacket(actorId, pushEnabled, 2, condition.conditionName));
|
||||
}
|
||||
|
||||
if (eventConditions.pushWithFanEventConditions != null)
|
||||
{
|
||||
foreach (EventList.PushFanEventCondition condition in eventConditions.pushWithFanEventConditions)
|
||||
subpackets.Add(SetEventStatusPacket.BuildPacket(actorId, true, 2, condition.conditionName));
|
||||
subpackets.Add(SetEventStatusPacket.BuildPacket(actorId, pushEnabled, 2, condition.conditionName));
|
||||
}
|
||||
|
||||
if (eventConditions.pushWithBoxEventConditions != null)
|
||||
{
|
||||
foreach (EventList.PushBoxEventCondition condition in eventConditions.pushWithBoxEventConditions)
|
||||
subpackets.Add(SetEventStatusPacket.BuildPacket(actorId, true, 2, condition.conditionName));
|
||||
subpackets.Add(SetEventStatusPacket.BuildPacket(actorId, pushEnabled, 2, condition.conditionName));
|
||||
}
|
||||
|
||||
return subpackets;
|
||||
|
|
|
@ -31,6 +31,7 @@ using Newtonsoft.Json;
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Meteor.Map.actors.chara.ai;
|
||||
using Meteor.Map.packets.send.actor.events;
|
||||
|
||||
namespace Meteor.Map.Actors
|
||||
{
|
||||
|
@ -420,7 +421,7 @@ namespace Meteor.Map.Actors
|
|||
|
||||
public void DoOnActorSpawn(Player player)
|
||||
{
|
||||
LuaEngine.GetInstance().CallLuaFunction(player, this, "onSpawn", true);
|
||||
LuaEngine.GetInstance().CallLuaFunction(player, this, "onSpawn", true);
|
||||
}
|
||||
|
||||
public void PlayMapObjAnimation(Player player, string animationName)
|
||||
|
|
|
@ -1456,27 +1456,24 @@ namespace Meteor.Map.Actors
|
|||
|
||||
public void AddQuest(string name, bool isSilent = false)
|
||||
{
|
||||
Actor actor = Server.GetStaticActors(name);
|
||||
Quest baseQuest = (Quest) Server.GetStaticActors(name);
|
||||
|
||||
if (actor == null)
|
||||
if (baseQuest == null)
|
||||
return;
|
||||
|
||||
uint id = actor.actorId;
|
||||
|
||||
int freeSlot = GetFreeQuestSlot();
|
||||
|
||||
if (freeSlot == -1)
|
||||
return;
|
||||
|
||||
playerWork.questScenario[freeSlot] = id;
|
||||
questScenario[freeSlot] = new Quest(this, playerWork.questScenario[freeSlot], name, null, 0, 0);
|
||||
playerWork.questScenario[freeSlot] = baseQuest.actorId;
|
||||
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());
|
||||
questScenario[freeSlot].NextPhase(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1541,9 +1538,9 @@ namespace Meteor.Map.Actors
|
|||
{
|
||||
if (questScenario[i] != null && questScenario[i].GetQuestId() == oldId)
|
||||
{
|
||||
Actor actor = Server.GetStaticActors((0xA0F00000 | newId));
|
||||
Quest baseQuest = (Quest) Server.GetStaticActors((0xA0F00000 | newId));
|
||||
playerWork.questScenario[i] = (0xA0F00000 | newId);
|
||||
questScenario[i] = new Quest(this, playerWork.questScenario[i], actor.actorName, null, 0, 0);
|
||||
questScenario[i] = new Quest(this, baseQuest);
|
||||
Database.SaveQuest(this, questScenario[i]);
|
||||
SendQuestClientUpdate(i);
|
||||
break;
|
||||
|
@ -1643,6 +1640,65 @@ namespace Meteor.Map.Actors
|
|||
return -1;
|
||||
}
|
||||
|
||||
public Quest GetDefaultTalkQuest(Npc npc)
|
||||
{
|
||||
Quest defaultTalk = null;
|
||||
|
||||
switch (npc.zone.regionId)
|
||||
{
|
||||
case 101:
|
||||
defaultTalk = (Quest) Server.GetStaticActors("DftSea");
|
||||
break;
|
||||
case 102:
|
||||
defaultTalk = (Quest) Server.GetStaticActors("DftRoc");
|
||||
break;
|
||||
case 103:
|
||||
defaultTalk = (Quest) Server.GetStaticActors("DftFst");
|
||||
break;
|
||||
case 104:
|
||||
defaultTalk = (Quest) Server.GetStaticActors("DftWil");
|
||||
break;
|
||||
case 105:
|
||||
defaultTalk = (Quest) Server.GetStaticActors("DftLak");
|
||||
break;
|
||||
case 805:
|
||||
defaultTalk = (Quest) Server.GetStaticActors("DftSrt");
|
||||
break;
|
||||
}
|
||||
|
||||
if (defaultTalk != null && defaultTalk.IsQuestENPC(this, npc))
|
||||
return defaultTalk;
|
||||
return null;
|
||||
}
|
||||
|
||||
public Quest GetTutorialQuest(Npc npc)
|
||||
{
|
||||
switch (npc.GetActorClassId())
|
||||
{
|
||||
case 1000137:
|
||||
return (Quest)Server.GetStaticActors("Trl0l1");
|
||||
case 1000230:
|
||||
return (Quest)Server.GetStaticActors("Trl0g1");
|
||||
case 1000841:
|
||||
return (Quest)Server.GetStaticActors("Trl0u1");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public Quest[] GetQuestsForNpc(Npc npc)
|
||||
{
|
||||
return Array.FindAll(questScenario, e => e != null && e.IsQuestENPC(this, npc));
|
||||
}
|
||||
|
||||
public void HandleNpcLS(uint id)
|
||||
{
|
||||
foreach (Quest quest in questScenario)
|
||||
{
|
||||
if (quest != null)
|
||||
quest.OnNpcLS(this, id);
|
||||
}
|
||||
}
|
||||
|
||||
public void SetNpcLS(uint npcLSId, uint state)
|
||||
{
|
||||
bool isCalling, isExtra;
|
||||
|
@ -1847,7 +1903,7 @@ namespace Meteor.Map.Actors
|
|||
|
||||
public void SetEventStatus(Actor actor, string conditionName, bool enabled, byte type)
|
||||
{
|
||||
SetEventStatusPacket.BuildPacket(actor.actorId, enabled, type, conditionName);
|
||||
QueuePacket(SetEventStatusPacket.BuildPacket(actor.actorId, enabled, type, conditionName));
|
||||
}
|
||||
|
||||
public void RunEventFunction(string functionName, params object[] parameters)
|
||||
|
|
|
@ -283,17 +283,19 @@ namespace Meteor.Map.actors.director
|
|||
|
||||
private void LoadLuaScript()
|
||||
{
|
||||
string errorMsg = "";
|
||||
string luaPath = String.Format(LuaEngine.FILEPATH_DIRECTORS, GetScriptPath());
|
||||
directorScript = LuaEngine.LoadScript(luaPath);
|
||||
directorScript = LuaEngine.LoadScript(luaPath, ref errorMsg);
|
||||
if (directorScript == null)
|
||||
Program.Log.Error("Could not find script for director {0}.", GetName());
|
||||
Program.Log.Error("Could not find script for director {0}.", GetName());
|
||||
}
|
||||
|
||||
private List<LuaParam> CallLuaScript(string funcName, params object[] args)
|
||||
{
|
||||
if (directorScript != null)
|
||||
{
|
||||
directorScript = LuaEngine.LoadScript(String.Format(LuaEngine.FILEPATH_DIRECTORS, directorScriptPath));
|
||||
string errorMsg = "";
|
||||
directorScript = LuaEngine.LoadScript(String.Format(LuaEngine.FILEPATH_DIRECTORS, directorScriptPath), ref errorMsg);
|
||||
if (!directorScript.Globals.Get(funcName).IsNil())
|
||||
{
|
||||
DynValue result = directorScript.Call(directorScript.Globals[funcName], args);
|
||||
|
|
|
@ -28,10 +28,257 @@ namespace Meteor.Map.Actors
|
|||
{
|
||||
class Quest : Actor
|
||||
{
|
||||
private Player owner;
|
||||
private uint currentPhase = 0;
|
||||
private uint questFlags = 0;
|
||||
private Dictionary<string, Object> questData = new Dictionary<string, object>();
|
||||
public const ushort SEQ_NOT_STARTED = ushort.MaxValue;
|
||||
|
||||
public class ENpcQuestInstance
|
||||
{
|
||||
public readonly uint actorClassId;
|
||||
public byte questFlagType { set; get; }
|
||||
public bool isSpawned { set; get; }
|
||||
public bool isTalkEnabled { set; get; }
|
||||
public bool isEmoteEnabled { set; get; }
|
||||
public bool isPushEnabled { set; get; }
|
||||
|
||||
public ENpcQuestInstance(uint actorClassId, byte questFlagType, bool isSpawned, bool isTalkEnabled, bool isEmoteEnabled, bool isPushEnabled)
|
||||
{
|
||||
this.actorClassId = actorClassId;
|
||||
this.questFlagType = questFlagType;
|
||||
this.isSpawned = isSpawned;
|
||||
this.isTalkEnabled = isTalkEnabled;
|
||||
this.isEmoteEnabled = isEmoteEnabled;
|
||||
this.isPushEnabled = isPushEnabled;
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
private Player Owner;
|
||||
private ushort currentSequence;
|
||||
private QuestData data = new QuestData();
|
||||
private Dictionary<uint, ENpcQuestInstance> ActiveENpcs = new Dictionary<uint, ENpcQuestInstance>();
|
||||
|
||||
public void AddENpc(uint classId, byte flagType = 0, bool isTalkEnabled = false, bool isEmoteEnabled = false, bool isPushEnabled = false, bool isSpawned = false)
|
||||
{
|
||||
if (ActiveENpcs.ContainsKey(classId))
|
||||
return;
|
||||
|
||||
ENpcQuestInstance instance = new ENpcQuestInstance(classId, flagType, isSpawned, isTalkEnabled, isEmoteEnabled, isPushEnabled);
|
||||
ActiveENpcs.Add(classId, instance);
|
||||
Owner.playerSession.UpdateQuestNpcInInstance(instance);
|
||||
}
|
||||
|
||||
public void ClearENpcs()
|
||||
{
|
||||
foreach (ENpcQuestInstance instance in ActiveENpcs.Values)
|
||||
Owner.playerSession.UpdateQuestNpcInInstance(instance, true);
|
||||
|
||||
ActiveENpcs.Clear();
|
||||
}
|
||||
|
||||
public void UpdateENpc(uint classId, int param, object value)
|
||||
{
|
||||
if (!ActiveENpcs.ContainsKey(classId))
|
||||
return;
|
||||
}
|
||||
|
||||
public ENpcQuestInstance GetENpcInstance(uint classId)
|
||||
{
|
||||
if (ActiveENpcs.ContainsKey(classId))
|
||||
return ActiveENpcs[classId];
|
||||
return null;
|
||||
}
|
||||
|
||||
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, Npc npc)
|
||||
{
|
||||
LuaEngine.GetInstance().CallLuaFunction(caller, this, "onNotice", true, npc);
|
||||
}
|
||||
|
||||
public void OnNpcLS(Player caller, uint npcLSId)
|
||||
{
|
||||
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 || ActiveENpcs.ContainsKey(npc.GetActorClassId());
|
||||
}
|
||||
|
||||
|
||||
public object[] GetJournalInformation()
|
||||
{
|
||||
List<LuaParam> 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<LuaParam> returned = LuaEngine.GetInstance().CallLuaFunctionForReturn(Owner, this, "getJournalMapMarkerList", true);
|
||||
if (returned != null && returned.Count != 0)
|
||||
return LuaUtils.CreateLuaParamObjectList(returned);
|
||||
else
|
||||
return new object[0];
|
||||
}
|
||||
|
||||
public ushort GetSequence()
|
||||
{
|
||||
return currentSequence;
|
||||
}
|
||||
|
||||
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;
|
||||
LuaEngine.GetInstance().CallLuaFunction(Owner, this, "onSequence", false, currentSequence);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
public void ClearFlag(int index)
|
||||
{
|
||||
if (index >= 0 && index < 32)
|
||||
data.flags &= (uint)~(1 << index);
|
||||
}
|
||||
|
||||
public void IncCounter(int num)
|
||||
{
|
||||
switch (num)
|
||||
{
|
||||
case 0:
|
||||
data.counter1++;
|
||||
break;
|
||||
case 1:
|
||||
data.counter2++;
|
||||
break;
|
||||
case 2:
|
||||
data.counter3++;
|
||||
break;
|
||||
case 3:
|
||||
data.counter4++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void DecCounter(int num)
|
||||
{
|
||||
switch (num)
|
||||
{
|
||||
case 0:
|
||||
data.counter1--;
|
||||
break;
|
||||
case 1:
|
||||
data.counter2--;
|
||||
break;
|
||||
case 2:
|
||||
data.counter3--;
|
||||
break;
|
||||
case 3:
|
||||
data.counter4--;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void SetCounter(int num, ushort value)
|
||||
{
|
||||
switch (num)
|
||||
{
|
||||
case 0:
|
||||
data.counter1 = value;
|
||||
break;
|
||||
case 1:
|
||||
data.counter2 = value;
|
||||
break;
|
||||
case 2:
|
||||
data.counter3 = value;
|
||||
break;
|
||||
case 3:
|
||||
data.counter4 = value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
|
@ -39,127 +286,41 @@ namespace Meteor.Map.Actors
|
|||
actorName = name;
|
||||
}
|
||||
|
||||
public Quest(Player owner, uint actorID, string name, string questDataJson, uint questFlags, uint currentPhase)
|
||||
: base(actorID)
|
||||
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.actorId)
|
||||
{
|
||||
this.owner = owner;
|
||||
actorName = name;
|
||||
this.questFlags = questFlags;
|
||||
Owner = owner;
|
||||
actorName = baseQuest.actorName;
|
||||
className = baseQuest.className;
|
||||
classPath = baseQuest.classPath;
|
||||
currentSequence = sequence;
|
||||
data = new QuestData(flags, counter1, counter2, counter3);
|
||||
|
||||
if (questDataJson != null)
|
||||
this.questData = JsonConvert.DeserializeObject<Dictionary<string, Object>>(questDataJson);
|
||||
if (currentSequence == SEQ_NOT_STARTED)
|
||||
LuaEngine.GetInstance().CallLuaFunction(Owner, this, "onStart", false);
|
||||
else
|
||||
questData = null;
|
||||
|
||||
if (questData == null)
|
||||
questData = new Dictionary<string, object>();
|
||||
|
||||
this.currentPhase = currentPhase;
|
||||
StartSequence(currentSequence);
|
||||
}
|
||||
|
||||
public void SetQuestData(string dataName, object data)
|
||||
{
|
||||
questData[dataName] = data;
|
||||
|
||||
//Inform update
|
||||
}
|
||||
|
||||
public uint GetQuestId()
|
||||
{
|
||||
return actorId & 0xFFFFF;
|
||||
}
|
||||
|
||||
public object GetQuestData(string dataName)
|
||||
public void DoComplete()
|
||||
{
|
||||
if (questData.ContainsKey(dataName))
|
||||
return questData[dataName];
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
public void ClearQuestData()
|
||||
{
|
||||
questData.Clear();
|
||||
}
|
||||
|
||||
public void ClearQuestFlags()
|
||||
{
|
||||
questFlags = 0;
|
||||
}
|
||||
|
||||
public void SetQuestFlag(int bitIndex, bool value)
|
||||
{
|
||||
if (bitIndex >= 32)
|
||||
{
|
||||
Program.Log.Error("Tried to access bit flag >= 32 for questId: {0}", actorId);
|
||||
return;
|
||||
}
|
||||
|
||||
int mask = 1 << bitIndex;
|
||||
|
||||
if (value)
|
||||
questFlags |= (uint)(1 << bitIndex);
|
||||
else
|
||||
questFlags &= (uint)~(1 << bitIndex);
|
||||
|
||||
DoCompletionCheck();
|
||||
}
|
||||
|
||||
public bool GetQuestFlag(int bitIndex)
|
||||
{
|
||||
if (bitIndex >= 32)
|
||||
{
|
||||
Program.Log.Error("Tried to access bit flag >= 32 for questId: {0}", actorId);
|
||||
return false;
|
||||
}
|
||||
else
|
||||
return (questFlags & (1 << bitIndex)) == (1 << bitIndex);
|
||||
}
|
||||
|
||||
public uint GetPhase()
|
||||
{
|
||||
return currentPhase;
|
||||
}
|
||||
|
||||
public void NextPhase(uint phaseNumber)
|
||||
{
|
||||
currentPhase = phaseNumber;
|
||||
owner.SendGameMessage(Server.GetWorldManager().GetActor(), 25116, 0x20, (object)GetQuestId());
|
||||
SaveData();
|
||||
|
||||
DoCompletionCheck();
|
||||
}
|
||||
|
||||
public uint GetQuestFlags()
|
||||
{
|
||||
return questFlags;
|
||||
}
|
||||
|
||||
public string GetSerializedQuestData()
|
||||
{
|
||||
return JsonConvert.SerializeObject(questData, Formatting.Indented);
|
||||
}
|
||||
|
||||
public void SaveData()
|
||||
{
|
||||
Database.SaveQuest(owner, this);
|
||||
}
|
||||
|
||||
public void DoCompletionCheck()
|
||||
{
|
||||
List<LuaParam> returned = LuaEngine.GetInstance().CallLuaFunctionForReturn(owner, this, "isObjectivesComplete", true);
|
||||
if (returned != null && returned.Count >= 1 && returned[0].typeID == 3)
|
||||
{
|
||||
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);
|
||||
Owner.SendDataPacket("attention", Server.GetWorldManager().GetActor(), "", 25225, (object)GetQuestId());
|
||||
Owner.SendGameMessage(Server.GetWorldManager().GetActor(), 25225, 0x20, (object)GetQuestId());
|
||||
}
|
||||
|
||||
public void DoAbandon()
|
||||
{
|
||||
LuaEngine.GetInstance().CallLuaFunctionForReturn(owner, this, "onAbandonQuest", true);
|
||||
owner.SendGameMessage(owner, Server.GetWorldManager().GetActor(), 25236, 0x20, (object)GetQuestId());
|
||||
LuaEngine.GetInstance().CallLuaFunctionForReturn(Owner, this, "onFinish", false);
|
||||
Owner.SendGameMessage(Owner, Server.GetWorldManager().GetActor(), 25236, 0x20, (object)GetQuestId());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -94,15 +94,22 @@ namespace Meteor.Map.Actors
|
|||
string actorType = output.Split('/')[1];
|
||||
string actorName = output.Substring(1 + output.LastIndexOf("/"));
|
||||
|
||||
Actor actor = null;
|
||||
if (actorType.Equals("Command"))
|
||||
mStaticActors.Add(id, new Command(id, actorName));
|
||||
actor = new Command(id, actorName);
|
||||
else if (actorType.Equals("Quest"))
|
||||
mStaticActors.Add(id, new Quest(id, actorName));
|
||||
actor = new Quest(id, actorName);
|
||||
//else if (actorType.Equals("Status"))
|
||||
//mStaticActors.Add(id, new Status(id, actorName));
|
||||
else if (actorType.Equals("Judge"))
|
||||
mStaticActors.Add(id, new Judge(id, actorName));
|
||||
actor = new Judge(id, actorName);
|
||||
|
||||
if (actor != null)
|
||||
{
|
||||
actor.className = actorName;
|
||||
actor.classPath = output;
|
||||
mStaticActors.Add(id, actor);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -25,6 +25,7 @@ using Meteor.Map.Actors;
|
|||
using Meteor.Map.packets.send.actor;
|
||||
using System.Collections.Generic;
|
||||
using Meteor.Map.actors.chara.npc;
|
||||
using static Meteor.Map.Actors.Quest;
|
||||
|
||||
namespace Meteor.Map.dataobjects
|
||||
{
|
||||
|
@ -110,10 +111,6 @@ namespace Meteor.Map.dataobjects
|
|||
if (isUpdatesLocked && !force)
|
||||
return;
|
||||
|
||||
List<BasePacket> basePackets = new List<BasePacket>();
|
||||
List<SubPacket> RemoveActorSubpackets = new List<SubPacket>();
|
||||
List<SubPacket> posUpdateSubpackets = new List<SubPacket>();
|
||||
|
||||
//Remove missing actors
|
||||
for (int i = 0; i < actorInstanceList.Count; i++)
|
||||
{
|
||||
|
@ -155,29 +152,56 @@ namespace Meteor.Map.dataobjects
|
|||
|
||||
}
|
||||
else
|
||||
{
|
||||
{
|
||||
QueuePacket(actor.GetSpawnPackets(playerActor, 1));
|
||||
|
||||
QueuePacket(actor.GetInitPackets());
|
||||
QueuePacket(actor.GetSetEventStatusPackets());
|
||||
actorInstanceList.Add(actor);
|
||||
|
||||
if (actor is Npc)
|
||||
if (actor is Npc npc)
|
||||
{
|
||||
((Npc)actor).DoOnActorSpawn(playerActor);
|
||||
npc.DoOnActorSpawn(playerActor);
|
||||
|
||||
// Quest Instance related
|
||||
Quest[] quests = playerActor.GetQuestsForNpc(npc);
|
||||
if (quests.Length != 0)
|
||||
{
|
||||
ENpcQuestInstance questInstance = quests[0].GetENpcInstance(npc.GetActorClassId());
|
||||
QueuePacket(npc.GetSetEventStatusPackets());
|
||||
QueuePacket(SetActorQuestGraphicPacket.BuildPacket(npc.actorId, questInstance.questFlagType));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
actorInstanceList.Add(actor);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void UpdateQuestNpcInInstance(ENpcQuestInstance questInstance, bool clearInstance = false)
|
||||
{
|
||||
LockUpdates(true);
|
||||
Actor actor = actorInstanceList.Find(x => x is Npc npc && npc.GetActorClassId().Equals(questInstance.actorClassId));
|
||||
if (actor != null)
|
||||
{
|
||||
if (!clearInstance)
|
||||
{
|
||||
QueuePacket(actor.GetSetEventStatusPackets());
|
||||
QueuePacket(SetActorQuestGraphicPacket.BuildPacket(actor.actorId, questInstance.questFlagType));
|
||||
}
|
||||
else
|
||||
{
|
||||
QueuePacket(actor.GetSetEventStatusPackets());
|
||||
QueuePacket(SetActorQuestGraphicPacket.BuildPacket(actor.actorId, 0));
|
||||
}
|
||||
}
|
||||
LockUpdates(false);
|
||||
}
|
||||
|
||||
public void ClearInstance()
|
||||
{
|
||||
actorInstanceList.Clear();
|
||||
}
|
||||
|
||||
|
||||
public void LockUpdates(bool f)
|
||||
{
|
||||
isUpdatesLocked = f;
|
||||
|
|
|
@ -502,20 +502,22 @@ namespace Meteor.Map
|
|||
|
||||
query = @"
|
||||
INSERT INTO characters_quest_scenario
|
||||
(characterId, slot, questId, currentPhase, questData, questFlags)
|
||||
(characterId, slot, questId, sequence, flags, counter1, counter2, counter3)
|
||||
VALUES
|
||||
(@charaId, @slot, @questId, @phase, @questData, @questFlags)
|
||||
(@charaId, @slot, @questId, @sequence, @flags, @counter1, @counter2, @counter3)
|
||||
ON DUPLICATE KEY UPDATE
|
||||
questId = @questId, currentPhase = @phase, questData = @questData, questFlags = @questFlags
|
||||
questId = @questId, sequence = @sequence, flags = @flags, counter1 = @counter1, counter2 = @counter2, counter3 = @counter3
|
||||
";
|
||||
|
||||
cmd = new MySqlCommand(query, conn);
|
||||
cmd.Parameters.AddWithValue("@charaId", player.actorId);
|
||||
cmd.Parameters.AddWithValue("@slot", slot);
|
||||
cmd.Parameters.AddWithValue("@questId", 0xFFFFF & quest.actorId);
|
||||
cmd.Parameters.AddWithValue("@phase", quest.GetPhase());
|
||||
cmd.Parameters.AddWithValue("@questData", quest.GetSerializedQuestData());
|
||||
cmd.Parameters.AddWithValue("@questFlags", quest.GetQuestFlags());
|
||||
cmd.Parameters.AddWithValue("@sequence", quest.GetSequence());
|
||||
cmd.Parameters.AddWithValue("@flags", quest.GetFlags());
|
||||
cmd.Parameters.AddWithValue("@counter1", quest.GetCounter(1));
|
||||
cmd.Parameters.AddWithValue("@counter2", quest.GetCounter(2));
|
||||
cmd.Parameters.AddWithValue("@counter3", quest.GetCounter(3));
|
||||
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
|
@ -1145,9 +1147,11 @@ namespace Meteor.Map
|
|||
SELECT
|
||||
slot,
|
||||
questId,
|
||||
questData,
|
||||
questFlags,
|
||||
currentPhase
|
||||
sequence,
|
||||
flags,
|
||||
counter1,
|
||||
counter2,
|
||||
counter3
|
||||
FROM characters_quest_scenario WHERE characterId = @charId";
|
||||
|
||||
cmd = new MySqlCommand(query, conn);
|
||||
|
@ -1156,27 +1160,18 @@ namespace Meteor.Map
|
|||
{
|
||||
while (reader.Read())
|
||||
{
|
||||
int index = reader.GetUInt16(0);
|
||||
player.playerWork.questScenario[index] = 0xA0F00000 | reader.GetUInt32(1);
|
||||
string questData = null;
|
||||
uint questFlags = 0;
|
||||
uint currentPhase = 0;
|
||||
int index = reader.GetUInt16("slot");
|
||||
uint questId = 0xA0F00000 | reader.GetUInt32("questId");
|
||||
ushort sequence = reader.GetUInt16("sequence");
|
||||
uint flags = reader.GetUInt32("flags");
|
||||
ushort counter1 = reader.GetUInt16("counter1");
|
||||
ushort counter2 = reader.GetUInt16("counter2");
|
||||
ushort counter3 = reader.GetUInt16("counter3");
|
||||
|
||||
if (!reader.IsDBNull(2))
|
||||
questData = reader.GetString(2);
|
||||
else
|
||||
questData = "{}";
|
||||
Quest baseQuest = (Quest) Server.GetStaticActors(questId);
|
||||
|
||||
if (!reader.IsDBNull(3))
|
||||
questFlags = reader.GetUInt32(3);
|
||||
else
|
||||
questFlags = 0;
|
||||
|
||||
if (!reader.IsDBNull(4))
|
||||
currentPhase = reader.GetUInt32(4);
|
||||
|
||||
string questName = Server.GetStaticActors(player.playerWork.questScenario[index]).actorName;
|
||||
player.questScenario[index] = new Quest(player, player.playerWork.questScenario[index], questName, questData, questFlags, currentPhase);
|
||||
player.playerWork.questScenario[index] = questId;
|
||||
player.questScenario[index] = new Quest(player, baseQuest, sequence, flags, counter1, counter2, counter3);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -61,10 +61,16 @@ namespace Meteor.Map.lua
|
|||
|
||||
private LuaEngine()
|
||||
{
|
||||
UserData.RegistrationPolicy = InteropRegistrationPolicy.Automatic;
|
||||
|
||||
luaTimer = new Timer(new TimerCallback(PulseSleepingOnTime),
|
||||
null, TimeSpan.Zero, TimeSpan.FromMilliseconds(50));
|
||||
|
||||
|
||||
UserData.RegisterType<Player>();
|
||||
UserData.RegisterType<Command>();
|
||||
UserData.RegisterType<Npc>();
|
||||
UserData.RegisterType<Quest>();
|
||||
UserData.RegisterType<WorldManager>();
|
||||
UserData.RegisterType<WorldMaster>();
|
||||
}
|
||||
|
||||
public static LuaEngine GetInstance()
|
||||
|
@ -403,20 +409,24 @@ namespace Meteor.Map.lua
|
|||
args2[0] = target;
|
||||
|
||||
LuaScript parent = null, child = null;
|
||||
string errorMsg = "";
|
||||
|
||||
if (File.Exists("./scripts/base/" + target.classPath + ".lua"))
|
||||
parent = LuaEngine.LoadScript("./scripts/base/" + target.classPath + ".lua");
|
||||
parent = LuaEngine.LoadScript("./scripts/base/" + target.classPath + ".lua", ref errorMsg);
|
||||
|
||||
if (!errorMsg.Equals(""))
|
||||
SendError(player, errorMsg);
|
||||
|
||||
Area area = target.zone;
|
||||
if (area is PrivateArea)
|
||||
{
|
||||
if (File.Exists(String.Format("./scripts/unique/{0}/privatearea/{1}_{2}/{3}/{4}.lua", area.zoneName, ((PrivateArea)area).GetPrivateAreaName(), ((PrivateArea)area).GetPrivateAreaType(), target.className, target.GetUniqueId())))
|
||||
child = LuaEngine.LoadScript(String.Format("./scripts/unique/{0}/privatearea/{1}_{2}/{3}/{4}.lua", area.zoneName, ((PrivateArea)area).GetPrivateAreaName(), ((PrivateArea)area).GetPrivateAreaType(), target.className, target.GetUniqueId()));
|
||||
child = LuaEngine.LoadScript(String.Format("./scripts/unique/{0}/privatearea/{1}_{2}/{3}/{4}.lua", area.zoneName, ((PrivateArea)area).GetPrivateAreaName(), ((PrivateArea)area).GetPrivateAreaType(), target.className, target.GetUniqueId()), ref errorMsg);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (File.Exists(String.Format("./scripts/unique/{0}/{1}/{2}.lua", area.zoneName, target.className, target.GetUniqueId())))
|
||||
child = LuaEngine.LoadScript(String.Format("./scripts/unique/{0}/{1}/{2}.lua", area.zoneName, target.className, target.GetUniqueId()));
|
||||
child = LuaEngine.LoadScript(String.Format("./scripts/unique/{0}/{1}/{2}.lua", area.zoneName, target.className, target.GetUniqueId()), ref errorMsg);
|
||||
}
|
||||
|
||||
if (parent == null && child == null)
|
||||
|
@ -451,20 +461,21 @@ namespace Meteor.Map.lua
|
|||
args2[0] = target;
|
||||
|
||||
LuaScript parent = null, child = null;
|
||||
string errorMsg = "";
|
||||
|
||||
if (File.Exists("./scripts/base/" + target.classPath + ".lua"))
|
||||
parent = LuaEngine.LoadScript("./scripts/base/" + target.classPath + ".lua");
|
||||
parent = LuaEngine.LoadScript("./scripts/base/" + target.classPath + ".lua", ref errorMsg);
|
||||
|
||||
Area area = target.zone;
|
||||
if (area is PrivateArea)
|
||||
{
|
||||
if (File.Exists(String.Format("./scripts/unique/{0}/privatearea/{1}_{2}/{3}/{4}.lua", area.zoneName, ((PrivateArea)area).GetPrivateAreaName(), ((PrivateArea)area).GetPrivateAreaType(), target.className, target.GetUniqueId())))
|
||||
child = LuaEngine.LoadScript(String.Format("./scripts/unique/{0}/privatearea/{1}_{2}/{3}/{4}.lua", area.zoneName, ((PrivateArea)area).GetPrivateAreaName(), ((PrivateArea)area).GetPrivateAreaType(), target.className, target.GetUniqueId()));
|
||||
child = LuaEngine.LoadScript(String.Format("./scripts/unique/{0}/privatearea/{1}_{2}/{3}/{4}.lua", area.zoneName, ((PrivateArea)area).GetPrivateAreaName(), ((PrivateArea)area).GetPrivateAreaType(), target.className, target.GetUniqueId()), ref errorMsg);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (File.Exists(String.Format("./scripts/unique/{0}/{1}/{2}.lua", area.zoneName, target.className, target.GetUniqueId())))
|
||||
child = LuaEngine.LoadScript(String.Format("./scripts/unique/{0}/{1}/{2}.lua", area.zoneName, target.className, target.GetUniqueId()));
|
||||
child = LuaEngine.LoadScript(String.Format("./scripts/unique/{0}/{1}/{2}.lua", area.zoneName, target.className, target.GetUniqueId()), ref errorMsg);
|
||||
}
|
||||
|
||||
if (parent == null && child == null)
|
||||
|
@ -493,6 +504,8 @@ namespace Meteor.Map.lua
|
|||
SendError(player, e.DecoratedMessage);
|
||||
}
|
||||
}
|
||||
if (!errorMsg.Equals(""))
|
||||
SendError(player, errorMsg);
|
||||
}
|
||||
|
||||
public List<LuaParam> CallLuaFunctionForReturn(Player player, Actor target, string funcName, bool optional, params object[] args)
|
||||
|
@ -511,8 +524,10 @@ namespace Meteor.Map.lua
|
|||
else
|
||||
args2[0] = target;
|
||||
|
||||
string errorMsg = "";
|
||||
|
||||
string luaPath = GetScriptPath(target);
|
||||
LuaScript script = LoadScript(luaPath);
|
||||
LuaScript script = LoadScript(luaPath, ref errorMsg);
|
||||
if (script != null)
|
||||
{
|
||||
if (!script.Globals.Get(funcName).IsNil())
|
||||
|
@ -533,13 +548,16 @@ namespace Meteor.Map.lua
|
|||
if (!optional)
|
||||
SendError(player, String.Format("Could not find script for actor {0}.", target.GetName()));
|
||||
}
|
||||
if (!errorMsg.Equals(""))
|
||||
SendError(player, errorMsg);
|
||||
return null;
|
||||
}
|
||||
|
||||
public List<LuaParam> CallLuaFunctionForReturn(string path, string funcName, bool optional, params object[] args)
|
||||
{
|
||||
string luaPath = path;
|
||||
LuaScript script = LoadScript(luaPath);
|
||||
string errorMsg = "";
|
||||
LuaScript script = LoadScript(luaPath, ref errorMsg);
|
||||
if (script != null)
|
||||
{
|
||||
if (!script.Globals.Get(funcName).IsNil())
|
||||
|
@ -549,7 +567,7 @@ namespace Meteor.Map.lua
|
|||
List<LuaParam> lparams = LuaUtils.CreateLuaParamList(result);
|
||||
return lparams;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -567,8 +585,9 @@ namespace Meteor.Map.lua
|
|||
args2[0] = player;
|
||||
args2[1] = target;
|
||||
|
||||
string errorMsg = "";
|
||||
string luaPath = GetScriptPath(target);
|
||||
LuaScript script = LoadScript(luaPath);
|
||||
LuaScript script = LoadScript(luaPath, ref errorMsg);
|
||||
if (script != null)
|
||||
{
|
||||
if (!script.Globals.Get(funcName).IsNil())
|
||||
|
@ -597,13 +616,16 @@ namespace Meteor.Map.lua
|
|||
if (!(target is Area) && !optional)
|
||||
SendError(player, String.Format("Could not find script for actor {0}.", target.GetName()));
|
||||
}
|
||||
if (!errorMsg.Equals(""))
|
||||
SendError(player, errorMsg);
|
||||
}
|
||||
|
||||
public void EventStarted(Player player, Actor target, EventStartPacket eventStart)
|
||||
{
|
||||
List<LuaParam> lparams = new List<LuaParam>();
|
||||
lparams.AddRange(eventStart.luaParams);
|
||||
lparams.Insert(0, new LuaParam(2, eventStart.eventName));
|
||||
lparams.Insert(0, new LuaParam(0, eventStart.eventType));
|
||||
lparams.Insert(1, new LuaParam(2, eventStart.eventName));
|
||||
if (mSleepingOnPlayerEvent.ContainsKey(player.actorId))
|
||||
{
|
||||
Coroutine coroutine = mSleepingOnPlayerEvent[player.actorId];
|
||||
|
@ -819,8 +841,8 @@ namespace Meteor.Map.lua
|
|||
return;
|
||||
}
|
||||
#endregion
|
||||
|
||||
public static LuaScript LoadScript(string path)
|
||||
|
||||
public static LuaScript LoadScript(string path, ref string errorMsg)
|
||||
{
|
||||
if (!File.Exists(path))
|
||||
return null;
|
||||
|
@ -834,6 +856,7 @@ namespace Meteor.Map.lua
|
|||
catch (SyntaxErrorException e)
|
||||
{
|
||||
Program.Log.Error("{0}.", e.DecoratedMessage);
|
||||
errorMsg = e.DecoratedMessage;
|
||||
return null;
|
||||
}
|
||||
return script;
|
||||
|
@ -851,7 +874,7 @@ namespace Meteor.Map.lua
|
|||
script.Globals["GetWorldMaster"] = (Func<Actor>)Server.GetWorldManager().GetActor;
|
||||
script.Globals["GetItemGamedata"] = (Func<uint, ItemData>)Server.GetItemGamedata;
|
||||
script.Globals["GetGuildleveGamedata"] = (Func<uint, GuildleveData>)Server.GetGuildleveGamedata;
|
||||
script.Globals["GetRecipeResolver"] = (Func<RecipeResolver>)Server.ResolveRecipe;
|
||||
//script.Globals["GetRecipeResolver"] = (Func<RecipeResolver>)Server.ResolveRecipe;
|
||||
script.Globals["GetLuaInstance"] = (Func<LuaEngine>)LuaEngine.GetInstance;
|
||||
|
||||
script.Options.DebugPrint = s => { Program.Log.Debug(s); };
|
||||
|
|
|
@ -67,8 +67,8 @@
|
|||
<HintPath>..\packages\Cyotek.CircularBuffer.1.0.0.0\lib\net20\Cyotek.Collections.Generic.CircularBuffer.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="MoonSharp.Interpreter">
|
||||
<HintPath>..\packages\MoonSharp.1.2.1.0\lib\net40-client\MoonSharp.Interpreter.dll</HintPath>
|
||||
<Reference Include="MoonSharp.Interpreter, Version=2.0.0.0, Culture=neutral, PublicKeyToken=921e73ce94aa17f8, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\MoonSharp.2.0.0.0\lib\net40-client\MoonSharp.Interpreter.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="MySql.Data, Version=6.9.8.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\MySql.Data.6.9.8\lib\net45\MySql.Data.dll</HintPath>
|
||||
|
|
|
@ -207,9 +207,9 @@ namespace Meteor.Map
|
|||
//Is it a instance actor?
|
||||
if (ownerActor == null)
|
||||
ownerActor = session.GetActor().zone.FindActorInArea(eventStart.ownerActorID);
|
||||
//Is it a Director?
|
||||
if (ownerActor == null)
|
||||
{
|
||||
//Is it a Director?
|
||||
Director director = session.GetActor().GetDirector(eventStart.ownerActorID);
|
||||
if (director != null)
|
||||
ownerActor = director;
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<packages>
|
||||
<package id="Cyotek.CircularBuffer" version="1.0.0.0" targetFramework="net45" />
|
||||
<package id="Microsoft.Net.Compilers" version="2.0.0-beta3" targetFramework="net45" developmentDependency="true" />
|
||||
<package id="MoonSharp" version="1.2.1.0" targetFramework="net45" />
|
||||
<package id="MoonSharp" version="2.0.0.0" targetFramework="net451" />
|
||||
<package id="MySql.Data" version="6.9.8" targetFramework="net45" />
|
||||
<package id="Newtonsoft.Json" version="9.0.1" targetFramework="net451" />
|
||||
<package id="NLog" version="4.5.0" targetFramework="net451" />
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue