RuneScape Wiki
Register
m (a thingy)
Tag: sourceedit
m (+ test)
Tag: sourceedit
 
(58 intermediate revisions by the same user not shown)
Line 5: Line 5:
 
local pt = require('Module:Paramtest')
 
local pt = require('Module:Paramtest')
 
local dt = pt.default_to
 
local dt = pt.default_to
  +
local hc = pt.has_content
   
 
--data borrowed from [[Module:Tier category]]
 
--data borrowed from [[Module:Tier category]]
Line 42: Line 43:
 
armour = 0.2,
 
armour = 0.2,
 
lifepoints = 35,
 
lifepoints = 35,
damagebonus = -1, -- damagebonus = -1 => N/A in 2 columns (power armour)
+
damagebonus = 0, -- damagebonus = -1 => N/A in 2 columns (power armour)
 
},
 
},
 
cape = {
 
cape = {
 
name = 'Cape',
 
name = 'Cape',
 
armour = 0.03,
 
armour = 0.03,
damagebonus = -1,
+
damagebonus = 0,
 
},
 
},
 
ring = {
 
ring = {
 
name = 'Ring',
 
name = 'Ring',
 
armour = 0.02,
 
armour = 0.02,
damagebonus = -1,
+
damagebonus = 0,
 
},
 
},
 
shieldbow = {
 
shieldbow = {
Line 58: Line 59:
 
armour = 0.2,
 
armour = 0.2,
 
lifepoints = 35,
 
lifepoints = 35,
damagebonus = -1,
+
damagebonus = 0,
 
average = 5.3,
 
average = 5.3,
 
ability = 9.6, --ability damage
 
ability = 9.6, --ability damage
Line 67: Line 68:
 
armour = 0.2/2,
 
armour = 0.2/2,
 
lifepoints = 35/2,
 
lifepoints = 35/2,
damagebonus = -1,
+
damagebonus = 0,
 
fastest = 2.4,
 
fastest = 2.4,
 
nohybrid = true,
 
nohybrid = true,
Line 91: Line 92:
 
}
 
}
 
 
  +
local slotmap = {
  +
head = 'head',
  +
body = 'body',
  +
legs = 'legs',
  +
hands = 'hands',
  +
feet = 'feet',
  +
ammo = 'ammo',
  +
cape = 'cape',
  +
ring = 'ring',
  +
aura = 'aura',
  +
pocket = 'pocket',
  +
main = 'mainhand',
  +
['main-hand'] = 'mainhand',
  +
mainhand = 'mainhand',
  +
weapon = 'mainhand',
  +
['off-hand'] = 'shield',
  +
shield = 'shield',
  +
['off-hand weapon'] = 'offhand',
  +
['offhand weapon'] = 'offhand',
  +
ohw = 'offhand',
  +
['2h'] = 'twohand',
  +
}
  +
local classmap = {
  +
melee = 'classed',
  +
magic = 'classed',
  +
ranged = 'classed',
  +
hybrid = 'hybrid',
  +
all = 'hybrid'
  +
}
  +
  +
function get_num(v1, v2)
  +
return tonumber(dt(v1, v2 or 0)) or 0
  +
end
  +
  +
p.data = data
  +
p.slotmap = slotmap
  +
 
local function armourfunc(t)
 
local function armourfunc(t)
 
local r = 2.5 * (t^3/1250 + 4*t + 40)
 
local r = 2.5 * (t^3/1250 + 4*t + 40)
Line 98: Line 136:
 
return 0
 
return 0
 
end
 
end
  +
end
  +
  +
local function revarmourfunc(a)
  +
local t = 1
  +
local af = armourfunc(t)
  +
while a > af and math.abs(a - af) > 5 do
  +
t = t + 1
  +
af = armourfunc(t)
  +
end
  +
return t
  +
end
  +
  +
  +
local powerarmour = false
  +
  +
function p.powertiers(frame)
  +
powerarmour = true
  +
return p.tiers(frame)
  +
end
  +
  +
function tierfail(p, col1, col2)
  +
return '\n|-\n! [['..p..']]\n|colspan="'..col1..'" style="text-align:center;"| \'\'Tier missing - Switch?\'\'\n|colspan="'..col2..'" {{na}}'
 
end
 
end
   
 
function p.tiers(frame)
 
function p.tiers(frame)
local a = frame.args
+
local a = frame:getParent().args
local tier, slot, armour, lp, str, ran, mag = a.tier, a.slot, dt(a.armour, 0), dt(a.life,0), dt(a.strength,0), dt(a.ranged,0), dt(a.magic,0)
+
local tier, atier, slot, armour, lp, str, ran, mag, name
  +
name = a['%PAGE%']
 
  +
tier = tonumber(a.tier)
  +
if tier == nil then
  +
return tierfail(name, 7, 3)
  +
end
  +
atier = tier
  +
slot = a.slot
  +
armour = tonumber(dt(a.armour, '0'))
  +
lp = tonumber(dt(a.life, '0'))
  +
str = tonumber(dt(a.strength, '0'))
  +
ran = tonumber(dt(a.ranged, '0'))
  +
mag = tonumber(dt(a.magic, '0'))
 
local ex_armour, ex_lp, ex_str, d
 
local ex_armour, ex_lp, ex_str, d
  +
  +
local class = classmap[string.lower(a.class)]
  +
if class == 'hybrid' then
  +
atier = tier - 15
  +
elseif powerarmour then
  +
atier = tier - 5
  +
end
  +
  +
slot = slotmap[string.lower(slot)]
 
d = data[slot]
 
d = data[slot]
 
 
ex_armour = math.floor(armourfunc(tier) * d.armour)
+
ex_armour = math.floor(armourfunc(atier) * d.armour)
 
if slot == "shield" then
 
if slot == "shield" then
 
ex_lp = (tier > 69 and tier - 69) or 0
 
ex_lp = (tier > 69 and tier - 69) or 0
Line 113: Line 193:
 
ex_lp = (tier > 79 and tier - 69) or 0
 
