Module:Skills/Gathering: Difference between revisions

Fix numerous issues
(getMiningOresTable: Fix & include shop purchases in requirements column)
(Fix numerous issues)
Line 155: Line 155:
end
end
-- Sort the loot table by weight in descending order
-- 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)
table.sort(itemArray, function(a, b) return a.weight > b.weight end)


local resultPart = {}
local resultPart = {}
Line 286: Line 286:
table.insert(resultPart, '\r\n!' .. Icons.Icon({'Cooking', type='skill', notext=true}) .. ' Level')
table.insert(resultPart, '\r\n!' .. Icons.Icon({'Cooking', type='skill', notext=true}) .. ' Level')
for i, recipe in ipairs(recipeList) do
for i, recipe in ipairs(recipeList) do
local fish = Items.getItemByID(recipe.productID)
local fish = Items.getItemByID(recipe.productId)
if fish ~= nil then
if fish ~= nil then
local timeSortVal = (recipe.baseMinInterval + recipe.baseMaxInterval) / 2000
local timeSortVal = (recipe.baseMinInterval + recipe.baseMaxInterval) / 2000
Line 292: Line 292:
local XPs = recipe.baseExperience / timeSortVal
local XPs = recipe.baseExperience / timeSortVal
local GPs = fish.sellsFor / timeSortVal
local GPs = fish.sellsFor / timeSortVal
local cookSortVal = cookReq[recipe.itemID] or 0
local cookSortVal = cookReq[recipe.productId] or 0
local cookStr = cookReq[recipe.itemID] or 'N/A'
local cookStr = cookReq[recipe.productId] or 'N/A'
table.insert(resultPart, '\r\n|-')
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|style="text-align:center"| ' .. Icons.Icon({fish.name, type='item', size='50', notext=true}))
Line 299: Line 299:
table.insert(resultPart, '\r\n|style="text-align:right"| ' .. recipe.level)
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" data-sort-value="' .. timeSortVal .. '"| ' .. timeStr)
table.insert(resultPart, '\r\n|style="text-align:right"| ' .. recipe.baseXP)
table.insert(resultPart, '\r\n|style="text-align:right"| ' .. recipe.baseExperience)
table.insert(resultPart, '\r\n|data-sort-value="' .. fish.sellsFor .. '"| ' .. Icons.GP(fish.sellsFor))
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|style="text-align:right"| ' .. Shared.round(XPs, 2, 2))
Line 336: Line 336:
result = result..'\r\n|}'
result = result..'\r\n|}'
return result
return result
end
function p.getThievingGeneralRareTable(frame)
return p._getThievingGeneralRareTable()
end
end


-- TODO Expose list of NPCs somewhere when applicable (e.g. for Thieving Shorts)
-- TODO Expose list of NPCs somewhere when applicable (e.g. for Thieving Shorts)
function p.getThievingGeneralRareTable(frame)
function p._getThievingGeneralRareTable(npcID)
local rareTxt = '{|class="wikitable sortable"'
local rareTxt = '{|class="wikitable sortable"'
rareTxt = rareTxt..'\r\n!Item!!Qty'
rareTxt = rareTxt..'\r\n!Item!!Qty'
rareTxt = rareTxt..'!!Price!!colspan="2"|Chance'
rareTxt = rareTxt..'!!Price!!colspan="2"|Chance'
for i, drop in pairs(SkillData.Thieving.generalRareItems) do
for i, drop in ipairs(SkillData.Thieving.generalRareItems) do
local thisItem = Items.getItemByID(drop.itemID)
-- If an npcID has been passed and the item is NPC specific, only display
local odds = drop.chance
-- the item if it may be obtained while pickpocketing that NPC
 
