12,787
edits
(fix header for new columns in Fishing table) |
(Move functions to Module:Skills; Move Farming functions from Module:Skills) |
||
(26 intermediate revisions by 3 users not shown) | |||
Line 9: | Line 9: | ||
local Items = require('Module:Items') | local Items = require('Module:Items') | ||
local Icons = require('Module:Icons') | local Icons = require('Module:Icons') | ||
local Skills = require('Module:Skills') | |||
local | local ItemSourceTables = require('Module:Items/SourceTables') | ||
local | |||
function p.getAxeTable(frame) | function p.getAxeTable(frame) | ||
Line 149: | Line 148: | ||
result = result..'||style="min-width:25px" data-sort-value="'..logName..'"|'..Icons.Icon({logName, type='item', notext=true, size=50}) | result = result..'||style="min-width:25px" data-sort-value="'..logName..'"|'..Icons.Icon({logName, type='item', notext=true, size=50}) | ||
result = result..'||'..Icons.Icon({logName, type='item', noicon=true}) | result = result..'||'..Icons.Icon({logName, type='item', noicon=true}) | ||
result = result..'||style="text-align:right"|'..tree. | result = result..'||style="text-align:right"|'..tree.levelRequired | ||
result = result..'||style="text-align:right"|'..tree. | result = result..'||style="text-align:right"|'..tree.baseExperience | ||
result = result..'||style="text-align:right" data-sort-value="'..tree. | result = result..'||style="text-align:right" data-sort-value="'..tree.baseInterval..'"|'..Shared.timeString(tree.baseInterval/1000, true) | ||
local XPs = tree. | local XPs = tree.baseExperience / (tree.baseInterval / 1000) | ||
local Log = Items.getItemByID( | local Log = Items.getItemByID(tree.logID) | ||
local GPs = Log.sellsFor / (tree. | local GPs = Log.sellsFor / (tree.baseInterval / 1000) | ||
result = result..'||style="text-align:right"|'..Shared.round(XPs, 2, 2) | result = result..'||style="text-align:right"|'..Shared.round(XPs, 2, 2) | ||
result = result..'||style="text-align:right" data-sort-value="'..GPs..'"|'..Icons.GP(Shared.round(GPs, 2, 2)) | result = result..'||style="text-align:right" data-sort-value="'..GPs..'"|'..Icons.GP(Shared.round(GPs, 2, 2)) | ||
Line 164: | Line 163: | ||
function p.getSpecialFishingTable(frame) | function p.getSpecialFishingTable(frame) | ||
local lootValue = 0 | local totalWt, lootValue = 0, 0 | ||
local totalWt = | local itemArray = Shared.clone(SkillData.Fishing.SpecialItems) | ||
for i, itemDef in ipairs(itemArray) do | |||
totalWt = totalWt + itemDef[2] | |||
end | |||
-- Sort the loot table by weight in descending order | |||
table.sort(itemArray, function(a, b) return (a[2] == b[2] and a[1] < b[1]) or a[2] > b[2] end) | |||
local | local resultPart = {} | ||
table.insert(resultPart, '\r\n{|class="wikitable sortable stickyHeader"') | |||
table.insert(resultPart, '\r\n|- class="headerRow-0"\r\n!colspan="2"| Item\r\n!Value\r\n!colspan="2"|Chance') | |||
for i, itemDef in ipairs(itemArray) do | |||
local item = Items.getItemByID(itemDef[1]) | |||
if item ~= nil then | |||
local dropChance = itemDef[2] / totalWt * 100 | |||
-- If chance is less than 0.10% then show 2 significant figures, otherwise 2 decimal places | |||
for i, | local fmt = (dropChance < 0.10 and '%.2g') or '%.2f' | ||
local | table.insert(resultPart, '\r\n|-\r\n|style="text-align:center"| ' .. Icons.Icon({item.name, type='item', notext=true})) | ||
table.insert(resultPart, '\r\n| ' .. Icons.Icon({item.name, type='item', noicon=true})) | |||
table.insert(resultPart, '\r\n|data-sort-value="' .. item.sellsFor .. '"| ' .. Icons.GP(math.floor(item.sellsFor))) | |||
table.insert(resultPart, '\r\n|style="text-align:right" data-sort-value="' .. itemDef[2] .. '"| ' .. Shared.fraction(itemDef[2], totalWt)) | |||
table.insert(resultPart, '\r\n|style="text-align:right"| ' .. string.format(fmt, dropChance) .. '%') | |||
lootValue = lootValue + (dropChance / 100 * item.sellsFor) | |||
end | |||
end | end | ||
table.insert(resultPart, '\r\n|}\r\nThe average value of a roll on the special fishing loot table is ' .. Icons.GP(Shared.round(lootValue, 2, 0))) | |||
return table.concat(resultPart) | |||
return | |||
end | end | ||
function p.getFishingJunkTable(frame) | function p.getFishingJunkTable(frame) | ||
local | local resultPart = {} | ||
table.insert(resultPart, '{| class="wikitable sortable stickyHeader"') | |||
table.insert(resultPart, '\r\n|- class="headerRow-0"') | |||
table.insert(resultPart, '\r\n!colspan="2"|Item!!Value') | |||
local itemArray = {} | |||
for i, itemID in ipairs(SkillData.Fishing.JunkItems) do | |||
local item = Items.getItemByID(itemID) | |||
if item ~= nil then | |||
table.insert(itemArray, item) | |||
end | |||
end | |||
table.sort(itemArray, function(a, b) return a.name < b.name end) | table.sort(itemArray, function(a, b) return a.name < b.name end) | ||
for i, item in | for i, item in ipairs(itemArray) do | ||
table.insert(resultPart, '\r\n|-') | |||
table.insert(resultPart, '\r\n|style="min-width:25px"| ' .. Icons.Icon({item.name, type='item', notext=true, size=50})) | |||
table.insert(resultPart, '\r\n| ' .. Icons.Icon({item.name, type='item', noicon=true})) | |||
table.insert(resultPart, '\r\n|data-sort-value="' .. item.sellsFor .. '"| ' .. Icons.GP(math.floor(item.sellsFor))) | |||
end | end | ||
table.insert(resultPart, '\r\n|}') | |||
return table.concat(resultPart) | |||
return | |||
end | end | ||
Line 222: | Line 225: | ||
local mineData = Shared.clone(SkillData.Mining.Rocks) | local mineData = Shared.clone(SkillData.Mining.Rocks) | ||
table.sort(mineData, function(a, b) return a. | table.sort(mineData, function(a, b) return a.levelRequired < b.levelRequired end) | ||
for i, oreData in Shared.skpairs(mineData) do | for i, oreData in Shared.skpairs(mineData) do | ||
local ore = Items.getItemByID(oreData. | local ore = Items.getItemByID(oreData.oreID) | ||
result = result..'\r\n|-\r\n|style="min-width:25px"|'..Icons.Icon({ore.name, type='item', size='50', notext=true}) | result = result..'\r\n|-\r\n|style="min-width:25px"|'..Icons.Icon({ore.name, type='item', size='50', notext=true}) | ||
result = result..'||'..Icons.Icon({ore.name, type='item', noicon=true}) | result = result..'||'..Icons.Icon({ore.name, type='item', noicon=true}) | ||
result = result..'||style="text-align:right"|'..oreData. | result = result..'||style="text-align:right"|'..oreData.levelRequired..'||style="text-align:right"|'..oreData.baseExperience | ||
result = result..'||style="text-align:right" data-sort-value="'..oreData. | result = result..'||style="text-align:right" data-sort-value="'..oreData.baseRespawnInterval..'"|' | ||
result = result..Shared.timeString(oreData. | result = result..Shared.timeString(oreData.baseRespawnInterval / 1000, true) | ||
result = result..'||data-sort-value="'..ore.sellsFor..'"|'..Icons.GP(ore.sellsFor) | result = result..'||data-sort-value="'..ore.sellsFor..'"|'..Icons.GP(ore.sellsFor) | ||
end | end | ||
Line 258: | Line 261: | ||
function p.getFishTable(frame) | function p.getFishTable(frame) | ||
local | local recipeList = {} | ||
for i, recipe in ipairs(SkillData.Fishing.Fish) do | |||
table.insert(recipeList, recipe) | |||
end | |||
table.sort(recipeList, function(a, b) return (a.level == b.level and a.masteryID < b.masteryID) or a.level < b.level end) | |||
-- Determine cooking levels for all fish | |||
local cookReq = {} | |||
for i, recipe in ipairs(SkillData.Cooking.Recipes) do | |||
-- This assumes that each raw fish only appears in a single recipe, which is a bit rubbish | |||
-- but currently holds | |||
for j, mat in ipairs(recipe.itemCosts) do | |||
if cookReq[mat.id] == nil then | |||
cookReq[mat.id] = recipe.level | |||
end | |||
end | |||
end | |||
local | local resultPart = {} | ||
table.insert(resultPart, '{| class="wikitable sortable stickyHeader"') | |||
table.insert(resultPart, '\r\n|- class="headerRow-0"') | |||
table.insert(resultPart, '\r\n!Fish\r\n!Name\r\n!' .. Icons.Icon({'Fishing', type='skill', notext=true}) .. ' Level\r\n!Catch Time') | |||
table.insert(resultPart, '\r\n!XP\r\n!Value\r\n!XP/s\r\n!GP/s') | |||
table.insert(resultPart, '\r\n!' .. Icons.Icon({'Cooking', type='skill', notext=true}) .. ' Level') | |||
for i, fish | for i, recipe in ipairs(recipeList) do | ||
local fish = Items.getItemByID(recipe.itemID) | |||
if fish ~= nil then | |||
local timeSortVal = (recipe.baseMinInterval + recipe.baseMaxInterval) / 2000 | |||
local timeStr = string.format("%.1fs - %.1fs", recipe.baseMinInterval / 1000, recipe.baseMaxInterval / 1000) | |||
local XPs = recipe.baseXP / timeSortVal | |||
local GPs = fish.sellsFor / timeSortVal | |||
local cookSortVal = cookReq[recipe.itemID] or 0 | |||
local cookStr = cookReq[recipe.itemID] or 'N/A' | |||
table.insert(resultPart, '\r\n|-') | |||
table.insert(resultPart, '\r\n|style="text-align:center"| ' .. Icons.Icon({fish.name, type='item', size='50', notext=true})) | |||
table.insert(resultPart, '\r\n| ' .. Icons.Icon({fish.name, type='item', noicon=true})) | |||
table.insert(resultPart, '\r\n|style="text-align:right"| ' .. recipe.level) | |||
table.insert(resultPart, '\r\n|style="text-align:right" data-sort-value="' .. timeSortVal .. '"| ' .. timeStr) | |||
table.insert(resultPart, '\r\n|style="text-align:right"| ' .. recipe.baseXP) | |||
table.insert(resultPart, '\r\n|data-sort-value="' .. fish.sellsFor .. '"| ' .. Icons.GP(fish.sellsFor)) | |||
table.insert(resultPart, '\r\n|style="text-align:right"| ' .. Shared.round(XPs, 2, 2)) | |||
table.insert(resultPart, '\r\n|data-sort-value="' .. GPs .. '"|' .. Icons.GP(Shared.round(GPs, 2, 2))) | |||
table.insert(resultPart, '\r\n|style="text-align:right" data-sort-value="' .. cookSortVal .. '"| ' .. cookStr) | |||
end | end | ||
end | end | ||
table.insert(resultPart, '\r\n|}') | |||
return table.concat(resultPart) | |||
return | |||
end | end | ||
function p.getFishingAreasTable(frame) | function p.getFishingAreasTable(frame) | ||
local result = '{| class="wikitable sortable stickyHeader"' | local result = '{| class="wikitable sortable stickyHeader"' | ||
result = result..'\r\n|- class="headerRow-0"' | result = result..'\r\n|- class="headerRow-0"' | ||
Line 302: | Line 316: | ||
result = result..'\r\n!Junk Chance\r\n!Special Chance' | result = result..'\r\n!Junk Chance\r\n!Special Chance' | ||
for i, area in | for i, area in ipairs(SkillData.Fishing.Areas) do | ||
result = result..'\r\n|-' | result = result..'\r\n|-' | ||
result = result..'\r\n| style ="text-align: left;" |'..area.name | result = result..'\r\n| style ="text-align: left;" |'..area.name | ||
local fishArray = {} | local fishArray = {} | ||
for j, fish in | for j, fish in ipairs(area.fish) do | ||
local | local fishItem = Items.getItemByID(fish.itemID) | ||
if fishItem ~= nil then | |||
table.insert(fishArray, Icons.Icon({fishItem.name, type='item'})) | |||
end | |||
end | end | ||
result = result..'\r\n|'..table.concat(fishArray, '<br />') | result = result..'\r\n|'..table.concat(fishArray, '<br/>') | ||
result = result..'\r\n| style="text-align:right"|'..area.fishChance..'%' | result = result..'\r\n| style="text-align:right"|'..area.fishChance..'%' | ||
Line 321: | Line 336: | ||
result = result..'\r\n|}' | result = result..'\r\n|}' | ||
return result | return result | ||
end | end | ||
Line 390: | Line 345: | ||
local thisItem = Items.getItemByID(drop.itemID) | local thisItem = Items.getItemByID(drop.itemID) | ||
local odds = drop.chance | local odds = drop.chance | ||
rareTxt = rareTxt..'\r\n|-\r\n|'..Icons.Icon({thisItem.name, type='item'}) | rareTxt = rareTxt..'\r\n|-\r\n|'..Icons.Icon({thisItem.name, type='item'}) | ||
rareTxt = rareTxt..'||1||data-sort-value="'..thisItem.sellsFor..'"|'..Icons.GP(thisItem.sellsFor) | rareTxt = rareTxt..'||1||data-sort-value="'..thisItem.sellsFor..'"|'..Icons.GP(thisItem.sellsFor) | ||
Line 403: | Line 358: | ||
local result = '' | local result = '' | ||
local sectionTxt = {} | local sectionTxt = {} | ||
--Five sections here: GP, normal loot, area loot, rare loot, and unique item | --Five sections here: GP, normal loot, area loot, rare loot, and unique item | ||
--First up, GP: | --First up, GP: | ||
local gpTxt = 'Successfully pickpocketing the '..npc.name..' will always give '..Icons.GP(1, npc.maxGP) | local gpTxt = 'Successfully pickpocketing the '..npc.name..' will always give '..Icons.GP(1, npc.maxGP) | ||
table.insert(sectionTxt, gpTxt) | table.insert(sectionTxt, gpTxt) | ||
--Next up, normal loot: | --Next up, normal loot: | ||
--(Skip if no loot) | --(Skip if no loot) | ||
Line 414: | Line 369: | ||
local normalTxt = '===Possible Common Drops:===\r\nUp to one of these will be received on a successful pickpocket:' | local normalTxt = '===Possible Common Drops:===\r\nUp to one of these will be received on a successful pickpocket:' | ||
local totalWt = 0 | local totalWt = 0 | ||
local lootChance = | local lootChance = SkillData.Thieving.ItemChance | ||
local lootValue = 0 | local lootValue = 0 | ||
--First loop through to get the total weight so we have it for later | --First loop through to get the total weight so we have it for later | ||
for i, loot in pairs(npc.lootTable) do | for i, loot in pairs(npc.lootTable) do | ||
totalWt = totalWt + loot[2] | totalWt = totalWt + loot[2] | ||
end | end | ||
normalTxt = normalTxt..'\r\n{|class="wikitable sortable"' | normalTxt = normalTxt..'\r\n{|class="wikitable sortable"' | ||
normalTxt = normalTxt..'\r\n!Item!!Qty' | normalTxt = normalTxt..'\r\n!Item!!Qty' | ||
normalTxt = normalTxt..'!!Price!!colspan="2"|Chance' | normalTxt = normalTxt..'!!Price!!colspan="2"|Chance' | ||
--Then sort the loot table by weight | --Then sort the loot table by weight | ||
table.sort(npc.lootTable, function(a, b) return a[2] > b[2] end) | table.sort(npc.lootTable, function(a, b) return a[2] > b[2] end) | ||
Line 437: | Line 392: | ||
end | end | ||
normalTxt = normalTxt..'||style="text-align:right" data-sort-value="'..maxQty..'"|' | normalTxt = normalTxt..'||style="text-align:right" data-sort-value="'..maxQty..'"|' | ||
if maxQty > 1 then | if maxQty > 1 then | ||
normalTxt = normalTxt.. '1 - ' | normalTxt = normalTxt.. '1 - ' | ||
end | end | ||
normalTxt = normalTxt..Shared.formatnum(row[3]) | normalTxt = normalTxt..Shared.formatnum(row[3]) | ||
--Adding price columns | --Adding price columns | ||
local itemPrice = 0 | local itemPrice = 0 | ||
Line 455: | Line 410: | ||
end | end | ||
end | end | ||
--Getting the drop chance | --Getting the drop chance | ||
local dropChance = (row[2] / totalWt * lootChance) | local dropChance = (row[2] / totalWt * lootChance) | ||
Line 467: | Line 422: | ||
end | end | ||
normalTxt = normalTxt..'style="text-align:right"|'..Shared.round(dropChance, 2, 2)..'%' | normalTxt = normalTxt..'style="text-align:right"|'..Shared.round(dropChance, 2, 2)..'%' | ||
--Adding to the average loot value based on price & dropchance | --Adding to the average loot value based on price & dropchance | ||
lootValue = lootValue + (dropChance * 0.01 * itemPrice * ((1 + maxQty) / 2)) | lootValue = lootValue + (dropChance * 0.01 * itemPrice * ((1 + maxQty) / 2)) | ||
end | end | ||
if | if Shared.tableCount(npc.lootTable) > 1 then | ||
normalTxt = normalTxt..'\r\n|-class="sortbottom" \r\n!colspan="3"|Total:' | normalTxt = normalTxt..'\r\n|-class="sortbottom" \r\n!colspan="3"|Total:' | ||
if lootChance < 100 then | if lootChance < 100 then | ||
Line 478: | Line 433: | ||
normalTxt = normalTxt..'\r\n|colspan="2" ' | normalTxt = normalTxt..'\r\n|colspan="2" ' | ||
end | end | ||
normalTxt = normalTxt..'style="text-align:right"|'..lootChance..' | normalTxt = normalTxt..'style="text-align:right"|'..Shared.round(lootChance, 2, 2)..'%' | ||
end | end | ||
normalTxt = normalTxt..'\r\n|}' | normalTxt = normalTxt..'\r\n|}' | ||
table.insert(sectionTxt, normalTxt) | table.insert(sectionTxt, normalTxt) | ||
end | end | ||
--After normal drops, add in rare drops | --After normal drops, add in rare drops | ||
local rareTxt = '===Possible Rare Drops:===\r\nAny of these can be received after a successful pickpocket' | local rareTxt = '===Possible Rare Drops:===\r\nAny of these can be received after a successful pickpocket' | ||
rareTxt = rareTxt..'\r\n'..p.getThievingGeneralRareTable() | rareTxt = rareTxt..'\r\n'..p.getThievingGeneralRareTable() | ||
table.insert(sectionTxt, rareTxt) | table.insert(sectionTxt, rareTxt) | ||
local areaTxt = '===Possible Area Unique Drops===' | local areaTxt = '===Possible Area Unique Drops===' | ||
areaTxt = areaTxt..'\r\nAny Area Unique Drop is equally likely to be obtained after a successful pickpocket. ' | areaTxt = areaTxt..'\r\nAny Area Unique Drop is equally likely to be obtained after a successful pickpocket. ' | ||
areaTxt = areaTxt..'\r\nEach Area Unique Drop is rolled for separately, so it is possible to receive multiple Area Unique Drops from a single action. ' | areaTxt = areaTxt..'\r\nEach Area Unique Drop is rolled for separately, so it is possible to receive multiple Area Unique Drops from a single action. ' | ||
areaTxt = areaTxt..'The chance of receiving an Area Unique drop is tripled if the 95% Thieving Mastery Pool checkpoint is active.' | areaTxt = areaTxt..'The chance of receiving an Area Unique drop is tripled if the 95% Thieving Mastery Pool checkpoint is active.' | ||
local area = | local area = Skills.getThievingNPCArea(npc) | ||
areaTxt = areaTxt..'\r\n{|class="wikitable sortable"' | areaTxt = areaTxt..'\r\n{|class="wikitable sortable"' | ||
areaTxt = areaTxt..'\r\n!Item!!Qty' | areaTxt = areaTxt..'\r\n!Item!!Qty' | ||
Line 505: | Line 460: | ||
lineTxt = lineTxt..'\r\n|-\r\n|'..Icons.Icon({thisItem.name, type='item'}) | lineTxt = lineTxt..'\r\n|-\r\n|'..Icons.Icon({thisItem.name, type='item'}) | ||
lineTxt = lineTxt..'||'..drop.qty..'||data-sort-value="'..thisItem.sellsFor..'"|'..Icons.GP(thisItem.sellsFor) | lineTxt = lineTxt..'||'..drop.qty..'||data-sort-value="'..thisItem.sellsFor..'"|'..Icons.GP(thisItem.sellsFor) | ||
lineTxt = lineTxt..'||style="text-align:right"|'..Shared.fraction(1, 1/( | lineTxt = lineTxt..'||style="text-align:right"|'..Shared.fraction(1, 1/(SkillData.Thieving.AreaUniqueChance/100)) | ||
lineTxt = lineTxt..'||'..Shared.round( | lineTxt = lineTxt..'||'..Shared.round(SkillData.Thieving.AreaUniqueChance, 2, 2)..'%' | ||
dropLines[thisItem.name] = lineTxt | dropLines[thisItem.name] = lineTxt | ||
end | end | ||
Line 513: | Line 468: | ||
end | end | ||
areaTxt = areaTxt..'\r\n|-class="sortbottom" \r\n!colspan="3"|Total:' | areaTxt = areaTxt..'\r\n|-class="sortbottom" \r\n!colspan="3"|Total:' | ||
areaTxt = areaTxt..'\r\n|style="text-align:right"|'..Shared.fraction(1, 1/( | areaTxt = areaTxt..'\r\n|style="text-align:right"|'..Shared.fraction(1, 1/(SkillData.Thieving.AreaUniqueChance/100))..'||' | ||
areaTxt = areaTxt..'style="text-align:right"|'..Shared.round( | areaTxt = areaTxt..'style="text-align:right"|'..Shared.round(SkillData.Thieving.AreaUniqueChance, 2, 2)..'%' | ||
areaTxt = areaTxt..'\r\n|}' | areaTxt = areaTxt..'\r\n|}' | ||
table.insert(sectionTxt, areaTxt) | table.insert(sectionTxt, areaTxt) | ||
if npc.uniqueDrop ~= nil and npc.uniqueDrop.itemID > -1 then | if npc.uniqueDrop ~= nil and npc.uniqueDrop.itemID > -1 then | ||
local uniqueTxt = '===Possible NPC Unique Drop===' | local uniqueTxt = '===Possible NPC Unique Drop===' | ||
Line 529: | Line 484: | ||
uniqueTxt = uniqueTxt..Icons.Icon({thisItem.name, type='item'}) | uniqueTxt = uniqueTxt..Icons.Icon({thisItem.name, type='item'}) | ||
end | end | ||
table.insert(sectionTxt, uniqueTxt) | table.insert(sectionTxt, uniqueTxt) | ||
end | end | ||
return table.concat(sectionTxt, '\r\n') | return table.concat(sectionTxt, '\r\n') | ||
end | end | ||
Line 538: | Line 493: | ||
function p.getThievingNPCLootTables(frame) | function p.getThievingNPCLootTables(frame) | ||
local npcName = frame.args ~= nil and frame.args[1] or frame | local npcName = frame.args ~= nil and frame.args[1] or frame | ||
local npc = | local npc = Skills.getThievingNPC(npcName) | ||
if npc == nil then | if npc == nil then | ||
return "ERROR: Invalid Thieving NPC "..npcName.."[[Category:Pages with script errors]]" | return "ERROR: Invalid Thieving NPC "..npcName.."[[Category:Pages with script errors]]" | ||
end | end | ||
return p._getThievingNPCLootTables(npc) | return p._getThievingNPCLootTables(npc) | ||
end | end | ||
Line 549: | Line 504: | ||
local result = '{| class="wikitable sortable stickyHeader"' | local result = '{| class="wikitable sortable stickyHeader"' | ||
result = result..'\r\n|- class="headerRow-0"' | result = result..'\r\n|- class="headerRow-0"' | ||
result = result..'\r\n!colspan="2"|Name!!Area!!'..Icons.Icon({'Thieving', type='skill', notext=true})..' Level!!Experience!!Max Hit!!Perception!!Unique Drop' | result = result..'\r\n!colspan="2"|Name!!Area!!'..Icons.Icon({'Thieving', type='skill', notext=true})..' Level!!Experience!!Max Hit!!Perception!!GP!!Unique Drop' | ||
local npcArray = Shared.clone(SkillData.Thieving.NPCs) | local npcArray = Shared.clone(SkillData.Thieving.NPCs) | ||
table.sort(npcArray, function(a, b) return a.level < b.level end) | table.sort(npcArray, function(a, b) return a.level < b.level end) | ||
Line 557: | Line 512: | ||
result = result..'||'..Icons.Icon({npc.name, type='thieving', noicon=true}) | result = result..'||'..Icons.Icon({npc.name, type='thieving', noicon=true}) | ||
local area = | local area = Skills.getThievingNPCArea(npc) | ||
result = result..'||'..area.name | result = result..'||'..area.name | ||
result = result..'||'..Icons._SkillReq('Thieving', npc.level) | result = result..'||'..Icons._SkillReq('Thieving', npc.level) | ||
Line 563: | Line 518: | ||
result = result..'||style="text-align:right"|'..(npc.maxHit * 10) | result = result..'||style="text-align:right"|'..(npc.maxHit * 10) | ||
result = result..'||style="text-align:right"|'..npc.perception | result = result..'||style="text-align:right"|'..npc.perception | ||
result = result..'||data-sort-value="' .. npc.maxGP .. '"|'..Icons.GP(1, npc.maxGP) | |||
if npc.uniqueDrop ~= nil and npc.uniqueDrop.itemID > -1 then | if npc.uniqueDrop ~= nil and npc.uniqueDrop.itemID > -1 then | ||
local uniqueDrop = Items.getItemByID(npc.uniqueDrop.itemID) | local uniqueDrop = Items.getItemByID(npc.uniqueDrop.itemID) | ||
Line 575: | Line 531: | ||
end | end | ||
result = result..'\r\n|}' | result = result..'\r\n|}' | ||
return result | return result | ||
end | end | ||
Line 584: | Line 540: | ||
table.insert(resultPart, '\r\n|- class="headerRow-0"') | table.insert(resultPart, '\r\n|- class="headerRow-0"') | ||
table.insert(resultPart, '\r\n!Area!!'..Icons.Icon({'Thieving', type='skill', notext=true})..' Level!!NPCs!!Unique Drops') | table.insert(resultPart, '\r\n!Area!!'..Icons.Icon({'Thieving', type='skill', notext=true})..' Level!!NPCs!!Unique Drops') | ||
local areaArray = Shared.clone(SkillData.Thieving.Areas) | local areaArray = Shared.clone(SkillData.Thieving.Areas) | ||
table.sort(areaArray, function(a, b) return a.id < b.id end) | table.sort(areaArray, function(a, b) return a.id < b.id end) | ||
Line 603: | Line 559: | ||
table.insert(npcList, '') | table.insert(npcList, '') | ||
end | end | ||
-- Build area unique item list | -- Build area unique item list | ||
if area.uniqueDrops ~= nil and Shared.tableCount(area.uniqueDrops) > 0 then | if area.uniqueDrops ~= nil and Shared.tableCount(area.uniqueDrops) > 0 then | ||
Line 621: | Line 577: | ||
table.insert(areaItemList, '') | table.insert(areaItemList, '') | ||
end | end | ||
-- Generate table row | -- Generate table row | ||
table.insert(resultPart, '\r\n|-') | table.insert(resultPart, '\r\n|-') | ||
Line 630: | Line 586: | ||
end | end | ||
table.insert(resultPart, '\r\n|}') | table.insert(resultPart, '\r\n|}') | ||
return table.concat(resultPart) | return table.concat(resultPart) | ||
end | end | ||
function p. | function p._getFarmingTable(category) | ||
local | local seedList = {} | ||
if category == 'Allotment' or category == 'Herb' or category == 'Tree' then | |||
local | seedList = Items.getItems(function(item) return item.tier == category end) | ||
else | |||
-- | return 'ERROR: Invalid farming category. Please choose Allotment, Herb, or Tree' | ||
end | |||
if | |||
for | local result = '{|class="wikitable sortable stickyHeader"' | ||
result = result..'\r\n|- class="headerRow-0"' | |||
result = result..'\r\n!colspan=2|Seeds!!'..Icons.Icon({'Farming', type='skill', notext=true})..' Level' | |||
result = result..'!!XP!!Growth Time!!Seed Value' | |||
if category == 'Allotment' then | |||
result = result..'!!colspan="2"|Crop!!Crop Healing!!Crop Value' | |||
elseif category == 'Herb' then | |||
result = result..'!!colspan="2"|Herb!!Herb Value' | |||
elseif category == 'Tree' then | |||
result = result..'!!colspan="2"|Logs!!Log Value' | |||
end | |||
result = result..'!!Seed Sources' | |||
table.sort(seedList, function(a, b) return a.farmingLevel < b.farmingLevel end) | |||
for i, seed in pairs(seedList) do | |||
result = result..'\r\n|-' | |||
result = result..'\r\n|'..Icons.Icon({seed.name, type='item', size='50', notext=true})..'||[['..seed.name..']]' | |||
result = result..'||'..seed.farmingLevel..'||'..Shared.formatnum(seed.farmingXP) | |||
result = result..'||data-sort-value="'..seed.timeToGrow..'"|'..Shared.timeString(seed.timeToGrow, true) | |||
result = result..'||data-sort-value="'..seed.sellsFor..'"|'..Icons.GP(seed.sellsFor) | |||
local crop = Items.getItemByID(seed.grownItemID) | |||
result = result..'||'..Icons.Icon({crop.name, type='item', size='50', notext=true})..'||[['..crop.name..']]' | |||
if category == 'Allotment' then | |||
result = result..'||'..Icons.Icon({'Hitpoints', type='skill', notext=true})..' '..(crop.healsFor * 10) | |||
end | |||
result = result..'||data-sort-value="'..crop.sellsFor..'"|'..Icons.GP(crop.sellsFor) | |||
result = result..'||'..ItemSourceTables._getItemSources(seed) | |||
end | |||
result = result..'\r\n|}' | |||
return result | |||
end | |||
function p.getFarmingTable(frame) | |||
local category = frame.args ~= nil and frame.args[1] or frame | |||
return p._getFarmingTable(category) | |||
end | |||
function p.getFarmingFoodTable(frame) | |||
local result = '{| class="wikitable sortable stickyHeader"' | |||
result = result..'\r\n|- class="headerRow-0"' | |||
result = result..'\r\n!colspan="2"|Crop!!'..Icons.Icon({"Farming", type="skill", notext=true})..' Level' | |||
result = result..'!!Healing!!Value' | |||
local itemArray = Items.getItems(function(item) return item.grownItemID ~= nil end) | |||
table.sort(itemArray, function(a, b) return a.farmingLevel < b.farmingLevel end) | |||
for i, item in Shared.skpairs(itemArray) do | |||
local crop = Items.getItemByID(item.grownItemID) | |||
if crop.healsFor ~= nil and crop.healsFor > 0 then | |||
result = result..'\r\n|-' | |||
result = result..'\r\n|'..Icons.Icon({crop.name, type='item', notext='true', size='50'})..'||[['..crop.name..']]' | |||
result = result..'||style="text-align:right;"|'..item.farmingLevel | |||
result = result..'||style="text-align:right" data-sort-value="'..crop.healsFor..'"|'..Icons.Icon({"Hitpoints", type="skill", notext=true})..' '..(crop.healsFor * 10) | |||
result = result..'||style="text-align:right" data-sort-value="'..crop.sellsFor..'"|'..Icons.GP(crop.sellsFor) | |||
end | |||
end | |||
result = result..'\r\n|}' | |||
return result | |||
end | |||
function p.getFarmingPlotTable(frame) | |||
local areaName = frame.args ~= nil and frame.args[1] or frame | |||
local patches = nil | |||
for i, area in Shared.skpairs(SkillData.Farming.Patches) do | |||
if area.areaName == areaName then | |||
patches = area.patches | |||
break | |||
end | end | ||
end | end | ||
if patches == nil then | |||
return "ERROR: Invalid area name.[[Category:Pages with script errors]]" | |||
for i, | end | ||
local result = '{|class="wikitable"' | |||
result = result..'\r\n!Plot!!'..Icons.Icon({'Farming', type='skill', notext=true})..' Level!!Cost' | |||
for i, patch in Shared.skpairs(patches) do | |||
result = result..'\r\n|-\r\n|'..i | |||
result = result..'||style="text-align:right;" data-sort-value="' .. patch.level .. '"|'..patch.level | |||
if patch.cost == 0 then | |||
result = result..'||Free' | |||
else | |||
result = result..'||style="text-align:right;" data-sort-value="'..patch.cost..'"|'..Icons.GP(patch.cost) | |||
end | end | ||
end | |||
result = result..'\r\n|}' | |||
return result | |||
end | |||
function p._buildAstrologyConstellationTable() | |||
local maxModifier = 5 | |||
local result = '{|class="wikitable sortable stickyHeader"' | |||
result = result..'\r\n|- class="headerRow-0"' | |||
result = result..'\r\n!colspan="2"|Constellation!!'..Icons.Icon({"Astrology", type='skill', notext='true'})..' Level' | |||
result = result..'!!XP!!Skills!!Standard Modifiers!!Unique Modifiers' | |||
for i, cons in ipairs(SkillData.Astrology.Constellations) do | |||
local name = cons.name | |||
result = result..'\r\n|-' | |||
result = result..'\r\n|data-sort-value="'..name..'"|'..Icons.Icon({name, type='constellation', size='50', notext=true})..'||'..name | |||
result = result..'||'..cons.level..'||'..cons.provides.xp | |||
local skillIconArray = {} | |||
for j, skillID in ipairs(cons.skills) do | |||
table.insert(skillIconArray, Icons.Icon({Constants.getSkillName(skillID), type='skill'})) | |||
end | end | ||
result = result..'||'..table.concat(skillIconArray, '<br/>') | |||
-- | |||
local standModsRaw = Skills._buildAstrologyModifierArray(cons, maxModifier, true, false, false, false) | |||
table.insert( | local standMods = {} | ||
--Building the list of Standard modifiers: | |||
for j, modifier in ipairs(standModsRaw) do | |||
table.insert(standMods, Constants._getModifierText(modifier[1], modifier[2], false)) | |||
end | end | ||
result = result..'|| '..table.concat(standMods, '<br/>') | |||
table.insert( | --Building the list of all Unique Modifiers | ||
local uModsRaw = Skills._buildAstrologyModifierArray(cons, maxModifier, false, true, false, false) | |||
local uMods = {} | |||
for j, modifier in ipairs(uModsRaw) do | |||
table.insert(uMods, Constants._getModifierText(modifier[1], modifier[2], false)) | |||
end | end | ||
result = result..'||'..table.concat(uMods, '<br/>') | |||
end | end | ||
result = result..'\r\n|}' | |||
for i, | |||
return result | |||
end | |||
function p.buildAstrologyConstellationTable(frame) | |||
return p._buildAstrologyConstellationTable() | |||
end | |||
function p.buildAstrologyValueTable() | |||
local result = '{|class="wikitable sortable"' | |||
result = result..'\r\n!rowspan="2"| Value!!colspan="2"| Chance' | |||
result = result..'\r\n|-\r\n! This Value!! This Value or Greater' | |||
local cumulativeChance = 100 | |||
for i, chance in ipairs(SkillData.Astrology.ModifierMagnitudeChances) do | |||
result = result..'\r\n|-' | |||
result = result..'\r\n|style="text-align:right"| ' .. i | |||
result = result..'\r\n|style="text-align:right"| ' .. chance .. '%' | |||
result = result..'\r\n|style="text-align:right"| ' .. cumulativeChance .. '%' | |||
cumulativeChance = cumulativeChance - chance | |||
end | end | ||
result = result..'\r\n|}' | |||
return | return result | ||
end | end | ||
return p | return p |