« Module:Infobox/Arme gamebryo » : différence entre les versions

De Les Archives de Vault-Tec
Kharmitch (discussion | contributions)
mAucun résumé des modifications
Kharmitch (discussion | contributions)
mAucun résumé des modifications
Ligne 24 : Ligne 24 :


--------------------------------------------------------
--------------------------------------------------------
-----             Calcul des dégâts               -----
-----           Calcul des dégâts et              -----
-----      et création des tables de stats        -----
--------------------------------------------------------
--------------------------------------------------------


-- Type d'arme
function buildStatsTables(localdata)
local weaponCompletType = localdata["type"] or ""
    -- Type d'arme
local weaponType = weaponCompletType:gsub(" unique", "")
    local weaponCompletType = localdata["type"] or ""
local isUnique = weaponCompletType:find(' unique')
    local weaponType = weaponCompletType:gsub(" unique", "")
    local isUnique = weaponCompletType:find(' unique')
   
    -- Dégâts
    local attacksPerSec = forceNumber(localdata["attack shots/sec"])
   
    -- Augmentation des dégâts via les aptitudes
    -- Les aptitudes agissent comme un coefficient multiplicateur
    local perksAttacksPerSec = 0
   
    for i = 1, 9 do
        local perkAttsecMult = forceNumber(localdata["perk" .. i .. " attsec mult"])
        if perkAttsecMult > 0 then
            perksAttacksPerSec = perksAttacksPerSec + (attacksPerSec * perkAttsecMult)
        else
            break
        end
    end
   
    local perksAttacksPerSecTotal = attacksPerSec + perksAttacksPerSec
   
    -- Multiplicateur de critique
    local critChance = forceNumber(localdata["crit % mult"])


-- Dégâts
    local critChanceModified = 0
local attacksPerSec = forceNumber(localdata["attack shots/sec"])
    if weaponType == 'gunautomatic' and perksAttacksPerSecTotal > 0 then
        critChanceModified = critChance / perksAttacksPerSecTotal
    end


-- Augmentation des dégâts via les aptitudes
    -- Nombre de projectiles
-- Les aptitudes agissent comme un coefficient multiplicateur
    local proj = 1
local perksAttacksPerSec = 0
    if weaponType == "gun" or weaponType == "gunautomatic" or weaponType == "gunhandload" then
        proj = forceNumber(localdata["projectiles"])
        if proj == 0 then proj = 1 end
    end


for i = 1, 9 do
    local clipRounds = forceNumber(localdata["clip rounds"])
local perkAttsecMult = forceNumber(localdata["perk" .. i .. " attsec mult"])
    local ammoUse = forceNumber(localdata["ammo use"])
if perkAttsecMult > 0 then
perksAttacksPerSec = perksAttacksPerSec + (attacksPerSec * perkAttsecMult)
else
break
end
end


local perksAttacksPerSecTotal = attacksPerSec + perksAttacksPerSec
    local shotsPerReload = 0
    if ammoUse > 0 then
        shotsPerReload = math.floor(clipRounds / ammoUse)
    end


-- Multiplicateur de critique
    -- Durée de rechargement
    local reloadTime = 0
    if weaponType == "gun" or weaponType == "gunautomatic" or weaponType == "gunhandload" then
        reloadTime = forceNumber(localdata["reload time"])
    end


local critChance = forceNumber(localdata["crit % mult"])
    -- Durée de rechargement en prenant en compte les aptitudes
    local perksReloadTime = 0


local critChanceModified = 0
    for i = 1, 9 do
if weaponType == 'gunautomatic' and perksAttacksPerSecTotal > 0 then
        local perkReloadTime = localdata["perk" .. i .. " reload mult"]
critChanceModified = critChance / perksAttacksPerSecTotal
        if perkReloadTime and type(perkReloadTime) == "number" then
end
            perksReloadTime = perksReloadTime + (reloadTime * perkReloadTime)
        else
            break
        end
    end


-- Nombre de projectiles
    local perksReloadTimeTotal = reloadTime - perksReloadTime
local proj = 1
if weaponType == "gun" or weaponType == "gunautomatic" or weaponType == "gunhandload" then
proj = forceNumber(localdata["projectiles"])
if proj == 0 then proj = 1 end
end


local clipRounds = forceNumber(localdata["clip rounds"])
    -- Dégâts par type (simple, explosif, poison)
local ammoUse = forceNumber(localdata["ammo use"])


local shotsPerReload = 0
    local damNormTotal = forceNumber(localdata["damage"])
if ammoUse > 0 then
    local damNormProj = damNormTotal / proj
shotsPerReload = math.floor(clipRounds / ammoUse)
end


-- Durée de rechargement
    local damEffProj = forceNumber(localdata["effect damage"])
local reloadTime = 0
    local damEffTotal = damEffProj * proj
