模块:Enemy

来自乐园数据管理室
ヒカリ讨论 | 贡献2020年5月24日 (日) 23:17的版本
(差异) ←上一版本 | 最后版本 (差异) | 下一版本→ (差异)

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

local p = {}
local loadJson = require("Module:JSON").loadJson
local html = require("Module:Html")
local torna = require("Module:Torna").checkTitle()

function p.getDataByEnemyId(enemyId)
  local bit32 = require("bit32")
  local EnArrange = loadJson("CHR_EnArrange/" .. enemyId)
  local Category = loadJson("EnemyCategory")[enemyId] or "普通敌人"

  -- 必定存在的属性
  local EnParamBase = loadJson("CHR_EnParamTable/" .. EnArrange.Lv)
  local EnParam = loadJson("CHR_EnParam/" .. EnArrange.ParamID)
  local RSC = loadJson("RSC_En/" .. EnParam.ResourceID)
  local Grow = loadJson("BTL_Grow/" .. EnArrange.Lv)

  -- 反应动作计算
  local IvdFiCombo = {
    ["击退"] = bit32.extract(EnParam.IvdFiCombo, 0),
    ["吹飞"] = bit32.extract(EnParam.IvdFiCombo, 1),
    ["破防"] = bit32.extract(EnParam.IvdFiCombo, 2),
    ["倒地"] = bit32.extract(EnParam.IvdFiCombo, 3),
    ["浮空"] = bit32.extract(EnParam.IvdFiCombo, 4),
    ["猛击"] = bit32.extract(EnParam.IvdFiCombo, 5)
  }
  local RstFiCombo = {
    ["击退"] = bit32.extract(EnParam.RstFiCombo, 0),
    ["吹飞"] = bit32.extract(EnParam.RstFiCombo, 1),
    ["破防"] = bit32.extract(EnParam.RstFiCombo, 2),
    ["倒地"] = bit32.extract(EnParam.RstFiCombo, 3),
    ["浮空"] = bit32.extract(EnParam.RstFiCombo, 4),
    ["猛击"] = bit32.extract(EnParam.RstFiCombo, 5)
  }
  local caculateReactionRate = function(Ivd, Rst)
    if Ivd == 1 then
      return "无效"
    elseif Rst == 1 then
      return "40%"
    else
      return "100%"
    end
  end

  -- 强化能力
  local loadEnhanceText = function(EnhanceID)
    if EnhanceID > 0 then
      local text = loadJson("BTL_Enhance/" .. EnhanceID).CaptionText
      if #text == 0 then
        return "Unknown Enhance: [[ " .. "JSON:BTL_Enhance/" .. EnhanceID .. "|" .. EnhanceID .. "]]"
      end
      return text
    end
    return nil
  end

  local Enhances = {
    loadEnhanceText(EnArrange.EnhanceID1),
    loadEnhanceText(EnArrange.EnhanceID2),
    loadEnhanceText(EnArrange.EnhanceID3)
  }

  local outData = {
    ["ID"] = EnArrange.id,
    ["等级"] = EnArrange.Lv,
    ["等级浮动"] = EnArrange.LvRand,
    ["体型"] = EnArrange.Scale .. "%",
    ["分类"] = Category,
    ["种族"] = RSC.TypeFamily,
    ["属性"] = EnParam.Atr,
    ["暴击率"] = EnParam.CriticalRate .. "%",
    ["格挡率"] = EnParam.GuardRate .. "%",
    ParamBase = {
      Hp = EnParamBase.HpMaxBase * EnParam.HpMaxRev / 1000,
      Strength = EnParamBase.StrengthBase * EnParam.StrengthRev / 1000,
      PowEther = EnParamBase.PowEtherBase * EnParam.PowEtherRev / 1000,
      Dex = EnParamBase.DexBase * EnParam.DexRev / 1000,
      Agility = EnParamBase.AgilityBase * EnParam.AgilityRev / 1000,
      Luck = EnParamBase.LuckBase * EnParam.LuckRev / 1000
    },
    ["物理防御"] = EnParam.RstPower .. "%",
    ["以太防御"] = EnParam.RstEther .. "%",
    ["击杀奖励"] = {
      EXP = math.floor(Grow.EnemyExp * EnArrange.ExpRev / 100),
      Gold = math.floor(Grow.EnemyGold * EnArrange.GoldRev / 100),
      WP = math.floor(Grow.EnemyWP * EnArrange.WPRev / 100),
      SP = math.floor(Grow.EnemySP * EnArrange.SPRev / 100)
    },
    ["反应动作抗性"] = {
      ["击退"] = caculateReactionRate(IvdFiCombo["击退"], RstFiCombo["击退"]),
      ["吹飞"] = caculateReactionRate(IvdFiCombo["吹飞"], RstFiCombo["吹飞"]),
      ["破防"] = caculateReactionRate(IvdFiCombo["破防"], RstFiCombo["破防"]),
      ["倒地"] = caculateReactionRate(IvdFiCombo["倒地"], RstFiCombo["倒地"]),
      ["浮空"] = caculateReactionRate(IvdFiCombo["浮空"], RstFiCombo["浮空"]),
      ["猛击"] = caculateReactionRate(IvdFiCombo["猛击"], RstFiCombo["猛击"])
    },
    Enhance = Enhances,
    IgnoreLevPow = EnArrange.IgnoreLevPow
  }

  -- 可能存在的属性

  -- 珍稀种能力修正
  if EnArrange.ParamRev > 0 then
    local EnParamRev = loadJson("CHR_EnParam_Rev/" .. EnArrange.ParamRev)
    outData.ParamBase.Hp = outData.ParamBase.Hp * EnParamRev.HpMaxRev / 1000
    outData.ParamBase.Strength = outData.ParamBase.Strength * EnParamRev.StrengthRev / 1000
    outData.ParamBase.PowEther = outData.ParamBase.PowEther * EnParamRev.PowEtherRev / 1000
    outData.ParamBase.Dex = outData.ParamBase.Dex * EnParamRev.DexRev / 1000
    outData.ParamBase.Agility = outData.ParamBase.Agility * EnParamRev.AgilityRev / 1000
    outData.ParamBase.Luck = outData.ParamBase.Luck * EnParamRev.LuckRev / 1000

    outData.Multiply = {
      Hp = EnParam.HpMaxRev / 1000 * EnParamRev.HpMaxRev / 1000,
      Strength = EnParam.StrengthRev / 1000 * EnParamRev.StrengthRev / 1000,
      PowEther = EnParam.PowEtherRev / 1000 * EnParamRev.PowEtherRev / 1000,
      Dex = EnParam.DexRev / 1000 * EnParamRev.DexRev / 1000,
      Agility = EnParam.AgilityRev / 1000 * EnParamRev.AgilityRev / 1000,
      Luck = EnParam.LuckRev / 1000 * EnParamRev.LuckRev / 1000
    }
  end

  -- 掉落
  local parseDropItem = function(DropItem)
    local out = {}
    for i = 1, 8 do
      if DropItem["ItemID" .. i] ~= 0 then
        local itemTitle = mw.title.new(DropItem["ItemID" .. i], "物品")
        if torna then
          local tornaTitle = mw.title.new(DropItem["ItemID" .. i], "黄金之国物品")
          if tornaTitle.exists then
            itemTitle = tornaTitle
          end
        end
        table.insert(
          out,
          {
            Item = "[[" .. itemTitle.fullText .. "|" .. itemTitle.text .. "]]",
            DropProb = DropItem["DropProb" .. i] / 10 .. "%",
            First = DropItem["FirstNamed" .. i] == 1 and "✔" or ""
          }
        )
        mw.smw.set {
          ["掉落"] = itemTitle.fullText,
          [itemTitle.fullText .. "掉率"] = DropItem["DropProb" .. i] / 10 ..
            "%" .. (DropItem["FirstNamed" .. i] == 1 and "(初次100%)" or "")
        }
      end
    end
    return out
  end

  if EnArrange.DropTableID > 0 then
    local EnDropItem1 = loadJson("BTL_EnDropItem/" .. EnArrange.DropTableID)
    outData["击杀奖励"]["DropItem1"] = parseDropItem(EnDropItem1)
  end

  if EnArrange.DropTableID3 > 0 then
    local EnDropItem2 = loadJson("BTL_EnDropItem/" .. EnArrange.DropTableID3)
    outData["击杀奖励"]["DropItem2"] = parseDropItem(EnDropItem2)
  end

  if EnArrange.PreciousID ~= 0 then
    local itemTitle = mw.title.new(EnArrange.PreciousID, "物品")
    outData["击杀奖励"].PreciousID = "[[" .. itemTitle.fullText .. "|" .. itemTitle.text .. "]]"
    mw.smw.set {
      ["掉落"] = itemTitle.fullText,
      [itemTitle.fullText .. "掉率"] = "100%"
    }
  end

  -- 愤怒光环
  if EnParam.Aura > 0 then
    local Aura = loadJson("BTL_Aura/" .. EnParam.Aura)
    outData.Aura = {
      Name = Aura.Name,
      ChangeAtr = Aura.ChangeAtr,
      Enhance = {
        loadEnhanceText(Aura.Enhance1),
        loadEnhanceText(Aura.Enhance2),
        loadEnhanceText(Aura.Enhance3)
      }
    }
  end

  -- arts
  local BdatEnums = require("Module:BdatEnums")

  local parseArtsEn = function(Arts)
    local ArtsType = BdatEnums.ArtsType[Arts.ArtsType]
    local ArtsBuff = Arts.ArtsBuff > 0 and BdatEnums.ArtsBuff[Arts.ArtsBuff] or ""
    local ArtsDeBuff = Arts.ArtsDeBuff > 0 and loadJson("BTL_Buff/" .. Arts.ArtsDeBuff).Name or ""
    local Target = BdatEnums.ArtsTarget[Arts.Target]
    local DmgMgn = Arts.DmgMgn
    if Target == "自身" or ArtsType == "减益效果" then
      DmgMgn = 0
    end

    local HitFrm = {}
    local hitNum = 0
    for i = 1, 16 do
      table.insert(HitFrm, Arts["HitFrm" .. i])
      if Arts["HitFrm" .. i] > 0 then
        hitNum = hitNum + 1
      end
    end

    local DmgRt = {}
    local DmgRtTotal = 0
    for i = 1, 16 do
      local potencyRatio = Arts["DmgRt" .. i]
      if potencyRatio == 255 then
        potencyRatio = -1
      end
      table.insert(DmgRt, potencyRatio)

      if potencyRatio > 0 then
        DmgRtTotal = DmgRtTotal + potencyRatio
      end
    end

    local ReAct = {}
    for i = 1, 16 do
      local ReActText = Arts["ReAct" .. i] > 0 and BdatEnums.ReActType[Arts["ReAct" .. i]] or ""
      table.insert(ReAct, ReActText)
    end

    local hit = {}
    local DmgTotal = 0
    for i = 1, 16 do
      local dmgPerHit = 0
      if DmgRtTotal > 0 then -- DmgRt 总和大于0时,每hit伤害按 DmgRt 分割
        if DmgRt[i] > 0 then
          dmgPerHit = DmgMgn * DmgRt[i] / DmgRtTotal
        end
      else -- DmgRtTotal 为 0
        if HitFrm[i] > 0 and DmgRt[i] == 0 then -- HitFrame存在且DmgRt不为-1
          dmgPerHit = DmgMgn / hitNum
        end
      end

      if HitFrm[i] > 0 or dmgPerHit > 0 or #ReAct[i] > 0 then
        local dmg = tonumber(mw.ustring.format("%.2f", dmgPerHit))
        table.insert(
          hit,
          {
            HitTime = tonumber(mw.ustring.format("%.2f", HitFrm[i] / 30)),
            Dmg = dmg > 0 and dmg or "",
            ReAct = ReAct[i]
          }
        )
        DmgTotal = DmgTotal + dmgPerHit
      end
    end
    local hitText =
      html.wikitable(
      {
        {scope = "HitTime", label = "秒"},
        {scope = "Dmg", label = "伤害倍率"},
        {scope = "ReAct", label = "特效"}
      },
      hit,
      {class = "borderless-table"}
    )

    -- summon
    local SummonText = ""
    if Arts.Summon and Arts.Summon > 0 then
      local SummonResult = {}
      local Summon = loadJson("BTL_Summon/" .. Arts.Summon)
      for _, id in ipairs(Summon.EnemyID) do
        if id > 0 then
          local enemyData = loadJson("CHR_EnArrange/" .. id)

          local ns = "敌人"
          local currentTitle = mw.title.getCurrentTitle()
          if "黄金之国" == mw.ustring.sub(tostring(currentTitle), 1, 4) then
            ns = "黄金之国敌人"
          end
          local title = mw.title.new(enemyData.Name, ns)
          table.insert(SummonResult, "[[" .. title.fullText .. "|" .. title.text .. "]]")
          mw.smw.set {["SummonEnemy"] = title.fullText}
        end
      end
      SummonText = table.concat(SummonResult, "<br>")
    end

    local Resist = {}
    if Arts.SArmor1 then
      table.insert(Resist, "吹飞")
      table.insert(Resist, "击退")
    end
    if Arts.SArmor2 then
      table.insert(Resist, "破防")
      table.insert(Resist, "倒地")
      table.insert(Resist, "浮空")
      table.insert(Resist, "猛击")
    end
    Resist = table.concat(Resist, " ")

    return {
      ID = Arts.id,
      Name = Arts.Name == 0 and "" or Arts.Name,
      DebugName = Arts.DebugName,
      ArtsType = ArtsType,
      ArtsBuff = ArtsBuff,
      ArtsDeBuff = ArtsDeBuff,
      Target = Target,
      Distance = Arts.Distance,
      RangeType = BdatEnums.ArtsRangeType[Arts.RangeType],
      Radius = Arts.Radius,
      Length = Arts.Length,
      Atr = Arts.Atr,
      HitRevise = Arts.HitRevise .. "%",
      CriRevise = Arts.CriRevise .. "%",
      DmgMgn = DmgTotal > 0 and DmgTotal or "",
      RecastTime = Arts.Recast / 30 .. "秒",
      StartRecast = Arts.StartRecast .. "%",
      Enhance = loadEnhanceText(Arts.Enhance),
      Summon = SummonText,
      Resist = Resist,
      Hit = hit,
      HitText = hitText
    }
  end

  outData.Arts = {}
  for i = 1, 16 do
    local artsId = EnParam["ArtsNum" .. i]
    if artsId > 0 then
      local Arts = loadJson("BTL_Arts_En/" .. artsId)
      table.insert(outData.Arts, parseArtsEn(Arts))
    end
  end

  local parseArtsBl = function(Arts)
    local ArtsType = BdatEnums.ArtsType[Arts.ArtsType]
    local ArtsBuff = Arts.ArtsBuff > 0 and BdatEnums.ArtsBuff[Arts.ArtsBuff] or ""
    local ArtsDeBuff = Arts.ArtsDeBuff > 0 and loadJson("BTL_Buff/" .. Arts.ArtsDeBuff).Name or ""
    local Target = BdatEnums.ArtsTarget[Arts.Target]
    local DmgMgn = Arts.DmgMgn6
    if Target == "自身" or ArtsType == "减益效果" then
      DmgMgn = 0
    end

    local HitFrm = {}
    local hitNum = 0
    for i = 1, 16 do
      table.insert(HitFrm, Arts["HitFrm" .. i])
      if Arts["HitFrm" .. i] > 0 then
        hitNum = hitNum + 1
      end
    end

    local DmgRt = {}
    local DmgRtTotal = 0
    for i = 1, 16 do
      local potencyRatio = Arts["DmgRt" .. i]
      if potencyRatio == 255 then
        potencyRatio = -1
      end
      table.insert(DmgRt, potencyRatio)

      if potencyRatio > 0 then
        DmgRtTotal = DmgRtTotal + potencyRatio
      end
    end

    local ReAct = {}
    for i = 1, 16 do
      local ReActText = Arts["ReAct" .. i] > 0 and BdatEnums.ReActType[Arts["ReAct" .. i]] or ""
      table.insert(ReAct, ReActText)
    end

    local hit = {}
    local DmgTotal = 0
    for i = 1, 16 do
      local dmgPerHit = 0
      if DmgRtTotal > 0 then -- DmgRt 总和大于0时,每hit伤害按 DmgRt 分割
        if DmgRt[i] > 0 then
          dmgPerHit = DmgMgn * DmgRt[i] / DmgRtTotal
        end
      else -- DmgRtTotal 为 0
        if HitFrm[i] > 0 and DmgRt[i] == 0 then -- HitFrame存在且DmgRt不为-1
          dmgPerHit = DmgMgn / hitNum
        end
      end

      if HitFrm[i] > 0 or dmgPerHit > 0 or #ReAct[i] > 0 then
        local dmg = tonumber(mw.ustring.format("%.2f", dmgPerHit))
        table.insert(
          hit,
          {
            HitTime = tonumber(mw.ustring.format("%.2f", HitFrm[i] / 30)),
            Dmg = dmg > 0 and dmg or "",
            ReAct = ReAct[i]
          }
        )
        DmgTotal = DmgTotal + dmgPerHit
      end
    end
    local hitText =
      html.wikitable(
      {
        {scope = "HitTime", label = "秒"},
        {scope = "Dmg", label = "伤害倍率"},
        {scope = "ReAct", label = "特效"}
      },
      hit,
      {class = "borderless-table"}
    )

    local Resist = {}
    if Arts.SArmor1 then
      table.insert(Resist, "吹飞")
      table.insert(Resist, "击退")
    end
    if Arts.SArmor2 then
      table.insert(Resist, "破防")
      table.insert(Resist, "倒地")
      table.insert(Resist, "浮空")
      table.insert(Resist, "猛击")
    end
    Resist = table.concat(Resist, " ")

    return {
      ID = Arts.id,
      Name = Arts.Name == 0 and "" or Arts.Name,
      DebugName = Arts.DebugName,
      ArtsType = ArtsType,
      ArtsBuff = ArtsBuff,
      ArtsDeBuff = ArtsDeBuff,
      Target = Target,
      Distance = Arts.Distance,
      RangeType = BdatEnums.ArtsRangeType[Arts.RangeType],
      Radius = Arts.Radius,
      Length = Arts.Length,
      Atr = Arts.Atr,
      HitRevise = Arts.HitRevise .. "%",
      CriRevise = Arts.CriRevise .. "%",
      DmgMgn = DmgTotal > 0 and DmgTotal or "",
      Enhance = loadEnhanceText(Arts.Enhance5),
      Resist = Resist,
      Hit = hit,
      HitText = hitText
    }
  end

  -- 携带异刃
  if EnArrange.EnemyBladeID > 0 then
    local BladeID = loadJson("CHR_EnArrange/" .. EnArrange.EnemyBladeID).BladeID
    local CHR_Bl = loadJson("CHR_Bl/" .. BladeID)
    local Arts1 = CHR_Bl.BArts1 > 0 and loadJson("BTL_Arts_Bl/" .. CHR_Bl.BArts1) or nil
    local Arts2 = CHR_Bl.BArts2 > 0 and loadJson("BTL_Arts_Bl/" .. CHR_Bl.BArts2) or nil
    local Arts3 = CHR_Bl.BArts3 > 0 and loadJson("BTL_Arts_Bl/" .. CHR_Bl.BArts3) or nil
    local ArtsEx = CHR_Bl.BArtsEx

    outData.Blade = {
      ["属性"] = CHR_Bl.Atr,
      ["Arts"] = {
        Arts1 and parseArtsBl(Arts1),
        Arts2 and parseArtsBl(Arts2),
        Arts3 and parseArtsBl(Arts3)
      }
    }
  end

  -- 后处理
  outData.ParamBase.Hp = math.floor(outData.ParamBase.Hp)
  outData.ParamBase.Strength = math.floor(outData.ParamBase.Strength)
  outData.ParamBase.PowEther = math.floor(outData.ParamBase.PowEther)
  outData.ParamBase.Dex = math.floor(outData.ParamBase.Dex)
  outData.ParamBase.Agility = math.floor(outData.ParamBase.Agility)
  outData.ParamBase.Luck = math.floor(outData.ParamBase.Luck)

  -- SMW
  mw.smw.set {
    ["ZoneID"] = EnArrange.ZoneID,
    ["敌人分类"] = Category,
    ["地域"] = EnArrange.ZoneID > 0 and loadJson("FLD_maplist/" .. EnArrange.ZoneID).nameID,
    ["等级"] = EnArrange.Lv,
    ["等级浮动"] = EnArrange.LvRand,
    ["无视等级差补正"] = EnArrange.IgnoreLevPow and "✔" or "✘",
    ["种族"] = outData["种族"],
    EXP = outData["击杀奖励"].EXP,
    Gold = outData["击杀奖励"].Gold,
    WP = outData["击杀奖励"].WP,
    SP = outData["击杀奖励"].SP,
    HP = outData.ParamBase.Hp,
    ["力量"] = outData.ParamBase.Strength,
    ["以太力"] = outData.ParamBase.PowEther,
    ["灵巧"] = outData.ParamBase.Dex,
    ["敏捷"] = outData.ParamBase.Agility,
    ["运气"] = outData.ParamBase.Luck,
    ["物理抗性"] = outData["物理防御"],
    ["以太抗性"] = outData["以太防御"],
    ["暴击率"] = outData["暴击率"],
    ["格挡率"] = outData["格挡率"],
    ["吹飞"] = outData["反应动作抗性"]["吹飞"],
    ["击退"] = outData["反应动作抗性"]["击退"],
    ["破防"] = outData["反应动作抗性"]["破防"],
    ["倒地"] = outData["反应动作抗性"]["倒地"],
    ["浮空"] = outData["反应动作抗性"]["浮空"],
    ["猛击"] = outData["反应动作抗性"]["猛击"]
  }

  return outData
