Anonymous

Module:Shop: Difference between revisions

From Melvor Idle
4,996 bytes added ,  17 November 2021
getShopMiscUpgradeTable: Include requirements column
(Implement getPurchase, getPurchaseStat, getCostString, _getPurchaseType, _getPurchaseContents, getPurchaseIcon; facilitates implementing a 'PurchaseBox' template)
(getShopMiscUpgradeTable: Include requirements column)
(6 intermediate revisions by the same user not shown)
Line 2: Line 2:


local ShopData = mw.loadData('Module:Shop/data')
local ShopData = mw.loadData('Module:Shop/data')
-- Data instead of Module:CombatAreas to avoid loop whne that module attempts to require Module:Shop
local AreaData = require('Module:CombatAreas/data')


local Shared = require('Module:Shared')
local Shared = require('Module:Shared')
Line 7: Line 9:
local Icons = require('Module:Icons')
local Icons = require('Module:Icons')
local Constants = require('Module:Constants')
local Constants = require('Module:Constants')
local Areas = require('Module:CombatAreas')


-- Overrides for various items, mostly relating to icon overrides
-- Overrides for various items, mostly relating to icon overrides
Line 48: Line 49:
     return p.getRequirementString(purchase.unlockRequirements)
     return p.getRequirementString(purchase.unlockRequirements)
   elseif stat == 'contents' then
   elseif stat == 'contents' then
     return p._getPurchaseContents(purchase)
     return p._getPurchaseContents(purchase, true)
   elseif stat == 'type' then
   elseif stat == 'type' then
     return p._getPurchaseType(purchase)
     return p._getPurchaseType(purchase)
Line 61: Line 62:
   local statName = args[2]
   local statName = args[2]
   local displayInline = (args['inline'] ~= nil and string.lower(args['inline']) == 'true' or false)
   local displayInline = (args['inline'] ~= nil and string.lower(args['inline']) == 'true' or false)
   local purchase = p.getPurchase(purchaseName)
  -- Hack for some purchases existing twice with varying costs (e.g. 'Extra Equipment Set')
   local purchaseList = {}
  if statName == 'cost' then
    purchaseList = p.getPurchases(function(cat, purch) return purch.name == purchaseName end)
  else
    purchaseList = {p.getPurchase(purchaseName)}
  end


   if purchase == nil then
   if Shared.tableCount(purchaseList) == 0 then
     return "ERROR: Couldn't find purchase with name '" .. purchaseName .. "'[[Category:Pages with script errors]]"
     return "ERROR: Couldn't find purchase with name '" .. purchaseName .. "'[[Category:Pages with script errors]]"
   else
   else
     return p._getPurchaseStat(purchase, statName, displayInline)
     local resultPart = {}
    for i, purchase in ipairs(purchaseList) do
      table.insert(resultPart, p._getPurchaseStat(purchase, statName, displayInline))
    end
    return table.concat(resultPart, ' or ')
   end
   end
end
end
Line 117: Line 128:
   if reqs.dungeonCompletion ~= nil then
   if reqs.dungeonCompletion ~= nil then
     for i, dungReq in Shared.skpairs(reqs.dungeonCompletion) do
     for i, dungReq in Shared.skpairs(reqs.dungeonCompletion) do
       local dung = Areas.getAreaByID('dungeon', dungReq[1])
       local dung = AreaData['dungeons'][dungReq[1] + 1]
       local dungStr = 'Complete '..Icons.Icon({dung.name, type='dungeon'})
       local dungStr = 'Complete '..Icons.Icon({dung.name, type='dungeon'})
       if dungReq[2] > 1 then
       if dungReq[2] > 1 then
Line 166: Line 177:
end
end


