From 12580fc56a61cc3346be56628393fd100c45ce9b Mon Sep 17 00:00:00 2001 From: Regisle Date: Sun, 22 Sep 2024 18:01:22 +0930 Subject: [PATCH 1/7] fix wrong tooltip text --- src/Classes/PartyTab.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Classes/PartyTab.lua b/src/Classes/PartyTab.lua index 61b0140368..686755d910 100644 --- a/src/Classes/PartyTab.lua +++ b/src/Classes/PartyTab.lua @@ -294,7 +294,7 @@ local PartyTabClass = newClass("PartyTab", "ControlHost", "Control", function(se return self.importCodeDetail or "" end self.controls.importCodeDestination = new("DropDownControl", {"TOPLEFT",self.controls.importCodeIn,"BOTTOMLEFT"}, {0, 4, 160, theme.buttonHeight}, partyDestinations) - self.controls.importCodeDestination.tooltipText = "Destination for Import/clear\nCurrently Links Skills do not export" + self.controls.importCodeDestination.tooltipText = "Destination for Import/clear" self.controls.importCodeGo = new("ButtonControl", {"LEFT",self.controls.importCodeDestination,"RIGHT"}, {8, 0, 160, theme.buttonHeight}, "Import", function() local importCodeFetching = false if self.importCodeSite and not self.importCodeXML then From 5b29e2e2b705bd8ffb6dea094e8227deeb8850b8 Mon Sep 17 00:00:00 2001 From: Regisle Date: Sun, 22 Sep 2024 19:03:48 +0930 Subject: [PATCH 2/7] add warcry undo and redo --- src/Classes/PartyTab.lua | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Classes/PartyTab.lua b/src/Classes/PartyTab.lua index 686755d910..04da93cec5 100644 --- a/src/Classes/PartyTab.lua +++ b/src/Classes/PartyTab.lua @@ -675,6 +675,8 @@ function PartyTabClass:Draw(viewPort, inputEvents) self.controls.editAuras:Undo() elseif self.controls.editCurses.hasFocus then self.controls.editCurses:Undo() + elseif self.controls.editWarcries.hasFocus then + self.controls.editWarcries:Undo() elseif self.controls.editLinks.hasFocus then self.controls.editLinks:Undo() elseif self.controls.editPartyMemberStats.hasFocus then @@ -685,6 +687,8 @@ function PartyTabClass:Draw(viewPort, inputEvents) self.controls.editAuras:Redo() elseif self.controls.editCurses.hasFocus then self.controls.editCurses:Redo() + elseif self.controls.editWarcries.hasFocus then + self.controls.editWarcries:Redo() elseif self.controls.editLinks.hasFocus then self.controls.editLinks:Redo() elseif self.controls.editPartyMemberStats.hasFocus then From dfafa36a8e078bb43dba20ef5626c409341cdfb9 Mon Sep 17 00:00:00 2001 From: Regisle Date: Mon, 23 Sep 2024 19:50:21 +0930 Subject: [PATCH 3/7] Add support for multiple party members other than just appending to one --- src/Classes/PartyTab.lua | 888 +++++++++++++++++++++++++++++---------- 1 file changed, 659 insertions(+), 229 deletions(-) diff --git a/src/Classes/PartyTab.lua b/src/Classes/PartyTab.lua index 04da93cec5..4449e9c729 100644 --- a/src/Classes/PartyTab.lua +++ b/src/Classes/PartyTab.lua @@ -7,13 +7,19 @@ local pairs = pairs local ipairs = ipairs local s_format = string.format local t_insert = table.insert +local t_remove = table.remove local m_max = math.max +local maximumMembers = 6 + local PartyTabClass = newClass("PartyTab", "ControlHost", "Control", function(self, build) self.ControlHost() self.Control() self.build = build + + self.selectedMember = 1 + self.partyMembers = { { } } self.actor = { Aura = { }, Curse = { }, Warcry = { }, Link = { }, modDB = new("ModDB"), output = { } } self.actor.modDB.actor = self.actor @@ -29,6 +35,7 @@ local PartyTabClass = newClass("PartyTab", "ControlHost", "Control", function(se EnemyCond = "", EnemyMods = "", EnableExportBuffs = false, + selectedMember = 1, showAdvancedTools = false, } @@ -50,7 +57,7 @@ local PartyTabClass = newClass("PartyTab", "ControlHost", "Control", function(se bufferHeightSmall = 106, bufferHeightLeft = function() -- 2 elements - return (self.height - 378 - ((self.width > 1350) and 0 or 24) - self.controls.importCodeHeader.y() - self.controls.editAurasLabel.y()) + return (self.height - 418 - ((self.width > 1350) and 0 or 24) - self.controls.importCodeHeader.y() - self.controls.editAurasLabel.y()) end, -- 4 elements bufferHeightRight = 434, @@ -76,40 +83,58 @@ local PartyTabClass = newClass("PartyTab", "ControlHost", "Control", function(se end local clearInputText = function() - if partyDestinations[self.controls.importCodeDestination.selIndex] == "All" or partyDestinations[self.controls.importCodeDestination.selIndex] == "Party Member Stats" then + if self.selectedMember == 1 then + return + end + local partyMember = self.partyMembers[self.selectedMember] + local destination = partyDestinations[self.controls.importCodeDestination.selIndex] + if destination == "All" or destination == "Party Member Stats" then self.controls.editPartyMemberStats:SetText("") + partyMember.editPartyMemberStats = "" end - if partyDestinations[self.controls.importCodeDestination.selIndex] == "All" or partyDestinations[self.controls.importCodeDestination.selIndex] == "Aura" then + if destination == "All" or destination == "Aura" then self.controls.simpleAuras.label = "" + partyMember.simpleAuras = "" self.controls.editAuras:SetText("") - wipeTable(self.actor["Aura"]) - self.actor["Aura"] = {} + partyMember.editAuras = "" + wipeTable(partyMember["Aura"]) + partyMember["Aura"] = {} end - if partyDestinations[self.controls.importCodeDestination.selIndex] == "All" or partyDestinations[self.controls.importCodeDestination.selIndex] == "Curse" then + if destination == "All" or destination == "Curse" then self.controls.simpleCurses.label = "" + partyMember.simpleCurses = "" self.controls.editCurses:SetText("") - wipeTable(self.actor["Curse"]) - self.actor["Curse"] = {} + partyMember.editCurses = "" + wipeTable(partyMember["Curse"]) + partyMember["Curse"] = {} end - if partyDestinations[self.controls.importCodeDestination.selIndex] == "All" or partyDestinations[self.controls.importCodeDestination.selIndex] == "Warcry Skills" then + if destination == "All" or destination == "Warcry Skills" then self.controls.simpleWarcries.label = "" + partyMember.simpleWarcries = "" self.controls.editWarcries:SetText("") - wipeTable(self.actor["Warcry"]) - self.actor["Warcry"] = {} + partyMember.editWarcries = "" + wipeTable(partyMember["Warcry"]) + partyMember["Warcry"] = {} end - if partyDestinations[self.controls.importCodeDestination.selIndex] == "All" or partyDestinations[self.controls.importCodeDestination.selIndex] == "Link Skills" then + if destination == "All" or destination == "Link Skills" then self.controls.simpleLinks.label = "" + partyMember.simpleLinks = "" self.controls.editLinks:SetText("") - wipeTable(self.actor["Link"]) - self.actor["Link"] = {} + partyMember.editLinks = "" + wipeTable(partyMember["Link"]) + partyMember["Link"] = {} end - if partyDestinations[self.controls.importCodeDestination.selIndex] == "All" or partyDestinations[self.controls.importCodeDestination.selIndex] == "EnemyConditions" then + if destination == "All" or destination == "EnemyConditions" then self.controls.simpleEnemyCond.label = "^7---------------------------\n" + partyMember.simpleEnemyCond = "" self.controls.enemyCond:SetText("") + partyMember.enemyCond = "" end - if partyDestinations[self.controls.importCodeDestination.selIndex] == "All" or partyDestinations[self.controls.importCodeDestination.selIndex] == "EnemyMods" then + if destination == "All" or destination == "EnemyMods" then self.controls.simpleEnemyMods.label = "\n" + partyMember.simpleEnemyMods = "" self.controls.enemyMods:SetText("") + partyMember.enemyMods = "" end end @@ -155,36 +180,45 @@ local PartyTabClass = newClass("PartyTab", "ControlHost", "Control", function(se self.importCodeXML = xmlText end - local finishImport = function() + local finishImport = function(replaceMember) if not self.importCodeValid or self.importCodeFetching then return end + if not replaceMember then + t_insert(self.partyMembers, { name = "New Member "..(#self.partyMembers), Aura = {}, Curse = {}, Warcry = { }, Link = {}, modDB = new("ModDB"), output = { }, enemyModList = new("ModList") }) + self:SwapSelectedMember(#self.partyMembers, true) + end + local partyMember = self.partyMembers[self.selectedMember] + local destination = partyDestinations[self.controls.importCodeDestination.selIndex] + local currentCurseBuffer = nil local currentLinkBuffer = nil - if self.controls.appendNotReplace.state ~= true then - clearInputText() - else - if partyDestinations[self.controls.importCodeDestination.selIndex] == "All" or partyDestinations[self.controls.importCodeDestination.selIndex] == "Aura" then - wipeTable(self.actor["Aura"]) - self.actor["Aura"] = { } - end - if partyDestinations[self.controls.importCodeDestination.selIndex] == "All" or partyDestinations[self.controls.importCodeDestination.selIndex] == "Curse" then - currentCurseBuffer = self.controls.editCurses.buf - self.controls.editCurses:SetText("") --curses do not play nicely with append atm, need to fix - wipeTable(self.actor["Curse"]) - self.actor["Curse"] = { } - end - if partyDestinations[self.controls.importCodeDestination.selIndex] == "All" or partyDestinations[self.controls.importCodeDestination.selIndex] == "Warcry Skills" then - wipeTable(self.actor["Warcry"]) - self.actor["Warcry"] = { } - end - if partyDestinations[self.controls.importCodeDestination.selIndex] == "All" or partyDestinations[self.controls.importCodeDestination.selIndex] == "Link Skills" then - -- only one link can be applied at a time anyway - currentLinkBuffer = self.controls.editLinks.buf - self.controls.editLinks:SetText("") - wipeTable(self.actor["Link"]) - self.actor["Link"] = { } + if replaceMember then + if self.controls.appendNotReplace.state ~= true then + clearInputText() + else + if destination == "All" or destination == "Aura" then + wipeTable(partyMember["Aura"]) + partyMember["Aura"] = { } + end + if destination == "All" or destination == "Curse" then + currentCurseBuffer = partyMember.editCurses + self.controls.editCurses:SetText("") --curses do not play nicely with append atm, need to fix + wipeTable(partyMember["Curse"]) + partyMember["Curse"] = { } + end + if destination == "All" or destination == "Warcry Skills" then + wipeTable(partyMember["Warcry"]) + partyMember["Warcry"] = { } + end + if destination == "All" or destination == "Link Skills" then + -- only one link can be applied at a time anyway + currentLinkBuffer = partyMember.editLinks + self.controls.editLinks:SetText("") + wipeTable(partyMember["Link"]) + partyMember["Link"] = { } + end end end @@ -206,78 +240,87 @@ local PartyTabClass = newClass("PartyTab", "ControlHost", "Control", function(se if not node.attrib.name then ConPrintf("missing name") elseif node.attrib.name == "PartyMemberStats" then - if partyDestinations[self.controls.importCodeDestination.selIndex] == "All" or partyDestinations[self.controls.importCodeDestination.selIndex] == "Party Member Stats" then - if #self.controls.editPartyMemberStats.buf > 0 then - node[1] = self.controls.editPartyMemberStats.buf.."\n"..(node[1] or "") + if destination == "All" or destination == "Party Member Stats" then + partyMember.editPartyMemberStats = partyMember.editPartyMemberStats or "" + if #partyMember.editPartyMemberStats > 0 then + node[1] = partyMember.editPartyMemberStats.."\n"..(node[1] or "") end self.controls.editPartyMemberStats:SetText(node[1] or "") - self:ParseBuffs(self.actor["modDB"], self.controls.editPartyMemberStats.buf, "PartyMemberStats", self.actor["output"]) + self:ParseBuffs("PartyMemberStats", partyMember, node[1]) end elseif node.attrib.name == "Aura" then - if partyDestinations[self.controls.importCodeDestination.selIndex] == "All" or partyDestinations[self.controls.importCodeDestination.selIndex] == "Aura" then - if #self.controls.editAuras.buf > 0 then - node[1] = self.controls.editAuras.buf.."\n"..(node[1] or "") + if destination == "All" or destination == "Aura" then + partyMember.editAuras = partyMember.editAuras or "" + if #partyMember.editAuras > 0 then + node[1] = partyMember.editAuras.."\n"..(node[1] or "") end self.controls.editAuras:SetText(node[1] or "") - self:ParseBuffs(self.actor["Aura"], self.controls.editAuras.buf, "Aura", self.controls.simpleAuras) + self:ParseBuffs("Aura", partyMember, node[1]) end elseif node.attrib.name == "Curse" then - if partyDestinations[self.controls.importCodeDestination.selIndex] == "All" or partyDestinations[self.controls.importCodeDestination.selIndex] == "Curse" then - if #self.controls.editCurses.buf > 0 then - node[1] = self.controls.editCurses.buf.."\n"..(node[1] or "") + if destination == "All" or destination == "Curse" then + partyMember.editCurses = partyMember.editCurses or "" + if #partyMember.editCurses > 0 then + node[1] = partyMember.editCurses.."\n"..(node[1] or "") end if currentCurseBuffer and node[1] =="--- Curse Limit ---\n1" then node[1] = currentCurseBuffer end self.controls.editCurses:SetText(node[1] or "") - self:ParseBuffs(self.actor["Curse"], self.controls.editCurses.buf, "Curse", self.controls.simpleCurses) + self:ParseBuffs("Curse", partyMember, node[1]) end elseif node.attrib.name == "Warcry Skills" then - if partyDestinations[self.controls.importCodeDestination.selIndex] == "All" or partyDestinations[self.controls.importCodeDestination.selIndex] == "Warcry Skills" then - if #self.controls.editWarcries.buf > 0 then - node[1] = self.controls.editWarcries.buf.."\n"..(node[1] or "") + if destination == "All" or destination == "Warcry Skills" then + partyMember.editWarcries = partyMember.editWarcries or "" + if #partyMember.editWarcries > 0 then + node[1] = partyMember.editWarcries.."\n"..(node[1] or "") end self.controls.editWarcries:SetText(node[1] or "") - self:ParseBuffs(self.actor["Warcry"], self.controls.editWarcries.buf, "Warcry", self.controls.simpleWarcries) + self:ParseBuffs("Warcry", partyMember, node[1]) end elseif node.attrib.name == "Link Skills" then - if partyDestinations[self.controls.importCodeDestination.selIndex] == "All" or partyDestinations[self.controls.importCodeDestination.selIndex] == "Link Skills" then - if #self.controls.editLinks.buf > 0 then - node[1] = self.controls.editLinks.buf.."\n"..(node[1] or "") + if destination == "All" or destination == "Link Skills" then + partyMember.editLinks = partyMember.editLinks or "" + if #partyMember.editLinks > 0 then + node[1] = partyMember.editLinks.."\n"..(node[1] or "") end if currentLinkBuffer and (not node[1] or node[1] == "") then node[1] = currentLinkBuffer end self.controls.editLinks:SetText(node[1] or "") - self:ParseBuffs(self.actor["Link"], self.controls.editLinks.buf, "Link", self.controls.simpleLinks) + self:ParseBuffs("Link", partyMember, node[1]) end elseif node.attrib.name == "EnemyConditions" then - if partyDestinations[self.controls.importCodeDestination.selIndex] == "All" or partyDestinations[self.controls.importCodeDestination.selIndex] == "EnemyConditions" then - if #self.controls.enemyCond.buf > 0 then - node[1] = self.controls.enemyCond.buf.."\n"..(node[1] or "") + if destination == "All" or destination == "EnemyConditions" then + partyMember.enemyCond = partyMember.enemyCond or "" + if #partyMember.enemyCond > 0 then + node[1] = partyMember.enemyCond.."\n"..(node[1] or "") end self.controls.enemyCond:SetText(node[1] or "") end elseif node.attrib.name == "EnemyMods" then - if partyDestinations[self.controls.importCodeDestination.selIndex] == "All" or partyDestinations[self.controls.importCodeDestination.selIndex] == "EnemyMods" then - if #self.controls.enemyMods.buf > 0 then - node[1] = self.controls.enemyMods.buf.."\n"..(node[1] or "") + if destination == "All" or destination == "EnemyMods" then + partyMember.enemyMods = partyMember.enemyMods or "" + if #partyMember.enemyMods > 0 then + node[1] = partyMember.enemyMods.."\n"..(node[1] or "") end self.controls.enemyMods:SetText(node[1] or "") end end end end - if partyDestinations[self.controls.importCodeDestination.selIndex] == "All" or partyDestinations[self.controls.importCodeDestination.selIndex] == "EnemyConditions" or partyDestinations[self.controls.importCodeDestination.selIndex] == "EnemyMods" then - wipeTable(self.enemyModList) - self.enemyModList = new("ModList") - self:ParseBuffs(self.enemyModList, self.controls.enemyCond.buf, "EnemyConditions") - self:ParseBuffs(self.enemyModList, self.controls.enemyMods.buf, "EnemyMods", self.controls.simpleEnemyMods) + if destination == "All" or destination == "EnemyConditions" or destination == "EnemyMods" then + wipeTable(partyMember.enemyModList) + partyMember.enemyModList = new("ModList") + self:ParseBuffs("EnemyConditions", partyMember, self.controls.enemyCond.buf) + self:ParseBuffs("EnemyMods", partyMember, self.controls.enemyMods.buf) end self.build.buildFlag = true break end end + self:CombineBuffs() + self:SwapSelectedMember(self.selectedMember, true) end self.controls.importCodeIn = new("EditControl", {"TOPLEFT",self.controls.importCodeHeader,"BOTTOMLEFT"}, {0, 4, 328, theme.buttonHeight}, "", nil, nil, nil, importCodeHandle) @@ -286,7 +329,7 @@ local PartyTabClass = newClass("PartyTab", "ControlHost", "Control", function(se end self.controls.importCodeIn.enterFunc = function() if self.importCodeValid then - self.controls.importCodeGo.onClick() + self.controls.importCodeNewMember.onClick() end end self.controls.importCodeState = new("LabelControl", {"LEFT",self.controls.importCodeIn,"RIGHT"}, {8, 0, 0, theme.stringHeight}) @@ -295,7 +338,7 @@ local PartyTabClass = newClass("PartyTab", "ControlHost", "Control", function(se end self.controls.importCodeDestination = new("DropDownControl", {"TOPLEFT",self.controls.importCodeIn,"BOTTOMLEFT"}, {0, 4, 160, theme.buttonHeight}, partyDestinations) self.controls.importCodeDestination.tooltipText = "Destination for Import/clear" - self.controls.importCodeGo = new("ButtonControl", {"LEFT",self.controls.importCodeDestination,"RIGHT"}, {8, 0, 160, theme.buttonHeight}, "Import", function() + self.controls.importCodeNewMember = new("ButtonControl", {"LEFT",self.controls.importCodeDestination,"RIGHT"}, {8, 0, 160, theme.buttonHeight}, "Import (New Member)", function() local importCodeFetching = false if self.importCodeSite and not self.importCodeXML then self.importCodeFetching = true @@ -307,38 +350,56 @@ local PartyTabClass = newClass("PartyTab", "ControlHost", "Control", function(se self.importCodeValid = false else importCodeHandle(data) - finishImport() + finishImport(false) end end) return end - finishImport() + finishImport(false) end) - self.controls.importCodeGo.enabled = function() - return (self.importCodeValid and not self.importCodeFetching) + self.controls.importCodeNewMember.enabled = function() + return (self.importCodeValid and not self.importCodeFetching) and (#self.partyMembers < maximumMembers) end - self.controls.importCodeGo.enterFunc = function() + self.controls.importCodeNewMember.enterFunc = function() if self.importCodeValid then - self.controls.importCodeGo.onClick() + self.controls.importCodeNewMember.onClick() end end - self.controls.appendNotReplace = new("CheckBoxControl", {"LEFT",self.controls.importCodeGo,"RIGHT"}, {60, 0, theme.buttonHeight}, "Append", function(state) - end, "This sets the import button to append to the current party lists instead of replacing them (curses will still replace)", false) - self.controls.appendNotReplace.x = function() - return (self.width > theme.widthThreshold1) and 60 or (-276) + self.controls.importCodeOverwriteMember = new("ButtonControl", {"LEFT",self.controls.importCodeNewMember,"RIGHT"}, {8, 0, 180, theme.buttonHeight}, "Import (Overwrite Member)", function() + local importCodeFetching = false + if self.importCodeSite and not self.importCodeXML then + self.importCodeFetching = true + local selectedWebsite = buildSites.websiteList[self.importCodeSite] + buildSites.DownloadBuild(self.controls.importCodeIn.buf, selectedWebsite, function(isSuccess, data) + self.importCodeFetching = false + if not isSuccess then + self.importCodeDetail = colorCodes.NEGATIVE..data + self.importCodeValid = false + else + importCodeHandle(data) + finishImport(true) + end + end) + return + end + + finishImport(true) + end) + self.controls.importCodeOverwriteMember.enabled = function() + return (self.importCodeValid and not self.importCodeFetching) and (self.selectedMember ~= 1) end - self.controls.appendNotReplace.y = function() - return (self.width > theme.widthThreshold1) and 0 or 24 + self.controls.importCodeOverwriteMember.enterFunc = function() + if self.importCodeValid then + self.controls.importCodeOverwriteMember.onClick() + end + end + self.controls.importCodeOverwriteMember.x = function() + return (self.width + 200 > theme.widthThreshold1) and 8 or (-328) + end + self.controls.importCodeOverwriteMember.y = function() + return (self.width + 200 > theme.widthThreshold1) and 0 or 24 end - - self.controls.clear = new("ButtonControl", {"LEFT",self.controls.appendNotReplace,"RIGHT"}, {8, 0, 160, theme.buttonHeight}, "Clear", function() - clearInputText() - wipeTable(self.enemyModList) - self.enemyModList = new("ModList") - self.build.buildFlag = true - end) - self.controls.clear.tooltipText = "^7Clears all the party tab imported data" self.controls.ShowAdvanceTools = new("CheckBoxControl", {"TOPLEFT",self.controls.importCodeDestination,"BOTTOMLEFT"}, {140, 4, theme.buttonHeight}, "^7Show Advanced Info", function(state) end, "This shows the advanced info like what stats each aura/curse etc are adding, as well as enables the ability to edit them without a re-export\nDo not edit any boxes unless you know what you are doing, use copy/paste or import instead", false) @@ -346,40 +407,134 @@ local PartyTabClass = newClass("PartyTab", "ControlHost", "Control", function(se return (self.width > theme.widthThreshold1) and 4 or 28 end - self.controls.removeEffects = new("ButtonControl", {"LEFT",self.controls.ShowAdvanceTools,"RIGHT"}, {8, 0, 160, theme.buttonHeight}, "Disable Party Effects", function() - wipeTable(self.actor) + self.controls.deleteMember = new("ButtonControl", {"LEFT",self.controls.ShowAdvanceTools,"RIGHT"}, {8, 0, 160, theme.buttonHeight}, "^7Delete Member", function() + wipeTable(self.partyMembers[self.selectedMember]) + t_remove(self.partyMembers, self.selectedMember) + self:CombineBuffs() + self:SwapSelectedMember(1, false) + self.build.buildFlag = true + end) + self.controls.deleteMember.tooltipText = "^7Removes the Current Party Member" + + self.controls.clear = new("ButtonControl", {"TOPLEFT",self.controls.ShowAdvanceTools,"TOPLEFT"}, {-140, 30, 160, theme.buttonHeight}, "^7Clear", function() + clearInputText() wipeTable(self.enemyModList) - self.actor = { Aura = {}, Curse = {}, Warcry = { }, Link = {}, modDB = new("ModDB"), output = { } } - self.actor.modDB.actor = self.actor self.enemyModList = new("ModList") self.build.buildFlag = true end) + self.controls.clear.tooltipText = "^7Clears all the party tab imported data" + self.controls.clear.shown = function() + return self.controls.ShowAdvanceTools.state + end + + self.controls.appendNotReplace = new("CheckBoxControl", {"LEFT",self.controls.clear,"RIGHT"}, {60, 0, theme.buttonHeight}, "^7Append", function(state) + end, "This sets the import button to append to the current party lists instead of replacing them (curses will still replace)", false) + + self.controls.removeEffects = new("ButtonControl", {"LEFT",self.controls.appendNotReplace,"RIGHT"}, {8, 0, 160, theme.buttonHeight}, "Disable Party Effects", function() + if self.selectedMember == 1 then + for i, partyMember in ipairs(self.partyMembers) do + if i ~= 1 then + partyMember["Aura"] = { } + partyMember["Curse"] = { } + partyMember["Warcry"] = { } + partyMember["Link"] = { } + partyMember["modDB"] = new("ModDB") + partyMember.modDB.actor = partyMember + partyMember["output"] = { } + wipeTable(partyMember.enemyModList) + partyMember.enemyModList = new("ModList") + end + end + else + local partyMember = self.partyMembers[self.selectedMember] + partyMember["Aura"] = { } + partyMember["Curse"] = { } + partyMember["Warcry"] = { } + partyMember["Link"] = { } + partyMember["modDB"] = new("ModDB") + partyMember.modDB.actor = partyMember + partyMember["output"] = { } + wipeTable(partyMember.enemyModList) + partyMember.enemyModList = new("ModList") + end + self:CombineBuffs() + self:SwapSelectedMember(self.selectedMember, false) + self.build.buildFlag = true + end) self.controls.removeEffects.tooltipText = "^7Removes the effects of the supports, without removing the data\nUse \"rebuild all\" to apply the effects again" + self.controls.removeEffects.x = function() + return (self.width > theme.widthThreshold1) and 8 or (-240) + end + self.controls.removeEffects.y = function() + return (self.width > theme.widthThreshold1) and 0 or 24 + end - self.controls.rebuild = new("ButtonControl", {"LEFT",self.controls.removeEffects,"RIGHT"}, {8, 0, 160, theme.buttonHeight}, "^7Rebuild All", function() - wipeTable(self.actor) - wipeTable(self.enemyModList) - self.actor = { Aura = {}, Curse = {}, Warcry = { }, Link = {}, modDB = new("ModDB"), output = { } } - self.actor.modDB.actor = self.actor - self.enemyModList = new("ModList") - self:ParseBuffs(self.actor["modDB"], self.controls.editPartyMemberStats.buf, "PartyMemberStats", self.actor["output"]) - self:ParseBuffs(self.actor["Aura"], self.controls.editAuras.buf, "Aura", self.controls.simpleAuras) - self:ParseBuffs(self.actor["Curse"], self.controls.editCurses.buf, "Curse", self.controls.simpleCurses) - self:ParseBuffs(self.actor["Warcry"], self.controls.editWarcries.buf, "Warcry", self.controls.simpleWarcries) - self:ParseBuffs(self.actor["Link"], self.controls.editLinks.buf, "Link", self.controls.simpleLinks) - self:ParseBuffs(self.enemyModList, self.controls.enemyCond.buf, "EnemyConditions") - self:ParseBuffs(self.enemyModList, self.controls.enemyMods.buf, "EnemyMods", self.controls.simpleEnemyMods) + self.controls.rebuild = new("ButtonControl", {"LEFT",self.controls.removeEffects,"RIGHT"}, {8, 0, 160, theme.buttonHeight}, "^7Rebuild All", function() + if self.selectedMember == 1 then + for i, partyMember in ipairs(self.partyMembers) do + if i ~= 1 then + partyMember["Aura"] = { } + partyMember["Curse"] = { } + partyMember["Warcry"] = { } + partyMember["Link"] = { } + partyMember["modDB"] = new("ModDB") + partyMember.modDB.actor = partyMember + partyMember["output"] = { } + wipeTable(partyMember.enemyModList) + partyMember.enemyModList = new("ModList") + self:ParseBuffs("PartyMemberStats", partyMember, partyMember.editPartyMemberStats or "") + self:ParseBuffs("Aura", partyMember, partyMember.editAuras or "") + self:ParseBuffs("Curse", partyMember, partyMember.editCurses or "") + self:ParseBuffs("Warcry", partyMember, partyMember.editWarcries or "") + self:ParseBuffs("Link", partyMember, partyMember.editLinks or "") + self:ParseBuffs("EnemyConditions", partyMember, partyMember.enemyCond or "") + self:ParseBuffs("EnemyMods", partyMember, partyMember.enemyMods or "") + end + end + else + local partyMember = self.partyMembers[self.selectedMember] + partyMember["Aura"] = { } + partyMember["Curse"] = { } + partyMember["Warcry"] = { } + partyMember["Link"] = { } + partyMember["modDB"] = new("ModDB") + partyMember.modDB.actor = partyMember + partyMember["output"] = { } + wipeTable(partyMember.enemyModList) + partyMember.enemyModList = new("ModList") + self:ParseBuffs("PartyMemberStats", partyMember, self.controls.editPartyMemberStats.buf) + self:ParseBuffs("Aura", partyMember, self.controls.editAuras.buf) + self:ParseBuffs("Curse", partyMember, self.controls.editCurses.buf) + self:ParseBuffs("Warcry", partyMember, self.controls.editWarcries.buf) + self:ParseBuffs("Link", partyMember, self.controls.editLinks.buf) + self:ParseBuffs("EnemyConditions", partyMember, self.controls.enemyCond.buf) + self:ParseBuffs("EnemyMods", partyMember, self.controls.enemyMods.buf) + end + self:CombineBuffs() + self:SwapSelectedMember(self.selectedMember, false) self.build.buildFlag = true end) self.controls.rebuild.tooltipText = "^7Reparse all the inputs incase they have been disabled or they have changed since loading the build or importing" - self.controls.rebuild.x = function() - return (self.width > theme.widthThreshold1) and 8 or (-328) + + self.controls.overviewButton = new("ButtonControl", {"TOPLEFT",self.controls.ShowAdvanceTools,"TOPLEFT"}, {-140, 30, 140, theme.buttonHeight}, "^7Overview", function() + self:SwapSelectedMember(1, true) + end) + self.controls.overviewButton.tooltipText = "^7 Overview of everything all the other party members give" + self.controls.overviewButton.y = function() + return self.controls.ShowAdvanceTools.state and (60 + ((self.width > theme.widthThreshold1) and 0 or 24)) or 30 end - self.controls.rebuild.y = function() - return (self.width > theme.widthThreshold1) and 0 or 24 + + for i = 2, maximumMembers do + self.controls["Member"..i.."Button"] = new("ButtonControl", {"LEFT",(i == 2) and self.controls.overviewButton or self.controls["Member"..(i - 1).."Button"],"RIGHT"}, {8, 0, 140, theme.buttonHeight}, "^7Member "..i, function() + self:SwapSelectedMember(i, true) + end) + self.controls["Member"..i.."Button"].tooltipText = "^7 Swap to the "..({"1st","2nd","3rd","4th","5th"})[(i - 1)].." Party member" + self.controls["Member"..i.."Button"].shown = function() + return (#self.partyMembers >= i) + end end - self.controls.editAurasLabel = new("LabelControl", {"TOPLEFT",self.controls.ShowAdvanceTools,"TOPLEFT"}, {-140, 40, 0, theme.stringHeight}, "^7Auras") + self.controls.editAurasLabel = new("LabelControl", {"TOPLEFT",self.controls.overviewButton,"TOPLEFT"}, {0, 40, 0, theme.stringHeight}, "^7Auras") self.controls.editAurasLabel.y = function() return 36 + ((self.width <= theme.widthThreshold1) and 24 or 0) end @@ -392,16 +547,16 @@ local PartyTabClass = newClass("PartyTab", "ControlHost", "Control", function(se end self.controls.editAuras.shown = function() - return self.controls.ShowAdvanceTools.state + return self.controls.ShowAdvanceTools.state and (self.selectedMember ~= 1) end self.controls.simpleAuras = new("LabelControl", {"TOPLEFT",self.controls.editAurasLabel,"TOPLEFT"}, {0, 18, 0, theme.stringHeight}, "") self.controls.simpleAuras.shown = function() - return not self.controls.ShowAdvanceTools.state + return not self.controls.ShowAdvanceTools.state or (self.selectedMember == 1) end self.controls.editWarcriesLabel = new("LabelControl", {"TOPLEFT",self.controls.editAurasLabel,"BOTTOMLEFT"}, {0, 8, 0, theme.stringHeight}, "^7Warcry Skills") self.controls.editWarcriesLabel.y = function() - return self.controls.ShowAdvanceTools.state and (self.controls.editAuras.height() + 8) or (theme.lineCounter(self.controls.simpleAuras.label) + 4) + return (self.controls.ShowAdvanceTools.state and (self.selectedMember ~= 1)) and (self.controls.editAuras.height() + 8) or (theme.lineCounter(self.controls.simpleAuras.label) + 4) end self.controls.editWarcries = new("EditControl", {"TOPLEFT",self.controls.editWarcriesLabel,"TOPLEFT"}, {0, 18, 0, 0}, "", nil, "^%C\t\n", nil, nil, 14, true) self.controls.editWarcries.width = function() @@ -411,16 +566,16 @@ local PartyTabClass = newClass("PartyTab", "ControlHost", "Control", function(se return (self.controls.editWarcries.hasFocus and theme.bufferHeightLeft() or theme.bufferHeightSmall) end self.controls.editWarcries.shown = function() - return self.controls.ShowAdvanceTools.state + return self.controls.ShowAdvanceTools.state and (self.selectedMember ~= 1) end self.controls.simpleWarcries = new("LabelControl", {"TOPLEFT",self.controls.editWarcriesLabel,"TOPLEFT"}, {0, 18, 0, theme.stringHeight}, "") self.controls.simpleWarcries.shown = function() - return not self.controls.ShowAdvanceTools.state + return not self.controls.ShowAdvanceTools.state or (self.selectedMember == 1) end self.controls.editLinksLabel = new("LabelControl", {"TOPLEFT",self.controls.editWarcriesLabel,"BOTTOMLEFT"}, {0, 8, 0, theme.stringHeight}, "^7Link Skills") self.controls.editLinksLabel.y = function() - return self.controls.ShowAdvanceTools.state and (self.controls.editWarcries.height() + 8) or (theme.lineCounter(self.controls.simpleWarcries.label) + 4) + return (self.controls.ShowAdvanceTools.state and (self.selectedMember ~= 1)) and (self.controls.editWarcries.height() + 8) or (theme.lineCounter(self.controls.simpleWarcries.label) + 4) end self.controls.editLinks = new("EditControl", {"TOPLEFT",self.controls.editLinksLabel,"TOPLEFT"}, {0, 18, 0, 0}, "", nil, "^%C\t\n", nil, nil, 14, true) self.controls.editLinks.width = function() @@ -430,11 +585,11 @@ local PartyTabClass = newClass("PartyTab", "ControlHost", "Control", function(se return (self.controls.editLinks.hasFocus and theme.bufferHeightLeft() or theme.bufferHeightSmall) end self.controls.editLinks.shown = function() - return self.controls.ShowAdvanceTools.state + return self.controls.ShowAdvanceTools.state and (self.selectedMember ~= 1) end self.controls.simpleLinks = new("LabelControl", {"TOPLEFT",self.controls.editLinksLabel,"TOPLEFT"}, {0, 18, 0, theme.stringHeight}, "") self.controls.simpleLinks.shown = function() - return not self.controls.ShowAdvanceTools.state + return not self.controls.ShowAdvanceTools.state or (self.selectedMember == 1) end self.controls.editPartyMemberStatsLabel = new("LabelControl", {"TOPLEFT",self.controls.notesDesc,"TOPRIGHT"}, {8, 0, 0, theme.stringHeight}, "^7Party Member Stats") @@ -446,12 +601,12 @@ local PartyTabClass = newClass("PartyTab", "ControlHost", "Control", function(se return (self.controls.editPartyMemberStats.hasFocus and (self.height - theme.bufferHeightRight) or theme.bufferHeightSmall) end self.controls.editPartyMemberStats.shown = function() - return self.controls.ShowAdvanceTools.state + return self.controls.ShowAdvanceTools.state and (self.selectedMember ~= 1) end self.controls.enemyCondLabel = new("LabelControl", {"TOPLEFT",self.controls.editPartyMemberStatsLabel,"BOTTOMLEFT"}, {0, 8, 0, theme.stringHeight}, "^7Enemy Conditions") self.controls.enemyCondLabel.y = function() - return self.controls.ShowAdvanceTools.state and (self.controls.editPartyMemberStats.height() + 8) or 4 + return (self.controls.ShowAdvanceTools.state and (self.selectedMember ~= 1)) and (self.controls.editPartyMemberStats.height() + 8) or 4 end self.controls.enemyCond = new("EditControl", {"TOPLEFT",self.controls.enemyCondLabel,"BOTTOMLEFT"}, {0, 2, 0, 0}, "", nil, "^%C\t\n", nil, nil, 14, true) self.controls.enemyCond.width = function() @@ -461,16 +616,16 @@ local PartyTabClass = newClass("PartyTab", "ControlHost", "Control", function(se return (self.controls.enemyCond.hasFocus and (self.height - theme.bufferHeightRight) or theme.bufferHeightSmall) end self.controls.enemyCond.shown = function() - return self.controls.ShowAdvanceTools.state + return self.controls.ShowAdvanceTools.state and (self.selectedMember ~= 1) end self.controls.simpleEnemyCond = new("LabelControl", {"TOPLEFT",self.controls.enemyCondLabel,"TOPLEFT"}, {0, 18, 0, theme.stringHeight}, "^7---------------------------\n") self.controls.simpleEnemyCond.shown = function() - return not self.controls.ShowAdvanceTools.state + return not self.controls.ShowAdvanceTools.state or (self.selectedMember == 1) end self.controls.enemyModsLabel = new("LabelControl", {"TOPLEFT",self.controls.enemyCondLabel,"BOTTOMLEFT"}, {0, 8, 0, theme.stringHeight}, "^7Enemy Modifiers") self.controls.enemyModsLabel.y = function() - return self.controls.ShowAdvanceTools.state and (self.controls.enemyCond.height() + 8) or (theme.lineCounter(self.controls.simpleEnemyCond.label) + 4) + return (self.controls.ShowAdvanceTools.state and (self.selectedMember ~= 1)) and (self.controls.enemyCond.height() + 8) or (theme.lineCounter(self.controls.simpleEnemyCond.label) + 4) end self.controls.enemyMods = new("EditControl", {"TOPLEFT",self.controls.enemyModsLabel,"BOTTOMLEFT"}, {0, 2, 0, 0}, "", nil, "^%C\t\n", nil, nil, 14, true) self.controls.enemyMods.width = function() @@ -480,16 +635,16 @@ local PartyTabClass = newClass("PartyTab", "ControlHost", "Control", function(se return (self.controls.enemyMods.hasFocus and (self.height - theme.bufferHeightRight) or theme.bufferHeightSmall) end self.controls.enemyMods.shown = function() - return self.controls.ShowAdvanceTools.state + return self.controls.ShowAdvanceTools.state and (self.selectedMember ~= 1) end self.controls.simpleEnemyMods = new("LabelControl", {"TOPLEFT",self.controls.enemyModsLabel,"TOPLEFT"}, {0, 18, 0, theme.stringHeight}, "\n") self.controls.simpleEnemyMods.shown = function() - return not self.controls.ShowAdvanceTools.state + return not self.controls.ShowAdvanceTools.state or (self.selectedMember == 1) end self.controls.editCursesLabel = new("LabelControl", {"TOPLEFT",self.controls.enemyModsLabel,"BOTTOMLEFT"}, {0, 8, 0, theme.stringHeight}, "^7Curses") self.controls.editCursesLabel.y = function() - return self.controls.ShowAdvanceTools.state and (self.controls.enemyMods.height() + 8) or (theme.lineCounter(self.controls.simpleEnemyMods.label) + 4) + return (self.controls.ShowAdvanceTools.state and (self.selectedMember ~= 1)) and (self.controls.enemyMods.height() + 8) or (theme.lineCounter(self.controls.simpleEnemyMods.label) + 4) end self.controls.editCurses = new("EditControl", {"TOPLEFT",self.controls.editCursesLabel,"BOTTOMLEFT"}, {0, 2, 0, 0}, "", nil, "^%C\t\n", nil, nil, 14, true) self.controls.editCurses.width = function() @@ -499,58 +654,91 @@ local PartyTabClass = newClass("PartyTab", "ControlHost", "Control", function(se return (self.controls.enemyCond.hasFocus or self.controls.enemyMods.hasFocus or self.controls.editPartyMemberStats.hasFocus) and theme.bufferHeightSmall or (self.height - theme.bufferHeightRight) end self.controls.editCurses.shown = function() - return self.controls.ShowAdvanceTools.state + return self.controls.ShowAdvanceTools.state and (self.selectedMember ~= 1) end self.controls.simpleCurses = new("LabelControl", {"TOPLEFT",self.controls.editCursesLabel,"TOPLEFT"}, {0, 18, 0, theme.stringHeight}, "") self.controls.simpleCurses.shown = function() - return not self.controls.ShowAdvanceTools.state + return not self.controls.ShowAdvanceTools.state or (self.selectedMember == 1) end self:SelectControl(self.controls.editAuras) end) function PartyTabClass:Load(xml, fileName) + local unknownMemeber for _, node in ipairs(xml) do - if node.elem == "ImportedBuffs" then + if node.elem == "ImportedMember" then + if not node.attrib.name then + ConPrintf("missing name") + else + t_insert(self.partyMembers, { name = node.attrib.name, Aura = {}, Curse = {}, Warcry = { }, Link = {}, modDB = new("ModDB"), output = { }, enemyModList = new("ModList") }) + local currentMember = self.partyMembers[#self.partyMembers] + for _, node2 in ipairs(node) do + if node2.attrib.name == "PartyMemberStats" then + currentMember.editPartyMemberStats = node2[1] or "" + self:ParseBuffs("PartyMemberStats", currentMember, node2[1] or "") + elseif node2.attrib.name == "Aura" then + currentMember.editAuras = node2[1] or "" + self:ParseBuffs("Aura", currentMember, node2[1] or "") + elseif node2.attrib.name == "Curse" then + currentMember.editCurses = node2[1] or "" + self:ParseBuffs("Curse", currentMember, node2[1] or "") + elseif node2.attrib.name == "Warcry Skills" then + currentMember.editWarcries = node2[1] or "" + self:ParseBuffs("Warcry", currentMember, node2[1] or "") + elseif node2.attrib.name == "Link Skills" then + currentMember.editLinks = node2[1] or "" + self:ParseBuffs("Link", currentMember, node2[1] or "") + elseif node2.attrib.name == "EnemyConditions" then + currentMember.enemyCond = node2[1] or "" + self:ParseBuffs("EnemyConditions", currentMember, node2[1] or "") + elseif node2.attrib.name == "EnemyMods" then + currentMember.enemyMods = node2[1] or "" + self:ParseBuffs("EnemyMods", currentMember, node2[1] or "") + end + end + end + elseif node.elem == "ImportedBuffs" then + if not unknownMemeber then + t_insert(self.partyMembers, { name = "Unknown", Aura = {}, Curse = {}, Warcry = { }, Link = {}, modDB = new("ModDB"), output = { }, enemyModList = new("ModList") }) + unknownMemeber = self.partyMembers[#self.partyMembers] + end if not node.attrib.name then ConPrintf("missing name") elseif node.attrib.name == "PartyMemberStats" then - self.controls.editPartyMemberStats:SetText(node[1] or "") - self:ParseBuffs(self.actor["modDB"], node[1] or "", "PartyMemberStats", self.actor["output"]) + unknownMemeber.editPartyMemberStats = node[1] or "" + self:ParseBuffs("PartyMemberStats", unknownMemeber, node[1] or "") elseif node.attrib.name == "Aura" then - self.controls.editAuras:SetText(node[1] or "") - self:ParseBuffs(self.actor["Aura"], node[1] or "", "Aura", self.controls.simpleAuras) + unknownMemeber.editAuras = node[1] or "" + self:ParseBuffs("Aura", unknownMemeber, node[1] or "") elseif node.attrib.name == "Curse" then - self.controls.editCurses:SetText(node[1] or "") - self:ParseBuffs(self.actor["Curse"], node[1] or "", "Curse", self.controls.simpleCurses) + unknownMemeber.editCurses = node[1] or "" + self:ParseBuffs("Curse", unknownMemeber, node[1] or "") elseif node.attrib.name == "Warcry Skills" then - self.controls.editWarcries:SetText(node[1] or "") - self:ParseBuffs(self.actor["Warcry"], node[1] or "", "Warcry", self.controls.simpleWarcries) + unknownMemeber.editWarcries = node[1] or "" + self:ParseBuffs("Warcry", unknownMemeber, node[1] or "") elseif node.attrib.name == "Link Skills" then - self.controls.editLinks:SetText(node[1] or "") - self:ParseBuffs(self.actor["Link"], node[1] or "", "Link", self.controls.simpleLinks) + unknownMemeber.editLinks = node[1] or "" + self:ParseBuffs("Link", unknownMemeber, node[1] or "") elseif node.attrib.name == "EnemyConditions" then - self.controls.enemyCond:SetText(node[1] or "") - self:ParseBuffs(self.enemyModList, node[1] or "", "EnemyConditions") + unknownMemeber.editPartyMemberStats = node[1] or "" + self:ParseBuffs("EnemyConditions", unknownMemeber, node[1] or "") elseif node.attrib.name == "EnemyMods" then - self.controls.enemyMods:SetText(node[1] or "") - self:ParseBuffs(self.enemyModList, node[1] or "", "EnemyMods", self.controls.simpleEnemyMods) + unknownMemeber.enemyMods = node[1] or "" + self:ParseBuffs("EnemyMods", unknownMemeber, node[1] or "") end elseif node.elem == "ExportedBuffs" then if not node.attrib.name then ConPrintf("missing name") end - --if node.attrib.name ~= "EnemyConditions" and node.attrib.name ~= "EnemyMods" then - --- self:ParseBuffs(self.buffExports, node[1] or "", node.attrib.name) - --end - --self:ParseBuffs(self.buffExports, node[1] or "", "PartyMemberStats") - --self:ParseBuffs(self.buffExports, node[1] or "", "Aura") - --self:ParseBuffs(self.buffExports, node[1] or "", "Curse") - --self:ParseBuffs(self.buffExports, node[1] or "", "Warcry") - --self:ParseBuffs(self.buffExports, node[1] or "", "Link") - --self:ParseBuffs(self.buffExports, node[1] or "", "EnemyConditions") - --self:ParseBuffs(self.buffExports, node[1] or "", "EnemyMods") end end + self:CombineBuffs() + + self.controls.importCodeDestination:SelByValue(xml.attrib.destination or "All") + self.controls.appendNotReplace.state = xml.attrib.append == "true" + self.controls.ShowAdvanceTools.state = xml.attrib.ShowAdvanceTools == "true" + self:SwapSelectedMember((tonumber(xml.attrib.selectedMember) or 1), false) + self.lastContent.PartyMemberStats = self.controls.editPartyMemberStats.buf self.lastContent.Aura = self.controls.editAuras.buf self.lastContent.Curse = self.controls.editCurses.buf @@ -559,50 +747,53 @@ function PartyTabClass:Load(xml, fileName) self.lastContent.EnemyCond = self.controls.enemyCond.buf self.lastContent.EnemyMods = self.controls.enemyMods.buf self.lastContent.EnableExportBuffs = self.enableExportBuffs - - self.controls.importCodeDestination:SelByValue(xml.attrib.destination or "All") - self.controls.appendNotReplace.state = xml.attrib.append == "true" - self.controls.ShowAdvanceTools.state = xml.attrib.ShowAdvanceTools == "true" + self.lastContent.selectedMember = self.selectedMember self.lastContent.showAdvancedTools = self.controls.ShowAdvanceTools.state end function PartyTabClass:Save(xml) local child - if self.controls.editPartyMemberStats.buf and self.controls.editPartyMemberStats.buf ~= "" then - child = { elem = "ImportedBuffs", attrib = { name = "PartyMemberStats" } } - t_insert(child, self.controls.editPartyMemberStats.buf) - t_insert(xml, child) - end - if self.controls.editAuras.buf and self.controls.editAuras.buf ~= "" then - child = { elem = "ImportedBuffs", attrib = { name = "Aura" } } - t_insert(child, self.controls.editAuras.buf) - t_insert(xml, child) - end - if self.controls.editCurses.buf and self.controls.editCurses.buf ~= "" then - child = { elem = "ImportedBuffs", attrib = { name = "Curse" } } - t_insert(child, self.controls.editCurses.buf) - t_insert(xml, child) - end - if self.controls.editWarcries.buf and self.controls.editWarcries.buf ~= "" then - child = { elem = "ImportedBuffs", attrib = { name = "Warcry Skills" } } - t_insert(child, self.controls.editWarcries.buf) - t_insert(xml, child) - end - if self.controls.editLinks.buf and self.controls.editLinks.buf ~= "" then - child = { elem = "ImportedBuffs", attrib = { name = "Link Skills" } } - t_insert(child, self.controls.editLinks.buf) - t_insert(xml, child) - end - if self.controls.enemyCond.buf and self.controls.enemyCond.buf ~= "" then - child = { elem = "ImportedBuffs", attrib = { name = "EnemyConditions" } } - t_insert(child, self.controls.enemyCond.buf) - t_insert(xml, child) - end - if self.controls.enemyMods.buf and self.controls.enemyMods.buf ~= "" then - child = { elem = "ImportedBuffs", attrib = { name = "EnemyMods" } } - t_insert(child, self.controls.enemyMods.buf) - t_insert(xml, child) + for i, partyMember in ipairs(self.partyMembers) do + if i ~= 1 then + local member = { elem = "ImportedMember", attrib = { name = partyMember.name } } + if partyMember.editPartyMemberStats and partyMember.editPartyMemberStats ~= "" then + child = { elem = "ImportedBuffs", attrib = { name = "PartyMemberStats" } } + t_insert(child, partyMember.editPartyMemberStats) + t_insert(member, child) + end + if partyMember.editAuras and partyMember.editAuras ~= "" then + child = { elem = "ImportedBuffs", attrib = { name = "Aura" } } + t_insert(child, partyMember.editAuras) + t_insert(member, child) + end + if partyMember.editCurses and partyMember.editCurses ~= "" then + child = { elem = "ImportedBuffs", attrib = { name = "Curse" } } + t_insert(child, partyMember.editCurses) + t_insert(member, child) + end + if partyMember.editWarcries and partyMember.editWarcries ~= "" then + child = { elem = "ImportedBuffs", attrib = { name = "Warcry Skills" } } + t_insert(child, partyMember.editWarcries) + t_insert(member, child) + end + if partyMember.editLinks and partyMember.editLinks ~= "" then + child = { elem = "ImportedBuffs", attrib = { name = "Link Skills" } } + t_insert(child, partyMember.editLinks) + t_insert(member, child) + end + if partyMember.enemyCond and partyMember.enemyCond ~= "" then + child = { elem = "ImportedBuffs", attrib = { name = "EnemyConditions" } } + t_insert(child, partyMember.enemyCond) + t_insert(member, child) + end + if partyMember.enemyMods and partyMember.enemyMods ~= "" then + child = { elem = "ImportedBuffs", attrib = { name = "EnemyMods" } } + t_insert(child, partyMember.enemyMods) + t_insert(member, child) + end + t_insert(xml, member) + end end local exportString = self:exportBuffs("PlayerMods") if exportString ~= "" then @@ -654,10 +845,12 @@ function PartyTabClass:Save(xml) self.lastContent.EnemyCond = self.controls.enemyCond.buf self.lastContent.EnemyMods = self.controls.enemyMods.buf self.lastContent.EnableExportBuffs = self.enableExportBuffs + self.lastContent.selectedMember = self.selectedMember xml.attrib = { destination = self.controls.importCodeDestination.list[self.controls.importCodeDestination.selIndex], append = tostring(self.controls.appendNotReplace.state), - ShowAdvanceTools = tostring(self.controls.ShowAdvanceTools.state) + ShowAdvanceTools = tostring(self.controls.ShowAdvanceTools.state), + selectedMember = tostring(self.selectedMember), } self.lastContent.showAdvancedTools = self.controls.ShowAdvanceTools.state end @@ -711,23 +904,58 @@ function PartyTabClass:Draw(viewPort, inputEvents) or self.lastContent.EnemyCond ~= self.controls.enemyCond.buf or self.lastContent.EnemyMods ~= self.controls.enemyMods.buf or self.lastContent.EnableExportBuffs ~= self.enableExportBuffs + or self.lastContent.selectedMember ~= self.selectedMember or self.lastContent.showAdvancedTools ~= self.controls.ShowAdvanceTools.state) end -function PartyTabClass:ParseBuffs(list, buf, buffType, label) + +function PartyTabClass:SwapSelectedMember(newMember, saveBuffers) + if saveBuffers and self.selectedMember ~= 1 then + self.partyMembers[self.selectedMember].editPartyMemberStats = self.controls.editPartyMemberStats.buf + self.partyMembers[self.selectedMember].editAuras = self.controls.editAuras.buf + self.partyMembers[self.selectedMember].editCurses = self.controls.editCurses.buf + self.partyMembers[self.selectedMember].editWarcries = self.controls.editWarcries.buf + self.partyMembers[self.selectedMember].editLinks = self.controls.editLinks.buf + self.partyMembers[self.selectedMember].enemyCond = self.controls.enemyCond.buf + self.partyMembers[self.selectedMember].enemyMods = self.controls.enemyMods.buf + end + self.selectedMember = newMember + if newMember ~= 1 then + self.controls.editPartyMemberStats.buf = self.partyMembers[self.selectedMember].editPartyMemberStats or "" + self.controls.editAuras.buf = self.partyMembers[self.selectedMember].editAuras or "" + self.controls.editCurses.buf = self.partyMembers[self.selectedMember].editCurses or "" + self.controls.editWarcries.buf = self.partyMembers[self.selectedMember].editWarcries or "" + self.controls.editLinks.buf = self.partyMembers[self.selectedMember].editLinks or "" + self.controls.enemyCond.buf = self.partyMembers[self.selectedMember].enemyCond or "" + self.controls.enemyMods.buf = self.partyMembers[self.selectedMember].enemyMods or "" + end + self.controls.simpleAuras.label = self.partyMembers[self.selectedMember].simpleAuras or "" + self.controls.simpleCurses.label = self.partyMembers[self.selectedMember].simpleCurses or "" + self.controls.simpleWarcries.label = self.partyMembers[self.selectedMember].simpleWarcries or "" + self.controls.simpleLinks.label = self.partyMembers[self.selectedMember].simpleLinks or "" + self.controls.simpleEnemyCond.label = self.partyMembers[self.selectedMember].simpleEnemyCond or "" + self.controls.simpleEnemyMods.label = self.partyMembers[self.selectedMember].simpleEnemyMods or "" +end + + +function PartyTabClass:ParseBuffs(buffType, partyMember, buf) + local list = partyMember[buffType] + local labelName = ({ Aura = "simpleAuras", Curse = "simpleCurses", Warcry = "simpleWarcries", Link = "simpleLinks", EnemyConditions = "simpleEnemyCond", EnemyMods = "simpleEnemyMods", })[buffType] if buffType == "EnemyConditions" then + list = partyMember.enemyModList for line in buf:gmatch("([^\n]*)\n?") do if line ~= "" then list:NewMod(line:gsub("Condition:", "Condition:Party:"), "FLAG", true, "Party") end end elseif buffType == "EnemyMods" then + list = partyMember.enemyModList local enemyModList = {} local currentName for line in buf:gmatch("([^\n]*)\n?") do if not line:find("|") then currentName = line - if label and currentName ~= "" then + if labelName and currentName ~= "" then enemyModList[currentName] = enemyModList[currentName] or {} end else @@ -735,37 +963,38 @@ function PartyTabClass:ParseBuffs(list, buf, buffType, label) if mod then mod.source = "Party"..mod.source list:AddMod(mod) - if label then + if labelName then t_insert(enemyModList[currentName], {mod.value, mod.type}) end end end end - if label then + if labelName then local count = 0 - label.label = "^7---------------------------" + partyMember[labelName] = "^7---------------------------" for modName, modList in pairs(enemyModList) do - label.label = label.label.."\n"..modName..":" + partyMember[labelName] = partyMember[labelName].."\n"..modName..":" count = count + 1 for _, mod in ipairs(modList) do - label.label = label.label.." "..(mod[1] and "True" or mod[1]).." "..(mod[2] == "FLAG" and "" or mod[2])..", " + partyMember[labelName] = partyMember[labelName].." "..(mod[1] and "True" or mod[1]).." "..(mod[2] == "FLAG" and "" or mod[2])..", " end end if count > 0 then - label.label = label.label.."\n---------------------------\n" + partyMember[labelName] = partyMember[labelName].."\n---------------------------\n" else - label.label = label.label.."\n" + partyMember[labelName] = partyMember[labelName].."\n" end end elseif buffType == "PartyMemberStats" then - if not list then + if not partyMember.modDB then else + local modDB = partyMember.modDB + local output = partyMember.output for line in buf:gmatch("([^\n]*)\n?") do if line:find("=") then - -- label is output for this type, as a special case if line:match("%.") then local k1, k2, v = line:match("([%w ]-%w+)%.([%w ]-%w+)=(.+)") - label[k1] = {[k2] = tonumber(v)} + output[k1] = {[k2] = tonumber(v)} elseif line:match("|") then local k, tags, v = line:match("([%w ]-%w+)|(.+)=(.+)") v = tonumber(v) @@ -773,16 +1002,16 @@ function PartyTabClass:ParseBuffs(list, buf, buffType, label) if tag == "percent" then v = v / 100 elseif tag == "max" then - v = m_max(v, label[k] or 1) + v = m_max(v, output[k] or 1) end end - label[k] = v + output[k] = v else local k, v = line:match("([%w ]-%w+)=(.+)") - label[k] = tonumber(v) + output[k] = tonumber(v) end elseif line ~= "" then - list:NewMod(line, "FLAG", true, "Party") + modDB:NewMod(line, "FLAG", true, "Party") end end end @@ -890,10 +1119,10 @@ function PartyTabClass:ParseBuffs(list, buf, buffType, label) end end end - if label then + if labelName then if buffType == "Aura" then local labelList = {} - label.label = "^7---------------------------\n" + partyMember[labelName] = "^7---------------------------\n" for aura, auraMod in pairs(list["Aura"] or {}) do if aura ~= "Vaal" then t_insert(labelList, aura..": "..auraMod.effectMult.."%\n") @@ -920,24 +1149,24 @@ function PartyTabClass:ParseBuffs(list, buf, buffType, label) end if #labelList > 0 then table.sort(labelList) - label.label = label.label..table.concat(labelList) - label.label = label.label.."---------------------------\n" + partyMember[labelName] = partyMember[labelName]..table.concat(labelList) + partyMember[labelName] = partyMember[labelName].."---------------------------\n" end if list["extraAura"] and list["extraAura"]["extraAura"] then - label.label = label.label.."extraAuras:\n" + partyMember[labelName] = partyMember[labelName].."extraAuras:\n" for _, auraMod in ipairs(list["extraAura"]["extraAura"].modList) do - label.label = label.label.." "..(auraMod.type == "FLAG" and "" or (auraMod.type.." "))..auraMod.name..": "..tostring(auraMod.value).."\n" + partyMember[labelName] = partyMember[labelName].." "..(auraMod.type == "FLAG" and "" or (auraMod.type.." "))..auraMod.name..": "..tostring(auraMod.value).."\n" end - label.label = label.label.."---------------------------\n" + partyMember[labelName] = partyMember[labelName].."---------------------------\n" end if list["otherEffects"] then - label.label = label.label.."otherEffects:\n" + partyMember[labelName] = partyMember[labelName].."otherEffects:\n" for buffName, buff in pairs(list["otherEffects"]) do for _, auraMod in ipairs(list["otherEffects"][buffName].modList) do - label.label = label.label.." "..(auraMod.type == "FLAG" and "" or (auraMod.type.." "))..auraMod.name..": "..tostring(auraMod.value).."\n" + partyMember[labelName] = partyMember[labelName].." "..(auraMod.type == "FLAG" and "" or (auraMod.type.." "))..auraMod.name..": "..tostring(auraMod.value).."\n" end end - label.label = label.label.."---------------------------\n" + partyMember[labelName] = partyMember[labelName].."---------------------------\n" end elseif buffType == "Warcry" then local labelList = {} @@ -946,9 +1175,9 @@ function PartyTabClass:ParseBuffs(list, buf, buffType, label) end if #labelList > 0 then table.sort(labelList) - label.label = "^7---------------------------\n"..table.concat(labelList).."---------------------------\n" + partyMember[labelName] = "^7---------------------------\n"..table.concat(labelList).."---------------------------\n" else - label.label = "" + partyMember[labelName] = "" end elseif buffType == "Link" then local labelList = {} @@ -957,9 +1186,9 @@ function PartyTabClass:ParseBuffs(list, buf, buffType, label) end if #labelList > 0 then table.sort(labelList) - label.label = "^7---------------------------\n"..table.concat(labelList).."---------------------------\n" + partyMember[labelName] = "^7---------------------------\n"..table.concat(labelList).."---------------------------\n" else - label.label = "" + partyMember[labelName] = "" end elseif buffType == "Curse" then local labelList = {} @@ -968,11 +1197,212 @@ function PartyTabClass:ParseBuffs(list, buf, buffType, label) end if #labelList > 0 then table.sort(labelList) - label.label = "^7---------------------------\n"..table.concat(labelList).."---------------------------\n" + partyMember[labelName] = "^7---------------------------\n"..table.concat(labelList).."---------------------------\n" else - label.label = "" + partyMember[labelName] = "" + end + end + end + end +end + +function PartyTabClass:CombineBuffs(filter) + for i, partyMember in ipairs(self.partyMembers) do + if i == 1 then + if not filter then + wipeTable(self.actor) + wipeTable(self.enemyModList) + self.actor = { Aura = {}, Curse = {}, Warcry = { }, Link = {}, modDB = new("ModDB"), output = { } } + self.actor.modDB.actor = self.actor + self.enemyModList = new("ModList") + end + self.actor.Curse = { Limit = 0 } + else + if not filter or filter == "EnemyConditions" or filter == "EnemyMods" then + self.enemyModList:AddList(partyMember.enemyModList) + end + if not filter or filter == "PartyMemberStats" then + self.actor.modDB:AddList(partyMember.modDB) + for k, v in pairs(partyMember.output) do + self.actor.output[k] = v + end + end + if not filter or filter == "Aura" then + if partyMember.Aura.Aura then + self.actor.Aura.Aura = self.actor.Aura.Aura or { } + for aura, auraMod in pairs(partyMember.Aura.Aura) do + if aura == "Vaal" then + self.actor.Aura.Aura.Vaal = self.actor.Aura.Aura.Vaal or { } + for auraVaal, auraModVaal in pairs(auraMod) do + if not self.actor.Aura.Aura.Vaal[auraVaal] or self.actor.Aura.Aura.Vaal[auraVaal].effectMult < auraModVaal.effectMult then + self.actor.Aura.Aura.Vaal[auraVaal] = auraModVaal + end + end + else + if not self.actor.Aura.Aura[aura] or self.actor.Aura.Aura[aura].effectMult < auraMod.effectMult then + self.actor.Aura.Aura[aura] = auraMod + end + end + end + end + if partyMember.Aura.AuraDebuff then + self.actor.Aura.AuraDebuff = self.actor.Aura.AuraDebuff or { } + for aura, auraMod in pairs(partyMember.Aura.AuraDebuff) do + if aura == "Vaal" then + self.actor.Aura.AuraDebuff.Vaal = self.actor.Aura.AuraDebuff.Vaal or { } + for auraVaal, auraModVaal in pairs(auraMod) do + if not self.actor.Aura.AuraDebuff.Vaal[auraVaal] or self.actor.Aura.AuraDebuff.Vaal[auraVaal].effectMult < auraModVaal.effectMult then + self.actor.Aura.AuraDebuff.Vaal[auraVaal] = auraModVaal + end + end + else + if not self.actor.Aura.AuraDebuff[aura] or self.actor.Aura.AuraDebuff[aura].effectMult < auraMod.effectMult then + self.actor.Aura.AuraDebuff[aura] = auraMod + end + end + end + end + if partyMember.Aura.extraAura then + self.actor.Aura.extraAura = self.actor.Aura.extraAura or { } + self.actor.Aura.extraAura.extraAura = self.actor.Aura.extraAura.extraAura or { modList = new("ModList") } + self.actor.Aura.extraAura.extraAura.modList:AddList(partyMember.Aura.extraAura.extraAura.modList) + end + if partyMember.Aura.otherEffects then + self.actor.Aura.otherEffects = self.actor.Aura.otherEffects or { } + for _, auraMod in ipairs(partyMember.Aura.otherEffects) do + t_insert(self.actor.Aura.otherEffects, auraMod) + end + end + end + if not filter or filter == "Curse" then + if partyMember.Curse and ((partyMember.Curse.Limit or 0) > self.actor.Curse.Limit) then + self.actor.Curse = partyMember.Curse + end + end + if not filter or filter == "Warcry" then + if partyMember.Warcry and partyMember.Warcry.Warcry then + self.actor.Warcry.Warcry = self.actor.Warcry.Warcry or { } + for k, v in pairs(partyMember.Warcry.Warcry) do + if not self.actor.Warcry.Warcry[k] or self.actor.Warcry.Warcry[k].effectMult < v.effectMult then + self.actor.Warcry.Warcry[k] = v + end + end + end + end + if not filter or filter == "Link" then + if partyMember.Link and partyMember.Link.Link and not self.actor.Link.Link then + self.actor.Link.Link = partyMember.Link.Link + end + end + end + end + if not filter or filter == "EnemyMods" then + local count = 0 + local enemyModList = { } + self.partyMembers[1].simpleEnemyMods = "^7---------------------------" + ConPrintTable(self.enemyModList) + for _, mod in ipairs(self.enemyModList) do + if not mod.name:match("Condition:Party") then + enemyModList[mod.name] = enemyModList[mod.name] or { } + t_insert(enemyModList[mod.name], {mod.value, mod.type}) + end + end + for modName, modList in pairs(enemyModList) do + self.partyMembers[1].simpleEnemyMods = self.partyMembers[1].simpleEnemyMods.."\n"..modName..":" + count = count + 1 + for _, mod in ipairs(modList) do + self.partyMembers[1].simpleEnemyMods = self.partyMembers[1].simpleEnemyMods.." "..(mod[1] and "True" or mod[1]).." "..(mod[2] == "FLAG" and "" or mod[2])..", " + end + end + if count > 0 then + self.partyMembers[1].simpleEnemyMods = self.partyMembers[1].simpleEnemyMods.."\n---------------------------\n" + else + self.partyMembers[1].simpleEnemyMods = self.partyMembers[1].simpleEnemyMods.."\n" + end + end + if not filter or filter == "Aura" then + local labelList = {} + self.partyMembers[1].simpleAuras = "^7---------------------------\n" + for aura, auraMod in pairs(self.actor.Aura["Aura"] or {}) do + if aura ~= "Vaal" then + t_insert(labelList, aura..": "..auraMod.effectMult.."%\n") + end + end + if self.actor.Aura["Aura"] and self.actor.Aura["Aura"]["Vaal"] then + for aura, auraMod in pairs(self.actor.Aura["Aura"]["Vaal"]) do + t_insert(labelList, aura..": "..auraMod.effectMult.."%\n") + end + end + for aura, auraMod in pairs(self.actor.Aura["AuraDebuff"] or {}) do + if not self.actor.Aura["Aura"] or not self.actor.Aura["Aura"][aura] then + if aura ~= "Vaal" then + t_insert(labelList, aura..": "..auraMod.effectMult.."%\n") + end + end + end + if self.actor.Aura["AuraDebuff"] and self.actor.Aura["AuraDebuff"]["Vaal"] then + if not self.actor.Aura["Aura"] or not self.actor.Aura["Aura"]["Vaal"] or not self.actor.Aura["Aura"]["Vaal"][aura] then + for aura, auraMod in pairs(self.actor.Aura["AuraDebuff"]["Vaal"]) do + t_insert(labelList, aura..": "..auraMod.effectMult.."%\n") + end + end + end + if #labelList > 0 then + table.sort(labelList) + self.partyMembers[1].simpleAuras = self.partyMembers[1].simpleAuras..table.concat(labelList) + self.partyMembers[1].simpleAuras = self.partyMembers[1].simpleAuras.."---------------------------\n" + end + if self.actor.Aura["extraAura"] and self.actor.Aura["extraAura"]["extraAura"] then + self.partyMembers[1].simpleAuras = self.partyMembers[1].simpleAuras.."extraAuras:\n" + for _, auraMod in ipairs(self.actor.Aura["extraAura"]["extraAura"].modList) do + self.partyMembers[1].simpleAuras = self.partyMembers[1].simpleAuras.." "..(auraMod.type == "FLAG" and "" or (auraMod.type.." "))..auraMod.name..": "..tostring(auraMod.value).."\n" + end + self.partyMembers[1].simpleAuras = self.partyMembers[1].simpleAuras.."---------------------------\n" + end + if self.actor.Aura["otherEffects"] then + self.partyMembers[1].simpleAuras = self.partyMembers[1].simpleAuras.."otherEffects:\n" + for buffName, buff in pairs(self.actor.Aura["otherEffects"]) do + for _, auraMod in ipairs(self.actor.Aura["otherEffects"][buffName].modList) do + self.partyMembers[1].simpleAuras = self.partyMembers[1].simpleAuras.." "..(auraMod.type == "FLAG" and "" or (auraMod.type.." "))..auraMod.name..": "..tostring(auraMod.value).."\n" end end + self.partyMembers[1].simpleAuras = self.partyMembers[1].simpleAuras.."---------------------------\n" + end + end + if not filter or filter == "Warcry" then + local labelList = {} + for warcry, warcryMod in pairs(self.actor.Warcry["Warcry"] or {}) do + t_insert(labelList, warcry..": "..warcryMod.effectMult.."%\n") + end + if #labelList > 0 then + table.sort(labelList) + self.partyMembers[1].simpleWarcries= "^7---------------------------\n"..table.concat(labelList).."---------------------------\n" + else + self.partyMembers[1].simpleWarcries = "" + end + end + if not filter or filter == "Link" then + local labelList = {} + for link, linkMod in pairs(self.actor.Link["Link"] or {}) do + t_insert(labelList, link..": "..linkMod.effectMult.."%\n") + end + if #labelList > 0 then + table.sort(labelList) + self.partyMembers[1].simpleLinks = "^7---------------------------\n"..table.concat(labelList).."---------------------------\n" + else + self.partyMembers[1].simpleLinks = "" + end + end + if not filter or filter == "Curse" then + local labelList = {} + for curse, curseMod in pairs(self.actor.Curse["Curse"] or {}) do + t_insert(labelList, curse..": "..curseMod.effectMult.."%\n") + end + if #labelList > 0 then + table.sort(labelList) + self.partyMembers[1].simpleCurses = "^7---------------------------\n"..table.concat(labelList).."---------------------------\n" + else + self.partyMembers[1].simpleCurses = "" end end end From c1db4fdf80b4df4f46ded2f22fd0b1fbf829fe21 Mon Sep 17 00:00:00 2001 From: Regisle Date: Mon, 23 Sep 2024 20:58:40 +0930 Subject: [PATCH 4/7] add support for renaming the other party members --- src/Classes/PartyTab.lua | 62 ++++++++++++++++++++++++++++++++++------ 1 file changed, 54 insertions(+), 8 deletions(-) diff --git a/src/Classes/PartyTab.lua b/src/Classes/PartyTab.lua index 4449e9c729..588e6b390d 100644 --- a/src/Classes/PartyTab.lua +++ b/src/Classes/PartyTab.lua @@ -9,6 +9,8 @@ local s_format = string.format local t_insert = table.insert local t_remove = table.remove local m_max = math.max +local m_min = math.min +local m_floor = math.floor local maximumMembers = 6 @@ -54,6 +56,7 @@ local PartyTabClass = newClass("PartyTab", "ControlHost", "Control", function(se return lineCount * 16 end, widthThreshold1 = 1350, + widthThreshold2 = 1150, bufferHeightSmall = 106, bufferHeightLeft = function() -- 2 elements @@ -188,6 +191,7 @@ local PartyTabClass = newClass("PartyTab", "ControlHost", "Control", function(se if not replaceMember then t_insert(self.partyMembers, { name = "New Member "..(#self.partyMembers), Aura = {}, Curse = {}, Warcry = { }, Link = {}, modDB = new("ModDB"), output = { }, enemyModList = new("ModList") }) self:SwapSelectedMember(#self.partyMembers, true) + self.controls["Member"..#self.partyMembers.."Button"].label = "^7".."New Member "..(#self.partyMembers - 1) end local partyMember = self.partyMembers[self.selectedMember] local destination = partyDestinations[self.controls.importCodeDestination.selIndex] @@ -205,6 +209,7 @@ local PartyTabClass = newClass("PartyTab", "ControlHost", "Control", function(se if destination == "All" or destination == "Curse" then currentCurseBuffer = partyMember.editCurses self.controls.editCurses:SetText("") --curses do not play nicely with append atm, need to fix + partyMember.editCurses = "" wipeTable(partyMember["Curse"]) partyMember["Curse"] = { } end @@ -216,6 +221,7 @@ local PartyTabClass = newClass("PartyTab", "ControlHost", "Control", function(se -- only one link can be applied at a time anyway currentLinkBuffer = partyMember.editLinks self.controls.editLinks:SetText("") + partyMember.editLinks = "" wipeTable(partyMember["Link"]) partyMember["Link"] = { } end @@ -395,31 +401,50 @@ local PartyTabClass = newClass("PartyTab", "ControlHost", "Control", function(se end end self.controls.importCodeOverwriteMember.x = function() - return (self.width + 200 > theme.widthThreshold1) and 8 or (-328) + return (self.width > theme.widthThreshold2) and 8 or (-328) end self.controls.importCodeOverwriteMember.y = function() - return (self.width + 200 > theme.widthThreshold1) and 0 or 24 + return (self.width > theme.widthThreshold2) and 0 or 24 end self.controls.ShowAdvanceTools = new("CheckBoxControl", {"TOPLEFT",self.controls.importCodeDestination,"BOTTOMLEFT"}, {140, 4, theme.buttonHeight}, "^7Show Advanced Info", function(state) - end, "This shows the advanced info like what stats each aura/curse etc are adding, as well as enables the ability to edit them without a re-export\nDo not edit any boxes unless you know what you are doing, use copy/paste or import instead", false) + end, "This shows the advanced info like what stats each aura/curse etc are adding, advanced buttons like disable/rebuild,\nas well as enables the ability to edit them without a re-export\nDo not edit any boxes unless you know what you are doing, use copy/paste or import instead", false) self.controls.ShowAdvanceTools.y = function() - return (self.width > theme.widthThreshold1) and 4 or 28 + return (self.width > theme.widthThreshold2) and 4 or 28 end - self.controls.deleteMember = new("ButtonControl", {"LEFT",self.controls.ShowAdvanceTools,"RIGHT"}, {8, 0, 160, theme.buttonHeight}, "^7Delete Member", function() + self.controls.renameMember = new("EditControl", {"LEFT",self.controls.ShowAdvanceTools,"RIGHT"}, {8, 0, 160, theme.buttonHeight}, "", nil, "%^", 15, function(buf) + if self.selectedMember ~= 1 then + self.controls["Member"..self.selectedMember.."Button"].label = "^7"..buf + self.partyMembers[self.selectedMember].name = buf + end + end, theme.stringHeight) + self.controls.renameMember.tooltipText = "^7Renames the Current Party Member" + self.controls.renameMember.enabled = function() + return self.selectedMember ~= 1 + end + + self.controls.deleteMember = new("ButtonControl", {"LEFT",self.controls.renameMember,"RIGHT"}, {8, 0, 160, theme.buttonHeight}, "^7Delete Member", function() wipeTable(self.partyMembers[self.selectedMember]) t_remove(self.partyMembers, self.selectedMember) + for i = self.selectedMember, #self.partyMembers do + self.controls["Member"..i.."Button"].label = "^7"..self.partyMembers[i].name + end self:CombineBuffs() self:SwapSelectedMember(1, false) self.build.buildFlag = true end) self.controls.deleteMember.tooltipText = "^7Removes the Current Party Member" + self.controls.deleteMember.x = function() + return (self.width > theme.widthThreshold2) and 8 or (-142) + end + self.controls.deleteMember.y = function() + return (self.width > theme.widthThreshold2) and 0 or -24 + end self.controls.clear = new("ButtonControl", {"TOPLEFT",self.controls.ShowAdvanceTools,"TOPLEFT"}, {-140, 30, 160, theme.buttonHeight}, "^7Clear", function() clearInputText() - wipeTable(self.enemyModList) - self.enemyModList = new("ModList") + self:CombineBuffs() self.build.buildFlag = true end) self.controls.clear.tooltipText = "^7Clears all the party tab imported data" @@ -520,6 +545,9 @@ local PartyTabClass = newClass("PartyTab", "ControlHost", "Control", function(se self:SwapSelectedMember(1, true) end) self.controls.overviewButton.tooltipText = "^7 Overview of everything all the other party members give" + self.controls.overviewButton.width = function() + return m_floor(m_min((self.width / 2) / m_min(#self.partyMembers, ((self.width > theme.widthThreshold1) and 6 or 3)) - 20, 160)) + end self.controls.overviewButton.y = function() return self.controls.ShowAdvanceTools.state and (60 + ((self.width > theme.widthThreshold1) and 0 or 24)) or 30 end @@ -532,6 +560,15 @@ local PartyTabClass = newClass("PartyTab", "ControlHost", "Control", function(se self.controls["Member"..i.."Button"].shown = function() return (#self.partyMembers >= i) end + self.controls["Member"..i.."Button"].width = function() + return m_floor(m_min((self.width / 2) / m_min(#self.partyMembers, ((self.width > theme.widthThreshold1) and 6 or 3)) - 20, 160)) + end + end + self.controls["Member4Button"].x = function() + return (self.width > theme.widthThreshold1) and 8 or (-self.controls["Member4Button"].width()*3-16) + end + self.controls["Member4Button"].y = function() + return (self.width > theme.widthThreshold1) and 0 or 24 end self.controls.editAurasLabel = new("LabelControl", {"TOPLEFT",self.controls.overviewButton,"TOPLEFT"}, {0, 40, 0, theme.stringHeight}, "^7Auras") @@ -671,6 +708,7 @@ function PartyTabClass:Load(xml, fileName) ConPrintf("missing name") else t_insert(self.partyMembers, { name = node.attrib.name, Aura = {}, Curse = {}, Warcry = { }, Link = {}, modDB = new("ModDB"), output = { }, enemyModList = new("ModList") }) + self.controls["Member"..#self.partyMembers.."Button"].label = "^7"..node.attrib.name local currentMember = self.partyMembers[#self.partyMembers] for _, node2 in ipairs(node) do if node2.attrib.name == "PartyMemberStats" then @@ -700,6 +738,7 @@ function PartyTabClass:Load(xml, fileName) elseif node.elem == "ImportedBuffs" then if not unknownMemeber then t_insert(self.partyMembers, { name = "Unknown", Aura = {}, Curse = {}, Warcry = { }, Link = {}, modDB = new("ModDB"), output = { }, enemyModList = new("ModList") }) + self.controls["Member"..#self.partyMembers.."Button"].label = "^7Unknown" unknownMemeber = self.partyMembers[#self.partyMembers] end if not node.attrib.name then @@ -921,6 +960,7 @@ function PartyTabClass:SwapSelectedMember(newMember, saveBuffers) end self.selectedMember = newMember if newMember ~= 1 then + self.controls.renameMember.buf = self.partyMembers[self.selectedMember].name self.controls.editPartyMemberStats.buf = self.partyMembers[self.selectedMember].editPartyMemberStats or "" self.controls.editAuras.buf = self.partyMembers[self.selectedMember].editAuras or "" self.controls.editCurses.buf = self.partyMembers[self.selectedMember].editCurses or "" @@ -928,6 +968,8 @@ function PartyTabClass:SwapSelectedMember(newMember, saveBuffers) self.controls.editLinks.buf = self.partyMembers[self.selectedMember].editLinks or "" self.controls.enemyCond.buf = self.partyMembers[self.selectedMember].enemyCond or "" self.controls.enemyMods.buf = self.partyMembers[self.selectedMember].enemyMods or "" + else + self.controls.renameMember.buf = "" end self.controls.simpleAuras.label = self.partyMembers[self.selectedMember].simpleAuras or "" self.controls.simpleCurses.label = self.partyMembers[self.selectedMember].simpleCurses or "" @@ -1224,7 +1266,11 @@ function PartyTabClass:CombineBuffs(filter) if not filter or filter == "PartyMemberStats" then self.actor.modDB:AddList(partyMember.modDB) for k, v in pairs(partyMember.output) do - self.actor.output[k] = v + if k == "MovementSpeedMod" then + self.actor.output[k] = m_max((self.actor.output[k] or 0), tonumber(v)) + else + self.actor.output[k] = v + end end end if not filter or filter == "Aura" then From 70b188e7bcb39293c5423843d477cc57afba69f3 Mon Sep 17 00:00:00 2001 From: Regisle Date: Tue, 24 Sep 2024 13:10:50 +0930 Subject: [PATCH 5/7] add colour codes for disabled and edited --- src/Classes/PartyTab.lua | 32 +++++++++++++++++++++++--------- 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/src/Classes/PartyTab.lua b/src/Classes/PartyTab.lua index 588e6b390d..e476300a62 100644 --- a/src/Classes/PartyTab.lua +++ b/src/Classes/PartyTab.lua @@ -415,7 +415,7 @@ local PartyTabClass = newClass("PartyTab", "ControlHost", "Control", function(se self.controls.renameMember = new("EditControl", {"LEFT",self.controls.ShowAdvanceTools,"RIGHT"}, {8, 0, 160, theme.buttonHeight}, "", nil, "%^", 15, function(buf) if self.selectedMember ~= 1 then - self.controls["Member"..self.selectedMember.."Button"].label = "^7"..buf + self.controls["Member"..self.selectedMember.."Button"].label = (self.partyMembers[self.selectedMember].NameColour or "^7")..buf self.partyMembers[self.selectedMember].name = buf end end, theme.stringHeight) @@ -428,7 +428,7 @@ local PartyTabClass = newClass("PartyTab", "ControlHost", "Control", function(se wipeTable(self.partyMembers[self.selectedMember]) t_remove(self.partyMembers, self.selectedMember) for i = self.selectedMember, #self.partyMembers do - self.controls["Member"..i.."Button"].label = "^7"..self.partyMembers[i].name + self.controls["Member"..i.."Button"].label = (self.partyMembers[i].NameColour or "^7")..self.partyMembers[i].name end self:CombineBuffs() self:SwapSelectedMember(1, false) @@ -459,6 +459,8 @@ local PartyTabClass = newClass("PartyTab", "ControlHost", "Control", function(se if self.selectedMember == 1 then for i, partyMember in ipairs(self.partyMembers) do if i ~= 1 then + partyMember.NameColour = "^1" + self.controls["Member"..i.."Button"].label = "^1"..partyMember.name partyMember["Aura"] = { } partyMember["Curse"] = { } partyMember["Warcry"] = { } @@ -472,6 +474,8 @@ local PartyTabClass = newClass("PartyTab", "ControlHost", "Control", function(se end else local partyMember = self.partyMembers[self.selectedMember] + partyMember.NameColour = "^1" + self.controls["Member"..self.selectedMember.."Button"].label = "^1"..partyMember.name partyMember["Aura"] = { } partyMember["Curse"] = { } partyMember["Warcry"] = { } @@ -498,6 +502,8 @@ local PartyTabClass = newClass("PartyTab", "ControlHost", "Control", function(se if self.selectedMember == 1 then for i, partyMember in ipairs(self.partyMembers) do if i ~= 1 then + partyMember.NameColour = "^7" + self.controls["Member"..i.."Button"].label = "^7"..partyMember.name partyMember["Aura"] = { } partyMember["Curse"] = { } partyMember["Warcry"] = { } @@ -518,6 +524,8 @@ local PartyTabClass = newClass("PartyTab", "ControlHost", "Control", function(se end else local partyMember = self.partyMembers[self.selectedMember] + partyMember.NameColour = "^7" + self.controls["Member"..self.selectedMember.."Button"].label = "^7"..partyMember.name partyMember["Aura"] = { } partyMember["Curse"] = { } partyMember["Warcry"] = { } @@ -571,11 +579,17 @@ local PartyTabClass = newClass("PartyTab", "ControlHost", "Control", function(se return (self.width > theme.widthThreshold1) and 0 or 24 end + local rebuildColourFunction = function(buf) + if not self.partyMembers[self.selectedMember].NameColour or self.partyMembers[self.selectedMember].NameColour ~= "^1" then + self.partyMembers[self.selectedMember].NameColour = "^4" + self.controls["Member"..self.selectedMember.."Button"].label = "^4"..self.partyMembers[self.selectedMember].name + end + end self.controls.editAurasLabel = new("LabelControl", {"TOPLEFT",self.controls.overviewButton,"TOPLEFT"}, {0, 40, 0, theme.stringHeight}, "^7Auras") self.controls.editAurasLabel.y = function() return 36 + ((self.width <= theme.widthThreshold1) and 24 or 0) end - self.controls.editAuras = new("EditControl", {"TOPLEFT",self.controls.editAurasLabel,"TOPLEFT"}, {0, 18, 0, 0}, "", nil, "^%C\t\n", nil, nil, 14, true) + self.controls.editAuras = new("EditControl", {"TOPLEFT",self.controls.editAurasLabel,"TOPLEFT"}, {0, 18, 0, 0}, "", nil, "^%C\t\n", nil, rebuildColourFunction, 14, true) self.controls.editAuras.width = function() return self.width / 2 - 16 end @@ -595,7 +609,7 @@ local PartyTabClass = newClass("PartyTab", "ControlHost", "Control", function(se self.controls.editWarcriesLabel.y = function() return (self.controls.ShowAdvanceTools.state and (self.selectedMember ~= 1)) and (self.controls.editAuras.height() + 8) or (theme.lineCounter(self.controls.simpleAuras.label) + 4) end - self.controls.editWarcries = new("EditControl", {"TOPLEFT",self.controls.editWarcriesLabel,"TOPLEFT"}, {0, 18, 0, 0}, "", nil, "^%C\t\n", nil, nil, 14, true) + self.controls.editWarcries = new("EditControl", {"TOPLEFT",self.controls.editWarcriesLabel,"TOPLEFT"}, {0, 18, 0, 0}, "", nil, "^%C\t\n", nil, rebuildColourFunction, 14, true) self.controls.editWarcries.width = function() return self.width / 2 - 16 end @@ -614,7 +628,7 @@ local PartyTabClass = newClass("PartyTab", "ControlHost", "Control", function(se self.controls.editLinksLabel.y = function() return (self.controls.ShowAdvanceTools.state and (self.selectedMember ~= 1)) and (self.controls.editWarcries.height() + 8) or (theme.lineCounter(self.controls.simpleWarcries.label) + 4) end - self.controls.editLinks = new("EditControl", {"TOPLEFT",self.controls.editLinksLabel,"TOPLEFT"}, {0, 18, 0, 0}, "", nil, "^%C\t\n", nil, nil, 14, true) + self.controls.editLinks = new("EditControl", {"TOPLEFT",self.controls.editLinksLabel,"TOPLEFT"}, {0, 18, 0, 0}, "", nil, "^%C\t\n", nil, rebuildColourFunction, 14, true) self.controls.editLinks.width = function() return self.width / 2 - 16 end @@ -630,7 +644,7 @@ local PartyTabClass = newClass("PartyTab", "ControlHost", "Control", function(se end self.controls.editPartyMemberStatsLabel = new("LabelControl", {"TOPLEFT",self.controls.notesDesc,"TOPRIGHT"}, {8, 0, 0, theme.stringHeight}, "^7Party Member Stats") - self.controls.editPartyMemberStats = new("EditControl", {"TOPLEFT",self.controls.editPartyMemberStatsLabel,"BOTTOMLEFT"}, {0, 2, 0, 0}, "", nil, "^%C\t\n", nil, nil, 14, true) + self.controls.editPartyMemberStats = new("EditControl", {"TOPLEFT",self.controls.editPartyMemberStatsLabel,"BOTTOMLEFT"}, {0, 2, 0, 0}, "", nil, "^%C\t\n", nil, rebuildColourFunction, 14, true) self.controls.editPartyMemberStats.width = function() return self.width / 2 - 16 end @@ -645,7 +659,7 @@ local PartyTabClass = newClass("PartyTab", "ControlHost", "Control", function(se self.controls.enemyCondLabel.y = function() return (self.controls.ShowAdvanceTools.state and (self.selectedMember ~= 1)) and (self.controls.editPartyMemberStats.height() + 8) or 4 end - self.controls.enemyCond = new("EditControl", {"TOPLEFT",self.controls.enemyCondLabel,"BOTTOMLEFT"}, {0, 2, 0, 0}, "", nil, "^%C\t\n", nil, nil, 14, true) + self.controls.enemyCond = new("EditControl", {"TOPLEFT",self.controls.enemyCondLabel,"BOTTOMLEFT"}, {0, 2, 0, 0}, "", nil, "^%C\t\n", nil, rebuildColourFunction, 14, true) self.controls.enemyCond.width = function() return self.width / 2 - 16 end @@ -664,7 +678,7 @@ local PartyTabClass = newClass("PartyTab", "ControlHost", "Control", function(se self.controls.enemyModsLabel.y = function() return (self.controls.ShowAdvanceTools.state and (self.selectedMember ~= 1)) and (self.controls.enemyCond.height() + 8) or (theme.lineCounter(self.controls.simpleEnemyCond.label) + 4) end - self.controls.enemyMods = new("EditControl", {"TOPLEFT",self.controls.enemyModsLabel,"BOTTOMLEFT"}, {0, 2, 0, 0}, "", nil, "^%C\t\n", nil, nil, 14, true) + self.controls.enemyMods = new("EditControl", {"TOPLEFT",self.controls.enemyModsLabel,"BOTTOMLEFT"}, {0, 2, 0, 0}, "", nil, "^%C\t\n", nil, rebuildColourFunction, 14, true) self.controls.enemyMods.width = function() return self.width / 2 - 16 end @@ -683,7 +697,7 @@ local PartyTabClass = newClass("PartyTab", "ControlHost", "Control", function(se self.controls.editCursesLabel.y = function() return (self.controls.ShowAdvanceTools.state and (self.selectedMember ~= 1)) and (self.controls.enemyMods.height() + 8) or (theme.lineCounter(self.controls.simpleEnemyMods.label) + 4) end - self.controls.editCurses = new("EditControl", {"TOPLEFT",self.controls.editCursesLabel,"BOTTOMLEFT"}, {0, 2, 0, 0}, "", nil, "^%C\t\n", nil, nil, 14, true) + self.controls.editCurses = new("EditControl", {"TOPLEFT",self.controls.editCursesLabel,"BOTTOMLEFT"}, {0, 2, 0, 0}, "", nil, "^%C\t\n", nil, rebuildColourFunction, 14, true) self.controls.editCurses.width = function() return self.width / 2 - 16 end From be79bc23264e660d6116b30b232abd5c6211861b Mon Sep 17 00:00:00 2001 From: Regisle Date: Tue, 24 Sep 2024 13:24:51 +0930 Subject: [PATCH 6/7] fix spelling and help file --- help.txt | 23 +++++++++++++---------- src/Classes/PartyTab.lua | 34 +++++++++++++++++----------------- 2 files changed, 30 insertions(+), 27 deletions(-) diff --git a/help.txt b/help.txt index b728173120..af3190c954 100644 --- a/help.txt +++ b/help.txt @@ -141,19 +141,22 @@ The "Sync" option is a backup option to force the UI to update in case the user The Party tab Allows you to import support characters and have their auras and curses apply -To import a build it must be exported with "Export support" enabled in the import/export tab and must be imported in the party tab -You can import a specific type like aura or curse, or import to all -You can also set it to append to a section rather than replace it (curses and links are always replaced if new one has a curse/link) +To import a build it must be exported with "Export support" enabled in the import/export tab and must be imported in the party tab. +You can import a specific type like aura or curse, or import to all. +You can also set it to append to a section rather than replace it in the advanced options (curses and links are always replaced if new one has a curse/link) -This does not add the auras, curses or links into the skills tab, but they do show up on calcs tab under "aura and buff skills" as well as "curses and debuffs" respectively -They also show other effects they add, like when physical damage reduction is applied by an aurabot with the Guardian node +These can be imported to a new member or overwriting the current one, these members can also be renamed but not reordered. +If the name is red it means its currently disabled (via advanced options), and if yellow it means its been edited without being rebuilt. -Auras with the highest effect will take priority -Your curses will take priority over a support's +This does not add the auras, curses, warcries or links into the skills tab, but they do show up on calcs tab under "aura and buff skills" as well as "curses and debuffs" respectively. +They also show other effects they add, like when physical damage reduction is applied by an aurabot with the Guardian node. -Links skills use stats from party members if they are exported -Some Enemy conditions and Modifiers may not be properly exported, please let us know if something is broken -Some auras like Mines which use a stack value for their effect will not apply as their stack value is missing +Auras with the highest effect will take priority. +Your curses will take priority over a support's. + +Links skills use stats from party members if they are exported. +Some Enemy conditions and Modifiers may not be properly exported, please let us know if something is broken. +Allied Flasks do not currently apply, and is a known issue. ---[Skills Tab] diff --git a/src/Classes/PartyTab.lua b/src/Classes/PartyTab.lua index e476300a62..4e9bc58996 100644 --- a/src/Classes/PartyTab.lua +++ b/src/Classes/PartyTab.lua @@ -715,7 +715,7 @@ local PartyTabClass = newClass("PartyTab", "ControlHost", "Control", function(se end) function PartyTabClass:Load(xml, fileName) - local unknownMemeber + local unknownMember for _, node in ipairs(xml) do if node.elem == "ImportedMember" then if not node.attrib.name then @@ -750,34 +750,34 @@ function PartyTabClass:Load(xml, fileName) end end elseif node.elem == "ImportedBuffs" then - if not unknownMemeber then + if not unknownMember then t_insert(self.partyMembers, { name = "Unknown", Aura = {}, Curse = {}, Warcry = { }, Link = {}, modDB = new("ModDB"), output = { }, enemyModList = new("ModList") }) self.controls["Member"..#self.partyMembers.."Button"].label = "^7Unknown" - unknownMemeber = self.partyMembers[#self.partyMembers] + unknownMember = self.partyMembers[#self.partyMembers] end if not node.attrib.name then ConPrintf("missing name") elseif node.attrib.name == "PartyMemberStats" then - unknownMemeber.editPartyMemberStats = node[1] or "" - self:ParseBuffs("PartyMemberStats", unknownMemeber, node[1] or "") + unknownMember.editPartyMemberStats = node[1] or "" + self:ParseBuffs("PartyMemberStats", unknownMember, node[1] or "") elseif node.attrib.name == "Aura" then - unknownMemeber.editAuras = node[1] or "" - self:ParseBuffs("Aura", unknownMemeber, node[1] or "") + unknownMember.editAuras = node[1] or "" + self:ParseBuffs("Aura", unknownMember, node[1] or "") elseif node.attrib.name == "Curse" then - unknownMemeber.editCurses = node[1] or "" - self:ParseBuffs("Curse", unknownMemeber, node[1] or "") + unknownMember.editCurses = node[1] or "" + self:ParseBuffs("Curse", unknownMember, node[1] or "") elseif node.attrib.name == "Warcry Skills" then - unknownMemeber.editWarcries = node[1] or "" - self:ParseBuffs("Warcry", unknownMemeber, node[1] or "") + unknownMember.editWarcries = node[1] or "" + self:ParseBuffs("Warcry", unknownMember, node[1] or "") elseif node.attrib.name == "Link Skills" then - unknownMemeber.editLinks = node[1] or "" - self:ParseBuffs("Link", unknownMemeber, node[1] or "") + unknownMember.editLinks = node[1] or "" + self:ParseBuffs("Link", unknownMember, node[1] or "") elseif node.attrib.name == "EnemyConditions" then - unknownMemeber.editPartyMemberStats = node[1] or "" - self:ParseBuffs("EnemyConditions", unknownMemeber, node[1] or "") + unknownMember.editPartyMemberStats = node[1] or "" + self:ParseBuffs("EnemyConditions", unknownMember, node[1] or "") elseif node.attrib.name == "EnemyMods" then - unknownMemeber.enemyMods = node[1] or "" - self:ParseBuffs("EnemyMods", unknownMemeber, node[1] or "") + unknownMember.enemyMods = node[1] or "" + self:ParseBuffs("EnemyMods", unknownMember, node[1] or "") end elseif node.elem == "ExportedBuffs" then if not node.attrib.name then From 6ddd3957b4f9dbda783dba85a02b6887fefbc3bb Mon Sep 17 00:00:00 2001 From: Regisle Date: Tue, 24 Sep 2024 15:30:48 +0930 Subject: [PATCH 7/7] fix remaining conprint --- src/Classes/PartyTab.lua | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Classes/PartyTab.lua b/src/Classes/PartyTab.lua index 4e9bc58996..49cd2e2cc9 100644 --- a/src/Classes/PartyTab.lua +++ b/src/Classes/PartyTab.lua @@ -1360,7 +1360,6 @@ function PartyTabClass:CombineBuffs(filter) local count = 0 local enemyModList = { } self.partyMembers[1].simpleEnemyMods = "^7---------------------------" - ConPrintTable(self.enemyModList) for _, mod in ipairs(self.enemyModList) do if not mod.name:match("Condition:Party") then enemyModList[mod.name] = enemyModList[mod.name] or { }