Module:Skills/Summoning

From Melvor Idle
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/Summoning/doc

local p = {}

local ItemData = mw.loadData('Module:Items/data')
local SkillData = mw.loadData('Module:Skills/data')

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

function p.getFamiliars()
  return Items.getItems(function(item) return item.type == "Familiar" end)
end

function p.getMarkTable(frame)
  local result = ''
  result = result..'{| class="wikitable sortable stickyHeader"'
  result = result..'\r\n|- class="headerRow-0"'
  result = result..'\r\n!colspan="2"|Mark!!'..Icons.Icon({'Summoning', type='skill', notext=true})..' Level'
  result = result..'!!Discovered in'

  local Familiars = {}
  for i, recipe in ipairs(SkillData.Summoning.Marks) do
	  table.insert(Familiars, recipe)
  end
  table.sort(Familiars, function(a, b)
                          if a.level == b.level then
                            return a.masteryID < b.masteryID
                          else
                            return a.level < b.level
                          end
                        end)

  local rowArray = {}
  for i, Fam in ipairs(Familiars) do
	local item = Items.getItemByID(Fam.itemID)
	if item ~= nil then
	    local rowText = '|-'
	    rowText = rowText..'\r\n|data-sort-value="'..item.name..'"|'..Icons.Icon({item.name, type='mark', notext=true, size='50'})
	    rowText = rowText..'||'..Icons.Icon({item.name, 'Mark of the ' .. item.name, type='mark', noicon=true})
	    rowText = rowText..'||style="text-align:right"|'..Fam.level
	    local discoveredArray = {}
	    for j, SkillID in Shared.skpairs(Fam.skills) do
	      table.insert(discoveredArray, Icons.Icon({Constants.getSkillName(SkillID), type='skill'}))
	    end
	    rowText = rowText..'||'..table.concat(discoveredArray, '<br/>')
	    table.insert(rowArray, rowText)
	end
  end

  result = result..'\r\n'..table.concat(rowArray, '\r\n')

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

function p.getTabletTable(frame)
  local result = ''
  result = result..'{| class="wikitable sortable stickyHeader"'
  result = result..'\r\n|- class="headerRow-0"'
  result = result..'\r\n!colspan="2"|Name!!'..Icons.Icon({'Summoning', type='skill', notext=true})..' Level'
  result = result..'!!Tier!!Effect!!' .. Icons.Icon({'Melee', notext=true, nolink=true}) .. ' Max Hit!!Description!!Shard Cost!!Secondary!!Creation XP'

  local Familiars = {}
  for i, recipe in ipairs(SkillData.Summoning.Marks) do
	  table.insert(Familiars, recipe)
  end
  table.sort(Familiars, function(a, b)
                          if a.level == b.level then
                            return a.masteryID < b.masteryID
                          else
                            return a.level < b.level
                          end
                        end)

  local rowArray = {}
  for i, Fam in ipairs(Familiars) do
	local item = Items.getItemByID(Fam.itemID)
	if item ~= nil then
	    local maxHit, maxHitText = Items._getItemStat(item, 'summoningMaxhit'), ''
	    if maxHit ~= nil then
	      maxHit = maxHit * 10
	      maxHitText = 'style="text-align:right"; data-sort-value="' .. maxHit .. '"|' .. Shared.formatnum(maxHit)
	    end
	    local rowText = '|-'
	    rowText = rowText..'\r\n|data-sort-value="'..item.name..'"|'..Icons.Icon({item.name, type='item', notext=true, size='50'})
	    rowText = rowText..'||'..Icons.Icon({item.name, type='item', noicon=true})
	    rowText = rowText..'||style="text-align:right"|'..Fam.level
	    rowText = rowText..'||style="text-align:right"|'..Fam.tier
	    rowText = rowText..'||'..item.description..'||'..maxHitText..'||'..Fam.description

		-- Create item requirements text
		local ShardCostArray, OtherCostArray = {}, {}
		-- Shards
		for j, cost in ipairs(Fam.itemCosts) do
			local shard = Items.getItemByID(cost.id)
			if shard ~= nil then
				table.insert(ShardCostArray, Icons.Icon({shard.name, type='item', notext=true, qty=cost.qty}))
			end
		end
		rowText = rowText..'||style="text-align:right"|'..table.concat(ShardCostArray, ', ')..'&nbsp;'

		-- Other costs
		local recipeGPCost = SkillData.Summoning.RecipeGPCost
		if Fam.gpCost > 0 then
			table.insert(OtherCostArray, Icons.GP(Fam.gpCost))
		end
		if Fam.scCost > 0 then
			table.insert(OtherCostArray, Icons.SC(Fam.scCost))
		end
		for j, nonShardID in ipairs(Fam.nonShardItemCosts) do
			local nonShard = Items.getItemByID(nonShardID)
			if nonShard ~= nil then
				local itemValue = math.max(nonShard.sellsFor, 20)
				local nonShardQty = math.max(1, math.floor(recipeGPCost / itemValue))
				table.insert(OtherCostArray, Icons.Icon({nonShard.name, type='item', notext=true, qty=nonShardQty}))
			end
		end
		rowText = rowText..'||style="text-align:right"|'..table.concat(OtherCostArray, "<br/>'''OR''' ")

		rowText = rowText..'||style="text-align:right"|'..Fam.baseXP

	    table.insert(rowArray, rowText)
	end
  end

  result = result..'\r\n'..table.concat(rowArray, '\r\n')

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