function p._getPurchaseContents(purchase)
function p._getPurchaseContents(purchase, asList)
  if asList == nil then asList = true end
   local containArray = {}
   local containArray = {}
   if purchase.contains.items ~= nil then
   if purchase.contains.items ~= nil and Shared.tableCount(purchase.contains.items) > 0 then
    if not asList then
      table.insert(containArray, '{| class="wikitable sortable stickyHeader"')
      table.insert(containArray, '|- class="headerRow-0"')
      table.insert(containArray, '! colspan="2" | Item !! Quantity')
    end
     for i, itemLine in Shared.skpairs(purchase.contains.items) do
     for i, itemLine in Shared.skpairs(purchase.contains.items) do
       local item = Items.getItemByID(itemLine[1])
       local item = Items.getItemByID(itemLine[1])
       table.insert(containArray, Icons.Icon({item.name, type='item', qty=itemLine[2]}))
       if asList then
        table.insert(containArray, Icons.Icon({item.name, type='item', qty=itemLine[2]}))
      else
        table.insert(containArray, '|-\r\n| style="min-width:25px"| ' .. Icons.Icon({item.name, type='item', notext=true, size='25'}))
        table.insert(containArray, '| ' .. Icons.Icon({item.name, type='item', noicon=true}) .. '\r\n| data-sort-value="' .. itemLine[2] .. '" style="text-align:right" | ' .. Shared.formatnum(itemLine[2]))
      end
     end
     end
   end
   end
   if purchase.charges ~= nil and purchase.charges > 0 then
   if purchase.charges ~= nil and purchase.charges > 0 then
     table.insert(containArray, '+'..purchase.charges..' '..Icons.Icon({purchase.name, type='item'})..' Charges')
     if asList then
      table.insert(containArray, '+'..purchase.charges..' '..Icons.Icon({purchase.name, type='item'})..' Charges')
    else
      table.insert(containArray, '|-\r\n| style="min-width:25px"| ' .. Icons.Icon({purchase.name, type='item', notext=true, size='25'}))
      table.insert(containArray, '| ' .. Icons.Icon({item.name, type='item', noicon=true}) .. ' Charges\r\n| data-sort-value="' .. purchase.charges .. '" style="text-align:right" | ' .. Shared.formatnum(purchase.charges))
    end
  end
  if not asList and Shared.tableCount(containArray) > 0 then table.insert(containArray, '|}') end
 
  local delim = (asList and '<br/>' or '\r\n')
  return table.concat(containArray, delim)
end
 
function p.getPurchaseContents(frame)
  local args = frame.args ~= nil and frame.args or frame
  local purchaseName = args[1]
  local asList = ((args[2] ~= nil and args[2] == 'true') or false)
  local purchase = p.getPurchase(purchaseName)
 
  if purchase == nil then
    return "ERROR: Couldn't find purchase with name '" .. purchaseName .. "'[[Category:Pages with script errors]]"
  else
    return p._getPurchaseContents(purchase, asList)
   end
   end
  return table.concat(containArray, '<br/>')
end
end


Line 226: Line 269:
   local headerPropsDefault = {
   local headerPropsDefault = {
     ["Purchase"] = 'colspan="2"',
     ["Purchase"] = 'colspan="2"',
     ["Cost"] = 'style="min-width:90px"'
     ["Cost"] = 'style="min-width:100px"'
   }
   }
   local usedColumns, purchHeader, sortOrder, headerProps = {}, 'Purchase', nil, {}
   local usedColumns, purchHeader, sortOrder, headerProps = {}, 'Purchase', nil, {}
Line 261: Line 304:
   end
   end


  -- Various overrides for certain shop items
  local purchOverrides = {
    ["Extra Bank Slot"] = { icon = {'Bank Slot', 'upgrade'}, link = 'Bank Slot', cost = Icons.Icon({'Coins', size = 25, notext = true}) .. ' <span style="font-size:127%; font-family: MathJax_Math; font-style: italic;">C<sub>b</sub></span>*' },
    -- Golbin Raid items
    ["Reduce Wave Skip Cost"] = { icon = {'Melvor Logo', nil}, link = nil },
    ["Food Bonus"] = { icon = {'Melvor Logo', nil}, link = nil },
    ["Ammo Gatherer"] = { icon = {'Melvor Logo', nil}, link = nil },
    ["Rune Pouch"] = { icon = {'Melvor Logo', nil}, link = nil },
    ["Increase Starting Prayer Points"] = { icon = {'Melvor Logo', nil}, link = nil },
    ["Unlock Combat Passive Slot"] = { icon = {'Melvor Logo', nil}, link = nil },
    ["Prayer"] = { icon = {'Prayer', 'skill'}, link = nil },
    ["Increase Prayer Level"] = { icon = {'Prayer', 'skill'}, link = nil },
    ["Increase Prayer Points gained per Wave Completion"] = { icon = {'Prayer', 'skill'}, link = nil }
  }
   -- Begin output generation
   -- Begin output generation
   local resultPart = {}
   local resultPart = {}
