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

Modul:SternensystemStruktur

Aus Star Citizen Wiki

Diese Vorlage erzeugt eine strukturelle Übersicht eines Sternensystems oder astronomischen Objektes.

Wird die Vorlage ohne den Paramter code aufgerufen, so wird angenommen, dass der Seitenname dem Namen eines Sternensystems entspricht.

Soll die Struktur eines astronomischen Objekts erstellt werden, so ist der Paramter code zwingend erforderlich.

Der Wert von code hat meistens die Form von: STERNENSYSTEM.TYP.NAME.

Beispielcode des Planeten Erde: SOL.PLANETS.EARTH

Kopiervorlage[Bearbeiten]

{{Sternensystem/Struktur}}

Kopiervorlage astronomisches Objekt[Bearbeiten]

{{Sternensystem/Struktur
|code=SOL.PLANETS.MARS
}}

Beispiel: Struktur des Planeten Mars[Bearbeiten]

🌍 Sol IV

local SternensystemStruktur = {}

local metatable = {}
local methodtable = {}

metatable.__index = methodtable

local starsystem = require( 'Module:Sternensystem' )
local celestialObject = require( 'Module:CelestialObject' )


--- Walks a table in order
local function spairs( t, order )
    -- collect the keys
    local keys = {}
    for k in pairs(t) do keys[#keys+1] = k end

    -- if order function given, sort by it by passing the table and keys a, b,
    -- otherwise just sort the keys
    if order then
        table.sort(keys, function(a,b) return order(t, a, b) end)
    else
        table.sort(keys)
    end

    -- return the iterator function
    local i = 0
    return function()
        i = i + 1
        if keys[i] then
            return keys[i], t[keys[i]]
        end
    end
end

--- Queries the SMW store for data of the current page name
function methodtable.getStarsystemData( t )
    if t.system ~= nil then
        return
    end

    local selector = t.pageName

    if mw.getCurrentFrame():getParent().args.code then
        selector = 'Starmap Code::' .. mw.getCurrentFrame():getParent().args.code
    end
    
    local askData = celestialObject.getSmwBaseAskData()
    table.insert( askData, 1, '[[' .. selector .. ']]' )

    askData.mainlabel = '-'
    askData.limit = 1

    local data = mw.smw.ask( askData )

    if data ~= nil and data[ 1 ] ~= nil then
        t.system = data[ 1 ]

        return
    end

    error( 'Could not get Starsystem data' )
end

--- Queries the SMW store for the objects of the system
function methodtable.getCelestialObjects( t )
    local selector = ''

    if mw.getCurrentFrame():getParent().args.code == nil then
        selector = '[[-Has subobject::' .. t.pageName .. ']]'

        if t.system.id ~= nil then
            selector = '<q>' .. selector .. '||[[Sternensystemid::' .. t.system.id .. ']]</q>'
        end

        selector = selector .. '[[Typ::!STATE]][[Typ::!TOWN]][[Typ::!LANDINGZONE]][[Typ::!STRUCTURE]][[Typ::!SETTLEMENT]]'
    elseif t.system.system_id ~= nil then
        selector = '[[Sternensystemid::' .. t.system.system_id .. ']]'
    end

    
    local askData = celestialObject.getSmwBaseAskData()
    table.insert( askData, 1, selector .. '[[Starmap Code::+]]' )
    table.insert( askData, 'sort=Typ,Bezeichnung' )
    table.insert( askData, 'order=desc,asc' )

    askData.mainlabel = '-'

    local data = mw.smw.ask( askData )

    if data ~= nil and data[ 1 ] ~= nil then
        t.celestialObjects = data

        return
    end

    error( 'Could not get Celestial Objects' )
end


--- This is just plain ugly
--- Sorts "recursively"
--- Best replaced by a tree
function methodtable.subSort( t )
    local copy = t.celestialObjects

    local function subSortWrap( object, container )
        if container[ object.parent_id ] ~= nil then
            container[ object.parent_id ].children[ tonumber(object.id) ] = object

            return true
        else
            for _, parent in pairs( container ) do
                subSortWrap( object, parent.children )
            end
        end
    end

    local i = 0
    while i < 4 do
        if #copy == 0 then
            --return
        end

        i = i + 1

        for id, object in pairs( copy ) do
            if t.structure[ t.system.id ].children[ object.parent_id ] ~= nil then
                t.structure[ t.system.id ].children[ object.parent_id ].children[ tonumber(object.id) ] = object

                table.remove( copy, id )
            else
                for _, parent in pairs( t.structure[ t.system.id ].children ) do
                    if subSortWrap( object, parent.children ) then

                        table.remove( copy, id )
                    end
                end
            end
        end
    end
end

--- Filters from all celestial objects
--- those that have the upper most parent of 'system.id'
--- @return table
function methodtable.filterCelestialObjects( t )
    local filtered = {}

    local parentIds = {
        [ t.system.id ] = '',
    }

    for _, object in spairs( t.celestialObjects ) do
        if parentIds[ object.parent_id ] ~= nil then
            parentIds[ object.id ] = ''
        end
    end

    for _, object in spairs( t.celestialObjects ) do
        if parentIds[ object.parent_id ] ~= nil then
            filtered[ object.id ] = object
        end
    end

    return filtered
end

--- Generates the data structure
--- A "tree" that has the system as its root
function methodtable.createDataStructure( t )
    t.structure = {
        [ t.system.id ] = t.system
    }

    t.types[ t.system.type ] = ''

    t.structure[ t.system.id ].children = {}

    for _, object in spairs( t.celestialObjects ) do
        object.children = {}

		if object.type ~= nil then
	        if t.types[ object.type ] == nil then
	            t.types[ object.type ] = ''
	        end
	
	        if object.id ~= nil and object.parent_id == nil or object.parent_id == t.system.id then
	            if object.type == 'JUMPPOINT' then
	                object.id = object.id + 10000 --hack
	            end
	            table.insert( t.structure[ t.system.id ].children, tonumber(object.id), object )
	        end
        end
    end

    t:subSort()
end

--- Makes a html entry
--- @param object table The current object from the list of smw entries
--- @param infoTable table The html table object
function methodtable.makeEntry( t, object, infoTable )
    local icon = ''
    if celestialObject.getIcon( object.type ) ~= nil then
        icon = string.format(
                '<span title="%s">%s</span>',
                celestialObject.reverseMapType( object.type ),
                celestialObject.getIcon( object.type )
        )
    end

    local text = celestialObject.getName( object.designation, true )

    if object.name ~= nil and text ~= object.name then
        text = text .. '|' .. text .. ': ' .. object.name
    end

    if object.type == 'STAR' or object.type == 'BLACKHOLE' then
        local starPage = mw.title.new( object.designation, 0 )

        if starPage.exists then
            if object.type == 'STAR' then
                text = object.designation .. ' (Stern)'
            else
                text = object.designation .. ' (Schwarzes Loch)'
            end
        end
    end

    text = '[[' .. text .. ']]'

    if object.type == 'ASTEROID_BELT' or object.type == 'ASTERPOD_FIELD' then
        text = object.designation
    end

    if object.type == 'JUMPPOINT' then
        local split = mw.text.split( object.designation, ' - ', true )

        text = '[[' .. starsystem.cleanJumppointDestination( split[ 2 ] ) .. ']]'
    end

    infoTable = infoTable
            :tag( 'div', {parent = infoTable} )
            :addClass( 'system-entry' )
            :addClass( 'system-entry-' .. object.type )
            :tag( 'span' )
            :addClass( 'system-entry-label' )
            :wikitext( icon .. ' ' .. text )
            :done()

    if type( object.children ) == 'table' then
        for _, child in spairs( object.children ) do
            infoTable = t:makeEntry( child, infoTable )
        end
    end

    return infoTable:done()
end

--- Generates the html
--- @return string
function methodtable.makeHtml( t )
    local headText = t.pageName

    if mw.getCurrentFrame():getParent().args.code then
        headText = t.system.designation
    end

    local icon = string.format(
            '<span title="%s">%s</span>',
            celestialObject.reverseMapType( t.system.type ),
            celestialObject.getIcon( t.system.type )
    )

    local infoTable = mw.html.create( 'div' )
                        :addClass( 'system-wrapper' )
                        :addClass( 'mw-collapsible mw-collapsed' )
                        :tag( 'span' )
                        :addClass( 'system-label' )
                        :wikitext( icon .. ' [[' .. headText .. ']]' )
                        :done()
                        :tag( 'div' )
                        :addClass( 'mw-collapsible-content' )
                        :addClass( 'system-content' )

    for _, object in spairs( t.structure[ t.system.id ].children ) do
        infoTable = t:makeEntry( object, infoTable )
    end

    infoTable = infoTable
            :tag( 'div', {parent = infoTable} )
            :addClass( 'system-entry' )
            :addClass( 'system-entry-INFO' )
            :tag( 'span' )
            :addClass( 'system-entry-label' )
            :addClass( 'mw-customtoggle-legend' )
            :wikitext( 'Legende' )
            :done()
            :tag( 'div' )
            :attr( 'id', 'mw-customcollapsible-legend' )
            :addClass( 'mw-collapsible mw-collapsed' )

    for key, _ in pairs( t.types ) do
    	local icon = ''
    	local typeTranslation = key

    	if celestialObject.getIcon( key ) ~= nil then
    		icon = celestialObject.getIcon( key )
		end

    	if celestialObject.reverseMapType( key ) ~= nil then
    		typeTranslation = celestialObject.reverseMapType( key )
		end

        infoTable = infoTable
                :tag( 'span' )
                :addClass( 'system-entry-label' )
                :wikitext( icon .. ' ' .. typeTranslation )
                :done()
    end

    return infoTable:allDone()
end

--- Template call entry
function SternensystemStruktur.output()
    local instance = SternensystemStruktur:new()

    if mw.getCurrentFrame():getParent().args.name ~= nil then
        instance.pageName = mw.getCurrentFrame():getParent().args.name
    else
        instance.pageName = mw.title.getCurrentTitle().subpageText
    end

    instance:getStarsystemData()
    instance:getCelestialObjects()

    if mw.getCurrentFrame():getParent().args.code then
        instance.celestialObjects = instance:filterCelestialObjects( instance )
    end

    instance:createDataStructure()

    return tostring( instance:makeHtml() )
end

--- New Instance
--- @return table CelestialObject
function SternensystemStruktur.new( self )
    local instance = {
        pageName = nil,
        system = nil,
        celestialObject = nil,
        structure = nil,
        types = {}
    }

    setmetatable( instance, metatable )

    return instance
end

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