Das Star Citizen Wiki wird von Leuten wie dir gemacht! Bitte überleg doch bei uns mitzuwirken, wir können viel Hilfe gebrauchen!

Modul:Sternensystem

Aus Star Citizen Wiki

Dokumentation unvollständig.


local Sternensystem = {}

-- Extensions
local api = mw.ext.Apiunto
local capiunto = require 'capiunto'
local systemData = require( 'Module:Sternensystem/Data' )
local common = require( 'Module:Common' )
local quelle = require( 'Modul:Quelle' )

-- Vars
local currentFrame
local frameArgs

local pageName

local categories = {}

local apiData

local smwData

-- Request Api Data
-- Using current subpage name
local function getApiDataForCurrentPage()
    local name = pageName

    local config = systemData.new( pageName )

    if config.get( 'api_name' ) ~= '' then
        name = config.get( 'api_name' )
    end

    local json = mw.text.jsonDecode( api.get_starsystem( name, {
        locale = 'de_DE',
        include = {
            'celestial_objects',
            'celestial_objects.jumppoint',
        },
    } ) )

    common.checkApiResponse( json )

    apiData = json.data or nil

    return apiData
end

-- Filters celestial_objects by type key
local function getCelestialObjectsForType( type )
    if apiData == nil or apiData.celestial_objects == nil or apiData.celestial_objects.data == nil then
        return {}
    end

    local objects = {}

    for _, object in pairs( apiData.celestial_objects.data ) do
        if object.type == type then
            table.insert( objects, object )
        end
    end

    return objects
end

-- Returns the highest star age
local function getSystemAge()
    local stars = getCelestialObjectsForType( 'STAR' )
    local age = 0

    for _, star in pairs( stars ) do
        if star.age ~= nil and tonumber( star.age, 10 ) >= age then
            age = tonumber( star.age, 10 )
        end
    end

    return age
end

-- Extracts the affiliations form api data
local function extractAffiliations( affiliationData, key )
    if type( affiliationData.data ) ~= 'table' or #affiliationData.data == 0 then
        return {}
    end

    local affiliations = {}

    for _, affiliation in pairs( affiliationData.data ) do
        if key ~= nil and affiliation[ key ] ~= nil then
            table.insert( affiliations, affiliation[ key ] )
        else
            table.insert( affiliations, {
                name = affiliation.name,
                code = affiliation.code,
            })
        end
    end

    return affiliations
end

-- Queries the SMW Store
local function getSmwData()
    -- Cache multiple calls
    if smwData ~= nil then
        return smwData
    end

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

    local query = table.concat( {
        '[[ ' .. queryName .. ' ]]',
        '?#-=page',
        '?Name#-=name',
        '?Starmap Code=code',
        '?Status=status',
        '?Typ=type',
        '?Sternensystem Größe=system_size',
        '?Sternensystem Alter=system_age',

        '?Kontrolle=affiliation',
        '?Bevölkerungsgröße=population_level',
        '?Wirtschaft=economic_level',
        '?Gefahrenlage=threat_level',

        '?Anzahl Sterne=star_count',
        '?Anzahl Planeten=planet_count',
        '?Anzahl Monde=moon_count',
        '?Anzahl Asteroidengürtel=asteroid_belt_count',
        '?Anzahl Sprungpunkte=jumppoint_count',
        'mainlabel=-'
    }, '|' )

    local data = mw.smw.ask( query )

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

    smwData = data[ 1 ]

    return smwData
end


-- Append 'Mrd. Jahre'
local function formatAge( age )
    if age ~= nil and common.formatNum( age ) ~= nil then
        if type( age ) == 'string' then
            age = tonumber( age, 10 )
        end

        age = age * 1000000000

        return common.formatNum( age ) .. ' Jahre'
    end
end

-- Append 'km'
local function formatSize( sizes )
    if sizes == nil then
        return sizes
    end

    if type( sizes ) == 'table' then
        for k, v in pairs( sizes ) do
            if k ~= nil and v ~= nil then
                local formatted = common.formatNum( v )

                if formatted ~= nil then
                    sizes[ k ] = formatted .. ' km'
                end
            end
        end

        return sizes
    end

    local formatted = common.formatNum( sizes )

    if formatted ~= nil then
        return formatted .. ' km'
    end
end


