Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Party tab link skills #6636

Merged
merged 5 commits into from
Sep 11, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 9 additions & 9 deletions help.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---[Help File Introduction]

This file contains a list of shortcuts, and other misc information about PoB functionality
While holding shift scroll bars in help section and version history will jump to the previous/next section while scrolling
This file contains a list of shortcuts and other misc information about PoB functionality
While holding shift scroll bars in the help section and version history will jump to the previous/next section while scrolling

---[Contents]

Expand Down Expand Up @@ -53,7 +53,7 @@ Passive Tree Shortcuts:
Ctrl Hide tooltips while held
P Toggle node power
Ctrl + D Toggle stat diff display
PgUp/PgDn/MWheel Zoom in / out (hold with shift to increase amount of zoom x 3)
PgUp/PgDn/MWheel Zoom in / out (hold with shift to increase the amount of zoom x 3)
Ctrl + LMB Zoom in on mouse cursor position
Hold Shift Enable "path trace mode"
(highlighted nodes will stay highlighted, and will be allocated when a node is clicked on the tree)
Expand All @@ -80,7 +80,7 @@ Adding ^ and then a number or hex code before text will change the colour of the

---[Timeless Jewels]

Timeless jewels modify nodes in a radius based off their seed, the same seed will apply the same changes to the same small/notable nodes so that is the number you look for. The Conqueror (name on the jewel) only affects the keystone.
Timeless jewels modify nodes in a radius based on their seed, the same seed will apply the same changes to the same small/notable nodes so that is the number you look for. The Conqueror (name on the jewel) only affects the keystone.

Path of Building has an inbuilt tool in the tree tab to search through seeds to find stats that would be good for your build.
Clicking the "Find Timeless Jewel" button on the bottom bar in the tree tab will open a UI that lets you:
Expand Down Expand Up @@ -118,25 +118,25 @@ The Party tab Allows you to import support characters and have their auras and c

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 replacing it (curses are always replaced if new one has a curse)
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)

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

Auras with the highest effect will take priority
Your curses will take priority over a support's
For now Links skills are not exported or parsed

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

---[Items Tab]

The Item Tab in Path of Building allows you to plan out the gear you will use for your character. To access the Item Tab, click on the "Items" tab located at the top of the screen.

From here, you can view all of the gear slots for your character, such as your weapon, chest armor, and boots. To add an item to a slot, click on the arrow button on the right side of the slot. This will bring up a list of all the items available in your build, which are visible in the "All items" window.
From here, you can view all of the gear slots for your character, such as your weapon, chest armour, and boots. To add an item to a slot, click on the arrow button on the right side of the slot. This will bring up a list of all the items available in your build, which are visible in the "All items" window.
If you wish to add more items, you can copy and paste items using CTRL+C (from the game or trade website) and CTRL+V into the "Shared items" window. Additionally, you can craft items using the "Craft item..." button on the top or create completely customizable items using the "Create custom..." option.

The item sets section located at the top of the screen can be used to save multiple sets of items and easily switch between them. You can add, remove, rename, and copy new sets using the "Manage..." button.

