Module:InfoboxNPC: Difference between revisions

From August Wiki
Jump to navigation Jump to search
No edit summary
No edit summary
 
(9 intermediate revisions by the same user not shown)
Line 59: Line 59:
       <th colspan="8">Combat level</th>
       <th colspan="8">Combat level</th>
       <td colspan="16">]] .. args.combat_level .. [[</td>
       <td colspan="16">]] .. args.combat_level .. [[</td>
    </tr>]]
        hasBasicInfo = true
    end
   
    -- Combat level
    if args.tier and args.tier ~= "" then
        html = html .. [[
    <tr>
      <th colspan="8">Tier</th>
      <td colspan="16">]] .. args.tier .. [[</td>
    </tr>]]
        hasBasicInfo = true
    end
   
    -- is_boss
    if args.is_boss and args.is_boss ~= "" then
        html = html .. [[
    <tr>
      <th colspan="8">Boss</th>
      <td colspan="16">]] .. args.is_boss .. [[</td>
    </tr>]]
        hasBasicInfo = true
    end
   
    -- Species
    if args.species and args.species ~= "" then
        html = html .. [[
    <tr>
      <th colspan="8">Species</th>
      <td colspan="16">]] .. args.species .. [[</td>
     </tr>]]
     </tr>]]
         hasBasicInfo = true
         hasBasicInfo = true
Line 194: Line 224:
     -- Check if any slayer info fields have values
     -- Check if any slayer info fields have values
     local hasSlayerInfo = false
     local hasSlayerInfo = false
     local slayerInfoFields = {"slayer_level", "slayer_xp", "slayer_category", "slayer_masters"}
     local slayerInfoFields = {"slayer_level", "slayer_xp", "slayer_category", "slayer_masters", "num_assigned"}


     for _, field in ipairs(slayerInfoFields) do
     for _, field in ipairs(slayerInfoFields) do
Line 248: Line 278:
       <th colspan="8">Assigned by</th>
       <th colspan="8">Assigned by</th>
       <td colspan="16">]] .. args.slayer_masters .. [[</td>
       <td colspan="16">]] .. args.slayer_masters .. [[</td>
    </tr>]]
        end
       
        -- Assigned by
        if args.num_assigned and args.num_assigned ~= "" then
            html = html .. [[
    <tr>
      <th colspan="8">Task Size</th>
      <td colspan="16">]] .. args.num_assigned .. [[</td>
     </tr>]]
     </tr>]]
         end
         end
