- 欢迎光临Satisfactory国区BWIKI。请登录您的B站账号,方可使用页面编辑与评论功能。

全站通知:

模块:CraftingOverclockingTable

来自幸福工厂WIKI_BWIKI_哔哩哔哩
跳到导航 跳到搜索

此模块的文档可以在模块:CraftingOverclockingTable/doc创建

local cargo = mw.ext.cargo
local recipeUsage = require([[Module:RecipeUsage]])

local p = {}

-- displays a table with info about input, output and energy-consumption on given base values
-- displays data for base (100%), 150 %, 200 % and 250 %
-- expected parameters for each row (with increasing suffixes): input1.1, inRate1.1, output1, outRate1
-- optional parameter for used energy at 100 %: energyBase
function p.overclockTable( f )
  local args = f:getParent().args
  local rows = {}

  local overclockings = {}
  local energyFactors = {}
  if args['overclockings'] ~= nil then
    for i in string.gmatch(args['overclockings'],"[%d%.]+") do
      table.insert(overclockings,tonumber(i))
    end
  else
    -- default values
    overclockings = {1, 1.5, 2, 2.5}
  end

  if args['energyFactors'] ~= nil then
    for i in string.gmatch(args['energyFactors'],"[%d%.]+") do
      table.insert(energyFactors,tonumber(i))
    end
  else
    -- default values
    -- energy used is energyBase * overclock ^ 1.6
    -- i.e. the factors are 150 % -> 7.65, 200 % -> 12.13, 250 % -> 17.33
    for _,o in ipairs(overclockings) do
      -- lua has only a natural exponential function, use a^x = e^(x*ln(a))
      table.insert(energyFactors, math.exp(1.6 * math.log(o)))
      -- default is
      --energyFactors = {1, 1.91, 3.03, 4.33}
    end
  end

  -- lookup recipe data from database
  if args['lookupDataCraftedIn'] ~= nil then
    local fields = table.concat(recipeUsage.argList, ',')
    local queryArgs = {
      where = 'craftedIn="' .. args['lookupDataCraftedIn'] .. '"',
      orderBy = 'product ASC, alternateRecipe ASC'
    }
    local recipes = cargo.query('crafting_recipes', fields, queryArgs)

    -- find first recipe row that is not used by manual parameters
    local r = 0
    repeat
      r = r + 1
    until(args['input'..r..'.1'] == nil)

    for _,res in ipairs(recipes) do
      local craftingTime = tonumber(res.craftingTime)
      local productsPerMinute = tonumber(res.productsPerMinute)
      if craftingTime ~= nil and craftingTime > 0 and productsPerMinute ~= nil and productsPerMinute > 0 then
        local productionCyclesPerMinute = 60 / craftingTime
        args['input'..r..'.1'] = res.ingredient1 ~= '' and res.ingredient1 or nil
        args['input'..r..'.2'] = res.ingredient2 ~= '' and res.ingredient2 or nil
        args['input'..r..'.3'] = res.ingredient3 ~= '' and res.ingredient3 or nil
        args['input'..r..'.4'] = res.ingredient4 ~= '' and res.ingredient4 or nil
        args['input'..r..'.5'] = res.ingredient5 ~= '' and res.ingredient5 or nil
        args['input'..r..'.6'] = res.ingredient6 ~= '' and res.ingredient6 or nil
        args['input'..r..'.7'] = res.ingredient7 ~= '' and res.ingredient7 or nil
        args['input'..r..'.8'] = res.ingredient8 ~= '' and res.ingredient8 or nil
        args['input'..r..'.9'] = res.ingredient9 ~= '' and res.ingredient9 or nil
        args['input'..r..'.10'] = res.ingredient10 ~= '' and res.ingredient10 or nil
        args['inRate'..r..'.1'] = res.quantity1 ~= '' and (productionCyclesPerMinute * tonumber(res.quantity1)) or nil
        args['inRate'..r..'.2'] = res.quantity2 ~= '' and (productionCyclesPerMinute * tonumber(res.quantity2)) or nil
        args['inRate'..r..'.3'] = res.quantity3 ~= '' and (productionCyclesPerMinute * tonumber(res.quantity3)) or nil
        args['inRate'..r..'.4'] = res.quantity4 ~= '' and (productionCyclesPerMinute * tonumber(res.quantity4)) or nil
        args['inRate'..r..'.5'] = res.quantity5 ~= '' and (productionCyclesPerMinute * tonumber(res.quantity5)) or nil
        args['inRate'..r..'.6'] = res.quantity6 ~= '' and (productionCyclesPerMinute * tonumber(res.quantity6)) or nil
        args['inRate'..r..'.7'] = res.quantity7 ~= '' and (productionCyclesPerMinute * tonumber(res.quantity7)) or nil
        args['inRate'..r..'.8'] = res.quantity8 ~= '' and (productionCyclesPerMinute * tonumber(res.quantity8)) or nil
        args['inRate'..r..'.9'] = res.quantity9 ~= '' and (productionCyclesPerMinute * tonumber(res.quantity9)) or nil
        args['inRate'..r..'.10'] = res.quantity10 ~= '' and (productionCyclesPerMinute * tonumber(res.quantity10)) or nil
        args['output'..r] = res.product
        args['outRate'..r] = res.productsPerMinute
        args['alternateRecipe'..r] = (res.alternateRecipe == '1') and true or false
        args['recipeName'..r] = res.recipeName ~= nil and res.recipeName or nil
        r = r + 1
      end
    end
  end

  -- header
  -- only show "Input"-header if there are inputs
  local cols={args['input1.1'] ~= nil and 'Input' or ''}
  for _,o in ipairs(overclockings) do
    table.insert(cols, (o*100)..' %')
  end
  if args['input1.1'] ~= nil then
    -- only show output column if there are outputs (if only energy is displayed, this col is not needed)
    table.insert(cols, 'Output')
  end
  table.insert(rows,'<tr><th>'..table.concat(cols,'</th><th>')..'</th></tr>')

  -- if base-energy available, display energy row
  if args['energyBase'] ~= nil then
    cols={'<th>Energy (MW)</th>'}
    local e = tonumber(args['energyBase'])
    for _,ef in ipairs(energyFactors) do
      table.insert(cols, '<td>'..round(e*ef)..'</td>')
    end
    if args['input1.1'] ~= nil then
      table.insert(cols, '<td></td>') -- empty col where the output is displayed for the other rows
    end
    table.insert(rows,'<tr>'..table.concat(cols)..'</tr>')
  end

  local borderTop = 'border-top: 2px solid #575757;'
  local noMoreRows, r = false, 1
  repeat
    if args['input'..r..'.1'] ~= nil and args['output'..r] ~= nil and args['inRate'..r..'.1'] ~= nil and args['outRate'..r] ~= nil then
      local noMoreIngredients, ingredientNr = false, 1
      repeat
        -- input rows
        if args['input'..r..'.'..ingredientNr] ~= nil and args['inRate'..r..'.'..ingredientNr] ~= nil then
          cols={'<tr style="'..(ingredientNr==1 and borderTop or '')..'"><td style="text-align: left;">[[File:'..args['input'..r..'.'..ingredientNr]..'.png|20px]]&nbsp;[['..args['input'..r..'.'..ingredientNr]..']]</td>'}
          for _,o in ipairs(overclockings) do
            table.insert(cols,'<td>'..round(o*tonumber(args['inRate'..r..'.'..ingredientNr]))..'</td>')
          end
          table.insert(cols,'<td></td></tr>')
          table.insert(rows,table.concat(cols))
          ingredientNr = ingredientNr + 1
        else
          noMoreIngredients=true
        end
      until(noMoreIngredients)

      -- output row
      cols={'<tr><td></td>'}
      for _,o in ipairs(overclockings) do
        table.insert(cols,'<td>'..round(o*tonumber(args['outRate'..r]))..'</td>')
      end
      local altRecipe = args['alternateRecipe'..r] and ' '..mw.getCurrentFrame():expandTemplate{title='alternateIcon'} or ''
      local linkName = (args['recipeName'..r] and args['recipeName'..r] ~= '' and args['recipeName'..r] ~= args['output'..r]) and '|'..args['recipeName'..r] or ''
      table.insert(cols, '<td style="text-align: left;">[[File:'..args['output'..r]..'.png|20px]]&nbsp;[['..args['output'..r]..linkName..']]'..altRecipe..'</td></tr>')
      table.insert(rows,table.concat(cols))

      r = r + 1
    else
      noMoreRows = true
    end
  until(noMoreRows)

  return '<table class="wikitable" style="text-align: right;">'..table.concat(rows)..'</table>'
end

-- round to 1 decimal
function round(n)
  return math.floor(n*10+0.5)/10
end

return p