12,787
edits
m (testing) |
(_getItemLootSourceTable: Add fraction alongside percentage for chance stat (Attempt 2)) |
||
(26 intermediate revisions by 3 users not shown) | |||
Line 11: | Line 11: | ||
local Icons = require('Module:Icons') | local Icons = require('Module:Icons') | ||
local Items = require('Module:Items') | local Items = require('Module:Items') | ||
local Shop = require('Module:Shop') | |||
-- Implements overrides for sources which cannot be obtained from game data | |||
-- Currently only overrides for dungeon sources are implemented here | |||
local sourceOverrides = { | |||
['Dungeon'] = { | |||
[361] = 'Volcanic Cave', -- Fire Cape | |||
[941] = 'Infernal Stronghold', -- Infernal Cape | |||
[950] = 'Volcanic Cave', -- A Tale of the Past, a future's prophecy | |||
[951] = 'Fire God Dungeon' -- The First Hero and an Unknown Evil | |||
} | |||
} | |||
function p._getCreationTable(item) | function p._getCreationTable(item) | ||
Line 108: | Line 119: | ||
table.insert(tables, p.buildCreationTable(skill, lvl, xp, req, qty, time, maxTime)) | table.insert(tables, p.buildCreationTable(skill, lvl, xp, req, qty, time, maxTime)) | ||
end | end | ||
if item.type == " | if item.type == "Harvest" or item.type == "Herb" or item.type == "Logs" then | ||
-- | --Harvest/Herb means farming | ||
--Logs might mean farming or might not. Depends on the logs | --Logs might mean farming or might not. Depends on the logs | ||
for i, item2 in pairs(ItemData.Items) do | for i, item2 in pairs(ItemData.Items) do | ||
if item2.grownItemID == item.id then | if item2.grownItemID == item.id then | ||
Line 118: | Line 128: | ||
xp = item2.farmingXP | xp = item2.farmingXP | ||
time = item2.timeToGrow | time = item2.timeToGrow | ||
qty = | if item.type == 'Logs' then | ||
qty = 35 | |||
else | |||
qty = 15 | |||
end | |||
req = {{id = i - 1, qty = (item2.seedsRequired ~= nil and item2.seedsRequired or 1)}} | req = {{id = i - 1, qty = (item2.seedsRequired ~= nil and item2.seedsRequired or 1)}} | ||
table.insert(tables, p.buildCreationTable(skill, lvl, xp, req, qty, time)) | table.insert(tables, p.buildCreationTable(skill, lvl, xp, req, qty, time)) | ||
Line 242: | Line 256: | ||
local item = Items.getItem(itemName) | local item = Items.getItem(itemName) | ||
if item == nil then | if item == nil then | ||
return "ERROR: No item named "..itemName.." exists in the data module" | return "ERROR: No item named "..itemName.." exists in the data module[[Category:Pages with script errors]]" | ||
end | end | ||
Line 285: | Line 299: | ||
if string.len(killStr) > 0 then | if string.len(killStr) > 0 then | ||
killStr = killStr..',' | killStr = killStr..',' | ||
if count1 % 3 == 1 and count1 > 1 then killStr = killStr..'<br/>' end | --if count1 % 3 == 1 and count1 > 1 then killStr = killStr..'<br/>' end | ||
killStr = killStr..Icons.Icon({monster.name, type="monster", notext="true"}) | killStr = killStr..Icons.Icon({monster.name, type="monster", notext="true"}) | ||
else | else | ||
Line 293: | Line 307: | ||
end | end | ||
end | end | ||
-- | -- Special exceptions for Fire/Infernal Cape and first two lore books | ||
if | if sourceOverrides['Dungeon'][item.id] ~= nil then | ||
if string.len(dungeonStr) > 0 then | |||
dungeonStr = dungeonStr .. ',' | |||
if string.len(dungeonStr) > 0 then | |||
dungeonStr = dungeonStr..',' | |||
else | else | ||
dungeonStr = 'Completing: ' | dungeonStr = 'Completing: ' | ||
end | end | ||
dungeonStr = dungeonStr..Icons.Icon({ | dungeonStr = dungeonStr .. Icons.Icon({sourceOverrides['Dungeon'][item.id], type='dungeon', notext=true}) | ||
end | end | ||
Line 329: | Line 336: | ||
if string.len(lootStr) > 0 then | if string.len(lootStr) > 0 then | ||
lootStr = lootStr..',' | lootStr = lootStr..',' | ||
if count1 % 3 == 1 and count1 > 1 then lootStr = lootStr..'<br/>' end | --if count1 % 3 == 1 and count1 > 1 then lootStr = lootStr..'<br/>' end | ||
lootStr = lootStr..Icons.Icon({item2.name, type="item", notext="true"}) | lootStr = lootStr..Icons.Icon({item2.name, type="item", notext="true"}) | ||
else | else | ||
Line 341: | Line 348: | ||
if string.len(upgradeStr) > 0 then | if string.len(upgradeStr) > 0 then | ||
upgradeStr = upgradeStr..',' | upgradeStr = upgradeStr..',' | ||
if count2 % 3 == 1 and count2 > 1 then upgradeStr = upgradeStr..'<br/>' end | --if count2 % 3 == 1 and count2 > 1 then upgradeStr = upgradeStr..'<br/>' end | ||
upgradeStr = upgradeStr..Icons.Icon({item2.name, type="item", notext="true"}) | upgradeStr = upgradeStr..Icons.Icon({item2.name, type="item", notext="true"}) | ||
else | else | ||
Line 475: | Line 482: | ||
local rhaStr = 'Any action in: ' | local rhaStr = 'Any action in: ' | ||
rhaStr = rhaStr..Icons.Icon({'Woodcutting', type = 'skill', notext = true})..', '..Icons.Icon({'Fishing', type = 'skill', notext = true})..', '..Icons.Icon({'Mining', type = 'skill', notext = true})..',<br/>' | rhaStr = rhaStr..Icons.Icon({'Woodcutting', type = 'skill', notext = true})..', '..Icons.Icon({'Fishing', type = 'skill', notext = true})..', '..Icons.Icon({'Mining', type = 'skill', notext = true})..',<br/>' | ||
rhaStr = rhaStr..Icons.Icon({'Thieving', type = 'skill', notext = true})..', '..Icons.Icon({'Farming', type = 'skill', notext = true}) | rhaStr = rhaStr..Icons.Icon({'Thieving', type = 'skill', notext = true})..', '..Icons.Icon({'Farming', type = 'skill', notext = true})..', '..Icons.Icon({'Agility', type = 'skill', notext = true}) | ||
table.insert(lineArray, rhaStr) | table.insert(lineArray, rhaStr) | ||
elseif item.name == 'Mysterious Stone' then | elseif item.name == 'Mysterious Stone' then | ||
Line 482: | Line 489: | ||
rhaStr = rhaStr..Icons.Icon({'Fletching', type = 'skill', notext = true})..', '..Icons.Icon({'Crafting', type = 'skill', notext = true})..', '..Icons.Icon({'Runecrafting', type = 'skill', notext = true})..',<br/>' | rhaStr = rhaStr..Icons.Icon({'Fletching', type = 'skill', notext = true})..', '..Icons.Icon({'Crafting', type = 'skill', notext = true})..', '..Icons.Icon({'Runecrafting', type = 'skill', notext = true})..',<br/>' | ||
rhaStr = rhaStr..Icons.Icon({'Herblore', type='skill', notext = true})..', '..Icons.Icon({'Woodcutting', type = 'skill', notext = true})..', '..Icons.Icon({'Fishing', type = 'skill', notext = true})..',<br/>' | rhaStr = rhaStr..Icons.Icon({'Herblore', type='skill', notext = true})..', '..Icons.Icon({'Woodcutting', type = 'skill', notext = true})..', '..Icons.Icon({'Fishing', type = 'skill', notext = true})..',<br/>' | ||
rhaStr = rhaStr..Icons.Icon({'Mining', type = 'skill', notext = true})..', '..Icons.Icon({'Thieving', type = 'skill', notext = true})..', '..Icons.Icon({'Farming', type = 'skill', notext = true}) | rhaStr = rhaStr..Icons.Icon({'Mining', type = 'skill', notext = true})..', '..Icons.Icon({'Thieving', type = 'skill', notext = true})..', '..Icons.Icon({'Farming', type = 'skill', notext = true})..', '..Icons.Icon({'Agility', type = 'skill', notext = true}) | ||
rhaStr = rhaStr..'<br/>after finding '..Icons.Icon({'Crown of Rhaelyx', type='item'}) | rhaStr = rhaStr..'<br/>after finding '..Icons.Icon({'Crown of Rhaelyx', type='item'}) | ||
table.insert(lineArray, rhaStr) | table.insert(lineArray, rhaStr) | ||
Line 496: | Line 503: | ||
--Shop items (including special items like gloves that aren't otherwise listed) | --Shop items (including special items like gloves that aren't otherwise listed) | ||
local shopSources = Shop.getItemSourceArray(item.id) | |||
table.insert(lineArray, ' | if Shared.tableCount(shopSources) > 0 then | ||
table.insert(lineArray, Icons.Icon({'Shop'})) | |||
end | end | ||
Line 526: | Line 534: | ||
end | end | ||
if item == nil then | if item == nil then | ||
return "ERROR: No item named "..itemName.." exists in the data module" | return "ERROR: No item named "..itemName.." exists in the data module[[Category:Pages with script errors]]" | ||
end | end | ||
Line 535: | Line 543: | ||
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!Source!!Source Type!!Quantity!!Chance' | result = result..'\r\n!Source!!Source Type!!Quantity!!colspan="2"|Chance' | ||
--Set up function for adding rows | --Set up function for adding rows | ||
local buildRow = function(source, type, minqty, qty, | local buildRow = function(source, type, minqty, qty, weight, totalWeight) | ||
if minqty == nil then minqty = 1 end | if minqty == nil then minqty = 1 end | ||
local rowTxt = '\r\n|-' | local rowTxt = '\r\n|-' | ||
rowTxt = rowTxt..'\r\n|style ="text-align: left;"|'..source | rowTxt = rowTxt..'\r\n|style="text-align: left;"|'..source | ||
rowTxt = rowTxt..'\r\n|style ="text-align: left;"|'..type | rowTxt = rowTxt..'\r\n|style="text-align: left;"|'..type | ||
rowTxt = rowTxt..'\r\n|style ="text-align: right;" data-sort-value | rowTxt = rowTxt..'\r\n|style="text-align: right;" data-sort-value="'..qty..'"|'..minqty | ||
if qty ~= minqty then rowTxt = rowTxt..' - '..qty end | if qty ~= minqty then rowTxt = rowTxt..' - '..qty end | ||
rowTxt = rowTxt..'\r\n|style ="text-align: right;"|'..Shared. | local chance = Shared.round(weight / totalWeight * 100, 2, 2) | ||
if weight >= totalWeight then | |||
-- Fraction would be 1/1, so only show the percentage | |||
chance = 100 | |||
rowTxt = rowTxt .. '\r\n|colspan="2" ' | |||
else | |||
rowTxt = rowTxt .. '\r\n|style="text-align: right;" data-sort-value="' .. chance .. '"| ' .. Shared.fraction(weight, totalWeight) .. '\r\n|' | |||
end | |||
rowTxt = rowTxt..'style="text-align: right;" data-sort-value="'.. chance .. '"|'..chance..'%' | |||
return rowTxt | return rowTxt | ||
end | end | ||
local dropRows = {} | local dropRows = {} | ||
--Alright, time to go through a few ways to get the item | --Alright, time to go through a few ways to get the item | ||
--First up: Can we kill somebody and take theirs? | --First up: Can we kill somebody and take theirs? | ||
Line 572: | Line 588: | ||
qty = loot[3] | qty = loot[3] | ||
end | end | ||
end | end | ||
end | end | ||
if | local lootChance = monster.lootChance ~= nil and monster.lootChance or 100 | ||
if wt > 0 and lootChance > 0 then | |||
local sourceTxt = nil | |||
local typeTxt = nil | |||
--If we're dealing with a boss, this is a Dungeon row instead | --If we're dealing with a boss, this is a Dungeon row instead | ||
if monster.isBoss and not Shared.contains(item.name, 'Shard') then | if monster.isBoss and not Shared.contains(item.name, 'Shard') then | ||
local dung = Areas.getMonsterAreas(i - 1)[1] | local dung = Areas.getMonsterAreas(i - 1)[1] | ||
sourceTxt = Icons.Icon({dung.name, type='dungeon', notext=true}) | |||
typeTxt = '[[Dungeon]]' | |||
else | else | ||
sourceTxt = Icons.Icon({monster.name, type='monster'}) | |||
typeTxt = '[[Monster]]' | |||
end | end | ||
table.insert(dropRows, {source = sourceTxt, type = typeTxt, minqty = minqty, qty = qty, weight = wt * lootChance, totalWeight = totalWt * 100}) | |||
end | end | ||
end | end | ||
--Special exception for the Fire Cape as | --Special exception for the Fire/Infernal Cape and first two lore books as bonus dungeon drops | ||
if item. | if sourceOverrides['Dungeon'][item.id] ~= nil then | ||
local sourceTxt = Icons.Icon({sourceOverrides['Dungeon'][item.id], type='dungeon', notext=true}) | |||
table.insert(dropRows, {source=sourceTxt, type='[[Dungeon]]', minqty=1, qty=1, weight = 1, totalWeight = 1}) | |||
end | end | ||
Line 616: | Line 629: | ||
if wt > 0 then | if wt > 0 then | ||
local sourceTxt = Icons.Icon({item2.name, type='item'}) | local sourceTxt = Icons.Icon({item2.name, type='item'}) | ||
table.insert(dropRows, {source = sourceTxt, type = '[[Chest]]', minqty = 1, qty = qty, | table.insert(dropRows, {source = sourceTxt, type = '[[Chest]]', minqty = 1, qty = qty, weight = wt, totalWeight = totalWt}) | ||
end | end | ||
end | end | ||
Line 638: | Line 650: | ||
end | end | ||
if wt > 0 then | if wt > 0 then | ||
chance | -- There is a constant 75% chance of gaining an item per successful steal attempt | ||
local sourceTxt = Icons.Icon({npc.name, type='thieving'}) | local sourceTxt = Icons.Icon({npc.name, type='thieving'}) | ||
table.insert(dropRows, {source = sourceTxt, type = thiefType, minqty = 1, qty = qty, | table.insert(dropRows, {source = sourceTxt, type = thiefType, minqty = 1, qty = qty, weight = wt * 75, totalWeight = totalWt * 100}) | ||
end | end | ||
end | end | ||
Line 648: | Line 660: | ||
if item.type == 'Gem' then | if item.type == 'Gem' then | ||
local mineType = Icons.Icon({'Mining', type='skill'}) | local mineType = Icons.Icon({'Mining', type='skill'}) | ||
local thisGemChance = Items.GemTable[item.name].chance | local thisGemChance = Items.GemTable[item.name].chance | ||
table.insert(dropRows, {source = '[[Mining#Gems|Gem]]', type = mineType, minqty = 1, qty = 1, | local totalGemChance = 0 | ||
for i, gem in pairs(Items.GemTable) do | |||
totalGemChance = totalGemChance + gem.chance | |||
end | |||
table.insert(dropRows, {source = '[[Mining#Gems|Gem]]', type = mineType, minqty = 1, qty = 1, weight = thisGemChance, totalWeight = totalGemChance}) | |||
local magicType = Icons.Icon({'Magic', type = 'skill'}) | local magicType = Icons.Icon({'Magic', type = 'skill'}) | ||
table.insert(dropRows, {source = Icons.Icon({"Rags to Riches I", type="spell"}), type = magicType, minqty = 1, qty = 1, | table.insert(dropRows, {source = Icons.Icon({"Rags to Riches I", type="spell"}), type = magicType, minqty = 1, qty = 1, weight = thisGemChance, totalWeight = totalGemChance}) | ||
table.insert(dropRows, {source = Icons.Icon({"Rags to Riches II", type="spell"}), type = magicType, minqty = 1, qty = 1, | table.insert(dropRows, {source = Icons.Icon({"Rags to Riches II", type="spell"}), type = magicType, minqty = 1, qty = 1, weight = thisGemChance, totalWeight = totalGemChance}) | ||
end | end | ||
Line 658: | Line 674: | ||
local fishSource = '[[Fishing#Special|Special]]' | local fishSource = '[[Fishing#Special|Special]]' | ||
local fishType = Icons.Icon({'Fishing', type='skill'}) | local fishType = Icons.Icon({'Fishing', type='skill'}) | ||
table.insert(dropRows, {source = fishSource, type = fishType, minqty = 1, qty = 1, weight = item.fishingCatchWeight, totalWeight = Items.specialFishWt}) | |||
table.insert(dropRows, {source = fishSource, type = fishType, minqty = 1, qty = 1, | |||
end | end | ||
Line 665: | Line 680: | ||
local fishSource = '[[Fishing#Junk|Junk]]' | local fishSource = '[[Fishing#Junk|Junk]]' | ||
local fishType = Icons.Icon({'Fishing', type='skill'}) | local fishType = Icons.Icon({'Fishing', type='skill'}) | ||
table.insert(dropRows, {source = fishSource, type = fishType, minqty = 1, qty = 1, weight = 1, totalWeight = Items.junkCount}) | |||
table.insert(dropRows, {source = fishSource, type = fishType, minqty = 1, qty = 1, | |||
end | end | ||
--Make sure to return nothing if there are no drop sources | --Make sure to return nothing if there are no drop sources | ||
if Shared.tableCount(dropRows) == 0 then return '' end | if Shared.tableCount(dropRows) == 0 then return '' end | ||
table.sort(dropRows, function(a, b) return a. | table.sort(dropRows, function(a, b) return a.weight / a.totalWeight > b.weight / b.totalWeight end) | ||
for i, data in pairs(dropRows) do | for i, data in pairs(dropRows) do | ||
result = result..buildRow(data.source, data.type, data.minqty, data.qty, data. | result = result..buildRow(data.source, data.type, data.minqty, data.qty, data.weight, data.totalWeight) | ||
end | end | ||
Line 685: | Line 699: | ||
local item = Items.getItem(itemName) | local item = Items.getItem(itemName) | ||
if item == nil then | if item == nil then | ||
return "ERROR: No item named "..itemName.." exists in the data module" | return "ERROR: No item named "..itemName.." exists in the data module[[Category:Pages with script errors]]" | ||
end | end | ||
return p._getItemLootSourceTable(item) | return p._getItemLootSourceTable(item) | ||
end | end | ||
Line 779: | Line 736: | ||
local item = Items.getItem(itemName) | local item = Items.getItem(itemName) | ||
if item == nil then | if item == nil then | ||
return "ERROR: No item named "..itemName.." exists in the data module" | return "ERROR: No item named "..itemName.." exists in the data module[[Category:Pages with script errors]]" | ||
end | end | ||
Line 837: | Line 794: | ||
local item = Items.getItem(itemName) | local item = Items.getItem(itemName) | ||
if item == nil then | if item == nil then | ||
return "ERROR: No item named "..itemName.." exists in the data module" | return "ERROR: No item named "..itemName.." exists in the data module[[Category:Pages with script errors]]" | ||
end | end | ||
Line 845: | Line 802: | ||
function p._getItemSourceTables(item) | function p._getItemSourceTables(item) | ||
local result = '' | local result = '' | ||
local shopTable = | local shopTable = Shop._getItemShopTable(item) | ||
if string.len(shopTable) > 0 then | if string.len(shopTable) > 0 then | ||
result = result..'===Shop===\r\n'..shopTable | result = result..'===Shop===\r\n'..shopTable | ||
Line 879: | Line 836: | ||
local item = Items.getItem(itemName) | local item = Items.getItem(itemName) | ||
if item == nil then | if item == nil then | ||
return "ERROR: No item named "..itemName.." exists in the data module" | return "ERROR: No item named "..itemName.." exists in the data module[[Category:Pages with script errors]]" | ||
end | end | ||
Line 887: | Line 844: | ||
function p.getCombatPassiveSlotItems(frame) | function p.getCombatPassiveSlotItems(frame) | ||
local table = '{| class="wikitable"\r\n' | local table = '{| class="wikitable"\r\n' | ||
table = table..'|-\r\n' | table = table..'|-\r\n' | ||
table = table..'!colspan="2"|Item\r\n! Passive\r\n' | |||
local itemArray = Items.getItems(function(item) return item.isPassiveItem and true or false end) | |||
for i, item in | for i, item in Shared.skpairs(itemArray) do | ||
table = table..'|-\r\n' | |||
table = table..'! '..Icons.Icon({item.name, type='item', notext='true'})..'\r\n! [['..item.name..']]\r\n' | |||
table = table..'| '..item.description..'\r\n' | |||
end | end | ||