Перейти к содержимому страницы
Открыть меню
Переключить меню настроек
Открыть персональное меню
Вы не представились системе
Если вы внесёте правку, для вас будет создана временная учетная запись.

Для документации этого модуля может быть создана страница Модуль:WeaponInfobox/doc

local p = {}

local lib = require('Module:Feature')
local Infobox = require('Module:InfoboxNeue')
local Tabber = require('Module:Tabber')
local config = require('Module:Config')

local TRAITS = { 
    { l = 'Сила', k = 'correctStrength', r = 'properStrength' }, 
    { l = 'Ловкость', k = 'correctAgility',  r = 'properAgility' }, 
    { l = 'Мудрость', k = 'correctIntelligence', r = 'properIntelligence' }, 
    { l = 'Вера', k = 'correctFaith', r = 'properFaith' }, 
    { l = 'Колдовство', k = 'correctLuck',  r = 'properLuck' } 
}
local STAT_MAP = {
    { l = 'Физ.', atk = 'attackBasePhysics', g = 'physGuardCutRate' },
    { l = 'Маг.', atk = 'attackBaseMagic',   g = 'magGuardCutRate' },
    { l = 'Огонь', atk = 'attackBaseFire',    g = 'fireGuardCutRate' },
    { l = 'Молн.', atk = 'attackBaseThunder', g = 'thunGuardCutRate' },
    { l = 'Свят.', atk = 'attackBaseDark',    g = 'darkGuardCutRate' }
}

local function fetchDb(tableName, where)
    local res = mw.ext.externalData.getDbData{ db = config.dbName, from = tableName, where = where }
    return (res and res[1]) and res[1] or nil
end

local function getEffectDisplay(msgId, w)
    local msgIdNum = tonumber(msgId)
    if not msgIdNum or msgIdNum <= 0 then return nil end

    local msgData = fetchDb('WeaponEffect', "id = " .. msgIdNum)
    local effText = msgData and msgData.rusru
    if not effText or effText == "" then return nil end

    if effText:find("<.->") or effText:find("%%s") then
        local val = 0
        for j = 0, 2 do
            local behId = tonumber(w['spEffectBehaviorId'..j])
            if behId and behId > 0 then
                local sp = fetchDb('SpEffectParam', "id = " .. behId)
                if sp then
                    val = tonumber(sp.bloodAttackPower) or tonumber(sp.poisonAttackPower) 
                       or tonumber(sp.diseaseAttackPower) or tonumber(sp.freezeAttackPower) 
                       or tonumber(sp.sleepAttackPower) or tonumber(sp.madnessAttackPower) 
                       or tonumber(sp.curseAttackPower) or 0
                end
            end
            if val > 0 then break end
        end

        if val > 0 then 
            effText = effText:gsub("<.->", val)
        end
    end
    
    return effText
end

