Skip to content

Commit

Permalink
fix(server/inventory): clean-up random loot generation
Browse files Browse the repository at this point in the history
Remove recursion and safeguard against potential infinite recursion.
May resolve #1645 (no full repro provided).
  • Loading branch information
thelindat committed May 9, 2024
1 parent e4bb063 commit 01fe7f8
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 24 deletions.
2 changes: 1 addition & 1 deletion init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ if IsDuplicityVersion() then
trimplate = GetConvarInt('inventory:trimplate', 1) == 1,
vehicleloot = json.decode(GetConvar('inventory:vehicleloot', [[
[
["cola", 1, 1],
["sprunk", 1, 1],
["water", 1, 1],
["garbage", 1, 2, 50],
["panties", 1, 1, 5],
Expand Down
70 changes: 47 additions & 23 deletions modules/inventory/server.lua
Original file line number Diff line number Diff line change
Expand Up @@ -703,34 +703,58 @@ function Inventory.Save(inv)
return db.saveStash(inv.owner, inv.dbId, data)
end

---@alias RandomLoot { [1]: string, [2]: number, [3]: number, [4]?: number }

---@param loot RandomLoot[]
---@param items RandomLoot[]
---@param size number
---@return RandomLoot
local function randomItem(loot, items, size)
local item = loot[math.random(1, size)]
for i = 1, #items do
if items[i][1] == item[1] then
return randomItem(loot, items, size)
end
end
return item
local itemIndex = math.random(1, size)
local selectedItem = nil

for _ = 1, size do
selectedItem = loot[itemIndex]
local found = false

for i = 1, #items do
if items[i][1] == selectedItem[1] then
found = true
break
end
end

if not found then break end

itemIndex = ((itemIndex - 1) % size) + 1
end

return selectedItem
end

---@param loot RandomLoot[]
---@return RandomLoot[]
local function randomLoot(loot)
local items = {}

if loot then
local size = #loot
for i = 1, math.random(0, 3) do
if i > size then return items end
local item = randomItem(loot, items, size)
if math.random(1, 100) <= (item[4] or 80) then
local count = math.random(item[2], item[3])
if count > 0 then
items[#items+1] = {item[1], count}
end
end
end
end
---@type RandomLoot[]
local items = {}
local size = #loot
local itemCount = math.random(0, 3)

for _ = 1, itemCount do
if #items >= size then break end

local item = randomItem(loot, items, size)

if item and math.random(1, 100) <= (item[4] or 80) then
local count = math.random(item[2], item[3])

if count > 0 then
items[#items + 1] = { item[1], count }
end
end
end

return items
return items
end

---@param inv inventory
Expand Down

0 comments on commit 01fe7f8

Please sign in to comment.