-- Write celestial objects as subobject
local function setSubObjects( celestialObjects )
    for _, celestialObject in pairs( celestialObjects ) do
        if celestialObject.habitable ~= nil then
            if celestialObject.habitable == 1 or celestialObject.habitable == true then
                celestialObject.habitable = "Ja"
            else
                celestialObject.habitable = "Nein"
            end
        end

        local data = {
            [ 'ID' ] = celestialObject.id,
            [ 'Starmap Code' ] = celestialObject.code,
            [ 'Typ' ] = celestialObject.type,
            [ 'Name' ] = celestialObject.name,
            [ 'Bezeichnung' ] = celestialObject.designation,
            [ 'Alter' ] = formatAge( celestialObject.age ),
            [ 'Radius' ] = formatSize( celestialObject.size ),
            [ 'Habitabel' ] = celestialObject.habitable,
            [ 'Beschreibung' ] = celestialObject.description,
            [ 'Gefahrenlage' ] = common.formatNum( celestialObject.sensor.danger ),
            [ 'Wirtschaft' ] = common.formatNum( celestialObject.sensor.economy ),
            [ 'Bevölkerungsgröße' ] = common.formatNum( celestialObject.sensor.population ),
            [ 'Kontrolle' ] = extractAffiliations( celestialObject.affiliation, 'name' ),

            [ 'Umlaufzeit' ] = common.formatNum( celestialObject.orbit_period ),
            [ 'Abstand' ] = common.formatNum( celestialObject.distance ),
            [ 'Breitengrad' ] = common.formatNum( celestialObject.latitude ),
            [ 'Längengrad' ] = common.formatNum( celestialObject.longitude ),

            [ 'Elternid' ] = celestialObject.parent_id,
            [ 'Sternensystemid' ] = celestialObject.system_id,
        }

        if celestialObject.subtype ~= nil and type( celestialObject.subtype.data ) == 'table' and celestialObject.subtype.data.id ~= nil then
            data[ 'Subtyp' ] = celestialObject.subtype.data.type
            data[ 'Subtypname' ] = systemData.getTranslatedSubtype( celestialObject.subtype.data.name )
        end

        if celestialObject.type == 'JUMPPOINT' and celestialObject.jumppoint ~= nil and type( celestialObject.jumppoint.data ) == 'table' then
            local jumppoint = celestialObject.jumppoint.data

            data[ 'Größe' ] = jumppoint.size
            data[ 'Richtung' ] = jumppoint.direction

            local designation = ''

            if jumppoint.entry.system_id == celestialObject.system_id then
                designation = jumppoint.entry.designation
            elseif jumppoint.exit.system_id == celestialObject.system_id then
                designation = jumppoint.exit.designation
            end

            local destinations = mw.text.split( designation, ' - ', true )

            if #destinations == 2 then
                data[ 'Sprungpunkt Start' ] = Sternensystem.cleanJumppointDestination( destinations[ 1 ] )
                data[ 'Sprungpunkt Ziel' ] = Sternensystem.cleanJumppointDestination( destinations[ 2 ] )
            end
        end

        common.checkSmwResult( mw.smw.subobject( data ) )
    end
end

-- Semantic Properties
local function setSemanticProperties()
    -- Api Error, don't set anything
    if apiData == nil then
        return
    end

    local setData = {
        [ 'Name' ] = apiData.name,
        [ 'ID' ] = apiData.id,
        [ 'Starmap Code' ] = apiData.code,
        [ 'Status' ] = apiData.status,
        [ 'Typ' ] = apiData.type,
        [ 'Sternensystem Größe' ] = common.formatNum( apiData.aggregated.size ),
        [ 'Sternensystem Alter' ] = common.formatNum( getSystemAge() ) .. ' Mrd.Jahre',

        [ 'Gefahrenlage' ] = common.formatNum( apiData.aggregated.danger ),
        [ 'Kontrolle' ] = extractAffiliations( apiData.affiliation, 'name' ),
        [ 'Wirtschaft' ] = common.formatNum( apiData.aggregated.economy ),
        [ 'Bevölkerungsgröße' ] = common.formatNum( apiData.aggregated.population ),

        [ 'Frostlinie' ] = common.formatNum( apiData.aggregated.frost_line ),
        -- [ 'Habitable Zone (Innen)' ] = common.formatNum( apiData.aggregated.habitable_zone_inner ),
        -- [ 'Habitable Zone (Außen)' ] = common.formatNum( apiData.aggregated.habitable_zone_outer ),

        [ 'Anzahl Sterne' ] = #getCelestialObjectsForType( 'STAR' ),
        [ 'Anzahl Planeten' ] = #getCelestialObjectsForType( 'PLANET' ),
        [ 'Anzahl Monde' ] = #getCelestialObjectsForType( 'SATELLITE' ),
        [ 'Anzahl Asteroidengürtel' ] = #getCelestialObjectsForType( 'ASTEROID_BELT' ),
        [ 'Anzahl Sprungpunkte' ] = #getCelestialObjectsForType( 'JUMPPOINT' ),

        [ 'Beschreibung' ] = frameArgs.description or apiData.description,
    }

    common.checkSmwResult( mw.smw.set( setData ) )

    if apiData.celestial_objects ~= nil and type( apiData.celestial_objects.data ) == 'table' then
        setSubObjects( apiData.celestial_objects.data )
    end
