Module:Skills/Artisan

From Melvor Idle
< Module:Skills
Revision as of 16:17, 30 September 2021 by Falterfire (talk | contribs) (updated getCookedItemsTable)
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 category = frame.args ~= nil and frame.args[1] or frame
	local itemArray = nil
	
	if category == "Cooking Fire" then 
		itemArray = Items.getItems(function(item) return item.cookingCategory == 0 end)
	elseif category == "Furnace" then 
		itemArray = Items.getItems(function(item) return item.cookingCategory == 1 end)
	elseif category == "Pot"  then 
		itemArray = Items.getItems(function(item) return item.cookingCategory == 2 end)
	else
		itemArray = Items.getItems(function(item) return item.cookingCategory ~= nil end)
	end
	table.sort(itemArray, function(a, b) return a.cookingLevel < b.cookingLevel end)
	
	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'

	for i, item in Shared.skpairs(itemArray) do
		local qty = item.cookingQty
		if qty == nil then
			qty = 1
		end
		result = result..'\r\n|-'
		result = result..'\r\n|style="min-width:25px"|'..Icons.Icon({item.name, type='item', notext='true', size='50'})
		result = result..'||'
		if qty > 1 then
			result = result..qty..'x '
		end
		result = result..'[['..item.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="'..item.healsFor..'"|'..Icons.Icon({"Hitpoints", type="skill", notext=true})..' '..(item.healsFor * 10)
		result = result..'||style="text-align:right" data-sort-value="'..(item.sellsFor * qty)..'"|'..Icons.GP(item.sellsFor)
		if qty > 1 then
			result = result..' (x'..qty..')'
		end
	    local matArray = {}
	    for j, reqSet in pairs(item.recipeRequirements)  do
		    for k, mat in pairs(reqSet) do
				local matItem = Items.getItemByID(mat.id)
				table.insert(matArray, Icons.Icon({matItem.name, type='item', notext=true, qty=mat.qty}))
	    	end
		end
	    result = result..'\r\n|'..table.concat(matArray, ' ')
	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 = 
         Items.getItems(function(item) return item.runecraftingCategory == 0 end)
  elseif category == "ComboRunes" then data = 
         Items.getItems(function(item) return item.runecraftingCategory == 1 end)
  elseif category == "Weapons"    then data = 
         Items.getItems(function(item) return item.runecraftingCategory == 2 and item.runecraftingID end)
  elseif category == "AirGear"    then data = 
         Items.getItems(function(item) return item.runecraftingCategory == 3 end)
  elseif category == "WaterGear"  then data = 
         Items.getItems(function(item) return item.runecraftingCategory == 4 end)
  elseif category == "EarthGear"  then data = 
         Items.getItems(function(item) return item.runecraftingCategory == 5 end)
  elseif category == "FireGear"   then data = 
         Items.getItems(function(item) return item.runecraftingCategory == 6 end)
  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'

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

  for i, rune in Shared.skpairs(data) 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 = Items.getItems(function(item) return item.fletchingCategory == 0 end)
  elseif category == "Shortbows" then 
  	data = Items.getItems(function(item) return item.fletchingCategory == 1 end)
  elseif category == "Longbows"  then 
  	data = Items.getItems(function(item) return item.fletchingCategory == 2 end)
  elseif category == "Bolts"     then 
  	data =  Items.getItems(function(item) return item.fletchingCategory == 3 end)
  elseif category == "Crossbows" then 
  	data = Items.getItems(function(item) return item.fletchingCategory == 4 end)
  elseif category == "Javelins"  then 
  	data = Items.getItems(function(item) return item.fletchingCategory == 5 end)
  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'

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

  for i, fletch in Shared.skpairs(data) 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