if npcID == nil or drop.npcs == nil or Shared.contains(drop.npcs, npcID) then
rareTxt = rareTxt..'\r\n|-\r\n|'..Icons.Icon({thisItem.name, type='item'})
local thisItem = Items.getItemByID(drop.itemID)
rareTxt = rareTxt..'||1||data-sort-value="'..thisItem.sellsFor..'"|'..Icons.GP(thisItem.sellsFor)
local odds = drop.chance
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..'\r\n|-\r\n|'..Icons.Icon({thisItem.name, type='item'})
rareTxt = rareTxt..'||1||data-sort-value="'..thisItem.sellsFor..'"|'..Icons.GP(thisItem.sellsFor)
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)..'%'
end
end
end
rareTxt = rareTxt..'\r\n|}'
rareTxt = rareTxt..'\r\n|}'
Line 387: Line 395:
table.sort(lootTable, function(a, b) return a.weight > b.weight end)
table.sort(lootTable, function(a, b) return a.weight > b.weight end)
for i, loot in ipairs(lootTable) do
for i, loot in ipairs(lootTable) do
local thisItem = Items.getItemByID(loot.id)
local thisItem = Items.getItemByID(loot.itemID)
if thisItem ~= nil then
if thisItem ~= nil then
table.insert(normalTxt, '\r\n|-\r\n|'..Icons.Icon({thisItem.name, type='item'}))
table.insert(normalTxt, '\r\n|-\r\n|'..Icons.Icon({thisItem.name, type='item'}))
Line 395: Line 403:
table.insert(normalTxt, '||style="text-align:right" data-sort-value="'..(loot.minQuantity + loot.maxQuantity)..'"|')
table.insert(normalTxt, '||style="text-align:right" data-sort-value="'..(loot.minQuantity + loot.maxQuantity)..'"|')


if loot.minQuantitiy ~= loot.maxQuantitiy then
if loot.minQuantity ~= loot.maxQuantity then
table.insert(normalTxt, Shared.formatnum(loot.minQuantitiy) .. ' - ' .. Shared.formatnum(loot.maxQuantity))
table.insert(normalTxt, Shared.formatnum(loot.minQuantity) .. ' - ' .. Shared.formatnum(loot.maxQuantity))
else
else
table.insert(normalTxt, Shared.formatnum(loot.maxQuantity))
table.insert(normalTxt, Shared.formatnum(loot.maxQuantity))
Line 407: Line 415:
else
else
itemPrice = thisItem.sellsFor ~= nil and thisItem.sellsFor or 0
itemPrice = thisItem.sellsFor ~= nil and thisItem.sellsFor or 0
if itemPrice == 0 or loot.minQuantity == loot.maxQuantitiy then
if itemPrice == 0 or loot.minQuantity == loot.maxQuantity then
table.insert(normalTxt, '||'..Icons.GP(itemPrice))
table.insert(normalTxt, '||'..Icons.GP(itemPrice))
else
else
table.insert(normalTxt, '||'..Icons.GP(itemPrice * loot.minQuantitiy, itemPrice * loot.maxQuantitiy))
table.insert(normalTxt, '||'..Icons.GP(itemPrice * loot.minQuantity, itemPrice * loot.maxQuantity))
end
end
end
end
Line 427: Line 435:


--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 * (loot.minQuantitiy + loot.maxQuantitiy) / 2)
lootValue = lootValue + (dropChance * 0.01 * itemPrice * (loot.minQuantity + loot.maxQuantity) / 2)
end
end
if Shared.tableCount(npc.lootTable) > 1 then
if Shared.tableCount(npc.lootTable) > 1 then
Line 446: Line 454:
--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(npc.id)
table.insert(sectionTxt, rareTxt)
table.insert(sectionTxt, rareTxt)


Line 459: Line 467:
areaTxt = areaTxt..'!!Price!!colspan="2"|Chance'
areaTxt = areaTxt..'!!Price!!colspan="2"|Chance'
local dropLines = {}
local dropLines = {}
for i, drop in pairs(area.uniqueDrops) do
for i, drop in ipairs(area.uniqueDrops) do
local thisItem = Items.getItemByID(drop.id)
local thisItem = Items.getItemByID(drop.id)
local lineTxt = ''
local lineTxt = ''
Line 465: Line 473:
lineTxt = lineTxt..'||data-sort-value="'..drop.quantity..'"| '..Shared.formatnum(drop.quantity)..'||data-sort-value="'..thisItem.sellsFor..'"|'..Icons.GP(thisItem.sellsFor)
lineTxt = lineTxt..'||data-sort-value="'..drop.quantity..'"| '..Shared.formatnum(drop.quantity)..'||data-sort-value="'..thisItem.sellsFor..'"|'..Icons.GP(thisItem.sellsFor)
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.AreaUniqueChance, 2, 2)..'%'
lineTxt = lineTxt..'||'..Shared.round(SkillData.Thieving.baseAreaUniqueChance, 2, 2)..'%'
dropLines[thisItem.name] = lineTxt
dropLines[thisItem.name] = lineTxt
end
end
for i, txt in Shared.skpairs(dropLines) do
for i, txt in pairs(dropLines) do
areaTxt = areaTxt..txt
areaTxt = areaTxt..txt
end
end
Line 522: Line 530:
result = result..'||style="text-align:right"|'..npc.baseExperience
result = result..'||style="text-align:right"|'..npc.baseExperience
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" data-sort-value="' .. npc.perception .. '| '..Shared.formatnum(npc.perception)
result = result..'||data-sort-value="' .. npc.maxGP .. '"|'..Icons.GP(1, npc.maxGP)
result = result..'||data-sort-value="' .. npc.maxGP .. '"|'..Icons.GP(1, npc.maxGP)
if npc.uniqueDrop ~= nil then
if npc.uniqueDrop ~= nil then
Line 550: Line 558:
-- Build NPC list & determine level for area, this is the minimum
-- Build NPC list & determine level for area, this is the minimum
-- Thieving level required for all NPCs within that area
-- Thieving level required for all NPCs within that area
if area.npcs ~= nil and not Shared.tableIsEmpty(area.npcs) then
if area.npcIDs ~= nil and not Shared.tableIsEmpty(area.npcIDs) then
for j, npcID in ipairs(area.npcs) do
for j, npcID in ipairs(area.npcIDs) do
local npc = Skills.getThievingNPCByID(npcID)
local npc = Skills.getThievingNPCByID(npcID)
if minLevel == nil or npc.level < minLevel then
if minLevel == nil or npc.level < minLevel then
Line 618: Line 626:
result = result..'!!Seed Sources'
result = result..'!!Seed Sources'


