Module:Skills/Artisan

From Melvor Idle
< Module:Skills
Revision as of 05:26, 21 August 2021 by ByteFoolish (talk | contribs) (getCraftingTable)
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.

Documentation for this module may be created at Module:Skills/Artisan/doc

--Splitting some functions into here to avoid bloating a single file
--Contains function for skills that consume resources (ie smithing, cooking, herblore, etc.)
local p = {}

local SkillData = mw.loadData('Module:Skills/data')
local ShopData = mw.loadData('Module:Shop/data')

local Shared = require('Module:Shared')
local Items = require('Module:Items')
local Icons = require('Module:Icons')
local Shop = require('Module:Shop')

function p.getCookedItemsTable(frame)
  local result = '{| class="wikitable sortable stickyHeader"'
  result = result..'\r\n|- class="headerRow-0"'
  result = result..'\r\n!colspan="2"|Cooked Item!!'..Icons.Icon({'Cooking', type='skill', notext=true})..' Level'
  result = result..'!!XP!!Healing!!Value!!Ingredients'

  local itemArray = Items.getItems(function(item) return item.cookingID ~= nil end)
  table.sort(itemArray, function(a, b) return a.cookingLevel < b.cookingLevel end)

  for i, item in Shared.skpairs(itemArray) do
    local cookedItem = Items.getItemByID(item.cookedItemID)
    result = result..'\r\n|-'
    result = result..'\r\n|style="min-width:25px"|'..Icons.Icon({cookedItem.name, type='item', notext='true', size='50'})..'||[['..cookedItem.name..']]'
    result = result..'||style="text-align:right"|'..item.cookingLevel
    result = result..'||style="text-align:right"|'..item.cookingXP
    result = result..'||style="text-align:right" data-sort-value="'..cookedItem.healsFor..'"|'..Icons.Icon({"Hitpoints", type="skill", notext=true})..' '..(cookedItem.healsFor * 10)
    result = result..'||style="text-align:right" data-sort-value="'..cookedItem.sellsFor..'"|'..Icons.GP(cookedItem.sellsFor)
    result = result..'||'..Icons.Icon({item.name, type='item', qty = 1})
  end

  result = result..'\r\n|}'
  return result
end

local tierSuffix = { 'I', 'II', 'III', 'IV' }
function p._getHerblorePotionTable(category)
  if string.upper(category) == 'COMBAT' then
    category = 0
  elseif string.upper(category) == 'SKILL' then
    category = 1
  elseif type(category) == 'string' then
    category = tonumber(category)
  end

  local potionArray = {}
  for i, potion in Shared.skpairs(SkillData.Herblore.ItemData) do
    if potion.category == category then
      table.insert(potionArray, potion)
    end
  end

  local result = '{|class = "wikitable sortable stickyHeader"'
  result = result..'\r\n|- class="headerRow-0"'
  result = result..'\r\n!Potion!!'..Icons.Icon({'Herblore', type='skill', notext=true})..' Level'
  result = result..'!!XP!!Ingredients!!colspan="2"|Tier!!Value!!Charges!!Effect'

  table.sort(potionArray, function(a, b) return a.herbloreLevel < b.herbloreLevel end)

  for i, potion in Shared.skpairs(potionArray) do
    local tierPots = {}
    for j = 1, 4, 1 do
      table.insert(tierPots, Items.getItemByID(potion.itemID[j]))
    end
    result = result..'\r\n|-'
    if potion.name == 'Bird Nests Potion' then
      result = result..'\r\n|rowspan="4"|[[Bird Nest Potion]]'
    else
      result = result..'\r\n|rowspan="4"|[['..potion.name..']]'
    end
    result = result..'||rowspan="4" style="text-align:right"|'..potion.herbloreLevel
    result = result..'||rowspan="4" style="text-align:right"|'..potion.herbloreXP

    local matArray = {}
    for j, mat in Shared.skpairs(tierPots[1].herbloreReq) do
      local matItem = Items.getItemByID(mat.id)
      table.insert(matArray, Icons.Icon({matItem.name, type='item', notext=true, qty=mat.qty}))
    end
    result = result..'||rowspan="4"|'..table.concat(matArray, ', ')..'||'
    
    local tierRows = {}
    for j, tierPot in Shared.skpairs(tierPots) do
      local rowTxt = Icons.Icon({tierPot.name, type='item', notext=true})
      rowTxt = rowTxt..'||[['..tierPot.name..'|'..tierSuffix[j]..']]'
      rowTxt = rowTxt..'||style="text-align:right;" data-sort-value="'..tierPot.sellsFor..'"|'..Icons.GP(tierPot.sellsFor)
      rowTxt = rowTxt..'||style="text-align:right;"|'..tierPot.potionCharges..'||'..tierPot.description
      table.insert(tierRows, rowTxt)
    end
    result = result..table.concat(tierRows, '\r\n|-\r\n|')
  end

  result = result..'\r\n|}'
  return result