if weaponType == "gun" or weaponType == "gunautomatic" or weaponType == "gunhandload" then
reloadTime = forceNumber(localdata["reload time"])
end


-- Durée de rechargement en prenant en compte les aptitudes
    local damExplProj = forceNumber(localdata["explosion damage"])
local perksReloadTime = 0
    local damExplTotal = damExplProj * proj


for i = 1, 9 do
    local perksDamNorm = 0
local perkReloadTime = localdata["perk" .. i .. " reload mult"]
if perkReloadTime and type(perkReloadTime) == "number" then
perksReloadTime = perksReloadTime + (reloadTime * perkReloadTime)
else
break
end
end


local perksReloadTimeTotal = reloadTime - perksReloadTime
    for i = 1, 9 do
        local perkDamNormMult = localdata["perk" .. i .. " mult"] or 0
        local perkDamNormAdd  = localdata["perk" .. i .. " add"] or 0
        if type(perkDamNormMult) == "number" and type(perkDamNormAdd) == "number" then
            perksDamNorm = perksDamNorm + (damNormTotal * perkDamNormMult) + perkDamNormAdd
        else
            break
        end
    end


-- Dégâts par type (simple, explosif, poison)
    local perksDamNormProj = perksDamNorm / proj
    local perksDamNormTotal = damNormTotal + perksDamNorm
    local perksDamNormProjTotal = damNormProj + perksDamNormProj


local damNormTotal = forceNumber(localdata["damage"])
    local perksDamEff = 0
local damNormProj = damNormTotal / proj


local damEffProj = forceNumber(localdata["effect damage"])
    for i = 1, 9 do
local damEffTotal = damEffProj * proj
        local perkDamEffMult = localdata["perk" .. i .. " eff mult"] or 0
        local perkDamEffAdd  = localdata["perk" .. i .. " eff add"] or 0
        if type(perkDamEffMult) == "number" and type(perkDamEffAdd) == "number" then
            perksDamEff = perksDamEff + (damEffProj * perkDamEffMult) + perkDamEffAdd
        else
            break
        end
    end


local damExplProj = forceNumber(localdata["explosion damage"])
    local perksDamEffProj = perksDamEff / proj
local damExplTotal = damExplProj * proj
    local perksDamEffTotal = damEffTotal + perksDamEff
    local perksDamEffProjTotal = damEffProj + perksDamEffProj


local perksDamNorm = 0
    local perksDamExpl = 0


for i = 1, 9 do
    for i = 1, 9 do
local perkDamNormMult = localdata["perk" .. i .. " mult"] or 0
        local perkDamExplMult = localdata["perk" .. i .. " eff mult"] or 0
local perkDamNormAdd = localdata["perk" .. i .. " add"] or 0
        local perkDamExplAdd = localdata["perk" .. i .. " eff add"] or 0
if type(perkDamNormMult) == "number" and type(perkDamNormAdd) == "number" then
        if type(perkDamExplMult) == "number" and type(perkDamExplAdd) == "number" then
perksDamNorm = perksDamNorm + (damNormTotal * perkDamNormMult) + perkDamNormAdd
            perksDamExpl = perksDamExpl + (damExplTotal * perkDamExplMult) + perkDamExplAdd
else
        else
break
            break
end
        end
end
    end


local perksDamNormProj = perksDamNorm / proj
    local perksDamExplProj = perksDamExpl / proj
local perksDamNormTotal = damNormTotal + perksDamNorm
    local perksDamExplTotal = damExplTotal + perksDamExpl
local perksDamNormProjTotal = damNormProj + perksDamNormProj
    local perksDamExplProjTotal = damExplTotal + perksDamExplProj


local perksDamEff = 0
    -- Calcul du DPS
    local DPS = (damNormTotal + damExplTotal) * attacksPerSec
    local DPSPerks = (perksDamNormTotal + perksDamExplTotal) * perksAttacksPerSecTotal


for i = 1, 9 do
    -- Calcul du DPS en prenant en compte la durée de rechargement
local perkDamEffMult = localdata["perk" .. i .. " eff mult"] or 0
    local DPSReload = 0
local perkDamEffAdd  = localdata["perk" .. i .. " eff add"] or 0
    local DPSReloadPerks = 0
if type(perkDamEffMult) == "number" and type(perkDamEffAdd) == "number" then
perksDamEff = perksDamEff + (damEffProj * perkDamEffMult) + perkDamEffAdd
else
break
end
end


local perksDamEffProj = perksDamEff / proj
    local coeff = 1
local perksDamEffTotal = damEffTotal + perksDamEff
    if weaponType == "gunhandload" then
local perksDamEffProjTotal = damEffProj + perksDamEffProj
        coeff = shotsPerReload
    end