end

-- Image
local function getImage( type )
    if type == nil then
        type = 'prefixedText'
    end

    local image = mw.title.new( pageName .. '_System.jpg', 6 )

    if frameArgs ~= nil and frameArgs.image ~= nil then
        image = mw.title.new( frameArgs.image, 6 )
    end

    if image.exists then
        if type == 'fullLink' then
            return currentFrame:callParserFunction( 'filepath:', image.text )
        end

        return image[ type ]
    end

    return nil
end

-- Creates the infobox
-- TBD
local function getInfoBox()
    local data = getSmwData()

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

    local astronomicalData = {
        star_count = 'Sterne',
        system_size = 'Größe (AE)',
        system_age = 'Alter',
    }

    local politicsAndEconomy = {
    	{
    		key = 'affiliation',
    		text = 'Zugehörigkeit',
    	},
    	{
			key = 'population_level',
    		text = 'Bevölkerung',
    	},
    	{
    		key = 'economic_level',
    		text = 'Wirtschaft',
    	},
    	{
    		key = 'threat_level',
    		text = 'Gefahrenlage',
    	},
    }

    local cleanTitle = pageName

    if cleanTitle == nil then
        cleanTitle = common.removeTypeSuffix( mw.title.getCurrentTitle().subpageText, 'Sternensystem' )
    end

    local infoBox = capiunto.create( {
        title = cleanTitle .. ' System',
        top = data.name or data.designation,
        bodyClass = 'wikitable',
    } )

    -- Image
    local image = getImage()

    if image ~= nil then
        infoBox:addHeader( '[[ ' .. image .. '|alternativtext=Bild des ' .. cleanTitle .. ' Sternensystem|rahmenlos|350px]]', 'table-image' )
    end

    quelle.setArgs( {
    	url = 'https://robertsspaceindustries.com/starmap?location=' .. ( data.code or '' ),
    	title = 'Ark Starmap: ' .. pageName .. ' System',
    	wrap = true,
    	ref_group = 'RSI',
    	ref_name = 'system_starmap',
    } )

    infoBox:addHeader( 'Astronomische Daten' .. quelle.format() )

    for smwKey, value in pairs( astronomicalData ) do
        if data[ smwKey ] ~= nil then
            infoBox:addRow( value, data[ smwKey ] )
        end
    end

    infoBox
            :addRow( 'Planeten', data.planet_count or '-' )
            :addRow( 'Monde', data.moon_count or '-' )
            :addRow( 'Asteroidengürtel', data.asteroid_belt_count or '-' )
            :addRow( 'Sprungpunkte', data.jumppoint_count or '-' )

    infoBox:addHeader( 'Politik und Wirtschaft' )

    for _, obj in ipairs( politicsAndEconomy ) do
        if data[ obj.key ] ~= nil then
            if obj.key == 'affiliation' then
                infoBox:addRow( obj.text, Sternensystem.getAffiliationLines( data.affiliation ) )
            else
	            infoBox:addRow( obj.text, data[ obj.key ] )
            end        	
        end
    end

    return infoBox
end