end

function p.getHerblorePotionTable(frame)
  local category = frame.args ~= nil and frame.args[1] or frame
  return p._getHerblorePotionTable(category)
end

function p.getCookingFireTable(frame)
  local toolArray = {}
  for i, upgrade in Shared.skpairs(ShopData.Shop.SkillUpgrades) do
    if Shared.contains(upgrade.name, 'Cooking Fire') then
      table.insert(toolArray, upgrade)
    end
  end

  local result = '{| class="wikitable"'
  result = result..'\r\n!colspan="4"| !!colspan="2"|Bonus '..Icons.Icon({'Cooking', type='skill', notext=true})..' XP'
  result = result..'\r\n|- class="headerRow-0"'
  result = result..'\r\n!colspan="2"|Name!!'..Icons.Icon({'Firemaking', type='skill', notext=true})..' Level'
  result = result..'!!Cost!!This Fire!!Total'

  local total = 0
  local total2 = 0

  for i, tool in Shared.skpairs(toolArray) do
    result = result..'\r\n|-'
    result = result..'\r\n|style="min-width:25px" data-sort-value="'..tool.name..'"|'..Icons.Icon({tool.name, type='upgrade', size='50', notext=true})
    result = result..'||'..tool.name
    local level = 1
    if tool.unlockRequirements ~= nil and tool.unlockRequirements.skillLevel ~= nil then
      --Gonna be lazy and assume there's only the one skill level and it's the one we care about
      level = tool.unlockRequirements.skillLevel[1][2]
    end
    result = result..'||style="text-align:right"|'..level
    result = result..'||style="text-align:right" data-sort-value="'..tool.cost.gp..'"|'..Shop.getCostString(tool.cost)

    local bonusXP = tool.contains.modifiers.increasedSkillXP[1][2]
    total = total + bonusXP

    result = result..'||style="text-align:right"|+'..bonusXP..'%'
    result = result..'||style="text-align:right"|+'..total..'%'
  end

  result = result..'\r\n|}'
  return result
end

function p.getRunecraftingTable(frame)
  local category = frame.args ~= nil and frame.args[1] or frame
  local data = nil
  if     category == "Runes"      then data = SkillData.Runecrafting.Runes
  elseif category == "ComboRunes" then data = SkillData.Runecrafting.ComboRunes
  elseif category == "Weapons"    then data = SkillData.Runecrafting.Weapons
  elseif category == "AirGear"    then data = SkillData.Runecrafting.AirGear
  elseif category == "WaterGear"  then data = SkillData.Runecrafting.WaterGear
  elseif category == "EarthGear"  then data = SkillData.Runecrafting.EarthGear
  elseif category == "FireGear"   then data = SkillData.Runecrafting.FireGear
  end

  if data == nil then
    return "ERROR: Invalid Runecrafting category name.[[Category:Pages with script errors]]"
  end

  local result = '{| class="wikitable sortable stickyHeader"'
  result = result..'\r\n|- class="headerRow-0"'
  result = result..'\r\n!Item\r\n!Name\r\n!Runecrafting Level\r\n!Experience'
  result = result..'\r\n!Item Price\r\n!Ingredients\r\n!XP/s\r\n!GP/s'

  local rcArray = {}
  for i, rc in Shared.skpairs(data) do
    table.insert(rcArray, rc)
  end
  table.sort(rcArray, function(a, b) return a.runecraftingLevel < b.runecraftingLevel end)

  for i, rune in Shared.skpairs(rcArray) do
    result = result..'\r\n|-'
    result = result..'\r\n| style="text-align: left;" | '..Icons.Icon({rune.name, type='item', size='50', notext=true})
    result = result..'\r\n| style ="text-align: left;" |[['..rune.name..']]'
    result = result..'\r\n| style="text-align:right"|'..rune.runecraftingLevel
    result = result..'\r\n| style="text-align:right"|'..rune.runecraftingXP
    result = result..'\r\n| style="text-align:right"|'..rune.sellsFor

    local matArray = {}
    for j, mat in Shared.skpairs(rune.runecraftReq) do
      local matItem = Items.getItemByID(mat.id)
      table.insert(matArray, Icons.Icon({matItem.name, type='item', notext=true, qty=mat.qty}))
    end
    result = result..'\r\n|'..table.concat(matArray, ' ')

    local rcCraftTime = 2.00
    local xps = rune.runecraftingXP / rcCraftTime
    local gps = rune.sellsFor / rcCraftTime
    result = result..'\r\n| style="text-align:right"|'..string.format("%.2f", xps)
    result = result..'\r\n| style="text-align:right"|'..string.format("%.2f", gps)
  end

  result = result..'\r\n|}'
  return result
