Module:Skills/Artisan

From Melvor Idle
< Module:Skills
Revision as of 19:36, 2 October 2021 by Auron956 (talk | contribs) (Substitute links with Icons.Icon() where possible to benefit from ambiguous link handling)
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 Shared = require('Module:Shared')
local Items = require('Module:Items')
local Icons = require('Module:Icons')

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 and item.name ~= 'Lemon Cake' 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 and item.name ~= 'Lemon Cake' end)
	end
	table.sort(itemArray, function(a, b) return a.cookingLevel < b.cookingLevel end)
	
	-- Logic for generating some cells of the table which are consistent for normal & perfect items
	local getHealingCell = function(item)
		if item ~= nil then
			return 'style="text-align:right" data-sort-value="'..math.floor(item.healsFor)..'"|'..Icons.Icon({"Hitpoints", type="skill", notext=true})..' '..math.floor(item.healsFor * 10)
		else
			return ' '
		end
	end
	local getSaleValueCell = function(item, qty)
		if item ~= nil then
			return 'data-sort-value="'..(math.floor(item.sellsFor) * qty)..'"|'..Icons.GP(math.floor(item.sellsFor))..(qty > 1 and ' (x'..qty..')' or '')
		else
			return ' '
		end
	end
	
	local result = '{| class="wikitable sortable stickyHeader"'
	result = result..'\r\n|- class="headerRow-0"'
	result = result..'\r\n!colspan="3" rowspan="2"|Cooked Item!!rowspan="2"|'..Icons.Icon({'Cooking', type='skill', notext=true})..' Level'
	result = result..'!!rowspan="2"|Cook Time!!rowspan="2"|XP!!colspan="2"|Healing!!colspan="2"|Value!!rowspan="2"|Ingredients'
	result = result..'\r\n|- class="headerRow-1"'
	result = result..'\r\n!Normal!!' .. Icons.Icon({'Perfect', type='bonus', ext='png', notext=true, nolink=true}) .. '!!Normal!!' .. Icons.Icon({'Perfect', type='bonus', ext='png', notext=true, nolink=true})
	
	for i, item in Shared.skpairs(itemArray) do
		local perfectItem = nil
		if item.perfectItem ~= nil then
			perfectItem = Items.getItemByID(item.perfectItem)
		end
		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..'\r\n|style="min-width:25px"| '
		if perfectItem ~= nil then
			result = result..Icons.Icon({perfectItem.name, type='item', notext=true, size='50'})
		end
		result = result..'||'
		if qty > 1 then
			result = result..qty..'x '
		end
		result = result..Icons.Icon({item.name, type='item', noicon = true})
		result = result..'||style="text-align:right"|'..item.cookingLevel
		result = result..'||style="text-align:right" data-sort-value="' .. item.cookingInterval .. '"|'..Shared.timeString(item.cookingInterval / 1000, true)
		result = result..'||style="text-align:right"|'..item.cookingXP
		result = result..'||'..getHealingCell(item)..'||'..getHealingCell(perfectItem)
		result = result..'||'..getSaleValueCell(item, qty)..'||'..getSaleValueCell(perfectItem, qty)
	    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.level < b.level 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.level
    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..'||'..Icons.Icon({tierPot.name, tierSuffix[j], type = 'item', noicon = true})
      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.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!'..Icons.Icon({'Runecrafting', type='skill', notext=true})..' 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;" |'..Icons.Icon({rune.name, type='item', noicon=true})
    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;" |'..Icons.Icon({fletch.name, type='item', noicon=true})
    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)
  elseif category == "Bags"		  then data =
  		 Items.getItems(function(item) return item.type == 'Bag' 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!'..Icons.Icon({'Crafting', type='skill', notext=true})..' 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;" |'..Icons.Icon({craft.name, type='item', noicon=true})
    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 = {}
    if craft.craftGPCost ~= nil and craft.craftGPCost > 0 then
    	table.insert(matArray, Icons.GP(craft.craftGPCost))
    end
    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