local perksDamExpl = 0
    if shotsPerReload > 0 then
        if attacksPerSec > 0 then
            DPSReload = ((damNormTotal + damExplTotal) * shotsPerReload) /
                ((shotsPerReload / attacksPerSec) + reloadTime * coef)
        end
       
        if perksAttacksPerSecTotal > 0 then
            DPSReloadPerks = ((perksDamNormTotal + perksDamExplTotal) * shotsPerReload) /
                ((shotsPerReload / perksAttacksPerSecTotal) + perksReloadTimeTotal * coef)
        end
    end


for i = 1, 9 do
    --------------------------------------------------------
local perkDamExplMult = localdata["perk" .. i .. " eff mult"] or 0
    -----            Formatage des données            -----
local perkDamExplAdd  = localdata["perk" .. i .. " eff add"] or 0
    --------------------------------------------------------
if type(perkDamExplMult) == "number" and type(perkDamExplAdd) == "number" then
perksDamExpl = perksDamExpl + (damExplTotal * perkDamExplMult) + perkDamExplAdd
else
break
end
end


local perksDamExplProj = perksDamExpl / proj
    local damagePerAttackCell = formatData(damNormTotal)
local perksDamExplTotal = damExplTotal + perksDamExpl
    if perksDamNormTotal > 0 then damagePerAttackCell = damagePerAttackCell .. ' (' .. formatData(perksDamNormTotal) .. ')' end
local perksDamExplProjTotal = damExplTotal + perksDamExplProj
    if damExplTotal > 0 then
        damagePerAttackCell = damagePerAttackCell .. ' + ' .. formatData(damExplTotal)
        if perksDamExplTotal > 0 then damagePerAttackCell = damagePerAttackCell .. ' (' .. formatData(perksDamExplTotal) .. ')' end
        damagePerAttackCell = damagePerAttackCell .. ' ' .. icon.build({ 'explosion' })
    end


-- Calcul du DPS
    if damEffTotal > 0 then
local DPS = (damNormTotal + damExplTotal) * attacksPerSec
        local effectDuration = localdata["effect duration"] or "1"
local DPSPerks = (perksDamNormTotal + perksDamExplTotal) * perksAttacksPerSecTotal
        damagePerAttackCell = damagePerAttackCell .. ' + ' .. formatData(damEffTotal)
        if perksDamEffTotal > 0 then damagePerAttackCell = damagePerAttackCell .. ' (' .. formatData(perksDamEffTotal) .. ')' end
        damagePerAttackCell = damagePerAttackCell .. ' sur ' .. effectDuration .. ' s ' .. icon.build({ 'effet' })
    end


-- Calcul du DPS en prenant en compte la durée de rechargement
    local damagePerProjCell = formatData(damNormProj)
local DPSReload = 0
    if perksDamNormProj > 0 then damagePerProjCell = damagePerProjCell .. ' (' .. formatData(perksDamNormProj) .. ')' end
local DPSReloadPerks = 0
    if damExplProj > 0 then
        damagePerProjCell = damagePerProjCell .. ' + ' .. formatData(damExplProj)
        if perksDamExplProjTotal > 0 then damagePerProjCell = damagePerProjCell .. ' (' .. formatData(perksDamExplProjTotal) .. ')' end
        damagePerProjCell = damagePerProjCell .. ' ' .. icon.build({ 'explosion' })
    end


local coeff = 1
    if damEffProj > 0 then
if weaponType == "gunhandload" then
        local effectDuration = localdata["effect duration"] or "1"
coeff = shotsPerReload
        damagePerProjCell = damagePerProjCell .. ' + ' .. formatData(damEffProj)
end
        if perksDamEffProjTotal > 0 then damagePerProjCell = damagePerProjCell .. ' (' .. formatData(perksDamEffProjTotal) .. ')' end
        damagePerProjCell = damagePerProjCell .. ' sur ' .. effectDuration .. ' s ' .. icon.build({ 'effet' })
    end


if shotsPerReload > 0 then
    local dpsCell = formatData(DPS)
if attacksPerSec > 0 then
    if DPSPerks > 0 then dpsCell = dpsCell .. ' ('.. formatData(DPSPerks) .. ')' end
DPSReload = ((damNormTotal + damExplTotal) * shotsPerReload) /
    if damEffTotal > 0 then
((shotsPerReload / attacksPerSec) + reloadTime * coef)
        dpsCell = dpsCell .. ' + ' .. formatData(damEffTotal)
end
        if perksDamEffTotal > 0 then dpsCell = dpsCell .. ' (' .. perksDamEffTotal .. ')' end
        dpsCell = dpsCell .. ' ' .. icon.build({ 'effet' })
if perksAttacksPerSecTotal > 0 then
    end