ex_lp = (tier > 79 and tier - 69) or 0
 
end
 
end
  +
if class == 'hybrid' or powerarmour then
ex_lp = ex_lp * d.lifepoints
 
  +
ex_lp = 0
  +
end
  +
ex_lp = ex_lp * (d.lifepoints or 0)
 
 
ex_str = tier * d.damagebonus
+
ex_str = math.floor(tier * (d.damagebonus or 0))
 
 
 
 
local out = '\n|-\n! ' .. a.name
+
local out = '\n|-\n! [[' .. name .. ']]'
 
 
 
out = out .. '\n| ' .. tier
 
out = out .. '\n| ' .. tier
  +
out = out .. '\n| ' .. slot
 
out = out .. '\n| ' .. armour
 
out = out .. '\n| ' .. armour
 
out = out .. '\n| ' .. lp
 
out = out .. '\n| ' .. lp
Line 142: Line 226:
 
out = out .. '\n| ' .. ex_str
 
out = out .. '\n| ' .. ex_str
 
local bon = math.max(str, ran, mag)
 
local bon = math.max(str, ran, mag)
if bon > 0 and math.abs(bon - ex_str) > 0 then
+
if (d.damagebonus or 0) > 0 and bon > 0 and math.abs(bon - ex_str) > 0 then
 
out = out .. ' {{notokay}}'
 
out = out .. ' {{notokay}}'
 
if math.abs(bon - ex_str) > 1 then
 
if math.abs(bon - ex_str) > 1 then
Line 151: Line 235:
 
return out
 
return out
 
end
 
end
  +
  +
function weprow(bon)
  +
local out = '\n|-\n! [[' .. bon.name .. ']]'
  +
local ex_acc, ex_dam, d
  +
d = data[bon.slot]
  +
ex_acc = math.floor(armourfunc(bon.tier))
  +
if bon.class == 'magic' or (bon.class == 'ranged' and string.lower(dt(bon.a.style, 'arrows')) ~= 'thrown') then
  +
ex_dam = 0
  +
else
  +
ex_dam = math.floor(bon.tier * (d[bon.speed] or 0))
  +
end
  +
  +
if bon.version then
  +
out = out .. ' <small>' .. bon.version .. '</small>'
  +
end
  +
  +
out = out .. '\n| ' .. bon.tier
  +
out = out .. '\n| ' .. bon.slot
  +
out = out .. '\n| ' .. bon.acc
  +
out = out .. '\n| ' .. bon.dam
  +
  +
out = out .. '\n| ' .. ex_acc
  +
if math.abs(bon.acc - ex_acc) > 0 then
  +
out = out .. ' {{notokay}}'
  +
if math.abs(bon.acc - ex_acc) > 1.5 then
  +
out = out .. '{{notokay}}'
  +
end
  +
end
  +
out = out .. '\n| ' .. revarmourfunc(bon.acc)
  +
  +
out = out .. '\n| ' .. ex_dam
  +
if math.abs(bon.dam - ex_dam) > 0 then
  +
out = out .. ' {{notokay}}'
  +
if math.abs(bon.dam - ex_dam) > 1.5 then
  +
out = out .. '{{notokay}}'
  +
end
  +
end
  +
out = out .. '\n| ' .. math.floor(bon.dam / (d[bon.speed] or 1))
  +
  +
return out
  +
end
  +
  +
  +
  +
function p.weptier(frame)
  +
local a = frame:getParent().args
  +
local slot, acc, dam, def_ma, def_md, def_oa, def_od, speed, class
  +
local ret = ''
  +
i = 1
  +
  +
slot = slotmap[string.lower(a.slot)]
  +
speed = string.lower(dt(a.speed, dt(a.aspeed, 'missing speed')))
  +
class = string.lower(dt(a.class, 'melee'))
  +
def_ma = get_num(a.mainAccuracy)
  +
def_md = get_num(a.mainDamage)
  +
def_oa = get_num(a.offAccuracy)
  +
def_od = get_num(a.offDamage)
  +
  +
  +
if hc(a.version1) then
  +
while hc(a['version' .. i]) do
  +
if slot == 'offhand' then
  +
acc = tonumber(dt(a['offAccuracy'..i], def_oa))
  +
dam = tonumber(dt(a['offDamage'..i], def_od))
  +
else
  +
acc = tonumber(dt(a['mainAccuracy'..i], def_ma))
  +
dam = tonumber(dt(a['mainDamage'..i], def_md))
  +
end
  +
if dam == nil then
  +
dam = 0
  +
end
  +
ret = ret .. weprow({
  +
name = a['%PAGE%'],
  +
version = a['version'..i],
  +
tier = tonumber(a['tier'..i]),
  +
slot = slot,
  +
speed = speed,
  +
class = class,
  +
acc = acc,
  +
dam = dam,
  +
a = a,
  +
});
  +
i = i + 1
  +
end
  +
else
  +
if slot == 'offhand' then
  +
acc = def_oa
  +
dam = def_od
  +
else
  +
acc = def_ma
  +
dam = def_md
  +
end
  +
if dam == nil then
  +
dam = 0
  +
end
  +
ret = weprow({
  +
name = a['%PAGE%'],
  +
tier = tonumber(a.tier),
  +
slot = slot,
  +
speed = speed,
  +
class = class,
  +
acc = acc,
  +
dam = dam,
  +
a = a,
  +
});
  +
  +
end
  +
  +
return ret
  +
end
  +
  +
   
   
Line 180: Line 376:
 
str = str .. '{{PAGENAME}}\t\t' .. frame:getParent():preprocess('{{FULLPAGENAME}}') .. '<br /><br />mw.title.getCurrentTitle().prefixedText = ' .. mw.title.getCurrentTitle().prefixedText
 
str = str .. '{{PAGENAME}}\t\t' .. frame:getParent():preprocess('{{FULLPAGENAME}}') .. '<br /><br />mw.title.getCurrentTitle().prefixedText = ' .. mw.title.getCurrentTitle().prefixedText
 