end

function p.singleEnemyContent(data)
  local out = ""
  out = out .. '<div class="flex-wrap">'

  -- 基本信息
  local basicInfo = ""
  if data["分类"] == "任务敌人" then
    local currentTitle = mw.title.getCurrentTitle()
    local quest = {}
    local result = mw.smw.ask {"[[任务敌人::" .. currentTitle.fullText .. "]]"}
    if result then
      for _, v in ipairs(result) do
        table.insert(quest, v[1])
      end
    end

    basicInfo =
      html.wikitable(
      {
        "等级",
        "属性",
        "分类",
        "任务",
        "种族",
        "体型"
      },
      {
        {
          data["等级"] .. (data["等级浮动"] == 0 and "" or " ( +" .. data["等级浮动"] .. " )"),
          data["属性"],
          data["分类"],
          table.concat(quest, "<br>"),
          data["种族"],
          data["体型"]
        }
      },
      {transpose = true}
    )
  else
    basicInfo =
      html.wikitable(
      {
        "等级",
        "属性",
        "分类",
        "种族",
        "体型"
      },
      {
        {
          data["等级"] .. (data["等级浮动"] == 0 and "" or " ( +" .. data["等级浮动"] .. " )"),
          data["属性"],
          data["分类"],
          data["种族"],
          data["体型"]
        }
      },
      {transpose = true}
    )
  end
  local ingoreLv = data.IgnoreLevPow and '<div class="card">无视等级差补正</div>' or ""
  out = out .. "<div>" .. basicInfo .. ingoreLv .. "</div>"

  out =
    out ..
    html.wikitable(
      {
        {scope = "Hp", label = "HP"},
        {scope = "Strength", label = "力量"},
        {scope = "PowEther", label = "以太力"},
        {scope = "Agility", label = "敏捷"},
        {scope = "Dex", label = "灵巧"},
        {scope = "Luck", label = "运气"}
      },
      {data.ParamBase},
      {transpose = true}
    )

  out =
    out ..
    html.wikitable(
      {"物理抗性", "以太抗性", "暴击率", "格挡率"},
      {
        {
          data["物理防御"],
          data["以太防御"],
          data["暴击率"],
          data["格挡率"]
        }
      },
      {transpose = true}
    )

  out =
    out ..
    html.wikitable(
      {
        {scope = "吹飞", label = "吹飞"},
        {scope = "击退", label = "击退"},
        {scope = "破防", label = "破防"},
        {scope = "倒地", label = "倒地"},
        {scope = "浮空", label = "浮空"},
        {scope = "猛击", label = "猛击"}
      },
      {data["反应动作抗性"]},
      {transpose = true}
    )

  if #data.Enhance > 0 then
    out = out .. html.wikitable({"被动能力"}, {{html.ul(data.Enhance)}})
  end

  if data.Aura then
    data.Aura.Name = data.Aura.Name or "愤怒"
    out =
      out ..
      '<div class="card"><div class="title">' ..
        data.Aura.Name ..
          '</div><div class="flex-wrap">' ..
            html.wikitable({"被动能力"}, {{html.ul(data.Aura.Enhance)}}) ..
              html.wikitable({"属性变化"}, {{data.Aura.ChangeAtr}}) .. "</div></div>"
  end
  out = out .. "</div>"

  -- 敌人武技
  if #data.Arts > 0 then
    out = out .. html.h3("武技")
    out =
      out ..
      html.wikitable(
        {
          {scope = "Name", label = "名称"},
          {scope = "ArtsType", label = "类型"},
          {scope = "Target", label = "释放对象"},
          {scope = "RangeType", label = "判定范围"},
          {scope = "DmgMgn", label = "伤害倍率"},
          {scope = "RecastTime", label = "冷却时间"}
        },
        data.Arts,
        {
          width = "100%",
          expandRow = {
            {scope = "Atr", label = "攻击属性"},
            {scope = "Distance", label = "使用距离"},
            {scope = "StartRecast", label = "初始冷却"},
            {scope = "HitRevise", label = "命中修正"},
            {scope = "CriRevise", label = "暴击修正"},
            {scope = "ArtsBuff", label = "技能使用中状态"},
            {scope = "ArtsDeBuff", label = "减益效果"},
            {scope = "Enhance", label = "特效"},
            {scope = "HitText", label = "技能判定"},
            {scope = "Summon", label = "召唤"},
            {scope = "Resist", label = "反应动作无效"}
          },
          expandRowKey = "ID"
        }
      )
  end

  if data.Blade then
    out = out .. html.h3("异刃必杀")
    out =
      out ..
      html.wikitable(
        {
          {scope = "Name", label = "名称"},
          {scope = "ArtsType", label = "类型"},
          {scope = "Target", label = "释放对象"},
          {scope = "RangeType", label = "判定范围"},
          {scope = "DmgMgn", label = "伤害倍率"}
        },
        data.Blade.Arts,
        {
          width = "100%",
          expandRow = {
            {scope = "Atr", label = "攻击属性"},
            {scope = "Distance", label = "使用距离"},
            {scope = "HitRevise", label = "命中修正"},
            {scope = "CriRevise", label = "暴击修正"},
            {scope = "ArtsBuff", label = "技能使用中状态"},
            {scope = "ArtsDeBuff", label = "减益效果"},
            {scope = "Enhance", label = "特效"},
            {scope = "HitText", label = "技能判定"},
            {scope = "Resist", label = "反应动作无效"}
          },
          expandRowKey = "ID"
        }
      )
  end

  -- 击杀奖励
  local dropContent = ""

  local schema
  if data["分类"] == "剧情敌人" or data["分类"] == "珍稀种" then
    schema = {
      {scope = "Item", label = "掉落物品"},
      {scope = "DropProb", label = "概率"},
      {scope = "First", label = "初次"}
    }
  else
    schema = {
      {scope = "Item", label = "掉落物品"},
      {scope = "DropProb", label = "概率"}
    }
  end

  if data["击杀奖励"]["DropItem1"] then
    dropContent = dropContent .. html.wikitable(schema, data["击杀奖励"]["DropItem1"])
  end

  if data["击杀奖励"]["DropItem2"] then
    dropContent = dropContent .. html.wikitable(schema, data["击杀奖励"]["DropItem2"])
  end

  if data["击杀奖励"].PreciousID then
    dropContent = dropContent .. html.wikitable({"贵重品"}, {{data["击杀奖励"].PreciousID}})
  end

  if data["击杀奖励"].EXP > 0 or data["击杀奖励"].Gold > 0 or data["击杀奖励"].WP > 0 or data["击杀奖励"].SP > 0 then
    dropContent =
      dropContent ..
      html.wikitable(
        {
          "EXP",
          "Gold",
          "WP",
          "SP"
        },
        {
          {
            data["击杀奖励"].EXP,
            data["击杀奖励"].Gold,
            data["击杀奖励"].WP,
            data["击杀奖励"].SP
          }
        }
      )
  end

  if #dropContent > 0 then
    out = out .. html.h3("击杀奖励") .. '<div class="flex-wrap">' .. dropContent .. "</div>"
  end

  -- 地图
  if data["分类"] == "打捞敌人" or data["分类"] == "召唤敌人" then
    out = out .. html.h3("出现方式")
    local currentTitle = mw.title.getCurrentTitle()
    local result
    result = mw.smw.ask("[[打捞点:+]][[SalvageEnemyPop::" .. currentTitle.fullText .. "]]|format=ul")
    if result then
      out = out .. html.wikitable({"打捞点"}, result)
    end
    result = mw.smw.ask("[[SummonEnemy::" .. currentTitle.fullText .. "]]")
    if result then
      out = out .. html.wikitable({"召唤"}, result)
    end
  else
    out = out .. html.h3("地图位置")
    out = out .. '<div class="multi-xb2map-enemy" data-enemy-id="' .. data.ID .. '"></div>'
  end

  return out