DPSReloadPerks = ((perksDamNormTotal + perksDamExplTotal) * shotsPerReload) /
((shotsPerReload / perksAttacksPerSecTotal) + perksReloadTimeTotal * coef)
end
end


--------------------------------------------------------
    local dpsReloadCell = formatData(DPSReload)
-----            Formatage des données            -----
    if DPSReloadPerks > 0 then dpsReloadCell = dpsReloadCell .. ' ('.. formatData(DPSReloadPerks) .. ')' end
--------------------------------------------------------
    if damEffTotal > 0 then
        dpsReloadCell = dpsReloadCell .. ' + ' .. formatData(damEffTotal)
        if perksDamEffTotal > 0 then dpsReloadCell = dpsReloadCell .. ' (' .. formatData(perksDamEffTotal) .. ')' end
        dpsReloadCell = dpsReloadCell .. ' ' .. icon.build({ 'effet' })
    end


local damagePerAttackCell = formatData(damNormTotal)
    local critMultCell = critChance
if perksDamNormTotal > 0 then damagePerAttackCell = damagePerAttackCell .. ' (' .. formatData(perksDamNormTotal) .. ')' end
    if critChanceModified > 0 then critMultCell = critChanceModified end
if damExplTotal > 0 then
    critMultCell = 'x ' .. formatData(critMultCell, "%.2f")
damagePerAttackCell = damagePerAttackCell .. ' + ' .. formatData(damExplTotal)
if perksDamExplTotal > 0 then damagePerAttackCell = damagePerAttackCell .. ' (' .. formatData(perksDamExplTotal) .. ')' end
damagePerAttackCell = damagePerAttackCell .. ' ' .. icon.build({ 'explosion' })
end


if damEffTotal > 0 then
    local attackPerSecondCell = formatData(attacksPerSec)
local effectDuration = localdata["effect duration"] or "1"
    if perksAttacksPerSecTotal > 0 then attackPerSecondCell = attackPerSecondCell .. ' (' .. formatData(perksAttacksPerSecTotal) .. ')' end
damagePerAttackCell = damagePerAttackCell .. ' + ' .. formatData(damEffTotal)
if perksDamEffTotal > 0 then damagePerAttackCell = damagePerAttackCell .. ' (' .. formatData(perksDamEffTotal) .. ')' end
damagePerAttackCell = damagePerAttackCell .. ' sur ' .. effectDuration .. ' s ' .. icon.build({ 'effet' })
end
 
local damagePerProjCell = formatData(damNormProj)
if perksDamNormProj > 0 then damagePerProjCell = damagePerProjCell .. ' (' .. formatData(perksDamNormProj) .. ')' end
if damExplProj > 0 then
damagePerProjCell = damagePerProjCell .. ' + ' .. formatData(damExplProj)
if perksDamExplProjTotal > 0 then damagePerProjCell = damagePerProjCell .. ' (' .. formatData(perksDamExplProjTotal) .. ')' end
damagePerProjCell = damagePerProjCell .. ' ' .. icon.build({ 'explosion' })
end


if damEffProj > 0 then
    local reloadTimeCell = formatData(reloadTime)
local effectDuration = localdata["effect duration"] or "1"
    if perksReloadTimeTotal > 0 then reloadTimeCell = reloadTimeCell .. ' (' .. formatData(perksReloadTimeTotal) .. ')' end
damagePerProjCell = damagePerProjCell .. ' + ' .. formatData(damEffProj)
if perksDamEffProjTotal > 0 then damagePerProjCell = damagePerProjCell .. ' (' .. formatData(perksDamEffProjTotal) .. ')' end
damagePerProjCell = damagePerProjCell .. ' sur ' .. effectDuration .. ' s ' .. icon.build({ 'effet' })
end


local dpsCell = formatData(DPS)
    --------------------------------------------------------
if DPSPerks > 0 then dpsCell = dpsCell .. ' ('.. formatData(DPSPerks) .. ')' end
    -----                    Retour                    -----
if damEffTotal > 0 then
    --------------------------------------------------------
dpsCell = dpsCell .. ' + ' .. formatData(damEffTotal)
if perksDamEffTotal > 0 then dpsCell = dpsCell .. ' (' .. perksDamEffTotal .. ')' end
dpsCell = dpsCell .. ' ' .. icon.build({ 'effet' })
end


