Module:Combat Only Pure/Combat Achievements
Jump to navigation
Jump to search
Documentation for this module may be created at Module:Combat Only Pure/Combat Achievements/doc
local tables = require('Module:Tables')
local VariablesLua = mw.ext.VariablesLua
local p = {}
local whitelist = {
["... 'til Dawn"] = true,
["A Demon's Best Friend"] = true,
["A Frozen Foe from the Past"] = true,
["A Frozen King"] = true,
["A Greater Foe"] = true,
["A Long Trip"] = true,
["A Near Miss!"] = true,
["A Not So Special Lizard"] = true,
["A Scaley Encounter"] = true,
["A Slithery Encounter"] = true,
["A Slow Death"] = true,
["A Smashing Time"] = true,
["A Timely Snack"] = true,
["Alchemical Master"] = true,
["Alchemical Speed-Chaser"] = true,
["Alchemical Speed-Runner"] = true,
["Alchemical Veteran"] = true,
["Alcleanical Hydra"] = true,
["Anti-Bite Mechanics"] = true,
["Anticoagulants"] = true,
["Antifire Protection"] = true,
["Anvil No More"] = true,
["Arooo No More"] = true,
["Ash Collector"] = true,
["Attack, Step, Wait"] = true,
["Avoiding Those Little Arms"] = true,
["Back in My Day..."] = true,
["Back to the Wall"] = true,
["Barrows Champion"] = true,
["Barrows Novice"] = true,
["Big, Black and Fiery"] = true,
["Blind Spot"] = true,
["Blizzard Dodger"] = true,
["Brutal, Big, Black and Firey"] = true,
["Bryophyta Champion"] = true,
["Bryophyta Novice"] = true,
["Budget Setup"] = true,
["Callisto Adept"] = true,
["Callisto Veteran"] = true,
["Can You Dance?"] = true,
["Can't Drain This"] = true,
["Can't Touch Me"] = true,
["Can't Wake Up"] = true,
["Cerberus Master"] = true,
["Cerberus Veteran"] = true,
["Chambers of Xeric (5-Scale) Speed-Chaser"] = true,
["Chambers of Xeric (5-Scale) Speed-Runner"] = true,
["Chambers of Xeric (Solo) Speed-Chaser"] = true,
["Chambers of Xeric (Solo) Speed-Runner"] = true,
["Chambers of Xeric (Trio) Speed-Chaser"] = true,
["Chambers of Xeric (Trio) Speed-Runner"] = true,
["Chambers of Xeric Grandmaster"] = true,
["Chambers of Xeric Master"] = true,
["Chambers of Xeric Veteran"] = true,
["Chambers of Xeric: CM (5-Scale) Speed-Chaser"] = true,
["Chambers of Xeric: CM (5-Scale) Speed-Runner"] = true,
["Chambers of Xeric: CM (Solo) Speed-Chaser"] = true,
["Chambers of Xeric: CM (Solo) Speed-Runner"] = true,
["Chambers of Xeric: CM (Trio) Speed-Chaser"] = true,
["Chambers of Xeric: CM (Trio) Speed-Runner"] = true,
["Chambers of Xeric: CM Grandmaster"] = true,
["Chambers of Xeric: CM Master"] = true,
["Chaos Elemental Adept"] = true,
["Chaos Elemental Veteran"] = true,
["Chaos Fanatic Adept"] = true,
["Chaos Fanatic Champion"] = true,
["Chicken Killer"] = true,
["Chitin Penetrator"] = true,
["Claw Clipper"] = true,
["Colosseum Grand Champion"] = true,
["Colosseum Speed-Chaser"] = true,
["Colosseum Speed-Runner"] = true,
["Corporeal Beast Master"] = true,
["Corporeal Beast Veteran"] = true,
["Crazy Archaeologist Adept"] = true,
["Crazy Archaeologist Champion"] = true,
["Crush Hour"] = true,
["Cryo No More"] = true,
["Dagannoth Prime Adept"] = true,
["Dagannoth Prime Champion"] = true,
["Dagannoth Rex Adept"] = true,
["Dagannoth Rex Champion"] = true,
["Dagannoth Supreme Adept"] = true,
["Dagannoth Supreme Champion"] = true,
["Dancing with Statues"] = true,
["Death to the Archer King"] = true,
["Death to the Seer King"] = true,
["Death to the Warrior King"] = true,
["Defence Matters"] = true,
["Defence? What Defence?"] = true,
["Demon Evasion"] = true,
["Demon Whisperer"] = true,
["Demonbane Weaponry"] = true,
["Demonbane Weaponry II"] = true,
["Demonic Defence"] = true,
["Demonic Showdown"] = true,
["Demonic Weakening"] = true,
["Denied"] = true,
["Denying the Healers"] = true,
["Denying the Healers II"] = true,
["Don't Flame Me"] = true,
["Don't Look at Me!"] = true,
["Don't Look at the Eclipse"] = true,
["Done before Dusk"] = true,
["Dreamland Express"] = true,
["Dust Seeker"] = true,
["Efficient Pest Control"] = true,
["Explosion!"] = true,
["Facing Jad Head-on"] = true,
["Facing Jad Head-on II"] = true,
["Facing Jad Head-on III"] = true,
["Facing Jad Head-on IV"] = true,
["Faithless Crypt Run"] = true,
["Fight Caves Master"] = true,
["Fight Caves Speed-Chaser"] = true,
["Fight Caves Speed-Runner"] = true,
["Fight Caves Veteran"] = true,
["Fighting as Intended"] = true,
["Fighting as Intended II"] = true,
["From Dusk..."] = true,
["From One King to Another"] = true,
["Furball"] = true,
["General Graardor Adept"] = true,
["General Graardor Veteran"] = true,
["General Showdown"] = true,
["Ghost Buster"] = true,
["Giant Mole Champion"] = true,
["Giant Mole Novice"] = true,
["Granite Footwork"] = true,
["Grotesque Guardians Adept"] = true,
["Grotesque Guardians Speed-Chaser"] = true,
["Grotesque Guardians Speed-Runner"] = true,
["Grotesque Guardians Speed-Trialist"] = true,
["Grotesque Guardians Veteran"] = true,
["Guardians No More"] = true,
["Half-Way There"] = true,
["Hard Hitter"] = true,
["Hard Mode? Completed It"] = true,
["Harder Mode I"] = true,
["Harder Mode II"] = true,
["Harder Mode III"] = true,
["Hazard Prevention"] = true,
["Heal No More"] = true,
["Hide Penetration"] = true,
["Hoarder"] = true,
["Hot on Your Feet"] = true,
["I Brought Mine Too"] = true,
["I Can't Reach That"] = true,
["I Would Simply React"] = true,
["I was here first!"] = true,
["I'd Rather Not Learn"] = true,
["Immortal Raid Team"] = true,
["Immortal Raider"] = true,
["Inferno Grandmaster"] = true,
["Inferno Speed-Runner"] = true,
["Inspect Repellent"] = true,
["Into the Den of Giants"] = true,
["It Wasn't a Fluke"] = true,
["Jad? What Are You Doing Here?"] = true,
["Just Like That"] = true,
["Just To Be Safe"] = true,
["K'ril Tsutsaroth Adept"] = true,
["K'ril Tsutsaroth Veteran"] = true,
["Kalphite Queen Adept"] = true,
["Kalphite Queen Veteran"] = true,
["Keep Away"] = true,
["Kill It with Fire"] = true,
["King Black Dragon Champion"] = true,
["King Black Dragon Novice"] = true,
["Krakan't Hurt Me"] = true,
["Kraken Adept"] = true,
["Lightning Lure"] = true,
["Mage of the Ruins"] = true,
["Master of Broad Weaponry"] = true,
["Mimic Veteran"] = true,
["Mixing Correctly"] = true,
["Morytania Only"] = true,
["Multi-Style Specialist"] = true,
["Mutta-diet"] = true,
["Newspaper Enthusiast"] = true,
["Nibbler Chaser"] = true,
["Nibblers, Begone!"] = true,
["Nightmare (5-Scale) Speed-Chaser"] = true,
["Nightmare (5-Scale) Speed-Runner"] = true,
["Nightmare (5-Scale) Speed-Trialist"] = true,
["Nightmare (Solo) Speed-Chaser"] = true,
["Nightmare (Solo) Speed-Runner"] = true,
["Nightmare (Solo) Speed-Trialist"] = true,
["Nightmare Adept"] = true,
["Nightmare Master"] = true,
["Nightmare Veteran"] = true,
["No Luck Required"] = true,
["No Pressure"] = true,
["No Time for Death"] = true,
["No Time for a Drink"] = true,
["No-Pillar"] = true,
["Not So Great After All"] = true,
["Noxious Foe"] = true,
["Nylo Sniper"] = true,
["Obor Champion"] = true,
["Obor Novice"] = true,
["One Hundred Tentacles"] = true,
["One-off"] = true,
["Ourg Freezer"] = true,
["Ourg Freezer II"] = true,
["Ourg Killer"] = true,
["Pack Like a Yak"] = true,
["Pass It On"] = true,
["Perfect Bloat"] = true,
["Perfect Footwork"] = true,
["Perfect Grotesque Guardians"] = true,
["Perfect Grotesque Guardians II"] = true,
["Perfect Maiden"] = true,
["Perfect Nightmare"] = true,
["Perfect Nylocas"] = true,
["Perfect Olm (Solo)"] = true,
["Perfect Olm (Trio)"] = true,
["Perfect Phosani's Nightmare"] = true,
["Perfect Scurrius"] = true,
["Perfect Sotesteg"] = true,
["Perfect Theatre"] = true,
["Perfect Verzik"] = true,
["Perfect Xarpus"] = true,
["Perfectly Balanced"] = true,
["Personal Space"] = true,
["Phosani's Grandmaster"] = true,
["Phosani's Master"] = true,
["Phosani's Speedchaser"] = true,
["Phosani's Speedrunner"] = true,
["Phosani's Veteran"] = true,
["Playing with Jads"] = true,
["Playing with Lasers"] = true,
["Pop It"] = true,
["Pray for Success"] = true,
["Prayer Smasher"] = true,
["Praying to the Gods"] = true,
["Preparation Is Key"] = true,
["Prison Break"] = true,
["Protection from Moss"] = true,
["Putting It Olm on the Line"] = true,
["Quick Cutter"] = true,
["Rapid Succession"] = true,
["Ready to Pounce"] = true,
["Redemption Enthusiast"] = true,
["Reinforcements"] = true,
["Rockin' around the croc"] = true,
["Royal Affairs"] = true,
["Sarachnis Champion"] = true,
["Sarachnis Novice"] = true,
["Scorpia Adept"] = true,
["Scorpia Veteran"] = true,
["Scurrius Champion"] = true,
["Scurrius Novice"] = true,
["Shayzien Protector"] = true,
["Shayzien Specialist"] = true,
["Showboating"] = true,
["Sit Rat"] = true,
["Skotizo Adept"] = true,
["Skotizo Champion"] = true,
["Sleep Tight"] = true,
["Sleeping Giant"] = true,
["Slow Dancing in the Sand"] = true,
["Sorry, What Was That?"] = true,
["Spec'd Out"] = true,
["Sportsmanship"] = true,
["Squashing the Giant"] = true,
["Static Awareness"] = true,
["Stop Drop and Roll"] = true,
["Stop Right There!"] = true,
["Supplies? Who Needs 'em?"] = true,
["Team Work Makes the Dream Work"] = true,
["Ten-tacles"] = true,
["Terrible Parent"] = true,
["The Bane of Demons"] = true,
["The Demonic Punching Bag"] = true,
["The Flame Skipper"] = true,
["The Flincher"] = true,
["The Floor Is Lava"] = true,
["The II Jad Challenge"] = true,
["The IV Jad Challenge"] = true,
["The VI Jad Challenge"] = true,
["The Walking Volcano"] = true,
["Theatre (4-Scale) Speed-Chaser"] = true,
["Theatre (4-Scale) Speed-Runner"] = true,
["Theatre (5-Scale) Speed-Chaser"] = true,
["Theatre (5-Scale) Speed-Runner"] = true,
["Theatre (Duo) Speed-Runner"] = true,
["Theatre (Trio) Speed-Chaser"] = true,
["Theatre (Trio) Speed-Runner"] = true,
["Theatre of Blood Grandmaster"] = true,
["Theatre of Blood Master"] = true,
["Theatre of Blood Veteran"] = true,
["Theatre of Blood: HM Grandmaster"] = true,
["Theatre of Blood: SM Adept"] = true,
["Theatre of Blood: SM Speed-Chaser"] = true,
["Theatre: HM (4-Scale) Speed-Runner"] = true,
["Theatre: HM (5-Scale) Speed-Runner"] = true,
["Theatre: HM (Trio) Speed-Runner"] = true,
["Thermonuclear Veteran"] = true,
["They Won't Expect This"] = true,
["Together We'll Fall"] = true,
["Toppling the Diarchy"] = true,
["Two-Down"] = true,
["TzHaar-Ket-Rak's Speed-Chaser"] = true,
["TzHaar-Ket-Rak's Speed-Runner"] = true,
["TzHaar-Ket-Rak's Speed-Trialist"] = true,
["Undying Raid Team"] = true,
["Undying Raider"] = true,
["Unnecessary Optimization"] = true,
["Unrequired Antifire"] = true,
["Unrequired Antipoisons"] = true,
["Up for the Challenge"] = true,
["Venenatis Adept"] = true,
["Venenatis Veteran"] = true,
["Vet'eran"] = true,
["Vet'ion Adept"] = true,
["Wasn't Even Close"] = true,
["Whack-a-Mole"] = true,
["Who Is the King Now?"] = true,
["Why Are You Running?"] = true,
["Working Overtime"] = true,
["Yarr No More"] = true,
["You Didn't Say Anything About a Bat"] = true
}
local prose = {
monster = '',
taskamount = 0,
ptsamount = 0
}
local headers = {
monster = "Monster",
name = "Name",
description = { text = "Description", attr = { class = 'unsortable' } },
tier = "Tier",
_type = "Type",
completion = '<span style="cursor:help; border-bottom:1px dotted;" title="Estimated percentage of players (with at least one CA completion) who have completed this achievement, based on wiki crowdsourcing">Comp%</span>'
}
local tiers = {
easy = 1,
medium = 2,
hard = 3,
elite = 4,
master = 5,
grandmaster = 6
}
local function getData(category)
local out = {}
local params = {
category[1],
"?Combat Achievement JSON",
limit = 1000
}
local data = mw.smw.ask(params) or {}
for _, task in ipairs(data) do
local raw = task['Combat Achievement JSON']
if raw ~= nil then
local json = mw.text.jsonDecode(raw)
table.insert(out, json)
end
end
return out
end
local function sortByTierAndMonster(k1, k2)
local k1_tier = tiers[string.lower(k1.tier)]
local k2_tier = tiers[string.lower(k2.tier)]
if k1_tier < k2_tier then
return true
elseif k1_tier > k2_tier then
return false
elseif k1.monster < k2.monster then
return true
elseif k1.monster > k2.monster then
return false
else
return false
end
end
local function completionCell(id)
local completion_percent = mw.loadJsonData("Module:Combat Achievements/completion.json")[tonumber(id)]
if (completion_percent ~= nil) then
local color = ""
if (completion_percent < 0.1) then
completion_percent = "<0.1"
color = "red"
elseif (completion_percent < 1) then
color = "orange"
elseif (completion_percent < 10) then
color = "yellow"
elseif (completion_percent < 50) then
color = "green"
elseif (completion_percent <= 100) then
color = "blue"
end
return {text = tostring(completion_percent)..'%', class = "table-bg-" .. color}
else
return {text = "N/A", class="table-na nohighlight"}
end
end
local function makeTable(data, columns)
local taskTable = mw.html.create('table'):addClass('wikitable lighttable sortable qc-active ca-tasks'):cssText('max-width: 800px')
local columnValues = {}
for _, v in ipairs(columns) do
table.insert(columnValues, headers[v])
end
tables._row(taskTable:tag('tr'), columnValues, true)
for _, v in ipairs(data) do
if whitelist[v.name] then
local rowData = {
monster = v.monster == "None" and "N/A" or string.format("[[%s]]", v.monster),
name = string.format("[[%s]]", v.name),
description = v.task,
tier = { text = ( v.tier .. ' (' .. tiers[v.tier:lower()] .. ' ' .. (tiers[v.tier:lower()] == 1 and 'pt' or 'pts') .. ')' ), attr = { ['data-sort-value'] = tiers[v.tier:lower()] } },
_type = v["type"],
completion = completionCell(v.id)
}
local row = {}
for _, column in ipairs(columns) do
table.insert(row, rowData[column])
end
local htmlRow = taskTable:tag('tr'):attr('data-ca-task-id', v.id)
tables._row(htmlRow, row, false)
prose.taskamount = prose.taskamount + 1
prose.ptsamount = prose.ptsamount + tiers[v.tier:lower()]
end
end
return taskTable
end
function p.list(frame)
local args = frame:getParent().args
local columns = {"name", "description", "_type"}
local category = {}
if args[1] == 'all' then
category = {"[[Category:Easy Combat Achievements tasks||Medium Combat Achievements tasks||Hard Combat Achievements tasks||Elite Combat Achievements tasks||Master Combat Achievements tasks||Grandmaster Combat Achievements tasks]]"}
table.insert(columns, 1, "monster")
table.insert(columns, "tier")
elseif tiers[string.lower(args[1])] ~= nil then
-- Get all Combat Achievement tasks for a tier and display its monster
category = {string.format("[[Category:%s Combat Achievements tasks]]", args[1])}
table.insert(columns, 1, "monster")
else
-- Get all Combat Achievement tasks for a boss and display its tier
category = {string.format("[[Category:%s achievements]]", args[1])}
table.insert(columns, "tier")
end
table.insert(columns, "completion")
prose.monster = args.mobname or args[1]
local data = getData(category)
table.sort(data, sortByTierAndMonster)
local rettbl = tostring( makeTable(data, columns) )
local strplural = (prose.taskamount ~= 1)
local moduleInvokedOnce = VariablesLua.varexists('caListModuleInvoked')
local retstr = ( string.find( mw.title.getCurrentTitle().text, 'Combat Achievements') and '' or
string.format('<p>There %s %s %s task%s (totalling %s point%s) available for %s.</p>',
(strplural and 'are' or 'is'),
prose.taskamount,
(moduleInvokedOnce and 'Combat Achievement' or '[[Combat Achievements|Combat Achievement]]'),
(strplural and 's' or ''),
prose.ptsamount,
(prose.ptsamount ~= 1 and 's' or ''),
prose.monster
) )
VariablesLua.vardefine( 'caListModuleInvoked', 0 )
return retstr .. rettbl
end
return p