From 0f066bcd0ece8ae5ab06b1477370c12921232f96 Mon Sep 17 00:00:00 2001 From: LocalIdentity Date: Mon, 15 Dec 2025 00:07:25 +1100 Subject: [PATCH] Import Quests from character ingame Added the logic to import quest rewards from your character in game The quest rewards in the API are just a list of strings for the given rewards so we have to guess and match them to a quest We loop through all the quests and see if the stat or options match 1 or more lines in the API list. If a match is made we remove those quest rewards from the API so that we don't enable multiple quests from 1 quest reward (e.g. +30 spirit is the reward from 2 different quests) We also only rebuild the mod list if the config option is not already set from a previous import or manual change. --- src/Classes/ImportTab.lua | 79 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 78 insertions(+), 1 deletion(-) diff --git a/src/Classes/ImportTab.lua b/src/Classes/ImportTab.lua index 8bc98584ef..ce99de9cc7 100644 --- a/src/Classes/ImportTab.lua +++ b/src/Classes/ImportTab.lua @@ -583,6 +583,82 @@ function ImportTabClass:DownloadItems() end) end +function ImportTabClass:ImportQuestRewardConfig(questStats) + local configTab = self.build.configTab + local statLines = {} + for _, stat in ipairs(questStats) do + t_insert(statLines, escapeGGGString(stat):lower()) + end + + local function splitLine(text) + local out = {} + for line in text:gmatch("[^\r\n]+") do + line = line:gsub("^%s+", ""):lower() + t_insert(out, line) + end + return out + end + + -- Ensure all required lines exist, then remove them so they can't match again + local function matchQuest(requiredLines) + local indices = {} + for _, needed in ipairs(requiredLines) do + local found + for idx, line in ipairs(statLines) do + if line == needed then + found = idx + break + end + end + if not found then + return false + end + t_insert(indices, found) + end + table.sort(indices, function(a, b) return a > b end) + for _, idx in ipairs(indices) do + t_remove(statLines, idx) + end + return true + end + + local updated = false + for _, quest in ipairs(data.questRewards) do + if #statLines == 0 then + break + end + if quest.useConfig == true then + local var = "quest" .. quest.Description .. quest.Area .. quest.Info + if quest.Stat then + local matches = matchQuest(splitLine(quest.Stat)) + if configTab.input[var] ~= matches then + configTab.input[var] = matches + updated = true + end + elseif quest.Options then + local selected = configTab.defaultState[var] or "None" + for _, option in ipairs(quest.Options) do + if matchQuest(splitLine(option)) then + selected = option + break + end + end + if configTab.input[var] ~= selected then + configTab.input[var] = selected + updated = true + end + end + end + end + + if updated then + configTab:BuildModList() + configTab:UpdateControls() + configTab.modFlag = true + self.build.buildFlag = true + end +end + function ImportTabClass:ImportPassiveTreeAndJewels(charData) local charPassiveData = charData.passives self.charImportStatus = colorCodes.POSITIVE.."Passive tree and jewels successfully imported." @@ -639,6 +715,7 @@ function ImportTabClass:ImportPassiveTreeAndJewels(charData) end self.build.spec:AddUndoState() + self:ImportQuestRewardConfig(charPassiveData.quest_stats) self.build.characterLevel = charData.level self.build.characterLevelAutoMode = false self.build.configTab:UpdateLevel() @@ -1138,4 +1215,4 @@ function UrlDecode(url) url = url:gsub("+", " ") url = url:gsub("%%(%x%x)", HexToChar) return url -end \ No newline at end of file +end