function p.weapon(frame)
    local args = frame:getParent().args
    local wikiName = tostring(args[1] or args.name or mw.title.getCurrentTitle().text):gsub("^%s*(.-)%s*$", "%1")
    
    local synonyms = mw.loadData('Module:Synonyms')
    local searchName = synonyms[wikiName] or wikiName

    local fuzzyName = searchName:gsub("'", "''"):gsub("[%s%c%p]", "%%")
    
    local weaponId
    if args.id then
        weaponId = tostring(args.id)
    else
        local data = fetchDb('WeaponName', "rusru LIKE '" .. fuzzyName .. "'")
        if data and data.id then 
            weaponId = string.format("%.0f", tonumber(data.id))
        end
    end
    
    if not weaponId then return "" end
	
    local w = fetchDb('EquipParamWeapon', "id = " .. weaponId)
    if not w then w = fetchDb('EquipParamWeapon', "id = " .. tonumber(weaponId)) end
    if not w then return "" end

    frame:callParserFunction('#vardefine', 'item_id', weaponId)

    local weaponType = require('Module:Data/WeaponTypes')[tonumber(w.wepType)] or { s = "Оружие", p = "Оружие" }
    local ib = Infobox.new({ type = 'weapon' })
    ib:renderImage(wikiName .. '.png')
    ib:renderHeader({ title = wikiName, subtitle = string.format('[[:Категория:%s|%s]]', weaponType.p, weaponType.s) })

    local atkTypes, caseMap = {}, { ["Обычный"] = "обычным", ["Дробящий"] = "дробящим", ["Рубящий"] = "рубящим", ["Колющий"] = "колющим" }
    if w.isNormalAttackType == "1" then table.insert(atkTypes, "Обычный") end
    if w.isBlowAttackType   == "1" then table.insert(atkTypes, "Дробящий") end
    if w.isSlashAttackType  == "1" then table.insert(atkTypes, "Рубящий") end
    if w.isThrustAttackType == "1" then table.insert(atkTypes, "Колющий") end
    
    local ammo = (w.boltSlotEquipable == "1") and "Болты" or (w.arrowSlotEquipable == "1" and "Стрелы" or nil)
    
    local topSection = {
        ib:renderItem({ label = 'Тип урона', data = #atkTypes > 0 and table.concat(atkTypes, " / ") or "—", row = true, spacebetween = true }),
        ib:renderItem({ label = 'Вес', data = lib.thousandsSeparator(w.weight), row = true, spacebetween = true })
    }
    if ammo then table.insert(topSection, ib:renderItem({ label = 'Снаряды', data = ammo, row = true, spacebetween = true })) end
    ib:renderSection({ content = topSection })

    local sId = tonumber(w.swordArtsParamId or w.swordartsparamid) or 0
    if sId > 0 then
        local sap = fetchDb('SwordArtsParam', "id = " .. sId)
        
        local textId = sap and tonumber(sap.textId or sap.textid) or sId
        
        local skillText = fetchDb('ArtsName', "id = " .. textId)
        
        if skillText and skillText.rusru then
            local sName = skillText.rusru
            local skillLink = mw.title.new("Пепел Войны: " .. sName).exists and string.format("[[Пепел Войны: %s|%s]]", sName, sName) or sName
            
            local function fmtFp(val)
                local v = tonumber(val)
                return (not v or v <= 0) and "—" or tostring(v)
            end

            local l2 = sap and (sap.useMagicPoint_L2 or sap.usemagicpoint_l2)
            local r1 = sap and (sap.useMagicPoint_R1 or sap.usemagicpoint_r1)
            local r2 = sap and (sap.useMagicPoint_R2 or sap.usemagicpoint_r2)
            
            local fp_display = string.format("%s (%s / %s)", fmtFp(l2), fmtFp(r1), fmtFp(r2))

            ib:renderSection({ title = 'Навык', content = {
                ib:renderItem({ label = 'Название', data = skillLink, row = true, spacebetween = true }),
                ib:renderItem({ label = 'Расход ОК', data = fp_display, row = true, spacebetween = true })
            }})
        end
    end

    local tIb = Infobox.new()
    local reqList = {}
    
    for i = 1, #TRAITS do
        local t = TRAITS[i]
        local rVal = tonumber(w[t.r]) or 0
        table.insert(reqList, tIb:renderItem({ 
            label = t.l, 
            data = rVal > 0 and rVal or "—", 
            row = true, 
            spacebetween = true 
        }))
    end

    ib:renderSection({ 
        title = 'Нужные характеристики', 
        content = reqList, 
        col = 2 
    })

    local effItems, cats = {}, { "[[Категория:Оружие]]", "[[Категория:" .. weaponType.p .. "]]" }
    
    local reinfId = tonumber(w.reinforceTypeId) or 0
    table.insert(cats, "[[Категория:Оружие, усиливаемое кузнечными камнями" .. (reinfId == 0 and "" or " мрака") .. "]]")

    for i = 0, 2 do
        local display = getEffectDisplay(w['spEffectMsgId'..i], w)
        if display then
            table.insert(effItems, ib:renderItem({ data = display }))
        end
    end

    if #effItems > 0 then
        ib:renderSection({ title = 'Особые эффекты', content = effItems })
        table.insert(cats, "[[Категория:Оружие с врождённым" .. (#effItems > 1 and "ми эффектами]]" or "ым эффектом]]"))
    end

    if tonumber(w.isDlc) == 1 then 
        table.insert(cats, "[[Категория:Оружие (Shadow of the Erdtree)]]") 
    end

    if (tonumber(w.throwAtkRate) or 0) > 0 then table.insert(cats, "[[Категория:Оружие с повышенным критическим уроном]]") end
    for i = 1, #atkTypes do
        local dt = atkTypes[i]
        if caseMap[dt] then table.insert(cats, "[[Категория:Оружие с " .. caseMap[dt] .. " типом урона]]") end
    end

    frame:callParserFunction('SHORTDESC', weaponType.s)
    return tostring(ib) .. table.concat(cats)
end

return p