Module:Sandbox/LVL: Difference between revisionsGive feedback
Jump to navigation
Jump to search
Blanked the page Tags: Blanking Manual revert |
No edit summary |
||
| Line 1: | Line 1: | ||
local p = {}; | |||
-- Load the data from the wiki's JSON pages | |||
local heroes_data = mw.loadJsonData("Data:HeroData.json") | |||
local soul_unlocks_data = mw.loadJsonData("Data:SoulUnlockData.json") | |||
-- A mapping to make the table headers more readable | |||
local level_scaling_key_to_name = { | |||
BulletDamage = "Bullet Damage", | |||
MaxHealth = "Health", | |||
TechPower = "Spirit Power", | |||
LightMeleeDamage = "Light Melee Damage", | |||
HeavyMeleeDamage = "Heavy Melee Damage" | |||
} | |||
-- Data for special alternate fire modes not found in HeroData.json | |||
local alt_fires = { | |||
Shiv = {base = 55.2, level = 2.64, suffix = "alt fire 12 pellets"}, | |||
Viscous = {base = 63, level = 0.9, suffix = "alt fire AOE"}, | |||
Yamato = {base = 63.36, level = 0.35, suffix = "alt fire AOE"} | |||
} | |||
-- This is the main function that will be called from your sandbox page. | |||
-- It generates the HTML for the input box and the interactive table. | |||
p.write_power_increase_table = function(frame) | |||
-- Calculate the maximum number of boons by counting entries with "PowerIncrease" | |||
local pi_souls_list = {} | |||
for _, v in ipairs(soul_unlocks_data) do | |||
if (v["PowerIncrease"]) then | |||
table.insert(pi_souls_list, v["RequiredSouls"]) | |||
end | |||
end | |||
local max_boons = #pi_souls_list | |||
-- Filter out any disabled heroes | |||
local filtered_heroes = {} | |||
for _, hero in pairs(heroes_data) do | |||
if (not hero["IsDisabled"]) then | |||
table.insert(filtered_heroes, hero) | |||
end | |||
end | |||
local property = frame.args[1] -- The stat we are calculating, e.g., "BulletDamage" | |||
local name = level_scaling_key_to_name[property] | |||
-- Create a unique ID for the table so the JavaScript can find it | |||
local table_id = "scaling-table-" .. property | |||
-- Create the table element with standard wiki classes and our unique ID | |||
local create_table = mw.html.create("table"):addClass("wikitable sortable"):attr("id", table_id) | |||
-- Create the header row for the table | |||
local header_row = mw.html.create("tr") | |||
header_row | |||
:tag("th"):wikitext("Hero"):done() | |||
:tag("th"):wikitext("Base " .. name):done() | |||
:tag("th"):wikitext("Increase per Boon"):done() | |||
-- The header for the "Total" column includes a span that will be updated by JavaScript | |||
:tag("th"):wikitext("Total (at <span class=\"boon-count-display\">0</span> Boons)"):done() | |||
create_table:node(header_row) | |||
-- Loop through each hero to create a row for them in the table | |||
for _, hero in ipairs(filtered_heroes) do | |||
local base = (hero[property] or 0) | |||
local level_scaling = hero["LevelScaling"] and hero["LevelScaling"][property] or 0 | |||
local level = level_scaling | |||
local shots = (hero["BulletsPerShot"] or 1) | |||
local burst = (hero["BulletsPerBurst"] or 1) | |||
local bullet_mult = shots * burst | |||
local hero_icon = frame:expandTemplate{ title = "HeroIcon", args = {hero["Name"]}} | |||
local hero_suffix = "" | |||
-- Special handling for bullet damage with multiple pellets/bursts | |||
if (property == "BulletDamage" and bullet_mult > 1) then | |||
if (not hero["HitOnceAcrossAllBullets"]) then | |||
base = base * bullet_mult | |||
level = level * bullet_mult | |||
end | |||
if (shots > 1) then hero_suffix = hero_suffix .. " (" .. shots .. " pellets)" end | |||
if (burst > 1) then hero_suffix = hero_suffix .. " (" .. burst .. " bullets)" end | |||
end | |||
local hero_row = mw.html.create("tr") | |||
-- Add the data-base and data-level attributes to the row for the JavaScript to read | |||
hero_row | |||
:attr("data-base", base) | |||
:attr("data-level", level) | |||
:tag("td"):wikitext(hero_icon .. " " .. hero["Name"] .. hero_suffix):done() | |||
:tag("td"):wikitext(string.format("%.2f", base)):done() | |||
:tag("td"):wikitext("+" .. string.format("%.2f", level)):done() | |||
-- Add a placeholder cell for the total, with a class for JS to find | |||
:tag("td"):addClass("total-value"):wikitext(string.format("%.2f", base)):done() | |||
create_table:node(hero_row) | |||
-- If the hero has a special alt-fire, create a separate row for it | |||
if (property == "BulletDamage" and alt_fires[hero["Name"]] ~= nil) then | |||
local alt_fire = alt_fires[hero["Name"]] | |||
local alt_base = alt_fire["base"] | |||
local alt_level = alt_fire["level"] | |||
local alt_suffix = " (''" .. alt_fire["suffix"] .. "'')" | |||
local alt_fire_row = mw.html.create("tr") | |||
-- Add data attributes for the alt-fire row as well | |||
alt_fire_row | |||
:attr("data-base", alt_base) | |||
:attr("data-level", alt_level) | |||
:tag("td"):wikitext(hero_icon .. " ''↳ Alt-fire''" .. alt_suffix):done() | |||
:tag("td"):wikitext(string.format("%.2f", alt_base)):done() | |||
:tag("td"):wikitext("+" .. string.format("%.2f", alt_level)):done() | |||
:tag("td"):addClass("total-value"):wikitext(string.format("%.2f", alt_base)):done() | |||
create_table:node(alt_fire_row) | |||
end | |||
end | |||
-- Create a container div to hold both the input controls and the table | |||
local container = mw.html.create("div"):addClass("scaling-calculator-container") | |||
local input_id = "boon-input-" .. property | |||
-- Create the HTML for the input box and its label | |||
local input_controls = mw.html.create("div"):addClass("boon-input-controls") | |||
input_controls | |||
:tag("label"):attr("for", input_id):wikitext("Number of Boons: "):done() | |||
:tag("input") | |||
:attr("type", "number") | |||
:attr("id", input_id) | |||
:attr("value", 0) | |||
:attr("min", 0) | |||
:attr("max", max_boons) -- Use the max_boons we calculated | |||
:css("width", "60px") | |||
:done() | |||
-- Add the input controls and the table to the container | |||
container:node(input_controls) | |||
container:node(create_table) | |||
-- Return the complete HTML for the component | |||
return tostring(container) | |||
end | |||
return p | |||