table.sort(seedList, function(a, b) return a.farmingLevel < b.farmingLevel end)
table.sort(seedList, function(a, b) return a.level < b.level end)


for i, seed in ipairs(seedList) do
for i, seed in ipairs(seedList) do
Line 656: Line 664:
local recipes = GameData.getEntities(SkillData.Farming.recipes,
local recipes = GameData.getEntities(SkillData.Farming.recipes,
function(recipe)
function(recipe)
local product = Items.getItemByID(recipe.productID)
local product = Items.getItemByID(recipe.productId)
return product ~= nil and product.healsFor ~= nil and product.healsFor > 0
return product ~= nil and product.healsFor ~= nil and product.healsFor > 0
end)
end)
Line 662: Line 670:


for i, recipe in ipairs(recipes) do
for i, recipe in ipairs(recipes) do
local product = Items.getItemByID(recipe.productID)
local product = Items.getItemByID(recipe.productId)
if product ~= nil and product.healsFor ~= nil and product.healsFor > 0 then
if product ~= nil and product.healsFor ~= nil and product.healsFor > 0 then
result = result..'\r\n|-'
result = result..'\r\n|-'
Line 679: Line 687:
function p.getFarmingPlotTable(frame)
function p.getFarmingPlotTable(frame)
local areaName = frame.args ~= nil and frame.args[1] or frame
local areaName = frame.args ~= nil and frame.args[1] or frame
local patches = nil
local category = GameData.getEntityByName(SkillData.Farming.categories, areaName)
for i, area in Shared.skpairs(SkillData.Farming.Patches) do
if category == nil then
if area.areaName == areaName then
return 'ERROR: Invalid farming category. Please choose Allotments, Herbs, or Trees'
patches = area.patches
break
end
end
end
if patches == nil then
local patches = GameData.getEntities(SkillData.Farming.plots,
return "ERROR: Invalid area name.[[Category:Pages with script errors]]"
function(plot)
return plot.categoryID == category.id
end)
if Shared.tableIsEmpty(patches) then
return ''
end
end


local result = '{|class="wikitable"'
local result = '{|class="wikitable sortable stickyHeader"'
result = result..'\r\n!Plot!!'..Icons.Icon({'Farming', type='skill', notext=true})..' Level!!Cost'
result = result..'\r\n!Plot!!'..Icons.Icon({'Farming', type='skill', notext=true})..' Level!!Cost'


Line 696: Line 705:
result = result..'\r\n|-\r\n|'..i
result = result..'\r\n|-\r\n|'..i
result = result..'||style="text-align:right;" data-sort-value="' .. patch.level .. '"|'..patch.level
result = result..'||style="text-align:right;" data-sort-value="' .. patch.level .. '"|'..patch.level
if patch.cost == 0 then
local costText = (patch.gpCost > 0 and Icons.GP(patch.gpCost)) or 'Free'
result = result..'||Free'
result = result..'||style="text-align:right;" data-sort-value="'..patch.gpCost..'"|'..costText
else
result = result..'||style="text-align:right;" data-sort-value="'..patch.cost..'"|'..Icons.GP(patch.cost)
end
end
end