return str
 
return str
  +
end
  +
  +
  +
  +
  +
  +
  +
  +
  +
  +
  +
  +
-- creates navigation links at the top of the table
  +
-- combat classes, members/free to play, tierless
  +
-- page navigation
  +
-- changing filter resets to first page
  +
-- changing page preserves filters
  +
p.eqtclasses = function(frame)
  +
local a = frame:getParent().args
  +
local title = mw.title.getCurrentTitle()
  +
local table = mw.html.create('table')
  +
local query = { action = 'purge', DPL_offset = 0 }
  +
local thcss = {} -- {['border-top'] = '1px dashed black'}
  +
local css = { ['background-color'] = '#e5e5e5', padding = '0.1em 0.7em 0.2em 0.7em' } --, ['border-top'] = '1px dashed black' }
  +
local td, query_working
  +
local boldmem, boldclass, boldtier, boldloc, boldaug = '0', 'all', '0', '0', '0'
  +
local showaug = false
  +
local sep = ' • '
  +
  +
local weps = false
  +
local ctype = 'armour'
  +
if dt(a.weapons, 'n') == 'y' then
  +
weps = true
  +
ctype = 'weapons'
  +
end
  +
if dt(a.showaug, 'n') == 'y' then
  +
showaug = true
  +
end
  +
  +
local tmin = 0
  +
local tmax = 120
  +
  +
local function make_link(td, link, query_new, bold)
  +
td:css(css)
  +
  +
if bold then
  +
td:wikitext("'''" .. link .. "'''")
  +
else
  +
td:wikitext(string.format('[%s %s]', title:fullUrl(query_new), link))
  +
end
  +
end
  +
  +
  +
-- setup base query
  +
if hc(a.mems) then
  +
query.members = a.mems
  +
boldmem = a.mems
  +
end
  +
  +
if hc(a.class) then
  +
query.class = a.class
  +
boldclass = string.lower(a.class)
  +
end
  +
  +
if hc(a.tierless) then
  +
query.tierless = a.tierless
  +
boldtier = a.tierless
  +
end
  +
  +
if hc(a.loc) then
  +
query.loc = a.loc
  +
boldloc = a.loc
  +
end
  +
  +
if hc(a.useskin) then
  +
query.useskin = a.useskin
  +
end
  +
  +
if showaug and hc(a.aug) then
  +
query.aug = a.aug
  +
boldaug = a.aug
  +
end
  +
  +
if hc(a.tiermin) then
  +
query.tiermin = a.tiermin
  +
tmin = tonumber(a.tiermin) or 0
  +
end
  +
if hc(a.tiermax) then
  +
query.tiermax = a.tiermax
  +
tmax = tonumber(a.tiermax) or 120
  +
end
  +
  +
  +
table:addClass('dplequipmenttable')
  +
:css('text-align', 'left')
  +
  +
-- total reset
  +
td = table:tag('tr'):tag('th')
  +
:wikitext('Reset filters')
  +
:done()
  +
:tag('td')
  +
query_working = {action = 'purge'}
  +
if hc(a.useskin) then
  +
query_working.useskin = a.useskin
  +
end
  +
make_link(td, 'Reset', query_working, false)
  +
  +
  +
-- membership status links
  +
td = table:tag('tr'):tag('th'):css(thcss)
  +
:wikitext('Membership')
  +
:done()
  +
:tag('td')
  +
  +
query_working = get_copy(query)
  +
query_working.members = '0'
  +
make_link(td, 'All', query_working, boldmem == '0')
  +
td:wikitext(sep)
  +
query_working.members = '1'
  +
make_link(td, 'Members only', query_working, boldmem == '1')
  +
td:wikitext(sep)
  +
query_working.members = '2'
  +
make_link(td, 'Free-to-play only', query_working, boldmem == '2')
  +
  +
  +
-- class links
  +
td = table:tag('tr'):tag('th'):css(thcss)
  +
:wikitext('Class')
  +
:done()
  +
:tag('td')
  +
  +
query_working = get_copy(query)
  +
query_working.class = 'all'
  +
make_link(td, 'All', query_working, boldclass == 'all')
  +
td:wikitext(sep)
  +
query_working.class = 'melee'
  +
make_link(td, 'Melee', query_working, boldclass == 'melee')
  +
td:wikitext(sep)
  +
query_working.class = 'ranged'
  +
make_link(td, 'Ranged', query_working, boldclass == 'ranged')
  +
td:wikitext(sep)
  +
query_working.class = 'magic'
  +
make_link(td, 'Magic', query_working, boldclass == 'magic')
  +
if not weps then
  +
td:wikitext(sep)
  +
query_working.class = 'hybrid'
  +
make_link(td, 'Hybrid', query_working, boldclass == 'hybrid')
  +
td:wikitext(sep)
  +
query_working.class = 'typeless'
  +
make_link(td, 'Typeless', query_working, boldclass == 'typeless')
  +
end
  +
  +
  +
td = table:tag('tr'):tag('th'):css(thcss)
  +
:wikitext('Restriction')
  +
:done()
  +
:tag('td')
  +
  +
query_working = get_copy(query)
  +
query_working.loc = '0'
  +
make_link(td, 'All', query_working, boldloc == '0')
  +
td:wikitext(sep)
  +
query_working.loc = '1'
  +
make_link(td, 'Surface only', query_working, boldloc == '1')
  +
td:wikitext(sep)
  +
query_working.loc = '2'
  +
make_link(td, 'Daemonheim only', query_working, boldloc == '2')
  +
td:wikitext(sep)
  +
query_working.loc = '3'
  +
make_link(td, 'No restricted', query_working, boldloc == '3')
  +
  +
  +
-- augmentation links
  +
if showaug then
  +
td = table:tag('tr'):tag('th'):css(thcss)
  +
:wikitext('Augmentation')
  +
:done()
  +
:tag('td')
  +
  +
query_working = get_copy(query)
  +
query_working.aug = '0'
  +
make_link(td, 'All', query_working, boldaug == '0')
  +