function p.getSynergyTable(frame)
  local result = ''
  result = result..'{| class="wikitable sortable stickyHeader"'
  result = result..'\r\n|- class="headerRow-0"'
  result = result..'\r\n!colspan="2"|Familiar 1!!colspan="2"|Familiar 2!!Effect!!Requirements'

  local synergyList = {}
  for i, syn in ipairs(SkillData.Summoning.Synergies) do
	  table.insert(synergyList, syn)
  end
  table.sort(synergyList, function (a, b) return (a.summons[1] == b.summons[1] and a.summons[2] < b.summons[2]) or a.summons[1] < b.summons[1] end)

  local marksByID, famNames = {}, {}
  for i, recipe in ipairs(SkillData.Summoning.Marks) do
	  marksByID[recipe.masteryID] = recipe
	  local item = Items.getItemByID(recipe.itemID)
	  if item ~= nil then
	  	famNames[recipe.masteryID] = item.name
	  end
  end

  local rowArray = {}
  for i, syn in ipairs(synergyList) do
	local Fam1 = marksByID[syn.summons[1]]
	local Fam2 = marksByID[syn.summons[2]]
	if Fam1 ~= nil and Fam2 ~= nil then
      local FamName1 = famNames[Fam1.masteryID] or 'Unknown'
	  local FamName2 = famNames[Fam2.masteryID] or 'Unknown'
      local rowText = '|-'
      rowText = rowText..'\r\n|data-sort-value="'..FamName1..'"|'..Icons.Icon({FamName1, type='item', notext=true, size='30'})
      rowText = rowText..'||'..Icons.Icon({FamName1, type='item', noicon=true})
      rowText = rowText..'||data-sort-value="'..FamName2..'"|'..Icons.Icon({FamName2, type='item', notext=true, size='30'})
      rowText = rowText..'||'..Icons.Icon({FamName2, type='item', noicon=true})
      rowText = rowText..'||'..syn.description

      local reqArray = {}
      local reqLvl = math.max(Fam1.level, Fam2.level)
      table.insert(reqArray, Icons._SkillReq('Summoning', reqLvl))
      table.insert(reqArray, FamName1..' Mark Level '..(Fam2.tier + 1))
      table.insert(reqArray, FamName2..' Mark Level '..(Fam1.tier + 1))

      rowText = rowText..'||data-sort-value="'..reqLvl..'"|'..table.concat(reqArray, '<br/>')

      table.insert(rowArray, rowText)
    end
  end

  result = result..'\r\n'..table.concat(rowArray, '\r\n')

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

function p._getFamiliarSynergyTable(familiarID)
	local result = ''
	result = result..'{| class="wikitable sortable stickyHeader"'
	result = result..'\r\n|- class="headerRow-0"'
	result = result..'\r\n!colspan="2"|Familiar 1!!colspan="2"|Familiar 2!!Effect!!Requirements'

	local synergyList = {}
	for i, syn in ipairs(SkillData.Summoning.Synergies) do
		if Shared.contains(syn.summons, familiarID) then
			table.insert(synergyList, syn)
		end
	end
    table.sort(synergyList, function (a, b) return (a.summons[1] == b.summons[1] and a.summons[2] < b.summons[2]) or a.summons[1] < b.summons[1] end)

	local marksByID, famNames = {}, {}
	for i, recipe in ipairs(SkillData.Summoning.Marks) do
		marksByID[recipe.masteryID] = recipe
		local item = Items.getItemByID(recipe.itemID)
		if item ~= nil then
		  famNames[recipe.masteryID] = item.name
		end
	end

	local rowArray = {}
	for i, syn in ipairs(synergyList) do
		local Fam1 = marksByID[syn.summons[1]]
		local Fam2 = marksByID[syn.summons[2]]
		if Fam1 ~= nil and Fam2 ~= nil then
			local FamName1 = famNames[Fam1.masteryID] or 'Unknown'
			local FamName2 = famNames[Fam2.masteryID] or 'Unknown'
			local rowText = '|-'
			rowText = rowText..'\r\n|data-sort-value="'..FamName1..'"|'..Icons.Icon({FamName1, type='item', notext=true, size='30'})
			rowText = rowText..'||'..Icons.Icon({FamName1, type='item', noicon=true})
			rowText = rowText..'||data-sort-value="'..FamName2..'"|'..Icons.Icon({FamName2, type='item', notext=true, size='30'})
			rowText = rowText..'||'..Icons.Icon({FamName2, type='item', noicon=true})
			rowText = rowText..'||'..syn.description

			local reqArray = {}
			local reqLvl = math.max(Fam1.level, Fam2.level)
			table.insert(reqArray, Icons._SkillReq('Summoning', reqLvl))
			table.insert(reqArray, FamName1..' Mark Level '..(Fam2.tier + 1))
			table.insert(reqArray, FamName2..' Mark Level '..(Fam1.tier + 1))
			rowText = rowText..'||data-sort-value="'..reqLvl..'"|'..table.concat(reqArray, '<br/>')

			table.insert(rowArray, rowText)
		end
	end

	result = result..'\r\n'..table.concat(rowArray, '\r\n')
	result = result..'\r\n|}'
	return result