--
-- Public Methods
--

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

    local data = getSmwData()

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

    if type( data.affiliation ) == 'string' then
        data.affiliation = { data.affiliation }
    end

    local cleanTitle = common.removeTypeSuffix( data.page, 'Sternensystem' )

    local desc = table.concat( {
        'Das',
        cleanTitle,
        'Sternensystem ist ein System under der Kontrolle',
        Sternensystem.getAffiliationsAsText( data.affiliation )
    }, ' ' )

    local image = getImage()

    -- Call to {{#seo:}}
    mw.ext.seo.set{
        author = currentFrame:preprocess( '{{SERVER}}/Benutzer:{{urlencode:{{REVISIONUSER}}|WIKI}}' ),
        section = 'Sternensystem',
        url = tostring( mw.uri.fullUrl( data.page ) ),
        title = table.concat( {
            cleanTitle,
            'Sternensystem',
            currentFrame:preprocess( '{{SITENAME}}' )
        }, ' - '),
        title_mode = 'replace',
        keywords = table.concat( {
            'Sternensystem',
            cleanTitle,
            table.concat( data.affiliation, ', '),
        }, ', '),
        description = frameArgs.description or desc,
        image = image or '',
        image_alt = 'Bild des ' .. data.Name .. ' Systems',
        locale = 'de_DE',
        type = 'article',
    }
end

-- Returns the 'old' Starsystem name from a format of
-- Starsystem (New Name)
function Sternensystem.cleanJumppointDestination( destination )
	local clean = mw.text.split( destination, '(', true )
	
	if clean[ 1 ] ~= nil and type( clean[ 1 ] ) == 'string' then
		return mw.text.trim( clean[ 1 ] )
	end
	
	return destination	
end

-- Returns small logo and link if available
function Sternensystem.getAffiliationLines( affiliations )
    local mapping = {
        BANU = '[[Banu]]',
        DEV = 'Developing',
        DEVELOPING = 'Developing',
        UEE = '[[Menschen]]',
        UNC = 'Unclaimed',
        UNCLAIMED = 'Unclaimed',
        VANDUUL = '[[Vanduul]]',
        [ 'XI\'AN' ] = '[[Xi\'An]]',
    }

    if type( affiliations ) == 'string' then
        affiliations = { affiliations }
    end

    local lines = {}

    for _, affiliation in pairs( affiliations ) do
        local line = '[[Datei:Systemlogo ' .. mw.ustring.upper( affiliation:gsub( '%\'', '' ) ) .. '.svg|frameless|link=|class=noviewer factionlogo|x15px]] '

        if mapping[ mw.ustring.upper( affiliation ) ] == nil then
            line = line .. mw.ustring.upper( affiliation )
        else
            line = line .. mapping[ mw.ustring.upper( affiliation ) ]
        end

        table.insert( lines, line )
    end

    if #lines == 0 then
        return '-'
    end

    return tostring( table.concat( lines, '<br>' ) )
end

-- Textual Affiliation
function Sternensystem.getAffiliationsAsText( affiliations )
    if affiliations == nil then
        return ''
    end

    if type( affiliations ) == 'string' then
        affiliations = { affiliations }
    end

    local line = ''

    for _, affiliation in pairs( affiliations ) do
        if #line > 0 then
            line = line .. ' und '
        end

        if affiliation == 'Developing' then
            line = line .. 'von niemandem, dieses System entwickelt sich derzeit'
        elseif affiliation == 'Unclaimend' then
            line = line .. 'von niemandem, keine Fraktion kontrolliert dieses System'
        elseif affiliation == 'UEE' then
            line = line .. 'des United Earth Empire'
        else
            line = line .. 'der ' .. affiliation
        end
    end

    return line .. '.'
end

-- Ouput infobox and categories and set seo
function Sternensystem.infoBox( frame )
    currentFrame = frame
    frameArgs = frame:getParent().args

    pageName = frameArgs.name or common.removeTypeSuffix( mw.title.getCurrentTitle().subpageText, 'Sternensystem' )

    if mw.title.getCurrentTitle().namespace == 0 then
        table.insert( categories, '[[Category:Sternensystem|' .. pageName .. ']]' )
    end

    common.setDisplayTitle( currentFrame, pageName )

    getApiDataForCurrentPage()
    setSemanticProperties()
    setSeoData()

    return tostring( getInfoBox() ) .. tostring( table.concat( categories ) )
end

return Sternensystem
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.