end

function p.main()
  local out = ""

  local getEnemyId = function(enemy)
    -- 判断enemy输入数字或对象
    local enemyId, enemyTitle
    if type(enemy) == "number" then
      enemyId = enemy
      enemyTitle = enemy
    elseif type(enemy) == "table" then
      enemyId = enemy.id
      enemyTitle = enemy.title
    end
    return enemyId, enemyTitle
  end
  local currentTitle = mw.title.getCurrentTitle()
  local ids = loadJson("EnemyIdMap")[currentTitle.text]
  local filteredIds = {}
  if torna then
    for _, enemy in ipairs(ids) do
      local id = getEnemyId(enemy)
      if id > 1427 and id < 1673 then
        table.insert(filteredIds, enemy)
      end
    end
  else
    for _, enemy in ipairs(ids) do
      local id = getEnemyId(enemy)
      if id < 1427 or id > 1673 then
        table.insert(filteredIds, enemy)
      end
    end
  end

  if #filteredIds > 0 then
    for _, enemy in ipairs(filteredIds) do
      local enemyId, enemyTitle = getEnemyId(enemy)

      local enemyData = p.getDataByEnemyId(enemyId)
      if #filteredIds > 1 then -- 分段落
        out = out .. html.h2(enemyTitle)
      end
      out = out .. p.singleEnemyContent(enemyData)
    end
  end
  return out
end

return p