Star Citizen Wiki Modul:WeaponPersonal
Wir laden dich herzlich auf den Star Citizen Wiki Discord Server ein! Du kannst uns auch auf unserem neuen YouTube-Chanel finden!

Modul:WeaponPersonal

Aus Star Citizen Wiki

Dokumentation unvollständig.


local WeaponPersonal = {}

local metatable = {}
local methodtable = {}

metatable.__index = methodtable

-- Extensions
local infobox = require( 'Module:Infobox' )
local manufacturer = require( 'Module:Hersteller' )
local common = require( 'Module:Common' )

--- Translate weapon type to german text
local typeTranslations = {
    [ 'Railgun' ]          = 'Railgun',
    [ 'Missile Launcher' ] = 'Raketenwerfer',
    [ 'Grenade Launcher' ] = 'Granatwerfer',
    [ 'LMG' ]              = 'LMG',
    [ 'Pistol' ]           = 'Pistole',
    [ 'Assault Rifle' ]    = 'Sturmgewehr',
    [ 'Shotgun' ]          = 'Schrotflinte',
    [ 'SMG' ]              = 'SMG',
    [ 'Sniper Rifle' ]     = 'Scharfschützengewehr',
    [ 'Frag Pistol' ]      = 'Splitterpistole',
    [ 'Launcher' ]         = 'Werfer',
}

--- Translate weapon class to german text
local classTranslations = {
    [ 'Ballistic' ]       = 'Ballistik',
    [ 'Energy (Laser)' ]  = 'Energie (Laser)',
    [ 'Laser' ]           = 'Laser',
    [ 'Energy (Plasma)' ] = 'Energie (Plasma)',
    [ 'Unknown Class' ]   = 'Unbekannte Klasse',
    [ 'Electron' ]        = 'Elektronen',
    [ 'Missile' ]         = 'Rakete',
}

--- Translate attachment port position to german text
local attachmentPositionTranslations = {
    [ 'optics' ]      = 'Optik',
    [ 'barrel' ]      = 'Lauf',
    [ 'underbarrel' ] = 'Unterlauf',
    [ 'magazine' ]    = 'Magazin',
}

--- Translate magazine type to german text
local magazineTranslations = {
    [ 'Battery' ]  = 'Batterie',
    [ 'Magazine' ] = 'Magazin',
}

--- Map some weapons to a manufacturer
local weaponManufacturerMap = {
    [ 'Atzkav Sniper Rifle' ] = 'Lightning Bolt Company',
    [ 'Yubarev Pistol' ] = 'Lightning Bolt Company',
}

--- @param class string
--- @return string
local function translateClass( class )
    if classTranslations[ class ] ~= nil then
        return classTranslations[ class ]
    end

    return class
end

--- @param type string
--- @return string
local function translateType( type )
    if typeTranslations[ type ] ~= nil then
        return typeTranslations[ type ]
    end

    return type
end

--- @param magazine string
--- @return string
local function translateMagazine( magazine )
    if magazineTranslations[ magazine ] ~= nil then
        return magazineTranslations[ magazine ]
    end

    return magazine
end

--- @param position string
--- @return string
local function translateAttachmentPosition( position )
    if attachmentPositionTranslations[ position ] ~= nil then
        return attachmentPositionTranslations[ position ]
    end

    return position
end

--- Add manual smw data
function methodtable.addManual( t )
    if t.frameArgs == nil then
        return
    end

    local setObj = {
        [ 'Name' ]                 = t.frameArgs[ 'Name' ]                 or nil,
        [ 'Größe' ]                = t.frameArgs[ 'Gewicht' ]              or nil,
        [ 'Hersteller' ]           = t.frameArgs[ 'Hersteller' ]           or nil,
        [ 'Beschreibung' ]         = t.frameArgs[ 'Beschreibung' ]         or nil,
        [ 'Waffentyp' ]            = t.frameArgs[ 'Waffentyp' ]            or nil,
        [ 'Waffenklasse' ]         = t.frameArgs[ 'Waffenklasse' ]         or nil,
        [ 'Magazingröße' ]         = t.frameArgs[ 'Magazingröße' ]         or nil,
        [ 'Effektive Reichweite' ] = t.frameArgs[ 'Effektive Reichweite' ] or nil,
        [ 'Feuerrate' ]            = t.frameArgs[ 'Feuerrate' ]            or nil,
        [ 'Spielversion' ]         = t.frameArgs[ 'Spielversion' ]         or nil,
    }

    mw.smw.set( setObj )
