Jump to content

Module:Shared VA

From The Petit Planet Wiki
Revision as of 21:49, 14 September 2026 by Shirra (talk | contribs)
Module documentation

This module implements {{Shared VA}}.

-- Source: https://honkai-star-rail.fandom.com/wiki/Module:Shared_VA
local p = {}
local Parse = require('Module:Parser').getTemplateArgs
local lib = require('Module:Feature')
local lang_dict = {
    ["EN"] = "English",
    ["CN"] = "Chinese",
    ["JP"] = "Japanese",
    ["KR"] = "Korean",
}
local games_dict = {
    ["pp"]  = nil,
    ["hsr"] = "Honkai: Star Rail",
    ["hi3"] = "Honkai Impact 3rd",
    ["hg2"] = "Houkai Gakuen 2",
    ["hna"] = "Honkai: Nexus Anima",
    ["gi"]  = "Genshin Impact",
    ["zzz"] = "Zenless Zone Zero",
    ["tot"] = "Tears of Themis",
}
local iw_links = {
    ["pp"]  = "[https://petitplanet.wiki/%s %s]",
    ["hsr"] = "[[w:c:honkai-star-rail:%s|%s]]",
    ["hi3"] = "[[w:c:honkaiimpact3:%s|%s]]",
    ["hg2"] = "[[w:c:houkai2nd:%s|%s]]",
    ["hna"] = "[https://hna.wiki/%s %s]",
    ["gi"]  = "[[w:c:genshin-impact:%s|%s]]",
    ["zzz"] = "[[w:c:zenless-zone-zero:%s|%s]]",
    ["tot"] = "[https://tot.wiki/wiki/%s %s]",
}
local game_order = {'pp', 'hg2', 'hi3', 'tot', 'gi', 'hsr', 'zzz', 'hna'}
local lang_order = {'EN', 'CN', 'JP', 'KR'}

function p.main(frame)
    local args = require('Module:Arguments').getArgs(frame, {
        parentFirst = true
    })
	if (lib.isEmpty(args['char'])) then
		args['char'] = mw.title.getCurrentTitle().rootText
	end
	return p._main(args, frame)
end

function p._main(args, frame)
	local VAs = {character = args['char']}
	local data = Parse(args['char'], {only='Neighbor Infobox'}) or {}
	local out = mw.html.create('ul')
	
	for _, lang in ipairs(lang_order) do
		-- Language's VA name
		local va = data['va'..lang] or ''
		VAs[lang] = {
			VA = args['va'..lang]
				or (lib.isNotEmpty(va) and
					frame:preprocess(lib.trim(
						VAs.character=='Trailblazer' --if we ever do have a voice actor for MC
							and (va:gsub('^.-F: (.-)<r?b?.-M: (.+)$', '%1 or %2'):gsub('%s*<ref.+$', ''))
							or (va:gsub('%s*<ref.+$', ''))
					))
				)
				or '<i>Unknown</i>',
			games = {}
		}
		
		-- Parse the characters from each game
		for _, game in ipairs(game_order) do
			local chars = lib.split(args[game .. lang] or '', ';', {removeEmpty = true})
			if #chars>0 then
				table.insert(VAs[lang].games, game)
				VAs[lang][game] = VAs[lang][game] or mw.html.create()
				for i, ch in ipairs(chars) do
					if i > 1 and #chars > 2 then VAs[lang][game]:wikitext(', ') end
					if i > 1 and i==#chars then VAs[lang][game]:wikitext(' and ') end
					local characterName, note = ch:match('(.+)\\(.+)')
					VAs[lang][game]:wikitext(string.format(iw_links[game], mw.uri.encode(characterName or ch, 'WIKI'), characterName or ch))
					if (lib.isNotEmpty(note)) then
						VAs[lang][game]:wikitext(" ''(", note, ")''")
					end
				end
				if games_dict[game] ~= nil then
					VAs[lang][game]:wikitext(' in '):tag('i'):wikitext(games_dict[game])
				end
			end
		end
		
		if #VAs[lang].games>0 then
			local li = out:tag('li')
			li:wikitext(VAs.character, ' shares the same ', lang_dict[lang], ' voice actor, ', VAs[lang].VA, ', with')
			if #VAs[lang].games==1 then
				li
					:wikitext(' ')
					:node(VAs[lang][VAs[lang].games[1]])
					:wikitext('.')
			else
				li:wikitext(':')
				local liul = li:tag('ul')
				-- Render the list
				for i, game in ipairs(game_order) do
					if VAs[lang][game] then liul:tag('li'):node(VAs[lang][game]) end
				end
			end
		end
	end

    return out
end

return p