Module:HeroTable/fr: Difference between revisions

From Heroes of Might and Magic: Olden Era Official Wiki
mNo edit summary
No edit summary
 
(5 intermediate revisions by the same user not shown)
Line 1: Line 1:
local p = {}
local p = {}


-- Chargement des données brutes traduites
-- Chargement de la base de données des héros
local heroesData = require('Module:HeroData/fr')
local heroesData = require('Module:HeroData/fr')


function p.renderInfobox(frame)
-- Fonction principale pour générer toutes les lignes du tableau
     -- Récupère les arguments passés au Modèle (ex: {{Infobox Héros|Mila|army1count=10}})
function p.renderTable(frame)
     local args = frame:getParent().args
     -- Récupère l'argument de faction s'il est spécifié (ex: {{#invoke:HeroTable/fr|renderTable|faction=Temple}})
    local heroName = args[1] or args['name']
     local targetFaction = frame.args.faction or frame:getParent().args.faction
      
      
    if not heroName or heroName == "" then
        return "<strong class='error'>Erreur : Le nom du héros est manquant dans l'appel du modèle.</strong>"
    end
   
    -- Sécurité si la table est mal chargée
     if type(heroesData) ~= "table" then
     if type(heroesData) ~= "table" then
         return "<strong class='error'>Erreur critique : Le Module:HeroData/fr n'a pas renvoyé une table valide.</strong>"
         return "<strong class='error'>Erreur critique : Le Module:HeroData/fr n'a pas pu être chargé.</strong>"
     end
     end
      
 
     local data = heroesData[heroName]
    -- --- MODIFICATION : TRI PAR HERO_ID ---
     if not data then
     -- On crée une table contenant des sous-tables { name = "NomEn", id = 123 }
         return "<strong class='error'>Erreur : Le héros '" .. heroName .. "' est introuvable dans le Module:HeroData/fr.</strong>"
     local sortedHeroes = {}
     for heroKey, heroData in pairs(heroesData) do
         -- Sécurité : conversion de l'ID en nombre, s'il n'existe pas ou est invalide, on met 999
        local idValue = tonumber(heroData.hero_id) or 999
        table.insert(sortedHeroes, { name = heroKey, id = idValue })
     end
     end
    -- --- 1. PRÉPARATION DES VARIABLES COMPOSÉES (LUA + WIKI) ---
    local name_fr = data.name_fr or heroName
    local faction = data.faction or ""
    local faction_fr = data.faction_fr or faction
    local class = data.class or ""
    local class_fr = data.class_fr or class
      
      
     -- Statistiques
     -- Algorithme de tri personnalisé basé sur la valeur du ID numérique
     local att = (data.attributes and data.attributes.attack) or 0
     table.sort(sortedHeroes, function(a, b)
    local def = (data.attributes and data.attributes.defense) or 0
        if a.id ~= b.id then
    local sp  = (data.attributes and data.attributes.spellpower) or 0
            return a.id < b.id -- Trie du plus petit ID au plus grand
    local kn  = (data.attributes and data.attributes.knowledge) or 0
         else
 
            return a.name < b.name -- En cas d'IDs identiques, trie par ordre alphabétique
    -- Gestion dynamique de la ligne "Compétences de départ"
         end
    local skillsHTML = ""
    end)
    if data.skill2 and data.skill2.en and data.skill2.en ~= "" then
     -- --------------------------------------
        -- Le héros a 2 compétences
         skillsHTML = "!colspan=2 style='border: 1px solid #BCB096; background-color:#1E3758; color:white;'|[[Skills/fr|Compétences de départ]]\n|-\n" ..
                    "|colspan=2 style='color: white; border: 1px solid #BCB096; padding:4px;'|\n" ..
                    "<div>[[File:Skill " .. data.skill1.en .. ".png|50px|link=" .. data.skill1.en .. "/fr]] [[" .. data.skill1.en .. "/fr|" .. data.skill1.fr .. "]] (" .. (data.skill1.gender == "f" and "Basique" or "Basique") .. ")</div>\n" ..
                    "<div>[[File:Skill " .. data.skill2.en .. ".png|50px|link=" .. data.skill2.en .. "/fr]] [[" .. data.skill2.en .. "/fr|" .. data.skill2.fr .. "]] (" .. (data.skill2.gender == "f" and "Basique" or "Basique") .. ")</div>"
    else
        -- Le héros n'a qu'une seule compétence (Maîtrise avancée "Advanced")
         skillsHTML = "!colspan=2 style='border: 1px solid #BCB096; background-color:#1E3758; color:white;'|[[Skills/fr|Compétence de départ]]\n|-\n" ..
                    "|colspan=2 style='color: white; border: 1px solid #BCB096; padding:4px;'|\n" ..
                    "<div>[[File:Skill Advanced " .. data.skill1.en .. ".png|50px|link=" .. data.skill1.en .. "/fr]] [[" .. data.skill1.en .. "/fr|" .. data.skill1.fr .. "]] (" .. (data.skill1.gender == "f" and "Avancée" or "Avancé") .. ")</div>"
     end


     -- Gestion dynamique de la ligne "Sorts de départ"
     local wiki = ""
    local spellsHTML = ""
    if data.spells and #data.spells > 0 then
        local label = (#data.spells > 1) and "Sorts de départ" or "Sort de départ"
        spellsHTML = "!colspan=2 style='border: 1px solid #BCB096; background-color:#1E3758; color:white;'|[[Spells/fr|" .. label .. "]]\n|-\n" ..
                    "|colspan=2 style='color: white; border: 1px solid #BCB096; padding:4px;'|\n"
        for _, spell in ipairs(data.spells) do
            spellsHTML = spellsHTML .. "<div>[[File:" .. spell.en .. ".png|50px|link=" .. spell.en .. "/fr]] [[" .. spell.en .. "/fr|" .. spell.fr .. "]]</div>"
        end
    else
        spellsHTML = "!colspan=2 style='border: 1px solid #BCB096; background-color:#1E3758; color:white;'|[[Spells/fr|Sort de départ]]\n|-\n" ..
                    "|colspan=2 style='color: white; border: 1px solid #BCB096; padding:4px;'|<div>Aucun.</div>"
    end


     -- Gestion dynamique de l'armée (Paramètres manuels du wiki)
     -- On parcourt tous les héros triés par leur ID
    local armyHTML = ""
    for _, sortedData in ipairs(sortedHeroes) do
    if args.army1creature and args.army1creature ~= "" then
        local heroName = sortedData.name
         armyHTML = "!colspan=2 style='border: 1px solid #BCB096; background-color:#1E3758; color:white;'|Armée de départ\n|-\n" ..
         local data = heroesData[heroName]
                  "|colspan=2|\n{| style='width:100%; text-align:center;'\n|-\n" ..
                  "|style='width:25%;'|<div style='color: white; display:inline-block; margin:4px 8px; vertical-align:top; text-align:center;'>[[File:" .. args.army1creature .. "_icon.png|75px|link=" .. args.army1creature .. "/fr]]<br/><span style='font-size:1.1em; color:white;'>" .. (args.army1count or "") .. "</span></div>"
          
          
         if args.army2creature and args.army2creature ~= "" then
        -- Si on a demandé une faction spécifique, on filtre les autres
             armyHTML = armyHTML .. "||style='width:25%;'|<div style='color: white; display:inline-block; margin:4px 8px; vertical-align:top; text-align:center;'>[[File:" .. args.army2creature .. "_icon.png|75px|link=" .. args.army2creature .. "/fr]]<br/><span style='font-size:1.1em; color:white;'>" .. (args.army2count or "") .. "</span></div>"
         if not targetFaction or targetFaction == "" or data.faction == targetFaction then
           
            -- Préparation des variables de base
            local icon = data.icon or (heroName .. ".png")
            local name_fr = data.name_fr or heroName
            local class = data.class or ""
             local class_fr = data.class_fr or class
           
            -- Début de la ligne du tableau
            wiki = wiki .. "|-\n"
           
            -- Colonne 1 : Image du héros
            wiki = wiki .. "|style='padding:0.25em 0; border-right:0px; text-align:center;'|[[File:" .. icon .. "|70px|link=" .. heroName .. "/fr]]\n"
           
            -- Colonne 2 : Nom du héros (avec lien interne)
            wiki = wiki .. "|style='border-left:0px; text-align:left;'|[[" .. heroName .. "/fr|" .. name_fr .. "]]\n"
           
            -- Colonne 3 : Classe
            wiki = wiki .. "|style='text-align:center;'|[[" .. class .. "/fr|" .. class_fr .. "]]\n"
           
            -- Colonnes Spécialisation
            if data.specialization then
                local spec = data.specialization
                local spec_icon = spec.icon or ""
                local spec_name = spec.name_fr or ""
                local spec_short = spec.desc_short_fr or ""
                local spec_full = spec.desc_full_fr or ""
               
                -- Colonne 4 : Icône Spécialisation
                wiki = wiki .. "|style='padding:0.25em 0.25em; border-right:0px; text-align:center;'|[[File:" .. spec_icon .. "|64px]]\n"
               
                -- Colonne 5 : Nom + Desc courte + Infobulle (tt) pour la version longue
                wiki = wiki .. "|style='border-left:0px; text-align:left;'|'''" .. spec_name .. "'''<br/>" .. spec_short .. " <sup>''(<span class='explain' title=\"" .. spec_full:gsub('"', '&quot;') .. "\">plus d'infos</span>)''</sup>\n"
            else
                wiki = wiki .. "|style='padding:0.25em 0.25em; border-right:0px;'|\n|style='border-left:0px;'|\n"
            end
           
            -- Colonne 6 : Compétences
            if data.skill2 and data.skill2.en and data.skill2.en ~= "" then
                local sk1_en = data.skill1.en or ""
                local sk1_fr = data.skill1.fr or ""
                local sk2_en = data.skill2.en or ""
                local sk2_fr = data.skill2.fr or ""
               
                wiki = wiki .. "|style='border-left:0px; text-align:left;'|[[File:Skill " .. sk1_en .. ".png|28px]] [[" .. sk1_en .. "/fr|" .. sk1_fr .. "]]<br/>[[File:Skill " .. sk2_en .. ".png|28px]] [[" .. sk2_en .. "/fr|" .. sk2_fr .. "]]\n"
            else
                local sk1_en = data.skill1.en or ""
                local sk1_fr = data.skill1.fr or ""
               
                wiki = wiki .. "|style='border-left:0px; text-align:left;'|[[File:Skill Advanced " .. sk1_en .. ".png|28px]] [[" .. sk1_en .. "/fr|" .. sk1_fr .. "]]\n"
            end
           
            -- Colonne 7 : Sorts de départ
            wiki = wiki .. "|style='text-align:left; border-left:0px;'|"
            if data.spells and #data.spells > 0 then
                for i, spell in ipairs(data.spells) do
                    if i > 1 then wiki = wiki .. "<br/>" end
                    wiki = wiki .. "[[File:" .. spell.en .. ".png|24px]] [[" .. spell.en .. "/fr|" .. spell.fr .. "]]"
                end
            end
            wiki = wiki .. "\n"
           
         end
         end
        if args.army3creature and args.army3creature ~= "" then
            armyHTML = armyHTML .. "||style='width:25%;'|<div style='color: white; display:inline-block; margin:4px 8px; vertical-align:top; text-align:center;'>[[File:" .. args.army3creature .. "_icon.png|75px|link=" .. args.army3creature .. "/fr]]<br/><span style='font-size:1.1em; color:white;'>" .. (args.army3count or "") .. "</span></div>"
        end
        armyHTML = armyHTML .. "\n|}"
    end
    -- --- 2. CONSTRUCTION DE LA STRUCTURE DE L'INFOBOX ---
    local wiki = "{| class=infobox style='margin:0em 1em 1em 1em; float:right; text-align: center; vertical-align: middle; width:25%; border-collapse: collapse; border: 1px solid #BCB096'\n" ..
                "|-style='border-bottom: 1px solid #BCB096; background-color:#1E3758'\n" ..
                "|colspan=2|\n{|style='width:100%; text-align: center; vertical-align: middle; border-collapse: collapse;'\n" ..
                "|<span style='font-size: 150%; color:white;'>" .. name_fr .. "</span>\n" ..
                "|}\n" ..
                "|-style='border-bottom: 1px solid #BCB096'\n" ..
                "|colspan=2|[[File:" .. heroName .. ".png|300px|link=]]\n" ..
                "|-style='border-bottom: 1px solid #BCB096; background-color:#1E3758'\n" ..
                "|style='border: 1px solid #BCB096; width:50%; color:white;'|[[Faction/fr|Faction]]||style='border: 1px solid #BCB096; width:50%; color:white;'|[[Class/fr|Classe]]\n" ..
                "|-\n" ..
                "|style='border: 1px solid #BCB096; padding:4px; width:50%;'|<div>[[File:" .. faction .. "_icon.png|x30px|link=" .. faction .. "/fr]][[" .. faction .. "/fr|" .. faction_fr .. "]]</div>||style='border: 1px solid #BCB096; padding:4px; width:50%;'|<div>[[File:" .. class .. ".png|x30px|link=" .. class .. "/fr]][[" .. class .. "/fr|" .. class_fr .. "]]</div>\n" ..
                "|-style='border-bottom: 1px solid #BCB096; background-color:#1E3758'\n" ..
                "|colspan=2 style='color:white;'|[[Hero Basics/fr#Attributs|Statistiques de départ]]\n" ..
                "|-style='border-bottom: 1px solid #BCB096'\n" ..
                "|colspan=2|\n" ..
                "{|style='gap:8px; justify-content:space-between; align-items:center; width:100%;'\n" ..
                "|style='color:white; text-align:center; width:25%;'|<div><div style='font-weight:bold; color:white;'>" .. att .. "</div><div style='margin-top:6px;'>[[File:Icon Stats Attack.png|28px|link=Hero_Basics/fr#Attributs]]<br><small>[[:Hero_Basics/fr#Attributs|Attaque]]</div></div>\n" ..
                "|style='color:white; text-align:center; width:25%;'|<div><div style='font-weight:bold; color:white;'>" .. def .. "</div><div style='margin-top:6px;'>[[File:Icon Stats Defence.png|28px|link=Hero_Basics/fr#Attributs]]<br><small>[[:Hero_Basics/fr#Attributs|Défense]]</div></div>\n" ..
                "|style='color:white; text-align:center; width:25%;'|<div><div style='font-weight:bold; color:white;'>" .. sp .. "</div><div style='margin-top:6px;'>[[File:Icon Stats Spellpower.png|28px|link=Hero_Basics/fr#Attributs]]<br><small>[[:Hero_Basics/fr#Attributs|P d S]]</div></div>\n" ..
                "|style='color:white; text-align:center; width:25%;'|<div><div style='font-weight:bold; color:white;'>" .. kn .. "</div><div style='margin-top:6px;'>[[File:Icon Stats Inteligence.png|28px|link=Knowledge/fr]]<br><small>[[:Hero_Basics/fr#Attributs|Savoir]]</div></div>\n" ..
                "|}\n" ..
                "|-\n" .. skillsHTML .. "\n" ..
                "|-\n" .. spellsHTML .. "\n" ..
                "|-\n" .. armyHTML .. "\n" ..
                "|}\n\n"
    -- --- 3. SECTIONS HORS INFOBOX (TEXTES ET BIOGRAPHIE) ---
    if args.tagline and args.tagline ~= "" then
        wiki = wiki .. "{| class=\"quote\" cellspacing=\"0\" cellpadding=\"0\" style=\"padding:0; margin:.5em 1em .5em 1em; width:auto;\"\n" ..
              "|style=\"padding:2.5px 10px; text-align:center\"|''" .. args.tagline .. "''<br>\n" ..
              "|}\n"
    end
   
    if args.intro and args.intro ~= "" then
        wiki = wiki .. args.intro .. "\n\n"
    end
   
    if args.biography and args.biography ~= "" then
        wiki = wiki .. "==Biographie==\n" .. args.biography .. "\n\n"
    end
    -- --- 4. SECTION SPÉCIALISATION (DONNÉES AUTOMATIQUES) ---
    if data.specialization then
        local spec = data.specialization
        local spec_icon = spec.icon or ""
        local spec_name = spec.name_fr or ""
        local spec_desc = spec.desc_full_fr or ""
       
        wiki = wiki .. "==Spécialisation==\n" ..
              "{|style='border-collapse: collapse; border: 1px solid #BCB096; width:100%; margin: 8px 0px 8px'\n" ..
              "|-style='border: 1px solid #BCB096; background-color:#1E3758;'\n" ..
              "| style='text-align:center; width:80px; vertical-align:middle; padding:5px' |[[File:" .. spec_icon .. "|70px]]|| style='padding:10px; color:white;' | <b>" .. spec_name .. "</b>\n" ..
              "|-style='text-color: white'\n" ..
              "|style='padding:10px;' colspan=2|" .. spec_desc .. "\n" ..
              "|}\n\n"
    end
    -- --- 5. STRATÉGIE ET ANECDOTE ---
    wiki = wiki .. "==Stratégie==\n"
    if args.strategy and args.strategy ~= "" then
        wiki = wiki .. args.strategy .. "\n\n"
    else
        wiki = wiki .. "<span style=\"font-style: italic;\">à venir.</span>\n\n"
    end
   
    if args.trivia and args.trivia ~= "" then
        wiki = wiki .. "==Anecdote==\n" .. args.trivia .. "\n"
     end
     end


     return wiki
     return wiki
end
-- Fonction d'aide pour découper les chaînes (utilisée pour les sorts si besoin)
function p.split(inputstr, sep)
    if sep == nil then
        sep = "%s"
    end
    local t = {}
    local i = 1
    for str in string.gmatch(inputstr, "([^" .. sep .. "]+)") do
        t[i] = str
        i = i + 1
    end
    return t
end
end


return p
return p

Latest revision as of 14:43, 23 May 2026

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

local p = {}

-- Chargement de la base de données des héros
local heroesData = require('Module:HeroData/fr')

-- Fonction principale pour générer toutes les lignes du tableau
function p.renderTable(frame)
    -- Récupère l'argument de faction s'il est spécifié (ex: {{#invoke:HeroTable/fr|renderTable|faction=Temple}})
    local targetFaction = frame.args.faction or frame:getParent().args.faction
    
    if type(heroesData) ~= "table" then
        return "<strong class='error'>Erreur critique : Le Module:HeroData/fr n'a pas pu être chargé.</strong>"
    end

    -- --- MODIFICATION : TRI PAR HERO_ID ---
    -- On crée une table contenant des sous-tables { name = "NomEn", id = 123 }
    local sortedHeroes = {}
    for heroKey, heroData in pairs(heroesData) do
        -- Sécurité : conversion de l'ID en nombre, s'il n'existe pas ou est invalide, on met 999
        local idValue = tonumber(heroData.hero_id) or 999
        table.insert(sortedHeroes, { name = heroKey, id = idValue })
    end
    
    -- Algorithme de tri personnalisé basé sur la valeur du ID numérique
    table.sort(sortedHeroes, function(a, b)
        if a.id ~= b.id then
            return a.id < b.id -- Trie du plus petit ID au plus grand
        else
            return a.name < b.name -- En cas d'IDs identiques, trie par ordre alphabétique
        end
    end)
    -- --------------------------------------

    local wiki = ""

    -- On parcourt tous les héros triés par leur ID
    for _, sortedData in ipairs(sortedHeroes) do
        local heroName = sortedData.name
        local data = heroesData[heroName]
        
        -- Si on a demandé une faction spécifique, on filtre les autres
        if not targetFaction or targetFaction == "" or data.faction == targetFaction then
            
            -- Préparation des variables de base
            local icon = data.icon or (heroName .. ".png")
            local name_fr = data.name_fr or heroName
            local class = data.class or ""
            local class_fr = data.class_fr or class
            
            -- Début de la ligne du tableau
            wiki = wiki .. "|-\n"
            
            -- Colonne 1 : Image du héros
            wiki = wiki .. "|style='padding:0.25em 0; border-right:0px; text-align:center;'|[[File:" .. icon .. "|70px|link=" .. heroName .. "/fr]]\n"
            
            -- Colonne 2 : Nom du héros (avec lien interne)
            wiki = wiki .. "|style='border-left:0px; text-align:left;'|[[" .. heroName .. "/fr|" .. name_fr .. "]]\n"
            
            -- Colonne 3 : Classe
            wiki = wiki .. "|style='text-align:center;'|[[" .. class .. "/fr|" .. class_fr .. "]]\n"
            
            -- Colonnes Spécialisation
            if data.specialization then
                local spec = data.specialization
                local spec_icon = spec.icon or ""
                local spec_name = spec.name_fr or ""
                local spec_short = spec.desc_short_fr or ""
                local spec_full = spec.desc_full_fr or ""
                
                -- Colonne 4 : Icône Spécialisation
                wiki = wiki .. "|style='padding:0.25em 0.25em; border-right:0px; text-align:center;'|[[File:" .. spec_icon .. "|64px]]\n"
                
                -- Colonne 5 : Nom + Desc courte + Infobulle (tt) pour la version longue
                wiki = wiki .. "|style='border-left:0px; text-align:left;'|'''" .. spec_name .. "'''<br/>" .. spec_short .. " <sup>''(<span class='explain' title=\"" .. spec_full:gsub('"', '&quot;') .. "\">plus d'infos</span>)''</sup>\n"
            else
                wiki = wiki .. "|style='padding:0.25em 0.25em; border-right:0px;'|\n|style='border-left:0px;'|\n"
            end
            
            -- Colonne 6 : Compétences
            if data.skill2 and data.skill2.en and data.skill2.en ~= "" then
                local sk1_en = data.skill1.en or ""
                local sk1_fr = data.skill1.fr or ""
                local sk2_en = data.skill2.en or ""
                local sk2_fr = data.skill2.fr or ""
                
                wiki = wiki .. "|style='border-left:0px; text-align:left;'|[[File:Skill " .. sk1_en .. ".png|28px]] [[" .. sk1_en .. "/fr|" .. sk1_fr .. "]]<br/>[[File:Skill " .. sk2_en .. ".png|28px]] [[" .. sk2_en .. "/fr|" .. sk2_fr .. "]]\n"
            else
                local sk1_en = data.skill1.en or ""
                local sk1_fr = data.skill1.fr or ""
                
                wiki = wiki .. "|style='border-left:0px; text-align:left;'|[[File:Skill Advanced " .. sk1_en .. ".png|28px]] [[" .. sk1_en .. "/fr|" .. sk1_fr .. "]]\n"
            end
            
            -- Colonne 7 : Sorts de départ
            wiki = wiki .. "|style='text-align:left; border-left:0px;'|"
            if data.spells and #data.spells > 0 then
                for i, spell in ipairs(data.spells) do
                    if i > 1 then wiki = wiki .. "<br/>" end
                    wiki = wiki .. "[[File:" .. spell.en .. ".png|24px]] [[" .. spell.en .. "/fr|" .. spell.fr .. "]]"
                end
            end
            wiki = wiki .. "\n"
            
        end
    end

    return wiki
end

return p