end

--- Request Api Data
--- Using current subpage name
--- @return table
function methodtable.getApiDataForCurrentPage( t )
    local name = t.frameArgs[ 'name' ] or mw.title.getCurrentTitle().subpageText

    local json = mw.text.jsonDecode( mw.ext.Apiunto.get_weapon_personal( name, {
        locale = 'de_DE',
        include = {
            'modes',
            'damages',
            'attachments',
            'attachmentPorts',
        }
    } ) )

    common.checkApiResponse( json, true, false )

    t.apiData = json[ 'data' ]

    return t.apiData
end

--- Query the weapon fire mode subobjects for this page
--- @param name string
--- @return table
function methodtable.getWeaponModes( t, name )
    local query = table.concat( {
        '[[-Has subobject::' .. name .. ']][[Feuerrate::+]]',
        '?Name#-',
        '?Feuerrate#-',
        '?Schaden pro Sekunde#-',
        '?Munition pro Schuss#-',
        '?Kugel pro Schuss#-',
        'mainlabel=-'
    }, '|' )

    return mw.smw.ask( query )
end

--- Query the default weapon attachment (the default loadout) subobjects for this page
--- @param name string
--- @return table
function methodtable.getDefaultAttachments( t, name )
    local query = table.concat( {
        '[[-Has subobject::' .. name .. ']][[Typ::Standardausrüstung]]',
        '?Name#-',
        '?Position#-',
        '?Größe#-',
        '?Grad#-',
        'mainlabel=-'
    }, '|' )

    return mw.smw.ask( query )
end

--- Query the weapon attachment subobjects for this page
--- @param name string
--- @return table
function methodtable.getAttachmentPorts( t, name )
    local query = table.concat( {
        '[[-Has subobject::' .. name .. ']][[Typ::Waffenbefestigung]]',
        '?Name#-',
        '?Position#-',
        '?Minimalgröße#-',
        '?Maximalgröße#-',
        'mainlabel=-'
    }, '|' )

    return mw.smw.ask( query )
end

--- Query the weapon damage subobjects for this page
--- Each damage is a separate subobject
--- @param name string
--- @return table
function methodtable.getDamages( t, name )
    local query = table.concat( {
        '[[-Has subobject::' .. name .. ']][[Schaden::+]][[Typ::+]]',
        '?Name#-',
        '?Typ#-',
        '?Schaden#-',
        'mainlabel=-'
    }, '|' )

    return mw.smw.ask( query )
end

--- Query the weapon ammunition subobjects for this page
--- In the future a weapon may have multiple ammunitions, hence we save it as a subobject
--- @param name string
--- @return table
function methodtable.getAmmunition( t, name )
    local query = table.concat( {
        '[[-Has subobject::' .. name .. ']][[Mündungsgeschwindigkeit::+]]',
        '?Größe#-',
        '?Lebenszeit#-',
        '?Mündungsgeschwindigkeit#-',
        '?Maximalreichweite#-',
        'mainlabel=-'
    }, '|' )

    return mw.smw.ask( query )
end

--- Queries the SMW Store
--- @return table
function methodtable.getSmwData( t )
    -- Cache multiple calls
    if t.smwData ~= nil then
        return t.smwData
    end

    -- name from args or current page
    local queryName = t.frameArgs[ 'name' ] or mw.title.getCurrentTitle().text

    local query = table.concat( {
        '[[' .. queryName .. ']]',
        '?#-=page',
        '?Name#-',
        '?Größe#-',
        '?Hersteller#-',
        '?Beschreibung#-',
        '?Waffentyp#-',
        '?Waffenklasse#-',
        '?Magazingröße#-',
        '?Magazintyp#-',
        '?Effektive Reichweite#-',
        '?Schaden pro Schuss#-',
        '?Feuerrate#-',
        '?Spielversion#-',
        'mainlabel=-'
    }, '|' )

    local data = mw.smw.ask( query )

    if data == nil or data[ 1 ] == nil then
        error( 'Seite "' .. queryName .. '" besitzt keine semantischen Daten.', 0 )
    end

    t.smwData = data[ 1 ]

    t.smwData.modes = t:getWeaponModes( queryName )
    t.smwData.defaultAttachments = t:getDefaultAttachments( queryName )
    t.smwData.attachmentPorts = t:getAttachmentPorts( queryName )
    t.smwData.damages = t:getDamages( queryName )
    t.smwData.ammunition = t:getAmmunition( queryName )

    return t.smwData
