Module:Revolution AADPT
Documentation for this module may be created at Module:Revolution AADPT/doc
--<nowiki>
local p = {}
-- dependencies: [[Module:Yesno]]
local yesno = require('Module:Yesno')
-- data: [[Module:Revolution AADPT/data]]
local ability_data = mw.loadData('Module:Revolution AADPT/data')
local settings = {}
local abilities = {}
local bar = {}
local cd_groups = {}
--[[
Make an ability from the data, and adds it to the abilities array
params
a - string - ability name
returns
the ability object for optional use
--]]
function p.make_ability(a)
local abil = ability_data[a]
local ret = {}
if settings.ice and a == 'wrack' then
abil = ability_data.wrack_ice
end
if a == "tuska's wrath" then
if settings.slayer then
abil = ability_data.tuska_slayer
else
abil = ability_data.tuska_noslayer
end
end
if abilities[abil.name] ~= nil then
return abilities[abil.name]
end
ret = {
name = abil.name,
cooldown = abil.cooldown,
duration = abil.duration or 3,
damage = abil.dmg or abil.damage*0.6,
stundur = abil.stundur or 0,
stundmg = abil.stundmg or (abil.stundamage and abil.stundamage*0.6) or abil.dmg or abil.damage*0.6,
shared = abil.shared,
next_abil_mult = abil.next_abil_mult or 1,
damagetype = abil.damagetype or "",
cd = 0,
used = false,
stunbuffed = false,
}
setmetatable(ret, {__tostring = function() return abil.name end})
if ret.stundmg > ret.damage then
ret.stunbuffed = true
end
if ret.shared then
if cd_groups[ret.shared] == nil then
cd_groups[ret.shared] = {}
end
table.insert(cd_groups[ret.shared], abil.name)
end
abilities[abil.name] = ret
return abilities[abil.name]
end
--[[
Resets abilities cooldowns and other statuses; mostly for testing, but good for using the same instance multiple times
params
a table the ability object
returns
nothing
--]]
local function reset(a)
a.cd = 0
a.used = false
end
--[[
Reduce the cooldown of an ability by a number of ticks
params
a table the ability object
i int the amount to reduce by
returns
nothing
--]]
local function reduce_cooldown(a, i)
if a.cd < i then
a.cd = 0
else
a.cd = a.cd - i
end
end
--[[
Set the cooldown of an ability, and all abilities in its cooldown groups
params
a table the ability object
i int the amount to reduce by
returns
nothing
--]]
local function set_cooldown(a)
local b
a.cd = a.cooldown
--cooldown group
if a.shared then
for _,b in ipairs(cd_groups[a.shared]) do
abilities[b].cd = a.cooldown
end
end
end
--[[
calculates the AADPT of the provided bar
params
bar array of strings list of ability names in order
returns
average ability damage per tick
--]]
function p.calcrevo()
local ret = {
t = 0,
d = 0,
stunbuffed = false,
broke = false,
}
ret.dpt = function() return ret.d/ret.t end
local incr, stunned, dmg, next_abil, next_mult = 0, 0, 0, nil, 1
local a
for n,a in pairs(abilities) do
reset(a)
end
while ret.t < settings.ticks do
--cooldowns
for _,a in pairs(abilities) do
reduce_cooldown(a, incr)
end
if stunned < incr then
stunned = 0
else
stunned = stunned - incr
end
--find next ability
next_abil = nil
for _,a in ipairs(bar) do
if abilities[a].cd == 0 then
next_abil = abilities[a]
break
end
end
if next_abil == nil then
ret.broke = true
return ret --broken revobar
end
-- multipliers don't apply to bleeds
if string.find(next_abil.damagetype, 'bleed') then
next_mult = 1
end
--increment counters
set_cooldown(next_abil)
incr = next_abil.duration
ret.t = ret.t + incr
next_abil.used = true
dmg = next_abil.damage
if stunned > 0 then
if next_abil.stunbuffed then --automatically detect if enabling stuns would affect the bar value
ret.stunbuffed = true
end
if settings.stuns then
dmg = next_abil.stundmg
end
end
ret.d = ret.d + dmg * next_mult
if next_abil.stundur > 0 then
stunned = next_abil.stundur
end
next_mult = next_abil.next_abil_mult
end
return ret
end
--make a permalink to [[Calculator:Revolution]]
function p.generate_permalink()
local uri = mw.uri.new(mw.uri.fullUrl('Calculator:Revolution'))
local query = {}
query.stuns = 0
if settings.stuns then
query.stuns = 1
end
query.ice = 0
if settings.ice then
query.ice = 1
end
query.slayer = 0
if settings.slayer then
query.slayer = 1
end
query.ticks = settings.ticks
query.hand = settings.hand
query.cbclass = settings.cbclass
query.bar = table.concat(bar,',')
uri.query = query;
return uri
end
function p.permalink(frame)
return p._permalink(frame:getParent().args)
end
function p._permalink(args)
setup(args)
local alt = args.alt or 'Open in calculator'
return '[' .. p.generate_permalink() .. ' ' .. alt .. ']'
end
--all the setup stuff
local function setup(a)
settings = {
stuns = false,
ice = false,
slayer = false,
ticks = 1000,
hand = 1,
cbclass = 'melee',
}
settings.stuns = yesno(a.stuns, false)
settings.ice = yesno(a.ice, false)
settings.slayer = yesno(a.slayer, false)
settings.hand = a.hand or 1
settings.cbclass = a.cbclass or 'melee'
settings.ticks = tonumber(a.ticks) or 1000
abilities = {}
bar = {}
local b = mw.text.split(a.bar, ',')
for _,ab in ipairs(b) do
table.insert(bar, p.make_ability(string.lower(ab)).name)
end
end
local function plinkp(s)
return string.format('[[File:%s.png|30x30px|alt=RS3 ability %s used in a Revolution bar|link=%s]]',s,s,s)
end
--test run
function p.run(frame)
return p._run(frame:getParent().args)
end
function p._run(args)
setup(args)
return p.calcrevo().dpt() .. '\t\t' .. tostring(p.generate_permalink())
end
--generate table row
function p.row(frame)
return p._row(frame:getParent().args)
end
function p._row(args)
setup(args)
local notes = args.notes or ''
local stunoriginal = settings.stuns
local val = p.calcrevo()
local dpt = val.dpt()
local barstr = ''
local stunstr = ''
if val.stunbuffed and not settings.stuns then
settings.stuns = true
stunstr = '<br />(Stuns: ' .. math.floor(p.calcrevo().dpt() * 10000)/100 .. '%)'
end
--turn into % with some 2 decimal places
--i.e. change from 0.273737 to 27.37, % appended later
dpt = math.floor(dpt * 10000)/100
for i,a in ipairs(bar) do
barstr = barstr .. plinkp(a)
if next(bar, i) then
barstr = barstr .. ' '
end
end
settings.stuns = stunoriginal
local tr = mw.html.create('tr')
:tag('td')
:wikitext(notes)
:done()
:tag('td')
:wikitext(barstr)
:done()
:tag('td')
:css('text-align', 'right')
:wikitext(dpt .. '%' .. stunstr)
:done()
:tag('td')
:wikitext('['..tostring(p.generate_permalink())..' Open in calculator]')
:done()
:done()
return tr
end
return p
--</nowiki>