| 🌟 | 現在、 鉄壁HSは通常HSと同じダメージになります。LMG及びDMR、チャージライフル、ハンマーポイント弾を除き、すべてのダメージ値が一致していることを確認しています。 |
「モジュール:WeaponInfobox/Duration」の版間の差分
ナビゲーションに移動
検索に移動
(L-スターEMGの改造ローダーの冷却時間に対応) |
(物資投下の際にホップアップ「デュアルシェル」を自動で有効化) |
||
| (同じ利用者による、間の3版が非表示) | |||
| 4行目: | 4行目: | ||
local cfg = mw.loadData('Module:WeaponInfobox/configuration') | local cfg = mw.loadData('Module:WeaponInfobox/configuration') | ||
local attachment = mw.loadData('Module:Stat/Attachment') | local attachment = mw.loadData('Module:Stat/Attachment') | ||
local Hopup = mw.loadData('Module:Stat/Hopup') | |||
local aw = require('Module:Utility/Library') | local aw = require('Module:Utility/Library') | ||
| 43行目: | 44行目: | ||
overheat_cooldown = proto.NumberRange(0), | overheat_cooldown = proto.NumberRange(0), | ||
overheat_cooldown_delay = proto.NumberRange(0), | overheat_cooldown_delay = proto.NumberRange(0), | ||
} | |||
local DualShellProto = { | |||
dual_shell = { | |||
ammo_size_segmented_reload = proto.NumberRange(1), | |||
}, | |||
} | } | ||
| 144行目: | 150行目: | ||
:addClass('intable') | :addClass('intable') | ||
local hasCooldown = proto.validateTypes(stat.time, CooldownProto) | local hasCooldown = proto.validateTypes(stat.time, CooldownProto) | ||
local hasDualShell = Hopup.dual_shell.enabled and proto.validateTypes(stat, DualShellProto) | |||
local colspan, rootOpts, secondOpts, thirdOpts | local colspan, rootOpts, secondOpts, thirdOpts | ||
if hasCooldown or canModdedLoader then | if hasCooldown or hasDualShell or canModdedLoader then | ||
colspan = 3 | colspan = 3 | ||
rootOpts = { colspan = 3 } | rootOpts = { colspan = 3 } | ||
| 207行目: | 214行目: | ||
reloadSegmentConfig, | reloadSegmentConfig, | ||
secondOpts) | secondOpts) | ||
-- [Hop-up] Dual Shell | |||
if hasDualShell then | |||
local virtualBaseAmmoSize = math.ceil(stat.magazine[1] / stat.dual_shell.ammo_size_segmented_reload) | |||
local dualShellBaseTime = calcSegmentedReloadTime(virtualBaseAmmoSize, stat.time) | |||
createMultipleRow( | |||
iu.hopup('dual_shell'), | |||
dualShellBaseTime, | |||
reloadSegmentConfig, | |||
secondOpts) | |||
local virtualLvl1AmmoSize = math.ceil(stat.magazine[2] / stat.dual_shell.ammo_size_segmented_reload) | |||
local dualShellLvl1Time = calcSegmentedReloadTime(virtualLvl1AmmoSize, stat.time) | |||
createMultipleRow( | |||
iu.attachment(magName, 1), | |||
dualShellLvl1Time, | |||
reloadSegmentConfig, | |||
thirdOpts) | |||
local virtualLvl2AmmoSize = math.ceil(stat.magazine[3] / stat.dual_shell.ammo_size_segmented_reload) | |||
local dualShellLvl2Time = calcSegmentedReloadTime(virtualLvl2AmmoSize, stat.time) | |||
createMultipleRow( | |||
iu.attachment(magName, 2), | |||
dualShellLvl2Time, | |||
reloadSegmentConfig, | |||
thirdOpts) | |||
local virtualLvl3AmmoSize = math.ceil(stat.magazine[4] / stat.dual_shell.ammo_size_segmented_reload) | |||
local dualShellLvl3Time = calcSegmentedReloadTime(virtualLvl3AmmoSize, stat.time) | |||
createMultipleRow( | |||
iu.attachment(magName, 3) .. iu.attachment(magName, 4), | |||
dualShellLvl3Time, | |||
reloadSegmentConfig, | |||
thirdOpts) | |||
end | |||
local reloadSegmentConfigOne = { | local reloadSegmentConfigOne = { | ||
| 643行目: | 685行目: | ||
lvl3Time, | lvl3Time, | ||
reloadSegmentConfig) | reloadSegmentConfig) | ||
-- [Hop-up] Dual Shell | |||
if (Hopup.dual_shell.enabled or isSpecial) and proto.validateTypes(stat, DualShellProto) then | |||
local lvl3VirtualAmmoSize = math.ceil(stat.magazine[4] / stat.dual_shell.ammo_size_segmented_reload) | |||
local lvl3DualShellTime = calcSegmentedReloadTime(lvl3VirtualAmmoSize, stat.time) | |||
renderRow( | |||
tbl, | |||
iu.hopup('dual_shell') .. ' ', | |||
lvl3DualShellTime, | |||
reloadSegmentConfig, | |||
secondOpts) | |||
end | |||
local oneTime = calcSegmentedReloadTime(1, stat.time) | local oneTime = calcSegmentedReloadTime(1, stat.time) | ||
| 659行目: | 713行目: | ||
baseTime, | baseTime, | ||
reloadSegmentConfig) | reloadSegmentConfig) | ||
-- [Hop-up] Dual Shell | |||
if (Hopup.dual_shell.enabled or isSpecial) and proto.validateTypes(stat, DualShellProto) then | |||
local virtualAmmoSize = math.ceil(stat.magazine / stat.dual_shell.ammo_size_segmented_reload) | |||
local dualShellTime = calcSegmentedReloadTime(virtualAmmoSize, stat.time) | |||
renderRow( | |||
tbl, | |||
iu.hopup('dual_shell') .. ' ', | |||
dualShellTime, | |||
reloadSegmentConfig, | |||
secondOpts) | |||
end | |||
local oneTime = calcSegmentedReloadTime(1, stat.time) | local oneTime = calcSegmentedReloadTime(1, stat.time) | ||
2022年5月19日 (木) 12:45時点における最新版
このモジュールについての説明文ページを モジュール:WeaponInfobox/Duration/doc に作成できます
require('Module:Utility/mw.html Extensions')
local p = {}
local cfg = mw.loadData('Module:WeaponInfobox/configuration')
local attachment = mw.loadData('Module:Stat/Attachment')
local Hopup = mw.loadData('Module:Stat/Hopup')
local aw = require('Module:Utility/Library')
local iu = require('Module:Utility/Image')
local nu = require('Module:Utility/Name')
local proto = require('Module:Utility/Prototypes')
-- Constants
local leftBorder = {
['border-left-width'] = '1px',
['border-left-style'] = 'solid',
}
local leftBorderWithoutTopRightBorder = {
['border-top'] = '0 none transparent',
['border-right'] = '0 none transparent',
['border-left-width'] = '1px',
['border-left-style'] = 'solid',
}
-- Protos
local ZoomProto = {
zoom_in = proto.NumberRange(0),
zoom_out = proto.NumberRange(0),
}
local MagazineProto = {
proto.NumberRange(0),
proto.NumberRange(0),
proto.NumberRange(0),
proto.NumberRange(0),
}
local SegmentReloadProto = {
reload_segment_loop = proto.NumberRange(0),
reload_segment_end = proto.NumberRange(0),
reload_segment_one = proto.NumberRange(0),
}
local CooldownProto = {
cooldown = proto.NumberRange(0),
cooldown_delay = proto.NumberRange(0),
overheat_cooldown = proto.NumberRange(0),
overheat_cooldown_delay = proto.NumberRange(0),
}
local DualShellProto = {
dual_shell = {
ammo_size_segmented_reload = proto.NumberRange(1),
},
}
-- Duration for multiple value
local function createMultipleRow(name, default, cfg, opts)
opts = opts or {}
local row = cfg.tbl:tag('tr')
if aw.isNumberAndGreaterThanZero(opts.offset) then
for i = 1, opts.offset do
local hasLeftBorder = opts.offsetStyles and opts.offsetStyles[i] and opts.offsetStyles[i].leftBorder
if hasLeftBorder then
row:tag('th')
:css(leftBorderWithoutTopRightBorder)
:wikitext(' ')
else
row:tag('th')
:css('border', '0 none transparent')
:wikitext(' ')
end
end
end
row:tag('th')
:attrIf(aw.isNumber(opts.colspan), { colspan = opts.colspan })
:cssIf(aw.isNumberAndGreaterThanZero(opts.offset), leftBorder)
:wikitext(name)
if not cfg.isLegendary then
row
:tag('td')
:addClass('cell-type-number')
:attr('align', 'right')
:wikitext(string.format(cfg.fmt, default))
:done()
if cfg.muls then
row
:tag('td')
:addClass('cell-type-number')
:attr('align', 'right')
:tag('span')
:addClass('text-rarity')
:addClass('text-rarity-common')
:wikitext(string.format(cfg.fmt, cfg.muls[1] * default))
:done()
:done()
:tag('td')
:addClass('cell-type-number')
:attr('align', 'right')
:tag('span')
:addClass('text-rarity')
:addClass('text-rarity-rare')
:wikitext(string.format(cfg.fmt, cfg.muls[2] * default))
:done()
:done()
:tag('td')
:addClass('cell-type-number')
:attr('align', 'right')
:tag('span')
:addClass('text-rarity')
:addClass('text-rarity-epic')
:wikitext(string.format(cfg.fmt, cfg.muls[3] * default))
:done()
:done()
else
row:tag('td')
:addClass('disabled')
:attr('align', 'center')
:attr('colspan', 3)
:wikitext(cfg.res.na)
end
else
row
:tag('td')
:addClass('cell-type-number')
:attr('align', 'right')
:attr('colspan', 4)
:tag('span')
:addClass('text-rarity')
:addClass('text-rarity-legendary')
:wikitext(string.format(cfg.fmt, default))
:done()
:done()
end
return row
end
local function calcSegmentedReloadTime(rounds, time)
if rounds <= 1 then
return time.reload_segment_one
else
return (rounds - 1) * time.reload_segment_loop + time.reload_segment_end
end
end
local function renderDurationWithStock(stat, duration, stock, canModdedLoader, isSniper)
local tbl = mw.html.create('table')
:addClass('intable')
local hasCooldown = proto.validateTypes(stat.time, CooldownProto)
local hasDualShell = Hopup.dual_shell.enabled and proto.validateTypes(stat, DualShellProto)
local colspan, rootOpts, secondOpts, thirdOpts
if hasCooldown or hasDualShell or canModdedLoader then
colspan = 3
rootOpts = { colspan = 3 }
secondOpts = { colspan = 2, offset = 1 }
thirdOpts = { offset = 2, offsetStyles = { nil, { leftBorder = true } } }
else
colspan = 2
rootOpts = { colspan = 2 }
secondOpts = { offset = 1 }
end
-- Header
local stockName = isSniper and 'スナイパーストック' or '標準ストック'
tbl:tag('tr')
:tag('th')
:attr('colspan', colspan)
:wikitext(name)
:done()
:tag('th'):done()
:tag('th'):wikitext(iu.attachment(stockName, 1)):done()
:tag('th'):wikitext(iu.attachment(stockName, 2)):done()
:tag('th'):wikitext(iu.attachment(stockName, 3))
-- Segmented Reload
if proto.validateTypes(stat.time, SegmentReloadProto) then
local reloadSegmentConfig = {
fmt = duration.reload.format,
tbl = tbl,
muls = stock.reload_segment,
res = duration,
}
if proto.validateTypes(stat.magazine, MagazineProto) then
local magName = nu.extmag(stat.ammo, 'ja')
local baseTime = calcSegmentedReloadTime(stat.magazine[1], stat.time)
createMultipleRow(
duration.reload.name,
baseTime,
reloadSegmentConfig,
rootOpts)
local lvl1Time = calcSegmentedReloadTime(stat.magazine[2], stat.time)
createMultipleRow(
iu.attachment(magName, 1),
lvl1Time,
reloadSegmentConfig,
secondOpts)
local lvl2Time = calcSegmentedReloadTime(stat.magazine[3], stat.time)
createMultipleRow(
iu.attachment(magName, 2),
lvl2Time,
reloadSegmentConfig,
secondOpts)
local lvl3Time = calcSegmentedReloadTime(stat.magazine[4], stat.time)
createMultipleRow(
iu.attachment(magName, 3) .. iu.attachment(magName, 4),
lvl3Time,
reloadSegmentConfig,
secondOpts)
-- [Hop-up] Dual Shell
if hasDualShell then
local virtualBaseAmmoSize = math.ceil(stat.magazine[1] / stat.dual_shell.ammo_size_segmented_reload)
local dualShellBaseTime = calcSegmentedReloadTime(virtualBaseAmmoSize, stat.time)
createMultipleRow(
iu.hopup('dual_shell'),
dualShellBaseTime,
reloadSegmentConfig,
secondOpts)
local virtualLvl1AmmoSize = math.ceil(stat.magazine[2] / stat.dual_shell.ammo_size_segmented_reload)
local dualShellLvl1Time = calcSegmentedReloadTime(virtualLvl1AmmoSize, stat.time)
createMultipleRow(
iu.attachment(magName, 1),
dualShellLvl1Time,
reloadSegmentConfig,
thirdOpts)
local virtualLvl2AmmoSize = math.ceil(stat.magazine[3] / stat.dual_shell.ammo_size_segmented_reload)
local dualShellLvl2Time = calcSegmentedReloadTime(virtualLvl2AmmoSize, stat.time)
createMultipleRow(
iu.attachment(magName, 2),
dualShellLvl2Time,
reloadSegmentConfig,
thirdOpts)
local virtualLvl3AmmoSize = math.ceil(stat.magazine[4] / stat.dual_shell.ammo_size_segmented_reload)
local dualShellLvl3Time = calcSegmentedReloadTime(virtualLvl3AmmoSize, stat.time)
createMultipleRow(
iu.attachment(magName, 3) .. iu.attachment(magName, 4),
dualShellLvl3Time,
reloadSegmentConfig,
thirdOpts)
end
local reloadSegmentConfigOne = {
fmt = duration.reloadsegmentone.format,
tbl = tbl,
muls = stock.reload_segment,
res = duration,
}
local oneTime = calcSegmentedReloadTime(1, stat.time)
createMultipleRow(
duration.reloadsegmentone.name,
oneTime,
reloadSegmentConfigOne,
rootOpts)
end
-- Cooldown
elseif hasCooldown then
local cooldownOverheatConfig = {
fmt = duration.cooldownoverheat.format,
tbl = tbl,
muls = stock.reload,
res = duration,
}
local overheatedTime = stat.time.overheat_cooldown + stat.time.overheat_cooldown_delay
createMultipleRow(
duration.cooldownoverheat.name,
overheatedTime,
cooldownOverheatConfig,
rootOpts)
-- [Passive] Modded Loader
if canModdedLoader then
local moddedLoaderOverheatedTime = stat.time.overheat_cooldown * 0.75 + stat.time.overheat_cooldown_delay
createMultipleRow(
iu.passive('modded_loader'),
moddedLoaderOverheatedTime,
cooldownOverheatConfig,
secondOpts)
end
local cooldownConfig = {
fmt = duration.cooldown.format,
tbl = tbl,
muls = stock.reload,
res = duration,
}
local baseTime = stat.time.cooldown + stat.time.cooldown_delay
local moddedLoaderTime = stat.time.cooldown * 0.75 + stat.time.cooldown_delay
for _, rate in ipairs(duration.cooldown.rates) do
createMultipleRow(
string.format(duration.cooldown.name, 100 * rate),
rate * baseTime,
cooldownConfig,
secondOpts)
-- [Passive] Modded Loader
if canModdedLoader then
createMultipleRow(
iu.passive('modded_loader'),
rate * moddedLoaderTime,
cooldownConfig,
thirdOpts)
end
end
-- Reload
elseif aw.isNumber(stat.time.reload) then
local reloadConfig = {
fmt = duration.reload.format,
tbl = tbl,
muls = stock.reload,
res = duration,
}
createMultipleRow(duration.reload.name, stat.time.reload, reloadConfig, rootOpts)
-- [Passive] Modded Loader
if canModdedLoader then
createMultipleRow(
iu.passive('modded_loader'),
stat.time.reload * 0.75,
reloadConfig,
secondOpts)
end
-- [Hop-up] Boosted Loader
if stat.boosted_loader and aw.isNumberAndGreaterThanZero(stat.boosted_loader.reloadfast) then
local reloadFastConfig = {
fmt = duration.reload.format,
tbl = tbl,
res = duration,
isLegendary = true,
}
createMultipleRow(
iu.hopup('boosted_loader'),
stat.boosted_loader.reloadfast,
reloadFastConfig,
secondOpts)
end
-- [Hop-up] Splatter Rounds
local reloadSplatterConfig = {
fmt = duration.reload.format,
tbl = tbl,
res = duration,
isLegendary = true,
}
createMultipleRow(
iu.hopup('splatter_rounds'),
stat.time.reload * stock.reload[3] * 0.75,
reloadSplatterConfig,
secondOpts)
-- [Passive] Modded Loader & [Hop-up] Splatter Rounds
if canModdedLoader then
createMultipleRow(
iu.passive('modded_loader'),
stat.time.reload * stock.reload[3] * 0.5625,
reloadSplatterConfig,
thirdOpts)
end
-- Reload (Empty)
if aw.isNumber(stat.time.reloadempty) and stat.time.reload ~= stat.time.reloadempty then
local reloadEmptyConfig = {
fmt = duration.reloadempty.format,
tbl = tbl,
muls = stock.reload,
res = duration,
}
createMultipleRow(duration.reloadempty.name, stat.time.reloadempty, reloadEmptyConfig, rootOpts)
-- [Passive] Modded Loader
if canModdedLoader then
createMultipleRow(
iu.passive('modded_loader'),
stat.time.reloadempty * 0.75,
reloadEmptyConfig,
secondOpts)
end
-- [Hop-up] Splatter Rounds
local reloadEmptySplatterConfig = {
fmt = duration.reloadempty.format,
tbl = tbl,
res = duration,
isLegendary = true,
}
createMultipleRow(
iu.hopup('splatter_rounds'),
stat.time.reloadempty * stock.reload[3] * 0.75,
reloadEmptySplatterConfig,
secondOpts)
-- [Passive] Modded Loader & [Hop-up] Splatter Rounds
if canModdedLoader then
createMultipleRow(
iu.passive('modded_loader'),
stat.time.reloadempty * stock.reload[3] * 0.5625,
reloadEmptySplatterConfig,
thirdOpts)
end
end
end
-- Deploy
if aw.isNumber(stat.time.draw) then
local deployConfig = {
fmt = duration.deploy.format,
tbl = tbl,
muls = stock.change,
res = duration,
}
createMultipleRow(duration.deploy.name, stat.time.draw, deployConfig, rootOpts)
if aw.isNumber(stat.time.deployfirst) then
local deployFirstConfig = {
fmt = duration.deploy.format,
tbl = tbl,
muls = nil,
res = duration,
}
createMultipleRow(duration.deployfirst.name, stat.time.deployfirst, deployFirstConfig, secondOpts)
end
end
-- Holster
if aw.isNumber(stat.time.holster) then
local holsterConfig = {
fmt = duration.holster.format,
tbl = tbl,
muls = stock.change,
res = duration,
}
createMultipleRow(duration.holster.name, stat.time.holster, holsterConfig, rootOpts)
end
-- Raise
if aw.isNumber(stat.time.upper) then
local raiseConfig = {
fmt = duration.raise.format,
tbl = tbl,
muls = stock.raise,
res = duration,
}
createMultipleRow(duration.raise.name, stat.time.upper, raiseConfig, rootOpts)
end
-- Lower
if aw.isNumber(stat.time.lower) then
local lowerConfig = {
fmt = duration.lower.format,
tbl = tbl,
muls = stock.lower,
res = duration,
}
createMultipleRow(duration.lower.name, stat.time.lower, lowerConfig, rootOpts)
end
-- Zoom In
if aw.isNumber(stat.time.zoom_in) then
local zoomInConfig = {
fmt = duration.zoomin.format,
tbl = tbl,
muls = stock.zoom,
res = duration,
}
createMultipleRow(duration.zoomin.name, stat.time.zoom_in, zoomInConfig, rootOpts)
-- HCOG Classic/Bruiser, Holosight, 1x Digital Threat
if proto.validateTypes(stat.time.hcog_classic, ZoomProto) then
local label
if proto.validateTypes(stat.time.threat, ZoomProto) then
label = iu.scope('1倍HCOG\'クラシック\'') .. iu.scope('2倍HCOG\'ブルーザー\'') .. iu.scope('1倍ホロサイト') .. iu.scope('1~2倍可変式ホロサイト') .. iu.scope('1倍デジタルスレット')
else
label = iu.scope('1倍HCOG\'クラシック\'') .. iu.scope('2倍HCOG\'ブルーザー\'') .. '<br>' .. iu.scope('1倍ホロサイト') .. iu.scope('1~2倍可変式ホロサイト')
end
createMultipleRow(label, stat.time.hcog_classic.zoom_in, zoomInConfig, secondOpts)
end
-- 3x HCOG 'Ranger', 2x-4x Variable AOG
if proto.validateTypes(stat.time.hcog_ranged, ZoomProto) then
if proto.validateTypes(stat.time.aog_variable, ZoomProto) then
if stat.time.hcog_ranged.zoom_in ~= stat.time.aog_variable.zoom_in then
createMultipleRow(
iu.scope('3倍HCOG\'レンジャー\''),
stat.time.hcog_ranged.zoom_in,
zoomInConfig,
secondOpts)
createMultipleRow(
iu.scope('2~4倍可変式AOG'),
stat.time.aog_variable.zoom_in,
zoomInConfig,
secondOpts)
else
createMultipleRow(
iu.scope('3倍HCOG\'レンジャー\'') .. iu.scope('2~4倍可変式AOG'),
stat.time.hcog_ranged.zoom_in,
zoomInConfig,
secondOpts)
end
else
createMultipleRow(
iu.scope('3倍HCOG\'レンジャー\''),
stat.time.hcog_ranged.zoom_in,
zoomInConfig,
secondOpts)
end
end
-- 6x Sniper Scope
if proto.validateTypes(stat.time.sniper, ZoomProto) then
createMultipleRow(
iu.scope('6倍スナイパー'),
stat.time.sniper.zoom_in,
zoomInConfig,
secondOpts)
end
-- 4x-8x Variable Sniper Scope
if proto.validateTypes(stat.time.sniper_variable, ZoomProto) then
createMultipleRow(
iu.scope('4~8倍可変式スナイパー'),
stat.time.sniper_variable.zoom_in,
zoomInConfig,
secondOpts)
end
-- 4x-10x Digital Sniper Threat
if proto.validateTypes(stat.time.sniper_threat, ZoomProto) then
createMultipleRow(
iu.scope('4~10倍デジタルスレット'),
stat.time.sniper_threat.zoom_in,
zoomInConfig,
secondOpts)
end
end
-- Zoom Out
if aw.isNumber(stat.time.zoom_out) then
local zoomOutConfig = {
fmt = duration.zoomout.format,
tbl = tbl,
muls = stock.zoom,
res = duration,
}
createMultipleRow(duration.zoomout.name, stat.time.zoom_out, zoomOutConfig, rootOpts)
-- HCOG Classic/Bruiser, Holosight, 1x Digital Threat
if proto.validateTypes(stat.time.hcog_classic, ZoomProto) then
local label
if proto.validateTypes(stat.time.threat, ZoomProto) then
label = iu.scope('1倍HCOG\'クラシック\'') .. iu.scope('2倍HCOG\'ブルーザー\'') .. iu.scope('1倍ホロサイト') .. iu.scope('1~2倍可変式ホロサイト') .. iu.scope('1倍デジタルスレット')
else
label = iu.scope('1倍HCOG\'クラシック\'') .. iu.scope('2倍HCOG\'ブルーザー\'') .. '<br>' .. iu.scope('1倍ホロサイト') .. iu.scope('1~2倍可変式ホロサイト')
end
createMultipleRow(
label,
stat.time.hcog_classic.zoom_out,
zoomOutConfig,
secondOpts)
end
-- 3x HCOG 'Ranger', 2x-4x Variable AOG
if proto.validateTypes(stat.time.hcog_ranged, ZoomProto) then
if proto.validateTypes(stat.time.aog_variable, ZoomProto) then
if stat.time.hcog_ranged.zoom_out ~= stat.time.aog_variable.zoom_out then
createMultipleRow(
iu.scope('3倍HCOG\'レンジャー\''),
stat.time.hcog_ranged.zoom_out,
zoomOutConfig,
secondOpts)
createMultipleRow(
iu.scope('2~4倍可変式AOG'),
stat.time.aog_variable.zoom_out,
zoomOutConfig,
secondOpts)
else
createMultipleRow(
iu.scope('3倍HCOG\'レンジャー\'') .. iu.scope('2~4倍可変式AOG'),
stat.time.hcog_ranged.zoom_out,
zoomOutConfig,
secondOpts)
end
else
createMultipleRow(
iu.scope('3倍HCOG\'レンジャー\''),
stat.time.hcog_ranged.zoom_out,
zoomOutConfig,
secondOpts)
end
end
-- 6x Sniper Scope
if proto.validateTypes(stat.time.sniper, ZoomProto) then
createMultipleRow(
iu.scope('6倍スナイパー'),
stat.time.sniper.zoom_out,
zoomOutConfig,
secondOpts)
end
-- 4x-8x Variable Sniper Scope
if proto.validateTypes(stat.time.sniper_variable, ZoomProto) then
createMultipleRow(
iu.scope('4~8倍可変式スナイパー'),
stat.time.sniper_variable.zoom_out,
zoomOutConfig,
secondOpts)
end
-- 4x-10x Digital Sniper Threat
if proto.validateTypes(stat.time.sniper_threat, ZoomProto) then
createMultipleRow(
iu.scope('4~10倍デジタルスレット'),
stat.time.sniper_threat.zoom_out,
zoomOutConfig,
secondOpts)
end
end
return tbl
end
-- Duration for single value
local function renderRow(tbl, name, num, cfg, opts)
opts = opts or {}
if cfg.isSpecial and cfg.muls then
num = num * cfg.muls[3]
end
local row = tbl:tag('tr')
:addClassIf(opts.class and type(opts.class) == 'string', opts.class)
:attr('role', 'listitem')
:tag('th')
:attrIf(opts.headerAlign and type(opts.headerAlign) == 'string', { align = opts.headerAlign })
:wikitext(name)
:done()
:tag('td')
:addClass('cell-type-number')
:attr('align', 'left')
:wikitext(string.format(cfg.fmt, num))
:done()
:tag('td')
:attr('align', 'left')
:wikitext(cfg.unit)
:done()
return row
end
local function renderDurationWithoutStock(stat, duration, stock, canModdedLoader, isSpecial)
local secondOpts = { class = 'no-list-style', headerAlign = 'right' }
local tbl = mw.html.create('table')
:addClass('condensedtable')
:addClass('listtable')
:attr('role', 'list')
-- Segmented Reload
if proto.validateTypes(stat.time, SegmentReloadProto) then
local reloadSegmentConfig = {
fmt = duration.reload.format,
muls = stock.reload_segment,
unit = duration.reload.unit,
isSpecial = isSpecial,
}
-- with Mags
if proto.validateTypes(stat.magazine, MagazineProto) then
local lvl3Time = calcSegmentedReloadTime(stat.magazine[4], stat.time)
renderRow(
tbl,
duration.reload.name .. ' ',
lvl3Time,
reloadSegmentConfig)
-- [Hop-up] Dual Shell
if (Hopup.dual_shell.enabled or isSpecial) and proto.validateTypes(stat, DualShellProto) then
local lvl3VirtualAmmoSize = math.ceil(stat.magazine[4] / stat.dual_shell.ammo_size_segmented_reload)
local lvl3DualShellTime = calcSegmentedReloadTime(lvl3VirtualAmmoSize, stat.time)
renderRow(
tbl,
iu.hopup('dual_shell') .. ' ',
lvl3DualShellTime,
reloadSegmentConfig,
secondOpts)
end
local oneTime = calcSegmentedReloadTime(1, stat.time)
renderRow(
tbl,
duration.reloadsegmentone.name .. ' ',
oneTime,
reloadSegmentConfig)
-- without Mags
elseif aw.isNumber(stat.magazine) then
local baseTime = calcSegmentedReloadTime(stat.magazine, stat.time)
renderRow(
tbl,
duration.reload.name .. ' ',
baseTime,
reloadSegmentConfig)
-- [Hop-up] Dual Shell
if (Hopup.dual_shell.enabled or isSpecial) and proto.validateTypes(stat, DualShellProto) then
local virtualAmmoSize = math.ceil(stat.magazine / stat.dual_shell.ammo_size_segmented_reload)
local dualShellTime = calcSegmentedReloadTime(virtualAmmoSize, stat.time)
renderRow(
tbl,
iu.hopup('dual_shell') .. ' ',
dualShellTime,
reloadSegmentConfig,
secondOpts)
end
local oneTime = calcSegmentedReloadTime(1, stat.time)
renderRow(
tbl,
duration.reloadsegmentone.name .. ' ',
oneTime,
reloadSegmentConfig)
end
-- Reload
elseif aw.isNumber(stat.time.reload) then
local reloadConfig = {
fmt = duration.reload.format,
muls = stock.reload,
unit = duration.reload.unit,
isSpecial = isSpecial,
}
renderRow(
tbl,
duration.reload.name .. ' ',
stat.time.reload,
reloadConfig)
if canModdedLoader then
renderRow(
tbl,
iu.passive('modded_loader') .. ' ',
stat.time.reload * 0.75,
reloadConfig,
secondOpts)
end
if stat.boosted_loader and aw.isNumberAndGreaterThanZero(stat.boosted_loader.reloadfast) then
renderRow(
tbl,
iu.hopup('boosted_loader') .. ' ',
stat.boosted_loader.reloadfast,
reloadConfig,
secondOpts)
end
if not isSpecial then
-- [Hop-up] Splatter Rounds
local reloadSplatterConfig = {
fmt = duration.reload.format,
unit = duration.reload.unit,
}
renderRow(
tbl,
iu.hopup('splatter_rounds') .. ' ',
stat.time.reload * 0.75,
reloadSplatterConfig,
secondOpts)
end
-- Reload (Empty)
if aw.isNumber(stat.time.reloadempty) and stat.time.reload ~= stat.time.reloadempty then
local reloademptyConfig = {
fmt = duration.reloadempty.format,
muls = stock.reload,
unit = duration.reloadempty.unit,
isSpecial = isSpecial,
}
renderRow(
tbl,
duration.reloadempty.name .. ' ',
stat.time.reloadempty,
reloademptyConfig)
if canModdedLoader then
renderRow(
tbl,
iu.passive('modded_loader') .. ' ',
stat.time.reloadempty * 0.75,
reloademptyConfig,
secondOpts)
end
if not isSpecial then
-- [Hop-up] Splatter Rounds
local reloademptySplatterConfig = {
fmt = duration.reloadempty.format,
unit = duration.reloadempty.unit,
}
renderRow(
tbl,
iu.hopup('splatter_rounds') .. ' ',
stat.time.reloadempty * 0.75,
reloademptySplatterConfig,
secondOpts)
end
end
end
-- Deploy
if aw.isNumber(stat.time.draw) then
local deployConfig = {
fmt = duration.deploy.format,
muls = stock.change,
unit = duration.deploy.unit,
isSpecial = isSpecial,
}
renderRow(
tbl,
duration.deploy.name .. ' ',
stat.time.draw,
deployConfig)
if aw.isNumber(stat.time.deployfirst) then
local deployFirstConfig = {
fmt = duration.deployfirst.format,
unit = duration.deployfirst.unit,
isSpecial = isSpecial,
}
renderRow(
tbl,
duration.deployfirst.name .. ' ',
stat.time.deployfirst,
deployFirstConfig,
secondOpts)
end
end
-- Holster
if aw.isNumber(stat.time.holster) then
local holsterConfig = {
fmt = duration.holster.format,
muls = stock.change,
unit = duration.holster.unit,
isSpecial = isSpecial,
}
renderRow(
tbl,
duration.holster.name .. ' ',
stat.time.holster,
holsterConfig)
end
-- Raise
if aw.isNumber(stat.time.upper) then
local raiseConfig = {
fmt = duration.raise.format,
muls = stock.raise,
unit = duration.raise.unit,
isSpecial = isSpecial,
}
renderRow(
tbl,
duration.raise.name .. ' ',
stat.time.upper,
raiseConfig)
end
-- Lower
if aw.isNumber(stat.time.lower) then
local lowerConfig = {
fmt = duration.lower.format,
muls = stock.lower,
unit = duration.lower.unit,
isSpecial = isSpecial,
}
renderRow(
tbl,
duration.lower.name .. ' ',
stat.time.lower,
lowerConfig)
end
-- Zoom In
if aw.isNumber(stat.time.zoom_in) then
local zoominConfig = {
fmt = duration.zoomin.format,
muls = stock.zoom,
unit = duration.zoomin.unit,
isSpecial = isSpecial,
}
renderRow(
tbl,
duration.zoomin.name .. ' ',
stat.time.zoom_in,
zoominConfig)
-- HCOG Classic/Bruiser, Holosight, 1x Digital Threat
if proto.validateTypes(stat.time.hcog_classic, ZoomProto) and stat.time.hcog_classic.zoom_in ~= stat.time.zoom_in then
local label
if proto.validateTypes(stat.time.threat, ZoomProto) then
label = duration.without_standard_scope
else
label = iu.scope('1倍HCOG\'クラシック\'') .. iu.scope('2倍HCOG\'ブルーザー\'') .. iu.scope('1倍ホロサイト') .. iu.scope('1~2倍可変式ホロサイト')
end
renderRow(
tbl,
label .. ' ',
stat.time.hcog_classic.zoom_in,
zoominConfig,
secondOpts)
end
-- 3x HCOG 'Ranger', 2x-4x Variable AOG
if proto.validateTypes(stat.time.hcog_ranged, ZoomProto) then
if proto.validateTypes(stat.time.aog_variable, ZoomProto) then
if stat.time.hcog_ranged.zoom_in ~= stat.time.aog_variable.zoom_in then
renderRow(
tbl,
iu.scope('3倍HCOG\'レンジャー\'') .. ' ',
stat.time.hcog_ranged.zoom_in,
zoominConfig,
secondOpts)
renderRow(
tbl,
iu.scope('2~4倍可変式AOG') .. ' ',
stat.time.aog_variable.zoom_in,
zoominConfig,
secondOpts)
else
renderRow(
tbl,
iu.scope('3倍HCOG\'レンジャー\'') .. iu.scope('2~4倍可変式AOG') .. ' ',
stat.time.hcog_ranged.zoom_in,
zoominConfig,
secondOpts)
end
elseif stat.time.hcog_ranged.zoom_in ~= stat.time.zoom_in then
renderRow(
tbl,
iu.scope('3倍HCOG\'レンジャー\'') .. ' ',
stat.time.hcog_ranged.zoom_in,
zoominConfig,
secondOpts)
end
end
-- 6x Sniper Scope
if proto.validateTypes(stat.time.sniper, ZoomProto) then
renderRow(
tbl,
iu.scope('6倍スナイパー') .. ' ',
stat.time.sniper.zoom_in,
zoominConfig,
secondOpts)
end
-- 4x-8x Variable Sniper Scope
if proto.validateTypes(stat.time.sniper_variable, ZoomProto) then
renderRow(
tbl,
iu.scope('4~8倍可変式スナイパー') .. ' ',
stat.time.sniper_variable.zoom_in,
zoominConfig,
secondOpts)
end
-- 4x-10x Digital Sniper Threat
if proto.validateTypes(stat.time.sniper_threat, ZoomProto) then
renderRow(
tbl,
iu.scope('4~10倍デジタルスレット') .. ' ',
stat.time.sniper_threat.zoom_in,
zoominConfig,
secondOpts)
end
end
-- Zoom Out
if aw.isNumber(stat.time.zoom_out) then
local zoomoutConfig = {
fmt = duration.zoomout.format,
muls = stock.zoom,
unit = duration.zoomout.unit,
isSpecial = isSpecial,
}
renderRow(
tbl,
duration.zoomout.name .. ' ',
stat.time.zoom_out,
zoomoutConfig)
-- HCOG Classic/Bruiser, Holosight, 1x Digital Threat
if proto.validateTypes(stat.time.hcog_classic, ZoomProto) and stat.time.hcog_classic.zoom_out ~= stat.time.zoom_out then
local label
if proto.validateTypes(stat.time.threat, ZoomProto) then
label = duration.without_standard_scope
else
label = iu.scope('1倍HCOG\'クラシック\'') .. iu.scope('2倍HCOG\'ブルーザー\'') .. iu.scope('1倍ホロサイト') .. iu.scope('1~2倍可変式ホロサイト')
end
renderRow(
tbl,
label .. ' ',
stat.time.hcog_classic.zoom_out,
zoomoutConfig,
secondOpts)
end
-- 3x HCOG 'Ranger', 2x-4x Variable AOG
if proto.validateTypes(stat.time.hcog_ranged, ZoomProto) then
if proto.validateTypes(stat.time.aog_variable, ZoomProto) then
if stat.time.hcog_ranged.zoom_out ~= stat.time.aog_variable.zoom_out then
renderRow(
tbl,
iu.scope('3倍HCOG\'レンジャー\'') .. ' ',
stat.time.hcog_ranged.zoom_out,
zoomoutConfig,
secondOpts)
renderRow(
tbl,
iu.scope('2~4倍可変式AOG') .. ' ',
stat.time.aog_variable.zoom_out,
zoomoutConfig,
secondOpts)
else
renderRow(
tbl,
iu.scope('3倍HCOG\'レンジャー\'') .. iu.scope('2~4倍可変式AOG') .. ' ',
stat.time.hcog_ranged.zoom_out,
zoomoutConfig,
secondOpts)
end
elseif stat.time.hcog_ranged.zoom_out ~= stat.time.zoom_out then
renderRow(
tbl,
iu.scope('3倍HCOG\'レンジャー\'') .. ' ',
stat.time.hcog_ranged.zoom_out,
zoomoutConfig,
secondOpts)
end
end
-- 6x Sniper Scope
if proto.validateTypes(stat.time.sniper, ZoomProto) then
renderRow(
tbl,
iu.scope('6倍スナイパー') .. ' ',
stat.time.sniper.zoom_out,
zoomoutConfig,
secondOpts)
end
-- 4x-8x Variable Sniper Scope
if proto.validateTypes(stat.time.sniper_variable, ZoomProto) then
renderRow(
tbl,
iu.scope('4~8倍可変式スナイパー') .. ' ',
stat.time.sniper_variable.zoom_out,
zoomoutConfig,
secondOpts)
end
-- 4x-10x Digital Sniper Threat
if proto.validateTypes(stat.time.sniper_threat, ZoomProto) then
renderRow(
tbl,
iu.scope('4~10倍デジタルスレット') .. ' ',
stat.time.sniper_threat.zoom_out,
zoomoutConfig,
secondOpts)
end
end
return tbl
end
function p.renderDuration(stat, lang)
local duration = cfg[lang].duration
local isSniper = stat.category == 'sniper' or stat.category == 'marksman_weapon'
local stock
if isSniper then
stock = attachment.sniper_stock
else
stock = attachment.standard_stock
end
local canModdedLoader = stat.category == 'light_machine_gun' or stat.ammo == 'minigun'
local isSpecial = aw.stringstarts(stat.ammo, 'special_') and not (stat.ammo == 'special_sniper')
local isSimple = not stat.attachments.stock or isSpecial
local node
if isSimple then
node = renderDurationWithoutStock(stat, duration, stock, canModdedLoader, isSpecial)
else
node = renderDurationWithStock(stat, duration, stock, canModdedLoader, isSniper)
end
return node, isSimple
end
function p._main(name, lang)
lang = lang or 'ja'
local stat = mw.loadData('Module:Stat/Weapon')[name]
local node, _ = p.renderDuration(stat, lang)
return tostring(node)
end
return p