1
Fork 0
mirror of https://bitbucket.org/Ioncannon/project-meteor-server.git synced 2025-04-22 20:57:47 +00:00

Changed how Quest ENPCs work. They should now automatically update themselves whenever data is update for immediate effect changes. Fixed wrong map qflag value. Fixed quest gm command. Fixed Director actorId clobbering areaMasters.

This commit is contained in:
Filip Maj 2022-02-06 12:12:26 -05:00
parent b11007b263
commit 8b3431e557
8 changed files with 180 additions and 179 deletions

View file

@ -18,6 +18,7 @@ function onTrigger(player, argc, command, var1, var2, var3)
local sender = "[quest] "; local sender = "[quest] ";
local message = "Error"; local message = "Error";
print(tostring(argc));
if player then if player then
if argc == 2 then if argc == 2 then
if command == "add" or command == "give" or command == "+" then if command == "add" or command == "give" or command == "+" then
@ -57,19 +58,45 @@ function onTrigger(player, argc, command, var1, var2, var3)
else else
message = ("remove error: either incorrect ID or quest "..var1.." isn't active on character"); message = ("remove error: either incorrect ID or quest "..var1.." isn't active on character");
end end
end
elseif command == "info" then
if tonumber(var1) then
if player:HasQuest(tonumber(var1)) then
quest = player:GetQuest(tonumber(var1));
local flagStr = "";
for i=0,31,1 do
if (quest:GetFlag(i)) then
flagStr = flagStr .. "O";
else
flagStr = flagStr .. "X";
end
if (i == 15) then
flagStr = flagStr .. "\n";
end
end
message = string.format("\nInfo for quest %s [%d]\n", quest.Name, quest:GetQuestId());
message = message .. string.format("Current Sequence: %d\n", quest:getSequence());
message = message .. string.format("Flags: \n%s\n", flagStr)
message = message .. string.format("Counters: %d,%d,%d,%d", quest:getCounter(1), quest:getCounter(2), quest:getCounter(3), quest:getCounter(4));
else
message = ("Quest not active: "..var1);
end
else
message = ("error: invalid parameters used");
end end
else else
message = ("error: command "..command.." not recognized"); message = ("error: command "..command.." not recognized");
end end
elseif argc == 3 then elseif argc == 3 then
if command == "phase" or command == "step" then if command == "seq" or command == "sequence" then
if (tonumber(var1) and tonumber(var2)) ~= nil then if (tonumber(var1) and tonumber(var2)) ~= nil then
if player:HasQuest(tonumber(var1)) == true then if player:HasQuest(tonumber(var1)) == true then
player:GetQuest(tonumber(var1)):NextPhase(tonumber(var2)); player:GetQuest(tonumber(var1)):StartSequence(tonumber(var2));
message = ("changing phase of quest "..var1.." to "..var2); message = ("changing sequence of quest "..var1.." to "..var2);
else else
message = ("phase error: either incorrect ID or quest "..var1.." isn't active on character"); message = ("sequence error: either incorrect ID or quest "..var1.." isn't active on character");
end end
else else
message = ("error: invalid parameters used"); message = ("error: invalid parameters used");
@ -85,13 +112,13 @@ function onTrigger(player, argc, command, var1, var2, var3)
flagvar = (tonumber(var2)); flagvar = (tonumber(var2));
boolvar = 0; boolvar = 0;
if var3 == "true" or var3 == "1" or var3 == "on" then if var3 == "true" or var3 == "1" or var3 == "on" or var3 == "O" then
boolvar = true; boolvar = true;
elseif var3 == "false" or var3 == "0" or var3 == "off" then elseif var3 == "false" or var3 == "0" or var3 == "off" or var3 == "X" then
boolvar = false; boolvar = false;
elseif var3 == "flip" or var3 == "toggle" then elseif var3 == "flip" or var3 == "toggle" then
if player:HasQuest(questvar) == true then if player:HasQuest(questvar) == true then
boolvar = not player:GetQuest(questvar):GetQuestFlag(flagvar); boolvar = not player:GetQuest(questvar):GetFlag(flagvar);
end end
else else
message = ("error: flag: boolean not recognized"); message = ("error: flag: boolean not recognized");
@ -99,10 +126,15 @@ function onTrigger(player, argc, command, var1, var2, var3)
return; return;
end end
var4 = player:GetQuest(questvar):GetQuestFlag(flagvar); var4 = player:GetQuest(questvar):GetFlag(flagvar);
if var4 ~= boolvar then if var4 ~= boolvar then
player:GetQuest(questvar):SetQuestFlag(flagvar, boolvar); if (boolvar == true) then
player:GetQuest(questvar):SetFlag(flagvar);
else
player:GetQuest(questvar):ClearFlag(flagvar);
end
player:GetQuest(questvar):UpdateENPCs();
player:GetQuest(questvar):SaveData(); player:GetQuest(questvar):SaveData();
if boolvar == true then if boolvar == true then
message = ("changing flag "..tonumber(var2).." to true on quest "..questvar); message = ("changing flag "..tonumber(var2).." to true on quest "..questvar);
@ -114,6 +146,18 @@ function onTrigger(player, argc, command, var1, var2, var3)
end end
else else
message = ("error: command "..command.." not recognized"); message = ("error: command "..command.." not recognized");
end
elseif command == "counter" then
if tonumber(var1) and (tonumber(var2) >= 0 and tonumber(var2) <= 4) then
questvar = tonumber(var1);
index = (tonumber(var2));
player:GetQuest(questvar):SetCounter(index, tonumber(var3));
player:GetQuest(questvar):UpdateENPCs();
player:GetQuest(questvar):SaveData();
message = ("changing counter "..tonumber(var2).." to "..var3);
else
message = ("error: command "..command.." not recognized");
end end
end end
end end