td:wikitext(sep)
  +
query_working.aug = '1'
  +
make_link(td, 'Augmentable', query_working, boldaug == '1')
  +
td:wikitext(sep)
  +
query_working.aug = '2'
  +
make_link(td, 'Augmented', query_working, boldaug == '2')
  +
td:wikitext(sep)
  +
query_working.aug = '3'
  +
make_link(td, 'No augmented', query_working, boldaug == '3')
  +
end
  +
  +
-- tier links
  +
td = table:tag('tr'):tag('th'):css(thcss)
  +
:attr('rowspan', '3')
  +
:wikitext('Tiers')
  +
:done()
  +
:tag('td')
  +
  +
query_working = get_copy(query)
  +
query_working.tierless = '0'
  +
make_link(td, 'All', query_working, boldtier == '0')
  +
td:wikitext(sep)
  +
query_working.tierless = '1'
  +
make_link(td, 'No tierless', query_working, boldtier == '1')
  +
td:wikitext(sep)
  +
query_working.tierless = '2'
  +
make_link(td, 'Only tierless', query_working, boldtier == '2')
  +
  +
table:tag('tr'):tag('td')
  +
:css(css)
  +
:wikitext("Current tier range: '''" .. tmin .. '&ndash;' .. tmax .. "''' inclusive")
  +
  +
query_working = get_copy(query)
  +
query_working.useskin = 'wikia'
  +
  +
td = table:tag('tr'):tag('td')
  +
td:css(css)
  +
:wikitext('<span class="jshide">Tier range selector requires javascript and ['.. title:fullUrl(query_working) .. ' the desktop site].<br /></span>')
  +
  +
  +
query_working = get_copy(query)
  +
query_working.tierless = '3'
  +
if query_working.tiermax then
  +
query_working.tiermax = nil
  +
end
  +
if query_working.tiermin then
  +
query_working.tiermin = nil
  +
end
  +
  +
td:tag('span')
  +
:addClass('jsunhide hidden')
  +
:css('display', 'none')
  +
:wikitext('Min:&nbsp;')
  +
:tag('span')
  +
:addClass('jcInput')
  +
:wikitext('name=tlow|type=int|range=0,120|value='..tmin..'|size=5|sublist=tierlink')
  +
:done()
  +
:wikitext(' &bull; Max:&nbsp;')
  +
:tag('span')
  +
:addClass('jcInput')
  +
:wikitext('name=thigh|type=int|range=0,120|value='..tmax..'|size=5|sublist=tierlink')
  +
:done()
  +
:wikitext('<br />')
  +
:tag('span')
  +
:addClass('jcInput')
  +
:wikitext('name=tout|type=output')
  +
:done()
  +
:tag('div')
  +
:addClass('jcSub hidden')
  +
:wikitext('tierlink|')
  +
:wikitext('let(tl, tlow)')
  +
:wikitext('let(th, thigh)')
  +
:wikitext('if(tl>th){')
  +
:wikitext('let(c,th)')
  +
:wikitext('let(th,tl)')
  +
:wikitext('let(tl,c)')
  +
:wikitext('}')
  +
:wikitext('let( link, "{"+"{fullurl:'..title.prefixedText..'|'..mw.uri.buildQueryString(query_working)..'&tiermin=" + tl + "&tiermax=" + th + "}}" )')
  +
:wikitext('parse(tout, "[" + link + " Click to filter to tiers " + tl + " to " + th + " inclusive]" )]=])')
  +
:done()
  +
:done():done()
  +
  +
  +
  +
-- pagination
  +
  +
--separate from filters by a bit
  +
table:tag('tr'):tag('td'):attr('colspan','2'):wikitext('&nbsp;'):done():done()
  +
  +
  +
local total = get_num(a.total) -- total results
  +
local count = get_num(a.count) -- results per page
  +
local offset = get_num(a.offset) -- starting point
  +
local pages = math.ceil(total / count) -- total number of pages
  +
local currpage = math.ceil(offset / count) -- current page, starting at 0
  +
local css2 = {['padding-right'] = '24px'}
  +
  +
table:tag('tr'):tag('td'):attr('colspan','2'):wikitext("'''Total results: " .. total .. "'''"):done():done()
  +
  +
-- if total <= count, only one page, so don't show any pagination
  +
if total > count then
  +
  +
td = table:tag('tr'):tag('th')
  +
:wikitext('Pages')
  +
:done()
  +
:tag('td')
  +
td:css(css)
  +
  +
if currpage == 0 then
  +
-- first page, have first interval bold
  +
td:tag('span'):css(css2):wikitext(string.format("'''1..%s'''", count)):done()
  +
elseif currpage == 1 then
  +
-- second page, first interval linked, second bolded
  +
td:tag('span'):css(css2):wikitext(string.format("[%s 1..%s]", title:fullUrl(query), count)):done()
  +
td:tag('span'):css(css2):wikitext(string.format("'''%s..%s'''", count + 1, math.min(count * 2, total))):done()
  +
else
  +
-- third and onwards, start link, prev link, bolded current
  +
td:tag('span'):css(css2):wikitext(string.format("[%s Start]", title:fullUrl(query))):done()
  +
query.offset = (currpage - 1) * count
  +
td:tag('span'):css(css2):wikitext(string.format("[%s %s..%s]", title:fullUrl(query), query.offset + 1, query.offset + count)):done()
  +
td:tag('span'):css(css2):wikitext(string.format("'''%s..%s'''", query.offset + count + 1, math.min(query.offset + count * 2, total))):done()
  +
end
  +
  +
-- at least another page left, so add next link
  +
if currpage < pages - 1 then
  +
query.offset = (currpage + 1) * count
  +
td:tag('span'):css(css2):wikitext(string.format("[%s %s..%s]", title:fullUrl(query), query.offset + 1, math.min(query.offset + count, total))):done()
  +
if currpage < pages - 2 then
  +
-- at least 2 pages left, so add 'end' link
  +