local dpsReloadCell = formatData(DPSReload)
    return { type = 'table', title = 'Statistiques de combat', collapseparameters = { collapsible = true, collapsed = true }, rows = {
if DPSReloadPerks > 0 then dpsReloadCell = dpsReloadCell .. ' ('.. formatData(DPSReloadPerks) .. ')' end
        { type = 'row', label = 'Dégâts par attaque', value = function() return damagePerAttackCell end },
if damEffTotal > 0 then
        { type = 'row', label = 'Dégâts par projectile', value = function() return damagePerProjCell end },
dpsReloadCell = dpsReloadCell .. ' + ' .. formatData(damEffTotal)
        { type = 'row', label = 'Dégâts par seconde', value = function() return dpsCell end },
if perksDamEffTotal > 0 then dpsReloadCell = dpsReloadCell .. ' (' .. formatData(perksDamEffTotal) .. ')' end
        { type = 'row', label = 'Dégâts par seconde (avec rechargement)', value = function() return dpsReloadCell end },
dpsReloadCell = dpsReloadCell .. ' ' .. icon.build({ 'effet' })
        { type = 'row', label = 'Dégâts critiques', value = 'crit dmg' },
        { type = 'row', label = 'Multiplicateur de critique', value = function() return critMultCell end },
        { type = 'row', label = 'Attaques par seconde', value = function() return attackPerSecondCell end },
        { type = 'row', label = 'Points d\'action', value = 'ap' },
        { type = 'row', label = 'Projectiles', value = 'projectiles' },
        { type = 'row', label = 'Dispersion', value = 'min spread' },
        { type = 'row', label = 'Effet', value = 'other effect' },
        { type = 'row', label = 'Effet critique', value = 'crit effect' }
    }},
    { type = 'table', title = 'Munitions et rechargement', collapseparameters = { collapsible = true, collapsed = true }, rows = {
        { type = 'row', label = 'Type de munitions', value = 'ammo' },
        { type = 'row', label = 'Projectiles par tir', value = 'ammo use' },
        { type = 'row', label = 'Tirs par magasin', function() return formatData(shotsPerReload) end },
        { type = 'row', label = 'Capacité', value = 'clip rounds' },
        { type = 'row', label = 'Durée de rechargement', value = function() return reloadTimeCell end }
    }}
end
end
local critMultCell = critChance
if critChanceModified > 0 then critMultCell = critChanceModified end
critMultCell = 'x ' .. formatData(critMultCell, "%.2f")
local attackPerSecondCell = formatData(attacksPerSec)
if perksAttacksPerSecTotal > 0 then attackPerSecondCell = attackPerSecondCell .. ' (' .. formatData(perksAttacksPerSecTotal) .. ')' end
local reloadTimeCell = formatData(reloadTime)
if perksReloadTimeTotal > 0 then reloadTimeCell = reloadTimeCell .. ' (' .. formatData(perksReloadTimeTotal) .. ')' end


