17,097
edits
(First attempt at 1.0.3 update, requires testing) |
(Various fixes, implement tests) |
||
Line 72: | Line 72: | ||
local recipeKey = (skillID == SkillEnum.Herblore and 'Potions') or 'Recipes' | local recipeKey = (skillID == SkillEnum.Herblore and 'Potions') or 'Recipes' | ||
local recipe = SkillData[skill][recipeKey][masteryID + 1] | local recipe = SkillData[skill][recipeKey][masteryID + 1] | ||
if recipe ~= nil | if recipe ~= nil then | ||
local baseTime = { | local masteryReq = nil | ||
local itemMatch = (recipe.itemID == item.id) | |||
if skillID == SkillEnum.Herblore then | |||
-- For Herblore, we need to check a table of potion IDs & determine the mastery requirement | |||
for i, potionID in ipairs(recipe.potionIDs) do | |||
if potionID == item.id then | |||
itemMatch = true | |||
masteryReq = SkillData.Herblore.TierMasteryLevels[i] | |||
break | |||
end | |||
end | |||
end | |||
if itemMatch then | |||
local baseTime = { | |||
[SkillEnum.Smithing] = 2, | |||
[SkillEnum.Fletching] = 2, | |||
table.insert(tables, p.buildCreationTable(skill, lvl, xp, req, qty, time)) | [SkillEnum.Crafting] = 3, | ||
[SkillEnum.Runecrafting] = 2, | |||
[SkillEnum.Herblore] = 2 | |||
} | |||
local baseQty = recipe.baseQuantity or 1 | |||
lvl = recipe.level | |||
xp = recipe.baseXP | |||
time = baseTime[skillID] | |||
if masteryReq ~= nil and masteryReq > 1 then | |||
specialReq = Icons._MasteryReq(item.name, masteryReq, false) | |||
end | |||
-- Some items (such as Arrow shafts) have multiple recipes | |||
if type(recipe.alternativeCosts) == 'table' then | |||
local reqPart, qtyPart = {}, {} | |||
for i, altCost in ipairs(recipe.alternativeCosts) do | |||
local reqSubPart = {} | |||
for j, itemCost in ipairs(altCost.itemCosts) do | |||
local reqItem = Items.getItemByID(itemCost.id) | |||
if reqItem == nil then | |||
table.insert(reqSubPart, itemCost.qty .. 'x ?????') | |||
else | |||
table.insert(reqSubPart, Icons.Icon({reqItem.name, type='item', qty=altCost.itemCosts.qty})) | |||
end | |||
end | |||
table.insert(reqPart, table.concat(reqSubPart, ', ')) | |||
table.insert(qtyPart, Shared.formatnum(baseQty * altCost.quantityMultiplier)) | |||
end | |||
local sep = "<br/>'''OR''' " | |||
req = table.concat(reqPart, sep) | |||
qty = table.concat(qtyPart, sep) | |||
table.insert(tables, p.buildCreationTable(skill, lvl, xp, req, qty, time, maxTime, specialReq)) | |||
elseif type(recipe.itemCosts) == 'table' and Shared.tableCount(recipe.itemCosts) > 0 then | |||
req = recipe.itemCosts | |||
table.insert(tables, p.buildCreationTable(skill, lvl, xp, req, baseQty, time, maxTime, specialReq)) | |||
end | end | ||
end | end | ||
end | end | ||
Line 110: | Line 140: | ||
local shard = Items.getItemByID(cost.id) | local shard = Items.getItemByID(cost.id) | ||
if shard ~= nil then | if shard ~= nil then | ||
table.insert(ShardCostArray, Icons.Icon({ | table.insert(ShardCostArray, Icons.Icon({shard.name, type='item', notext=true, qty=cost.qty})) | ||
end | end | ||
end | end | ||
Line 304: | Line 334: | ||
table.insert(resultPart, '\r\n|-\r\n!style="text-align:right;"|Base Creation Time') | table.insert(resultPart, '\r\n|-\r\n!style="text-align:right;"|Base Creation Time') | ||
table.insert(resultPart, '\r\n|'..Shared.formatnum(Shared.round(time, 2, 0))..'s') | table.insert(resultPart, '\r\n|'..Shared.formatnum(Shared.round(time, 2, 0))..'s') | ||
if maxTime ~= nil then table.insert(resultPart, ' - '..Shared.formatnum(Shared.round(maxTime, 2, 0))..'s') end | if maxTime ~= nil and maxTime > time then table.insert(resultPart, ' - '..Shared.formatnum(Shared.round(maxTime, 2, 0))..'s') end | ||
table.insert(resultPart, '\r\n|}') | table.insert(resultPart, '\r\n|}') | ||
Line 626: | Line 656: | ||
table.insert(rowPart, '\r\n|style="text-align: left;"|'..type) | table.insert(rowPart, '\r\n|style="text-align: left;"|'..type) | ||
table.insert(rowPart, '\r\n|style="text-align: right;" data-sort-value="'..qty..'"|'..minqty) | table.insert(rowPart, '\r\n|style="text-align: right;" data-sort-value="'..qty..'"|'..Shared.formatnum(minqty)) | ||
if qty ~= minqty then table.insert(rowPart, ' - '..qty) end | if qty ~= minqty then table.insert(rowPart, ' - '..Shared.formatnum(qty)) end | ||
local chance = weight / totalWeight * 100 | local chance = weight / totalWeight * 100 | ||
-- 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 | ||
Line 749: | Line 779: | ||
local fishSource = '[[Fishing#Junk|Junk]]' | local fishSource = '[[Fishing#Junk|Junk]]' | ||
local fishType = Icons.Icon({'Fishing', type='skill'}) | local fishType = Icons.Icon({'Fishing', type='skill'}) | ||
local fishTotWeight = | local fishTotWeight = Shared.tableCount(SkillData.Fishing.JunkItems) | ||
table.insert(dropRows, {source = fishSource, type = fishType, minqty = 1, qty = 1, weight = 1, totalWeight = fishTotWeight}) | table.insert(dropRows, {source = fishSource, type = fishType, minqty = 1, qty = 1, weight = 1, totalWeight = fishTotWeight}) | ||
else | else | ||
Line 787: | Line 817: | ||
table.sort(dropRows, function(a, b) | table.sort(dropRows, function(a, b) | ||
if a.weight / a.totalWeight == b.weight / b.totalWeight then | if a.weight / a.totalWeight == b.weight / b.totalWeight then | ||
return a.minqty + a.qty > b.minqty + b.qty | if a.minqty + a.qty == b.minqty + b.qty then | ||
return (a.type == b.type and a.source < b.source) or a.type < b.type | |||
else | |||
return a.minqty + a.qty > b.minqty + b.qty | |||
end | |||
else | else | ||
return a.weight / a.totalWeight > b.weight / b.totalWeight | return a.weight / a.totalWeight > b.weight / b.totalWeight | ||
Line 998: | Line 1,032: | ||
-- - A monster before the boss, which doesn't drop anything except shards (checked above) | -- - A monster before the boss, which doesn't drop anything except shards (checked above) | ||
-- - A boss monster, whose drops are accounted for in data from Areas instead | -- - A boss monster, whose drops are accounted for in data from Areas instead | ||
for j, loot in ipairs(monster.lootTable) do | for j, loot in ipairs(monster.lootTable) do | ||
weight = weight + loot[2] | weight = weight + loot[2] | ||
Line 1,024: | Line 1,057: | ||
end | end | ||
--[[= | --[==[ | ||
-- Uncomment this block and execute 'p.test()' within the debug console | |||
-- to test after making changes | |||
]= | function p.test() | ||
local checkItems = { | |||
'Gold Bar', | |||
'Raw Shrimp', | |||
'Coal Ore', | |||
'Rune Platebody', | |||
'Arrow Shafts', | |||
'Yew Longbow', | |||
'Water Rune', | |||
'Steam Rune', | |||
'Controlled Heat Potion II', | |||
'Wolf', | |||
'Cyclops', | |||
'Leprechaun', | |||
'Redwood Logs', | |||
'Carrot Cake', | |||
'Carrot Cake (Perfect)', | |||
'Mantalyme Herb', | |||
'Carrot', | |||
'Topaz', | |||
'Rune Essence', | |||
'Sanguine Blade', | |||
'Ring of Power', | |||
'Infernal Claw', | |||
'Chapeau Noir', | |||
'Stardust', | |||
'Rope', | |||
'Ancient Ring of Mastery', | |||
'Mysterious Stone', | |||
'Mastery Token (Cooking)', | |||
'Gem Gloves' | |||
} | |||
local checkFuncs = { | |||
p.getItemSourceTables, | |||
--p.getCreationTable, | |||
p.getItemSources, | |||
--p.getItemLootSourceTable, | |||
} | |||
local errCount = 0 | |||
for i, item in ipairs(checkItems) do | |||
local param = {args={item}} | |||
mw.log('==' .. item .. '==') | |||
for j, func in ipairs(checkFuncs) do | |||
local callSuccess, retVal = pcall(func, param) | |||
if not callSuccess then | |||
errCount = errCount + 1 | |||
mw.log('Error with item "' .. item .. '": ' .. retVal) | |||
else | |||
mw.log(retVal) | |||
end | |||
end | |||
end | |||
if errCount == 0 then | |||
mw.log('Test successful') | |||
else | |||
mw.log('Test failed with ' .. errCount .. ' failures') | |||
end | |||
end | |||
--]==] | |||
return p | return p |