query.offset = (pages - 1) * count
  +
td:tag('span'):css(css2):wikitext(string.format("[%s End]", title:fullUrl(query))):done()
  +
end
  +
end
  +
td:done():done()
  +
end
  +
  +
return tostring(table)
  +
end
  +
  +
function get_copy(t)
  +
local r = {}
  +
for i,v in pairs(t) do
  +
r[i] = v
  +
end
  +
return r
  +
end
  +
  +
  +
function p.testvar(frame)
  +
return frame:preprocess('dplvar: {{#dplvar:test2}} - var: {{#var:test}}')
  +
end
  +
  +
  +
  +
function p.gaztestinputs(frame)
  +
local arr = mw.text.split(frame.args[1], '%]%] ?')
  +
local v = mw.text.split(arr[1], ' ')
  +
v = v[1]
  +
local s
  +
if tonumber(v) then
  +
s = 'use level ' .. v
  +
else
  +
s = 'value not found, use tier'
  +
end
  +
  +
return s
  +
end
  +
  +
  +
function p.gaztestagain(frame)
  +
local args = frame.args
  +
local s = 'the value of arg[1] is %s%s. the value of arg.hi is %s%s.'
  +
  +
return s:format(tostring(args[1]), args[1] == '' and ' (empty string)' or '', tostring(args.hi), args.hi == '' and ' (empty string)' or '')
 
end
 
end
   

Latest revision as of 18:33, 7 March 2017

Documentation for this module may be created at Module:Sandbox/User:Gaz Lloyd/doc

-- <nowiki>
-- Sandbox belonging to [[User:Gaz Lloyd]]
local p = {}
local portdata = mw.loadData('Module:Ports resources/data')
local pt = require('Module:Paramtest')
local dt = pt.default_to
local hc = pt.has_content

--data borrowed from [[Module:Tier category]]
local data = {
		head = {
				name = 'Head',  --name of slot to go into th
				armour = 0.2,   --armour multiplier
				lifepoints = 20,	--lifepoints multiplier
				damagebonus = 0.25, --damage bonus multiplier (not weapon damage)
			},
		body = {
				name = 'Body',
				armour = 0.23,
				lifepoints = 40,
				damagebonus = 0.375,
			},
		legs = {
				name = 'Legs',
				armour = 0.22,
				lifepoints = 30,
				damagebonus = 0.3125,
			},
		hands = {
				name = 'Hands',
				armour = 0.05,
				lifepoints = 0, --0 shows a 0 in the column; missing/nil shows NA
				damagebonus = 0.15625,
			},
		feet = {
				name = 'Feet',
				armour = 0.05,
				lifepoints = 0,
				damagebonus = 0.15625,
			},
		shield = {
				name = 'Shield',
				armour = 0.2,
				lifepoints = 35,
				damagebonus = 0, -- damagebonus = -1 => N/A in 2 columns (power armour)
			},
		cape = {
				name = 'Cape',
				armour = 0.03,
				damagebonus = 0,
			},
		ring = {
				name = 'Ring',
				armour = 0.02,
				damagebonus = 0,
			},
		shieldbow = {
				name = 'Shieldbow',
				armour = 0.2,
				lifepoints = 35,
				damagebonus = 0,
				average = 5.3,
				ability = 9.6, --ability damage
				nohybrid = true,	--no hybrid variants available, put NA
			},
		defender = {	--all for the reworked defenders
				name = 'Defender',
				armour = 0.2/2,
				lifepoints = 35/2,
				damagebonus = 0,
				fastest = 2.4,
				nohybrid = true,
			},
		mainhand = {
				name = 'Main-hand',
				fastest = 9.6,  --damage multipliers at each speed
				fast = 12.25,   --if missing, defaults to NA
				average = 14.9,
			},
		offhand = {
				name = 'Off-hand',
				fastest = 4.8,
				fast = 6.125,
				average = 7.45,
			},
		twohand = {
				name = 'Two-handed',
				fastest = 14.4,
				fast = 18.375,
				average = 22.35,
			},
	}
	
local slotmap = {
		head = 'head',
		body = 'body',
		legs = 'legs',
		hands = 'hands',
		feet = 'feet',
		ammo = 'ammo',
		cape = 'cape',
		ring = 'ring',
		aura = 'aura',
		pocket = 'pocket',
		main = 'mainhand',
		['main-hand'] = 'mainhand',
		mainhand = 'mainhand',
		weapon = 'mainhand',
		['off-hand'] = 'shield',
		shield = 'shield',
		['off-hand weapon'] = 'offhand',
		['offhand weapon'] = 'offhand',
		ohw = 'offhand',
		['2h'] = 'twohand',
	}
local classmap = {
		melee = 'classed',
		magic = 'classed',
		ranged = 'classed',
		hybrid = 'hybrid',
		all = 'hybrid'
	}
	
function get_num(v1, v2)
	return tonumber(dt(v1, v2 or 0)) or 0
end
	
p.data = data
p.slotmap = slotmap

local function armourfunc(t)
	local r = 2.5 * (t^3/1250 + 4*t + 40)
	if r > 0 then
		return r
	else
		return 0
	end
end

local function revarmourfunc(a)
	local t = 1
	local af = armourfunc(t)
	while a > af and math.abs(a - af) > 5 do
		t = t + 1
		af = armourfunc(t)
	end
	return t
end


local powerarmour = false

function p.powertiers(frame)
	powerarmour = true
	return p.tiers(frame)
end

function tierfail(p, col1, col2)
	return '\n|-\n! [['..p..']]\n|colspan="'..col1..'" style="text-align:center;"| \'\'Tier missing - Switch?\'\'\n|colspan="'..col2..'" {{na}}'
end

