Skip to content
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
19 changes: 19 additions & 0 deletions spec/System/TestSkills_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,25 @@ describe("TestSkills", function()
assert.True(math.abs(finalCost - 8.67) < 0.1) -- floor(9 * 1.5) / 1.5
end)

it("Fractional skill count scales Full DPS", function()
build.skillsTab:PasteSocketGroup("Ball Lightning 20/0 1")
build.skillsTab.socketGroupList[1].includeInFullDPS = true
runCallback("OnFrame")

local fullDPS = build.calcsTab.mainOutput.FullDPS
assert.truthy(fullDPS)
assert.True(fullDPS > 0)

newBuild()

build.skillsTab:PasteSocketGroup("Ball Lightning 20/0 0.5")
build.skillsTab.socketGroupList[1].includeInFullDPS = true
runCallback("OnFrame")

assert.are.equals(0.5, build.skillsTab.socketGroupList[1].gemList[1].count)
assert.True(math.abs(build.calcsTab.mainOutput.FullDPS - fullDPS * 0.5) < fullDPS * 0.001)
end)

it("Test mana cost efficiency with support gems", function()
-- Test interaction between cost efficiency and cost multipliers
build.skillsTab:PasteSocketGroup("Contagion 6/0 1\nMagnified Area I 1/0 1")
Expand Down
10 changes: 7 additions & 3 deletions src/Classes/EditControl.lua
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ local EditClass = newClass("EditControl", "ControlHost", "Control", "UndoHandler
local _, height = self:GetSize()
return height - 4
end
if self.filter == "%D" or self.filter == "^%-%d" then
if self.filter == "%D" or self.filter == "^%-%d" or self.filter == "^%d." then
-- Add +/- buttons for integer number edits
self.isNumeric = true
self.controls.buttonDown = new("ButtonControl", {"RIGHT",self,"RIGHT"}, {-2, 0, buttonSize, buttonSize}, "-", function()
Expand Down Expand Up @@ -686,8 +686,12 @@ function EditClass:OnKeyUp(key)
end
end
elseif key == "WHEELDOWN" or key == "DOWN" then
if cur and (self.filter ~= "%D" or cur > 0)then
self:SetText(tostring(cur - (self.numberInc or 1)), true)
if cur then
local value = cur - (self.numberInc or 1)
if self.filter == "%D" or self.filter == "^%d." then
value = m_max(value, 0)
end
self:SetText(tostring(value), true)
else
if self.placeholder then
self:SetText(tostring((tonumber(self.placeholder) or 0) - (self.numberInc or 1)), true)
Expand Down
15 changes: 7 additions & 8 deletions src/Classes/SkillsTab.lua
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ local SkillsTabClass = newClass("SkillsTab", "UndoHandler", "ControlHost", "Cont
self.controls.groupCountLabel.shown = function()
return self.displayGroup.source ~= nil
end
self.controls.groupCount = new("EditControl", { "LEFT", self.controls.groupCountLabel, "RIGHT" }, { 4, 0, 60, 20 }, nil, nil, "%D", 2, function(buf)
self.controls.groupCount = new("EditControl", { "LEFT", self.controls.groupCountLabel, "RIGHT" }, { 4, 0, 80, 20 }, nil, nil, "^%d.", 6, function(buf)
self.displayGroup.groupCount = tonumber(buf) or 1
self:AddUndoState()
self.build.buildFlag = true
Expand Down Expand Up @@ -254,7 +254,7 @@ will automatically apply to the skill.]]
self.controls.gemLevelHeader = new("LabelControl", {"BOTTOMLEFT", self.gemSlots[1].level, "TOPLEFT"}, {0, -2, 0, 16}, "^7Level:")
self.controls.gemQualityHeader = new("LabelControl", {"BOTTOMLEFT", self.gemSlots[1].quality, "TOPLEFT"}, {0, -2, 0, 16}, "^7Quality:")
self.controls.gemEnableHeader = new("LabelControl", {"BOTTOMLEFT", self.gemSlots[1].enabled, "TOPLEFT"}, {-16, -2, 0, 16}, "^7Enabled:")
self.controls.gemCountHeader = new("LabelControl", {"BOTTOMLEFT", self.gemSlots[1].count, "TOPLEFT"}, {8, -2, 0, 16}, "^7Count:")
self.controls.gemCountHeader = new("LabelControl", {"BOTTOMLEFT", self.gemSlots[1].count, "TOPLEFT"}, {18, -2, 0, 16}, "^7Count:")
end)

function SkillsTabClass:LoadSkill(node, skillSetId)
Expand Down Expand Up @@ -506,7 +506,7 @@ function SkillsTabClass:Draw(viewPort, inputEvents)
self.controls.scrollBarH.y = viewPort.y + viewPort.height - 18

do
local maxX = self.controls.gemCountHeader:GetPos() + self.controls.gemCountHeader:GetSize() + 15
local maxX = self.controls.gemCountHeader:GetPos() + self.controls.gemCountHeader:GetSize() + 25
local contentWidth = maxX - self.x
self.controls.scrollBarH:SetContentDimension(contentWidth, viewPort.width)
end
Expand Down Expand Up @@ -568,7 +568,7 @@ function SkillsTabClass:CopySocketGroup(socketGroup)
skillText = skillText .. "Slot: " .. socketGroup.slot .. "\r\n"
end
for _, gemInstance in ipairs(socketGroup.gemList) do
skillText = skillText .. string.format("%s %d/%d %s %d\r\n", gemInstance.nameSpec, gemInstance.level, gemInstance.quality, gemInstance.enabled and "" or "DISABLED", gemInstance.count or 1)
skillText = skillText .. string.format("%s %d/%d %s %s\r\n", gemInstance.nameSpec, gemInstance.level, gemInstance.quality, gemInstance.enabled and "" or "DISABLED", string.format("%g", gemInstance.count or 1))
end
Copy(skillText)
end
Expand All @@ -585,7 +585,7 @@ function SkillsTabClass:PasteSocketGroup(testInput)
if slot then
newGroup.slot = slot
end
for nameSpec, level, quality, state, count in skillText:gmatch("([ %a']+) (%d+)/(%d+) ?(%a*) (%d+)") do
for nameSpec, level, quality, state, count in skillText:gmatch("([ %a']+) (%d+)/(%d+) ?(%a*) ([%d%.]+)") do
t_insert(newGroup.gemList, {
nameSpec = nameSpec,
level = tonumber(level) or 20,
Expand Down Expand Up @@ -853,7 +853,7 @@ function SkillsTabClass:CreateGemSlot(index)
self.controls["gemSlot"..index.."Enable"] = slot.enabled

-- Count gem
slot.count = new("EditControl", {"LEFT",slot.enabled,"RIGHT"}, {18, 0, 60, 20}, nil, nil, "%D", 2, function(buf)
slot.count = new("EditControl", {"LEFT",slot.enabled,"RIGHT"}, {18, 0, 80, 20}, nil, nil, "^%d.", 5, function(buf)
local gemInstance = self.displayGroup.gemList[index]
if not gemInstance then
gemInstance = { nameSpec = "", level = self.defaultGemLevel or 20, quality = self.defaultGemQuality or 0, enabled = true, enableGlobal1 = true, count = 1, new = true }
Expand All @@ -864,7 +864,6 @@ function SkillsTabClass:CreateGemSlot(index)
slot.enableGlobal1.state = true
end
gemInstance.count = tonumber(buf) or 1
slot.count.buf = tostring(gemInstance.count)
self:ProcessSocketGroup(self.displayGroup)
self:AddUndoState()
self.build.buildFlag = true
Expand All @@ -883,7 +882,7 @@ function SkillsTabClass:CreateGemSlot(index)
end
slot.count.tooltipFunc = function(tooltip)
if tooltip:CheckForUpdate(self.build.outputRevision, self.displayGroup) then
tooltip:AddLine(16, "^8Note: `count` integer value scales the DPS of associated skill by a scalar.")
tooltip:AddLine(16, "^8Note: `count` numeric value scales the DPS of associated skill by a scalar.")
tooltip:AddLine(16, "^8To be used with totems, minions, shot-gunning of projectiles (e.g., VD, magma-orbs),")
tooltip:AddLine(16, "^8multi-hit projectiles (e.g. ball-lightning), traps, mines.")
end
Expand Down
14 changes: 8 additions & 6 deletions src/Modules/Build.lua
Original file line number Diff line number Diff line change
Expand Up @@ -1007,11 +1007,12 @@ function buildMode:Save(xml)
if skillData.trigger and skillData.trigger ~= "" then
triggerStr = skillData.trigger
end
local skillCount = skillData.count or 1
local lhsString = skillData.name
if skillData.count >= 2 then
lhsString = tostring(skillData.count).."x "..skillData.name
if skillCount ~= 1 then
lhsString = s_format("%g", skillCount).."x "..skillData.name
end
t_insert(xml, { elem = "FullDPSSkill", attrib = { stat = lhsString, value = tostring(skillData.dps * skillData.count), skillPart = skillData.skillPart or "", source = skillData.source or skillData.trigger or "" } })
t_insert(xml, { elem = "FullDPSSkill", attrib = { stat = lhsString, value = tostring(skillData.dps * skillCount), skillPart = skillData.skillPart or "", source = skillData.source or skillData.trigger or "" } })
end
addedStatNames[statName] = true
else
Expand Down Expand Up @@ -1928,14 +1929,15 @@ function buildMode:AddDisplayStatList(statList, actor)
if skillData.trigger and skillData.trigger ~= "" then
triggerStr = colorCodes.WARNING.." ("..skillData.trigger..")"..labelColor
end
local skillCount = skillData.count or 1
local lhsString = labelColor..skillData.name..triggerStr..":"
if skillData.count >= 2 then
lhsString = labelColor..tostring(skillData.count).."x "..skillData.name..triggerStr..":"
if skillCount ~= 1 then
lhsString = labelColor..s_format("%g", skillCount).."x "..skillData.name..triggerStr..":"
end
t_insert(statBoxList, {
height = 16,
lhsString,
self:FormatStat({fmt = "1.f"}, skillData.dps * skillData.count, overCapStatVal),
self:FormatStat({fmt = "1.f"}, skillData.dps * skillCount, overCapStatVal),
})
if skillData.skillPart then
t_insert(statBoxList, {
Expand Down
Loading