end

--- Base Properties that are shared across all Vehicles
--- @return table SMW Result
function methodtable.setSemanticProperties( t )
    -- Api Error, don't set anything
    if t.apiData == nil then
        return
    end

    local price = t.apiData[ 'msrp' ]

    if price == nil and t.frameArgs[ 'price' ] ~= nil then
        price = t.frameArgs[ 'price' ]
    end

    local manufacturerName = t.apiData.manufacturer or nil
    if manufacturerName ~= nil then
        manufacturerName = mw.ustring.gsub( manufacturerName, '%[PH%]', '' )
    end

    if manufacturerName == '@LOC_PLACEHOLDER' or manufacturerName == '@LOC PLACEHOLDER' then
        manufacturerName = 'Unbekannter Hersteller'
    end

    if weaponManufacturerMap[ t.apiData.name ] ~= nil then
        manufacturerName = weaponManufacturerMap[ t.apiData.name ]
    end

    --- The base data for the page
    local setData = {
        [ 'Name' ]                 = t.apiData.name or nil,
        [ 'Größe' ]                = t.apiData.size or nil,
        [ 'Hersteller' ]           = manufacturerName,
        [ 'Beschreibung' ]         = t.apiData.desdcription or nil,
        [ 'Waffentyp' ]            = translateType( t.apiData.type or nil ),
        [ 'Waffenklasse' ]         = translateClass( t.apiData.class or nil ),
        [ 'Magazingröße' ]         = t.apiData.magazine_size or nil,
        [ 'Magazintyp' ]           = translateMagazine( t.apiData.magazine_type or nil ),
        [ 'Effektive Reichweite' ] = t.apiData.effective_range or nil,
        [ 'Schaden pro Schuss' ]   = common.formatNum( t.apiData.damage_per_shot, nil ),
        [ 'Feuerrate' ]            = t.apiData.rof or nil,
        [ 'Feuerrate' ]            = t.apiData.rof or nil,
        [ 'Spielversion' ]         = t.apiData.version or nil,
    }

    local result = mw.smw.set( setData )

    if t.apiData.ammunition ~= nil then
        local muzzleVelocity = t.apiData.ammunition.speed or nil
        if muzzleVelocity ~= nil then
            muzzleVelocity = common.formatNum( muzzleVelocity ) .. 'm/s'
        end

        mw.smw.subobject( {
            [ 'Größe' ]                   = t.apiData.ammunition.size or nil,
            [ 'Lebenszeit' ]              = t.apiData.ammunition.lifetime or nil,
            [ 'Mündungsgeschwindigkeit' ] = muzzleVelocity,
            [ 'Maximalreichweite' ]       = t.apiData.ammunition.range or nil,
        }, 'Munition' )
    end

    if t.apiData.damages ~= nil and type( t.apiData.damages.data ) == 'table' then
        for _, damage in pairs( t.apiData.damages.data ) do
            if damage.name ~= nil then
                mw.smw.subobject( {
                    [ 'Name' ]    = damage.name,
                    [ 'Typ' ]     = damage.type,
                    [ 'Schaden' ] = damage.damage,
                } )
            end
        end
    end

    if t.apiData.attachmentPorts ~= nil and type( t.apiData.attachmentPorts.data ) == 'table' then
        for _, attachment in pairs( t.apiData.attachmentPorts.data ) do
            if attachment.name ~= nil then
                mw.smw.subobject( {
                    [ 'Name' ]         = attachment.name,
                    [ 'Position' ]     = translateAttachmentPosition( attachment.position or nil ),
                    [ 'Minimalgröße' ] = attachment.sizes.min or nil,
                    [ 'Maximalgröße' ] = attachment.sizes.max or nil,
                    [ 'Typ' ]          = 'Waffenbefestigung',
                }, attachment.name )
            end
        end
    end

    if t.apiData.attachments ~= nil and type( t.apiData.attachments.data ) == 'table' then
        for _, attachment in pairs( t.apiData.attachments.data ) do
            if attachment.name ~= nil then
                mw.smw.subobject( {
                    [ 'Name' ]     = attachment.name,
                    [ 'Position' ] = translateAttachmentPosition( attachment.position or nil ),
                    [ 'Größe' ]    = attachment.size or nil,
                    [ 'Grad' ]     = attachment.grade or nil,
                    [ 'Typ' ]      = 'Standardausrüstung',
                }, attachment.name )
            end
        end
    end

    if t.apiData.modes ~= nil and type( t.apiData.modes.data ) == 'table' then
        for _, mode in pairs( t.apiData.modes.data ) do
            if mode.mode ~= nil then
                mw.smw.subobject( {
                    [ 'Name' ]                = mode.mode,
                    [ 'Feuerrate' ]           = mode.rpm or nil,
                    [ 'Schaden pro Sekunde' ] = mode.damage_per_second or nil,
                    [ 'Munition pro Schuss' ] = mode.ammo_per_shot or nil,
                    [ 'Kugel pro Schuss' ]    = mode.pellet_per_shot or nil,
                }, mode.mode )
            end
        end
    end

    return result