function p.tiers(frame)
	local a = frame:getParent().args
	local tier, atier, slot, armour, lp, str, ran, mag, name
	name = a['%PAGE%']
	tier = tonumber(a.tier)
	if tier == nil then
		return tierfail(name, 7, 3)
	end
	atier = tier
	slot = a.slot
	armour = tonumber(dt(a.armour, '0'))
	lp = tonumber(dt(a.life, '0'))
	str = tonumber(dt(a.strength, '0'))
	ran = tonumber(dt(a.ranged, '0'))
	mag = tonumber(dt(a.magic, '0'))
	local ex_armour, ex_lp, ex_str, d
	
	local class = classmap[string.lower(a.class)]
	if class == 'hybrid' then
		atier = tier - 15
	elseif powerarmour then
		atier = tier - 5
	end
	
	slot = slotmap[string.lower(slot)]
	d = data[slot]
	
	ex_armour = math.floor(armourfunc(atier) * d.armour)
	if slot == "shield" then
		ex_lp = (tier > 69 and tier - 69) or 0
	else
		ex_lp = (tier > 79 and tier - 69) or 0
	end
	if class == 'hybrid' or powerarmour then
		ex_lp = 0
	end
	ex_lp = ex_lp * (d.lifepoints or 0)
		
	ex_str = math.floor(tier * (d.damagebonus or 0))
	
	
	local out = '\n|-\n! [[' .. name .. ']]'
	
	out = out .. '\n| ' .. tier
	out = out .. '\n| ' .. slot
	out = out .. '\n| ' .. armour
	out = out .. '\n| ' .. lp
	out = out .. '\n| ' .. str
	out = out .. '\n| ' .. ran
	out = out .. '\n| ' .. mag
	
	out = out .. '\n| ' .. ex_armour
	if math.abs(armour - ex_armour) > 0 then
			out = out .. ' {{notokay}}'
		if math.abs(armour - ex_armour) > 1.5 then
			out = out .. '{{notokay}}'
		end
	end
	
	out = out .. '\n| ' .. ex_lp
	if math.abs(lp - ex_lp) > 0 then
		out = out .. ' {{notokay}}{{notokay}}'
	end
	
	out = out .. '\n| ' .. ex_str
	local bon = math.max(str, ran, mag)
	if (d.damagebonus or 0) > 0 and bon > 0 and math.abs(bon - ex_str) > 0 then
			out = out .. ' {{notokay}}'
		if math.abs(bon - ex_str) > 1 then
			out = out .. '{{notokay}}'
		end
	end
	
	return out
end

function weprow(bon)
	local out = '\n|-\n! [[' .. bon.name .. ']]'
	local ex_acc, ex_dam, d
	d = data[bon.slot]
	ex_acc = math.floor(armourfunc(bon.tier))
	if bon.class == 'magic' or (bon.class == 'ranged' and string.lower(dt(bon.a.style, 'arrows')) ~= 'thrown') then
		ex_dam = 0
	else
		ex_dam = math.floor(bon.tier * (d[bon.speed] or 0))
	end
	
	if bon.version then
		out = out .. ' <small>' .. bon.version .. '</small>'
	end
	
	out = out .. '\n| ' .. bon.tier
	out = out .. '\n| ' .. bon.slot
	out = out .. '\n| ' .. bon.acc
	out = out .. '\n| ' .. bon.dam
	
	out = out .. '\n| ' .. ex_acc
	if math.abs(bon.acc - ex_acc) > 0 then
			out = out .. ' {{notokay}}'
		if math.abs(bon.acc - ex_acc) > 1.5 then
			out = out .. '{{notokay}}'
		end
	end
	out = out .. '\n| ' .. revarmourfunc(bon.acc)
	
	out = out .. '\n| ' .. ex_dam
	if math.abs(bon.dam - ex_dam) > 0 then
			out = out .. ' {{notokay}}'
		if math.abs(bon.dam - ex_dam) > 1.5 then
			out = out .. '{{notokay}}'
		end
	end
	out = out .. '\n| ' .. math.floor(bon.dam / (d[bon.speed] or 1))

	return out
end



function p.weptier(frame)
	local a = frame:getParent().args
	local slot, acc, dam, def_ma, def_md, def_oa, def_od, speed, class
	local ret = ''
	i = 1
	
	slot = slotmap[string.lower(a.slot)]
	speed = string.lower(dt(a.speed, dt(a.aspeed, 'missing speed')))
	class = string.lower(dt(a.class, 'melee'))
	def_ma = get_num(a.mainAccuracy)
	def_md = get_num(a.mainDamage)
	def_oa = get_num(a.offAccuracy)
	def_od = get_num(a.offDamage)
	
	
	if hc(a.version1) then
		while hc(a['version' .. i]) do
			if slot == 'offhand' then
				acc = tonumber(dt(a['offAccuracy'..i], def_oa))
				dam = tonumber(dt(a['offDamage'..i], def_od))
			else
				acc = tonumber(dt(a['mainAccuracy'..i], def_ma))
				dam = tonumber(dt(a['mainDamage'..i], def_md))
			end
			if dam == nil then
				dam = 0
			end
			ret = ret .. weprow({
				name = a['%PAGE%'],
				version = a['version'..i],
				tier = tonumber(a['tier'..i]),
				slot = slot,
				speed = speed,
				class = class,
				acc = acc,
				dam = dam,
				a = a,
			});
			i = i + 1
		end
	else
		if slot == 'offhand' then
			acc = def_oa
			dam = def_od
		else
			acc = def_ma
			dam = def_md
		end
		if dam == nil then
			dam = 0
		end
		ret = weprow({
			name = a['%PAGE%'],
			tier = tonumber(a.tier),
			slot = slot,
			speed = speed,
			class = class,
			acc = acc,
			dam = dam,
			a = a,
		});
		
	end
	
	return ret
end








function p.test()
    return '\n|-\n!hi\n|pls'
end

function p.ports()
    local s = ''
    for _,v in pairs(portdata) do
        s = s .. v ..'<br />'
    end
    return s
end

