🌟 | 現在、 鉄壁ヘッドショットには対応済みです。 鉄壁HSは通常HSと同じダメージになります。LMG及びDMR、チャージライフル、ハンマーポイント弾を除き、すべてのダメージ値が一致していることを確認しています。 |
「モジュール:DamageTable」の版間の差分
ナビゲーションに移動
検索に移動
(増幅バリケードを経由する場合の丸め演算が間違っていた問題の修正) |
(ハンマーポイント弾の正式な計算を実装) |
||
1行目: | 1行目: | ||
local p = {} | local p = {} | ||
local aw = require('Module:Utility/Library') | |||
local getArgs -- lazily initialized | local getArgs -- lazily initialized | ||
local function round(num) | local function round(num) | ||
return math.floor(tonumber(string.format("%. | return math.floor(tonumber(string.format("%.4f", num)) + 0.5) | ||
end | end | ||
local function roundover(num) | local function roundover(num) | ||
return math.ceil(tonumber(string.format("%. | return math.ceil(tonumber(string.format("%.4f", num)) - 0.5) | ||
end | end | ||
63行目: | 64行目: | ||
end | end | ||
local function | local function getDamage(part, info) | ||
return math. | local damage = info.damage | ||
-- 増幅バリケード | |||
if info.amped then | |||
damage = round(1.2 * damage) | |||
end | |||
-- ハンマーポイント弾 | |||
if info.hammerpoint > 1 then | |||
damage = round(info.hammerpoint * damage) | |||
end | |||
-- 部位倍率 | |||
if part ~= 1 then | |||
damage = round(part * damage) | |||
end | |||
-- 小柄・鉄壁 | |||
if info.mul == 1.05 and not info.amped then | |||
damage = selectiveRound(info.mul * damage, info.useRound) | |||
elseif info.mul ~= 1 then | |||
damage = round(info.mul * damage) | |||
end | |||
return damage | |||
end | |||
local function getDamageForPartAndPassive(damage, part, info) | |||
-- 部位倍率 | |||
if part ~= 1 then | |||
damage = round(part * damage) | |||
end | |||
-- 小柄・鉄壁 | |||
if info.mul == 1.05 and not info.amped then | |||
damage = selectiveRound(info.mul * damage, info.useRound) | |||
elseif info.mul ~= 1 then | |||
damage = round(info.mul * damage) | |||
end | |||
return damage | |||
end | |||
local function _getShotCount(damage, health, info) | |||
local count = 0 | |||
local damages = {} | |||
local damageStack = 0 | |||
local pelletCount = info.pellet | |||
while health > 0 do | |||
pelletCount = pelletCount - 1 | |||
health = health - damage | |||
damageStack = damageStack + damage | |||
if pelletCount == 0 then | |||
count = count + 1 | |||
pelletCount = info.pellet | |||
table.insert(damages, damageStack) | |||
damageStack = 0 | |||
end | |||
end | |||
if damageStack > 0 then | |||
count = count + 1 | |||
table.insert(damages, damageStack) | |||
end | |||
return count, damages | |||
end | |||
local function _getShotCountForGunShield(info) | |||
local gunshieldinfo = aw.shallowCopy(info) | |||
gunshieldinfo.mul = 1 | |||
gunshieldinfo.hammerpoint = 1 | |||
local damage = getDamage(1, gunshieldinfo) | |||
return _getShotCount(damage, 50, gunshieldinfo) | |||
end | |||
local function _getShotCountForDefault(part, health, info, gunshield) | |||
local damage = getDamage(part, info) | |||
if gunshield then | |||
local gunshieldcount, damages = _getShotCountForGunShield(info) | |||
local count, damages2 = _getShotCount(damage, health, info) | |||
for _, value in ipairs(damages2) do | |||
table.insert(damages, value) | |||
end | |||
return gunshieldcount + count, damages | |||
else | |||
return _getShotCount(damage, health, info) | |||
end | |||
end | |||
local function _getShotCountForHammerpointRounds(ampedDamage, part, health, shield, info, gunshield) | |||
local count = 0 | |||
local damages = {} | |||
local damageStack = 0 | |||
local pelletCount = info.pellet | |||
if gunshield then | |||
count, damages = _getShotCountForGunShield(info) | |||
end | |||
local shieldDamage = getDamageForPartAndPassive(ampedDamage, part, info) | |||
while shield >= shieldDamage do | |||
pelletCount = pelletCount - 1 | |||
shield = shield - shieldDamage | |||
damageStack = damageStack + shieldDamage | |||
if pelletCount == 0 then | |||
count = count + 1 | |||
pelletCount = info.pellet | |||
table.insert(damages, damageStack) | |||
damageStack = 0 | |||
end | |||
end | |||
if shield > 0 then | |||
local mergedDamage | |||
if shield < ampedDamage then | |||
mergedDamage = getDamageForPartAndPassive(shield + math.floor(info.hammerpoint * (ampedDamage - shield)), part, info) | |||
else | |||
mergedDamage = shieldDamage | |||
end | |||
pelletCount = pelletCount - 1 | |||
health = health - (mergedDamage - shield) | |||
damageStack = damageStack + mergedDamage | |||
end | |||
if pelletCount == 0 then | |||
count = count + 1 | |||
pelletCount = info.pellet | |||
table.insert(damages, damageStack) | |||
damageStack = 0 | |||
end | |||
local healthDamage = getDamageForPartAndPassive(round(info.hammerpoint * ampedDamage), part, info) | |||
while health > 0 do | |||
pelletCount = pelletCount - 1 | |||
health = health - healthDamage | |||
damageStack = damageStack + healthDamage | |||
if pelletCount == 0 then | |||
count = count + 1 | |||
pelletCount = info.pellet | |||
table.insert(damages, damageStack) | |||
damageStack = 0 | |||
end | |||
end | |||
if pelletCount > 0 and pelletCount < info.pellet then | |||
count = count + 1 | |||
pelletCount = info.pellet | |||
table.insert(damages, damageStack) | |||
end | |||
return count, damages | |||
end | |||
local function getShotCount(part, health, shield, info, gunshield) | |||
gunshield = gunshield or false | |||
if info.hammerpoint > 1 then | |||
local damage | |||
if info.amped then | |||
damage = round(1.2 * info.damage) | |||
else | |||
damage = info.damage | |||
end | |||
return _getShotCountForHammerpointRounds(damage, part, health, shield, info, gunshield) | |||
else | |||
return _getShotCountForDefault(part, health + shield, info, gunshield) | |||
end | |||
end | |||
local function _arrangeArray(cache, count) | |||
if count > 1 then | |||
return cache .. '×' .. count | |||
else | |||
return cache | |||
end | |||
end | |||
local function arrangeArray(array, separator) | |||
local cache = array[1] | |||
local count = 0 | |||
local output = nil | |||
for _, damage in ipairs(array) do | |||
if cache == damage then | |||
count = count + 1 | |||
else | |||
local text = _arrangeArray(cache, count) | |||
if output ~= nil then | |||
output = output .. separator .. text | |||
else | |||
output = text | |||
end | |||
cache = damage | |||
count = 1 | |||
end | |||
end | |||
local text = _arrangeArray(cache, count) | |||
if output ~= nil then | |||
output = output .. separator .. text | |||
else | |||
output = text | |||
end | |||
return output | |||
end | end | ||
93行目: | 299行目: | ||
end | end | ||
local function renderCell(row, | local function renderCell(row, part, health, shield, info, gunshield) | ||
local shotCount = getShotCount( | local shotCount, damages = getShotCount(part, health, shield, info, gunshield) | ||
local ratio = (shotCount | local ratio = (shotCount - info.minCount) / (info.maxCount - info.minCount) | ||
row:tag('td') | row:tag('td') | ||
:attr('align', 'right') | :attr('align', 'right') | ||
:attr('title', arrangeArray(damages, '→')) | |||
:css('background-color', getColorAsString(0.85 * ratio)) | :css('background-color', getColorAsString(0.85 * ratio)) | ||
:wikitext( | :wikitext(shotCount) | ||
end | end | ||
137行目: | 332行目: | ||
end | end | ||
local function renderRow(table, name, | local function renderRow(table, name, part, weaponinfo, rowinfo, gunshield) | ||
local row = table:tag('tr') | local row = table:tag('tr') | ||
renderHeaderCell(row, name, rowinfo) | renderHeaderCell(row, name, rowinfo) | ||
if pellet > 1 then | local damage | ||
row:tag('td'):attr('align', 'right'):wikitext((damage * pellet) .. ' <span style="white-space:nowrap"><small>(' .. damage .. ' × ' .. pellet .. ')</small></span>') | if gunshield then | ||
if weaponinfo.amped then | |||
damage = round(1.2 * weaponinfo.damage) | |||
else | |||
damage = weaponinfo.damage | |||
end | |||
else | |||
damage = getDamage(part, weaponinfo) | |||
end | |||
if weaponinfo.pellet > 1 then | |||
row:tag('td'):attr('align', 'right'):wikitext((damage * weaponinfo.pellet) .. ' <span style="white-space:nowrap"><small>(' .. damage .. ' × ' .. weaponinfo.pellet .. ')</small></span>') | |||
else | else | ||
row:tag('td'):attr('align', 'right'):wikitext(damage) | row:tag('td'):attr('align', 'right'):wikitext(damage) | ||
end | end | ||
renderCell(row, part, 100, 0, weaponinfo, gunshield) | |||
renderCell(row, part, 70, 50, weaponinfo, gunshield) | |||
renderCell(row, part, 100, 50, weaponinfo, gunshield) | |||
renderCell(row, part, 100, 75, weaponinfo, gunshield) | |||
renderCell(row, part, 100, 100, weaponinfo, gunshield) | |||
renderCell(row, part, 100, 125, weaponinfo, gunshield) | |||
end | end | ||
local function renderTable(args, frame) | local function renderTable(args, frame) | ||
local skullpiercer = args.skullpiercer or 1 | local skullpiercer = args.skullpiercer or 1 | ||
local headMul = args.head or 2 | local headMul = args.head or 2 | ||
local minCount = getShotCount( | local minCount, _ = getShotCount( | ||
local | math.max(headMul, skullpiercer), | ||
100, | |||
0, | |||
{ | |||
damage = math.max(args.damage, args.damagemax), | |||
mul = 1.05, | |||
pellet = args.pellet, | |||
amped = true, | |||
hammerpoint = math.max(args.hammerpoint, args.hammerpointsup), | |||
}) | |||
local damagemin = math.min(args.damage, args.damagemin) | |||
local mininfo = { | |||
damage = damagemin, | |||
mul = 0.85, | |||
pellet = args.pellet, | |||
amped = false, | |||
hammerpoint = 1, | |||
} | |||
local legCount, _ = getShotCount(args.leg, 100, 125, mininfo) | |||
local bodyWithGunSheild, _ = getShotCount(1, 100, 125, mininfo, true) | |||
local maxCount = math.max(legCount, bodyWithGunSheild) | |||
local weaponinfo = { | |||
damage = args.damage, | |||
mul = args.mul, | |||
pellet = args.pellet, | |||
amped = args.amped, | |||
hammerpoint = args.hammerpoint, | |||
minCount = minCount, | |||
maxCount = maxCount, | |||
} | |||
local colspan, info | local colspan, info | ||
if skullpiercer > 1 then | if skullpiercer > 1 then | ||
268行目: | 463行目: | ||
end | end | ||
renderHeader(table, mul, colspan) | renderHeader(table, args.mul, colspan) | ||
if skullpiercer > 1 then | if skullpiercer > 1 then | ||
274行目: | 469行目: | ||
table, | table, | ||
skullpiercerHtml .. '(x' .. skullpiercer .. ')', | skullpiercerHtml .. '(x' .. skullpiercer .. ')', | ||
skullpiercer, weaponinfo, info.level3top) | |||
end | end | ||
281行目: | 475行目: | ||
table, | table, | ||
"頭 (x" .. headMul .. ")", | "頭 (x" .. headMul .. ")", | ||
headMul, weaponinfo, info.level1top) | |||
if skullpiercer > 1 then | if skullpiercer > 1 then | ||
289行目: | 482行目: | ||
table, | table, | ||
skullpiercerHtml .. '<span class="text-rarity text-rarity-common">(x' .. skullpiercerLv1Mul .. ')</span>', | skullpiercerHtml .. '<span class="text-rarity text-rarity-common">(x' .. skullpiercerLv1Mul .. ')</span>', | ||
skullpiercerLv1Mul, weaponinfo, info.level3) | |||
end | end | ||
297行目: | 489行目: | ||
table, | table, | ||
'<span class="text-rarity text-rarity-common">Lv.1 (x' .. hlmLv1Mul .. ')</span>', | '<span class="text-rarity text-rarity-common">Lv.1 (x' .. hlmLv1Mul .. ')</span>', | ||
hlmLv1Mul, weaponinfo, info.level2) | |||
if skullpiercer > 1 then | if skullpiercer > 1 then | ||
305行目: | 496行目: | ||
table, | table, | ||
skullpiercerHtml .. '<span class="text-rarity text-rarity-rare">(x' .. skullpiercerLv2Mul .. ')</span>', | skullpiercerHtml .. '<span class="text-rarity text-rarity-rare">(x' .. skullpiercerLv2Mul .. ')</span>', | ||
skullpiercerLv2Mul, weaponinfo, info.level3) | |||
end | end | ||
313行目: | 503行目: | ||
table, | table, | ||
'<span class="text-rarity text-rarity-rare">Lv.2 (x' .. hlmLv2Mul .. ')</span>', | '<span class="text-rarity text-rarity-rare">Lv.2 (x' .. hlmLv2Mul .. ')</span>', | ||
hlmLv2Mul, weaponinfo, info.level2) | |||
if skullpiercer > 1 then | if skullpiercer > 1 then | ||
321行目: | 510行目: | ||
table, | table, | ||
skullpiercerHtml .. '<span class="text-rarity text-rarity-epic">(x' .. skullpiercerLv3Mul .. ')</span>', | skullpiercerHtml .. '<span class="text-rarity text-rarity-epic">(x' .. skullpiercerLv3Mul .. ')</span>', | ||
skullpiercerLv3Mul, weaponinfo, info.level3) | |||
end | end | ||
329行目: | 517行目: | ||
table, | table, | ||
'<span class="text-rarity text-rarity-epic">Lv.3</span>/<span class="text-rarity text-rarity-legendary">4</span> <span class="text-rarity text-rarity-epic">(x' .. hlmLv3Mul .. ')</span>', | '<span class="text-rarity text-rarity-epic">Lv.3</span>/<span class="text-rarity text-rarity-legendary">4</span> <span class="text-rarity text-rarity-epic">(x' .. hlmLv3Mul .. ')</span>', | ||
hlmLv3Mul, weaponinfo, info.level2) | |||
if legMul == 1 then | if legMul == 1 then | ||
if mul == 0.85 then | if args.mul == 0.85 then | ||
renderRow(table, "胴・脚", | renderRow(table, "胴・脚", 1, weaponinfo, info.level1gunshiled) | ||
renderRow(table, '+ガンシールド', 1, weaponinfo, info.level2gunshiled, true) | |||
else | else | ||
renderRow(table, "胴・脚", | renderRow(table, "胴・脚", 1, weaponinfo, info.level1) | ||
end | end | ||
else | else | ||
if mul == 1.05 then | if args.mul == 1.05 then | ||
renderRow(table, "胴・脚", | renderRow(table, "胴・脚", 1, weaponinfo, info.level1) | ||
else | else | ||
if mul == 0.85 then | if args.mul == 0.85 then | ||
renderRow(table, "胴", | renderRow(table, "胴", 1, weaponinfo, info.level1gunshiled) | ||
renderRow(table, '+ガンシールド', 1, weaponinfo, info.level2gunshiled, true) | |||
else | else | ||
renderRow(table, "胴", | renderRow(table, "胴", 1, weaponinfo, info.level1) | ||
end | end | ||
renderRow( | renderRow(table, "脚 (x" .. args.leg .. ")", args.leg, weaponinfo, info.level1) | ||
end | end | ||
end | end | ||
361行目: | 544行目: | ||
function p._main(args, frame) | function p._main(args, frame) | ||
-- init value | |||
local initValues = { | |||
damage = 20, | |||
damagemin = 1000, | |||
damagemax = 0, | |||
pellet = 1, | |||
head = 2, | |||
leg = 0.8, | |||
mul = 1, | |||
skullpiercer = 1, | |||
hammerpoint = 1, | |||
hammerpointsup = 1, | |||
} | |||
-- fix arguments | |||
for key, value in pairs(initValues) do | |||
args[key] = aw.getAsNumber(args[key], value) | |||
end | |||
args.round = aw.getAsBoolean(args.round, false) | |||
args.amped = aw.getAsBoolean(args.amped, false) | |||
return tostring(renderTable(args, frame)) | return tostring(renderTable(args, frame)) | ||
end | end | ||
369行目: | 573行目: | ||
end | end | ||
args = getArgs(frame) | args = getArgs(frame) | ||
return p._main(args, frame) | return p._main(args, frame) |
2021年2月1日 (月) 18:05時点における版
このモジュールについての説明文ページを モジュール:DamageTable/doc に作成できます
local p = {} local aw = require('Module:Utility/Library') local getArgs -- lazily initialized local function round(num) return math.floor(tonumber(string.format("%.4f", num)) + 0.5) end local function roundover(num) return math.ceil(tonumber(string.format("%.4f", num)) - 0.5) end local function selectiveRound(num, useRound) useRound = useRound or false if useRound then return round(num) else return roundover(num) end end local function convertHslToRgb(hue, saturation, lightness) hue = math.max(0, math.min(1, hue)) saturation = math.max(0, math.min(1, saturation)) lightness = math.max(0, math.min(1, lightness)) if saturation == 0 then return lightness, lightness, lightness else local function to(p, q, t) if t < 0 then t = t + 1 end if t > 1 then t = t - 1 end if t < 1/6 then return p + (q - p) * 6 * t elseif t < 3/6 then return q elseif t < 4/6 then return p + (q - p) * (2/3 - t) * 6 else return p end end local q if lightness < 0.5 then q = lightness * (1 + saturation) else q = lightness + saturation - lightness * saturation end local p = 2 * lightness - q return to(p, q, hue + 1/3), to(p, q, hue), to(p, q, hue - 1/3) end end local function getColorAsString(hue) local r, g, b = convertHslToRgb(hue, 0.91, 0.89) return '#' .. string.format('%02X', 255 * r) .. string.format('%02X', 255 * g) .. string.format('%02X', 255 * b) end local function getDamage(part, info) local damage = info.damage -- 増幅バリケード if info.amped then damage = round(1.2 * damage) end -- ハンマーポイント弾 if info.hammerpoint > 1 then damage = round(info.hammerpoint * damage) end -- 部位倍率 if part ~= 1 then damage = round(part * damage) end -- 小柄・鉄壁 if info.mul == 1.05 and not info.amped then damage = selectiveRound(info.mul * damage, info.useRound) elseif info.mul ~= 1 then damage = round(info.mul * damage) end return damage end local function getDamageForPartAndPassive(damage, part, info) -- 部位倍率 if part ~= 1 then damage = round(part * damage) end -- 小柄・鉄壁 if info.mul == 1.05 and not info.amped then damage = selectiveRound(info.mul * damage, info.useRound) elseif info.mul ~= 1 then damage = round(info.mul * damage) end return damage end local function _getShotCount(damage, health, info) local count = 0 local damages = {} local damageStack = 0 local pelletCount = info.pellet while health > 0 do pelletCount = pelletCount - 1 health = health - damage damageStack = damageStack + damage if pelletCount == 0 then count = count + 1 pelletCount = info.pellet table.insert(damages, damageStack) damageStack = 0 end end if damageStack > 0 then count = count + 1 table.insert(damages, damageStack) end return count, damages end local function _getShotCountForGunShield(info) local gunshieldinfo = aw.shallowCopy(info) gunshieldinfo.mul = 1 gunshieldinfo.hammerpoint = 1 local damage = getDamage(1, gunshieldinfo) return _getShotCount(damage, 50, gunshieldinfo) end local function _getShotCountForDefault(part, health, info, gunshield) local damage = getDamage(part, info) if gunshield then local gunshieldcount, damages = _getShotCountForGunShield(info) local count, damages2 = _getShotCount(damage, health, info) for _, value in ipairs(damages2) do table.insert(damages, value) end return gunshieldcount + count, damages else return _getShotCount(damage, health, info) end end local function _getShotCountForHammerpointRounds(ampedDamage, part, health, shield, info, gunshield) local count = 0 local damages = {} local damageStack = 0 local pelletCount = info.pellet if gunshield then count, damages = _getShotCountForGunShield(info) end local shieldDamage = getDamageForPartAndPassive(ampedDamage, part, info) while shield >= shieldDamage do pelletCount = pelletCount - 1 shield = shield - shieldDamage damageStack = damageStack + shieldDamage if pelletCount == 0 then count = count + 1 pelletCount = info.pellet table.insert(damages, damageStack) damageStack = 0 end end if shield > 0 then local mergedDamage if shield < ampedDamage then mergedDamage = getDamageForPartAndPassive(shield + math.floor(info.hammerpoint * (ampedDamage - shield)), part, info) else mergedDamage = shieldDamage end pelletCount = pelletCount - 1 health = health - (mergedDamage - shield) damageStack = damageStack + mergedDamage end if pelletCount == 0 then count = count + 1 pelletCount = info.pellet table.insert(damages, damageStack) damageStack = 0 end local healthDamage = getDamageForPartAndPassive(round(info.hammerpoint * ampedDamage), part, info) while health > 0 do pelletCount = pelletCount - 1 health = health - healthDamage damageStack = damageStack + healthDamage if pelletCount == 0 then count = count + 1 pelletCount = info.pellet table.insert(damages, damageStack) damageStack = 0 end end if pelletCount > 0 and pelletCount < info.pellet then count = count + 1 pelletCount = info.pellet table.insert(damages, damageStack) end return count, damages end local function getShotCount(part, health, shield, info, gunshield) gunshield = gunshield or false if info.hammerpoint > 1 then local damage if info.amped then damage = round(1.2 * info.damage) else damage = info.damage end return _getShotCountForHammerpointRounds(damage, part, health, shield, info, gunshield) else return _getShotCountForDefault(part, health + shield, info, gunshield) end end local function _arrangeArray(cache, count) if count > 1 then return cache .. '×' .. count else return cache end end local function arrangeArray(array, separator) local cache = array[1] local count = 0 local output = nil for _, damage in ipairs(array) do if cache == damage then count = count + 1 else local text = _arrangeArray(cache, count) if output ~= nil then output = output .. separator .. text else output = text end cache = damage count = 1 end end local text = _arrangeArray(cache, count) if output ~= nil then output = output .. separator .. text else output = text end return output end local function renderHeader(table, mul, colspan) local row = table:tag('tr') local cell = row:tag('th') :attr('colspan', colspan) :attr('rowspan', 2) if mul == 1 then cell:wikitext('部位') else cell:wikitext('部位 (x' .. mul .. ')') end row:tag('th') :attr('rowspan', 2) :wikitext('ダメージ') row:tag('th') :attr('colspan', 6) :wikitext('確殺数') row = table:tag('tr') row:tag('th'):wikitext('100<small> HP</small>') row:tag('th'):wikitext('<span class="text-rarity text-rarity-legendary">120<small> HP</small></span>') row:tag('th'):wikitext('<span class="text-rarity text-rarity-common">150<small> HP</small></span>') row:tag('th'):wikitext('<span class="text-rarity text-rarity-rare">175<small> HP</small></span>') row:tag('th'):wikitext('<span class="text-rarity text-rarity-epic">200<small> HP</small></span>') row:tag('th'):wikitext('<span class="text-rarity text-rarity-heirloom">225<small> HP</small></span>') end local function renderCell(row, part, health, shield, info, gunshield) local shotCount, damages = getShotCount(part, health, shield, info, gunshield) local ratio = (shotCount - info.minCount) / (info.maxCount - info.minCount) row:tag('td') :attr('align', 'right') :attr('title', arrangeArray(damages, '→')) :css('background-color', getColorAsString(0.85 * ratio)) :wikitext(shotCount) end local function renderHeaderCell(row, name, rowinfo) for i = 1, #rowinfo do local cellinfo = rowinfo[i] local colspan = cellinfo.colspan or 1 local cell = row:tag('th') if colspan > 1 then cell:attr('colspan', colspan) end if cellinfo.breaktop then cell:css('border-top', '0 none') end if cellinfo.breakbottom then cell:css('border-bottom', '0 none') end if i == #rowinfo then cell:wikitext(name) else cell:wikitext(' ') end end end local function renderRow(table, name, part, weaponinfo, rowinfo, gunshield) local row = table:tag('tr') renderHeaderCell(row, name, rowinfo) local damage if gunshield then if weaponinfo.amped then damage = round(1.2 * weaponinfo.damage) else damage = weaponinfo.damage end else damage = getDamage(part, weaponinfo) end if weaponinfo.pellet > 1 then row:tag('td'):attr('align', 'right'):wikitext((damage * weaponinfo.pellet) .. ' <span style="white-space:nowrap"><small>(' .. damage .. ' × ' .. weaponinfo.pellet .. ')</small></span>') else row:tag('td'):attr('align', 'right'):wikitext(damage) end renderCell(row, part, 100, 0, weaponinfo, gunshield) renderCell(row, part, 70, 50, weaponinfo, gunshield) renderCell(row, part, 100, 50, weaponinfo, gunshield) renderCell(row, part, 100, 75, weaponinfo, gunshield) renderCell(row, part, 100, 100, weaponinfo, gunshield) renderCell(row, part, 100, 125, weaponinfo, gunshield) end local function renderTable(args, frame) local skullpiercer = args.skullpiercer or 1 local headMul = args.head or 2 local minCount, _ = getShotCount( math.max(headMul, skullpiercer), 100, 0, { damage = math.max(args.damage, args.damagemax), mul = 1.05, pellet = args.pellet, amped = true, hammerpoint = math.max(args.hammerpoint, args.hammerpointsup), }) local damagemin = math.min(args.damage, args.damagemin) local mininfo = { damage = damagemin, mul = 0.85, pellet = args.pellet, amped = false, hammerpoint = 1, } local legCount, _ = getShotCount(args.leg, 100, 125, mininfo) local bodyWithGunSheild, _ = getShotCount(1, 100, 125, mininfo, true) local maxCount = math.max(legCount, bodyWithGunSheild) local weaponinfo = { damage = args.damage, mul = args.mul, pellet = args.pellet, amped = args.amped, hammerpoint = args.hammerpoint, minCount = minCount, maxCount = maxCount, } local colspan, info if skullpiercer > 1 then colspan = 3 info = { level1 = { { breaktop = false, breakbottom = false, colspan = 3 }, }, level1top = { { breaktop = true, breakbottom = true, colspan = 3 }, }, level1gunshiled = { { breaktop = false, breakbottom = true, colspan = 3 }, }, level2 = { { breaktop = true, breakbottom = true }, { breaktop = true, breakbottom = false, colspan = 2 }, }, level2gunshiled = { { breaktop = true, breakbottom = false }, { breaktop = false, breakbottom = false, colspan = 2 }, }, level3 = { { breaktop = true, breakbottom = true }, { breaktop = false, breakbottom = true }, { breaktop = false, breakbottom = false }, }, level3top = { { breaktop = false, breakbottom = true, colspan = 2 }, { breaktop = false, breakbottom = false }, }, } else colspan = 2 info = { level1 = { { breaktop = false, breakbottom = true, colspan = 2 }, }, level1gunshiled = { { breaktop = false, breakbottom = true, colspan = 2 }, }, level2 = { { breaktop = true, breakbottom = true }, { breaktop = false, breakbottom = false }, }, level2gunshiled = { { breaktop = true, breakbottom = false }, { breaktop = false, breakbottom = false }, }, } info.level1top = info.level1 end local skullpiercerHtml if frame ~= nil then skullpiercerHtml = frame:expandTemplate { title = 'Hopup', args = { "スカルピアサーライフリング" }} .. ' ' else skullpiercerHtml = '' end local table = mw.html.create('table') :addClass('wikitable') :addClass('numbertable') if args.caption ~= nil then table:tag('caption') :wikitext(args.caption) end renderHeader(table, args.mul, colspan) if skullpiercer > 1 then renderRow( table, skullpiercerHtml .. '(x' .. skullpiercer .. ')', skullpiercer, weaponinfo, info.level3top) end renderRow( table, "頭 (x" .. headMul .. ")", headMul, weaponinfo, info.level1top) if skullpiercer > 1 then local skullpiercerLv1Mul = 0.2 + 0.8 * skullpiercer renderRow( table, skullpiercerHtml .. '<span class="text-rarity text-rarity-common">(x' .. skullpiercerLv1Mul .. ')</span>', skullpiercerLv1Mul, weaponinfo, info.level3) end local hlmLv1Mul = 0.2 + 0.8 * headMul renderRow( table, '<span class="text-rarity text-rarity-common">Lv.1 (x' .. hlmLv1Mul .. ')</span>', hlmLv1Mul, weaponinfo, info.level2) if skullpiercer > 1 then local skullpiercerLv2Mul = 0.4 + 0.6 * skullpiercer renderRow( table, skullpiercerHtml .. '<span class="text-rarity text-rarity-rare">(x' .. skullpiercerLv2Mul .. ')</span>', skullpiercerLv2Mul, weaponinfo, info.level3) end local hlmLv2Mul = 0.4 + 0.6 * headMul renderRow( table, '<span class="text-rarity text-rarity-rare">Lv.2 (x' .. hlmLv2Mul .. ')</span>', hlmLv2Mul, weaponinfo, info.level2) if skullpiercer > 1 then local skullpiercerLv3Mul = 0.5 + 0.5 * skullpiercer renderRow( table, skullpiercerHtml .. '<span class="text-rarity text-rarity-epic">(x' .. skullpiercerLv3Mul .. ')</span>', skullpiercerLv3Mul, weaponinfo, info.level3) end local hlmLv3Mul = 0.5 + 0.5 * headMul renderRow( table, '<span class="text-rarity text-rarity-epic">Lv.3</span>/<span class="text-rarity text-rarity-legendary">4</span> <span class="text-rarity text-rarity-epic">(x' .. hlmLv3Mul .. ')</span>', hlmLv3Mul, weaponinfo, info.level2) if legMul == 1 then if args.mul == 0.85 then renderRow(table, "胴・脚", 1, weaponinfo, info.level1gunshiled) renderRow(table, '+ガンシールド', 1, weaponinfo, info.level2gunshiled, true) else renderRow(table, "胴・脚", 1, weaponinfo, info.level1) end else if args.mul == 1.05 then renderRow(table, "胴・脚", 1, weaponinfo, info.level1) else if args.mul == 0.85 then renderRow(table, "胴", 1, weaponinfo, info.level1gunshiled) renderRow(table, '+ガンシールド', 1, weaponinfo, info.level2gunshiled, true) else renderRow(table, "胴", 1, weaponinfo, info.level1) end renderRow(table, "脚 (x" .. args.leg .. ")", args.leg, weaponinfo, info.level1) end end return table end function p._main(args, frame) -- init value local initValues = { damage = 20, damagemin = 1000, damagemax = 0, pellet = 1, head = 2, leg = 0.8, mul = 1, skullpiercer = 1, hammerpoint = 1, hammerpointsup = 1, } -- fix arguments for key, value in pairs(initValues) do args[key] = aw.getAsNumber(args[key], value) end args.round = aw.getAsBoolean(args.round, false) args.amped = aw.getAsBoolean(args.amped, false) return tostring(renderTable(args, frame)) end function p.main(frame) if not getArgs then getArgs = require('Module:Arguments').getArgs end args = getArgs(frame) return p._main(args, frame) end return p