Module:Vendor List
From Kenshi Wiki
More actions
From https://kenshi.fandom.com/wiki/Module:Vendor_List
local p = {}
-- TODO: Figure out a way to make this mw.loadData
local vendorData = require('Module:Vendor List/data')
local get_armour_grades = require('Module:Faction').get_armour_grades
local vendor_templates = {
['weapons'] = {title = 'Vendor/Weapon'},
['clothing'] = {title = 'Vendor/Armour'},
['items'] = {title = 'Vendor/Entry'}
}
function p.main(frame)
local args = frame:getParent().args
local names = string.split(args['vendors'],',')
local closed = args['collapsed'] ~= nil
local faction = args['faction']
local rolls = args['rolls']
return p._display_vendor(names, closed, faction, rolls, frame)
end
function p._display_vendor(vendors, closed, faction, rolls, frame)
local data = p._convert_vendor_items(vendors, faction, rolls)
if data == nil then
return "Error: One of the vendors (" .. table.concat(vendors, " or ") .. ") was not found." -- TODO: Leave a module link so that the editor can be sure where and how to add the vendor
end
local result = ''
result = result .. frame:expandTemplate({title = 'Vendor/Header', args = (closed and {collapsed = 'true'} or {})})
for category, items in pairs(data) do
local template = vendor_templates[category]
if template ~= nil then
result = result .. frame:expandTemplate({title = 'Vendor/Subheader', args = {firstToUpper(category), (category ~= 'items' and 'Manufacturer' or '')}})
for i, chanceItem in ipairs(items) do
template.args = {name = chanceItem[1], chance = string.format('%02.2f%%', chanceItem[2])}
for j = 1, #chanceItem[3] do
local grade_name = chanceItem[3][j][1]
local grade_chance = chanceItem[3][j][2]
if grade_chance > 0 then
template.args[grade_name] = string.format('%02.2f', grade_chance)
end
end
if category == 'items' then
template.args.price = frame:expandTemplate({title = 'Price', args = {chanceItem[1]}})
template.args.item = template.args.name
template.args.name = nil
end
result = result .. frame:expandTemplate(template)
end
end
end
result = result .. frame:expandTemplate({title = 'Vendor/Footer'})
return result
end
function p._convert_vendor_items(vendors, faction, rolls)
local data = p._merge_vendors(vendors)
if data == nil then
return nil
end
local chance_sums = {}
local results = {}
local manufacturers = table.shallow_copy(data['weapon manufacturers'])
local armour_grades = table.shallow_copy(get_armour_grades(faction))
p._calculate_chance_sum(chance_sums, 'armour grades', armour_grades)
for category, items in pairs(data) do
if category ~= 'base' then
if vendor_templates[category] then
category = 'overall'
end
p._calculate_chance_sum(chance_sums, category, items)
end
end
for i, _ in ipairs(manufacturers) do
manufacturers[i] = {manufacturers[i][1], p._calculate_roll_probability(chance_sums['weapon manufacturers'], manufacturers[i][2], 1)}
end
for i, _ in ipairs(armour_grades) do
armour_grades[i] = {armour_grades[i][1], p._calculate_roll_probability(chance_sums['armour grades'], armour_grades[i][2], 1)}
end
for category, items in pairs(data) do
if category ~= 'base' then
results[category] = {}
local chances
if vendor_templates[category] then
chances = chance_sums['overall']
else
chances = chance_sums[category]
end
for _, chanceItem in ipairs(items) do
local chance = p._calculate_roll_probability(chances, chanceItem[2], rolls)
local grades
if category == 'weapons' and manufacturers ~= nil then
grades = manufacturers
elseif category == 'clothing' then
grades = armour_grades
else
grades = {}
end
table.insert(results[category], {chanceItem[1], chance, grades})
end
end
end
for category, _ in pairs(results) do
table.sort(results[category], compare)
end
return results
end
function p._calculate_chance_sum(chance_sums, category, items)
local chance_sum = chance_sums[category] or 0
for _, chanceItem in ipairs(items) do
chance_sum = chance_sum + chanceItem[2]
end
chance_sums[category] = chance_sum
end
function p._calculate_roll_probability(chance_sum, chance, rolls)
return (1 - ((chance_sum-chance) / chance_sum)^rolls) * 100
end
function p._merge_vendors(vendors)
local results = {}
for i, vendor in ipairs(vendors) do
local data = vendorData[vendor]
table.merge(results, data)
end
return results
end
function firstToUpper(str)
return (str:gsub("^%l", string.upper))
end
function compare(a,b)
return a[2] > b[2]
end
function table.shallow_copy(t)
local t2 = {}
for k,v in pairs(t) do
t2[k] = v
end
return t2
end
function table.merge(t1, t2)
for k,v in pairs(t2) do
if type(v) == "table" then
if type(t1[k] or false) == "table" then
table.merge(t1[k] or {}, t2[k] or {})
else
t1[k] = v
end
else
if type(t1[k] or false) == "number" then
t1[k] = t1[k] + v
end
end
end
return t1
end
function string.split (inputstr, sep)
if sep == nil then
sep = "%s"
end
local t={}
for str in string.gmatch(inputstr, "([^"..sep.."]+)") do
table.insert(t, str)
end
return t
end
return p