Editing Module:BuildupGive feedback
Jump to navigation
Jump to search
The edit can be undone.
Please check the comparison below to verify that this is what you want to do, and then publish the changes below to finish undoing the edit.
| Latest revision | Your text | ||
| Line 7: | Line 7: | ||
-- Handles both flat numbers and lookup in the ItemData file | -- Handles both flat numbers and lookup in the ItemData file | ||
local function get_item_bb(target_name) | local function get_item_bb(target_name) | ||
if target_name == nil then return nil end | |||
-- Clean input | |||
local clean_name = mw.text.trim(target_name) | |||
-- If user input a number directly | |||
if tonumber(clean_name) then return tonumber(clean_name) end | |||
-- Iterate Item Data | |||
for key, item in pairs(items_data) do | |||
if item["Name"] == clean_name then | |||
-- Valve data structure (nested) | |||
if item["m_mapAbilityProperties"] and item["m_mapAbilityProperties"]["BuildUpPerShot"] then | |||
return tonumber(item["m_mapAbilityProperties"]["BuildUpPerShot"]["m_strValue"]) | |||
end | |||
-- Flat data structure (fallback) | |||
if item["BuildUpPerShot"] then | |||
return tonumber(item["BuildUpPerShot"]) | |||
end | |||
end | |||
end | |||
return nil | |||
end | end | ||
-- Helper to find Hero Data by name or key | -- Helper to find Hero Data by name or key | ||
local function get_hero_data(hero_name) | local function get_hero_data(hero_name) | ||
if hero_name == nil then return nil end | |||
local clean_name = mw.text.trim(hero_name) | |||
-- Try direct Key lookup | |||
if heroes_data[clean_name] then return heroes_data[clean_name] end | |||
-- Try adding "hero_" prefix | |||
local key_lower = "hero_" .. string.lower(clean_name) | |||
if heroes_data[key_lower] then return heroes_data[key_lower] end | |||
-- Search by Name field | |||
for k, v in pairs(heroes_data) do | |||
if v["Name"] == clean_name then return v end | |||
end | |||
return nil | |||
end | end | ||
-- Core calculation logic | -- Core calculation logic | ||
local function calculate_bps(hero, bb) | local function calculate_bps(hero, bb) | ||
if not hero or not hero.Weapon then return 0 | if not hero or not hero.Weapon then return 0 end | ||
local rps = tonumber(hero.Weapon.RoundsPerSecond or 0) | local rps = tonumber(hero.Weapon.RoundsPerSecond or 0) | ||
| Line 100: | Line 83: | ||
end | end | ||
if rps == 0 then return 0 end | |||
if rps == 0 then return 0 | |||
-- Formula: 100 / (BB * (RPS + 1)) | |||
return 100 / (bb * (rps + 1)) | |||
-- | |||
end | end | ||
--{{#invoke:Buildup|get_bps|HERO_NAME|ITEM_NAME}} | --{{#invoke:Buildup|get_bps|HERO_NAME|ITEM_NAME}} | ||
--Returns a single float value (rounded to 1 decimal) | --Returns a single float value (rounded to 1 decimal) | ||
p.get_bps = function(frame) | p.get_bps = function(frame) | ||
local hero_name = frame.args[1] or frame.args['hero'] | |||
local item_name = frame.args[2] or frame.args['item'] | |||
local hero = get_hero_data(hero_name) | |||
if not hero then return "Hero Not Found" end | |||
local bb = get_item_bb(item_name) | |||
if not bb then return "Item Not Found" end | |||
local result = calculate_bps(hero, bb) | |||
return string.format("%.1f", result) | |||
end | end | ||
--{{#invoke:Buildup|write_buildup_table|ITEM_NAME}} | --{{#invoke:Buildup|write_buildup_table|ITEM_NAME}} | ||
--Generates a sortable wikitable for all heroes | --Generates a sortable wikitable for all heroes | ||
p.write_buildup_table = function(frame) | p.write_buildup_table = function(frame) | ||
local item_name = frame.args[1] | local item_name = frame.args[1] | ||
| Line 149: | Line 119: | ||
local is_disabled = hero["IsDisabled"] == true | local is_disabled = hero["IsDisabled"] == true | ||
if not is_dev and not is_disabled and hero["Weapon | if not is_dev and not is_disabled and hero["Weapon"] then | ||
local val | local val = calculate_bps(hero, bb) | ||
if val > 0 then | if val > 0 then | ||
local shots = math.ceil(100 / val) | |||
local shots = math.ceil(100 / | |||
table.insert(hero_list, { | table.insert(hero_list, { | ||
name = hero["Name"], | name = hero["Name"], | ||
bps = val, | bps = val, | ||
shots = shots | shots = shots | ||
}) | }) | ||
| Line 185: | Line 152: | ||
if item_name then | if item_name then | ||
html:tag('caption'):wikitext('Buildup Per | html:tag('caption'):wikitext('Buildup Per Shot: ' .. item_name) | ||
end | end | ||
| Line 191: | Line 158: | ||
local headerRow = html:tag('tr') | local headerRow = html:tag('tr') | ||
headerRow:tag('th'):wikitext('Hero') | headerRow:tag('th'):wikitext('Hero') | ||
headerRow:tag('th'):wikitext('% per | headerRow:tag('th'):wikitext('% per shot') | ||
headerRow:tag('th'):wikitext('Shots to Proc') | |||
headerRow:tag('th'):wikitext('Shots to Proc | |||
-- Rows | -- Rows | ||
for _, h in ipairs(hero_list) do | for _, h in ipairs(hero_list) do | ||
local row = html:tag('tr') | local row = html:tag('tr') | ||
local | local icon_template = frame:expandTemplate{ title = 'HeroIcon', args = { h.name } } | ||
-- Use data-sort-value so the table sorts correctly even with the icon | |||
row:tag('td') | row:tag('td') | ||
:attr('data-sort-value', h.name) | :attr('data-sort-value', h.name) -- Uses the name including "The" for consistent default sort | ||
:wikitext( | :wikitext(icon_template) | ||
row:tag('td'):wikitext(string.format("%.1f", h.bps)) | row:tag('td'):wikitext(string.format("%.1f", h.bps)) | ||
row:tag('td'):wikitext(tostring(h.shots)) | row:tag('td'):wikitext(tostring(h.shots)) | ||
end | end | ||
| Line 244: | Line 181: | ||
-- Decides whether to return a single value or a full table based on arguments | -- Decides whether to return a single value or a full table based on arguments | ||
p.main = function(frame) | p.main = function(frame) | ||
local args = frame:getParent().args | |||
-- Handle direct #invoke calls vs Template calls | |||
if not args[1] and not args['item'] then args = frame.args end | |||
local arg1 = args[1] or args['hero'] | |||
local arg2 = args[2] or args['item'] | |||
-- If both Hero and Item are present -> Return Single Number | |||
if arg1 and arg2 then | |||
-- Manually setting args for the helper function to read | |||
frame.args = {arg1, arg2} | |||
return p.get_bps(frame) | |||
-- If only one arg (Item) is present -> Return Table | |||
elseif arg1 then | |||
frame.args = {arg1} | |||
return p.write_buildup_table(frame) | |||
else | |||
return "Error: Provide [Item Name] for a table, or [Hero Name] [Item Name] for a value." | |||
end | |||
end | end | ||
return p | return p | ||