end

function p.getFletchingTable(frame)
  local category = frame.args ~= nil and frame.args[1] or frame
  local data = nil
  if     category == "Arrows"    then data = SkillData.Fletching.Arrows
  elseif category == "Shortbows" then data = SkillData.Fletching.Shortbows
  elseif category == "Longbows"  then data = SkillData.Fletching.Longbows
  elseif category == "Bolts"     then data = SkillData.Fletching.Bolts
  elseif category == "Crossbows" then data = SkillData.Fletching.Crossbows
  elseif category == "Javelins"  then data = SkillData.Fletching.Javelins
  end

  if data == nil then
    return "ERROR: Invalid Fletching category name.[[Category:Pages with script errors]]"
  end

  local result = '{| class="wikitable sortable stickyHeader"'
  result = result..'\r\n|- class="headerRow-0"'
  result = result..'\r\n!Item\r\n!Name\r\n!Fletching Level\r\n!Experience'
  result = result..'\r\n!Quantity\r\n!Sells For\r\n!Ingredients'

  local fletchArray = {}
  for i, fc in Shared.skpairs(data) do
    table.insert(fletchArray, fc)
  end
  table.sort(fletchArray, function(a, b) return a.fletchingLevel < b.fletchingLevel end)

  for i, fletch in Shared.skpairs(fletchArray) do
    result = result..'\r\n|-'
    result = result..'\r\n| style="text-align: left;" | '..Icons.Icon({fletch.name, type='item', size='50', notext=true})
    result = result..'\r\n| style ="text-align: left;" |[['..fletch.name..']]'
    result = result..'\r\n| style="text-align:right"|'..fletch.fletchingLevel
    result = result..'\r\n| style="text-align:right"|'..fletch.fletchingXP
    result = result..'\r\n| style="text-align:right"|'..fletch.fletchQty
    result = result..'\r\n| style="text-align:right"|'..fletch.sellsFor

    local matArray = {}
    for j, mat in Shared.skpairs(fletch.fletchReq) do
      local matItem = Items.getItemByID(mat.id)
      table.insert(matArray, Icons.Icon({matItem.name, type='item', notext=true, qty=mat.qty}))
    end
    result = result..'\r\n|'..table.concat(matArray, ' ')
  end

  result = result..'\r\n|}'
  return result
end

function p.getCraftingTable(frame)
  local category = frame.args ~= nil and frame.args[1] or frame
  local data = nil

  if     category == "Leather"    then data = 
         Items.getItems(function(item) return item.tier == "Leather" or item.tier == "Hard Leather" end)
  elseif category == "Dragonhide" then data = 
         Items.getItems(function(item) return item.tier == "Dragonhide" and item.craftingLevel ~= nil end)
  elseif category == "Rings"      then data = 
         Items.getItems(function(item) return item.type == "Ring" and item.craftingLevel ~= nil end)
  elseif category == "Necklaces"  then data = 
         Items.getItems(function(item) return item.type == "Amulet" and item.craftingLevel ~= nil end)
  end

  if data == nil then
    return "ERROR: Invalid Crafting category name.[[Category:Pages with script errors]]"
  end

  table.sort(data, function(a, b) return (a.craftingLevel == b.craftingLevel and a.id < b.id) 
                                       or a.craftingLevel <  b.craftingLevel end)

  local result = '{| class="wikitable sortable stickyHeader"'
  result = result..'\r\n|- class="headerRow-0"'
  result = result..'\r\n!Item\r\n!Name\r\n!Crafting Level\r\n!Experience'
  result = result..'\r\n!Item Price\r\n!Ingredients'

  for i, craft in Shared.skpairs(data) do
    result = result..'\r\n|-'
    result = result..'\r\n| style="text-align: left;" | '..Icons.Icon({craft.name, type='item', size='50', notext=true})
    result = result..'\r\n| style ="text-align: left;" |[['..craft.name..']]'
    result = result..'\r\n| style="text-align:right"|'..craft.craftingLevel
    result = result..'\r\n| style="text-align:right"|'..craft.craftingXP
    result = result..'\r\n| style="text-align:right"|'..craft.sellsFor

    local matArray = {}
    for j, mat in Shared.skpairs(craft.craftReq) do
      local matItem = Items.getItemByID(mat.id)
      table.insert(matArray, Icons.Icon({matItem.name, type='item', notext=true, qty=mat.qty}))
    end
    result = result..'\r\n|'..table.concat(matArray, ' ')
  end

  result = result..'\r\n|}'
  return result
end

return p