Skip to content

Commit 1c75452

Browse files
author
LocalIdentity
committed
Merge branch 'dev' into fix/jewels-and-radius-in-compare-tree
2 parents a499960 + 2e68973 commit 1c75452

96 files changed

Lines changed: 14562 additions & 12844 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.busted

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
return {
22
_all = {
3-
coverage = true,
3+
coverage = false,
44
verbose = true,
55
},
66
default = {

.github/workflows/test.yml

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,6 @@ jobs:
1414
uses: actions/checkout@v4
1515
- name: Run tests
1616
run: busted --lua=luajit
17-
- name: Report coverage
18-
continue-on-error: true # May fail on server errors (of coveralls.io)
19-
run: cd src; luacov-coveralls --repo-token=${{ secrets.github_token }} -e TestData -e Data -e runtime
2017
check_modcache:
2118
runs-on: ubuntu-latest
2219
container: ghcr.io/pathofbuildingcommunity/pathofbuilding-tests:latest

runtime/lua/socket.lua

Lines changed: 96 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -17,53 +17,56 @@ local _M = socket
1717
-- Exported auxiliar functions
1818
-----------------------------------------------------------------------------
1919
function _M.connect4(address, port, laddress, lport)
20-
return socket.connect(address, port, laddress, lport, "inet")
20+
return socket.connect(address, port, laddress, lport, "inet")
2121
end
2222

2323
function _M.connect6(address, port, laddress, lport)
24-
return socket.connect(address, port, laddress, lport, "inet6")
24+
return socket.connect(address, port, laddress, lport, "inet6")
2525
end
2626

2727
function _M.bind(host, port, backlog)
28-
if host == "*" then host = "0.0.0.0" end
29-
local addrinfo, err = socket.dns.getaddrinfo(host);
30-
if not addrinfo then return nil, err end
31-
local sock, res
32-
err = "no info on address"
33-
for i, alt in base.ipairs(addrinfo) do
34-
if alt.family == "inet" then
35-
sock, err = socket.tcp4()
36-
else
37-
sock, err = socket.tcp6()
38-
end
39-
if not sock then return nil, err end
40-
sock:setoption("reuseaddr", true)
41-
res, err = sock:bind(alt.addr, port)
42-
if not res then
43-
sock:close()
44-
else
45-
res, err = sock:listen(backlog)
46-
if not res then
47-
sock:close()
48-
else
49-
return sock
50-
end
51-
end
52-
end
53-
return nil, err
28+
if host == "*" then host = "0.0.0.0" end
29+
local addrinfo, err = socket.dns.getaddrinfo(host);
30+
if not addrinfo then return nil, err end
31+
local sock, res
32+
err = "no info on address"
33+
for i, alt in base.ipairs(addrinfo) do
34+
if alt.family == "inet" then
35+
sock, err = socket.tcp4()
36+
else
37+
sock, err = socket.tcp6()
38+
end
39+
if not sock then return nil, err end
40+
-- sock:setoption("reuseaddr", true)
41+
res, err = sock:bind(alt.addr, port)
42+
if not res then
43+
sock:close()
44+
else
45+
res, err = sock:listen(backlog)
46+
if not res then
47+
sock:close()
48+
else
49+
return sock
50+
end
51+
end
52+
end
53+
return nil, err
5454
end
5555

5656
_M.try = _M.newtry()
5757

5858
function _M.choose(table)
59-
return function(name, opt1, opt2)
60-
if base.type(name) ~= "string" then
61-
name, opt1, opt2 = "default", name, opt1
62-
end
63-
local f = table[name or "nil"]
64-
if not f then base.error("unknown key (".. base.tostring(name) ..")", 3)
65-
else return f(opt1, opt2) end
66-
end
59+
return function(name, opt1, opt2)
60+
if base.type(name) ~= "string" then
61+
name, opt1, opt2 = "default", name, opt1
62+
end
63+
local f = table[name or "nil"]
64+
if not f then
65+
base.error("unknown key (" .. base.tostring(name) .. ")", 3)
66+
else
67+
return f(opt1, opt2)
68+
end
69+
end
6770
end
6871

6972
-----------------------------------------------------------------------------
@@ -77,68 +80,76 @@ _M.sinkt = sinkt
7780
_M.BLOCKSIZE = 2048
7881

7982
sinkt["close-when-done"] = function(sock)
80-
return base.setmetatable({
81-
getfd = function() return sock:getfd() end,
82-
dirty = function() return sock:dirty() end
83-
}, {
84-
__call = function(self, chunk, err)
85-
if not chunk then
86-
sock:close()
87-
return 1
88-
else return sock:send(chunk) end
89-
end
90-
})
83+
return base.setmetatable({
84+
getfd = function() return sock:getfd() end,
85+
dirty = function() return sock:dirty() end
86+
}, {
87+
__call = function(self, chunk, err)
88+
if not chunk then
89+
sock:close()
90+
return 1
91+
else
92+
return sock:send(chunk)
93+
end
94+
end
95+
})
9196
end
9297

9398
sinkt["keep-open"] = function(sock)
94-
return base.setmetatable({
95-
getfd = function() return sock:getfd() end,
96-
dirty = function() return sock:dirty() end
97-
}, {
98-
__call = function(self, chunk, err)
99-
if chunk then return sock:send(chunk)
100-
else return 1 end
101-
end
102-
})
99+
return base.setmetatable({
100+
getfd = function() return sock:getfd() end,
101+
dirty = function() return sock:dirty() end
102+
}, {
103+
__call = function(self, chunk, err)
104+
if chunk then
105+
return sock:send(chunk)
106+
else
107+
return 1
108+
end
109+
end
110+
})
103111
end
104112

105113
sinkt["default"] = sinkt["keep-open"]
106114

107115
_M.sink = _M.choose(sinkt)
108116

109117
sourcet["by-length"] = function(sock, length)
110-
return base.setmetatable({
111-
getfd = function() return sock:getfd() end,
112-
dirty = function() return sock:dirty() end
113-
}, {
114-
__call = function()
115-
if length <= 0 then return nil end
116-
local size = math.min(socket.BLOCKSIZE, length)
117-
local chunk, err = sock:receive(size)
118-
if err then return nil, err end
119-
length = length - string.len(chunk)
120-
return chunk
121-
end
122-
})
118+
return base.setmetatable({
119+
getfd = function() return sock:getfd() end,
120+
dirty = function() return sock:dirty() end
121+
}, {
122+
__call = function()
123+
if length <= 0 then return nil end
124+
local size = math.min(socket.BLOCKSIZE, length)
125+
local chunk, err = sock:receive(size)
126+
if err then return nil, err end
127+
length = length - string.len(chunk)
128+
return chunk
129+
end
130+
})
123131
end
124132

125133
sourcet["until-closed"] = function(sock)
126-
local done
127-
return base.setmetatable({
128-
getfd = function() return sock:getfd() end,
129-
dirty = function() return sock:dirty() end
130-
}, {
131-
__call = function()
132-
if done then return nil end
133-
local chunk, err, partial = sock:receive(socket.BLOCKSIZE)
134-
if not err then return chunk
135-
elseif err == "closed" then
136-
sock:close()
137-
done = 1
138-
return partial
139-
else return nil, err end
140-
end
141-
})
134+
local done
135+
return base.setmetatable({
136+
getfd = function() return sock:getfd() end,
137+
dirty = function() return sock:dirty() end
138+
}, {
139+
__call = function()
140+
if done then return nil end
141+
local chunk, err, partial = sock:receive(socket.BLOCKSIZE)
142+
if not err then
143+
return chunk
144+
elseif err == "closed" then
145+
sock:close()
146+
done = 1
147+
return partial
148+
else
149+
return nil, err
150+
end
151+
end
152+
})
142153
end
143154

144155

spec/System/TestDefence_spec.lua

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -527,7 +527,7 @@ describe("TestDefence", function()
527527
assert.are.equals(0, floor(poolsRemaining.Life))
528528
assert.are.equals(0, floor(poolsRemaining.OverkillDamage))
529529
end)
530-
530+
531531
it("uses block chance against projectile spells", function()
532532
build.configTab.input.enemyIsBoss = "None"
533533
build.configTab.input.enemyDamageType = "SpellProjectile"
@@ -549,4 +549,43 @@ describe("TestDefence", function()
549549
assert.are.equals(15, build.calcsTab.calcsOutput.EffectiveAverageBlockChance)
550550
assert.are.equals(85, build.calcsTab.calcsOutput.ConfiguredDamageChance)
551551
end)
552+
553+
it("limits EHP speedup when hit damage is delayed", function()
554+
local function assertClose(actual, expected)
555+
assert.is_true(math.abs(actual - expected) < 0.01)
556+
end
557+
558+
local function calcEHP(extraMods)
559+
build.configTab.input.enemyPhysicalDamage = "500"
560+
build.configTab.input.enemyFireDamage = "500"
561+
build.configTab.input.enemyColdDamage = "500"
562+
build.configTab.input.enemyLightningDamage = "500"
563+
build.configTab.input.enemyChaosDamage = "0"
564+
build.configTab.input.customMods = [[
565+
+4000 to maximum Life
566+
75% of Life Loss from Hits is prevented, then that much Life is lost over 4 seconds instead
567+
+75% to all Elemental Resistances
568+
+75% to Chaos Resistance
569+
]] .. (extraMods or "")
570+
pob1and2Compat()
571+
runCallback("OnFrame")
572+
runCallback("OnFrame")
573+
local calcsOutput = build.calcsTab.calcsOutput
574+
return {
575+
TotalEHP = calcsOutput.TotalEHP,
576+
EffectiveBlockChance = calcsOutput.EffectiveBlockChance,
577+
NumberOfMitigatedDamagingHits = calcsOutput.NumberOfMitigatedDamagingHits,
578+
}
579+
end
580+
581+
local base = calcEHP()
582+
local block = calcEHP("\n+10% to Block chance\n")
583+
584+
newBuild()
585+
586+
assertClose(base.TotalEHP, 17582.417582418)
587+
assertClose(block.TotalEHP, 19008.019008019)
588+
assertClose(block.EffectiveBlockChance, 10)
589+
assert.is_true(block.TotalEHP > base.TotalEHP)
590+
end)
552591
end)

spec/System/TestItemMods_spec.lua

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,25 @@ describe("TetsItemMods", function()
4040
assert.are.equals(68, build.calcsTab.mainOutput.ChaosResistTotal)
4141
end)
4242

43+
it("sorts defensive item stats when the best score is negative", function()
44+
build.configTab.input.enemyFireDamage = "1000"
45+
build.configTab:BuildModList()
46+
runCallback("OnFrame")
47+
48+
local itemDB = build.itemsTab.controls.uniqueDB
49+
itemDB.db = { list = {
50+
new("Item", "New Item\nRing"),
51+
new("Item", "New Item\nRing\n+50% to Fire Resistance"),
52+
new("Item", "New Item\nBroadhead Quiver"),
53+
} }
54+
itemDB:SetSortMode("FireTakenHit")
55+
56+
itemDB:ListBuilder()
57+
58+
assert.is_true(itemDB.list[1].measuredPower < 0)
59+
assert.are.equals(-math.huge, itemDB.list[#itemDB.list].measuredPower)
60+
end)
61+
4362
it("Both slots mod (evasion and es mastery)", function()
4463

4564
build.configTab.input.customMods = "\z
@@ -655,4 +674,45 @@ describe("TetsItemMods", function()
655674
assert.are.equals(0, smallModList:Sum("BASE", nil, "Str"))
656675
assert.are.equals(11, smallModList:Sum("BASE", nil, "Dex"))
657676
end)
677+
678+
it("ancestral bond", function()
679+
build.itemsTab:CreateDisplayItemFromRaw([[
680+
Rarity: UNIQUE
681+
Hoghunt
682+
Felled Greatclub
683+
Variant: Pre 0.1.1
684+
Variant: Current
685+
Selected Variant: 2
686+
Quality: 20
687+
LevelReq: 0
688+
Implicits: 0
689+
{variant:1}{range:0.5}(100-150)% increased Physical Damage
690+
{variant:2}{range:0.5}Adds (16-20) to (23-27) Physical Damage
691+
+15% to Critical Hit Chance
692+
10% reduced Attack Speed
693+
+10 to Strength
694+
Maim on Critical Hit
695+
]])
696+
build.itemsTab:AddDisplayItem()
697+
runCallback("OnFrame")
698+
699+
build.skillsTab:PasteSocketGroup("Ancestral Warrior Totem 20/0 2")
700+
runCallback("OnFrame")
701+
702+
build.configTab.input.customMods = [[
703+
Totems reserve 75 spirit each
704+
+100 spirit
705+
]]
706+
build.configTab:BuildModList()
707+
runCallback("OnFrame")
708+
assert.are.equals(150, build.calcsTab.mainOutput.SpiritReserved)
709+
710+
build.configTab.input.customMods = [[
711+
Totems reserve 75 spirit each
712+
100% increased spirit reservation efficiency
713+
]]
714+
build.configTab:BuildModList()
715+
runCallback("OnFrame")
716+
assert.are.equals(76, build.calcsTab.mainOutput.SpiritReserved)
717+
end)
658718
end)

spec/System/TestItemParse_spec.lua

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,35 @@ describe("TestItemParse", function()
200200
assert.are.equals("VolatileDeadPlayer", item.grantedSkills[1].skillId)
201201
end)
202202

203+
it("Crafted affixes matching base implicit ranges stay explicit", function()
204+
local item = new("Item", [[
205+
Rarity: Rare
206+
New Item
207+
Solar Amulet
208+
Crafted: true
209+
Prefix: {range:0}IncreasedSpirit4
210+
Prefix: None
211+
Prefix: None
212+
Suffix: None
213+
Suffix: None
214+
Suffix: None
215+
Implicits: 1
216+
+(10-15) to Spirit
217+
]])
218+
219+
item:Craft()
220+
assert.are.equals(1, #item.implicitModLines)
221+
assert.are.equals("+(10-15) to Spirit", item.implicitModLines[1].line)
222+
assert.are.equals(1, #item.explicitModLines)
223+
assert.are.equals("+43 to Spirit", item.explicitModLines[1].line)
224+
225+
item.prefixes[1].range = 0.2
226+
item:Craft()
227+
assert.are.equals(1, #item.implicitModLines)
228+
assert.are.equals(1, #item.explicitModLines)
229+
assert.are.equals("+44 to Spirit", item.explicitModLines[1].line)
230+
end)
231+
203232
--TODO: POB2 Leagues?
204233
--it("League", function()
205234
--end)

0 commit comments

Comments
 (0)