From 281ee329531bf69ebd4681b72c1e5ba552749906 Mon Sep 17 00:00:00 2001 From: prooheckcp <61127277+prooheckcp@users.noreply.github.com> Date: Wed, 12 Jun 2024 13:46:59 +0100 Subject: [PATCH 01/15] Adding OnTimeQuestAvailable and OnTimeQuestUnavailable. Fixing SetPlayerData racing condition --- RoQuest/Server/init.lua | 44 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) diff --git a/RoQuest/Server/init.lua b/RoQuest/Server/init.lua index 55be0bc..8a22ab6 100644 --- a/RoQuest/Server/init.lua +++ b/RoQuest/Server/init.lua @@ -165,6 +165,44 @@ RoQuestServer.OnQuestDelivered = Signal.new() -- Event (player: Player, questId: @within RoQuestServer ]=] RoQuestServer.OnQuestCancelled = Signal.new() +--[=[ + This gets called when a quest becomes available. This isn't player specific and instead + gets called when per e.g a quest with a starting and end date becomes available + + ```lua + local ReplicatedStorage = game:GetService("ReplicatedStorage") + + local RoQuest = require(ReplicatedStorage.RoQuest).Server + + RoQuest.OnTimeQuestAvailable:Connect(function(questId: string) + print("The following quest just became available: ", RoQuest:GetQuest(player, questId).Name) + end) + ``` + + @server + @prop OnTimeQuestAvailable Signal + @within RoQuestServer +]=] +RoQuestServer.OnTimeQuestAvailable = Signal.new() +--[=[ + This gets called when a quest becomes unavailable. This isn't player specific and instead + gets called when per e.g a quest with a starting and end date becomes unavailable + + ```lua + local ReplicatedStorage = game:GetService("ReplicatedStorage") + + local RoQuest = require(ReplicatedStorage.RoQuest).Server + + RoQuest.OnTimeQuestUnavailable:Connect(function(questId: string) + print("The following quest just became unavailable: ", RoQuest:GetQuest(player, questId).Name) + end) + ``` + + @server + @prop OnTimeQuestUnavailable Signal + @within RoQuestServer +]=] +RoQuestServer.OnTimeQuestUnavailable = Signal.new() --[=[ This gets called when a quest becomes available. This usually means that the player can now accept this quest at a given quest giver @@ -174,7 +212,7 @@ RoQuestServer.OnQuestCancelled = Signal.new() local RoQuest = require(ReplicatedStorage.RoQuest).Server - RoQuest.OnQuestAvailable:Connect(function(questId: string) + RoQuest.OnQuestAvailable:Connect(function(player: Player, questId: string) print("The following quest just became available: ", RoQuest:GetQuest(player, questId).Name) end) ``` @@ -863,6 +901,8 @@ end @return () ]=] function RoQuestServer:SetPlayerData(player: Player, data: PlayerQuestData): () + self:_WaitForPlayerToLoad(player) + self._PlayerQuestData[player] = data self:_LoadPlayerData(player) @@ -1379,6 +1419,7 @@ function RoQuestServer:_QuestBecameAvailable(questId: string): () end self._StaticAvailableQuests[questId] = true -- Should give to players if possible + self.OnTimeQuestAvailable:Fire(questId) for player: Player in self._Quests do task.delay(0, self._NewPlayerAvailableQuest, self, player, questId) @@ -1402,6 +1443,7 @@ function RoQuestServer:_QuestBecameUnavailable(questId: string): () end self._StaticAvailableQuests[questId] = nil + self.OnTimeQuestUnavailable:Fire(questId) for player: Player in self._Quests do self:_NewPlayerAvailableQuest(player, questId) From cce0bcdee2b74513962c3444b46d34e7ae06e47d Mon Sep 17 00:00:00 2001 From: prooheckcp <61127277+prooheckcp@users.noreply.github.com> Date: Wed, 12 Jun 2024 14:18:56 +0100 Subject: [PATCH 02/15] Adding GetAvailableStaticQuests --- RoQuest/Server/init.lua | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/RoQuest/Server/init.lua b/RoQuest/Server/init.lua index 8a22ab6..43694d7 100644 --- a/RoQuest/Server/init.lua +++ b/RoQuest/Server/init.lua @@ -652,6 +652,29 @@ function RoQuestServer:GetStaticQuest(questId: string): Quest? return quest end +--[=[ + Gets all the available static quests + + ```lua + local ReplicatedStorage = game:GetService("ReplicatedStorage") + + local RoQuest = require(ReplicatedStorage.RoQuest).Server + + local quest: {[string]: Quest} = RoQuest:GetAvailableStaticQuests() + ``` + + @return {[string]: Quest} +]=] +function RoQuestServer:GetAvailableStaticQuests(): {[string]: Quest} + local quests: {[string]: Quest} = {} + + for questId: string in self._StaticAvailableQuests do + quests[questId] = self:GetStaticQuest(questId) + end + + return quests +end + --[=[ Gets the static data of all of the cached quests From e50a7575be5e6a1f65b9ba92595a7a2fabfa52d7 Mon Sep 17 00:00:00 2001 From: prooheckcp <61127277+prooheckcp@users.noreply.github.com> Date: Wed, 12 Jun 2024 14:26:24 +0100 Subject: [PATCH 03/15] Adding OnQuestObjectiveCompleted --- RoQuest/Shared/Classes/Quest.lua | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/RoQuest/Shared/Classes/Quest.lua b/RoQuest/Shared/Classes/Quest.lua index b5cc876..f4d0415 100644 --- a/RoQuest/Shared/Classes/Quest.lua +++ b/RoQuest/Shared/Classes/Quest.lua @@ -60,6 +60,19 @@ local NO_OBJECTIVE: string = "There is no ObjectiveId %s in the Quest %s" local Quest = {} Quest.__index = Quest Quest.__type = "Quest" +--[=[ + Called whenever a quest objective gets completed + + ```lua + quest.OnQuestObjectiveCompleted:Connect(function(objectiveId: string) + print("Completed Objective: " .. objectiveId) + end) + ``` + + @prop OnQuestObjectiveCompleted Signal + @within Quest +]=] +Quest.OnQuestObjectiveCompleted = newproxy() :: Signal --[=[ Called whenever one of the quests objective changes the value @@ -265,6 +278,7 @@ Quest._Trove = newproxy() :: Trove function Quest.new(properties: {[string]: any}): Quest properties = properties or {} local self: Quest = assertProperties(properties, Quest) + self.OnQuestObjectiveCompleted = Signal.new() self.OnQuestObjectiveChanged = Signal.new() self.OnQuestCompleted = Signal.new() self.OnQuestDelivered = Signal.new() @@ -288,6 +302,8 @@ function Quest.new(properties: {[string]: any}): Quest LastCompletedTick = 0, }) self._Trove = Trove.new() + self._Trove:Add(self.OnQuestObjectiveCompleted) + self._Trove:Add(self.OnQuestObjectiveChanged) self._Trove:Add(self.OnQuestCompleted) self._Trove:Add(self.OnQuestDelivered) self._Trove:Add(self.OnQuestCanceled) @@ -564,6 +580,7 @@ function Quest:_SetQuestProgress(newQuestProgress: QuestProgress): () newQuestObjective._QuestObjectiveProgress = questObjectiveProgress newQuestObjective.Completed:Connect(function() + self.OnQuestObjectiveCompleted:Fire(objectiveId) self:_CheckProgress() end) From 65794b9f8175eabf5ef6f79366a5d33c5427312d Mon Sep 17 00:00:00 2001 From: prooheckcp <61127277+prooheckcp@users.noreply.github.com> Date: Wed, 12 Jun 2024 14:50:10 +0100 Subject: [PATCH 04/15] Fix GetTimeForAvailable; Add GetTimeForUnavailable --- RoQuest/Shared/Classes/Quest.lua | 24 +++++++++++++++++++++++- wally.toml | 2 +- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/RoQuest/Shared/Classes/Quest.lua b/RoQuest/Shared/Classes/Quest.lua index f4d0415..73c8b2d 100644 --- a/RoQuest/Shared/Classes/Quest.lua +++ b/RoQuest/Shared/Classes/Quest.lua @@ -391,7 +391,29 @@ end @return number ]=] function Quest:GetTimeForAvailable(): number - return math.max(0, workspace:GetServerTimeNow() - self:GetQuestStart()) + local serverTime: number = workspace:GetServerTimeNow() + + if serverTime < self:GetQuestStart() then + return self:GetQuestStart() - serverTime + end + + return 0 +end + +--[=[ + Will return how long until the quest becomes unavailable. + It will return 0 if it is already unavailable + + @return number +]=] +function Quest:GetTimeForUnavailable(): number + local serverTime: number = workspace:GetServerTimeNow() + + if serverTime < self:GetQuestEnd() then + return self:GetQuestEnd() - serverTime + end + + return 0 end --[=[ diff --git a/wally.toml b/wally.toml index 6086c8f..448a253 100644 --- a/wally.toml +++ b/wally.toml @@ -1,7 +1,7 @@ [package] name = "prooheckcp/roquest" description = "" -version = "0.1.0" +version = "0.1.1" license = "MIT" registry = "https://github.com/UpliftGames/wally-index" realm = "shared" From 40a0135dcd53f458aed4f1ccc471161d7f5014fc Mon Sep 17 00:00:00 2001 From: prooheckcp <61127277+prooheckcp@users.noreply.github.com> Date: Wed, 12 Jun 2024 15:45:47 +0100 Subject: [PATCH 05/15] Adding OnQuestUnavailable on Client --- RoQuest/Client/init.lua | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/RoQuest/Client/init.lua b/RoQuest/Client/init.lua index a604d91..5f9dea5 100644 --- a/RoQuest/Client/init.lua +++ b/RoQuest/Client/init.lua @@ -195,6 +195,25 @@ RoQuestClient.OnQuestCancelled = Signal.new() -- Event(questId: string) @within RoQuestClient ]=] RoQuestClient.OnQuestAvailable = Signal.new() +--[=[ + This gets called when a quest becomes unavailable. Usually only happens when a quest + gets disabled at run-time or when the quest's end time has passed + + ```lua + local ReplicatedStorage = game:GetService("ReplicatedStorage") + + local RoQuest = require(ReplicatedStorage.RoQuest).Server + + RoQuest.OnQuestUnavailable:Connect(function(questId: string) + print("The player's quest has just been cancelled: ", RoQuest:GetStaticQuest(questId).Name) + end) + ``` + + @client + @prop OnQuestUnavailable Signal + @within RoQuestClient +]=] +RoQuestClient.OnQuestUnavailable = Signal.new() --[=[ This gets called whenever the quests that are unavailable changes. This means that either a quest just became available OR that a quest became @@ -1129,6 +1148,8 @@ function RoQuestClient:_ChangeAvailableState(questId: string, state: true?): () if state then self.OnQuestAvailable:Fire(questId) + else + self.OnQuestUnavailable:Fire(questId) end end From 119c79d305904b7faa280b4f8deb57de5f4ab898 Mon Sep 17 00:00:00 2001 From: prooheckcp <61127277+prooheckcp@users.noreply.github.com> Date: Thu, 13 Jun 2024 15:21:37 +0100 Subject: [PATCH 06/15] Fixing Quest:IsObjectiveCompleted --- RoQuest/Shared/Classes/Quest.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/RoQuest/Shared/Classes/Quest.lua b/RoQuest/Shared/Classes/Quest.lua index 73c8b2d..c3c1cb7 100644 --- a/RoQuest/Shared/Classes/Quest.lua +++ b/RoQuest/Shared/Classes/Quest.lua @@ -320,7 +320,7 @@ end @return boolean ]=] function Quest:IsObjectiveCompleted(objectiveId: string): boolean - return self:GetObjective(objectiveId) == self:GetTargetObjective() + return self:GetObjective(objectiveId) == self:GetTargetObjective(objectiveId) end --[=[ @@ -482,7 +482,7 @@ function Quest:GetObjective(objectiveId: number): number end --[=[ - Gets teh target objective by the id + Gets the target objective by the id @param objectiveId string From c0b142d229999af4b54606207294de5768530e00 Mon Sep 17 00:00:00 2001 From: prooheckcp <61127277+prooheckcp@users.noreply.github.com> Date: Thu, 13 Jun 2024 16:17:26 +0100 Subject: [PATCH 07/15] Adding Quest:GetQuestObjectivesCompletedCount and Quest:GetQuestObjectivesCount --- RoQuest/Shared/Classes/Quest.lua | 34 ++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/RoQuest/Shared/Classes/Quest.lua b/RoQuest/Shared/Classes/Quest.lua index c3c1cb7..5326d18 100644 --- a/RoQuest/Shared/Classes/Quest.lua +++ b/RoQuest/Shared/Classes/Quest.lua @@ -498,6 +498,40 @@ function Quest:GetTargetObjective(objectiveId: string): number return questObjective:GetTargetProgress() end +--[=[ + Returns a number with the amount of objectives that exist within + this quest + + @return number +]=] +function Quest:GetQuestObjectivesCount(): number + local counter: number = 0 + + for _ in self:GetQuestObjectives() do + counter += 1 + end + + return counter +end + +--[=[ + Returns a number with the amount of **completed** objectives that exist within + this quest + + @return number +]=] +function Quest:GetQuestObjectivesCompletedCount(): number + local counter: number = 0 + + for _, questObjective: QuestObjective in self:GetQuestObjectives() do + if questObjective:IsCompleted() then + counter += 1 + end + end + + return counter +end + --[=[ Returns an array of quest objectives for this given quest From 7ecc478719cc2af3a3f207ebe69b2b957d73b160 Mon Sep 17 00:00:00 2001 From: prooheckcp <61127277+prooheckcp@users.noreply.github.com> Date: Fri, 14 Jun 2024 11:44:20 +0100 Subject: [PATCH 08/15] Update QuestLifeCycle.lua --- RoQuest/Shared/Classes/QuestLifeCycle.lua | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/RoQuest/Shared/Classes/QuestLifeCycle.lua b/RoQuest/Shared/Classes/QuestLifeCycle.lua index 49aed83..993d155 100644 --- a/RoQuest/Shared/Classes/QuestLifeCycle.lua +++ b/RoQuest/Shared/Classes/QuestLifeCycle.lua @@ -61,25 +61,29 @@ type Quest = { -- Fake quest type for autocomplete candy Name = "AppleQuest", } - function appleQuest:OnAvailable() - print("AppleQuest is now available!") + function appleQuest:OnInit() + print("AppleQuest OnInit") end - function appleQuest:OnStarted() + function appleQuest:OnStart() print("AppleQuest has been started!") end - function appleQuest:OnCompleted() + function appleQuest:OnComplete() print("AppleQuest has been completed!") end - function appleQuest:OnDelivered() + function appleQuest:OnDeliver() print("AppleQuest has been delivered!") end - function appleQuest:OnObjectiveChanged(objectiveId: string, newAmount: number) + function appleQuest:OnObjectiveChange(objectiveId: string, newAmount: number) print("Objective " .. objectiveId .. " has been updated to " .. newAmount) end + + function appleQuest:OnDestroy() + print("AppleQuest has been destroyed!") + end ``` ]=] From d30710c067f1b3db34daf86ca74f8c6a35152374 Mon Sep 17 00:00:00 2001 From: prooheckcp <61127277+prooheckcp@users.noreply.github.com> Date: Sat, 15 Jun 2024 22:15:04 +0100 Subject: [PATCH 09/15] Error message for SetPlayerData --- RoQuest/Server/init.lua | 5 +++++ RoQuest/Shared/Data/WarningMessages.lua | 1 + default.project.json | 29 +++++++++++++++++++++++-- default2.project.json | 29 ------------------------- default3.project.json | 4 ++++ src/ServerScriptService/main.server.lua | 17 +++++++++++---- 6 files changed, 50 insertions(+), 35 deletions(-) delete mode 100644 default2.project.json create mode 100644 default3.project.json diff --git a/RoQuest/Server/init.lua b/RoQuest/Server/init.lua index 43694d7..9435a94 100644 --- a/RoQuest/Server/init.lua +++ b/RoQuest/Server/init.lua @@ -926,6 +926,11 @@ end function RoQuestServer:SetPlayerData(player: Player, data: PlayerQuestData): () self:_WaitForPlayerToLoad(player) + if not data.InProgress or not data.Completed or not data.Delivered then + error(WarningMessages.SetPlayerData) + return + end + self._PlayerQuestData[player] = data self:_LoadPlayerData(player) diff --git a/RoQuest/Shared/Data/WarningMessages.lua b/RoQuest/Shared/Data/WarningMessages.lua index 2f3f5c1..9ef980b 100644 --- a/RoQuest/Shared/Data/WarningMessages.lua +++ b/RoQuest/Shared/Data/WarningMessages.lua @@ -6,4 +6,5 @@ return { DuplicateLifeCycleName = "Duplicate life cycle name %s found", NoObjectiveId = "No objective with the id %s exists in any of the loaded quests", NoLifeCycleMethod = "No method %s exists in the life cycle %s", + SetPlayerData = "When using RoQuest:SetPlayerData make sure to pass a PlayerQuestData struct\n\nlocal RoQuest = require(ReplicatedStorage.RoQuest).Server\nlocal PlayerQuestData = RoQuest.PlayerQuestData\nRoQuest:SetPlayerData(player, PlayerQuestData {})", } \ No newline at end of file diff --git a/default.project.json b/default.project.json index d0704be..cd01099 100644 --- a/default.project.json +++ b/default.project.json @@ -1,4 +1,29 @@ { - "name": "roquest", - "tree": {"$path":"RoQuest"} + "name": "RoQuest", + "tree": { + "$className": "DataModel", + + "RoQuest":{ + "$path": "RoQuest" + }, + + "ReplicatedStorage": { + "$path": "src/ReplicatedStorage", + "RoQuest":{ + "$path": "RoQuest" + } + }, + + "ServerScriptService": { + "Server": { + "$path": "src/ServerScriptService" + } + }, + + "StarterPlayer": { + "StarterPlayerScripts": { + "$path": "src/StarterPlayerScripts" + } + } + } } \ No newline at end of file diff --git a/default2.project.json b/default2.project.json deleted file mode 100644 index cd01099..0000000 --- a/default2.project.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "name": "RoQuest", - "tree": { - "$className": "DataModel", - - "RoQuest":{ - "$path": "RoQuest" - }, - - "ReplicatedStorage": { - "$path": "src/ReplicatedStorage", - "RoQuest":{ - "$path": "RoQuest" - } - }, - - "ServerScriptService": { - "Server": { - "$path": "src/ServerScriptService" - } - }, - - "StarterPlayer": { - "StarterPlayerScripts": { - "$path": "src/StarterPlayerScripts" - } - } - } -} \ No newline at end of file diff --git a/default3.project.json b/default3.project.json new file mode 100644 index 0000000..d0704be --- /dev/null +++ b/default3.project.json @@ -0,0 +1,4 @@ +{ + "name": "roquest", + "tree": {"$path":"RoQuest"} +} \ No newline at end of file diff --git a/src/ServerScriptService/main.server.lua b/src/ServerScriptService/main.server.lua index 4ed8b60..d715add 100644 --- a/src/ServerScriptService/main.server.lua +++ b/src/ServerScriptService/main.server.lua @@ -5,6 +5,7 @@ local DataStoreService = game:GetService("DataStoreService") local RoQuest = require(ReplicatedStorage.RoQuest).Server local questsStore = DataStoreService:GetDataStore("PlayerQuests") +local PlayerQuestData = RoQuest.PlayerQuestData RoQuest:Init( RoQuest:LoadDirectory(ReplicatedStorage.Quests), @@ -17,15 +18,23 @@ RoQuest.OnStart():andThen(function() return questsStore:GetAsync("player_"..player.UserId) end) - print("Joined", playerData) + + + print(PlayerQuestData { + InProgress = {}, + Completed = {}, + Delivered = {}, + }) + + print(PlayerQuestData {}) task.delay(1, function() print("After 1 sec", RoQuest:GetPlayerData(player)) end) - if playerData then -- Set the data on RoQuest - --RoQuest:SetPlayerData(player, playerData) - end + --if playerData then -- Set the data on RoQuest + RoQuest:SetPlayerData(player, {}) + --end end local function playerRemoved(player: Player) From cd8a64558fc38eee0fe6bfe8f2d622487d9bb871 Mon Sep 17 00:00:00 2001 From: prooheckcp <61127277+prooheckcp@users.noreply.github.com> Date: Sat, 15 Jun 2024 22:51:15 +0100 Subject: [PATCH 10/15] Fixing Client data overriding --- RoQuest/Client/init.lua | 1 + .../LifeCycles/Server/CornQuest.lua | 20 ---------------- src/ServerScriptService/main.server.lua | 23 +++++-------------- .../Interface/QuestLog.lua | 4 ++++ 4 files changed, 11 insertions(+), 37 deletions(-) diff --git a/RoQuest/Client/init.lua b/RoQuest/Client/init.lua index 5f9dea5..4da22ee 100644 --- a/RoQuest/Client/init.lua +++ b/RoQuest/Client/init.lua @@ -978,6 +978,7 @@ end @return () ]=] function RoQuestClient:_OnPlayerDataChanged(playerQuestData: PlayerQuestData) + self._Quests = {} self._PlayerQuestData = playerQuestData for questId: string, questProgress: QuestProgress in playerQuestData.InProgress do diff --git a/src/ReplicatedStorage/LifeCycles/Server/CornQuest.lua b/src/ReplicatedStorage/LifeCycles/Server/CornQuest.lua index 8302f63..662a761 100644 --- a/src/ReplicatedStorage/LifeCycles/Server/CornQuest.lua +++ b/src/ReplicatedStorage/LifeCycles/Server/CornQuest.lua @@ -10,24 +10,4 @@ local CornQuest: QuestLifeCycle = QuestLifeCycle { Name = "CornQuest", } -function CornQuest:OnInit() - -end - -function CornQuest:OnStart() - self.Quest:AddObjective("Corn", 100) - task.delay(1, function() - print("Delayed set!") - --self.Quest:AddObjective("Corn", 100) - end) -end - -function CornQuest:OnComplete() - print("Completed corn!") -end - -function CornQuest:OnDeliver() - print("OnDeliver") -end - return CornQuest \ No newline at end of file diff --git a/src/ServerScriptService/main.server.lua b/src/ServerScriptService/main.server.lua index d715add..deac415 100644 --- a/src/ServerScriptService/main.server.lua +++ b/src/ServerScriptService/main.server.lua @@ -17,24 +17,13 @@ RoQuest.OnStart():andThen(function() local success, playerData = pcall(function() return questsStore:GetAsync("player_"..player.UserId) end) - - - - print(PlayerQuestData { - InProgress = {}, - Completed = {}, - Delivered = {}, - }) - - print(PlayerQuestData {}) - task.delay(1, function() - print("After 1 sec", RoQuest:GetPlayerData(player)) - end) - - --if playerData then -- Set the data on RoQuest - RoQuest:SetPlayerData(player, {}) - --end + if playerData then -- Set the data on RoQuest + task.delay(2, function() + print("[test] Set player data!", playerData) + RoQuest:SetPlayerData(player, playerData) + end) + end end local function playerRemoved(player: Player) diff --git a/src/StarterPlayerScripts/Interface/QuestLog.lua b/src/StarterPlayerScripts/Interface/QuestLog.lua index 598bed7..9870be5 100644 --- a/src/StarterPlayerScripts/Interface/QuestLog.lua +++ b/src/StarterPlayerScripts/Interface/QuestLog.lua @@ -146,6 +146,10 @@ function QuestLog:Init() RoQuest.OnPlayerDataChanged:Connect(function() self:SetAllScreens() + + task.delay(2, function() + print("[test] with delay", RoQuest:GetQuests()) + end) end) -- Hard reset our screens end From ab38cf597ca9a607192dbeb068105a20fb0c2c8f Mon Sep 17 00:00:00 2001 From: prooheckcp <61127277+prooheckcp@users.noreply.github.com> Date: Sun, 16 Jun 2024 01:34:05 +0100 Subject: [PATCH 11/15] Reworking server and client structure --- RoQuest/Client/init.lua | 9 +- RoQuest/Server/init.lua | 374 ++++++++++++++++-- RoQuest/Shared/Data/WarningMessages.lua | 1 + .../LifeCycles/Client/AppleQuest.lua | 10 +- src/ServerScriptService/main.server.lua | 29 +- .../Interface/QuestLog.lua | 4 - src/StarterPlayerScripts/Interface/Quests.lua | 1 - 7 files changed, 376 insertions(+), 52 deletions(-) diff --git a/RoQuest/Client/init.lua b/RoQuest/Client/init.lua index 4da22ee..72b3ff5 100644 --- a/RoQuest/Client/init.lua +++ b/RoQuest/Client/init.lua @@ -530,7 +530,6 @@ function RoQuestClient:Init(lifeCycles: {QuestLifeCycle}?): () end self:_OnPlayerDataChanged(net:Call("GetPlayerData"):Await()) - net:On("OnPlayerDataChanged", function(playerQuestData: PlayerQuestData) self:_OnPlayerDataChanged(playerQuestData) end) @@ -980,7 +979,7 @@ end function RoQuestClient:_OnPlayerDataChanged(playerQuestData: PlayerQuestData) self._Quests = {} self._PlayerQuestData = playerQuestData - + print("[test] On Data Changed: ", playerQuestData) for questId: string, questProgress: QuestProgress in playerQuestData.InProgress do self:_GiveQuest(questId, questProgress) end @@ -992,7 +991,7 @@ function RoQuestClient:_OnPlayerDataChanged(playerQuestData: PlayerQuestData) for questId: string, questProgress: QuestProgress in playerQuestData.Delivered do self:_GiveQuest(questId, questProgress) end - + self.OnPlayerDataChanged:Fire(playerQuestData) end @@ -1298,7 +1297,9 @@ function RoQuestClient:_GiveQuest(questId: string, questProgress: QuestProgress? self:_ChangeDeliveredQuest(questId, nil) self._Quests[questId] = questClone - self:_ChangeInProgressQuest(questId, questClone:_GetQuestProgress()) + if STATUS_CHANGED_REFERENCE[questClone:GetQuestStatus()] then + self[STATUS_CHANGED_REFERENCE[questClone:GetQuestStatus()]](self, questId, questClone:_GetQuestProgress()) + end return true end diff --git a/RoQuest/Server/init.lua b/RoQuest/Server/init.lua index 9435a94..eba06f1 100644 --- a/RoQuest/Server/init.lua +++ b/RoQuest/Server/init.lua @@ -38,6 +38,12 @@ type Trove = Trove.Trove -- We want to give enough time for developers to get and save their player data local DATA_RELEASE_DELAY: number = 5 +local WAITING_TIMEOUT: number = 5 +local STATUS_CHANGED_REFERENCE: {[QuestStatus]: string} = { + [QuestStatus.InProgress] = "_ChangeInProgressQuest", + [QuestStatus.Completed] = "_ChangeCompletedQuest", + [QuestStatus.Delivered] = "_ChangeDeliveredQuest", +} --[=[ @class RoQuestServer @@ -241,6 +247,104 @@ RoQuestServer.OnQuestAvailable = Signal.new() @within RoQuestServer ]=] RoQuestServer.OnQuestUnavailable = Signal.new() -- Event (player: Player, questId: string) +--[=[ + This gets called whenever the quests that are unavailable changes. + This means that either a quest just became available OR that a quest became + unavailable (such as a quest with an end time) + + ```lua + local ReplicatedStorage = game:GetService("ReplicatedStorage") + + local RoQuest = require(ReplicatedStorage.RoQuest).Server + + RoQuest.OnUnAvailableQuestChanged:Connect(function(player: Player) + print(self:GetUnAvailableQuests(player)) + end) + ``` + + @server + @prop OnUnAvailableQuestChanged Signal + @within RoQuestServer +]=] +RoQuestServer.OnUnAvailableQuestChanged = Signal.new() +--[=[ + This gets called whenever the quests that are available changes. + Called when one of the available quests becomes unavailable or when a quest + gets started by the player + + ```lua + local ReplicatedStorage = game:GetService("ReplicatedStorage") + + local RoQuest = require(ReplicatedStorage.RoQuest).Server + + RoQuest.OnAvailableQuestChanged:Connect(function(player: Player) + print(self:GetAvailableQuests(player)) + end) + ``` + + @server + @prop OnAvailableQuestChanged Signal + @within RoQuestServer +]=] +RoQuestServer.OnAvailableQuestChanged = Signal.new() +--[=[ + This gets called whenever the quests that are completed changes. + This gets called when either a quest got delivered, a quest just got completed + or somehow the quest got cancelled while completed + + ```lua + local ReplicatedStorage = game:GetService("ReplicatedStorage") + + local RoQuest = require(ReplicatedStorage.RoQuest).Server + + RoQuest.OnCompletedQuestChanged:Connect(function(player: Player) + print(self:GetCompletedQuests(player)) + end) + ``` + + @server + @prop OnCompletedQuestChanged Signal + @within RoQuestServer +]=] +RoQuestServer.OnCompletedQuestChanged = Signal.new() +--[=[ + This gets called whenever the quests that are delivered changes. + This gets called when either a quest got delivered or a delivered quest gets restarted + + ```lua + local ReplicatedStorage = game:GetService("ReplicatedStorage") + + local RoQuest = require(ReplicatedStorage.RoQuest).Server + + RoQuest.OnDeliveredQuestChanged:Connect(function(player: Player) + print(self:GetDeliveredQuests(player)) + end) + ``` + + @server + @prop OnDeliveredQuestChanged Signal + @within RoQuestServer +]=] +RoQuestServer.OnDeliveredQuestChanged = Signal.new() +--[=[ + This gets called whenever the quests that are in progress change. + This gets called when either a quest got completed or started by the player + + ```lua + local ReplicatedStorage = game:GetService("ReplicatedStorage") + + local RoQuest = require(ReplicatedStorage.RoQuest).Server + + RoQuest.OnInProgressQuestChanged:Connect(function(player: Player) + print(self:GetInProgressQuests(player)) + end) + ``` + + @server + @prop OnInProgressQuestChanged Signal + @within RoQuestServer +]=] +RoQuestServer.OnInProgressQuestChanged = Signal.new() --[=[ This is a reference to our PlayerQuestData struct @@ -428,6 +532,15 @@ RoQuestServer._Troves = {} :: {[Player]: Trove} ]=] RoQuestServer._LifeCycles = {} :: {[Player]: {[string]: {[string]: QuestLifeCycle}}} +--[=[ + Caches whether a player has already loaded at least once or not + This allows us to properly wait for a player and avoid racing conditions + + @server + @private +]=] +RoQuestServer._LoadedChache = {} :: {[Player]: true?} + --[=[ This is one of the most important methods of this Module. It is used to ensure that your code is only called **after** the RoQuestServer has been initiated. @@ -568,7 +681,6 @@ function RoQuestServer:Init(quests: {Quest}, lifeCycles: {QuestLifeCycle}?): () return RoQuestServer._UnavailableQuests[player] end) - Players.PlayerAdded:Connect(function(player: Player) self:_PlayerAdded(player) end) @@ -721,7 +833,9 @@ end @return Quest? ]=] function RoQuestServer:GetQuest(player: Player, questId: string): Quest? - return self._Quests[player][questId] + self:_WaitForPlayerToLoad(player) + + return self:_GetQuest(player, questId) end --[=[ @@ -749,6 +863,8 @@ end @return {[string]: Quest} -- ]=] function RoQuestServer:GetQuests(player: Player): {[string]: Quest} + self:_WaitForPlayerToLoad(player) + return self._Quests[player] or {} end @@ -772,9 +888,11 @@ end @return {[string]: Quest} -- ]=] function RoQuestServer:GetCompletedQuests(player: Player): {[string]: Quest} + self:_WaitForPlayerToLoad(player) + local quests: {[string]: Quest} = {} - for questId: string in self:GetPlayerData(player).Completed do + for questId: string in self:_GetPlayerData(player).Completed do quests[questId] = self:GetQuest(player, questId) end @@ -801,13 +919,9 @@ end @return {[string]: Quest} -- ]=] function RoQuestServer:GetDeliveredQuests(player: Player): {[string]: Quest} - local quests: {[string]: Quest} = {} - - for questId: string in self:GetPlayerData(player).Delivered do - quests[questId] = self:GetQuest(player, questId) - end + self:_WaitForPlayerToLoad(player) - return quests + return self:_GetDeliveredQuests(player) end --[=[ @@ -830,9 +944,11 @@ end @return {[string]: Quest} -- ]=] function RoQuestServer:GetInProgressQuests(player: Player): {[string]: Quest} + self:_WaitForPlayerToLoad(player) + local quests: {[string]: Quest} = {} - for questId: string in self:GetPlayerData(player).InProgress do + for questId: string in self:_GetPlayerData(player).InProgress do quests[questId] = self:GetQuest(player, questId) end @@ -859,6 +975,8 @@ end @return {[string]: Quest} -- ]=] function RoQuestServer:GetAvailableQuests(player: Player): {[string]: Quest} + self:_WaitForPlayerToLoad(player) + local quests: {[string]: Quest} = {} for questId: string in self._AvailableQuests[player] do @@ -888,6 +1006,8 @@ end @return {[string]: Quest} -- ]=] function RoQuestServer:GetUnAvailableQuests(player: Player): {[string]: Quest} + self:_WaitForPlayerToLoad(player) + local quests: {[string]: Quest} = {} for questId: string in self._UnavailableQuests[player] do @@ -956,7 +1076,9 @@ end @return PlayerQuestData ]=] function RoQuestServer:GetPlayerData(player: Player): PlayerQuestData - return self._PlayerQuestData[player] or PlayerQuestData {} + self:_WaitForPlayerToLoad(player) + + return self:_GetPlayerData(player) end --[=[ @@ -980,6 +1102,8 @@ end @return number ]=] function RoQuestServer:GetObjective(player: Player, questId: string, objectiveId: string): number + self:_WaitForPlayerToLoad(player) + local quest: Quest? = self:GetQuest(player, questId) if not quest then @@ -1010,6 +1134,8 @@ end @return () ]=] function RoQuestServer:AddObjective(player: Player, objectiveId: string, amount: number): () + self:_WaitForPlayerToLoad(player) + if not self._PlayerQuestData[player] then return end @@ -1048,6 +1174,8 @@ end @return () ]=] function RoQuestServer:SetObjective(player: Player, objectiveId: string, amount: number): () + self:_WaitForPlayerToLoad(player) + if not self._PlayerQuestData[player] then return end @@ -1084,6 +1212,8 @@ end @return () ]=] function RoQuestServer:RemoveObjective(player: Player, objectiveId: string, amount: number): () + self:_WaitForPlayerToLoad(player) + if not self._PlayerQuestData[player] then return end @@ -1155,6 +1285,8 @@ end @return boolean -- If it managed to complete the quest or not ]=] function RoQuestServer:CompleteQuest(player: Player, questId: string): boolean + self:_WaitForPlayerToLoad(player) + local quest: Quest? = self:GetQuest(player, questId) if not quest then @@ -1185,6 +1317,8 @@ end @return boolean -- If it managed to deliver the quest or not ]=] function RoQuestServer:DeliverQuest(player: Player, questId: string) + self:_WaitForPlayerToLoad(player) + local quest: Quest? = self:GetQuest(player, questId) if not quest then @@ -1215,6 +1349,8 @@ end @return boolean -- If it managed to cancel the quest or not ]=] function RoQuestServer:CancelQuest(player: Player, questId: string): boolean + self:_WaitForPlayerToLoad(player) + local quest: Quest? = self:GetQuest(player, questId) if not quest or quest:GetQuestStatus() == QuestStatus.Delivered then @@ -1223,7 +1359,9 @@ function RoQuestServer:CancelQuest(player: Player, questId: string): boolean quest.OnQuestCanceled:Fire() self._Quests[player][questId] = nil - self._PlayerQuestData[player][quest:GetQuestStatus()][questId] = nil + if STATUS_CHANGED_REFERENCE[quest:GetQuestStatus()] then + self[STATUS_CHANGED_REFERENCE[quest:GetQuestStatus()]](self, questId, nil) + end quest:Destroy() self.OnQuestCancelled:Fire(player, questId) task.defer(self._NewPlayerAvailableQuest, self, player, questId) @@ -1263,13 +1401,13 @@ function RoQuestServer:CanGiveQuest(player: Player, questId: string): boolean return false end - local currentQuest: Quest? = self:GetQuest(player, questId) + local currentQuest: Quest? = self:_GetQuest(player, questId) for _, requiredQuestId: string in quest.RequiredQuests do if not self._PlayerQuestData[player].Delivered[requiredQuestId] then return false end - local requiredQuest: Quest? = self:GetQuest(player, requiredQuestId) + local requiredQuest: Quest? = self:_GetQuest(player, requiredQuestId) if currentQuest and @@ -1302,6 +1440,8 @@ end @return () ]=] function RoQuestServer:MakeQuestAvailable(player: Player, questId: string): () + self:_WaitForPlayerToLoad(player) + local quest: Quest? = self:GetQuest(player, questId) if not quest or quest:GetQuestStatus() ~= QuestStatus.Delivered then @@ -1332,6 +1472,8 @@ end @return QuestStatus ]=] function RoQuestServer:GetQuestStatus(player: Player, questId: string): QuestStatus + self:_WaitForPlayerToLoad(player) + local quest: Quest? = self:GetQuest(player, questId) if not quest then @@ -1376,8 +1518,8 @@ function RoQuestServer:_QuestCompleted(player: Player, questId: string): () return end - self._PlayerQuestData[player].InProgress[questId] = nil - self._PlayerQuestData[player].Completed[questId] = quest:_GetQuestProgress() + self:_ChangeInProgressQuest(player, questId, nil) + self:_ChangeCompletedQuest(player, questId, quest:_GetQuestProgress()) end --[=[ @@ -1397,8 +1539,8 @@ function RoQuestServer:_QuestDelivered(player: Player, questId: string): () return end - self._PlayerQuestData[player].Completed[questId] = nil - self._PlayerQuestData[player].Delivered[questId] = quest:_GetQuestProgress() + self:_ChangeCompletedQuest(player, questId, nil) + self:_ChangeDeliveredQuest(player, questId, quest:_GetQuestProgress()) if self._RequiredQuestPointer[questId] then for requiredQuestId: string in self._RequiredQuestPointer[questId] do @@ -1427,8 +1569,15 @@ end @return () ]=] function RoQuestServer:_WaitForPlayerToLoad(player: Player): () - while not self._PlayerQuestData[player] and player.Parent == Players do -- Wait for player to load - task.wait() + local timer: number = 0 + + while not self._LoadedChache[player] and player.Parent == Players do -- Wait for player to load + timer += task.wait() + + if timer > WAITING_TIMEOUT then + warn(WarningMessages.WaitForLoad:format(debug.traceback())) + break + end end end @@ -1478,6 +1627,111 @@ function RoQuestServer:_QuestBecameUnavailable(questId: string): () end end +--[=[ + Called whenever we need to update the status of a quest that was available + + @server + @private + + @param player Player + @param questId string + @param state true? + + @return () +]=] +function RoQuestServer:_ChangeAvailableState(player: Player, questId: string, state: true?): () + if not self._AvailableQuests[player] or self._AvailableQuests[player][questId] == state then + return + end + + self._AvailableQuests[player][questId] = state + self.OnAvailableQuestChanged:Fire(player, questId, state) +end + +--[=[ + Called whenever we need to update the status of a quest that was unavailable + + @server + @private + + @param player Player + @param questId string + @param state true? + + @return () +]=] +function RoQuestServer:_ChangeUnAvailableState(player: Player, questId: string, state: true?): () + if not self._UnavailableQuests[player] or self._UnavailableQuests[player][questId] == state then + return + end + + self._UnavailableQuests[player][questId] = state + self.OnUnAvailableQuestChanged:Fire(player, questId, state) +end + +--[=[ + Called whenever we need to update the progress of a quest that was completed + + @server + @private + + @parma player Player + @param questId string + @param questProgress QuestProgress? + + @return () +]=] +function RoQuestServer:_ChangeCompletedQuest(player: Player, questId: string, questProgress: QuestProgress?): () + if not self._PlayerQuestData[player] or self._PlayerQuestData[player].Completed[questId] == questProgress then + return + end + + self._PlayerQuestData[player].Completed[questId] = questProgress + self.OnCompletedQuestChanged:Fire(player, questId) +end + +--[=[ + Called whenever we need to update the progress of a quest that was delivered + + @server + @private + + @param player Player + @param questId string + @param questProgress QuestProgress? + + @return () +]=] +function RoQuestServer:_ChangeDeliveredQuest(player: Player, questId: string, questProgress: QuestProgress?): () + if not self._PlayerQuestData[player] or self._PlayerQuestData[player].Delivered[questId] == questProgress then + return + end + + self._PlayerQuestData[player].Delivered[questId] = questProgress + self.OnDeliveredQuestChanged:Fire(player, questId) +end + +--[=[ + Called whenever we need to update the progress of a quest that is in progress + + @server + @private + + @param player Player + @param questId string + @param questProgress QuestProgress? + + @return () +]=] +function RoQuestServer:_ChangeInProgressQuest(player: Player, questId: string, questProgress: QuestProgress?): () + if not self._PlayerQuestData[player] or self._PlayerQuestData[player].InProgress[questId] == questProgress then + return + end + + self._PlayerQuestData[player].InProgress[questId] = questProgress + self.OnInProgressQuestChanged:Fire(player, questId) +end + --[=[ If possible we'll give the quest to the player @@ -1490,6 +1744,10 @@ end @return boolean -- If it managed to give the quest to the player or not ]=] function RoQuestServer:_GiveQuest(player: Player, questId: string, questProgress: QuestProgress?): boolean + while not self._PlayerQuestData[player] and player.Parent == Players do -- Wait for player to load + task.wait() + end + if not self:CanGiveQuest(player, questId) then return false end @@ -1519,7 +1777,7 @@ function RoQuestServer:_GiveQuest(player: Player, questId: string, questProgress end if not questProgress then - local quest: Quest? = self:GetQuest(player, questId) + local quest: Quest? = self:_GetQuest(player, questId) if quest then -- We are repeating the quest!!! questProgress = quest:_GetQuestProgress() @@ -1546,13 +1804,13 @@ function RoQuestServer:_GiveQuest(player: Player, questId: string, questProgress }) end - - self._AvailableQuests[player][questId] = nil + self:_ChangeAvailableState(player, questId, nil) self._Quests[player][questId] = questClone - self._PlayerQuestData[player].Delivered[questId] = nil - self._PlayerQuestData[player][questClone:GetQuestStatus()][questId] = questClone:_GetQuestProgress() + self:_ChangeDeliveredQuest(player, questId, nil) + if STATUS_CHANGED_REFERENCE[questClone:GetQuestStatus()] then + self[STATUS_CHANGED_REFERENCE[questClone:GetQuestStatus()]](self, player, questId, questClone:_GetQuestProgress()) + end self._Troves[player]:Add(questClone) - for _, lifeCycleName: string in questClone.LifeCycles do self:_CreateLifeCycle(player, questClone, lifeCycleName) end @@ -1560,6 +1818,52 @@ function RoQuestServer:_GiveQuest(player: Player, questId: string, questProgress return true end +--[=[ + Gets the delivered quests from the player and returns them + + @private + @server + @param player Player + + @return {[string]: Quest} +]=] +function RoQuestServer:_GetDeliveredQuests(player: Player): {[string]: Quest} + local quests: {[string]: Quest} = {} + + for questId: string in self:_GetPlayerData(player).Delivered do + quests[questId] = self:GetQuest(player, questId) + end + + return quests +end + +--[=[ + Gets the given quest from the player + + @private + @server + @param player Player + @param questId string + + @return Quest? +]=] +function RoQuestServer:_GetQuest(player: Player, questId: string): Quest? + return self._Quests[player][questId] +end + +--[=[ + Gets the player data + + @private + @server + @param player Player + + @return PlayerQuestData +]=] +function RoQuestServer:_GetPlayerData(player: Player): PlayerQuestData + return self._PlayerQuestData[player] or PlayerQuestData {} +end + --[=[ Loads all the quests for the given player @@ -1572,8 +1876,8 @@ end function RoQuestServer:_LoadPlayerData(player: Player): () self._Quests[player] = {} -- Reset our player quest self._Troves[player]:Clean() - - for _questStatus, questArray: {[string]: QuestProgress} in self:GetPlayerData(player) do + + for _questStatus, questArray: {[string]: QuestProgress} in self._PlayerQuestData[player] do for questId: string, questProgress: QuestProgress in questArray do self:_GiveQuest(player, questId, questProgress) end @@ -1583,7 +1887,7 @@ function RoQuestServer:_LoadPlayerData(player: Player): () self:_NewPlayerAvailableQuest(player, questId) end - for _, quest: Quest in self:GetDeliveredQuests(player) do + for _, quest: Quest in self:_GetDeliveredQuests(player) do if quest.QuestRepeatableType ~= QuestRepeatableType.NonRepeatable then local timeForAvailable: number = TimeRequirement[quest.QuestRepeatableType] @@ -1591,7 +1895,7 @@ function RoQuestServer:_LoadPlayerData(player: Player): () end end - self.OnPlayerDataChanged:Fire(player, self:GetPlayerData(player)) + self.OnPlayerDataChanged:Fire(player, self._PlayerQuestData[player]) end --[=[ @@ -1612,9 +1916,9 @@ function RoQuestServer:_NewPlayerAvailableQuest(player: Player, questId: string) end if not self:CanGiveQuest(player, questId) then - if not self:GetQuest(player, questId) then + if not self:_GetQuest(player, questId) then if not self._UnavailableQuests[player][questId] then - self._UnavailableQuests[player][questId] = true + self:_ChangeUnAvailableState(player, questId, true) self.OnQuestUnavailable:Fire(player, questId) end end @@ -1622,14 +1926,14 @@ function RoQuestServer:_NewPlayerAvailableQuest(player: Player, questId: string) end if self._UnavailableQuests[player][questId] then - self._UnavailableQuests[player][questId] = nil + self:_ChangeUnAvailableState(player, questId, nil) end if quest.QuestAcceptType == QuestAcceptType.Automatic then self.OnQuestAvailable:Fire(player, questId) self:GiveQuest(player, questId) elseif not self._AvailableQuests[player][questId] then - self._AvailableQuests[player][questId] = true + self:_ChangeAvailableState(player, questId, true) self.OnQuestAvailable:Fire(player, questId) end end @@ -1819,6 +2123,7 @@ function RoQuestServer:_PlayerAdded(player: Player): () self._PlayerQuestData[player] = PlayerQuestData {} self:_LoadPlayerData(player) + self._LoadedChache[player] = true end --[=[ @@ -1839,6 +2144,7 @@ function RoQuestServer:_PlayerRemoving(player: Player): () self._UnavailableQuests[player] = nil self._PlayerQuestData[player] = nil self._Troves[player] = nil + self._LoadedChache[player] = nil end return RoQuestServer \ No newline at end of file diff --git a/RoQuest/Shared/Data/WarningMessages.lua b/RoQuest/Shared/Data/WarningMessages.lua index 9ef980b..963a8c8 100644 --- a/RoQuest/Shared/Data/WarningMessages.lua +++ b/RoQuest/Shared/Data/WarningMessages.lua @@ -7,4 +7,5 @@ return { NoObjectiveId = "No objective with the id %s exists in any of the loaded quests", NoLifeCycleMethod = "No method %s exists in the life cycle %s", SetPlayerData = "When using RoQuest:SetPlayerData make sure to pass a PlayerQuestData struct\n\nlocal RoQuest = require(ReplicatedStorage.RoQuest).Server\nlocal PlayerQuestData = RoQuest.PlayerQuestData\nRoQuest:SetPlayerData(player, PlayerQuestData {})", + WaitForLoad = "Wait For Load timed out. Traceback: \n%s", } \ No newline at end of file diff --git a/src/ReplicatedStorage/LifeCycles/Client/AppleQuest.lua b/src/ReplicatedStorage/LifeCycles/Client/AppleQuest.lua index 46c561a..e57126f 100644 --- a/src/ReplicatedStorage/LifeCycles/Client/AppleQuest.lua +++ b/src/ReplicatedStorage/LifeCycles/Client/AppleQuest.lua @@ -11,23 +11,23 @@ local AppleQuest = QuestLifeCycle { } function AppleQuest:OnStart() - print("Apple On Start") + -- print("Apple On Start") end function AppleQuest:OnComplete() - print("Apple On Complete") + -- print("Apple On Complete") end function AppleQuest:OnObjectiveChange(...) - print(...) + -- print(...) end function AppleQuest:OnDeliver() - print("Apple On Deliver") + -- print("Apple On Deliver") end function AppleQuest:OnDestroy() - print("Apple On Destroy") + --print("Apple On Destroy") end return AppleQuest \ No newline at end of file diff --git a/src/ServerScriptService/main.server.lua b/src/ServerScriptService/main.server.lua index deac415..140e646 100644 --- a/src/ServerScriptService/main.server.lua +++ b/src/ServerScriptService/main.server.lua @@ -12,18 +12,39 @@ RoQuest:Init( RoQuest:LoadDirectory(ReplicatedStorage.LifeCycles.Server) ) +--[[ +RoQuest.OnUnAvailableQuestChanged:Connect(function(...) + print("Unavailable Changed", ...) +end) +RoQuest.OnAvailableQuestChanged:Connect(function(...) + print("Available Changed", ...) +end) +RoQuest.OnCompletedQuestChanged:Connect(function(...) + print("Completed Changed", ...) +end) +RoQuest.OnDeliveredQuestChanged:Connect(function(...) + print("Delivered Changed", ...) +end) +RoQuest.OnInProgressQuestChanged:Connect(function(...) + print("In Progress Changed", ...) +end) +]] + + RoQuest.OnStart():andThen(function() local function playerAdded(player: Player) - local success, playerData = pcall(function() + local _success, playerData = pcall(function() return questsStore:GetAsync("player_"..player.UserId) end) - + + if playerData then -- Set the data on RoQuest task.delay(2, function() - print("[test] Set player data!", playerData) + print("[test] Before Set", RoQuest:GetQuests(player)) RoQuest:SetPlayerData(player, playerData) + print("[test] After Set", RoQuest:GetQuests(player)) end) - end + end end local function playerRemoved(player: Player) diff --git a/src/StarterPlayerScripts/Interface/QuestLog.lua b/src/StarterPlayerScripts/Interface/QuestLog.lua index 9870be5..598bed7 100644 --- a/src/StarterPlayerScripts/Interface/QuestLog.lua +++ b/src/StarterPlayerScripts/Interface/QuestLog.lua @@ -146,10 +146,6 @@ function QuestLog:Init() RoQuest.OnPlayerDataChanged:Connect(function() self:SetAllScreens() - - task.delay(2, function() - print("[test] with delay", RoQuest:GetQuests()) - end) end) -- Hard reset our screens end diff --git a/src/StarterPlayerScripts/Interface/Quests.lua b/src/StarterPlayerScripts/Interface/Quests.lua index 8306c4f..b8c5b50 100644 --- a/src/StarterPlayerScripts/Interface/Quests.lua +++ b/src/StarterPlayerScripts/Interface/Quests.lua @@ -89,7 +89,6 @@ end function Quests:Init() RoQuest.OnInProgressQuestChanged:Connect(function() - print("Progress changed!", RoQuest:GetQuests()) self:UpdateInterface() end) From f09a04ae30095fafc1c9015cb6cee84ceee3df4b Mon Sep 17 00:00:00 2001 From: prooheckcp <61127277+prooheckcp@users.noreply.github.com> Date: Sun, 16 Jun 2024 01:41:22 +0100 Subject: [PATCH 12/15] Fixed example --- RoQuest/Client/init.lua | 4 ++-- src/ServerScriptService/main.server.lua | 4 ++-- src/StarterPlayerScripts/Interface/Quests.lua | 9 ++++++--- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/RoQuest/Client/init.lua b/RoQuest/Client/init.lua index 72b3ff5..30ea29e 100644 --- a/RoQuest/Client/init.lua +++ b/RoQuest/Client/init.lua @@ -979,7 +979,7 @@ end function RoQuestClient:_OnPlayerDataChanged(playerQuestData: PlayerQuestData) self._Quests = {} self._PlayerQuestData = playerQuestData - print("[test] On Data Changed: ", playerQuestData) + for questId: string, questProgress: QuestProgress in playerQuestData.InProgress do self:_GiveQuest(questId, questProgress) end @@ -991,7 +991,7 @@ function RoQuestClient:_OnPlayerDataChanged(playerQuestData: PlayerQuestData) for questId: string, questProgress: QuestProgress in playerQuestData.Delivered do self:_GiveQuest(questId, questProgress) end - + self.OnPlayerDataChanged:Fire(playerQuestData) end diff --git a/src/ServerScriptService/main.server.lua b/src/ServerScriptService/main.server.lua index 140e646..ff220a4 100644 --- a/src/ServerScriptService/main.server.lua +++ b/src/ServerScriptService/main.server.lua @@ -40,9 +40,9 @@ RoQuest.OnStart():andThen(function() if playerData then -- Set the data on RoQuest task.delay(2, function() - print("[test] Before Set", RoQuest:GetQuests(player)) + print("[test] Before Set", RoQuest:GetPlayerData(player)) RoQuest:SetPlayerData(player, playerData) - print("[test] After Set", RoQuest:GetQuests(player)) + print("[test] After Set", RoQuest:GetPlayerData(player)) end) end end diff --git a/src/StarterPlayerScripts/Interface/Quests.lua b/src/StarterPlayerScripts/Interface/Quests.lua index b8c5b50..1746fc8 100644 --- a/src/StarterPlayerScripts/Interface/Quests.lua +++ b/src/StarterPlayerScripts/Interface/Quests.lua @@ -52,7 +52,7 @@ end function Quests:UpdateInterface() local quests: {[string]: Quest} = RoQuest:GetInProgressQuests() - + for _, instance: Instance in scrollingFrame:GetChildren() do -- Delete quests that dont exit if instance:IsA("Frame") and not quests[instance.Name] then instance:Destroy() @@ -63,8 +63,7 @@ function Quests:UpdateInterface() local existingFrame: Frame = scrollingFrame:FindFirstChild(questId) if existingFrame then - self:UpdateQuestFrame(quest, existingFrame) - continue -- Quest already exists + existingFrame:Destroy() end local newTemplate: Frame = template:Clone() @@ -88,6 +87,10 @@ function Quests:UpdateInterface() end function Quests:Init() + RoQuest.OnPlayerDataChanged:Connect(function() + self:UpdateInterface() + end) + RoQuest.OnInProgressQuestChanged:Connect(function() self:UpdateInterface() end) From d81e30ce4a495054d1ba984e4f84a8ebc262d1ff Mon Sep 17 00:00:00 2001 From: prooheckcp <61127277+prooheckcp@users.noreply.github.com> Date: Sun, 16 Jun 2024 12:10:52 +0100 Subject: [PATCH 13/15] Update main.server.lua --- src/ServerScriptService/main.server.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ServerScriptService/main.server.lua b/src/ServerScriptService/main.server.lua index ff220a4..5b0debf 100644 --- a/src/ServerScriptService/main.server.lua +++ b/src/ServerScriptService/main.server.lua @@ -12,7 +12,7 @@ RoQuest:Init( RoQuest:LoadDirectory(ReplicatedStorage.LifeCycles.Server) ) ---[[ + RoQuest.OnUnAvailableQuestChanged:Connect(function(...) print("Unavailable Changed", ...) end) @@ -28,7 +28,7 @@ end) RoQuest.OnInProgressQuestChanged:Connect(function(...) print("In Progress Changed", ...) end) -]] + RoQuest.OnStart():andThen(function() From 1c305116b492c42a15c7edf26ca35d6c0ccfbb0b Mon Sep 17 00:00:00 2001 From: prooheckcp <61127277+prooheckcp@users.noreply.github.com> Date: Sun, 16 Jun 2024 12:26:58 +0100 Subject: [PATCH 14/15] changing name --- default.project.json | 29 ++--------------------------- default2.project.json | 29 +++++++++++++++++++++++++++++ default3.project.json | 4 ---- 3 files changed, 31 insertions(+), 31 deletions(-) create mode 100644 default2.project.json delete mode 100644 default3.project.json diff --git a/default.project.json b/default.project.json index cd01099..d0704be 100644 --- a/default.project.json +++ b/default.project.json @@ -1,29 +1,4 @@ { - "name": "RoQuest", - "tree": { - "$className": "DataModel", - - "RoQuest":{ - "$path": "RoQuest" - }, - - "ReplicatedStorage": { - "$path": "src/ReplicatedStorage", - "RoQuest":{ - "$path": "RoQuest" - } - }, - - "ServerScriptService": { - "Server": { - "$path": "src/ServerScriptService" - } - }, - - "StarterPlayer": { - "StarterPlayerScripts": { - "$path": "src/StarterPlayerScripts" - } - } - } + "name": "roquest", + "tree": {"$path":"RoQuest"} } \ No newline at end of file diff --git a/default2.project.json b/default2.project.json new file mode 100644 index 0000000..cd01099 --- /dev/null +++ b/default2.project.json @@ -0,0 +1,29 @@ +{ + "name": "RoQuest", + "tree": { + "$className": "DataModel", + + "RoQuest":{ + "$path": "RoQuest" + }, + + "ReplicatedStorage": { + "$path": "src/ReplicatedStorage", + "RoQuest":{ + "$path": "RoQuest" + } + }, + + "ServerScriptService": { + "Server": { + "$path": "src/ServerScriptService" + } + }, + + "StarterPlayer": { + "StarterPlayerScripts": { + "$path": "src/StarterPlayerScripts" + } + } + } +} \ No newline at end of file diff --git a/default3.project.json b/default3.project.json deleted file mode 100644 index d0704be..0000000 --- a/default3.project.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "name": "roquest", - "tree": {"$path":"RoQuest"} -} \ No newline at end of file From 8123e303fbb53e771f01bca4f236954d4e0a7466 Mon Sep 17 00:00:00 2001 From: prooheckcp <61127277+prooheckcp@users.noreply.github.com> Date: Sun, 16 Jun 2024 15:56:51 +0100 Subject: [PATCH 15/15] Fixing issues --- RoQuest/Server/init.lua | 4 +++- wally.toml | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/RoQuest/Server/init.lua b/RoQuest/Server/init.lua index eba06f1..ddf4bcf 100644 --- a/RoQuest/Server/init.lua +++ b/RoQuest/Server/init.lua @@ -538,6 +538,8 @@ RoQuestServer._LifeCycles = {} :: {[Player]: {[string]: {[string]: QuestLifeCycl @server @private + @prop _LoadedChache {[Player]: true?} + @within RoQuestServer ]=] RoQuestServer._LoadedChache = {} :: {[Player]: true?} @@ -1675,7 +1677,7 @@ end @server @private - @parma player Player + @param player Player @param questId string @param questProgress QuestProgress? diff --git a/wally.toml b/wally.toml index 448a253..6df347b 100644 --- a/wally.toml +++ b/wally.toml @@ -1,6 +1,6 @@ [package] name = "prooheckcp/roquest" -description = "" +description = "RoQuest is a sophisticated abstract implementation of a Quest System. Although it can self manage nearly everything it also allows for the developer to manually set and manage everything. API: prooheckcp.github.io/RoQuest/" version = "0.1.1" license = "MIT" registry = "https://github.com/UpliftGames/wally-index"