--------------------------------------------------------
--------------------------------------------------------
Ligne 246 : Ligne 274 :
{ type = 'title', value = 'nom', subtitle = 'sous-titre', icon = 'icône', subhead = { games = 'jeux', subject = 'Arme', link = 'Armes' }},
{ type = 'title', value = 'nom', subtitle = 'sous-titre', icon = 'icône', subhead = { games = 'jeux', subject = 'Arme', link = 'Armes' }},
{ type = 'images', imageparameters = { 'image', 'image2', 'image3', 'image4', 'image5' }, captionparameter = { 'légende', 'image desc' }},
{ type = 'images', imageparameters = { 'image', 'image2', 'image3', 'image4', 'image5' }, captionparameter = { 'légende', 'image desc' }},
{ type = 'table', title = 'Conditions d\'utilisation', rows = {
buildStatsTables(localdata),
{ type = 'row', label = 'Compétence', value = 'compétence' },
{ type = 'row', label = 'Force', value = 'force' }
}},
{ type = 'table', title = 'Statistiques de combat', collapseparameters = { collapsible = true, collapsed = true }, rows = {
{ type = 'row', label = 'Dégâts par attaque', value = function() return damagePerAttackCell end },
{ type = 'row', label = 'Dégâts par projectile', value = function() return damagePerProjCell end },
{ type = 'row', label = 'Dégâts par seconde', value = function() return dpsCell end },
{ type = 'row', label = 'Dégâts par seconde (avec rechargement)', value = function() return dpsReloadCell end },
{ type = 'row', label = 'Dégâts critiques', value = 'crit dmg' },
{ type = 'row', label = 'Multiplicateur de critique', value = function() return critMultCell end },
{ type = 'row', label = 'Attaques par seconde', value = function() return attackPerSecondCell end },
{ type = 'row', label = 'Points d\'action', value = 'ap' },
{ type = 'row', label = 'Projectiles', value = 'projectiles' },
{ type = 'row', label = 'Dispersion', value = 'min spread' },
{ type = 'row', label = 'Effet', value = 'other effect' },
{ type = 'row', label = 'Effet critique', value = 'crit effect' }
}},
{ type = 'table', title = 'Munitions et rechargement', collapseparameters = { collapsible = true, collapsed = true }, rows = {
{ type = 'row', label = 'Type de munitions', value = 'ammo' },
{ type = 'row', label = 'Projectiles par tir', value = 'ammo use' },
{ type = 'row', label = 'Tirs par magasin', function() return formatData(shotsPerReload) end },
{ type = 'row', label = 'Capacité', value = 'clip rounds' },
{ type = 'row', label = 'Durée de rechargement', value = function() return reloadTimeCell end }
}},
{ type = 'table', title = 'Autres propriétés', rows = {
{ type = 'row', label = 'Poids', value = 'poids' },
{ type = 'row', label = 'Valeur', value = 'valeur' },
{ type = 'row', label = 'Points de vie', 'hp' },
{ type = 'row', label = 'Réparation', value = 'repair' },
{ type = 'row', label = 'Quêtes', value = 'quêtes' }
}},
{ type = 'table', title = 'Effets des aptitudes', rows = {
{ type = 'table', title = 'Effets des aptitudes', rows = {
-- TODO
-- TODO

Version du 30 juillet 2021 à 18:08

Documentation du module

Ce module contient le paramétrage de l'infobox {{Infobox arme gamebryo}}.

Documentation transclues de Module:Infobox/Arme gamebryo/doc.
local localdata = require( 'Module:Infobox/Localdata' )
local icon = require( 'Module:Icône' )

--------------------------------------------------------
-----             Fonctions communes               -----
--------------------------------------------------------

-- Récupère un paramètre en forçant à 0
-- si nil ou n'est pas nombre
function forceNumber(data)
	if not data or type(data) ~= 'number' then
		return 0
	end
	return data
end

function formatData(data, round)
--	local formattedData
--	if data and data > 0 then
--		formattedData = string.format(round, data)
--	end
	return string.format(round or "%.1f", data)
end

--------------------------------------------------------
-----            Calcul des dégâts et              -----
-----       et création des tables de stats         -----
--------------------------------------------------------

function buildStatsTables(localdata)
    -- Type d'arme
    local weaponCompletType = localdata["type"] or ""
    local weaponType = weaponCompletType:gsub(" unique", "")
    local isUnique = weaponCompletType:find(' unique')
    
    -- Dégâts
    local attacksPerSec = forceNumber(localdata["attack shots/sec"])
    
    -- Augmentation des dégâts via les aptitudes
    -- Les aptitudes agissent comme un coefficient multiplicateur
    local perksAttacksPerSec = 0
    
    for i = 1, 9 do
        local perkAttsecMult = forceNumber(localdata["perk" .. i .. " attsec mult"])
        if perkAttsecMult > 0 then
            perksAttacksPerSec = perksAttacksPerSec + (attacksPerSec * perkAttsecMult)
        else
            break
        end
    end
    
    local perksAttacksPerSecTotal = attacksPerSec + perksAttacksPerSec
    
    -- Multiplicateur de critique
    local critChance = forceNumber(localdata["crit % mult"])

    local critChanceModified = 0
    if weaponType == 'gunautomatic' and perksAttacksPerSecTotal > 0 then
        critChanceModified = critChance / perksAttacksPerSecTotal
    end

    -- Nombre de projectiles
    local proj = 1
    if weaponType == "gun" or weaponType == "gunautomatic" or weaponType == "gunhandload" then
        proj = forceNumber(localdata["projectiles"])
        if proj == 0 then proj = 1 end
    end

    local clipRounds = forceNumber(localdata["clip rounds"])
    local ammoUse = forceNumber(localdata["ammo use"])

    local shotsPerReload = 0
    if ammoUse > 0 then
        shotsPerReload = math.floor(clipRounds / ammoUse)
    end

    -- Durée de rechargement
    local reloadTime = 0
    if weaponType == "gun" or weaponType == "gunautomatic" or weaponType == "gunhandload" then
        reloadTime = forceNumber(localdata["reload time"])
    end

    -- Durée de rechargement en prenant en compte les aptitudes
    local perksReloadTime = 0

    for i = 1, 9 do
        local perkReloadTime = localdata["perk" .. i .. " reload mult"]
        if perkReloadTime and type(perkReloadTime) == "number" then
            perksReloadTime = perksReloadTime + (reloadTime * perkReloadTime)
        else
            break
        end
    end

    local perksReloadTimeTotal = reloadTime - perksReloadTime

    -- Dégâts par type (simple, explosif, poison)

    local damNormTotal = forceNumber(localdata["damage"])
    local damNormProj = damNormTotal / proj

    local damEffProj = forceNumber(localdata["effect damage"])
    local damEffTotal = damEffProj * proj

    local damExplProj = forceNumber(localdata["explosion damage"])
    local damExplTotal = damExplProj * proj

    local perksDamNorm = 0

    for i = 1, 9 do
        local perkDamNormMult = localdata["perk" .. i .. " mult"] or 0
        local perkDamNormAdd  = localdata["perk" .. i .. " add"] or 0
        if type(perkDamNormMult) == "number" and type(perkDamNormAdd) == "number" then
            perksDamNorm = perksDamNorm + (damNormTotal * perkDamNormMult) + perkDamNormAdd
        else
            break
        end
    end

    local perksDamNormProj = perksDamNorm / proj
    local perksDamNormTotal = damNormTotal + perksDamNorm
    local perksDamNormProjTotal = damNormProj + perksDamNormProj

    local perksDamEff = 0

    for i = 1, 9 do
        local perkDamEffMult = localdata["perk" .. i .. " eff mult"] or 0
        local perkDamEffAdd  = localdata["perk" .. i .. " eff add"] or 0
        if type(perkDamEffMult) == "number" and type(perkDamEffAdd) == "number" then
            perksDamEff = perksDamEff + (damEffProj * perkDamEffMult) + perkDamEffAdd
        else
            break
        end
    end

    local perksDamEffProj = perksDamEff / proj
    local perksDamEffTotal = damEffTotal + perksDamEff
    local perksDamEffProjTotal = damEffProj + perksDamEffProj

    local perksDamExpl = 0

    for i = 1, 9 do
        local perkDamExplMult = localdata["perk" .. i .. " eff mult"] or 0
        local perkDamExplAdd  = localdata["perk" .. i .. " eff add"] or 0
        if type(perkDamExplMult) == "number" and type(perkDamExplAdd) == "number" then
            perksDamExpl = perksDamExpl + (damExplTotal * perkDamExplMult) + perkDamExplAdd
        else
            break
        end
    end

    local perksDamExplProj = perksDamExpl / proj
    local perksDamExplTotal = damExplTotal + perksDamExpl
    local perksDamExplProjTotal = damExplTotal + perksDamExplProj

    -- Calcul du DPS
    local DPS = (damNormTotal + damExplTotal) * attacksPerSec
    local DPSPerks = (perksDamNormTotal + perksDamExplTotal) * perksAttacksPerSecTotal

    -- Calcul du DPS en prenant en compte la durée de rechargement
    local DPSReload = 0
    local DPSReloadPerks = 0

    local coeff = 1
    if weaponType == "gunhandload" then
        coeff = shotsPerReload
    end

    if shotsPerReload > 0 then
        if attacksPerSec > 0 then
            DPSReload = ((damNormTotal + damExplTotal) * shotsPerReload) /
                ((shotsPerReload / attacksPerSec) + reloadTime * coef)
        end
        
        if perksAttacksPerSecTotal > 0 then
            DPSReloadPerks = ((perksDamNormTotal + perksDamExplTotal) * shotsPerReload) /
                ((shotsPerReload / perksAttacksPerSecTotal) + perksReloadTimeTotal * coef)
        end
    end			

    --------------------------------------------------------
    -----            Formatage des données             -----
    --------------------------------------------------------

    local damagePerAttackCell = formatData(damNormTotal)
    if perksDamNormTotal > 0 then damagePerAttackCell = damagePerAttackCell .. ' (' .. formatData(perksDamNormTotal) .. ')' end
    if damExplTotal > 0 then
        damagePerAttackCell = damagePerAttackCell .. ' + ' .. formatData(damExplTotal)
        if perksDamExplTotal > 0 then damagePerAttackCell = damagePerAttackCell .. ' (' .. formatData(perksDamExplTotal) .. ')' end
        damagePerAttackCell = damagePerAttackCell .. ' ' .. icon.build({ 'explosion' })
    end

    if damEffTotal > 0 then
        local effectDuration = localdata["effect duration"] or "1"
        damagePerAttackCell = damagePerAttackCell .. ' + ' .. formatData(damEffTotal)
        if perksDamEffTotal > 0 then damagePerAttackCell = damagePerAttackCell .. ' (' .. formatData(perksDamEffTotal) .. ')' end
        damagePerAttackCell = damagePerAttackCell .. ' sur ' .. effectDuration .. ' s ' .. icon.build({ 'effet' })
    end

    local damagePerProjCell = formatData(damNormProj)
    if perksDamNormProj > 0 then damagePerProjCell = damagePerProjCell .. ' (' .. formatData(perksDamNormProj) .. ')' end
    if damExplProj > 0 then
        damagePerProjCell = damagePerProjCell .. ' + ' .. formatData(damExplProj)
        if perksDamExplProjTotal > 0 then damagePerProjCell = damagePerProjCell .. ' (' .. formatData(perksDamExplProjTotal) .. ')' end
        damagePerProjCell = damagePerProjCell .. ' ' .. icon.build({ 'explosion' })
    end

    if damEffProj > 0 then
        local effectDuration = localdata["effect duration"] or "1"
        damagePerProjCell = damagePerProjCell .. ' + ' .. formatData(damEffProj)
        if perksDamEffProjTotal > 0 then damagePerProjCell = damagePerProjCell .. ' (' .. formatData(perksDamEffProjTotal) .. ')' end
        damagePerProjCell = damagePerProjCell .. ' sur ' .. effectDuration .. ' s ' .. icon.build({ 'effet' })
    end

    local dpsCell = formatData(DPS)
    if DPSPerks > 0 then dpsCell = dpsCell .. ' ('.. formatData(DPSPerks) .. ')' end
    if damEffTotal > 0 then
        dpsCell = dpsCell .. ' + ' .. formatData(damEffTotal)
        if perksDamEffTotal > 0 then dpsCell = dpsCell .. ' (' .. perksDamEffTotal .. ')' end
        dpsCell = dpsCell .. ' ' .. icon.build({ 'effet' })
    end

    local dpsReloadCell = formatData(DPSReload)
    if DPSReloadPerks > 0 then dpsReloadCell = dpsReloadCell .. ' ('.. formatData(DPSReloadPerks) .. ')' end
    if damEffTotal > 0 then
        dpsReloadCell = dpsReloadCell .. ' + ' .. formatData(damEffTotal)
        if perksDamEffTotal > 0 then dpsReloadCell = dpsReloadCell .. ' (' .. formatData(perksDamEffTotal) .. ')' end
        dpsReloadCell = dpsReloadCell .. ' ' .. icon.build({ 'effet' })
    end

    local critMultCell = critChance
    if critChanceModified > 0 then critMultCell = critChanceModified end
    critMultCell = 'x ' .. formatData(critMultCell, "%.2f")

    local attackPerSecondCell = formatData(attacksPerSec)
    if perksAttacksPerSecTotal > 0 then attackPerSecondCell = attackPerSecondCell .. ' (' .. formatData(perksAttacksPerSecTotal) .. ')' end

    local reloadTimeCell = formatData(reloadTime)
    if perksReloadTimeTotal > 0 then reloadTimeCell = reloadTimeCell .. ' (' .. formatData(perksReloadTimeTotal) .. ')' end

    --------------------------------------------------------
    -----                    Retour                    -----
    --------------------------------------------------------

    return { type = 'table', title = 'Statistiques de combat', collapseparameters = { collapsible = true, collapsed = true }, rows = {
        { type = 'row', label = 'Dégâts par attaque', value = function() return damagePerAttackCell end },
        { type = 'row', label = 'Dégâts par projectile', value = function() return damagePerProjCell end },
        { type = 'row', label = 'Dégâts par seconde', value = function() return dpsCell end },
        { type = 'row', label = 'Dégâts par seconde (avec rechargement)', value = function() return dpsReloadCell end },
        { type = 'row', label = 'Dégâts critiques', value = 'crit dmg' },
        { type = 'row', label = 'Multiplicateur de critique', value = function() return critMultCell end },
        { type = 'row', label = 'Attaques par seconde', value = function() return attackPerSecondCell end },
        { type = 'row', label = 'Points d\'action', value = 'ap' },
        { type = 'row', label = 'Projectiles', value = 'projectiles' },
        { type = 'row', label = 'Dispersion', value = 'min spread' },
        { type = 'row', label = 'Effet', value = 'other effect' },
        { type = 'row', label = 'Effet critique', value = 'crit effect' }
    }},
    { type = 'table', title = 'Munitions et rechargement', collapseparameters = { collapsible = true, collapsed = true }, rows = {
        { type = 'row', label = 'Type de munitions', value = 'ammo' },
        { type = 'row', label = 'Projectiles par tir', value = 'ammo use' },
        { type = 'row', label = 'Tirs par magasin', function() return formatData(shotsPerReload) end },
        { type = 'row', label = 'Capacité', value = 'clip rounds' },
        { type = 'row', label = 'Durée de rechargement', value = function() return reloadTimeCell end }
    }}
end

--------------------------------------------------------
-----          Construction de l'infobox           -----
--------------------------------------------------------

return {
	parts = {
		{ type = 'title', value = 'nom', subtitle = 'sous-titre', icon = 'icône', subhead = { games = 'jeux', subject = 'Arme', link = 'Armes' }},
		{ type = 'images', imageparameters = { 'image', 'image2', 'image3', 'image4', 'image5' }, captionparameter = { 'légende', 'image desc' }},
		buildStatsTables(localdata),
		{ type = 'table', title = 'Effets des aptitudes', rows = {
			-- TODO
		}},
		{ type = 'table', title = 'Technique', collapseparameters = { collapsible = true, collapsed = true }, rows = {
			{ type = 'row', label = '[[Form ID|Base ID]]', value = 'baseid' },
			{ type = 'row', label = 'Editor ID', value = 'editorid' }
		}},
		{ type = 'text', value = 'pied' }
	}
}