17,105
edits
(_getRecipeTable: Support GP & SC costs) |
(Update for v1.1) |
||
Line 2: | Line 2: | ||
--Contains function for skills that consume resources (ie smithing, cooking, herblore, etc.) | --Contains function for skills that consume resources (ie smithing, cooking, herblore, etc.) | ||
local p = {} | local p = {} | ||
local Shared = require('Module:Shared') | local Shared = require('Module:Shared') | ||
local Constants = require('Module:Constants') | |||
local GameData = require('Module:GameData') | |||
local SkillData = GameData.skillData | |||
local Items = require('Module:Items') | local Items = require('Module:Items') | ||
local Icons = require('Module:Icons') | local Icons = require('Module:Icons') | ||
Line 12: | Line 13: | ||
local category = frame.args ~= nil and frame.args[1] or frame | local category = frame.args ~= nil and frame.args[1] or frame | ||
local categoryMap = { | local categoryMap = { | ||
["Cooking Fire"] = | ["Cooking Fire"] = 'melvorD:Fire', | ||
["Furnace"] = | ["Furnace"] = 'melvorD:Furnace', | ||
["Pot"] = | ["Pot"] = 'melvorD:Pot' | ||
} | } | ||
local categoryID = categoryMap[category] | local categoryID = categoryMap[category] | ||
-- Find recipes for the relevant categories | -- Find recipes for the relevant categories | ||
-- Note: Excludes Lemon cake | |||
local recipeArray = GameData.getEntities(SkillData.Cooking.recipes, | |||
function(recipe) | |||
return (categoryID == nil or recipe.category == categoryID) and recipe.noMastery == nil | |||
end | end) | ||
table.sort(recipeArray, function(a, b) return a.level < b.level end) | |||
table.sort(recipeArray, function(a, b) return | |||
-- Logic for generating some cells of the table which are consistent for normal & perfect items | -- Logic for generating some cells of the table which are consistent for normal & perfect items | ||
Line 38: | Line 37: | ||
local getSaleValueCell = function(item, qty) | local getSaleValueCell = function(item, qty) | ||
if item ~= nil then | if item ~= nil then | ||
return 'data-sort-value="'.. | return 'data-sort-value="'..math.floor(item.sellsFor * qty)..'"|'..Icons.GP(math.floor(item.sellsFor))..(qty > 1 and ' (x'..qty..')' or '') | ||
else | else | ||
return ' ' | return ' ' | ||
Line 54: | Line 53: | ||
for i, recipe in ipairs(recipeArray) do | for i, recipe in ipairs(recipeArray) do | ||
local item = Items.getItemByID(recipe. | local item = Items.getItemByID(recipe.productID) | ||
local perfectItem = nil | local perfectItem = nil | ||
if recipe.perfectCookID ~= nil then | if recipe.perfectCookID ~= nil then | ||
Line 74: | Line 73: | ||
table.insert(resultPart, '||style="text-align:right"|' .. recipe.level) | table.insert(resultPart, '||style="text-align:right"|' .. recipe.level) | ||
table.insert(resultPart, '||style="text-align:right" data-sort-value="' .. recipe.baseInterval .. '"|' .. Shared.timeString(recipe.baseInterval / 1000, true)) | table.insert(resultPart, '||style="text-align:right" data-sort-value="' .. recipe.baseInterval .. '"|' .. Shared.timeString(recipe.baseInterval / 1000, true)) | ||
table.insert(resultPart, '||style="text-align:right" data-sort-value="' .. recipe. | table.insert(resultPart, '||style="text-align:right" data-sort-value="' .. recipe.baseExperience .. '"|' .. Shared.formatnum(recipe.baseExperience)) | ||
table.insert(resultPart, '||'..getHealingCell(item, qty)..'||'..getHealingCell(perfectItem, qty)) | table.insert(resultPart, '||'..getHealingCell(item, qty)..'||'..getHealingCell(perfectItem, qty)) | ||
table.insert(resultPart, '||'..getSaleValueCell(item, qty)..'||'..getSaleValueCell(perfectItem, qty)) | table.insert(resultPart, '||'..getSaleValueCell(item, qty)..'||'..getSaleValueCell(perfectItem, qty)) | ||
Line 81: | Line 80: | ||
local matItem = Items.getItemByID(mat.id) | local matItem = Items.getItemByID(mat.id) | ||
if matItem ~= nil then | if matItem ~= nil then | ||
table.insert(matArray, Icons.Icon({matItem.name, type='item', notext=true, qty=mat. | table.insert(matArray, Icons.Icon({matItem.name, type='item', notext=true, qty=mat.quantity})) | ||
end | end | ||
end | end | ||
Line 92: | Line 91: | ||
local tierSuffix = { 'I', 'II', 'III', 'IV' } | local tierSuffix = { 'I', 'II', 'III', 'IV' } | ||
function p._getHerblorePotionTable( | function p._getHerblorePotionTable(categoryName) | ||
if string.upper( | local categoryID = nil | ||
if string.upper(categoryName) == 'COMBAT' then | |||
elseif string.upper( | categoryID = 'melvorF:CombatPotions' | ||
elseif string.upper(categoryName) == 'SKILL' then | |||
categoryID = 'melvorF:SkillPotions' | |||
category | else | ||
return 'ERROR: No such potion category ' .. (categoryName or 'nil') .. '[[Category:Pages with script errors]]' | |||
end | end | ||
local potionArray = | local potionArray = GameData.getEntities(SkillData.Herblore.recipes, function(potion) return potion.categoryID == categoryID end) | ||
table.sort(potionArray, function(a, b) return a.level < b.level end) | |||
local resultPart = {} | local resultPart = {} | ||
Line 113: | Line 109: | ||
table.insert(resultPart, '\r\n!Potion!!'..Icons.Icon({'Herblore', type='skill', notext=true})..' Level') | table.insert(resultPart, '\r\n!Potion!!'..Icons.Icon({'Herblore', type='skill', notext=true})..' Level') | ||
table.insert(resultPart, '!!XP!!Ingredients!!style="width:30px;"|Tier!!Value!!Charges!!Effect') | table.insert(resultPart, '!!XP!!Ingredients!!style="width:30px;"|Tier!!Value!!Charges!!Effect') | ||
for i, potion in ipairs(potionArray) do | for i, potion in ipairs(potionArray) do | ||
Line 124: | Line 118: | ||
end | end | ||
table.insert(resultPart, '||rowspan="4" style="text-align:right"|'..potion.level) | table.insert(resultPart, '||rowspan="4" style="text-align:right"|'..potion.level) | ||
table.insert(resultPart, '||rowspan="4" style="text-align:right"|'..potion. | table.insert(resultPart, '||rowspan="4" style="text-align:right"|'..potion.baseExperience) | ||
local matArray = {} | local matArray = {} | ||
for j, mat in ipairs(potion.itemCosts) do | for j, mat in ipairs(potion.itemCosts) do | ||
local matItem = Items.getItemByID(mat.id) | local matItem = Items.getItemByID(mat.id) | ||
table.insert(matArray, Icons.Icon({matItem.name, type='item', notext=true, qty=mat. | table.insert(matArray, Icons.Icon({matItem.name, type='item', notext=true, qty=mat.quantity})) | ||
end | end | ||
table.insert(resultPart, '||rowspan="4"|'..table.concat(matArray, ', ')..'||') | table.insert(resultPart, '||rowspan="4"|'..table.concat(matArray, ', ')..'||') | ||
Line 137: | Line 131: | ||
local rowTxt = {} | local rowTxt = {} | ||
local tierPot = Items.getItemByID(potionID) | local tierPot = Items.getItemByID(potionID) | ||
local potDesc = '' | |||
if type(tierPot.modifiers) == 'table' and not Shared.tableIsEmpty(tierPot.modifiers) then | |||
potDesc = Constants.getModifiersText(tierPot.modifiers, false) or '' | |||
end | |||
table.insert(rowTxt, Icons.Icon({tierPot.name, type='item', notext=true})) | table.insert(rowTxt, Icons.Icon({tierPot.name, type='item', notext=true})) | ||
table.insert(rowTxt, Icons.Icon({tierPot.name, tierSuffix[j], type = 'item', noicon = true})) | table.insert(rowTxt, Icons.Icon({tierPot.name, tierSuffix[j], type = 'item', noicon=true})) | ||
table.insert(rowTxt, '||style="text-align:right;" data-sort-value="'..tierPot.sellsFor..'"|'..Icons.GP(tierPot.sellsFor)) | table.insert(rowTxt, '||style="text-align:right;" data-sort-value="'..tierPot.sellsFor..'"|'..Icons.GP(tierPot.sellsFor)) | ||
table.insert(rowTxt, '||style="text-align:right;"|'..tierPot. | table.insert(rowTxt, '||style="text-align:right;"|'..tierPot.charges..'|| '..potDesc) | ||
table.insert(tierRows, table.concat(rowTxt)) | table.insert(tierRows, table.concat(rowTxt)) | ||
end | end | ||
Line 181: | Line 179: | ||
elseif not Shared.contains({'string', 'nil'}, type(categoryName)) then | elseif not Shared.contains({'string', 'nil'}, type(categoryName)) then | ||
return 'ERROR: category must be a string or nil' | return 'ERROR: category must be a string or nil' | ||
elseif type(columnList) ~= 'table' or Shared. | elseif type(columnList) ~= 'table' or Shared.tableIsEmpty(columnList) then | ||
return 'ERROR: columnList must be a table with 1+ elements' | return 'ERROR: columnList must be a table with 1+ elements' | ||
end | end | ||
local supportedSkills = { | |||
'Crafting', | |||
'Fletching', | |||
'Runecrafting' | |||
} | |||
if not Shared.contains(supportedSkills, skillName) then | |||
return 'ERROR: The ' .. skillName .. ' skill is not supported by this function' | |||
end | |||
local categoryMap = { | local categoryMap = { | ||
["Runecrafting"] = { | ["Runecrafting"] = { | ||
Line 217: | Line 223: | ||
} | } | ||
-- Validation: Category | -- Validation: Category | ||
local category = GameData.getEntityByName(SkillData[skillName].categories, categoryName) | |||
if category == nil then | |||
local catNames = {} | local catNames = {} | ||
for | for i, cat in pairs(SkillData[skillName].categories) do | ||
table.insert(catNames, | table.insert(catNames, cat.name) | ||
end | end | ||
return 'ERROR: No such category ' .. categoryName .. ' for skill ' .. skillName .. ', the following are available: ' .. table.concat(catNames, ', ') | return 'ERROR: No such category ' .. categoryName .. ' for skill ' .. skillName .. ', the following are available: ' .. table.concat(catNames, ', ') | ||
end | end | ||
local actionInterval = SkillData[skillName].baseInterval | |||
local actionInterval = | |||
-- Validation: Skill data | -- Validation: Skill data | ||
local recipeKey = ' | local recipeKey = 'recipes' | ||
if SkillData[skillName] == nil then | if SkillData[skillName] == nil then | ||
return 'ERROR: Could not locate skill data for ' .. skillName | return 'ERROR: Could not locate skill data for ' .. skillName | ||
Line 259: | Line 263: | ||
-- Determine which recipes to include | -- Determine which recipes to include | ||
local recipeList = | local recipeList = GameData.getEntities(SkillData[skillName][recipeKey], | ||
function(recipe) | |||
return category.id == nil or recipe.category == category.id | |||
end) | |||
end | if Shared.tableIsEmpty(recipeList) then | ||
if Shared. | |||
return '' | return '' | ||
end | end | ||
table.sort(recipeList, function(a, b) return | table.sort(recipeList, function(a, b) return a.level < b.level end) | ||
-- Build rows based on recipes | -- Build rows based on recipes | ||
for i, recipe in ipairs(recipeList) do | for i, recipe in ipairs(recipeList) do | ||
local item = Items.getItemByID(recipe. | local item = Items.getItemByID(recipe.productID) | ||
if item ~= nil then | if item ~= nil then | ||
-- Some recipes have alternative costs, so the recipe may require multiple rows | -- Some recipes have alternative costs, so the recipe may require multiple rows | ||
local costList = nil | local costList = nil | ||
if recipe.alternativeCosts ~= nil and Shared. | if recipe.alternativeCosts ~= nil and not Shared.tableIsEmpty(recipe.alternativeCosts) then | ||
costList = recipe.alternativeCosts | costList = recipe.alternativeCosts | ||
else | else | ||
Line 303: | Line 305: | ||
table.insert(resultPart, '\r\n|' .. spanStr .. 'style="text-align:right"| ' .. recipe.level) | table.insert(resultPart, '\r\n|' .. spanStr .. 'style="text-align:right"| ' .. recipe.level) | ||
elseif colID == 'SkillXP' then | elseif colID == 'SkillXP' then | ||
table.insert(resultPart, '\r\n|' .. spanStr .. 'style="text-align:right"| ' .. recipe. | table.insert(resultPart, '\r\n|' .. spanStr .. 'style="text-align:right"| ' .. recipe.baseExperience) | ||
elseif colID == 'GP' then | elseif colID == 'GP' then | ||
local val = math.floor(item.sellsFor) | local val = math.floor(item.sellsFor) | ||
Line 312: | Line 314: | ||
local matItem = Items.getItemByID(mat.id) | local matItem = Items.getItemByID(mat.id) | ||
if matItem ~= nil then | if matItem ~= nil then | ||
table.insert(matArray, Icons.Icon({matItem.name, type='item', notext=true, qty=mat. | table.insert(matArray, Icons.Icon({matItem.name, type='item', notext=true, qty=mat.quantity})) | ||
end | end | ||
end | end | ||
Line 319: | Line 321: | ||
end | end | ||
if recipe.scCost ~= nil and recipe.scCost > 0 then | if recipe.scCost ~= nil and recipe.scCost > 0 then | ||
table.insert(matArray, Icons.SC(recipe. | table.insert(matArray, Icons.SC(recipe.scCost)) | ||
end | end | ||
table.insert(resultPart, '\r\n|' .. (spanStr ~= '' and spanStr .. '| ' or ' ') .. table.concat(matArray, ', ')) | table.insert(resultPart, '\r\n|' .. (spanStr ~= '' and spanStr .. '| ' or ' ') .. table.concat(matArray, ', ')) | ||
elseif colID == 'SkillXPSec' then | elseif colID == 'SkillXPSec' then | ||
table.insert(resultPart, '\r\n|' .. spanStr .. 'style="text-align:right"| ' .. string.format('%.2f', recipe. | table.insert(resultPart, '\r\n|' .. spanStr .. 'style="text-align:right"| ' .. string.format('%.2f', recipe.baseExperience / actionInterval)) | ||
elseif colID == 'GPSec' then | elseif colID == 'GPSec' then | ||
local val = math.floor(item.sellsFor) * qty / actionInterval | local val = math.floor(item.sellsFor) * qty / actionInterval |