模块

Enemy

来自蒙纳多研究本部

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

local p = {}
local post = require("Module:RequestHelper").post
local getArgs = require("Module:Arguments").getArgs
local html = require("Module:Html")
local compress = html.compress
local addlink = html.addlink

local function itemName(data)
  local name = data.itemID.name
  if data.rankType > 0 then
    name = name .. data.rankType
  end
  return name
end

local function calcActualDropRate(rateList)
  local totalRate = 0

  local middleData = {}
  local remainRate = 1
  for _, v in ipairs(rateList) do
    local rate = v / 100 * remainRate
    table.insert(middleData, rate)
    totalRate = totalRate + rate
    remainRate = remainRate * (1 - v / 100)
  end

  local result = {}
  local multiply = totalRate > 0 and 1 / totalRate * 100 or 0
  for _, v in ipairs(middleData) do
    table.insert(result, v * multiply)
  end

  return result
end

local function showRate(value)
  return mw.ustring.format("%.2f%%", value)
end

function p.template(frame, data)
  mw.smw.set(
    {
      id = data.row_id,
      lv = data.lv,
      hp = data.hp * 100,
      named = data.named,
      agi = data.agi,
      mapID = data.mapID.id_name,
      map = data.mapID.name
    }
  )

  local wikitext = ""

  do
    local header = {"named", "Lv", "HP", "力量", "以太力", "敏捷", "双重攻击率", "暴击率"}
    local body = {
      data.named,
      data.lv,
      data.hp * 100,
      data.str,
      data.eth,
      data.agi,
      data.dbl_atk,
      data.cnt_atk
    }

    wikitext = wikitext .. html.wikitable(header, {body}, {transpose = true, class = "xbtable"})

    wikitext =
      mw.ustring.format(
      [[
      <div class="row">
        <div class="large-6 columns">%s</div>
      </div>
    ]],
      wikitext
    )
  end

  do -- drop
    local boxlist = {}

    local boxRateList = calcActualDropRate({data.drop_spr_per, data.drop_rar_per, data.drop_nml_per})

    if data.drop_nml then
      local box = html.h4("普通宝箱 " .. boxRateList[3] .. "%")

      local header = {"种类", "物品", "概率"}
      local rows = {}

      local rateList = {data.drop_nml.materia1Per, data.drop_nml.materia2Per}
      local actualRateList = calcActualDropRate(rateList)

      for i = 1, 2 do
        if data.drop_nml["materia" .. i .. "Per"] > 0 then
          table.insert(
            rows,
            {
              data.drop_nml["materia" .. i].itemType,
              addlink(data.drop_nml["materia" .. i].itemID.name, "物品"),
              showRate(actualRateList[1])
            }
          )
          mw.smw.set({dropMateria = data.drop_nml["materia" .. i].itemID.name})
        end
      end

      box = box .. html.wikitable(header, rows, {class = "xbtable"})
      table.insert(boxlist, box)
    end

    if data.drop_rar then
      local box = html.h4("稀有宝箱 " .. boxRateList[2] .. "%")
      local header = {"种类", "物品", "概率"}
      local rows = {}

      local totalPer =
        data.drop_rar.crystal_per + data.drop_rar.wpn_per + data.drop_rar.equip_per + data.drop_rar.arts_per
      local actual_crystal_per = data.drop_rar.crystal_per / totalPer
      local actual_wpn_per = data.drop_rar.wpn_per / totalPer
      local actual_equip_per = data.drop_rar.equip_per / totalPer
      local actual_arts_per = data.drop_rar.arts_per / totalPer

      -- 结晶
      if actual_crystal_per > 0 then
        for i = 1, 2 do
          local skills = {}
          for j = 1, 2 do
            if data.drop_rar["crystal" .. i]["skill" .. j] then
              table.insert(skills, data.drop_rar["crystal" .. i]["skill" .. j].name)
              mw.smw.set(
                {dropCrystal = data.drop_rar["crystal" .. i]["skill" .. j].name .. data.drop_rar["crystal" .. i].rank}
              )
            end
          end

          if #skills > 0 then
            table.insert(
              rows,
              {
                "结晶" .. data.drop_rar["crystal" .. i].rank,
                table.concat(skills, "<br>"),
                showRate(data.drop_rar.crystal1Per * actual_crystal_per)
              }
            )
          end
        end
      end

      -- s武器
      if actual_wpn_per > 0 then
        local rateList = {data.drop_rar.wpn1Per, data.drop_rar.wpn2Per, data.drop_rar.wpn3Per, data.drop_rar.wpn4Per}
        local actualRateList = calcActualDropRate(rateList)

        for i = 1, 4 do
          if data.drop_rar["wpn" .. i] then
            table.insert(
              rows,
              {
                "S武器",
                addlink(data.drop_rar["wpn" .. i].itemID.name, "物品") ..
                  "[" .. data.drop_rar["wpn" .. i .. "_slot"] .. "]",
                showRate(actualRateList[i] * actual_wpn_per)
              }
            )
            mw.smw.set(
              {dropWpn = data.drop_rar["wpn" .. i].itemID.name .. "[" .. data.drop_rar["wpn" .. i .. "_slot"] .. "]"}
            )
          end
        end
      end

      -- s装备
      if actual_equip_per > 0 then
        local rateList = {
          data.drop_rar.equip1Per,
          data.drop_rar.equip2Per,
          data.drop_rar.equip3Per,
          data.drop_rar.equip4Per
        }
        local actualRateList = calcActualDropRate(rateList)

        for i = 1, 4 do
          if data.drop_rar["equip" .. i] then
            table.insert(
              rows,
              {
                "S装备",
                addlink(data.drop_rar["equip" .. i].itemID.name, "物品") ..
                  "[" .. data.drop_rar["equip" .. i .. "_slot"] .. "]",
                showRate(actualRateList[i] * actual_equip_per)
              }
            )
            mw.smw.set(
              {
                dropEquip = data.drop_rar["equip" .. i].itemID.name ..
                  "[" .. data.drop_rar["equip" .. i .. "_slot"] .. "]"
              }
            )
          end
        end
      end

      -- 战技书
      if actual_arts_per > 0 then
        local rateList = {
          data.drop_rar.arts1Per,
          data.drop_rar.arts2Per,
          data.drop_rar.arts3Per,
          data.drop_rar.arts4Per,
          data.drop_rar.arts5Per,
          data.drop_rar.arts6Per,
          data.drop_rar.arts7Per,
          data.drop_rar.arts8Per
        }
        local actualRateList = calcActualDropRate(rateList)

        for i = 1, 8 do
          if data.drop_rar["arts" .. i] then
            table.insert(
              rows,
              {
                "战技书",
                data.drop_rar["arts" .. i].itemID.name,
                showRate(actualRateList[i] * actual_arts_per)
              }
            )
            mw.smw.set({dropArts = data.drop_rar["arts" .. i].itemID.name})
          end
        end
      end

      box = box .. html.wikitable(header, rows, {class = "xbtable"})
      table.insert(boxlist, box)
    end

    if data.drop_spr then
      local box = html.h4("金宝箱 " .. boxRateList[1] .. "%")
      local header = {"种类", "物品", "概率"}
      local rows = {}

      local totalPer =
        data.drop_spr.wpn_per + data.drop_spr.uni_wpn_per + data.drop_spr.uni_equip_per + data.drop_spr.arts_per
      local actual_wpn_per = data.drop_spr.wpn_per / totalPer
      local actual_uni_wpn_per = data.drop_spr.uni_wpn_per / totalPer
      local actual_uni_equip_per = data.drop_spr.uni_equip_per / totalPer
      local actual_arts_per = data.drop_spr.arts_per / totalPer

      -- s武器
      if actual_wpn_per > 0 then
        local rateList = {data.drop_spr.wpn1Per, data.drop_spr.wpn2Per, data.drop_spr.wpn3Per, data.drop_spr.wpn4Per}
        local actualRateList = calcActualDropRate(rateList)

        for i = 1, 4 do
          if data.drop_spr["wpn" .. i] then
            table.insert(
              rows,
              {
                "S武器",
                addlink(data.drop_spr["wpn" .. i].itemID.name, "物品") ..
                  "[" .. data.drop_spr["wpn" .. i .. "_slot"] .. "]",
                showRate(actualRateList[i] * actual_wpn_per)
              }
            )
            mw.smw.set(
              {dropWpn = data.drop_spr["wpn" .. i].itemID.name .. "[" .. data.drop_spr["wpn" .. i .. "_slot"] .. "]"}
            )
          end
        end
      end

      -- u武器
      if actual_uni_wpn_per > 0 then
        local rateList = {
          data.drop_spr.uni_wpn1Per,
          data.drop_spr.uni_wpn2Per,
          data.drop_spr.uni_wpn3Per,
          data.drop_spr.uni_wpn4Per,
          data.drop_spr.uni_wpn5Per,
          data.drop_spr.uni_wpn6Per,
          data.drop_spr.uni_wpn7Per,
          data.drop_spr.uni_wpn8Per
        }
        local actualRateList = calcActualDropRate(rateList)

        for i = 1, 8 do
          if data.drop_spr["uni_wpn" .. i] then
            table.insert(
              rows,
              {
                "U武器",
                addlink(data.drop_spr["uni_wpn" .. i].itemID.name, "物品"),
                showRate(actualRateList[i] * actual_uni_wpn_per)
              }
            )
            mw.smw.set({dropUniWpn = data.drop_spr["uni_wpn" .. i].itemID.name})
          end
        end
      end

      -- u装备
      if actual_uni_equip_per > 0 then
        local rateList = {
          data.drop_spr.uni_equip1Per,
          data.drop_spr.uni_equip2Per,
          data.drop_spr.uni_equip3Per,
          data.drop_spr.uni_equip4Per,
          data.drop_spr.uni_equip5Per,
          data.drop_spr.uni_equip6Per,
          data.drop_spr.uni_equip7Per,
          data.drop_spr.uni_equip8Per
        }
        local actualRateList = calcActualDropRate(rateList)

        for i = 1, 8 do
          if data.drop_spr["uni_equip" .. i] then
            table.insert(
              rows,
              {
                "U装备",
                addlink(data.drop_spr["uni_equip" .. i].itemID.name, "物品"),
                showRate(actualRateList[i] * actual_uni_equip_per)
              }
            )
            mw.smw.set({dropUniEquip = data.drop_spr["uni_equip" .. i].itemID.name})
          end
        end
      end

      -- 战技书
      if actual_arts_per > 0 then
        local rateList = {
          data.drop_spr.arts1Per,
          data.drop_spr.arts2Per,
          data.drop_spr.arts3Per,
          data.drop_spr.arts4Per,
          data.drop_spr.arts5Per,
          data.drop_spr.arts6Per,
          data.drop_spr.arts7Per,
          data.drop_spr.arts8Per
        }
        local actualRateList = calcActualDropRate(rateList)

        for i = 1, 8 do
          if data.drop_spr["arts" .. i] then
            table.insert(
              rows,
              {
                "战技书",
                data.drop_spr["arts" .. i].itemID.name,
                showRate(actualRateList[i] * actual_arts_per)
              }
            )
            mw.smw.set({dropArts = data.drop_spr["arts" .. i].itemID.name})
          end
        end
      end

      box = box .. html.wikitable(header, rows, {class = "xbtable"})
      table.insert(boxlist, box)
    end

    if #boxlist > 0 then
      wikitext = wikitext .. html.h3("掉落")
      wikitext = wikitext .. '<div class="row">'
      for _, v in ipairs(boxlist) do
        wikitext = wikitext .. mw.ustring.format([[<div class="large-4 medium-6 columns">%s</div>]], v)
      end
      wikitext = wikitext .. "</div>"
    end
  end

  wikitext = wikitext .. '<div class="xb1map-enemy" data-enemy-id="' .. data.row_id .. '" ></div>'

  return compress(wikitext)
end

function p.fetchDataById(id)
  return post("bdat_common.BTL_enelist", id)
end

function p.main(frame)
  local args = getArgs(frame)
  local out = ""

  for _, id in ipairs(args) do
    local data = p.fetchDataById(id)
    out = out .. html.h2(data.mapID.name .. " (" .. data.row_id .. ")")
    out = out .. p.template(frame, data)
  end

  -- mw.log(mw.text.jsonEncode(data, mw.text.JSON_PRETTY))

  return out
end

return p