Anonymous

Module:Items/SourceTables: Difference between revisions

From Melvor Idle
_getItemLootSourceTable: Add fraction alongside percentage for chance stat (Attempt 2)
(Shop in Source list now uses the icon)
(_getItemLootSourceTable: Add fraction alongside percentage for chance stat (Attempt 2))
(4 intermediate revisions by the same user not shown)
Line 13: Line 13:
local Shop = require('Module:Shop')
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 246: 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 297: Line 307:
     end
     end
   end
   end
   --Add the special exceptions for Fire/Infernal Cape + lore books
   -- Special exceptions for Fire/Infernal Cape and first two lore books
   if item.name == 'Fire Cape' or item.id == 950 then
   if sourceOverrides['Dungeon'][item.id] ~= nil then
     if string.len(dungeonStr) > 0 then  
     if string.len(dungeonStr) > 0 then
       dungeonStr = dungeonStr..','
       dungeonStr = dungeonStr .. ','
     else
     else
       dungeonStr = 'Completing: '
       dungeonStr = 'Completing: '
     end
     end
     dungeonStr = dungeonStr..Icons.Icon({"Volcanic Cave", type="dungeon", notext=true})
     dungeonStr = dungeonStr .. Icons.Icon({sourceOverrides['Dungeon'][item.id], type='dungeon', notext=true})
  elseif item.name == 'Infernal Cape' or item.id == 951 then
    if string.len(dungeonStr) > 0 then
      dungeonStr = dungeonStr..','
    else
      dungeonStr = 'Completing: '
    end
    dungeonStr = dungeonStr..Icons.Icon({"Infernal Stronghold", type="dungeon", notext=true})
   end
   end


Line 531: 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 540: 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, chance)
   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:"'..qty..'"|'..minqty
     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.round(chance, 2, 2)..'%'
     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 577: Line 588:
           qty = loot[3]
           qty = loot[3]
         end
         end
      end
      if wt > 0 then
        local lootChance = monster.lootChance ~= nil and monster.lootChance or 100
        chance = ((wt * lootChance) / (totalWt * 100)) * 100
       end
       end
     end
     end
     if chance > 0 then
    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]
         local sourceTxt = Icons.Icon({dung.name, type="dungeon", notext=true})
         sourceTxt = Icons.Icon({dung.name, type='dungeon', notext=true})
         table.insert(dropRows, {source = sourceTxt, type = '[[Dungeon]]', minqty = minqty, qty = qty, chance = chance})
         typeTxt = '[[Dungeon]]'
       else
       else
         local sourceTxt = Icons.Icon({monster.name, type='monster'})
         sourceTxt = Icons.Icon({monster.name, type='monster'})
         table.insert(dropRows, {source = sourceTxt, type = '[[Monster]]', minqty = minqty, qty = qty, chance = chance})
         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/Infernal Cape and first two lore books as bonus dungeon drops
   --Special exception for the Fire/Infernal Cape and first two lore books as bonus dungeon drops
   if item.name == 'Fire Cape' or item.id == 950 then
   if sourceOverrides['Dungeon'][item.id] ~= nil then
      local sourceTxt = Icons.Icon({"Volcanic Cave", type="dungeon", notext=true})
    local sourceTxt = Icons.Icon({sourceOverrides['Dungeon'][item.id], type='dungeon', notext=true})
      table.insert(dropRows, {source = sourceTxt, type = '[[Dungeon]]', minqty = 1, qty = 1, chance = 100})
    table.insert(dropRows, {source=sourceTxt, type='[[Dungeon]]', minqty=1, qty=1, weight = 1, totalWeight = 1})
  elseif item.name == 'Infernal Cape' or item.id == 951 then
      local sourceTxt = Icons.Icon({"Infernal Stronghold", type="dungeon", notext=true})
      table.insert(dropRows, {source = sourceTxt, type = '[[Dungeon]]', minqty = 1, qty = 1, chance = 100})
   end
   end


Line 621: Line 629:


       if wt > 0 then
       if wt > 0 then
        chance = (wt / totalWt) * 100
         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, chance = chance})
         table.insert(dropRows, {source = sourceTxt, type = '[[Chest]]', minqty = 1, qty = qty, weight = wt, totalWeight = totalWt})
       end
       end
     end
     end
Line 643: Line 650:
       end
       end
       if wt > 0 then
       if wt > 0 then
         chance = (wt / totalWt) * 75
         -- 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, chance = chance})
         table.insert(dropRows, {source = sourceTxt, type = thiefType, minqty = 1, qty = qty, weight = wt * 75, totalWeight = totalWt * 100})
       end
       end
     end
     end
Line 653: 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, chance = thisGemChance})
    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, chance = thisGemChance})
     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, chance = thisGemChance})
     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 663: 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'})
    local thisChance = (item.fishingCatchWeight / Items.specialFishWt) * 100
     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, chance = thisChance})
   end
   end


Line 670: 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'})
    local thisChance = 100 / Items.junkCount
     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, chance = thisChance})
   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.chance > b.chance end)
   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.chance)
     result = result..buildRow(data.source, data.type, data.minqty, data.qty, data.weight, data.totalWeight)
   end
   end


Line 690: 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


Line 727: 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 785: 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 827: 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