View file

@ -161,8 +161,8 @@ ENPC_PROP_CAN_EMOTE = 3;
ENPC_PROP_CAN_NOTICE = 4; ENPC_PROP_CAN_NOTICE = 4;
QFLAG_NONE = 0; QFLAG_NONE = 0;
QFLAG_MAP = 1;
QFLAG_PLATE = 2; QFLAG_PLATE = 2;
QFLAG_MAP = 3;
-- Common Helper Functions -- Common Helper Functions
function attentionMessage(player, textId, ...) function attentionMessage(player, textId, ...)

View file

@ -63,9 +63,6 @@ function onFinish(player, quest)
end end
function onSequence(player, quest, sequence) function onSequence(player, quest, sequence)
quest:ClearENpcs();
quest:ClearData();
if (sequence == SEQ_000) then if (sequence == SEQ_000) then
-- Setup states incase we loaded in. -- Setup states incase we loaded in.
local rostnsthalFlag = quest:GetFlag(FLAG_SEQ000_MINITUT1) and QFLAG_NONE or QFLAG_PLATE; local rostnsthalFlag = quest:GetFlag(FLAG_SEQ000_MINITUT1) and QFLAG_NONE or QFLAG_PLATE;
@ -73,7 +70,7 @@ function onSequence(player, quest, sequence)
local babyfaceFlag = quest:GetFlag(FLAG_SEQ000_MINITUT3) and QFLAG_NONE or QFLAG_PLATE; local babyfaceFlag = quest:GetFlag(FLAG_SEQ000_MINITUT3) and QFLAG_NONE or QFLAG_PLATE;
local rostnsthalCanPush = not quest:GetFlag(FLAG_SEQ000_MINITUT0); local rostnsthalCanPush = not quest:GetFlag(FLAG_SEQ000_MINITUT0);
local exitCanPush = quest:GetFlags() == 0xF; local exitCanPush = quest:GetFlags() == 0xF;
local exitFlag = quest:GetFlags() == 0xF and QFLAG_PLATE or QFLAG_NONE; local exitFlag = quest:GetFlags() == 0xF and QFLAG_MAP or QFLAG_NONE;
quest:AddENpc(WELLTRAVELED_MERCHANT); quest:AddENpc(WELLTRAVELED_MERCHANT);
quest:AddENpc(TIPSY_ADVENTURER); quest:AddENpc(TIPSY_ADVENTURER);
@ -90,7 +87,7 @@ function onSequence(player, quest, sequence)
quest:AddENpc(LANKY_TRAVELER); quest:AddENpc(LANKY_TRAVELER);
quest:AddENpc(GRINNING_ADVENTURER); quest:AddENpc(GRINNING_ADVENTURER);
quest:AddENpc(ROSTNSTHAL, rostnsthalFlag, true, rostnsthalCanPush); quest:AddENpc(ROSTNSTHAL, rostnsthalFlag, true, rostnsthalCanPush);
quest:AddENpc(EXIT_TRIGGER, exitFlag, false, false, exitCanPush); quest:AddENpc(EXIT_TRIGGER, exitFlag, false, exitCanPush);
elseif (sequence == SEQ_005) then elseif (sequence == SEQ_005) then
elseif (sequence == SEQ_010) then elseif (sequence == SEQ_010) then
quest:AddENpc(HOB); quest:AddENpc(HOB);
@ -102,7 +99,7 @@ function onSequence(player, quest, sequence)
quest:AddENpc(WELLTRAVELED_MERCHANT); quest:AddENpc(WELLTRAVELED_MERCHANT);
quest:AddENpc(VOLUPTUOUS_VIXEN); quest:AddENpc(VOLUPTUOUS_VIXEN);
quest:AddENpc(LANKY_TRAVELER); quest:AddENpc(LANKY_TRAVELER);
quest:AddENpc(PRIVAREA_PAST_EXIT, QFLAG_NONE, false, false, true); quest:AddENpc(PRIVAREA_PAST_EXIT, QFLAG_NONE, false, true);
end end
end end
@ -115,6 +112,8 @@ function onTalk(player, quest, npc)
elseif (sequence == SEQ_010) then elseif (sequence == SEQ_010) then
seq010_onTalk(player, quest, npc, classId); seq010_onTalk(player, quest, npc, classId);
end end
quest:UpdateENPCs();
end end
function onPush(player, quest, npc) function onPush(player, quest, npc)
@ -138,6 +137,8 @@ function onPush(player, quest, npc)
end end
end end
end end
quest:UpdateENPCs();
end end
function onNotice(player, quest, target) function onNotice(player, quest, target)
@ -148,6 +149,7 @@ function onNotice(player, quest, target)
end end
player:EndEvent(); player:EndEvent();
quest:UpdateENPCs();
end end
function seq000_onTalk(player, quest, npc, classId) function seq000_onTalk(player, quest, npc, classId)
@ -162,7 +164,6 @@ function seq000_onTalk(player, quest, npc, classId)
elseif (classId == BABYFACED_ADVENTURER) then elseif (classId == BABYFACED_ADVENTURER) then
if (not quest:GetFlag(FLAG_SEQ000_MINITUT3)) then if (not quest:GetFlag(FLAG_SEQ000_MINITUT3)) then
callClientFunction(player, "delegateEvent", player, quest, "processTtrMini003"); callClientFunction(player, "delegateEvent", player, quest, "processTtrMini003");
quest:UpdateENpc(BABYFACED_ADVENTURER, ENPC_PROP_QFLAG, QFLAG_NONE);
quest:SetFlag(FLAG_SEQ000_MINITUT3); quest:SetFlag(FLAG_SEQ000_MINITUT3);
else else
callClientFunction(player, "delegateEvent", player, quest, "processEvent000_8"); callClientFunction(player, "delegateEvent", player, quest, "processEvent000_8");
@ -178,7 +179,6 @@ function seq000_onTalk(player, quest, npc, classId)
elseif (classId == VOLUPTUOUS_VIXEN) then elseif (classId == VOLUPTUOUS_VIXEN) then
if (not quest:GetFlag(FLAG_SEQ000_MINITUT2)) then if (not quest:GetFlag(FLAG_SEQ000_MINITUT2)) then
callClientFunction(player, "delegateEvent", player, quest, "processTtrMini002"); callClientFunction(player, "delegateEvent", player, quest, "processTtrMini002");
quest:UpdateENpc(VOLUPTUOUS_VIXEN, ENPC_PROP_QFLAG, QFLAG_NONE);
quest:SetFlag(FLAG_SEQ000_MINITUT2); quest:SetFlag(FLAG_SEQ000_MINITUT2);
else else
callClientFunction(player, "delegateEvent", player, quest, "processEvent000_13"); callClientFunction(player, "delegateEvent", player, quest, "processEvent000_13");
@ -196,24 +196,14 @@ function seq000_onTalk(player, quest, npc, classId)
if (not quest:GetFlag(FLAG_SEQ000_MINITUT0)) then if (not quest:GetFlag(FLAG_SEQ000_MINITUT0)) then
callClientFunction(player, "delegateEvent", player, quest, "processTtrNomal003"); callClientFunction(player, "delegateEvent", player, quest, "processTtrNomal003");
quest:SetFlag(FLAG_SEQ000_MINITUT0); quest:SetFlag(FLAG_SEQ000_MINITUT0);
quest:UpdateENpc(ROSTNSTHAL, ENPC_PROP_CAN_PUSH, false);
quest:UpdateENpc(ROSTNSTHAL, ENPC_PROP_QFLAG, QFLAG_PLATE);
quest:UpdateENpc(VOLUPTUOUS_VIXEN, ENPC_PROP_QFLAG, QFLAG_PLATE);
quest:UpdateENpc(BABYFACED_ADVENTURER, ENPC_PROP_QFLAG, QFLAG_PLATE);
else else
callClientFunction(player, "delegateEvent", player, quest, "processTtrMini001"); callClientFunction(player, "delegateEvent", player, quest, "processTtrMini001");
if (not quest:GetFlag(FLAG_SEQ000_MINITUT1)) then if (not quest:GetFlag(FLAG_SEQ000_MINITUT1)) then
quest:UpdateENpc(ROSTNSTHAL, ENPC_PROP_QFLAG, QFLAG_NONE);
quest:SetFlag(FLAG_SEQ000_MINITUT1); quest:SetFlag(FLAG_SEQ000_MINITUT1);
end end
end end
end end
if (quest:GetFlags() == 0xF) then
quest:UpdateENpc(EXIT_TRIGGER, ENPC_PROP_CAN_PUSH, true);
quest:UpdateENpc(EXIT_TRIGGER, ENPC_PROP_QFLAG, QFLAG_MAP);
end
player:EndEvent(); player:EndEvent();
end end
@ -233,7 +223,7 @@ function seq010_onTalk(player, quest, npc, classId)
elseif (classId == HOB) then elseif (classId == HOB) then
local choice = callClientFunction(player, "delegateEvent", player, quest, "processEvent020_9"); local choice = callClientFunction(player, "delegateEvent", player, quest, "processEvent020_9");
if (choice == 1) then if (choice == 1) then
quest:completeAndReplace(110002); player:ReplaceQuest(quest, "Man0l1");
return; return;
end end
elseif (classId == GERT) then elseif (classId == GERT) then