Line 445: Line 474:


   result = result..'\r\n|-\r\n!style="text-align:right;"|Contains'
   result = result..'\r\n|-\r\n!style="text-align:right;"|Contains'
   result = result..'\r\n|style="text-align:right;"|'..p._getPurchaseContents(purchase)
   result = result..'\r\n|style="text-align:right;"|'..p._getPurchaseContents(purchase, true)


   result = result..'\r\n|}'
   result = result..'\r\n|}'
Line 474: Line 503:
function p.getShopMiscUpgradeTable()
function p.getShopMiscUpgradeTable()
   local purchList = p.getPurchases(function(cat, purch) return cat == 'General' and string.find(purch.name, '^Auto Eat') == nil end)
   local purchList = p.getPurchases(function(cat, purch) return cat == 'General' and string.find(purch.name, '^Auto Eat') == nil end)
   return p._getShopTable(purchList, { columns = { 'Purchase', 'Description', 'Cost' }, purchaseHeader = 'Upgrade' })
   return p._getShopTable(purchList, { columns = { 'Purchase', 'Description', 'Cost', 'Requirements' }, purchaseHeader = 'Upgrade' })
end
end


Line 514: Line 543:
     local costAmt = p._getPurchaseSortValue(purchase)
     local costAmt = p._getPurchaseSortValue(purchase)
     table.insert(resultPart, '|-\r\n|style="min-width:25px; text-align:center;" data-sort-value="' .. purchase.name .. '"| ' .. Icons.Icon({purchase.name, type='upgrade', size=50, notext=true}))
     table.insert(resultPart, '|-\r\n|style="min-width:25px; text-align:center;" data-sort-value="' .. purchase.name .. '"| ' .. Icons.Icon({purchase.name, type='upgrade', size=50, notext=true}))
     table.insert(resultPart, '| [[' .. purchase.name .. ']]')
     table.insert(resultPart, '| ' .. Icons.Icon({purchase.name, type='upgrade', noicon=true}))
     table.insert(resultPart, '| style="text-align:right;" data-sort-value="' .. mods.increasedAutoEatThreshold .. '" | ' .. Shared.formatnum(Shared.round(mods.increasedAutoEatThreshold, 0, 0)) .. '%')
     table.insert(resultPart, '| style="text-align:right;" data-sort-value="' .. mods.increasedAutoEatThreshold .. '" | ' .. Shared.formatnum(Shared.round(mods.increasedAutoEatThreshold, 0, 0)) .. '%')
     table.insert(resultPart, '| style="text-align:right;" data-sort-value="' .. mods.increasedAutoEatEfficiency .. '" | ' .. Shared.formatnum(Shared.round(mods.increasedAutoEatEfficiency, 0, 0)) .. '%')
     table.insert(resultPart, '| style="text-align:right;" data-sort-value="' .. mods.increasedAutoEatEfficiency .. '" | ' .. Shared.formatnum(Shared.round(mods.increasedAutoEatEfficiency, 0, 0)) .. '%')
Line 533: Line 562:
       if reqs.dungeonCompletion ~= nil then
       if reqs.dungeonCompletion ~= nil then
         for i, areaReq in ipairs(reqs.dungeonCompletion) do
         for i, areaReq in ipairs(reqs.dungeonCompletion) do
           local dung = Areas.getAreaByID('dungeon', areaReq[1])
           local dung = AreaData['dungeons'][areaReq[1] + 1]
           if string.find(dung.name, 'God Dungeon$') ~= nil then return dung end
           if string.find(dung.name, 'God Dungeon$') ~= nil then return dung end
         end
         end
Line 558: Line 587:
     local costSortValue = p._getPurchaseSortValue(upgrade)
     local costSortValue = p._getPurchaseSortValue(upgrade)
     table.insert(resultPart, '|-\r\n|style="min-width:25px; text-align:center;" data-sort-value="' .. upgrade.name .. '"| ' .. Icons.Icon({upgrade.name, type='upgrade', size=50, notext=true}))
     table.insert(resultPart, '|-\r\n|style="min-width:25px; text-align:center;" data-sort-value="' .. upgrade.name .. '"| ' .. Icons.Icon({upgrade.name, type='upgrade', size=50, notext=true}))
     table.insert(resultPart, '| [[' .. upgrade.name .. ']]')
     table.insert(resultPart, '| ' .. Icons.Icon({upgrade.name, type='upgrade', noicon=true}))
     table.insert(resultPart, '| ' .. upgrade.description)
     table.insert(resultPart, '| ' .. upgrade.description)
     table.insert(resultPart, '| data-sort-value="' .. dung.name .. '"| ' .. Icons.Icon({dung.name, type='dungeon'}))
     table.insert(resultPart, '| data-sort-value="' .. dung.name .. '"| ' .. Icons.Icon({dung.name, type='dungeon'}))