end

--- Entrypoint for {{#seo:}}
function methodtable.setSeoData( t )
    if t.currentFrame == nil then
        error( 'No frame set. Call "setFrame" first.', 0 )
    end

    local data = t:getSmwData()

    if nil == data.Hersteller then
        -- Faulty SMW data, don't call #seo
        return
    end

    local desc = table.concat( {
        data.Name,
        'vom Hersteller',
        data.Hersteller
    }, ' ' )

    if t.frameArgs[ 'description' ] == nil or #t.frameArgs[ 'description' ] == 0 then
        if data.Beschreibung ~= nil then
            desc = data.Beschreibung
        end
    else
        desc = t.frameArgs[ 'description' ]
    end

    -- Call to {{#seo:}}
    mw.ext.seo.set{
        author = t.currentFrame:preprocess( '{{SERVER}}/Benutzer:{{urlencode:{{REVISIONUSER}}|WIKI}}' ),
        section = 'Persönliche Waffen',
        url = tostring( mw.uri.fullUrl( data.page ) ),
        title = table.concat({
            data.Name,
            data.Hersteller,
            t.currentFrame:preprocess( '{{SITENAME}}' )
        }, ' - '),
        title_mode = 'replace',
        keywords = table.concat({
            data.Name or '',
            translateType( data.Waffentyp ) or '',
            translateClass( data.Waffenklasse ) or '',
            data.Hersteller or '',
            manufacturer.getCodeFromName( data.Hersteller ) or '',
        }, ', '),
        description = desc,
        image= t.frameArgs[ 'image' ] or '',
        image_alt = desc,
        locale = 'de_DE',
        type = 'article',
    }
end

--- Creates the infobox
--- TODO: This is a mess ;_;
function methodtable.getInfoBox( t )
    local data = t:getSmwData()

    if nil == data.Hersteller then
        return 'SMW Daten noch nicht geladen, bitte Seite neu laden.'
    end

    table.insert( t.categories, '[[Category:' .. data.Hersteller .. '|' .. data.Name .. ' ]]' )

    if data.Waffentyp ~= nil then
        table.insert( t.categories, '[[Category:' .. data.Waffentyp .. '|' .. data.Name .. ' ]]' )
    end

    -- Set Title
    common.setDisplayTitle( t.currentFrame, data.Name )

    local box = infobox.create( {
        bodyClass = 'floatright',
        allowReplace = false,
        removeEmpty = true,
        emptyString = '-',
        placeholderImage = 'Platzhalter Waffen.webp',
    } )

    -- Image
    box:addImage( common.getImage( {
        t.frameArgs[ 'image' ]
    } ), {
        [ 'alternativtext' ] = data.Name,
        'rahmenlos',
        '600px'
    } )

    box:addTitle( data.Name )

    box:addRow(
        'Hersteller',
        '[[' .. data.Hersteller .. ']]',
        nil,
        'col2'
    )

    local weaponType = data.Waffentyp
    if weaponType ~= nil then
        weaponType = string.format('[[:Kategorie:%s|%s]]', weaponType, weaponType)
    end

    local weaponClass = data.Waffenklasse
    if weaponClass ~= nil then
        weaponClass = string.format('[[:Kategorie:%s|%s]]', weaponClass, weaponClass)
    end

    local maxRange = '-'
    local muzzleVelocity = '-'
    if type( data.ammunition ) == 'table' then
        maxRange = data.ammunition[ 1 ][ 'Maximalreichweite' ]
        muzzleVelocity = data.ammunition[ 1 ][ 'Mündungsgeschwindigkeit' ]
    end

    box:addRow( 'Typ', weaponType, nil, 'col2' )
       :addRow( 'Klasse', weaponClass, nil, 'col2' )
       :addRow( 'Magazingröße', data[ 'Magazingröße' ] .. ' Schuss', nil, 'col2' )
       :addRow( 'Schaden pro Schuss', data[ 'Schaden pro Schuss' ], nil, 'col2' )
       :addRow( 'Magazintyp', data[ 'Magazintyp' ], nil, 'col2' )
       :addRow( 'Feuerrate', data[ 'Feuerrate' ] .. ' Schuss/s', nil, 'col2' )
       :addRow( 'Mündungsgeschwindigkeit', muzzleVelocity, nil, 'col2' )
       :addRow( 'Effektive Reichweite', data[ 'Effektive Reichweite' ], nil, 'col2' )
       :addRow( 'Maximalreichweite', maxRange, nil, 'col2' )

    --[[
        Weapon Modes
    ]]--
    if data.modes ~= nil and type( data.modes ) == 'table' then
        local source = t.currentFrame:extensionTag{
            name = 'ref',
            content = 'Daten aus der Spielversion ' .. data.Spielversion
        }
        box:addHeader( 'Feuermodi' .. source )

        for _, mode in pairs( data.modes ) do
            local dps = mode[ 'Schaden pro Sekunde' ] or nil
            if dps ~= nil then
                dps = string.format("%.2f", dps)
            else
                dps = ' - '
            end

            box:addRow( 'Modus', mode[ 'Name' ], nil, 'col3' )
            box:addRow( 'Feuerrate', (mode[ 'Feuerrate' ] or ' - ') .. ' Schuss/s', nil, 'col3' )
            box:addRow( 'Schaden/s', dps, nil, 'col3' )
        end
    end

    --[[
        Weapon Attachments
    ]]--
    if data.attachmentPorts ~= nil and type( data.attachmentPorts ) == 'table' then
        box:addHeader( 'Befestigungen' )

        for _, attachment in pairs( data.attachmentPorts ) do
            if type( attachment ) == 'table' and attachment[ 'Position' ] ~= 'Magazin' then
                local size
                if attachment[ 'Minimalgröße' ] == attachment[ 'Maximalgröße' ] then
                    size = 'S' .. attachment[ 'Minimalgröße' ]
                else
                    size = 'S' .. attachment[ 'Minimalgröße' ] .. ' - S' .. attachment[ 'Maximalgröße' ]
                end

                box:addRow( attachment[ 'Position' ], size, nil, 'col3' )
            end
        end
    end

    --[[
        Weapon Default Loadout
    ]]--
    if data.defaultAttachments ~= nil and type( data.defaultAttachments ) == 'table' then
        box:addHeader( 'Standardausrüstung' )

        for _, attachment in pairs( data.defaultAttachments ) do
            if type( attachment ) == 'table' and attachment[ 'Name' ] ~= nil then
                local size = attachment[ 'Größe' ]
                if size ~= nil and tonumber( size ) > 0 then
                    size = 'S' .. size .. ' '
                end

                box:addRow( attachment[ 'Position' ], size .. attachment[ 'Name' ], nil, 'col-full' )
            end
        end
    end

    if t.currentFrame ~= nil then
        box:addRowsFromArgs( require( 'Module:Arguments' ).getArgs( t.currentFrame ), '!' )
    end

    return tostring( box )
end

--- Set the frame and load args
--- @param frame table
function methodtable.setFrame( t, frame )
    t.currentFrame = frame
    t.frameArgs = require( 'Module:Arguments' ).getArgs( frame )
end

--- Get categories
function methodtable.getCategories( t )
    return tostring( table.concat( t.categories ) )
end

--- Save Api Data to SMW store
function methodtable.saveApiData( t )
    if t.currentFrame == nil then
        error( 'No frame set. Call "setFrame" first.', 0 )
    end

    local data = t:getApiDataForCurrentPage()

    t:setSemanticProperties()

    return data
end

--- Template entry
function WeaponPersonal.main( frame )
    local instance = WeaponPersonal:new()
    instance:setFrame( frame )

    if instance.frameArgs[ 'Manuell' ] ~= nil then
        instance:addManual()
    else
        instance:saveApiData()
    end

    instance:setSeoData()

    return tostring( instance:getInfoBox() ) .. instance:getCategories()
end

--- New Instance
function WeaponPersonal.new( self )
    local instance = {
        categories = {}
    }

    setmetatable( instance, metatable )

    return instance
end

return WeaponPersonal
Cookies helfen uns bei der Bereitstellung dieses Wikis. Durch die Nutzung des Star Citizen Wiki erklärst du dich damit einverstanden, dass wir Cookies speichern.