function p.test2(frame)
    local str = ''
    for i,v in pairs(frame) do
        str = str .. i .. '\t\t' .. tostring(v) .. '<br />'
    end
    str = str .. '{{PAGENAME}}\t\t' .. frame:preprocess('{{FULLPAGENAME}}') .. '<br /><br />'
    for i,v in pairs(frame:getParent()) do
        str = str .. i .. '\t\t' .. tostring(v) .. '<br />'
    end
    str = str .. '{{PAGENAME}}\t\t' .. frame:getParent():preprocess('{{FULLPAGENAME}}') .. '<br /><br />mw.title.getCurrentTitle().prefixedText = ' .. mw.title.getCurrentTitle().prefixedText
    return str
end











-- creates navigation links at the top of the table
-- combat classes, members/free to play, tierless
-- page navigation
-- changing filter resets to first page
-- changing page preserves filters
p.eqtclasses = function(frame)
	local a = frame:getParent().args
	local title = mw.title.getCurrentTitle()
	local table = mw.html.create('table')
	local query = { action = 'purge', DPL_offset = 0 }
	local thcss = {} -- {['border-top'] = '1px dashed black'}
	local css = { ['background-color'] = '#e5e5e5', padding = '0.1em 0.7em 0.2em 0.7em' } --, ['border-top'] = '1px dashed black' }
	local td, query_working
	local boldmem, boldclass, boldtier, boldloc, boldaug = '0', 'all', '0', '0', '0'
	local showaug = false
	local sep = ' • '
	
	local weps = false
	local ctype = 'armour'
	if dt(a.weapons, 'n') == 'y' then
		weps = true
		ctype = 'weapons'
	end
	if dt(a.showaug, 'n') == 'y' then
		showaug = true
	end
	
	local tmin = 0
	local tmax = 120
	
	local function make_link(td, link, query_new, bold)
		td:css(css)
	
		if bold then
			td:wikitext("'''" .. link .. "'''")
		else
			td:wikitext(string.format('[%s %s]', title:fullUrl(query_new), link))
		end
	end
	
	
	-- setup base query
	if hc(a.mems) then
		query.members = a.mems
		boldmem = a.mems
	end
	
	if hc(a.class) then
		query.class = a.class
		boldclass = string.lower(a.class)
	end
	
	if hc(a.tierless) then
		query.tierless = a.tierless
		boldtier = a.tierless
	end
	
	if hc(a.loc) then
		query.loc = a.loc
		boldloc = a.loc
	end
	
	if hc(a.useskin) then
		query.useskin = a.useskin
	end
	
	if showaug and hc(a.aug) then
		query.aug = a.aug
		boldaug = a.aug
	end
	
	if hc(a.tiermin) then
		query.tiermin = a.tiermin
		tmin = tonumber(a.tiermin) or 0
	end
	if hc(a.tiermax) then
		query.tiermax = a.tiermax
		tmax = tonumber(a.tiermax) or 120
	end
	
	
	table:addClass('dplequipmenttable')
		:css('text-align', 'left')

	-- total reset
	td = table:tag('tr'):tag('th')
			:wikitext('Reset filters')
		:done()
		:tag('td')
	query_working = {action = 'purge'}
	if hc(a.useskin) then
		query_working.useskin = a.useskin
	end
	make_link(td, 'Reset', query_working, false)
	
	
	-- membership status links
	td = table:tag('tr'):tag('th'):css(thcss)
			:wikitext('Membership')
		:done()
		:tag('td')
	
	query_working = get_copy(query)
	query_working.members = '0'
	make_link(td, 'All', query_working, boldmem == '0')
	td:wikitext(sep)
	query_working.members = '1'
	make_link(td, 'Members only', query_working, boldmem == '1')
	td:wikitext(sep)
	query_working.members = '2'
	make_link(td, 'Free-to-play only', query_working, boldmem == '2')
	
	
	-- class links
	td = table:tag('tr'):tag('th'):css(thcss)
			:wikitext('Class')
		:done()
		:tag('td')
	
	query_working = get_copy(query)
	query_working.class = 'all'
	make_link(td, 'All', query_working, boldclass == 'all')
	td:wikitext(sep)
	query_working.class = 'melee'
	make_link(td, 'Melee', query_working, boldclass == 'melee')
	td:wikitext(sep)
	query_working.class = 'ranged'
	make_link(td, 'Ranged', query_working, boldclass == 'ranged')
	td:wikitext(sep)
	query_working.class = 'magic'
	make_link(td, 'Magic', query_working, boldclass == 'magic')
	if not weps then
		td:wikitext(sep)
		query_working.class = 'hybrid'
		make_link(td, 'Hybrid', query_working, boldclass == 'hybrid')
		td:wikitext(sep)
		query_working.class = 'typeless'
		make_link(td, 'Typeless', query_working, boldclass == 'typeless')
	end
	
	
	td = table:tag('tr'):tag('th'):css(thcss)
			:wikitext('Restriction')
		:done()
		:tag('td')
	
	query_working = get_copy(query)
	query_working.loc = '0'
	make_link(td, 'All', query_working, boldloc == '0')
	td:wikitext(sep)
	query_working.loc = '1'
	make_link(td, 'Surface only', query_working, boldloc == '1')
	td:wikitext(sep)
	query_working.loc = '2'
	make_link(td, 'Daemonheim only', query_working, boldloc == '2')
	td:wikitext(sep)
	query_working.loc = '3'
	make_link(td, 'No restricted', query_working, boldloc == '3')
	
	
	-- augmentation links
	if showaug then
		td = table:tag('tr'):tag('th'):css(thcss)
				:wikitext('Augmentation')
			:done()
			:tag('td')
		
		query_working = get_copy(query)
		query_working.aug = '0'
		make_link(td, 'All', query_working, boldaug == '0')
		td:wikitext(sep)
		query_working.aug = '1'
		make_link(td, 'Augmentable', query_working, boldaug == '1')
		td:wikitext(sep)
		query_working.aug = '2'
		make_link(td, 'Augmented', query_working, boldaug == '2')
		td:wikitext(sep)
		query_working.aug = '3'
		make_link(td, 'No augmented', query_working, boldaug == '3')
	end
	
	-- tier links
	td = table:tag('tr'):tag('th'):css(thcss)
			:attr('rowspan', '3')
			:wikitext('Tiers')
		:done()
		:tag('td')
	
	query_working = get_copy(query)
	query_working.tierless = '0'
	make_link(td, 'All', query_working, boldtier == '0')
	td:wikitext(sep)
	query_working.tierless = '1'
	make_link(td, 'No tierless', query_working, boldtier == '1')
	td:wikitext(sep)
	query_working.tierless = '2'
	make_link(td, 'Only tierless', query_working, boldtier == '2')
	
	table:tag('tr'):tag('td')
		:css(css)
		:wikitext("Current tier range: '''" .. tmin .. '&ndash;' .. tmax .. "''' inclusive")
	
	query_working = get_copy(query)
	query_working.useskin = 'wikia'
	
	td = table:tag('tr'):tag('td')
	td:css(css)
		:wikitext('<span class="jshide">Tier range selector requires javascript and ['.. title:fullUrl(query_working) .. ' the desktop site].<br /></span>')
	
	
	query_working = get_copy(query)
	query_working.tierless = '3'
	if query_working.tiermax then
		query_working.tiermax = nil
	end
	if query_working.tiermin then
		query_working.tiermin = nil
	end
	
	td:tag('span')
		:addClass('jsunhide hidden')
		:css('display', 'none')
		:wikitext('Min:&nbsp;')
		:tag('span')
			:addClass('jcInput')
			:wikitext('name=tlow|type=int|range=0,120|value='..tmin..'|size=5|sublist=tierlink')
		:done()
		:wikitext(' &bull; Max:&nbsp;')
		:tag('span')
			:addClass('jcInput')
			:wikitext('name=thigh|type=int|range=0,120|value='..tmax..'|size=5|sublist=tierlink')
		:done()
		:wikitext('<br />')
		:tag('span')
			:addClass('jcInput')
			:wikitext('name=tout|type=output')
		:done()
		:tag('div')
			:addClass('jcSub hidden')
			:wikitext('tierlink|')
			:wikitext('let(tl, tlow)')
			:wikitext('let(th, thigh)')
			:wikitext('if(tl>th){')
			:wikitext('let(c,th)')
			:wikitext('let(th,tl)')
			:wikitext('let(tl,c)')
			:wikitext('}')
			:wikitext('let( link, "{"+"{fullurl:'..title.prefixedText..'|'..mw.uri.buildQueryString(query_working)..'&tiermin=" + tl + "&tiermax=" + th + "}}" )')
			:wikitext('parse(tout, "[" + link + " Click to filter to tiers " + tl + " to " + th + " inclusive]" )]=])')
		:done()
	:done():done()
	
	
	
	-- pagination
	
	--separate from filters by a bit
	table:tag('tr'):tag('td'):attr('colspan','2'):wikitext('&nbsp;'):done():done()
	
	
	local total = get_num(a.total) -- total results
	local count = get_num(a.count) -- results per page
	local offset = get_num(a.offset) -- starting point
	local pages = math.ceil(total / count) -- total number of pages
	local currpage = math.ceil(offset / count) -- current page, starting at 0
	local css2 = {['padding-right'] = '24px'}
	
	table:tag('tr'):tag('td'):attr('colspan','2'):wikitext("'''Total results: " .. total .. "'''"):done():done()
	
	-- if total <= count, only one page, so don't show any pagination
	if total > count then
		
		td = table:tag('tr'):tag('th')
				:wikitext('Pages')
				:done()
				:tag('td')
		td:css(css)
		
		if currpage == 0 then
			-- first page, have first interval bold
			td:tag('span'):css(css2):wikitext(string.format("'''1..%s'''", count)):done()
		elseif currpage == 1 then
			-- second page, first interval linked, second bolded
			td:tag('span'):css(css2):wikitext(string.format("[%s 1..%s]", title:fullUrl(query), count)):done()
			td:tag('span'):css(css2):wikitext(string.format("'''%s..%s'''", count + 1, math.min(count * 2, total))):done()
		else
			-- third and onwards, start link, prev link, bolded current
			td:tag('span'):css(css2):wikitext(string.format("[%s Start]", title:fullUrl(query))):done()
			query.offset = (currpage - 1) * count
			td:tag('span'):css(css2):wikitext(string.format("[%s %s..%s]", title:fullUrl(query), query.offset + 1, query.offset + count)):done()
			td:tag('span'):css(css2):wikitext(string.format("'''%s..%s'''", query.offset + count + 1, math.min(query.offset + count * 2, total))):done()
		end
		
		-- at least another page left, so add next link
		if currpage < pages - 1 then
			query.offset = (currpage + 1) * count
			td:tag('span'):css(css2):wikitext(string.format("[%s %s..%s]", title:fullUrl(query), query.offset + 1, math.min(query.offset + count, total))):done()
			if currpage < pages - 2 then
				-- at least 2 pages left, so add 'end' link
				query.offset = (pages - 1) * count
				td:tag('span'):css(css2):wikitext(string.format("[%s End]", title:fullUrl(query))):done()
			end
	end
	td:done():done()
	end
	
	return tostring(table)
end

function get_copy(t)
	local r = {}
	for i,v in pairs(t) do
		r[i] = v
	end
	return r
end


function p.testvar(frame)
	return frame:preprocess('dplvar: {{#dplvar:test2}} - var: {{#var:test}}')
end



function p.gaztestinputs(frame)
	local arr = mw.text.split(frame.args[1], '%]%] ?')
	local v = mw.text.split(arr[1], ' ')
	v = v[1]
	local s
	if tonumber(v) then
		s = 'use level ' .. v
	else
		s = 'value not found, use tier'
	end
	
	return s
end


function p.gaztestagain(frame)
		local args = frame.args
		local s = 'the value of arg[1] is %s%s. the value of arg.hi is %s%s.'
		
		return s:format(tostring(args[1]), args[1] == '' and ' (empty string)' or '', tostring(args.hi), args.hi == '' and ' (empty string)' or '')
end

return p