17,101
edits
(getSpecialFishingTable: Show smaller chance values to 2sf) |
(Update for v1.0.3) |
||
Line 187: | Line 187: | ||
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 283: | Line 285: | ||
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 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"| ' .. 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 327: | Line 339: | ||
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 744: | Line 757: | ||
end | end | ||
end | end | ||
local modTypes = {} | |||
if includeStandard then | |||
table.insert(modTypes, 'standardModifiers') | |||
end | |||
if includeUnique then | |||
table.insert(modTypes, 'uniqueModifiers') | |||
end | |||
local modArray = {} | local modArray = {} | ||
local isSkillMod = {} | local isSkillMod = {} | ||
for _, modType in ipairs(modTypes) do | |||
for i, skillMods in ipairs(cons[modType]) do | |||
for i, skillMods in ipairs(cons | |||
local skillID = cons.skills[i] | local skillID = cons.skills[i] | ||
if skillID ~= nil then | if skillID ~= nil then | ||
Line 762: | Line 782: | ||
addToArray(modArray, {modName, modVal}) | addToArray(modArray, {modName, modVal}) | ||
end | end | ||
end | end | ||
end | end | ||
Line 817: | Line 812: | ||
result = result..'!!XP!!Skills!!Standard Modifiers!!Unique Modifiers' | result = result..'!!XP!!Skills!!Standard Modifiers!!Unique Modifiers' | ||
for i, cons in | for i, cons in ipairs(SkillData.Astrology.Constellations) do | ||
local name = cons.name | local name = cons.name | ||
result = result..'\r\n|-' | result = result..'\r\n|-' | ||
Line 858: | Line 853: | ||
result = result..'\r\n!rowspan="2"| Value!!colspan="2"| Chance' | result = result..'\r\n!rowspan="2"| Value!!colspan="2"| Chance' | ||
result = result..'\r\n|-\r\n! This Value!! This Value or Greater' | result = result..'\r\n|-\r\n! This Value!! This Value or Greater' | ||
local cumulativeChance = 100 | local cumulativeChance = 100 | ||
for i, chance in | for i, chance in ipairs(SkillData.Astrology.ModifierMagnitudeChances) do | ||
result = result..'\r\n|-' | result = result..'\r\n|-' | ||
result = result..'\r\n|style="text-align:right"| '..i | result = result..'\r\n|style="text-align:right"| ' .. i | ||
result = result..'\r\n|style="text-align:right"| ' .. | result = result..'\r\n|style="text-align:right"| ' .. chance .. '%' | ||
result = result..'\r\n|style="text-align:right"| ' .. cumulativeChance .. '%' | result = result..'\r\n|style="text-align:right"| ' .. cumulativeChance .. '%' | ||
cumulativeChance = cumulativeChance - | cumulativeChance = cumulativeChance - chance | ||
end | end | ||
result = result..'\r\n|}' | result = result..'\r\n|}' |