View file

@ -41,92 +41,20 @@ end
function onSequence(player, quest, sequence) function onSequence(player, quest, sequence)
quest:ClearENpcs(); quest:ClearENpcs();
if (sequence == SEQ_000) then
-- Setup states incase we loaded in.
local rostnsthalFlag = quest:GetFlag(FLAG_SEQ000_MINITUT1) and QFLAG_NONE or QFLAG_PLATE;
local vixenFlag = quest:GetFlag(FLAG_SEQ000_MINITUT2) and QFLAG_NONE or QFLAG_PLATE;
local babyfaceFlag = quest:GetFlag(FLAG_SEQ000_MINITUT3) and QFLAG_NONE or QFLAG_PLATE;
local rostnsthalCanPush = not quest:GetFlag(FLAG_SEQ000_MINITUT0);
local exitCanPush = quest:GetFlags() == 0xF;
local exitFlag = quest:GetFlags() == 0xF and QFLAG_PLATE or QFLAG_NONE;
quest:AddENpc(WELLTRAVELED_MERCHANT);
quest:AddENpc(TIPSY_ADVENTURER);
quest:AddENpc(CULTIVATED_TENDER);
quest:AddENpc(ANXIOUS_ADVENTURER);
quest:AddENpc(BABYFACED_ADVENTURER, babyfaceFlag);
quest:AddENpc(AUSTERE_ADVENTURER);
quest:AddENpc(UNDIGNIFIED_ADVENTURER);
quest:AddENpc(SHADOWY_TRAVELER);
quest:AddENpc(ASTUTE_MERCHANT);
quest:AddENpc(VOLUPTUOUS_VIXEN, vixenFlag);
quest:AddENpc(INDIFFERENT_PASSERBY);
quest:AddENpc(PRATTLING_ADVENTURER);
quest:AddENpc(LANKY_TRAVELER);
quest:AddENpc(GRINNING_ADVENTURER);
quest:AddENpc(ROSTNSTHAL, rostnsthalFlag, true, rostnsthalCanPush);
quest:AddENpc(EXIT_TRIGGER, exitFlag, false, false, exitCanPush);
elseif (sequence == SEQ_005) then
elseif (sequence == SEQ_010) then
quest:AddENpc(HOB);
quest:AddENpc(GERT);
quest:AddENpc(LORHZANT);
quest:AddENpc(MUSCLEBOUND_DECKHAND);
quest:AddENpc(PEARLYTOOTHED_PORTER);
quest:AddENpc(UNDIGNIFIED_ADVENTURER);
quest:AddENpc(WELLTRAVELED_MERCHANT);
quest:AddENpc(VOLUPTUOUS_VIXEN);
quest:AddENpc(LANKY_TRAVELER);
quest:AddENpc(PRIVAREA_PAST_EXIT, QFLAG_NONE, false, false, true);
end
end end
function onTalk(player, quest, npc) function onTalk(player, quest, npc)
local sequence = quest:getSequence(); local sequence = quest:getSequence();
local classId = npc:GetActorClassId(); local classId = npc:GetActorClassId();
if (sequence == SEQ_000) then
seq000_onTalk(player, quest, npc, classId);
elseif (sequence == SEQ_010) then
seq010_onTalk(player, quest, npc, classId);
end
end end
function onPush(player, quest, npc) function onPush(player, quest, npc)
local sequence = quest:getSequence(); local sequence = quest:getSequence();
local classId = npc:GetActorClassId(); local classId = npc:GetActorClassId();
if (sequence == SEQ_000) then
elseif (sequence == SEQ_010) then
end
end
function onNotice(player, quest, target)
local sequence = quest:getSequence();
if (sequence == SEQ_000) then
callClientFunction(player, "delegateEvent", player, quest, "processTtrNomal001withHQ");
end
end
function seq000_onTalk(player, quest, npc, classId)
if (classId == WELLTRAVELED_MERCHANT) then
callClientFunction(player, "delegateEvent", player, quest, "processEvent000_4");
elseif (classId == TIPSY_ADVENTURER) then
callClientFunction(player, "delegateEvent", player, quest, "processEvent000_5");
end
player:EndEvent();
end end
function getJournalMapMarkerList(player, quest) function getJournalMapMarkerList(player, quest)
local sequence = quest:getSequence(); local sequence = quest:getSequence();
if (sequence == SEQ_000) then
-- return MRKR_ROSTNSTHAL, MRKR_BABYFACED_ADVENTURER, MRKR_VOLUPTUOUS_VIXEN;
elseif (sequence == SEQ_010) then
-- return MRKR_HOB;
end
end end

