16,985
edits
(Fix Mining pickaxe requirement issue) |
(Update for v1.3) |
||
Line 7: | Line 7: | ||
local SkillData = GameData.skillData | local SkillData = GameData.skillData | ||
local Common = require('Module:Common') | local Common = require('Module:Common') | ||
local | local Modifiers = require('Module:Modifiers') | ||
local Items = require('Module:Items') | local Items = require('Module:Items') | ||
local Icons = require('Module:Icons') | local Icons = require('Module:Icons') | ||
Line 13: | Line 13: | ||
local ItemSourceTables = require('Module:Items/SourceTables') | local ItemSourceTables = require('Module:Items/SourceTables') | ||
function | local function lootValueText(lootValue) | ||
local | local returnPart = {} | ||
for _, currencyDefn in ipairs(GameData.rawData.currencies) do | |||
-- Guarantee order by iterating through currency game data definition | |||
local currID = currencyDefn.id | |||
local val = Shared.round(lootValue[currID], 2, 2) | |||
if val ~= nil then | |||
table.insert(returnPart, Icons._Currency(currID, val)) | |||
if | |||
table.insert( | |||
end | end | ||
end | end | ||
return table.concat( | return table.concat(returnPart, ', ') | ||
end | end | ||
function p.getTreesTable(frame) | function p.getTreesTable(frame) | ||
local args = frame.args ~= nil and frame.args or frame | |||
local realmName = args.realm | |||
local realm = Skills.getRealmFromName(realmName) | |||
if realm == nil then | |||
return Shared.printError('Failed to find a realm with name ' .. (realmName or 'nil')) | |||
end | |||
local skillID = 'Woodcutting' | |||
local resultPart = {} | local resultPart = {} | ||
table.insert(resultPart, '{| class="wikitable sortable"') | table.insert(resultPart, '{| class="wikitable sortable stickyHeader"') | ||
table.insert(resultPart, '\n|- class="headerRow-0"') | table.insert(resultPart, '\n|- class="headerRow-0"') | ||
table.insert(resultPart, '\n!colspan="2"|Tree!!colspan="2"|Logs!!Requirements') | table.insert(resultPart, '\n!colspan="2"|Tree!!colspan="2"|Logs!!Requirements') | ||
table.insert(resultPart, '!!XP!!Cut Time!!XP/s!! | table.insert(resultPart, '!!XP!!Cut Time!!XP/s!!Price/s') | ||
local trees = | local trees = GameData.getEntities(SkillData.Woodcutting.trees, | ||
table.sort(trees, function(a, b) return a | function(tree) | ||
return Skills.getRecipeRealm(tree) == realm.id | |||
end | |||
) | |||
table.sort(trees, function(a, b) return Skills.standardRecipeSort(skillID, a, b) end) | |||
for i, tree in ipairs(trees) do | for i, tree in ipairs(trees) do | ||
local level = Skills.getRecipeLevel(skillID, tree) | |||
local baseXP = tree.baseAbyssalExperience or tree.baseExperience | |||
local baseInt = tree.baseInterval | |||
local reqText = Skills.getRecipeRequirementText(SkillData.Woodcutting.name, tree) | |||
local log = Items.getItemByID(tree.productId) | local log = Items.getItemByID(tree.productId) | ||
local sellCurrency = log.sellsForCurrency or 'melvorD:GP' | |||
local XPSec = baseXP / (baseInt / 1000) | |||
local currSec = Shared.round(log.sellsFor / (baseInt / 1000), 2, 2) | |||
table.insert(resultPart, '\n|-') | table.insert(resultPart, '\n|-') | ||
table.insert(resultPart, '\n|class="table-img" data-sort-value="'..tree.name..'"| '..Icons.Icon({log.name, img=tree.name, type='tree', notext=true, size=50})) | table.insert(resultPart, '\n|class="table-img" data-sort-value="'..tree.name..'"| '..Icons.Icon({log.name, img=tree.name, type='tree', notext=true, size=50})) | ||
Line 59: | Line 62: | ||
table.insert(resultPart, '\n|class="table-img" data-sort-value="'..log.name..'"| '..Icons.Icon({log.name, type='item', notext=true, size=50})) | table.insert(resultPart, '\n|class="table-img" data-sort-value="'..log.name..'"| '..Icons.Icon({log.name, type='item', notext=true, size=50})) | ||
table.insert(resultPart, '\n| '..Icons.Icon({log.name, type='item', noicon=true})) | table.insert(resultPart, '\n| '..Icons.Icon({log.name, type='item', noicon=true})) | ||
table.insert(resultPart, '\n|data-sort-value="' . | table.insert(resultPart, '\n|data-sort-value="' .. level .. '"| ' .. reqText) | ||
table.insert(resultPart, '\n|style="text-align:right"| '.. | table.insert(resultPart, '\n|style="text-align:right"| ' .. Shared.formatnum(baseXP)) | ||
table.insert(resultPart, '\n|style="text-align:right" data-sort-value="'.. | table.insert(resultPart, '\n|style="text-align:right" data-sort-value="'..baseInt..'"| '..Shared.timeString(baseInt / 1000, true)) | ||
table.insert(resultPart, '\n|style="text-align:right"| '..Shared.round(XPSec, 2, 2)) | |||
table.insert(resultPart, '\n|style="text-align:right" data-sort-value="'..currSec..'"| '..Icons._Currency(sellCurrency, currSec)) | |||
table.insert(resultPart, '\n|style="text-align:right"| '..Shared.round( | |||
table.insert(resultPart, '\n|style="text-align:right" data-sort-value="'.. | |||
end | end | ||
Line 73: | Line 74: | ||
function p.getSpecialFishingTable(frame) | function p.getSpecialFishingTable(frame) | ||
local totalWt, lootValue = 0, | local args = frame.args ~= nil and frame.args or frame | ||
local | local realmName = args.realm | ||
local realm = Skills.getRealmFromName(realmName) | |||
if realm == nil then | |||
return Shared.printError('Failed to find a realm with name ' .. (realmName or 'nil')) | |||
end | |||
local totalWt, lootValue = 0, {} | |||
local realmSpecials = GameData.getEntityByProperty(SkillData.Fishing.specialItems, 'realmID', realm.id) | |||
if realmSpecials == nil then | |||
return '' | |||
end | |||
local itemArray = realmSpecials.drops | |||
for i, itemDef in ipairs(itemArray) do | for i, itemDef in ipairs(itemArray) do | ||
totalWt = totalWt + itemDef.weight | totalWt = totalWt + itemDef.weight | ||
Line 88: | Line 100: | ||
if item ~= nil then | if item ~= nil then | ||
local dropChance = itemDef.weight / totalWt * 100 | local dropChance = itemDef.weight / totalWt * 100 | ||
local currID = item.sellsForCurrency or 'melvorD:GP' | |||
-- If chance is less than 0.10% then show 2 significant figures, otherwise 2 decimal places | -- If chance is less than 0.10% then show 2 significant figures, otherwise 2 decimal places | ||
local fmt = (dropChance < 0.10 and '%.2g') or '%.2f' | local fmt = (dropChance < 0.10 and '%.2g') or '%.2f' | ||
table.insert(resultPart, '\r\n|-\r\n|class="table-img"| ' .. Icons.Icon({item.name, type='item', notext=true})) | table.insert(resultPart, '\r\n|-\r\n|class="table-img"| ' .. 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| ' .. Icons.Icon({item.name, type='item', noicon=true})) | ||
table.insert(resultPart, '\r\n|data-sort-value="' .. item.sellsFor .. '"| ' .. | table.insert(resultPart, '\r\n|data-sort-value="' .. item.sellsFor .. '"| ' .. Items.getValueText(item)) | ||
table.insert(resultPart, '\r\n|style="text-align:right" data-sort-value="' .. itemDef.weight .. '"| ' .. Shared.fraction(itemDef.weight, totalWt)) | table.insert(resultPart, '\r\n|style="text-align:right" data-sort-value="' .. itemDef.weight .. '"| ' .. Shared.fraction(itemDef.weight, totalWt)) | ||
table.insert(resultPart, '\r\n|style="text-align:right"| ' .. string.format(fmt, dropChance) .. '%') | table.insert(resultPart, '\r\n|style="text-align:right"| ' .. string.format(fmt, dropChance) .. '%') | ||
lootValue = lootValue + (dropChance / 100 * item.sellsFor) | if lootValue[currID] == nil then | ||
lootValue[currID] = 0 | |||
end | |||
lootValue[currID] = lootValue[currID] + (dropChance / 100 * item.sellsFor) | |||
end | end | ||
end | end | ||
table.insert(resultPart, '\r\n|}\r\nThe average value of a roll on the special fishing loot table is ' .. | table.insert(resultPart, '\r\n|}\r\nThe average value of a roll on the special fishing loot table is ' .. lootValueText(lootValue)) | ||
return table.concat(resultPart) | return table.concat(resultPart) | ||
end | end | ||
Line 121: | Line 137: | ||
table.insert(resultPart, '\r\n|class="table-img"| ' .. Icons.Icon({item.name, type='item', notext=true, size=50})) | table.insert(resultPart, '\r\n|class="table-img"| ' .. 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| ' .. Icons.Icon({item.name, type='item', noicon=true})) | ||
table.insert(resultPart, '\r\n|data-sort-value="' .. item.sellsFor .. '"| ' .. | table.insert(resultPart, '\r\n|data-sort-value="' .. item.sellsFor .. '"| ' .. Items.getValueText(item)) | ||
end | end | ||
table.insert(resultPart, '\r\n|}') | table.insert(resultPart, '\r\n|}') | ||
Line 128: | Line 144: | ||
function p.getMiningOresTable(frame) | function p.getMiningOresTable(frame) | ||
local args = frame.args ~= nil and frame.args or frame | |||
local realmName = args.realm | |||
local realm = Skills.getRealmFromName(realmName) | |||
if realm == nil then | |||
return Shared.printError('Failed to find a realm with name ' .. (realmName or 'nil')) | |||
end | |||
local skillID = 'Mining' | |||
local resultPart = {} | local resultPart = {} | ||
table.insert(resultPart, '{|class="wikitable sortable stickyHeader"') | table.insert(resultPart, '{|class="wikitable sortable stickyHeader"') | ||
Line 134: | Line 158: | ||
table.insert(resultPart, '!!XP!!Respawn Time!!Ore Value') | table.insert(resultPart, '!!XP!!Respawn Time!!Ore Value') | ||
local mineData = | local mineData = GameData.getEntities(SkillData.Mining.rockData, | ||
table.sort(mineData, function(a, b) return a | function(obj) | ||
return Skills.getRecipeRealm(obj) == realm.id | |||
end | |||
) | |||
table.sort(mineData, function(a, b) return Skills.standardRecipeSort(skillID, a, b) end) | |||
for i, oreData in ipairs(mineData) do | for i, oreData in ipairs(mineData) do | ||
local level = Skills.getRecipeLevel(skillID, oreData) | |||
local baseXP = oreData.baseAbyssalExperience or oreData.baseExperience | |||
local reqText = Skills.getRecipeRequirementText(SkillData.Mining.name, oreData) | |||
local ore = Items.getItemByID(oreData.productId) | local ore = Items.getItemByID(oreData.productId) | ||
local respawnStyle, respawnSort, respawnText = 'class="table-na"', 0, 'N/A' | local respawnStyle, respawnSort, respawnText = 'class="table-na"', 0, 'N/A' | ||
Line 144: | Line 174: | ||
respawnSort = oreData.baseRespawnInterval / 1000 | respawnSort = oreData.baseRespawnInterval / 1000 | ||
respawnText = Shared.timeString(respawnSort, true) | respawnText = Shared.timeString(respawnSort, true) | ||
end | |||
local categoryName = '' | |||
local category = GameData.getEntityByID(SkillData.Mining.categories, oreData.category) | |||
if category ~= nil and category.name ~= nil then | |||
categoryName = category.name | |||
end | end | ||
local rockName = Icons.Icon({oreData.name, type='rock', noicon=true, nolink=true}) | local rockName = Icons.Icon({oreData.name, type='rock', noicon=true, nolink=true}) | ||
Line 152: | Line 187: | ||
table.insert(resultPart, '\n|class="table-img" data-sort-value="' .. ore.name .. '"| '..Icons.Icon({ore.name, type='item', size='50', notext=true})) | table.insert(resultPart, '\n|class="table-img" data-sort-value="' .. ore.name .. '"| '..Icons.Icon({ore.name, type='item', size='50', notext=true})) | ||
table.insert(resultPart, '\n| ' .. qtyText .. Icons.Icon({ore.name, type='item', noicon=true})) | table.insert(resultPart, '\n| ' .. qtyText .. Icons.Icon({ore.name, type='item', noicon=true})) | ||
table.insert(resultPart, '\n| ' .. | table.insert(resultPart, '\n| ' .. categoryName) | ||
table.insert(resultPart, '\n|data-sort-value="' . | table.insert(resultPart, '\n|data-sort-value="' .. level ..'"| ' .. reqText) | ||
table.insert(resultPart, '\n|style="text-align:right"| '.. | table.insert(resultPart, '\n|style="text-align:right"| '..Shared.formatnum(baseXP)) | ||
table.insert(resultPart, '\n|' .. respawnStyle .. ' data-sort-value="'..respawnSort..'"| ' .. respawnText) | table.insert(resultPart, '\n|' .. respawnStyle .. ' data-sort-value="'..respawnSort..'"| ' .. respawnText) | ||
table.insert(resultPart, '\n|data-sort-value="'..ore.sellsFor..'"| '.. | table.insert(resultPart, '\n|data-sort-value="'..ore.sellsFor..'"| '..Items.getValueText(ore)) | ||
end | end | ||
Line 169: | Line 204: | ||
local validTypes = { | local validTypes = { | ||
["Normal"] = 'randomGems', | ["Normal"] = 'randomGems', | ||
["Superior"] = 'randomSuperiorGems' | ["Superior"] = 'randomSuperiorGems', | ||
["Abyssal"] = 'randomAbyssalGems' | |||
} | } | ||
local gemDataKey = validTypes[gemType] | local gemDataKey = validTypes[gemType] | ||
Line 194: | Line 230: | ||
table.insert(resultPart, '\n| data-sort-value="'..gemItem.name..'"|'..Icons.getExpansionIcon(gemItem.id) .. Icons.Icon({gemItem.name, type='item', noicon=true})) | table.insert(resultPart, '\n| data-sort-value="'..gemItem.name..'"|'..Icons.getExpansionIcon(gemItem.id) .. Icons.Icon({gemItem.name, type='item', noicon=true})) | ||
table.insert(resultPart, '\n|style="text-align:right" data-sort-value="' .. gemPct .. '" | ' .. string.format("%.1f%%", gemPct)) | table.insert(resultPart, '\n|style="text-align:right" data-sort-value="' .. gemPct .. '" | ' .. string.format("%.1f%%", gemPct)) | ||
table.insert(resultPart, '\n|data-sort-value="' .. gemItem.sellsFor .. '"| ' .. | table.insert(resultPart, '\n|data-sort-value="' .. gemItem.sellsFor .. '"| ' .. Items.getValueText(gemItem)) | ||
end | end | ||
Line 207: | Line 243: | ||
function p.getFishTable(frame) | function p.getFishTable(frame) | ||
local recipeList = | local args = frame.args ~= nil and frame.args or frame | ||
table.sort(recipeList, function(a, b) return a | local realmName = args.realm | ||
local realm = Skills.getRealmFromName(realmName) | |||
if realm == nil then | |||
return Shared.printError('Failed to find a realm with name ' .. (realmName or 'nil')) | |||
end | |||
local skillID = 'Fishing' | |||
local recipeList = GameData.getEntities(SkillData.Fishing.fish, | |||
function(obj) | |||
return Skills.getRecipeRealm(obj) == realm.id | |||
end | |||
) | |||
table.sort(recipeList, function(a, b) return Skills.standardRecipeSort(skillID, a, b) end) | |||
-- Determine cooking levels for all fish | -- Determine cooking levels for all fish | ||
local | local cookRecipes = {} | ||
for i, recipe in ipairs(SkillData.Cooking.recipes) do | 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 | -- This assumes that each raw fish only appears in a single recipe, which is a bit rubbish | ||
-- but currently holds | -- but currently holds | ||
for j, mat in ipairs(recipe.itemCosts) do | for j, mat in ipairs(recipe.itemCosts) do | ||
if | if cookRecipes[mat.id] == nil then | ||
cookRecipes[mat.id] = recipe | |||
end | end | ||
end | end | ||
Line 225: | Line 273: | ||
table.insert(resultPart, '{| class="wikitable sortable stickyHeader"') | table.insert(resultPart, '{| class="wikitable sortable stickyHeader"') | ||
table.insert(resultPart, '\n|- class="headerRow-0"') | table.insert(resultPart, '\n|- class="headerRow-0"') | ||
table.insert(resultPart, '\n!colspan="2" rowspan="2"|Fish\n!rowspan="2"| | table.insert(resultPart, '\n!colspan="2" rowspan="2"|Fish\n!rowspan="2"|Requirements') | ||
table.insert(resultPart, '\n!colspan="3"|Catch Time\n!rowspan="2"|XP\n!rowspan="2"|Value\n!rowspan="2"|XP/s\n!rowspan="2"| | table.insert(resultPart, '\n!colspan="3"|Catch Time\n!rowspan="2"|XP\n!rowspan="2"|Value\n!rowspan="2"|XP/s\n!rowspan="2"|Price/s') | ||
table.insert(resultPart, '\n!rowspan="2"|' .. Icons.Icon({'Cooking', type='skill', notext=true}) .. ' Level') | table.insert(resultPart, '\n!rowspan="2"|' .. Icons.Icon({'Cooking', type='skill', notext=true}) .. ' Level') | ||
table.insert(resultPart, '\n|- class="headerRow-1"\n!Min\n!Max\n!Avg') | table.insert(resultPart, '\n|- class="headerRow-1"\n!Min\n!Max\n!Avg') | ||
Line 236: | Line 284: | ||
local timeSortVal = (recipe.baseMinInterval + recipe.baseMaxInterval) / 2000 | local timeSortVal = (recipe.baseMinInterval + recipe.baseMaxInterval) / 2000 | ||
local timeStr = string.format("%.1fs - %.1fs", recipe.baseMinInterval / 1000, recipe.baseMaxInterval / 1000) | local timeStr = string.format("%.1fs - %.1fs", recipe.baseMinInterval / 1000, recipe.baseMaxInterval / 1000) | ||
local | local level = Skills.getRecipeLevel(skillID, recipe) | ||
local | local reqText = Skills.getRecipeRequirementText(skillID, recipe) | ||
local | local baseXP = recipe.baseAbyssalExperience or recipe.baseExperience | ||
local cookStyle = | local XPSec = baseXP / timeSortVal | ||
local sellCurrency = fish.sellsForCurrency or 'melvorD:GP' | |||
local currPerSec = Shared.round(fish.sellsFor / timeSortVal, 2, 2) | |||
local cookRecipe = cookRecipes[recipe.productId] | |||
local cookLevel, cookStyle, cookStr = 0, 'class="table-na" ', 'N/A' | |||
if cookRecipe ~= nil then | |||
cookLevel = Skills.getRecipeLevel('Cooking', cookRecipe) | |||
cookStyle = 'style="text-align:right" ' | |||
cookStr = Skills.getRecipeRequirementText('Cooking', cookRecipe) | |||
end | |||
table.insert(resultPart, '\n|-') | table.insert(resultPart, '\n|-') | ||
table.insert(resultPart, '\n|class="table-img"| ' .. Icons.Icon({fish.name, type='item', size='50', notext=true})) | table.insert(resultPart, '\n|class="table-img"| ' .. Icons.Icon({fish.name, type='item', size='50', notext=true})) | ||
table.insert(resultPart, '\n|data-sort-value="'..fish.name..'"|'..Icons.getExpansionIcon(fish.id) .. Icons.Icon({fish.name, type='item', noicon=true})) | table.insert(resultPart, '\n|data-sort-value="'..fish.name..'"|'..Icons.getExpansionIcon(fish.id) .. Icons.Icon({fish.name, type='item', noicon=true})) | ||
table.insert(resultPart, '\n|style="text-align:right"| ' .. | table.insert(resultPart, '\n|style="text-align:right" data-sort-value="' .. level .. '"| ' .. reqText) | ||
table.insert(resultPart, '\n|style="text-align:right" data-sort-value="' .. timeMin .. '"| ' .. string.format("%.1fs", timeMin)) | table.insert(resultPart, '\n|style="text-align:right" data-sort-value="' .. timeMin .. '"| ' .. string.format("%.1fs", timeMin)) | ||
table.insert(resultPart, '\n|style="text-align:right" data-sort-value="' .. timeMax .. '"| ' .. string.format("%.1fs", timeMax)) | table.insert(resultPart, '\n|style="text-align:right" data-sort-value="' .. timeMax .. '"| ' .. string.format("%.1fs", timeMax)) | ||
table.insert(resultPart, '\n|style="text-align:right" data-sort-value="' .. timeAvg .. '"| ' .. string.format("%.1fs", timeAvg)) | table.insert(resultPart, '\n|style="text-align:right" data-sort-value="' .. timeAvg .. '"| ' .. string.format("%.1fs", timeAvg)) | ||
table.insert(resultPart, '\n|style="text-align:right" data-sort-value="' .. | table.insert(resultPart, '\n|style="text-align:right" data-sort-value="' .. baseXP .. '"| ' .. Shared.formatnum(baseXP)) | ||
table.insert(resultPart, '\n|data-sort-value="' .. fish.sellsFor .. '"| ' .. | table.insert(resultPart, '\n|data-sort-value="' .. fish.sellsFor .. '"| ' .. Items.getValueText(fish)) | ||
table.insert(resultPart, '\n|style="text-align:right"| ' .. Shared.round( | table.insert(resultPart, '\n|style="text-align:right"| ' .. Shared.round(XPSec, 2, 2)) | ||
table.insert(resultPart, '\n|data-sort-value="' .. | table.insert(resultPart, '\n|data-sort-value="' .. currPerSec .. '"|' .. Icons._Currency(sellCurrency, currPerSec)) | ||
table.insert(resultPart, '\n|' .. cookStyle .. 'data-sort-value="' .. | table.insert(resultPart, '\n|' .. cookStyle .. 'data-sort-value="' .. cookLevel .. '"| ' .. cookStr) | ||
end | end | ||
end | end | ||
Line 260: | Line 316: | ||
function p.getFishingAreasTable(frame) | function p.getFishingAreasTable(frame) | ||
local args = frame.args ~= nil and frame.args or frame | |||
local realmName = args.realm | |||
local realm = Skills.getRealmFromName(realmName) | |||
if realm == nil then | |||
return Shared.printError('Failed to find a realm with name ' .. (realmName or 'nil')) | |||
end | |||
local skillID = 'Fishing' | |||
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 265: | Line 329: | ||
result = result..'\r\n!Junk Chance\r\n!Special Chance' | result = result..'\r\n!Junk Chance\r\n!Special Chance' | ||
for i, area in ipairs( | local fishAreas = GameData.getEntities(SkillData.Fishing.areas, | ||
function(obj) | |||
return Skills.getRecipeRealm(obj) == realm.id | |||
end | |||
) | |||
for i, area in ipairs(fishAreas) do | |||
result = result..'\r\n|-' | result = result..'\r\n|-' | ||
result = result..'\r\n| style ="text-align: left;" |'..Icons.getExpansionIcon(area.id)..area.name | result = result..'\r\n| style ="text-align: left;" |'..Icons.getExpansionIcon(area.id)..area.name | ||
Line 291: | Line 361: | ||
end | end | ||
function p._getThievingGeneralRareTable( | function p._getThievingGeneralRareTable(npc) | ||
local npcRealm = nil | |||
if npc ~= nil then | |||
npcRealm = Skills.getRecipeRealm(npc) | |||
end | |||
local rareTxt = '{|class="wikitable sortable"' | local rareTxt = '{|class="wikitable sortable"' | ||
rareTxt = rareTxt..'\r\n!Item!!Qty' | rareTxt = rareTxt..'\r\n!Item!!Qty' | ||
Line 298: | Line 373: | ||
-- If an npcID has been passed and the item is NPC specific, only display | -- If an npcID has been passed and the item is NPC specific, only display | ||
-- the item if it may be obtained while pickpocketing that NPC | -- the item if it may be obtained while pickpocketing that NPC | ||
local npcMatch = ( | |||
npc == nil | |||
or drop.npcs == nil | |||
or Shared.contains(drop.npcs, npc.id) | |||
) | |||
local realmMatch = ( | |||
npcRealm == nil | |||
or drop.realms == nil | |||
or Shared.contains(drop.realms, npcRealm) | |||
) | |||
if npcMatch and realmMatch then | |||
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|data-sort-value="'..thisItem.name..'"|'..Icons.getExpansionIcon(thisItem.id)..Icons.Icon({thisItem.name, type='item'}) | rareTxt = rareTxt..'\r\n|-\r\n|data-sort-value="'..thisItem.name..'"|'..Icons.getExpansionIcon(thisItem.id)..Icons.Icon({thisItem.name, type='item'}) | ||
rareTxt = rareTxt..'||1||data-sort-value="'..thisItem.sellsFor..'"|'.. | rareTxt = rareTxt..'||1||data-sort-value="'..thisItem.sellsFor..'"|'..Items.getValueText(thisItem) | ||
rareTxt = rareTxt..'||style="text-align:right" data-sort-value="'..odds..'"|'..Shared.fraction(1, Shared.round2(1/(odds/100), 0)) | rareTxt = rareTxt..'||style="text-align:right" data-sort-value="'..odds..'"|'..Shared.fraction(1, Shared.round2(1/(odds/100), 0)) | ||
rareTxt = rareTxt..'||style="text-align:right" data-sort-value="'..odds..'"|'..Shared.round(odds, 4, 4)..'%' | rareTxt = rareTxt..'||style="text-align:right" data-sort-value="'..odds..'"|'..Shared.round(odds, 4, 4)..'%' | ||
Line 310: | Line 395: | ||
rareTxt = rareTxt..'\r\n|}' | rareTxt = rareTxt..'\r\n|}' | ||
return rareTxt | return rareTxt | ||
end | |||
function p._getThievingNPCCurrencyText(npc) | |||
local currTextPart = {} | |||
for _, currencyDrop in ipairs(npc.currencyDrops) do | |||
table.insert(currTextPart, Icons._Currency(currencyDrop.id, 1, currencyDrop.quantity)) | |||
end | |||
return table.concat(currTextPart, ', ') | |||
end | end | ||
Line 316: | Line 409: | ||
local sectionTxt = {} | local sectionTxt = {} | ||
--Five sections here: | --Five sections here: Currency, normal loot, area loot, rare loot, and unique item | ||
--First up, | --First up, currency: | ||
table.insert(sectionTxt, 'Successfully pickpocketing the ' .. npc.name .. ' will always give '.. p._getThievingNPCCurrencyText(npc)) | |||
--Next up, normal loot: | --Next up, normal loot: | ||
Line 328: | Line 420: | ||
local totalWt = 0 | local totalWt = 0 | ||
local lootChance = SkillData.Thieving.itemChance | local lootChance = SkillData.Thieving.itemChance | ||
local lootValue = | local lootValue = {} | ||
--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 | ||
Line 358: | Line 450: | ||
--Adding price columns | --Adding price columns | ||
local | local sellAmount, sellCurrency = nil, nil | ||
if thisItem == nil then | if thisItem == nil then | ||
table.insert(normalTxt, '||data-sort-value="0"|???') | table.insert(normalTxt, '||data-sort-value="0"|???') | ||
else | else | ||
sellAmount = thisItem.sellsFor or 0 | |||
sellCurrency = thisItem.sellsForCurrency or 'melvorD:GP' | |||
table.insert(normalTxt, '||' .. Items.getValueText(thisItem, loot.minQuantity, loot.maxQuantity)) | |||
end | end | ||
Line 383: | Line 472: | ||
--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 * | if sellAmount ~= nil and sellCurrency ~= nil then | ||
if lootValue[sellCurrency] == nil then | |||
lootValue[sellCurrency] = 0 | |||
end | |||
lootValue[sellCurrency] = lootValue[sellCurrency] + (dropChance * 0.01 * sellAmount * (loot.minQuantity + loot.maxQuantity) / 2) | |||
end | |||
end | end | ||
if Shared.tableCount(npc.lootTable) > 1 then | if Shared.tableCount(npc.lootTable) > 1 then | ||
Line 395: | Line 489: | ||
end | end | ||
table.insert(normalTxt, '\r\n|}') | table.insert(normalTxt, '\r\n|}') | ||
table.insert(normalTxt, '\r\nThe loot obtained from the average successful pickpocket is worth ' .. | |||
table.insert(normalTxt, '\r\n\r\nIncluding | table.insert(normalTxt, '\r\nThe loot obtained from the average successful pickpocket is worth ' .. lootValueText(lootValue) .. ' if sold.') | ||
-- Amend lootValue | |||
for _, currencyDrop in ipairs(npc.currencyDrops) do | |||
lootValue[currencyDrop.id] = lootValue[currencyDrop.id] + (1 + currencyDrop.quantity) / 2 | |||
end | |||
table.insert(normalTxt, '\r\n\r\nIncluding currency, the average successful pickpocket is worth ' .. lootValueText(lootValue) .. '.') | |||
table.insert(sectionTxt, table.concat(normalTxt)) | table.insert(sectionTxt, table.concat(normalTxt)) | ||
end | end | ||
Line 402: | Line 503: | ||
--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(npc | rareTxt = rareTxt..'\r\n'..p._getThievingGeneralRareTable(npc) | ||
table.insert(sectionTxt, rareTxt) | table.insert(sectionTxt, rareTxt) | ||
Line 419: | Line 520: | ||
local lineTxt = '' | local lineTxt = '' | ||
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..'||data-sort-value="'..drop.quantity..'"| '..Shared.formatnum(drop.quantity)..'||data-sort-value="'..thisItem.sellsFor..'"|'.. | lineTxt = lineTxt..'||data-sort-value="'..drop.quantity..'"| '..Shared.formatnum(drop.quantity)..'||data-sort-value="'..thisItem.sellsFor..'"|'..Items.getValueText(thisItem) | ||
lineTxt = lineTxt..'||style="text-align:right"|'..Shared.fraction(1, 1/(SkillData.Thieving.baseAreaUniqueChance/100)) | lineTxt = lineTxt..'||style="text-align:right"|'..Shared.fraction(1, 1/(SkillData.Thieving.baseAreaUniqueChance/100)) | ||
lineTxt = lineTxt..'||'..Shared.round(SkillData.Thieving.baseAreaUniqueChance, 2, 2)..'%' | lineTxt = lineTxt..'||'..Shared.round(SkillData.Thieving.baseAreaUniqueChance, 2, 2)..'%' | ||
Line 459: | Line 560: | ||
end | end | ||
function p.getThievingNPCTable() | function p.getThievingNPCTable(frame) | ||
local args = frame.args ~= nil and frame.args or frame | |||
local realmName = args.realm | |||
local realm = Skills.getRealmFromName(realmName) | |||
if realm == nil then | |||
return Shared.printError('Failed to find a realm with name ' .. (realmName or 'nil')) | |||
end | |||
local skillID = 'Thieving' | |||
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!! | result = result..'\r\n!colspan="2"|Name!!Area!!'..Icons.Icon({'Thieving', type='skill', notext=true})..' Level!!Experience!!Max Hit!!Perception!!Currency!!Unique Drop' | ||
local npcArray = | local npcArray = GameData.getEntities(SkillData.Thieving.npcs, | ||
table.sort(npcArray, function(a, b) return a | function(obj) | ||
return Skills.getRecipeRealm(obj) == realm.id | |||
end | |||
) | |||
table.sort(npcArray, function(a, b) return Skills.standardRecipeSort(skillID, a, b) end) | |||
for i, npc in ipairs(npcArray) do | for i, npc in ipairs(npcArray) do | ||
local level = Skills.getRecipeLevel(skillID, npc) | |||
local baseXP = npc.baseAbyssalExperience or npc.baseExperience | |||
local reqText = Skills.getRecipeRequirementText(SkillData.Thieving.name, npc) | |||
local area = Skills.getThievingNPCArea(npc) | |||
local currSortAmt = npc.currencyDrops[1].quantity | |||
result = result..'\r\n|-' | result = result..'\r\n|-' | ||
result = result..'\r\n|'..Icons.Icon({npc.name, type='thieving', size='50', notext=true}) | result = result..'\r\n|'..Icons.Icon({npc.name, type='thieving', size='50', notext=true}) | ||
result = result..'||data-sort-value="'..npc.name..'"|'..Icons.getExpansionIcon(npc.id)..Icons.Icon({npc.name, type='thieving', noicon=true}) | result = result..'||data-sort-value="'..npc.name..'"|'..Icons.getExpansionIcon(npc.id)..Icons.Icon({npc.name, type='thieving', noicon=true}) | ||
result = result..'||'..area.name | result = result..'||'..area.name | ||
result = result..'||data-sort-value="' . | result = result..'||data-sort-value="' .. level .. '"| ' .. reqText | ||
result = result..'||style="text-align:right"|'.. | result = result..'||style="text-align:right"|' .. Shared.formatnum(baseXP) | ||
result = result..'||style="text-align:right"|'..(npc.maxHit * 10) | result = result..'||style="text-align:right"|' .. Shared.formatnum(npc.maxHit * 10) | ||
result = result..'||style="text-align:right" data-sort-value="' .. npc.perception .. '| '..Shared.formatnum(npc.perception) | result = result..'||style="text-align:right" data-sort-value="' .. npc.perception .. '| '..Shared.formatnum(npc.perception) | ||
result = result..'||data-sort-value="' .. | result = result..'||data-sort-value="' .. currSortAmt .. '"|' .. p._getThievingNPCCurrencyText(npc) | ||
if npc.uniqueDrop ~= nil then | if npc.uniqueDrop ~= nil then | ||
local uniqueDrop = Items.getItemByID(npc.uniqueDrop.id) | local uniqueDrop = Items.getItemByID(npc.uniqueDrop.id) | ||
Line 494: | Line 612: | ||
function p.getThievingAreaTable(frame) | function p.getThievingAreaTable(frame) | ||
local args = frame.args ~= nil and frame.args or frame | |||
local realmName = args.realm | |||
local realm = Skills.getRealmFromName(realmName) | |||
if realm == nil then | |||
return Shared.printError('Failed to find a realm with name ' .. (realmName or 'nil')) | |||
end | |||
local skillID = 'Thieving' | |||
local resultPart = {} | local resultPart = {} | ||
table.insert(resultPart, '{| class="wikitable sortable stickyHeader"') | table.insert(resultPart, '{| class="wikitable sortable stickyHeader"') | ||
Line 499: | Line 625: | ||
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') | ||
for i, area in ipairs( | local areas = GameData.getEntities(SkillData.Thieving.areas, | ||
function(obj) | |||
return Skills.getRecipeRealm(obj) == realm.id | |||
end | |||
) | |||
for i, area in ipairs(areas) do | |||
local minLevel, npcList, areaItemList = nil, {}, {} | local minLevel, npcList, areaItemList = nil, {}, {} | ||
-- Build NPC list & determine level for area, this is the minimum | -- Build NPC list & determine level for area, this is the minimum | ||
Line 506: | Line 638: | ||
for j, npcID in ipairs(area.npcIDs) do | for j, npcID in ipairs(area.npcIDs) do | ||
local npc = Skills.getThievingNPCByID(npcID) | local npc = Skills.getThievingNPCByID(npcID) | ||
if minLevel == nil or | local level = Skills.getRecipeLevel(skillID, npc) | ||
minLevel = | if minLevel == nil or level < minLevel then | ||
minLevel = level | |||
end | end | ||
table.insert(npcList, Icons.Icon({npc.name, type='thieving'})) | table.insert(npcList, Icons.Icon({npc.name, type='thieving'})) | ||
Line 545: | Line 678: | ||
end | end | ||
function p._getFarmingTable(categoryName) | function p._getFarmingTable(realmID, categoryName) | ||
local category = GameData.getEntityByName(SkillData.Farming.categories, categoryName) | local category = GameData.getEntityByName(SkillData.Farming.categories, categoryName) | ||
if category == nil then | if category == nil then | ||
Line 552: | Line 685: | ||
local seedList = GameData.getEntities(SkillData.Farming.recipes, | local seedList = GameData.getEntities(SkillData.Farming.recipes, | ||
function(recipe) | function(recipe) | ||
return recipe.categoryID == category.id | return recipe.categoryID == category.id and Skills.getRecipeRealm(recipe) == realmID | ||
end) | end) | ||
if Shared.tableIsEmpty(seedList) then | if Shared.tableIsEmpty(seedList) then | ||
return '' | return '' | ||
end | end | ||
local skillID = 'Farming' | |||
local tbl = mw.html.create() | local tbl = mw.html.create() | ||
Line 563: | Line 698: | ||
:tag('tr'):addClass("headerRow-0") | :tag('tr'):addClass("headerRow-0") | ||
:tag('th'):attr("colspan", 2):wikitext("Seeds") | :tag('th'):attr("colspan", 2):wikitext("Seeds") | ||
:tag('th'):wikitext( | :tag('th'):wikitext('Requirements') | ||
:tag('th'):wikitext('XP') | :tag('th'):wikitext('XP') | ||
:tag('th'):wikitext('Growth Time') | :tag('th'):wikitext('Growth Time') | ||
Line 581: | Line 716: | ||
html = html:tag('th'):wikitext('Seed Sources') | html = html:tag('th'):wikitext('Seed Sources') | ||
table.sort(seedList, function(a, b) return a | table.sort(seedList, function(a, b) return Skills.standardRecipeSort(skillID, a, b) end) | ||
for i, seed in ipairs(seedList) do | for i, seed in ipairs(seedList) do | ||
Line 587: | Line 722: | ||
local productItem = Items.getItemByID(seed.productId) | local productItem = Items.getItemByID(seed.productId) | ||
if seedItem ~= nil and productItem ~= nil then | if seedItem ~= nil and productItem ~= nil then | ||
local level = Skills.getRecipeLevel(skillID, seed) | |||
local baseXP = seed.baseAbyssalExperience or seed.baseExperience | |||
local baseInt = seed.baseInterval | |||
local reqText = Skills.getRecipeRequirementText(SkillData.Farming.name, seed) | |||
html = | html = | ||
html:tag('tr') | html:tag('tr') | ||
:tag('td'):wikitext(Icons.Icon({seedItem.name, type='item', size='50', notext=true})) | :tag('td'):wikitext(Icons.Icon({seedItem.name, type='item', size='50', notext=true})) | ||
:tag('td'):wikitext(Icons.getExpansionIcon(seedItem.id) .. Icons.Icon({seedItem.name, type='item', noicon=true})) | :tag('td'):wikitext(Icons.getExpansionIcon(seedItem.id) .. Icons.Icon({seedItem.name, type='item', noicon=true})) | ||
:tag('td'):wikitext( | :tag('td'):wikitext(reqText) | ||
:tag('td'):wikitext(Shared.formatnum( | :tag('td'):wikitext(Shared.formatnum(baseXP)) | ||
:tag('td'):attr('data-sort-value', ( | :tag('td'):attr('data-sort-value', (baseInt / 1000)) | ||
:wikitext(Shared.timeString( | :wikitext(Shared.timeString(baseInt / 1000, true)) | ||
:tag('td'):attr('data-sort-value', seedItem.sellsFor) | :tag('td'):attr('data-sort-value', seedItem.sellsFor) | ||
:wikitext( | :wikitext(Items.getValueText(seedItem)) | ||
:tag('td'):wikitext(Icons.Icon({productItem.name, type='item', size='50', notext=true})) | :tag('td'):wikitext(Icons.Icon({productItem.name, type='item', size='50', notext=true})) | ||
:tag('td'):wikitext(Icons.getExpansionIcon(productItem.id) .. Icons.Icon({productItem.name, type='item', noicon=true})) | :tag('td'):wikitext(Icons.getExpansionIcon(productItem.id) .. Icons.Icon({productItem.name, type='item', noicon=true})) | ||
Line 607: | Line 747: | ||
html = | html = | ||
html:tag('td'):attr('data-sort-value', productItem.sellsFor) | html:tag('td'):attr('data-sort-value', productItem.sellsFor) | ||
:wikitext( | :wikitext(Items.getValueText(productItem)) | ||
:tag('td'):wikitext(ItemSourceTables._getItemSources(seedItem)) | :tag('td'):wikitext(ItemSourceTables._getItemSources(seedItem)) | ||
:css('text-align', 'left') | :css('text-align', 'left') | ||
Line 618: | Line 758: | ||
function p.getFarmingTable(frame) | function p.getFarmingTable(frame) | ||
local | local args = frame.args ~= nil and frame.args or frame | ||
local realmName = args.realm | |||
local realm = Skills.getRealmFromName(realmName) | |||
if realm == nil then | |||
return Shared.printError('Failed to find a realm with name ' .. (realmName or 'nil')) | |||
end | |||
local category = args[1] | |||
return p._getFarmingTable(category) | return p._getFarmingTable(realm.id, category) | ||
end | end | ||
Line 644: | Line 790: | ||
result = result..'||style="text-align:right;"|'..recipe.level | result = result..'||style="text-align:right;"|'..recipe.level | ||
result = result..'||style="text-align:right" data-sort-value="'..product.healsFor..'"|'..Icons.Icon({"Hitpoints", type="skill", notext=true})..' '..(product.healsFor * 10) | result = result..'||style="text-align:right" data-sort-value="'..product.healsFor..'"|'..Icons.Icon({"Hitpoints", type="skill", notext=true})..' '..(product.healsFor * 10) | ||
result = result..'||style="text-align:right" data-sort-value="'..product.sellsFor..'"|'.. | result = result..'||style="text-align:right" data-sort-value="'..product.sellsFor..'"|'..Items.getValueText(product) | ||
end | end | ||
end | end | ||
Line 654: | Line 800: | ||
function p.getFarmingPlotTable(frame) | function p.getFarmingPlotTable(frame) | ||
local skillID = 'Farming' | |||
local areaName = frame.args ~= nil and frame.args[1] or frame | local areaName = frame.args ~= nil and frame.args[1] or frame | ||
local category = GameData.getEntityByName(SkillData.Farming.categories, areaName) | local category = GameData.getEntityByName(SkillData.Farming.categories, areaName) | ||
Line 665: | Line 812: | ||
table.sort(patches, | table.sort(patches, | ||
function(a, b) | function(a, b) | ||
if a.level == b.level then | local abyssA, abyssB = a.abyssalLevel or 0, b.abyssalLevel or 0 | ||
if abyssA == abyssB then | |||
if a.level == b.level then | |||
return a.id < b.id | |||
else | |||
return a.level < b.level | |||
end | |||
else | else | ||
return | return abyssA < abyssB | ||
end | end | ||
end) | end) | ||
Line 676: | Line 828: | ||
local result = '{|class="wikitable sortable stickyHeader"' | local result = '{|class="wikitable sortable stickyHeader"' | ||
result = result..'\r\n!Plot!! | result = result..'\r\n!Plot!!Requirements!!Cost' | ||
for i, patch in ipairs(patches) do | for i, patch in ipairs(patches) do | ||
local level = Skills.getRecipeLevel(skillID, patch) | |||
local reqText = Skills.getRecipeRequirementText(skillID, patch) | |||
local costText = Common.getCostString({ items = patch.itemCosts, currencies = patch.currencyCosts }, 'Free') | |||
local costVal = (patch.currencyCosts ~= nil and patch.currencyCosts[1].quantity) or 0 | |||
result = result..'\r\n|-\r\n|'..i | result = result..'\r\n|-\r\n|'..i | ||
result = result..'||style="text-align:right;" data-sort-value="' . | result = result..'||style="text-align:right;" data-sort-value="' .. level .. '"|'..reqText | ||
result = result..'||style="text-align:right;" data-sort-value="'..costVal..'"|'..costText | |||
result = result..'||style="text-align:right;" data-sort-value="'.. | |||
end | end | ||
Line 689: | Line 845: | ||
end | end | ||
function p._buildAstrologyConstellationTable() | function p._buildAstrologyConstellationTable(realmID) | ||
local modTypes = { | |||
{ | |||
["name"] = 'Standard', | |||
["modKey"] = 'standardModifiers', | |||
["levels"] = SkillData.Astrology.standardModifierLevels, | |||
["inUse"] = false | |||
}, | |||
{ | |||
["name"] = 'Unique', | |||
["modKey"] = 'uniqueModifiers', | |||
["levels"] = SkillData.Astrology.uniqueModifierLevels, | |||
["inUse"] = false | |||
}, | |||
{ | |||
["name"] = 'Abyssal', | |||
["modKey"] = 'abyssalModifiers', | |||
["levels"] = SkillData.Astrology.abyssalModifierLevels, | |||
["inUse"] = false | |||
}, | |||
} | |||
local recipes = GameData.getEntities(SkillData.Astrology.recipes, | |||
function(cons) | |||
return Skills.getRecipeRealm(cons) == realmID | |||
end | |||
) | |||
table.sort(recipes, | |||
function(a, b) | |||
return Skills.getRecipeLevel('Astrology', a) < Skills.getRecipeLevel('Astrology', b) | |||
end | |||
) | |||
-- Figure out which mod types are to be displayed | |||
for _, recipe in ipairs(recipes) do | |||
for _, modType in ipairs(modTypes) do | |||
if not modType.inUse then | |||
local recipeMods = recipe[modType.modKey] | |||
if recipeMods ~= nil and not Shared.tableIsEmpty(recipeMods) then | |||
modType.inUse = true | |||
end | |||
end | |||
end | |||
end | |||
local resultPart = {} | local resultPart = {} | ||
table.insert(resultPart, '{|class="wikitable sortable stickyHeader"') | table.insert(resultPart, '{|class="wikitable sortable stickyHeader"') | ||
table.insert(resultPart, '\n|- class="headerRow-0"') | table.insert(resultPart, '\n|- class="headerRow-0"') | ||
table.insert(resultPart, '\n!rowspan="2" colspan="2"|Constellation!!rowspan="2"| ' .. Icons.Icon({"Astrology", type='skill', notext='true'}) .. ' Level') | table.insert(resultPart, '\n!rowspan="2" colspan="2"|Constellation!!rowspan="2"| ' .. Icons.Icon({"Astrology", type='skill', notext='true'}) .. ' Level') | ||
table.insert(resultPart, '!!rowspan="2"| XP!!rowspan="2"| Skills | table.insert(resultPart, '!!rowspan="2"| XP!!rowspan="2"| Skills') | ||
local repCount = 0 | |||
for _, modType in ipairs(modTypes) do | |||
if modType.inUse then | |||
repCount = repCount + 1 | |||
table.insert(resultPart, '!!colspan="2"| ' .. modType.name .. ' Stars') | |||
end | |||
end | |||
table.insert(resultPart, '\n|- class="headerRow-1"') | table.insert(resultPart, '\n|- class="headerRow-1"') | ||
table.insert(resultPart, string.rep('\n! ' .. Icons.Icon({'Mastery', notext=true}) .. 'Level\n! Modifiers', | table.insert(resultPart, string.rep('\n! ' .. Icons.Icon({'Mastery', notext=true}) .. 'Level\n! Modifiers', repCount)) | ||
for i, cons in ipairs(recipes) do | for i, cons in ipairs(recipes) do | ||
local modData = Skills._getConstellationModifiers(cons) | |||
local name = cons.name | |||
local | local skillIconArray = {} | ||
for j, skillID in ipairs(cons.skillIDs) do | |||
table.insert(skillIconArray, Icons.Icon({Constants.getSkillName(skillID), type='skill'})) | |||
end | |||
local maxRows = 1 | local maxRows = 1 | ||
for | for _, modTypeData in pairs(modData) do | ||
maxRows = math.max(maxRows, Shared.tableCount(modTypeData)) | |||
end | end | ||
local rowSpan = (maxRows > 1 and 'rowspan="' .. maxRows .. '"') or '' | local rowSpan = (maxRows > 1 and 'rowspan="' .. maxRows .. '"') or '' | ||
table.insert(resultPart, '\n|-') | table.insert(resultPart, '\n|-') | ||
table.insert(resultPart, '\n|' .. rowSpan .. ' data-sort-value="' .. name .. '" id="'..name..'"| ') | table.insert(resultPart, '\n|' .. rowSpan .. ' data-sort-value="' .. name .. '" id="'..name..'"| ') | ||
Line 739: | Line 925: | ||
table.insert(resultPart, '\n|' .. rowSpan .. ' style="text-align:right"| ' .. cons.level) | table.insert(resultPart, '\n|' .. rowSpan .. ' style="text-align:right"| ' .. cons.level) | ||
table.insert(resultPart, '\n|' .. rowSpan .. ' style="text-align:right"| ' .. cons.baseExperience) | table.insert(resultPart, '\n|' .. rowSpan .. ' style="text-align:right"| ' .. cons.baseExperience) | ||
table.insert(resultPart, '\n|' .. rowSpan .. '| ' .. table.concat(skillIconArray, '<br/>')) | table.insert(resultPart, '\n|' .. rowSpan .. '| ' .. table.concat(skillIconArray, '<br/>')) | ||
-- Generate table text for | -- Generate table text for modifiers | ||
for row = 1, maxRows, 1 do | for row = 1, maxRows, 1 do | ||
for | for _, modType in ipairs(modTypes) do | ||
local masteryLevel = | if modType.inUse then | ||
local masteryLevel = modType.levels[row] | |||
table.insert(resultPart, '\n|style="text-align:right"| ' .. masteryLevel) | local rowModData = modData[modType.modKey][row] | ||
if masteryLevel == nil or rowModData == nil then | |||
table.insert(resultPart, '\n|colspan="2" class="table-na"| ') | |||
else | |||
table.insert(resultPart, '\n|style="text-align:right"| ' .. masteryLevel) | |||
table.insert(resultPart, '\n| ' .. Modifiers.getModifiersText(rowModData, false, false, 10)) | |||
end | |||
end | end | ||
end | end | ||
Line 768: | Line 952: | ||
function p.buildAstrologyConstellationTable(frame) | function p.buildAstrologyConstellationTable(frame) | ||
return p._buildAstrologyConstellationTable() | local args = frame.args ~= nil and frame.args or frame | ||
local realmName = args.realm | |||
local realm = Skills.getRealmFromName(realmName) | |||
if realm == nil then | |||
return Shared.printError('Failed to find a realm with name ' .. (realmName or 'nil')) | |||
end | |||
return p._buildAstrologyConstellationTable(realm.id) | |||
end | end | ||
return p | return p |