If you want to search for item upgrades, you can use the "Trade for these items" button to quickly search for items that can improve your gear.
If you want to search for item upgrades, you can use the "Trade for these items" button to quickly search for items that can improve your gear.
67 changes: 52 additions & 15 deletions src/Classes/PartyTab.lua
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ local PartyTabClass = newClass("PartyTab", "ControlHost", "Control", function(se

self.build = build

self.actor = { Aura = { }, Curse = { }, Link = { }, ModList = new("ModList"), output = { } }
self.actor = { Aura = { }, Curse = { }, Link = { }, modDB = new("ModDB"), output = { } }
self.actor.modDB.actor = self.actor
self.enemyModList = new("ModList")
self.buffExports = { }
self.enableExportBuffs = false
Expand Down Expand Up @@ -89,8 +90,8 @@ local PartyTabClass = newClass("PartyTab", "ControlHost", "Control", function(se
self.actor["Curse"] = {}
end
if partyDestinations[self.controls.importCodeDestination.selIndex] == "All" or partyDestinations[self.controls.importCodeDestination.selIndex] == "Link Skills" then
self.controls.simpleLinks.label = "^7Link Skills are not currently supported"
self.controls.editCurses:SetText("")
self.controls.simpleLinks.label = ""
self.controls.editLinks:SetText("")
wipeTable(self.actor["Link"])
self.actor["Link"] = {}
end
Expand Down Expand Up @@ -152,6 +153,7 @@ local PartyTabClass = newClass("PartyTab", "ControlHost", "Control", function(se
end

local currentCurseBuffer = nil
local currentLinkBuffer = nil
if self.controls.appendNotReplace.state ~= true then
clearInputText()
else
Expand All @@ -166,6 +168,9 @@ local PartyTabClass = newClass("PartyTab", "ControlHost", "Control", function(se
self.actor["Curse"] = { }
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"] = { }
end
Expand Down Expand Up @@ -194,7 +199,7 @@ local PartyTabClass = newClass("PartyTab", "ControlHost", "Control", function(se
node[1] = self.controls.editPartyMemberStats.buf.."\n"..(node[1] or "")
end
self.controls.editPartyMemberStats:SetText(node[1] or "")
self:ParseBuffs(self.actor["ModList"], self.controls.editPartyMemberStats.buf, "PartyMemberStats", self.actor["output"])
self:ParseBuffs(self.actor["modDB"], self.controls.editPartyMemberStats.buf, "PartyMemberStats", self.actor["output"])
end
elseif node.attrib.name == "Aura" then
if partyDestinations[self.controls.importCodeDestination.selIndex] == "All" or partyDestinations[self.controls.importCodeDestination.selIndex] == "Aura" then
Expand All @@ -220,6 +225,9 @@ local PartyTabClass = newClass("PartyTab", "ControlHost", "Control", function(se
if #self.controls.editLinks.buf > 0 then
node[1] = self.controls.editLinks.buf.."\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)
end
Expand Down Expand Up @@ -321,7 +329,8 @@ local PartyTabClass = newClass("PartyTab", "ControlHost", "Control", function(se
self.controls.removeEffects = new("ButtonControl", {"LEFT",self.controls.ShowAdvanceTools,"RIGHT"}, 8, 0, 160, theme.buttonHeight, "Disable Party Effects", function()
wipeTable(self.actor)
wipeTable(self.enemyModList)
self.actor = { Aura = {}, Curse = {}, Link = {}, ModList = new("ModList"), output = { } }
self.actor = { Aura = {}, Curse = {}, Link = {}, modDB = new("ModDB"), output = { } }
self.actor.modDB.actor = self.actor
self.enemyModList = new("ModList")
self.build.buildFlag = true
end)
Expand All @@ -330,9 +339,10 @@ local PartyTabClass = newClass("PartyTab", "ControlHost", "Control", function(se
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 = {}, Link = {}, ModList = new("ModList"), output = { } }
self.actor = { Aura = {}, Curse = {}, Link = {}, modDB = new("ModDB"), output = { } }
self.actor.modDB.actor = self.actor
self.enemyModList = new("ModList")
self:ParseBuffs(self.actor["ModList"], self.controls.editPartyMemberStats.buf, "PartyMemberStats", self.actor["output"])
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["Link"], self.controls.editLinks.buf, "Link", self.controls.simpleLinks)
Expand Down Expand Up @@ -382,7 +392,7 @@ local PartyTabClass = newClass("PartyTab", "ControlHost", "Control", function(se
self.controls.editLinks.shown = function()
return self.controls.ShowAdvanceTools.state
end
self.controls.simpleLinks = new("LabelControl", {"TOPLEFT",self.controls.editLinksLabel,"TOPLEFT"}, 0, 18, 0, theme.stringHeight, "^7Link Skills are not currently supported")
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
end
Expand Down Expand Up @@ -465,7 +475,7 @@ function PartyTabClass:Load(xml, fileName)
ConPrintf("missing name")
elseif node.attrib.name == "PartyMemberStats" then
self.controls.editPartyMemberStats:SetText(node[1] or "")
self:ParseBuffs(self.actor["ModList"], node[1] or "", "PartyMemberStats", self.actor["output"])
self:ParseBuffs(self.actor["modDB"], node[1] or "", "PartyMemberStats", self.actor["output"])
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)
Expand Down Expand Up @@ -691,8 +701,16 @@ function PartyTabClass:ParseBuffs(list, buf, buffType, label)
for line in buf:gmatch("([^\n]*)\n?") do
if line:find("=") then
-- label is output for this type, as a special case
local k, v = line:match("([%w ]-%w+)=(.+)")
label[k] = v
if line:match("%.") then
local k1, k2, v = line:match("([%w ]-%w+)%.([%w ]-%w+)=(.+)")
label[k1] = {[k2] = tonumber(v)}
else
local k, v = line:match("([%w ]-%w+)=(.+)")
label[k] = tonumber(v)
if k == "Life" then -- special cases that needs to be mods
list:NewMod(k, "BASE", v, "Party")
end
end
elseif line ~= "" then
list:NewMod(line, "FLAG", true, "Party")
end
Expand All @@ -706,7 +724,7 @@ function PartyTabClass:ParseBuffs(list, buf, buffType, label)
local currentName
local currentEffect
local isMark
local currentModType = "Unknown"
local currentModType = (buffType == "Link") and "Link" or "Unknown"
for line in buf:gmatch("([^\n]*)\n?") do
if line ~= "---" and line:match("%-%-%-") then
-- comment but not divider, skip the line
Expand Down Expand Up @@ -743,7 +761,7 @@ function PartyTabClass:ParseBuffs(list, buf, buffType, label)
local mod = modLib.parseFormattedSourceMod(line)
if mod then
for _, tag in ipairs(mod) do
if tag.type == "GlobalEffect" and currentModType ~= "otherEffects" then
if tag.type == "GlobalEffect" and currentModType ~= "Link" and currentModType ~= "otherEffects" then
currentModType = tag.effectType
end
end
Expand Down Expand Up @@ -776,6 +794,14 @@ function PartyTabClass:ParseBuffs(list, buf, buffType, label)
_, mod.source = mod.source:match("Item:(%d+):(.+)")
mod.source = "Party - "..mod.source
end
if buffType == "Link" then
mod.name = mod.name:gsub("Parent", "PartyMember")
for _, modTag in ipairs(mod) do
if modTag.actor and modTag.actor == "parent" then
modTag.actor = "partyMembers"
end
end
end
listElement[currentName].modList:AddMod(mod)
end
end
Expand Down Expand Up @@ -831,6 +857,17 @@ function PartyTabClass:ParseBuffs(list, buf, buffType, label)
end
label.label = label.label.."---------------------------\n"
end
elseif buffType == "Link" then
local labelList = {}
for link, linkMod in pairs(list["Link"] or {}) do
t_insert(labelList, link..": "..linkMod.effectMult.."%\n")
end
if #labelList > 0 then
table.sort(labelList)
label.label = "^7---------------------------\n"..table.concat(labelList).."---------------------------\n"
else
label.label = ""
end
elseif buffType == "Curse" then
local labelList = {}
for curse, curseMod in pairs(list["Curse"] or {}) do
Expand Down Expand Up @@ -876,7 +913,7 @@ function PartyTabClass:exportBuffs(buffType)
else
buf = buf.."\nfalse"
end
elseif buffType == "Aura" and buffName ~= "extraAura" and buffName ~= "otherEffects" then
elseif buffType == "Link" or buffType == "Aura" and buffName ~= "extraAura" and buffName ~= "otherEffects" then
buf = buf.."\n"..tostring(buff.effectMult * 100)
end
if buffType == "Aura" and buffName == "otherEffects" then
Expand All @@ -886,7 +923,7 @@ function PartyTabClass:exportBuffs(buffType)
end
end
buf = buf.."\n---"
elseif buffType == "Curse" or buffType == "Aura" then
elseif buffType == "Curse" or buffType == "Aura" or buffType == "Link" then
for _, mod in ipairs(buff.modList) do
buf = buf.."\n"..modLib.formatSourceMod(mod)
end
Expand Down
13 changes: 13 additions & 0 deletions src/Modules/CalcDefence.lua
Original file line number Diff line number Diff line change
Expand Up @@ -407,6 +407,8 @@ function calcs.defence(env, actor)
output.BlockChanceMax = modDB:Sum("BASE", nil, "BlockChanceMax")
if modDB:Flag(nil, "MaximumBlockAttackChanceIsEqualToParent") then
output.BlockChanceMax = actor.parent.output.BlockChanceMax
elseif modDB:Flag(nil, "MaximumBlockAttackChanceIsEqualToPartyMember") then
output.BlockChanceMax = actor.partyMembers.output.BlockChanceMax
end
output.BlockChanceOverCap = 0
output.SpellBlockChanceOverCap = 0
Expand All @@ -420,6 +422,8 @@ function calcs.defence(env, actor)
output.ShieldBlockChance = baseBlockChance
if modDB:Flag(nil, "BlockAttackChanceIsEqualToParent") then
output.BlockChance = actor.parent.output.BlockChance
elseif modDB:Flag(nil, "BlockAttackChanceIsEqualToPartyMember") then
output.BlockChance = actor.partyMembers.output.BlockChance
elseif modDB:Flag(nil, "MaxBlockIfNotBlockedRecently") then
output.BlockChance = output.BlockChanceMax
else
Expand Down Expand Up @@ -829,6 +833,8 @@ function calcs.defence(env, actor)
output.ShieldBlockChance = baseBlockChance
if modDB:Flag(nil, "BlockAttackChanceIsEqualToParent") then
output.BlockChance = actor.parent.output.BlockChance
elseif modDB:Flag(nil, "BlockAttackChanceIsEqualToPartyMember") then
output.BlockChance = actor.partyMembers.output.BlockChance
elseif modDB:Flag(nil, "MaxBlockIfNotBlockedRecently") then
output.BlockChance = output.BlockChanceMax
else
Expand Down Expand Up @@ -910,6 +916,8 @@ function calcs.defence(env, actor)
output.MaxLifeLeechRatePercent = calcLib.val(modDB, "MaxLifeLeechRate")
if modDB:Flag(nil, "MaximumLifeLeechIsEqualToParent") then
output.MaxLifeLeechRatePercent = actor.parent.output.MaxLifeLeechRatePercent
elseif modDB:Flag(nil, "MaximumLifeLeechIsEqualToPartyMember") then
output.MaxLifeLeechRatePercent = actor.partyMembers.output.MaxLifeLeechRatePercent
end
output.MaxLifeLeechRate = output.Life * output.MaxLifeLeechRatePercent / 100
if breakdown then
Expand Down Expand Up @@ -2069,6 +2077,11 @@ function calcs.buildDefenceEstimations(env, actor)
output["SoulLinkMitigation"] = modDB:Sum("BASE", nil, "TakenFromParentESBeforeYou")
if output["SoulLinkMitigation"] ~= 0 then
output["AlliedEnergyShield"] = actor.parent.output.EnergyShieldRecoveryCap or 0
else
output["SoulLinkMitigation"] = modDB:Sum("BASE", nil, "TakenFromPartyMemberESBeforeYou")
if output["SoulLinkMitigation"] ~= 0 then
output["AlliedEnergyShield"] = actor.partyMembers.output.EnergyShieldRecoveryCap or 0
end
end
end

Expand Down
Loading