View file

@ -1550,24 +1550,21 @@ namespace Meteor.Map.Actors
} }
} }
public void ReplaceQuest(uint oldId, uint newId) public void ReplaceQuest(Quest oldQuest, string questCode)
{
if (HasQuest(oldId))
{ {
for (int i = 0; i < questScenario.Length; i++) for (int i = 0; i < questScenario.Length; i++)
{ {
if (questScenario[i] != null && questScenario[i].GetQuestId() == oldId) if (questScenario[i] != null && questScenario[i].Equals(oldQuest))
{ {
Quest baseQuest = (Quest) Server.GetStaticActors((0xA0F00000 | newId)); Quest baseQuest = (Quest) Server.GetStaticActors(questCode);
playerWork.questScenario[i] = (0xA0F00000 | newId);
questScenario[i] = new Quest(this, baseQuest); questScenario[i] = new Quest(this, baseQuest);
playerWork.questScenario[i] = questScenario[i].Id;
Database.SaveQuest(this, questScenario[i]); Database.SaveQuest(this, questScenario[i]);
SendQuestClientUpdate(i); SendQuestClientUpdate(i);
break; break;
} }
} }
} }
}
public bool CanAcceptQuest(string name) public bool CanAcceptQuest(string name)
{ {
@ -1638,6 +1635,11 @@ namespace Meteor.Map.Actors
return false; return false;
} }
public bool HasQuest(Quest quest)
{
return HasQuest(quest.className);
}
public bool HasGuildleve(uint id) public bool HasGuildleve(uint id)
{ {
for (int i = 0; i < work.guildleveId.Length; i++) for (int i = 0; i < work.guildleveId.Length; i++)

View file

@ -46,7 +46,7 @@ namespace Meteor.Map.actors.director
private Coroutine currentCoroutine; private Coroutine currentCoroutine;
public Director(uint id, Area zone, string directorPath, bool hasContentGroup, params object[] args) public Director(uint id, Area zone, string directorPath, bool hasContentGroup, params object[] args)
: base((6 << 28 | zone.CurrentArea.ZoneId << 19 | (uint)id)) : base((6 << 28 | zone.ZoneId << 19 | (uint)id + 2))
{ {
directorId = id; directorId = id;
CurrentArea = zone; CurrentArea = zone;

View file

@ -51,6 +51,24 @@ namespace Meteor.Map.Actors
this.isEmoteEnabled = isEmoteEnabled; this.isEmoteEnabled = isEmoteEnabled;
this.isPushEnabled = isPushEnabled; this.isPushEnabled = isPushEnabled;
} }
public bool IsChanged(byte flagType, bool isTalkEnabled, bool isPushEnabled, bool isEmoteEnabled, bool isSpawned)
{
return flagType != this.questFlagType
|| isTalkEnabled != this.isTalkEnabled
|| isPushEnabled != this.isPushEnabled
|| isEmoteEnabled != this.isEmoteEnabled
|| isSpawned != this.isSpawned;
}
public void Update(byte flagType, bool isTalkEnabled, bool isPushEnabled, bool isEmoteEnabled, bool isSpawned)
{
this.questFlagType = flagType;
this.isSpawned = isSpawned;
this.isTalkEnabled = isTalkEnabled;
this.isEmoteEnabled = isEmoteEnabled;
this.isPushEnabled = isPushEnabled;
}
} }
private struct QuestData private struct QuestData
@ -73,59 +91,38 @@ namespace Meteor.Map.Actors
private Player Owner; private Player Owner;
private ushort currentSequence; private ushort currentSequence;
private QuestData data = new QuestData(); private QuestData data = new QuestData();
private Dictionary<uint, ENpcQuestInstance> ActiveENpcs = new Dictionary<uint, ENpcQuestInstance>(); private bool dataDirty = false;
private Dictionary<uint, ENpcQuestInstance> CurrentENPCs = new Dictionary<uint, ENpcQuestInstance>();
private Dictionary<uint, ENpcQuestInstance> OldENPCs = new Dictionary<uint, ENpcQuestInstance>();
public void AddENpc(uint classId, byte flagType = 0, bool isTalkEnabled = true, bool isEmoteEnabled = false, bool isPushEnabled = false, bool isSpawned = false) public void AddENpc(uint classId, byte flagType = 0, bool isTalkEnabled = true, bool isPushEnabled = false, bool isEmoteEnabled = false, bool isSpawned = false)
{ {
if (ActiveENpcs.ContainsKey(classId)) ENpcQuestInstance instanceUpdated = null;
return;
ENpcQuestInstance instance = new ENpcQuestInstance(classId, flagType, isSpawned, isTalkEnabled, isEmoteEnabled, isPushEnabled); if (OldENPCs.ContainsKey(classId))
ActiveENpcs.Add(classId, instance); {
Owner.playerSession.UpdateQuestNpcInInstance(instance); if (OldENPCs[classId].IsChanged(flagType, isTalkEnabled, isPushEnabled, isEmoteEnabled, isSpawned))
{
instanceUpdated = OldENPCs[classId];
instanceUpdated.Update(flagType, isTalkEnabled, isPushEnabled, isEmoteEnabled, isSpawned);
CurrentENPCs.Add(classId, instanceUpdated);
}
OldENPCs.Remove(classId);
}
else
{
instanceUpdated = new ENpcQuestInstance(classId, flagType, isSpawned, isTalkEnabled, isEmoteEnabled, isPushEnabled);
CurrentENPCs.Add(classId, instanceUpdated);
} }
public void ClearENpcs() if (instanceUpdated != null)
{ Owner.playerSession.UpdateQuestNpcInInstance(instanceUpdated);
foreach (ENpcQuestInstance instance in ActiveENpcs.Values)
Owner.playerSession.UpdateQuestNpcInInstance(instance, true);
ActiveENpcs.Clear();
}
public void UpdateENpc(uint classId, ENpcProperty property, object value)
{
if (!ActiveENpcs.ContainsKey(classId))
return;
ENpcQuestInstance instance = ActiveENpcs[classId];
switch (property)
{
case ENpcProperty.QuestFlag:
if (value is double)
instance.questFlagType = (byte)(double)value;
else if (value is int)
instance.questFlagType = (byte)value;
break;
case ENpcProperty.CanTalk:
instance.isTalkEnabled = (bool)value;
break;
case ENpcProperty.CanPush:
instance.isPushEnabled = (bool)value;
break;
case ENpcProperty.CanEmote:
instance.isEmoteEnabled = (bool)value;
break;
}
Owner.playerSession.UpdateQuestNpcInInstance(instance, false);
} }
public ENpcQuestInstance GetENpcInstance(uint classId) public ENpcQuestInstance GetENpcInstance(uint classId)
{ {
if (ActiveENpcs.ContainsKey(classId)) if (CurrentENPCs.ContainsKey(classId))
return ActiveENpcs[classId]; return CurrentENPCs[classId];
return null; return null;
} }
@ -154,11 +151,25 @@ namespace Meteor.Map.Actors
LuaEngine.GetInstance().CallLuaFunction(caller, this, "onNpcLS", true, npcLSId); LuaEngine.GetInstance().CallLuaFunction(caller, this, "onNpcLS", true, npcLSId);
} }
public void UpdateENPCs()
{
if (dataDirty)
{
OldENPCs = CurrentENPCs;
CurrentENPCs = new Dictionary<uint, ENpcQuestInstance>();
LuaEngine.GetInstance().CallLuaFunctionForReturn(Owner, this, "onSequence", false, currentSequence);
foreach (var enpc in OldENPCs)
Owner.playerSession.UpdateQuestNpcInInstance(enpc.Value);
OldENPCs = null;
dataDirty = false;
}
}
public bool IsQuestENPC(Player caller, Npc npc) public bool IsQuestENPC(Player caller, Npc npc)
{ {
List<LuaParam> returned = LuaEngine.GetInstance().CallLuaFunctionForReturn(caller, this, "IsQuestENPC", true, npc, this); List<LuaParam> returned = LuaEngine.GetInstance().CallLuaFunctionForReturn(caller, this, "IsQuestENPC", true, npc, this);
bool scriptReturned = returned != null && returned.Count != 0 && returned[0].typeID == 3; bool scriptReturned = returned != null && returned.Count != 0 && returned[0].typeID == 3;
return scriptReturned || ActiveENpcs.ContainsKey(npc.GetActorClassId()); return scriptReturned || CurrentENPCs.ContainsKey(npc.GetActorClassId());
} }
@ -195,7 +206,8 @@ namespace Meteor.Map.Actors
Owner.SendGameMessage(Server.GetWorldManager().GetActor(), 25116, 0x20, (object)GetQuestId()); Owner.SendGameMessage(Server.GetWorldManager().GetActor(), 25116, 0x20, (object)GetQuestId());
currentSequence = sequence; currentSequence = sequence;
LuaEngine.GetInstance().CallLuaFunction(Owner, this, "onSequence", false, currentSequence); dataDirty = true;
UpdateENPCs();
} }
public void ClearData() public void ClearData()
@ -206,70 +218,88 @@ namespace Meteor.Map.Actors
public void SetFlag(int index) public void SetFlag(int index)
{ {
if (index >= 0 && index < 32) if (index >= 0 && index < 32)
{
data.flags |= (uint)(1 << index); data.flags |= (uint)(1 << index);
dataDirty = true;
}
} }
public void ClearFlag(int index) public void ClearFlag(int index)
{ {
if (index >= 0 && index < 32) if (index >= 0 && index < 32)
{
data.flags &= (uint)~(1 << index); data.flags &= (uint)~(1 << index);
dataDirty = true;
}
} }
public void IncCounter(int num) public void IncCounter(int num)
{ {
dataDirty = true;
switch (num) switch (num)
{ {
case 0: case 0:
data.counter1++; data.counter1++;
break; return;
case 1: case 1:
data.counter2++; data.counter2++;
break; return;
case 2: case 2:
data.counter3++; data.counter3++;
break; return;
case 3: case 3:
data.counter4++; data.counter4++;
break; return;
} }
dataDirty = false;
} }
public void DecCounter(int num) public void DecCounter(int num)
{ {
dataDirty = true;
switch (num) switch (num)
{ {
case 0: case 0:
data.counter1--; data.counter1--;
break; return;
case 1: case 1:
data.counter2--; data.counter2--;
break; return;
case 2: case 2:
data.counter3--; data.counter3--;
break; return;
case 3: case 3:
data.counter4--; data.counter4--;
break; return;
} }
dataDirty = false;
} }
public void SetCounter(int num, ushort value) public void SetCounter(int num, ushort value)
{ {
dataDirty = true;
switch (num) switch (num)
{ {
case 0: case 0:
data.counter1 = value; data.counter1 = value;
break; return;
case 1: case 1:
data.counter2 = value; data.counter2 = value;
break; return;
case 2: case 2:
data.counter3 = value; data.counter3 = value;
break; return;
case 3: case 3:
data.counter4 = value; data.counter4 = value;
break; return;
} }
dataDirty = false;
} }
public bool GetFlag(int index) public bool GetFlag(int index)