Line 566: Line 595:


   return table.concat(resultPart, '\r\n')
   return table.concat(resultPart, '\r\n')
end
function p.getCookingUtilityTable(frame)
local category = nil
if frame ~= nil then category = frame.args ~= nil and frame.args[1] or frame end
local validCategories = {'Cooking Fire', 'Furnace', 'Pot'}
if category == nil or not Shared.contains({'Cooking Fire', 'Furnace', 'Pot'}, category) then
return 'ERROR: Invalid category specified. Must be one of the following: ' .. mw.text.listToText(validCategories, ', ', ' or ')
end
local categoryShort = string.match(category, '[^%s]+$')
local bonusSkillID = Constants.getSkillID('Cooking')
local bonusColMod, bonusColName = nil, nil
if category == 'Cooking Fire' then
bonusColMod = 'increasedSkillXP'
bonusColName = 'Bonus ' .. Icons.Icon({'Cooking', type='skill', notext=true}) .. ' XP'
else
bonusColMod = 'increasedChanceToDoubleItemsSkill'
bonusColName = 'Double Items Chance'
end
local modsPerfectChance = {'increasedChancePerfectCookFire', 'increasedChancePerfectCookFurnace',
                      'increasedChancePerfectCookPot', 'increasedChancePerfectCookGlobal'}
local totalBonusVal, totalPerfectChance = 0, 0
local utilityList = p.getPurchases(function(cat, purch) return cat == 'SkillUpgrades' and string.find(purch.name, category .. '$') ~= nil end)
local resultPart = {}
    -- Table header
    table.insert(resultPart, '{| class="wikitable stickyHeader"')
    table.insert(resultPart, '|- class="headerRow-0"')
    table.insert(resultPart, '!colspan="4"| !!colspan="2"|' .. bonusColName .. '!!colspan="2"|Bonus Perfect Chance')
    table.insert(resultPart, '|- class="headerRow-1"')
    table.insert(resultPart, '!colspan="2"|Name!!Level!!Cost' .. string.rep('!!This ' .. categoryShort .. '!!Total', 2))
   
    -- Row for each upgrade
    for i, utility in ipairs(utilityList) do
    -- First determine bonus XP/doubling chance and perfect chance
    local bonusVal, perfectChance = 0, 0
    if type(utility.contains) == 'table' then
    if type(utility.contains.modifiers) == 'table' then
    for modName, modVal in pairs(utility.contains.modifiers) do
    if modName == bonusColMod and type(modVal) == 'table' then
    -- Bonus XP/doubling
    for skID, skVal in pairs(modVal) do
    if skVal[1] == bonusSkillID then bonusVal = bonusVal + skVal[2] end
    end
    elseif Shared.contains(modsPerfectChance, modName) then
    -- Perfect chance
    perfectChance = perfectChance + modVal
    end
    end
    end
    end
    totalBonusVal = totalBonusVal + bonusVal
    totalPerfectChance = totalPerfectChance + perfectChance
   
    -- Mangle unlockRequirements so that it only includes skillLevels
    local unlockReqs = {}
    if type(utility.unlockRequirements) == 'table' then
    unlockReqs['skillLevel'] = utility.unlockRequirements.skillLevel
    end
   
    table.insert(resultPart, '|-')
    table.insert(resultPart, '|style="min-width:25px"|' .. Icons.Icon({utility.name, type='upgrade', size='50', notext=true}))
    table.insert(resultPart, '|' .. utility.name)
    table.insert(resultPart, '|style="text-align:right"|' .. p.getRequirementString(unlockReqs))
    table.insert(resultPart, '|style="text-align:right"|' .. p.getCostString(utility.cost, false))
    table.insert(resultPart, '|style="text-align:right"|' .. '+' .. bonusVal .. '%')
    table.insert(resultPart, '|style="text-align:right"|' .. '+' .. totalBonusVal .. '%')
    table.insert(resultPart, '|style="text-align:right"|' .. '+' .. perfectChance .. '%')
    table.insert(resultPart, '|style="text-align:right"|' .. '+' .. totalPerfectChance .. '%')
    end
    table.insert(resultPart, '|}')
return table.concat(resultPart, '\r\n')
end
end


return p
return p