end

function p.getFamiliarSynergyTable(frame)
	local famName = frame.args ~= nil and frame.args[1] or frame
	local familiarID = nil
	local familiarItem = Items.getItem(famName)
	if familiarItem == nil then
		return 'ERROR: Not a valid familiar[[Category:Pages with script errors]]'
	else
		for i, recipe in ipairs(SkillData.Summoning.Marks) do
			if recipe.itemID == familiarItem.id then
				familiarID = recipe.masteryID
				break
			end
		end
		if familiarID == nil then
			return 'ERROR: Not a valid familiar[[Category:Pages with script errors]]'
		else
			return p._getFamiliarSynergyTable(familiarID)
		end
	end
end

function p._getSkillSummoningBonusTable(skill)
	local rowArray = {}
	local famNames = {}

	-- Familiars
	for i, recipe in ipairs(SkillData.Summoning.Marks) do
		local item = Items.getItemByID(recipe.itemID)
		if item ~= nil then
			famNames[recipe.masteryID] = item.name
			if item.modifiers ~= nil then
				local famSkills = Constants.getModifierSkills(item.modifiers)
				if Shared.contains(famSkills, skill) then
					table.insert(rowArray, {Fam1 = item.name, Fam2 = nil, Descrip = Constants.getModifiersText(item.modifiers, false)})
				end
			end
		end
	end

	-- Synergies
	for i, syn in ipairs(SkillData.Summoning.Synergies) do
		local synSkills = Constants.getModifierSkills(syn.modifiers)
		if Shared.contains(synSkills, skill) then
			local FamName1 = famNames[syn.summons[1]] or 'Unknown'
			local FamName2 = famNames[syn.summons[2]] or 'Unknown'
			table.insert(rowArray, {Fam1 = FamName1, Fam2 = FamName2, Descrip = syn.description})
		end
	end

	if Shared.tableCount(rowArray) == 0 then
		return ''
	end

	local resultPart = {}
	table.insert(resultPart, '{| class="wikitable sortable stickyHeader"')
  	table.insert(resultPart, '\r\n|- class="headerRow-0"')
	table.insert(resultPart, '\r\n!colspan="2"|Familiar 1!!colspan="2"|Familiar 2!!Effect')

	for i, rowItem in Shared.skpairs(rowArray) do
		table.insert(resultPart, '\r\n|-')
	    table.insert(resultPart, '\r\n|data-sort-value="'..rowItem.Fam1..'"|'..Icons.Icon({rowItem.Fam1, type='item', notext=true, size='30'}))
		table.insert(resultPart, '||'..Icons.Icon({rowItem.Fam1, type='item', noicon=true}))
		if rowItem.Fam2 ~= nil then
			table.insert(resultPart, '||data-sort-value="'..rowItem.Fam2..'"|'..Icons.Icon({rowItem.Fam2, type='item', notext=true, size='30'}))
			table.insert(resultPart, '||'..Icons.Icon({rowItem.Fam2, type='item', noicon=true}))
		else
			table.insert(resultPart, '|| || ')
		end
		table.insert(resultPart, '||'..(rowItem.Descrip or ' '))
	end

	table.insert(resultPart, '\r\n|}')
	return table.concat(resultPart)
end

function p.getSkillSummoningBonusTable(frame)
	local skillName = frame.args ~= nil and frame.args[1] or frame
	return p._getSkillSummoningBonusTable(skillName)
end

return p