From Official Arms of God Wiki

Renders Enemies records from Data:Enemies.json on index and detail pages.

  • infobox — infobox for one record (used via Template:Enemies infobox)
  • index — sortable index table on Enemies
  • body / crossRefs — per-section renderers invoked from detail pages

Bot-published: the module and its Data: page are regenerated on re-publish. Restyle via the per-section templates rather than editing page wikitext.


local Core = require('Module:Core')
local p = {}
local CAT = 'Enemies'

function p.infobox(frame)
    return Core.infoboxEntry(CAT, frame)
end

function p.body(frame)
    return Core.bodyEntry(CAT, frame)
end

function p.crossRefs(frame)
    return require('Module:CrossRef').entry(CAT, frame)
end

function p.index(frame)
    return Core.indexEntry(CAT, frame)
end

function p.render(frame)
    return Core.renderEntry(CAT, frame)
end

local function plain(value)
    return mw.text.nowiki(tostring(value or ''))
end

local function number(value)
    if value == nil then return '—' end

    local n = tonumber(value)
    if not n then return plain(value) end

    local s = string.format('%.2f', n)
    s = s:gsub('0+$', ''):gsub('%.$', '')
    return s
end

local function findRecord(key)
    for _, rec in ipairs(Core.load(CAT)) do
        if rec.id == key or rec.slug == key or rec.name == key then
            return rec
        end
    end
end

function p.profile(frame)
    local key = mw.text.trim(frame.args.id or frame.args[1] or '')
    local rec = findRecord(key)

    if not rec then
        return tostring(
            mw.html.create('strong')
                :addClass('error')
                :wikitext('Enemy not found: ' .. plain(key))
        )
    end

    local root = mw.html.create('div')
        :addClass('aog-enemy-profile')

    local main = root:tag('div')
        :addClass('aog-enemy-main')

    if rec.icon and rec.icon ~= '' then
        local art = '[[File:' .. rec.icon
            .. '|frameless|600x600px|alt='
            .. rec.name .. ']]'

        main:tag('div')
            :addClass('aog-enemy-art')
            :wikitext(frame:preprocess(art))
    end

    if rec.description and rec.description ~= '' then
        main:tag('p')
            :addClass('aog-enemy-lore')
            :wikitext(plain(rec.description))
    end

    if rec.tactics and rec.tactics ~= '' then
        main:tag('p')
            :addClass('aog-enemy-label')
            :wikitext('Combat tips')

        main:tag('p')
            :wikitext(plain(rec.tactics))
    end

    if rec.notes and #rec.notes > 0 then
        local list = main:tag('ul')
            :addClass('aog-enemy-notes')

        for _, note in ipairs(rec.notes) do
            list:tag('li'):wikitext(plain(note))
        end
    end

    local aside = root:tag('div')
        :addClass('aog-enemy-aside')

    local stats = aside:tag('table')
        :addClass('wikitable aog-enemy-stats')

    stats:tag('caption'):wikitext(plain(rec.name))

    local function row(label, value)
        local tr = stats:tag('tr')

        tr:tag('th')
            :attr('scope', 'row')
            :wikitext(label)

        tr:tag('td'):wikitext(value)
    end

    local classes = {}
    local labels = {
        Melee = 'Melee',
        Range = 'Ranged',
        Big = 'Big',
        Boss = 'Boss'
    }

    for _, tag in ipairs(rec.tags or {}) do
        classes[#classes + 1] = plain(labels[tag] or tag)
    end

    if #classes > 0 then
        row('Classification', table.concat(classes, ', '))
    end

    local st = rec.stats or {}

    row('Base health', number(st.Health))
    row('Health per wave', number(st['HP per Wave']))
    row('Base damage', number(st.Damage))
    row('Damage per wave', number(st['Damage per Wave']))
    row('Speed', number(st.Speed))
    row('Resources', number(st.Resources))

    aside:tag('p')
        :addClass('aog-enemy-stat-note')
        :wikitext(
            'Base parameters. Actual combat values depend on wave, '
            .. 'difficulty and other modifiers.'
        )

    return tostring(root)
end

return p