Line 280: Line 319:
         html = html .. [[
         html = html .. [[
     <tr>
     <tr>
       <th colspan="24" class="infobox-subheader">]] .. "[[File:" .. combatIcon .. "|19px]] Combat stats" .. [[</th>
       <th colspan="24" class="infobox-subheader">]] .. "[[File:" .. combatIcon .. "|19px]] Combat levels" .. [[</th>
     </tr>
     </tr>
     <tr>
     <tr>
Line 329: Line 368:
         html = html .. [[
         html = html .. [[
     <tr>
     <tr>
       <th colspan="24" class="infobox-subheader">]] .. "[[File:" .. attackIcon .. "|25px]] Aggressive stats" .. [[</th>
       <th colspan="24" class="infobox-subheader">]] .. "[[File:" .. attackIcon .. "|25px]] Combat stats" .. [[</th>
     </tr>
     </tr>
     <tr>
     <tr>
Line 406: Line 445:
     </tr>
     </tr>
     <tr>
     <tr>
         <th colspan="8" class="infobox-nested">]] .. "[[File:" .. stabIcon .. "|21px]]" .. [[</th>
         <th colspan="8" class="infobox-nested">]] .. "[[File:" .. stabIcon .. "|30px]]" .. [[</th>
         <th colspan="8" class="infobox-nested">]] .. "[[File:" .. slashIcon .. "|27px]]" .. [[</th>
         <th colspan="8" class="infobox-nested">]] .. "[[File:" .. slashIcon .. "|30px]]" .. [[</th>
         <th colspan="8" class="infobox-nested">]] .. "[[File:" .. crushIcon .. "|22px]]" .. [[</th>
         <th colspan="8" class="infobox-nested">]] .. "[[File:" .. crushIcon .. "|30px]]" .. [[</th>
     </tr>
     </tr>
     <tr>
     <tr>
Line 432: Line 471:
         <td colspan="24" class="infobox-padding"></td>
         <td colspan="24" class="infobox-padding"></td>
     </tr>
     </tr>
    ]]
        if hasRangedDefence then
            html = html .. [[
         <tr>
         <tr>
             <th colspan="12" class="infobox-nested">]] .. "[[File:" .. rangedDefenceIcon .. "|22px]]" .. [[</th>
             <th colspan="12" class="infobox-nested">]] .. "[[File:" .. rangedDefenceIcon .. "|30px]]" .. [[</th>
            <th colspan="12" class="infobox-nested">]] .. "[[File:" .. magicDefenceIcon .. "|30px]]" .. [[</th>
        </tr>
        <tr>
             <td colspan="12" class="infobox-nested">]] .. (args.ranged_def or "") .. [[</td>
             <td colspan="12" class="infobox-nested">]] .. (args.ranged_def or "") .. [[</td>
         </tr>]]
            <td colspan="12" class="infobox-nested">]] .. (args.magic_def or "") .. [[</td>
        </tr>
    <tr>
        <td colspan="24" class="infobox-padding"></td>
    </tr>]]
    end
 
    -- Weaknesses Section
    html = html .. [[
    <tr>
        <th colspan="24" class="infobox-subheader">Weaknesses</th>
    </tr>
    <tr>
         <td colspan="24" class="infobox-padding"></td>
    </tr>]]
 
    local hasWeaknesses = false
    local weaknessCount = 0
 
    local weaknessHeaders = ""
    local weaknessData = ""
 
    for i = 1, 3 do
        local weaknessType = args["weakness_type" .. i]
        local weaknessFactor = args["weakness_factor" .. i]
 
        if weaknessType and weaknessFactor then
            hasWeaknesses = true
            weaknessCount = i
            weaknessHeaders = weaknessHeaders .. [[<th colspan="" class="infobox-nested">]] .. weaknessType .. [[</th>]]
            weaknessData = weaknessData .. [[<td colspan="" class="infobox-nested">]] .. weaknessFactor .. [[</td>]]
        else
            break -- Stop if a weakness is missing
         end
         end
    end


        if hasMagicDefence then
    if hasWeaknesses then
            html = html .. [[
        local colspanValue = 24 / weaknessCount
         <tr>
 
            <th colspan="12" class="infobox-nested">]] .. "[[File:" .. magicDefenceIcon .. "|22px]]" .. [[</th>
         local adjustedHeaders = weaknessHeaders:gsub('colspan=""', 'colspan="' .. colspanValue .. '"')
            <td colspan="12" class="infobox-nested">]] .. (args.magic_def or "") .. [[</td>
        local adjustedData = weaknessData:gsub('colspan=""', 'colspan="' .. colspanValue .. '"')
        </tr>]]
        end


         html = html .. [[
         html = html .. [[
    <tr>]] .. adjustedHeaders .. [[</tr>
    <tr>]] .. adjustedData .. [[</tr>]]
    else
        html = html .. [[
    <tr>
        <td colspan="24" class="infobox-nested">N/A</td>
    </tr>]]
    end
    html = html .. [[
     <tr>
     <tr>
         <td colspan="24" class="infobox-padding"></td>
         <td colspan="24" class="infobox-padding"></td>
     </tr>]]
     </tr>]]
    end


     -- Check if any immunity values have been specified
     -- Check if any immunity values have been specified

Latest revision as of 02:29, 21 March 2025

Documentation for this module may be created at Module:InfoboxNPC/doc

local p = {}

function p.renderInfobox(frame)
    local args = frame.args
    local parent = frame:getParent()

    if parent then
        args = parent.args
    end

    local html = [[
<table class="infobox no-parenthesis-style infobox-item">
    <tr>
      <th colspan="24" class="infobox-header">]] .. (args.name or "Unknown Monster") .. [[</th>
    </tr>
    <tr>
      <td colspan="24" class="infobox-padding"></td>
    </tr>]]

    -- Character Image (conditional)
    if args.image and args.image ~= "" then
        html = html .. [[
    <tr>
      <td colspan="24" class="infobox-image infobox-full-width-content">]] .. "[[File:" .. args.image .. "|32px]]" ..
                   [[</td>
    </tr>
    <tr>
      <td colspan="24" class="infobox-padding"></td>
    </tr>]]
    end

    -- Basic Information (conditional for each row)
    local hasBasicInfo = false

    -- Released
    if args.released and args.released ~= "" then
        html = html .. [[
    <tr>
      <th colspan="8">Released</th>
      <td colspan="16">]] .. args.released .. [[</td>
    </tr>]]
        hasBasicInfo = true
    end

    -- Members
    if args.members and args.members ~= "" then
        html = html .. [[
    <tr>
      <th colspan="8">Members</th>
      <td colspan="16">]] .. args.members .. [[</td>
    </tr>]]
        hasBasicInfo = true
    end

    -- Combat level
    if args.combat_level and args.combat_level ~= "" then
        html = html .. [[
    <tr>
      <th colspan="8">Combat level</th>
      <td colspan="16">]] .. args.combat_level .. [[</td>
    </tr>]]
        hasBasicInfo = true
    end
    
    -- Combat level
    if args.tier and args.tier ~= "" then
        html = html .. [[
    <tr>
      <th colspan="8">Tier</th>
      <td colspan="16">]] .. args.tier .. [[</td>
    </tr>]]
        hasBasicInfo = true
    end
    
    -- is_boss
    if args.is_boss and args.is_boss ~= "" then
        html = html .. [[
    <tr>
      <th colspan="8">Boss</th>
      <td colspan="16">]] .. args.is_boss .. [[</td>
    </tr>]]
        hasBasicInfo = true
    end
    
    -- Species
    if args.species and args.species ~= "" then
        html = html .. [[
    <tr>
      <th colspan="8">Species</th>
      <td colspan="16">]] .. args.species .. [[</td>
    </tr>]]
        hasBasicInfo = true
    end

    -- Size
    if args.size and args.size ~= "" then
        html = html .. [[
    <tr>
      <th colspan="8">Size</th>
      <td colspan="16">]] .. args.size .. [[</td>
    </tr>]]
        hasBasicInfo = true
    end

    -- Examine
    if args.examine and args.examine ~= "" then
        html = html .. [[
    <tr>
      <th colspan="8">Examine</th>
      <td colspan="16">]] .. args.examine .. [[</td>
    </tr>]]
        hasBasicInfo = true
    end

    -- League Information
    if args.league_region and args.league_region ~= "" then
        html = html .. [[
    <tr class="leagues-global-flag">
      <th colspan="8">League region</th>
      <td colspan="16">]] .. args.league_region .. [[</td>
    </tr>]]
        hasBasicInfo = true
    end

    -- Add padding if at least one basic info field was displayed
    if hasBasicInfo then
        html = html .. [[
    <tr>
      <td colspan="24" class="infobox-padding"></td>
    </tr>]]
    end

    -- Check if any combat info fields have values
    local hasCombatInfo = false
    local combatInfoFields = {"xp_bonus", "max_hit", "aggressive", "poisonous", "attack_style", "attack_speed",
                              "respawn_time"}

    for _, field in ipairs(combatInfoFields) do
        if args[field] and args[field] ~= "" then
            hasCombatInfo = true
            break
        end
    end

    -- Combat Information Section (only if at least one field has a value)
    if hasCombatInfo then
        html = html .. [[
    <tr>
      <th colspan="24" class="infobox-subheader">Combat info</th>
    </tr>
    <tr>
      <td colspan="24" class="infobox-padding"></td>
    </tr>]]

        -- XP Bonus
        if args.xp_bonus and args.xp_bonus ~= "" then
            html = html .. [[
    <tr>
      <th colspan="8">XP bonus</th>
      <td colspan="16">]] .. args.xp_bonus .. [[</td>
    </tr>]]
        end

        -- Max hit
        if args.max_hit and args.max_hit ~= "" then
            html = html .. [[
    <tr>
      <th colspan="8">Max hit</th>
      <td colspan="16">]] .. args.max_hit .. [[</td>
    </tr>]]
        end

        -- Aggressive
        if args.aggressive and args.aggressive ~= "" then
            html = html .. [[
    <tr>
      <th colspan="8">Aggressive</th>
      <td colspan="16">]] .. args.aggressive .. [[</td>
    </tr>]]
        end

        -- Poisonous
        if args.poisonous and args.poisonous ~= "" then
            html = html .. [[
    <tr>
      <th colspan="8">Poisonous</th>
      <td colspan="16">]] .. args.poisonous .. [[</td>
    </tr>]]
        end

        -- Attack style
        if args.attack_style and args.attack_style ~= "" then
            html = html .. [[
    <tr>
      <th colspan="8">Attack style</th>
      <td colspan="16">]] .. args.attack_style .. [[</td>
    </tr>]]
        end

        -- Attack speed
        if args.attack_speed and args.attack_speed ~= "" then
            html = html .. [[
    <tr>
      <th colspan="8">Attack speed</th>
      <td colspan="16">]] .. args.attack_speed .. [[</td>
    </tr>]]
        end

        -- Respawn time
        if args.respawn_time and args.respawn_time ~= "" then
            html = html .. [[
    <tr>
      <th colspan="8">Respawn time</th>
      <td colspan="16">]] .. args.respawn_time .. [[</td>
    </tr>]]
        end

        html = html .. [[
    <tr>
      <td colspan="24" class="infobox-padding"></td>
    </tr>]]
    end

    -- Check if any slayer info fields have values
    local hasSlayerInfo = false
    local slayerInfoFields = {"slayer_level", "slayer_xp", "slayer_category", "slayer_masters", "num_assigned"}

    for _, field in ipairs(slayerInfoFields) do
        if args[field] and args[field] ~= "" then
            hasSlayerInfo = true
            break
        end
    end

    -- Slayer Section (only if at least one field has a value)
    if hasSlayerInfo then
        local slayerIcon = args.slayer_icon or "Slayer_icon.png"

        html = html .. [[
    <tr>
      <th colspan="24" class="infobox-subheader">]] .. "[[File:" .. slayerIcon .. "|23px]] Slayer info" .. [[</th>
    </tr>
    <tr>
      <td colspan="24" class="infobox-padding"></td>
    </tr>]]

        -- Slayer level
        if args.slayer_level and args.slayer_level ~= "" then
            html = html .. [[
    <tr>
      <th colspan="8">Slayer level</th>
      <td colspan="16">]] .. args.slayer_level .. [[</td>
    </tr>]]
        end

        -- Slayer XP
        if args.slayer_xp and args.slayer_xp ~= "" then
            html = html .. [[
    <tr>
      <th colspan="8">Slayer XP</th>
      <td colspan="16">]] .. args.slayer_xp .. [[</td>
    </tr>]]
        end

        -- Category
        if args.slayer_category and args.slayer_category ~= "" then
            html = html .. [[
    <tr>
      <th colspan="8">Category</th>
      <td colspan="16">]] .. args.slayer_category .. [[</td>
    </tr>]]
        end

        -- Assigned by
        if args.slayer_masters and args.slayer_masters ~= "" then
            html = html .. [[
    <tr>
      <th colspan="8">Assigned by</th>
      <td colspan="16">]] .. args.slayer_masters .. [[</td>
    </tr>]]
        end
        
        -- Assigned by
        if args.num_assigned and args.num_assigned ~= "" then
            html = html .. [[
    <tr>
      <th colspan="8">Task Size</th>
      <td colspan="16">]] .. args.num_assigned .. [[</td>
    </tr>]]
        end

        html = html .. [[
    <tr>
      <td colspan="24" class="infobox-padding"></td>
    </tr>]]
    end

    -- Check if any combat stats have values
    local hasCombatStats = false
    local combatStatFields = {"hitpoints", "attack", "strength", "defence", "magic", "ranged"}

    for _, field in ipairs(combatStatFields) do
        if args[field] and args[field] ~= "" then
            hasCombatStats = true
            break
        end
    end

    -- Combat Stats Section (only if at least one stat has a value)
    if hasCombatStats then
        local combatIcon = args.combat_icon or "Multicombat.png"
        local hitpointsIcon = args.hitpoints_icon or "Hitpoints_icon.png"
        local attackIcon = args.attack_icon or "Attack_icon.png"
        local strengthIcon = args.strength_icon or "Strength_icon.png"
        local defenceIcon = args.defence_icon or "Defence_icon.png"
        local magicIcon = args.magic_icon or "Magic_icon.png"
        local rangedIcon = args.ranged_icon or "Ranged_icon.png"

        html = html .. [[
    <tr>
      <th colspan="24" class="infobox-subheader">]] .. "[[File:" .. combatIcon .. "|19px]] Combat levels" .. [[</th>
    </tr>
    <tr>
      <td colspan="24" class="infobox-padding"></td>
    </tr>
    <tr>
      <th colspan="4" class="infobox-nested">]] .. "[[File:" .. hitpointsIcon .. "|23px]]" .. [[</th>
      <th colspan="4" class="infobox-nested">]] .. "[[File:" .. attackIcon .. "|25px]]" .. [[</th>
      <th colspan="4" class="infobox-nested">]] .. "[[File:" .. strengthIcon .. "|16px]]" .. [[</th>
      <th colspan="4" class="infobox-nested">]] .. "[[File:" .. defenceIcon .. "|17px]]" .. [[</th>
      <th colspan="4" class="infobox-nested">]] .. "[[File:" .. magicIcon .. "|25px]]" .. [[</th>
      <th colspan="4" class="infobox-nested">]] .. "[[File:" .. rangedIcon .. "|23px]]" .. [[</th>
    </tr>
    <tr>
      <td colspan="4" class="infobox-nested">]] .. (args.hitpoints or "") .. [[</td>
      <td colspan="4" class="infobox-nested">]] .. (args.attack or "") .. [[</td>
      <td colspan="4" class="infobox-nested">]] .. (args.strength or "") .. [[</td>
      <td colspan="4" class="infobox-nested">]] .. (args.defence or "") .. [[</td>
      <td colspan="4" class="infobox-nested">]] .. (args.magic or "") .. [[</td>
      <td colspan="4" class="infobox-nested">]] .. (args.ranged or "") .. [[</td>
    </tr>
    <tr>
      <td colspan="24" class="infobox-padding"></td>
    </tr>]]
    end

    -- Check if any aggressive stats have values
    local hasAggressiveStats = false
    local aggressiveStatFields = {"attack_bonus", "strength_bonus", "magic_bonus", "magic_damage", "ranged_bonus",
                                  "ranged_strength"}

    for _, field in ipairs(aggressiveStatFields) do
        if args[field] and args[field] ~= "" then
            hasAggressiveStats = true
            break
        end
    end

    -- Aggressive stats section (only if at least one stat has a value)
    if hasAggressiveStats then
        local attackIcon = args.attack_icon or "Attack_icon.png"
        local strengthIcon = args.strength_icon or "Strength_icon.png"
        local magicIcon = args.magic_icon or "Magic_icon.png"
        local magicDamageIcon = args.magic_damage_icon or "Magic_Damage_icon.png"
        local rangedIcon = args.ranged_icon or "Ranged_icon.png"
        local rangedStrengthIcon = args.ranged_strength_icon or "Ranged_Strength_icon.png"

        html = html .. [[
    <tr>
      <th colspan="24" class="infobox-subheader">]] .. "[[File:" .. attackIcon .. "|25px]] Combat stats" .. [[</th>
    </tr>
    <tr>
      <td colspan="24" class="infobox-padding"></td>
    </tr>
    <tr>
      <th colspan="4" class="infobox-nested">]] .. "[[File:" .. attackIcon .. "|25px]]" .. [[</th>
      <th colspan="4" class="infobox-nested">]] .. "[[File:" .. strengthIcon .. "|16px]]" .. [[</th>
      <th colspan="4" class="infobox-nested">]] .. "[[File:" .. magicIcon .. "|25px]]" .. [[</th>
      <th colspan="4" class="infobox-nested">]] .. "[[File:" .. magicDamageIcon .. "|28px]]" .. [[</th>
      <th colspan="4" class="infobox-nested">]] .. "[[File:" .. rangedIcon .. "|23px]]" .. [[</th>
      <th colspan="4" class="infobox-nested">]] .. "[[File:" .. rangedStrengthIcon .. "|26px]]" .. [[</th>
    </tr>
    <tr>
      <td colspan="4" class="infobox-nested">]] .. (args.attack_bonus or "") .. [[</td>
      <td colspan="4" class="infobox-nested">]] .. (args.strength_bonus or "") .. [[</td>
      <td colspan="4" class="infobox-nested">]] .. (args.magic_bonus or "") .. [[</td>
      <td colspan="4" class="infobox-nested">]] .. (args.magic_damage or "") .. [[</td>
      <td colspan="4" class="infobox-nested">]] .. (args.ranged_bonus or "") .. [[</td>
      <td colspan="4" class="infobox-nested">]] .. (args.ranged_strength or "") .. [[</td>
    </tr>
    <tr>
      <td colspan="24" class="infobox-padding"></td>
    </tr>]]
    end

    -- Check if any melee defence stats have values
    local hasMeleeDefence = false
    local meleeDefenceFields = {"stab_def", "slash_def", "crush_def"}

    for _, field in ipairs(meleeDefenceFields) do
        if args[field] and args[field] ~= "" then
            hasMeleeDefence = true
            break
        end
    end

    -- Check if any other defence stats have values
    local hasOtherDefence = false
    local otherDefenceFields = {"magic_def", "ranged_def"}

    for _, field in ipairs(otherDefenceFields) do
        if args[field] and args[field] ~= "" then
            hasOtherDefence = true
            break
        end
    end

    -- Check if any magic defence stats have values
    local hasMagicDefence = args.magic_def and args.magic_def ~= ""

    -- Check if any ranged defence stats have values
    local hasRangedDefence = args.ranged_def and args.ranged_def ~= ""

    if hasRangedDefence then
        local rangedDefenceIcon = args.ranged_defence_icon or "Ranged_defence_icon.png"
    end

    if hasMagicDefence then
        local magicDefenceIcon = args.magic_defence_icon or "Magic_defence_icon.png"
    end

    -- Melee Defence Section
    if hasMeleeDefence then
        local defenceIcon = args.defence_icon or "Defence_icon.png"
        local stabIcon = args.stab_icon or "White_dagger.png"
        local slashIcon = args.slash_icon or "White_scimitar.png"
        local crushIcon = args.crush_icon or "White_warhammer.png"

        html = html .. [[
    <tr>
        <th colspan="24" class="infobox-subheader">]] .. "[[File:" .. defenceIcon .. "|17px]] Melee defence" .. [[</th>
    </tr>
    <tr>
        <td colspan="24" class="infobox-padding"></td>
    </tr>
    <tr>
        <th colspan="8" class="infobox-nested">]] .. "[[File:" .. stabIcon .. "|30px]]" .. [[</th>
        <th colspan="8" class="infobox-nested">]] .. "[[File:" .. slashIcon .. "|30px]]" .. [[</th>
        <th colspan="8" class="infobox-nested">]] .. "[[File:" .. crushIcon .. "|30px]]" .. [[</th>
    </tr>
    <tr>
        <td colspan="8" class="infobox-nested">]] .. (args.stab_def or "") .. [[</td>
        <td colspan="8" class="infobox-nested">]] .. (args.slash_def or "") .. [[</td>
        <td colspan="8" class="infobox-nested">]] .. (args.crush_def or "") .. [[</td>
    </tr>
    <tr>
        <td colspan="24" class="infobox-padding"></td>
    </tr>]]
    end

    -- Other Defences Section
    if hasOtherDefence then
        local rangedDefenceIcon = args.ranged_defence_icon or "Ranged_defence_icon.png"
        local magicDefenceIcon = args.magic_defence_icon or "Magic_defence_icon.png"

        html = html .. [[
    <tr>
        <th colspan="24" class="infobox-subheader">]] .. "Other defences" .. [[</th>
    </tr>
    <tr>
        <td colspan="24" class="infobox-padding"></td>
    </tr>
        <tr>
            <th colspan="12" class="infobox-nested">]] .. "[[File:" .. rangedDefenceIcon .. "|30px]]" .. [[</th>
            <th colspan="12" class="infobox-nested">]] .. "[[File:" .. magicDefenceIcon .. "|30px]]" .. [[</th>
        </tr>
        <tr>
            <td colspan="12" class="infobox-nested">]] .. (args.ranged_def or "") .. [[</td>
            <td colspan="12" class="infobox-nested">]] .. (args.magic_def or "") .. [[</td>
        </tr>
    <tr>
        <td colspan="24" class="infobox-padding"></td>
    </tr>]]
    end

    -- Weaknesses Section
    html = html .. [[
    <tr>
        <th colspan="24" class="infobox-subheader">Weaknesses</th>
    </tr>
    <tr>
        <td colspan="24" class="infobox-padding"></td>
    </tr>]]

    local hasWeaknesses = false
    local weaknessCount = 0

    local weaknessHeaders = ""
    local weaknessData = ""

    for i = 1, 3 do
        local weaknessType = args["weakness_type" .. i]
        local weaknessFactor = args["weakness_factor" .. i]

        if weaknessType and weaknessFactor then
            hasWeaknesses = true
            weaknessCount = i
            weaknessHeaders = weaknessHeaders .. [[<th colspan="" class="infobox-nested">]] .. weaknessType .. [[</th>]]
            weaknessData = weaknessData .. [[<td colspan="" class="infobox-nested">]] .. weaknessFactor .. [[</td>]]
        else
            break -- Stop if a weakness is missing
        end
    end

    if hasWeaknesses then
        local colspanValue = 24 / weaknessCount

        local adjustedHeaders = weaknessHeaders:gsub('colspan=""', 'colspan="' .. colspanValue .. '"')
        local adjustedData = weaknessData:gsub('colspan=""', 'colspan="' .. colspanValue .. '"')

        html = html .. [[
    <tr>]] .. adjustedHeaders .. [[</tr>
    <tr>]] .. adjustedData .. [[</tr>]]
    else
        html = html .. [[
    <tr>
        <td colspan="24" class="infobox-nested">N/A</td>
    </tr>]]
    end

    html = html .. [[
    <tr>
        <td colspan="24" class="infobox-padding"></td>
    </tr>]]

    -- Check if any immunity values have been specified
    local hasImmunities = false
    local immunityFields = {"poison_immunity", "venom_immunity", "cannon_immunity", "thrall_immunity"}

    for _, field in ipairs(immunityFields) do
        if args[field] and args[field] ~= "" then
            hasImmunities = true
            break
        end
    end

    -- Immunities Section (only if at least one immunity has a value)
    if hasImmunities then
        html = html .. [[
    <tr>
      <th colspan="24" class="infobox-subheader">Immunities</th>
    </tr>
    <tr>
      <td colspan="24" class="infobox-padding"></td>
    </tr>]]

        -- Poison immunity
        if args.poison_immunity and args.poison_immunity ~= "" then
            html = html .. [[
    <tr>
      <th colspan="8">Poison</th>
      <td colspan="16">]] .. args.poison_immunity .. [[</td>
    </tr>]]
        end

        -- Venom immunity
        if args.venom_immunity and args.venom_immunity ~= "" then
            html = html .. [[
    <tr>
      <th colspan="8">Venom</th>
      <td colspan="16">]] .. args.venom_immunity .. [[</td>
    </tr>]]
        end

        -- Cannon immunity
        if args.cannon_immunity and args.cannon_immunity ~= "" then
            html = html .. [[
    <tr>
      <th colspan="8">Cannons</th>
      <td colspan="16">]] .. args.cannon_immunity .. [[</td>
    </tr>]]
        end

        -- Thrall immunity
        if args.thrall_immunity and args.thrall_immunity ~= "" then
            html = html .. [[
    <tr>
      <th colspan="8">Thralls</th>
      <td colspan="16">]] .. args.thrall_immunity .. [[</td>
    </tr>]]
        end

        html = html .. [[
    <tr>
      <td colspan="24" class="infobox-padding"></td>
    </tr>]]
    end

    -- DPS Calculator Button (optional, can be parameterized if needed)
    if args.include_dps_calc and args.include_dps_calc == "yes" then
        html = html .. [[
    <tr>
      <td colspan="24" class="dps-calc-button infobox-full-width-content">DPS calculator button here</td>
    </tr>]]
    end

    -- Advanced data section (if monster_id is provided)
    if args.monster_id and args.monster_id ~= "" then
        html = html .. [[
    <tr class="advanced-data">
      <th colspan="24" class="infobox-subheader">Advanced data</th>
    </tr>
    <tr class="advanced-data">
      <td colspan="24" class="infobox-padding"></td>
    </tr>
    <tr class="advanced-data">
      <th colspan="8">Monster ID</th>
      <td colspan="16">]] .. args.monster_id .. [[</td>
    </tr>
    <tr class="advanced-data">
      <td colspan="24" class="infobox-padding"></td>
    </tr>]]
    end

    html = html .. [[
  </tr>
</table>]]

    return html
end

-- Function for testing/debugging - outputs what parameters were received
function p.debug(frame)
    local args = frame:getParent().args
    local output = "Received parameters:<br>"

    for k, v in pairs(args) do
        output = output .. k .. " = " .. v .. "<br>"
    end

    return output
end

return p