Module:Cards

From Wildfrost Wiki
Revision as of 09:33, 13 June 2024 by Hopeless (talk | contribs) (oops)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

To edit card information, see Module:Cards/data

GetStat

Usage: {{#invoke:Cards|GetStat|<card>|<stat>}}

Returns the respective stat of the card.
Possible values for <stat>: name health scrap attack counter other desc summoncon tribes price gold challenge unlock

Table

Usage: {{#invoke:Cards|Table|<entry>|<header_list>}} OR
{{#invoke:Cards|Table|<entry_list>|*|<header_list>}}

Returns a table based on the given paramenters. <entry> is either a card name or type.
Types include: Boss Pet NonPetCompanion Companion Item Shade Clunker EnemyClunker Enemy Miniboss Boss ShopItem InventorsHut HotSpring Charm CursedCharm

Append a tribename before the type to filter cards exclusive to that tribe, eg SnowdwellersCompanion

<entry_list> is a list of valid <entry> values, input as multiple parameters, i.e. <entry1>|<entry2>|... etc..

<header_list> is a list of valid stats, input as multiple parameters, i.e. <stat1>|<stat2>|... etc..
Stats include: name health scrap attack counter other desc summoncon tribes price challenge

The first usage option is used when only 1 entry is needed, e.g. the only entry is a type category. Otherwise, use the second option.

If challenge is among the header stats, the table will be sorted based off the entry's ChallengeOrder value, if it exists.

CardInfobox

Usage: {{#invoke:Cards|CardInfobox|<card>|<template_params>}}

Returns the infobox of the card.

<template_params> is a list of template parameters input as multiple parameters, i.e. <p1>=<data1>|<p2>=<data2>|... etc.. These parameters are the same parameters used by Template:Infobox. Parameters without inputs are autofilled with fitting module data, to the best of its ability.

CharmInfobox

Usage: {{#invoke:Cards|CharmInfobox|<charm>|<template_params>}}

Returns the infobox of the charm.

<template_params> is a list of template parameters input as multiple parameters, i.e. <p1>=<data1>|<p2>=<data2>|... etc.. These parameters are the same parameters used by Template:Infobox. Parameters without inputs are autofilled with fitting module data, to the best of its ability.

Itembox

Usage: {{#invoke:Cards|Itembox|<card>|<template_params>}}

Returns the itembox of the card.

<template_params> is a list of template parameters input as multiple parameters, i.e. <p1>=<data1>|<p2>=<data2>|... etc.. These parameters are the same parameters used by Template:Itembox. Parameters without inputs are autofilled with fitting module data, to the best of its ability.

NavBoxSection

Usage: {{#invoke:Cards|NavBoxSection|<type>}}

Returns a list of links for cards of a certain type, for use in Template:NavboxCards.

suggested values for <type>: Boss Pet NonPetCompanion Item Shade Clunker EnemyClunker Enemy Miniboss Boss


local p = {}

--local KeyData = mw.loadData( 'Module:Code/data')
local all_cards = require("Module:Cards/data").cards
local all_langs = require("Module:Other_Languages/data").cards

--[[
Usage: {{#invoke:Cards|GetStat|<card>|<stat>}}

returns the respective stat of the card.
possible values for <stat>: name health scrap attack counter other desc summoncon tribes price challenge 
]]
function p.GetStat(frame)
	local card = all_cards[frame.args.name or frame.args[1]] 
	if card == nil then 
		return ""
	end
	local stat =  frame.args.stat or frame.args[2]  
	stat = trim(stat)
	local langCode = frame:expandTemplate{ title = 'USERLANG' } or 'en'
	return frame:preprocess(_getStat(card, stat, langCode))
end 

function _getStat(card, stat, langCode)
	local langCode = langCode or mw.getCurrentFrame():expandTemplate{ title = 'USERLANG' } or 'en'
	stat = string.lower(stat)
	if stat == "name" then
		return _getName(card, langCode) or ""
	elseif stat == "health" then
		return card.Health or ""
	elseif stat == "scrap" then
		return card.Scrap or ""
	elseif stat == "attack" then
		return card.Attack or ""
	elseif stat == "counter" then
		return card.Counter or ""
	elseif stat == "other" then
		return card.Other or ""
	elseif stat == "description" or stat == "desc" then
		return _getDesc(card, langCode) or ""
	elseif stat == "summoncon" then
		return card.SummonCon or ""
	elseif stat == "tribes" then
		local out = ""
		for i, tribe in ipairs(card.Tribes) do
			out = out .. "[[Tribes#" .. tribe .. "|".. tribe.."]]"
			if i < #card.Tribes then
				out = out .. ",<br>"
			end
		end
		return out
	elseif stat == "gold" then
		return card.Gold or ""
	elseif stat == "price" then
		return card.Price or ""
	elseif stat == "unlock" then
		return card.Unlock or ""
	elseif stat == "challenge" then
		return card.Challenge or ""
	else
		error("Argument Invalid:" .. stat) -- why is this necessary
	end
end

function _getOtherLangs(card)
	if all_langs[card.UniqueName] then 
		return all_langs[card.UniqueName]
	end
	if all_langs[card.Name] then 
		return all_langs[card.Name] 
	end
	for _, langs in pairs(all_langs) do
		if langs.en.Name == card.Name then
			return langs
		end
	end
	-- if no matches, the parent functions default to en
end

function _getName(card, langCode)
	local target = langCode or mw.getCurrentFrame():expandTemplate{ title = 'USERLANG' } or "en"
	if target ~= "en" and _getOtherLangs(card) and _getOtherLangs(card)[target] then
		return _getOtherLangs(card)[target].Name or ""
	end
	return card.Name or ""
end

function _getDesc(card, langCode)
	local target = langCode or mw.getCurrentFrame():expandTemplate{ title = 'USERLANG' } or "en"
	if target ~= "en" and _getOtherLangs(card) and _getOtherLangs(card)[target] then
		return _getOtherLangs(card)[target].Desc or ""
	end
	return card.Desc or ""
end

function p.testlang(name)
	mw.log(_getStat(all_cards[name], "name"), _getName(all_cards[name], "ja"))
end

--[[
Usage: {{#invoke:Cards|Table|<entry>|<header_list>}} OR
{{#invoke:Cards|Table|<entry_list>|*|<header_list>}}

returns a table based on the given paramenters.
<entry> is either a card name or type.
Types include: Boss Pet NonPetCompanion Companion Item Shade Clunker EnemyClunker Enemy Miniboss Boss ShopItem

Append a tribename before the type to filter cards exclusive to that tribe, eg "SnowdwellersCompanion"

<entry_list> is a list of valid <entry> values, input as multiple parameters, ie <entry1>|<entry2>|... etc.

<header_list> is a list of valid stats, input as multiple parameters, ie <stat1>|<stat2>|... etc.
stats include: name health scrap attack counter other desc summoncon tribes price

The first usage option is used when only 1 entry is needed, eg the only entry is a type category. otherwise, use the second option.
]]
function p.Table(frame)
	local arr = {{}, {}}
	local i = 1
	while frame.args[i] ~= nil and trim(frame.args[i]) ~= "*" do
	  	table.insert(arr[1], trim(frame.args[i]) or "")
	  	i = i + 1
	end
	if frame.args[i] ~= nil then
		i = i + 1
		while frame.args[i] ~= nil do
		  	table.insert(arr[2], string.lower(trim(frame.args[i]) or ""))
		  	i = i + 1
		end
	else 
		for i=2,#arr[1] do
			arr[2][i-1] = string.lower(arr[1][i])
		end
		arr[1] = {arr[1][1]}
	end
	return frame:preprocess(_table(arr[1], arr[2]))
end

function p.testy() 
	return _table({"Pet", "SnowdwellersNonPetCompanion"}, {"name", "desc", "challenge"})
end

function _table(entries, headers)
  local sortByChallenge = false
  
  local out = '{| class="wikitable sortable" style="text-align:center;"\n'
  for i, header in ipairs(headers) do
  	if header == "scrap" or header == "health" or header == "attack" or header == "counter" then
  		local statname = header:gsub("^%l", string.upper)
  		out = out .. "![[File:"..statname..".png|20px|link=Stats#Primary Stats]] "..statname.."\n"
  	elseif header == "tribes" then
  		out = out .. "!Tribe-exclusive?\n"
  	elseif header == "name" then
  		out = out .. "!Card Name\n"
  	elseif header == "desc" then
  		out = out .. "!Description\n"
  	elseif header == "summoncon" then
  		out = out .. "!Summon conditions\n"
  	elseif header == "challenge" then
  		out = out .. "!Challenge\n"
  		sortByChallenge = true
  	else
  		out = out .. "!" .. header:gsub("^%l", string.upper) .. "\n" --Covers all cases where the stat name and intended header are equal
  	end
  end
  
  local entryList = {}
  for i, entry in ipairs(entries) do
  	if all_cards[entry] then
  		all_cards[entry].UniqueName = entry
  		table.insert(entryList, all_cards[entry])
  	else -- entry is a type category
  		local tribe = nil
  		for _, tribename in ipairs({"Snowdwellers", "Shademancers", "Clunkmasters"}) do
  			if entry:sub(1, #tribename) == tribename then
  				tribe = tribename
  				entry = entry:sub(1+#tribename)
  			end
  		end
	  	for i, card in ipairs(sortedCards()) do
	  		if card.Types and card.Types[entry] 
	  		and (tribe == nil or (tribe and card.Tribes and tableContains(card.Tribes, tribe)))
	  		then
	    		table.insert(entryList, card)
	    	end
	  	end
	end
  end
  
  if sortByChallenge then
  	table.sort(entryList, function(a,b)
  		if a.ChallengeOrder and b.ChallengeOrder then
			return a.ChallengeOrder and b.ChallengeOrder and a.ChallengeOrder < b.ChallengeOrder
  		elseif a.ChallengeOrder ~= b.ChallengeOrder then
			return a.ChallengeOrder and true
		else
			return a.Name < b.Name
		end
	end)
  end
  
  for i, card in ipairs(entryList) do
	out = out.."|-\n"
	for i, header in ipairs(headers) do
		out = out.."|"
		if header == "image" then
			if card.Types and (card.Types["Charm"] or card.Types["CursedCharm"]) then
				out = out.."{{CharmArt|"
			else
				out = out.."{{CardArt|"
			end
			out = out.. (card.Image or card.UniqueName) .."}}"
		elseif header == "name" then
			local link = card.Link or card.UniqueName
			out = out.."style=\"text-align:center;\"|[[".. link .. "|" .. _getName(card) .."]]"
		elseif header == "description" or header == "desc" or header == "summoncon" then
			out = out.."style=\"text-align:center;\"|".. (_getStat(card, header) or "")
		elseif header == "health" and card.Health == nil and card.Scrap then
			out = out.. card.Scrap .." {{Stat|Scrap}}"
		else
			out = out .. _getStat(card, header) 
		end
		out = out.."\n"
    end
  end
  return out .. "|}"
end

function sortedCards()
	local sortedTable = {}
	for name, card in pairs(all_cards) do
		card.UniqueName = name
		table.insert(sortedTable, card)
	end
	table.sort(sortedTable, function(a,b)
		return a.Name < b.Name
	end)
	return sortedTable
end

function tableContains(table, value)
  for i = 1,#table do
    if (table[i] == value) then
      return true
    end
  end
  return false
end

--[[
Usage: {{#invoke:Cards|CardInfobox|<card>|<template_params>}}

returns the infobox of the card.
<template_params> is a list of template parameters input as multiple parameters, ie <p1>=<data1>|<p2>=<data2>|... etc.
These parameters are the same parameters used by Template:Infobox
Parameters without inputs are autofilled with fitting module data, to the best of its ability.
]]
function p.CardInfobox(frame) 
	local card = frame.args[1]
	card = trim(card)
	return frame:preprocess(_cardInfobox(all_cards[card], frame.args))
end

function _cardInfobox(card, params)
	local out = "{{infobox|category=Card"
	out = out .. "|name=" .. (params.name or _getName(card) or card.Name or "<br>")
	out = out .. "|image=" .. (params.image or "")
	out = out .. "|width=" .. (params.width or "")
	if params.hpType then
		out = out .. "|hpType=" .. params.hpType 
	elseif card.Health == nil and card.Scrap then
		out = out .. "|hpType=scrap"
	end
	out = out .. "|health=" .. (params.health or card.Health or card.Scrap or "<br>")
	out = out .. "|attack=" .. (params.attack or card.Attack or "<br>")
	out = out .. "|counter=" .. (params.counter or card.Counter or "<br>")
	out = out .. "|other=<div style=\"text-align: center;\">" .. (params.other or card.Other or "<br>") .. "</div>"
	out = out .. "|description=" .. (params.description or _getDesc(card) or card.Desc or "<br>")
	out = out .. "|desCol=" .. (params.desCol or "")
	if params.art then
		out = out .. "|art=" .. params.art
	else
		out = out .. "|art=" .. (card.Image or card.UniqueName or card.Name) .. ".png"
	end
	out = out .. "}}"
    return out
end

function trim(str)
	return str:match( "^%s*(.-)%s*$" )	
end

--[[
Usage: {{#invoke:Cards|CharmInfobox|<card>|<template_params>}}

returns the infobox of the charm.
<template_params> is a list of template parameters input as multiple parameters, ie <p1>=<data1>|<p2>=<data2>|... etc.
These parameters are the same parameters used by Template:Infobox
Parameters without inputs are autofilled with fitting module data, to the best of its ability.
]]
function p.CharmInfobox(frame) 
	local card = frame.args[1]
	card = trim(card)
	return frame:preprocess(_charmInfobox(all_cards[card], frame.args))
end

function _charmInfobox(card, params)
	local out = "{{infobox|category=Charm"
	out = out .. "|name=" .. (params.name or _getName(card) or card.Name or "<br>")
	out = out .. "|image=" .. (params.image or "")
	out = out .. "|width=" .. (params.width or "")
	out = out .. "|description=" .. (params.description or _getDesc(card) or card.Desc or "<br>")
	out = out .. "}}"
    return out
end

--[[
Usage: {{#invoke:Cards|Itembox|<card>|<template_params>}}

returns the itembox of the card.
<template_params> is a list of template parameters input as multiple parameters, ie <p1>=<data1>|<p2>=<data2>|... etc.
These parameters are the same parameters used by Template:Itembox
Parameters without inputs are autofilled with fitting module data, to the best of its ability.
]]
function p.Itembox(frame) 
	local card = frame.args[1]
	card = trim(card)
	return frame:preprocess(_itembox(all_cards[card], frame.args))
end

function _itembox(card, params)
	local out = "{{itembox|category=Card"
	out = out .. "|name=" .. (params.name or _getName(card) or card.Name or "<br>")
	out = out .. "|image=" .. (params.image or "")
	out = out .. "|attack=" .. (params.attack or card.Attack or "<br>")
	out = out .. "|other=<div style=\"text-align: center;\">" .. (params.other or card.Other or "<br>") .. "</div>"
	out = out .. "|description=" .. (params.description or _getDesc(card) or card.Desc or "<br>")
	out = out .. "|desCol=" .. (params.desCol or "")
	if params.art then
		out = out .. "|art=" .. params.art
	else
		out = out .. "|art=" .. (card.Image or card.UniqueName or card.Name) .. ".png"
	end
	out = out .. "}}"
    return out
end

--[[
Usage: {{#invoke:Cards|NavBoxSection|<type>}}

returns a list of links for cards of a certain type. For use in navboxes.
possible values for <type>: Boss Pet NonPetCompanion Companion Item Shade Clunker EnemyClunker Enemy Miniboss Boss ShopItem 
]]
function p.NavBoxSection(frame)
	local type = frame.args[1]
	return frame:preprocess(_navBoxSection(type))
end

function _navBoxSection(type)
	local out = ""
	local first = true
	for i, card in ipairs(sortedCards()) do
    	if card.Types and card.Types[type] then
    		if first then
    			first = false
    		else 
    			out = out .. " • "
    		end
    		out = out.. "<div style=\"display: inline-block;\">[[" .. (card.Link or card.UniqueName) .. "|" .. _getName(card) .. "]]</div>"
    	end
    end
	return out
end

return p