View file

@ -39,6 +39,9 @@ using Meteor.Map.actors.chara.ai;
using Meteor.Map.actors.chara.ai.controllers; using Meteor.Map.actors.chara.ai.controllers;
using Meteor.Map.DataObjects; using Meteor.Map.DataObjects;
using Meteor.Map.actors.chara.player; using Meteor.Map.actors.chara.player;
using Meteor.Map.Actors.Chara;
using Meteor.Map.dataobjects.chara;
using Meteor.Map.actors.chara;
namespace Meteor.Map.lua namespace Meteor.Map.lua
{ {
@ -69,12 +72,16 @@ namespace Meteor.Map.lua
UserData.RegisterType<LuaEngine>(); UserData.RegisterType<LuaEngine>();
UserData.RegisterType<Player>(); UserData.RegisterType<Player>();
UserData.RegisterType<CharaWork>();
UserData.RegisterType<ParameterSave>();
UserData.RegisterType<PlayerWork>();
UserData.RegisterType<Command>(); UserData.RegisterType<Command>();
UserData.RegisterType<Npc>(); UserData.RegisterType<Npc>();
UserData.RegisterType<Quest>(); UserData.RegisterType<Quest>();
UserData.RegisterType<Zone>(); UserData.RegisterType<Zone>();
UserData.RegisterType<InventoryItem>(); UserData.RegisterType<InventoryItem>();
UserData.RegisterType<ItemPackage>(); UserData.RegisterType<ItemPackage>();
UserData.RegisterType<ReferencedItemPackage>();
UserData.RegisterType<PrivateArea>(); UserData.RegisterType<PrivateArea>();
UserData.RegisterType<PrivateAreaContent>(); UserData.RegisterType<PrivateAreaContent>();
UserData.RegisterType<Director>(); UserData.RegisterType<Director>();