2023年政策修订增补工作正在进行中,欢迎参与!
  • Moegirl.ICU:萌娘百科流亡社群 581077156(QQ),欢迎对萌娘百科运营感到失望的编辑者加入
  • Moegirl.ICU:账号认领正在试运行,有意者请参照账号认领流程

Module:Akopbasics/genwikitext

萌娘百科,万物皆可萌的百科全书!转载请标注来源页面的网页链接,并声明引自萌娘百科。内容不可商用。
跳转到导航 跳转到搜索
-- This module isolate M:Akopbasic's HTML-generating contents. It accepts an data table as input.
-- It should not be called directly – it won't work; it should only be called by M:Akopbaics or M:Akopbasics/canary.
-- Crappy code originally by U:公的驱逐舰 (One-Six) of Moegirlpedia. Released under CC BY 4.0.

-- update: I shall claim this release as R1.2.0! It's the second merge from the /canary branch.
-- As /canary contains no work from other editors, 
-- this particular version (oldid=5743831) should be safely released under CC BY 4.0 again.
-- Thank you to everyone who kept this module alive through 2021.

-- Gotta praise the Crocc. 
--[[
	Input requirement. The input datatable d must contain:
		name
		dataName
		rarity = int
		placementTag
		radarPPS = preproccessed {{雷达图}}
		
	It may (and likely should) contain:
		categoryArray
		enName
		illustrator
		spIllustrator
		cv
		spcv
		tachieArray = { { label = string, file = string(filename) }, ... }
		sabunArray = { { string(filename), ... }, ... }
		otherTachie = { string(filename), ... }
		faction 
		factionImgPath = preprocessed image path
		data = { 
			maxHealth,
			attack,
			defense,
			artsResistance,
			redeploy,
			cost,
			block,
			attackInterval
		}
		profession
		subProfession
		rangeArray = { { label, rangeString }, ... }
		tags
		characteristic
		talent
		isRogueOnly = boolean
		wasRogueOnly = boolean
		rogueEvents
		skillArray = {
			useSwitch = boolean,
			useItem = boolean,
			switchPPS = preprocessed {{明日方舟技能条|#style}}{{明日方舟技能条|#skill*#*}},
			{ icon, skillname, activation, skillPoint, description, masterTabsPPS = preprocessed, tabbed M:明日方舟材料) }, ...
		}
		baseSkillArray = { { icon, description }, ... }
		orderedPotentialBuffArray = { { indexName, data } ... } -- see ./.. for accepted inputs
		potentialBuffArray = { indexName=data, ... } 
		operatorModule
		altOpOverride
]]--

local p = {}

local getArgs = require ( 'Module:Arguments' ).getArgs
local akrange = require ( 'Module:Akrange' )
local akMatData = require ( 'Module:明日方舟材料' )._skill
local wrapperArray = { 'Template:沙盒' }

-- F: is string empty?
local function isEmpty( s )
	return (s == nil or s == '')
end
local function getArgFromAlias ( args, argsAliasArray, defaultReturn )
	for i = 1, #argsAliasArray do
		if ( args[argsAliasArray[i]] ~= nil ) then
			return args[argsAliasArray[i]]
		end
	end
	return defaultReturn
end

--[[local function textColorPreprocess ( s )
	if isEmpty( s ) then return s end
	return s:gsub('%<%/text%>','</span>'):gsub('%<trusttext%>','<span class=trusttext>'):gsub('%<(text)%>','<span style=color:')
end--]]

-- F: generate div.akopbasics.
function p.genOpComplex ( frame, d )
	local outputString = '<div class="akopbasics" style="max-width: min(1150px, calc(100% - 300px));text-size-adjust: none;-webkit-text-size-adjust: none;-moz-text-size-adjust: none;"><div class="aoc-scroll-wrapper><div class="ak-operator-complex">'
	-- START aoc-main-tabs-container
	outputString = outputString
		.. '<div class="aoc-main-tabs-container" style="position:static;">'
		.. '<div class="Tabs" data-label-side="top" data-label-color-side-reverse="yes" data-divider-size="0" data-default-tab="1"  data-label-color="#EEE" data-text-border-color="transparent" data-text-padding="0" data-label-background-color="#444" data-text-background-color="transparent">'
	local i = 1
	while d.tachieArray[i] ~= nil do
		outputString = outputString .. '<div class="Tab"><div class="TabLabelText aoc-e-lvl-label">' .. d.tachieArray[i].label ..'</div><div class="TabContentText">[[File:'..d.tachieArray[i].file ..'|x700px]]</div></div>'
		i = i + 1
	end
	i = 1
	while d.sabunArray[i] ~= nil do -- TODO: d.sabunArray[i][1] throws nil error, so d.sabunArray[1] DNE
		outputString = outputString
			.. '<div class="Tab"><div class="TabLabelText">表情差分'..( i ~= 1 and tostring(i) or '' )..'</div><div class="TabContentText sabun-tabs">'
			.. '<div class="Tabs" data-label-side="top" data-label-color-side-reverse="yes" data-divider-size="0" data-default-tab="1" data-label-color="#DDD" data-text-border-color="transparent" data-text-padding="0" data-label-background-color="#555" data-text-background-color="transparent">'
		for j = 1, #d.sabunArray[i] do
			outputString = outputString .. '<div class="Tab"><div class="TabLabelText">#'..j..'</div><div class="TabContentText">[[File:'..d.sabunArray[i][j]..'|x666px]]</div></div>'
		end
		outputString = outputString .. '</div></div></div>'
		i = i + 1
	end
	if (#d.otherTachie ~= 0) then
		outputString = outputString
			.. '<div class="Tab"><div class="TabLabelText">其他立绘</div><div class="TabContentText sabun-tabs">'
			.. '<div class="Tabs" data-label-side="top" data-label-color-side-reverse="yes" data-divider-size="0" data-default-tab="1" data-label-color="#DDD" data-text-border-color="transparent" data-text-padding="0" data-label-background-color="#555" data-text-background-color="transparent">'
		for i = 1, #d.otherTachie do
			outputString = outputString .. '<div class="Tab"><div class="TabLabelText">#'..i..'</div><div class="TabContentText">[[File:'..d.otherTachie[i]..'|x532px]]</div></div>'
		end
		outputString = outputString .. '</div></div></div>'
    end
	outputString = outputString .. '</div></div>'
	-- END aoc-main-tabs-container
	-- START aoc-faction-logo
	outputString = outputString
		.. '<div class="aoc-faction-logo aoc-noselect">'
		.. '<img src="' .. d.factionImgPath .. '" /><div style="display:none !important;">[[File:Aklogo_'..(d.faction or '罗德岛')..'.png|link=]]</div>'
		.. '</div>'
	-- END aoc-faction-logo
	-- START aoc-left-bottom-box
	outputString = outputString .. '<div class="aoc-left-bottom-box">'
	-- START aoc-data
	outputString = outputString .. '<div class="aoc-data aoc-fullwidth-only" style="width:-moz-fit-content;width:fit-content;">'
	local dataString = '' 
	dataString = dataString
		..'<div>生命上限</div><div>'..(d.data.maxHealth
			and( d.data.maxHealth .. ( d.potentialBuffArray["生命"] and ( ' <span class=orangetext title="潜能加成">('..d.potentialBuffArray["生命"]..')</span>' ) or '') )
			or  '暂无数据')
		..'</div><div>攻击</div><div>'..(d.data.attack
			and ( d.data.attack .. ( d.potentialBuffArray["攻击"] and ( ' <span class=orangetext title="潜能加成">('..d.potentialBuffArray["攻击"]..')</span>' ) or '') )
			or  '暂无数据')
		..'</div><div>防御</div><div>'..(d.data.defense
   			and ( d.data.defense .. ( d.potentialBuffArray["防御"] and ( ' <span class=orangetext title="潜能加成">('..d.potentialBuffArray["防御"]..')</span>' ) or '') )
   			or  '暂无数据')
   		..'</div><div>法术抗性</div><div>'..(d.data.artsResistance
   			and ( d.data.artsResistance .. ( d.potentialBuffArray["法抗"] and ( ' <span class=orangetext title="潜能加成">('..d.potentialBuffArray["法抗"]..')</span>' ) or '') )
   			or  '暂无数据')
   		..'</div>'
   		..'<div>再部署</div><div>'..(d.data.redeploy
   			and ( d.data.redeploy .. ( d.potentialBuffArray["再部署"] and ( ' <span class=orangetext title="潜能加成">('..d.potentialBuffArray["再部署"]..'秒)</span>' ) or '') )
   			or  '暂无数据')
   		..'</div><div>部署费用</div><div>'..(d.data.cost
   			and ( d.data.cost .. ( d.potentialBuffArray["费用"] and ( ' <span class=orangetext title="潜能加成">('..d.potentialBuffArray["费用"]..')</span>' ) or '') )
   			or  '暂无数据')
   		..'</div><div>阻挡数</div><div>'..(d.data.block
   			and ( d.data.block .. ( d.potentialBuffArray["阻挡"] and ( ' <span class=orangetext title="潜能加成">('..d.potentialBuffArray["阻挡"]..')</span>' ) or '') )
   			or  '暂无数据')
   		..'</div><div>攻击速度</div><div>'..(d.data.attackInterval
   			and ( d.data.attackInterval .. ( d.potentialBuffArray["攻速"] and ( ' <span class=orangetext title="潜能加成">('..d.potentialBuffArray["攻速"]..')</span>' ) or '') )
   			or  '暂无数据')
   		..'</div>'
	outputString = outputString .. dataString .. '</div>'
	-- END aoc-data
	-- START aoc-names
	outputString = outputString
		.. '<div class="aoc-names">'
		.. '<div class="aoc-whitestyles aoc-stars">' .. string.rep( '<span style="transform:rotate(16deg);display:inline-block;">★</span>', d.rarity ) .. '</div>'
		.. '<div class="aoc-whitestyles aoc-name-en">' .. ( d.enName or '' ) .. '</div>'
		.. '<div class="aoc-whitestyles aoc-name-zh">'..d.name..'</div>'
		-- illustrator data
		.. '<div class="aoc-artist">画师:'
		if d.spIllustrator ~= nil then
			outputString = outputString .. d.spIllustrator
		else
			local i = 1
			while not isEmpty ( d.illustrator[i] ) do
				outputString = outputString 
					.. (i > 1 and ' / ' or '' ) 
					.. ( d.illustrator[i]["nolink"]
						and d.illustrator[i][1]
						or ( '[[' .. d.illustrator[i][1] .. (d.illustrator[i][3] and ('|'..d.illustrator[i][3]) or '') .. ']]' ) 
					)
					.. ( isEmpty( d.illustrator[i][2] ) and '' or ('<sup>'..d.illustrator[i][2]..'</sup>') )
				i = i + 1
			end
		end
		-- cv data
	outputString = outputString .. '</div><div class="aoc-cv">配音:'
		if d.spcv ~= nil then
			outputString = outputString .. d.spcv
		else
			local i = 1
			while not isEmpty ( d.cv[i] ) do
				outputString = outputString
					.. (i > 1 and ' / ' or '' ) 
					.. ( d.cv[i]["nolink"]
						and d.cv[i][1]
						or ( '[[' .. d.cv[i][1] .. (d.cv[i][3] and ('|'..d.cv[i][3]) or '') .. ']]' ) 
					)
					.. ( isEmpty( d.cv[i][2] ) and '' or ('<sup>'..d.cv[i][2]..'</sup>') )
				i = i + 1
			end
		end
	outputString = outputString	.. '</div>' .. '</div>'
	-- END aoc-names
	-- START aoc-prl
	outputString = outputString
		.. '<div class="aoc-prl">'
		.. '<div class="aoc-professions">'
		.. '<div class="aoc-profession aoc-noselect">'
		-- if no profession, load a placeholder
		.. ( d.profession and ('[[File:明日方舟职业 '..d.profession..'.png|50px|'..d.profession..'|alt='..d.profession..'图标|link=]]')
			or ( '<div role="img" alt="未知" style="'
				.. 'font-weight:bold;font-size:3em;'
				.. 'background:linear-gradient(to bottom, #FFF, #888);'
				.. 'background-clip:text;-webkit-background-clip:text;'
				.. 'color:transparent;height:50px;'
				.. 'text-shadow: none;line-height: 1.1em;">'
				.. '?</div>' 
			)
		)
		.. '</div><div class="aoc-subprofession">' 
		-- if no sub-profession, load a placeholder
		.. ( d.subProfession and ( '[[File:明日方舟职业_分支_'..d.subProfession..'.png|40px|link=|alt='..d.subProfession..'图标]]'..'<span style="vertical-align:middle;">'..d.subProfession..'</span>' )
			or ( '<div role="img" alt="未知" class="aoc-noselect" style="display:inline-block;font-weight:bold;font-size:1.5em;width:20px;height:20px;text-shadow: none;>?</div>无分支数据' )
		)
		.. '</div></div>'
		.. '<div class="aoc-range" >'
		-- if more than one range datum, use and build tabs
	if #d.rangeArray > 1 then
		i = 1
		outputString = outputString .. '<div class="Tabs" data-label-side="top" data-label-color-side-reverse="yes" data-divider-size="0" data-default-tab="1" data-label-border-color="transparent" data-label-color="#EEE" data-text-border-color="transparent" data-text-padding="0" data-label-background-color="#444" data-text-background-color="transparent">'
		while i <= #d.rangeArray do
			outputString = outputString .. '<div class="Tab"><div class="TabLabelText aoc-e-lvl-label">'..d.rangeArray[i].label..'</div><div class="TabContentText">'..akrange._main( { d.rangeArray[i].rangeString, color="#FFF" } )..'</div></div>'
			i = i + 1
		end
		outputString = outputString .. '</div>'
		-- if no range data, load a placeholder
	elseif isEmpty( d.rangeArray[1].rangeString ) then
		outputString = outputString .. '<div role="img" alt="未知" class="aoc-noselect" style="font-weight:bold;font-size:3em;height:1em;text-shadow: none; line-height: .8em;">?</div>'
		-- else there is only one: build directly
	else
		outputString = outputString .. akrange._main( { d.rangeArray[1].rangeString, color="#FFF" } )
	end
	outputString = outputString
		.. '<div class="aoc-prl-labels">攻击范围</div>'
		.. '</div>'
		.. '<div class="aoc-location-label">'..(d.placementTag or '')..'</div>'
		.. '<div class="aoc-other-labels">'..(d.tags or '')..'</div>'
		.. '</div>'
	-- END aoc-prl
	outputString = outputString .. '</div>'
	-- END aoc-left-bottom-box
	-- START aoc-radar-container
	outputString = outputString
		.. '<div class="aoc-radar-container aoc-fullwidth-only">'
		.. d.radarPPS
		.. '</div>'
	-- END aoc-radar-container
	-- START aoc-bottom-right-box
	outputString = outputString .. '<div class="aoc-bottomright-box aoc-fullwidth-only">'
	local showPotentialBox = not ( d.orderedPotentialBuffArray == nil or ( d.isRouge and not d.wasRouge ) or d.noPotential )
	local potentialString = ''
	if showPotentialBox then
		potentialString = '<div class="aoc-comp-title">潜能提升</div>'
		for i = 1, 5 do
			potentialString = potentialString
			.. '<div class="aoc-potential-item' .. ( d.orderedPotentialBuffArray[i][1] and '' or ' aoc-pot-item-na' ) .. '">'
			.. '<div>[[File:明日方舟潜能_' .. i .. '.png|25px|link=|潜能'..i..']]</div><div'
			.. ( d.orderedPotentialBuffArray[i][1]
				and ('>'..d.orderedPotentialBuffArray[i][1]..'<br /><span class=orangetext>'..d.orderedPotentialBuffArray[i][2]..(d.orderedPotentialBuffArray[i][1]=='再部署' and '秒' or ''))..'</span>'
				or ' style="padding-top: calc(9.5px - 0.5em);">N/A' )
			.. '</div></div>'
		end
	end
	local charaString = '<div class="aoc-comp-title">特性</div><div>' .. ( d.characteristic or "暂无数据" ) .. '</div>'
	local talentString = '<div class="aoc-comp-title">天赋</div><div>'.. ( d.talent or "暂无数据" ) .. '</div>'
	outputString = outputString
		.. ( showPotentialBox and ( '<div class="aoc-potential">' .. potentialString .. '</div>' ) or '' )
		.. '<div class="aoc-characteristic">' .. charaString
		.. '</div><div class="aoc-talent">' .. talentString.. '</div></div>'
	-- END aoc-bottomright-box
	-- END main AOC div
	outputString = outputString .. '</div></div>'
	-- START mobile-specific div
	outputString = outputString .. '<div class="aoc-mobile-alt">'
		.. '<div class="aoc-data">' .. dataString .. '</div>'
		.. '<div class="aoc-radar-container"><div class="aoc-radar-outer" style="width:-moz-fit-content;width:fit-content;">' .. d.radarPPS .. '</div></div>'
		.. charaString .. talentString
		.. '</div>'
	-- END mobile-specific div
	
	-- bottom table
	outputString = outputString .. '<table class="wikitable" style="background:#f9f9f9;">'
	if d.isRogueOnly then
		outputString = outputString
			.. '<tr><th colspan="2">Rogue-like Only<br />'
			.. '<span style="font-weight:normal; font-size:.8em;">该干员' .. ( d.wasRogueOnly and '曾' or '' ) .. '仅在' .. ( d.rogueEvents or '部分集成战略活动' ) .. '中可用'
			.. ( d.skillArray[1] ~= nil and ',其可用技能等级固定为<span style="color:blue;">7级</span>(进阶前)或<span style="color:blue;">专精三</span>(进阶后)' or '' ) .. '。</span></th></tr>'
	end
	if d.skillArray[1] ~= nil then
		local skillString = '<tr><th colspan=2>技能'
			.. ( d.skillArray.useSwitch and '<br /><span style="font-weight:normal;font-size:.8em;">默认显示技能等级<span style="color:blue;">7级</span>时的数据。用下方的按钮可以选择不同的技能等级。</span>' or '' )
			.. '</th></tr>'
			.. ( d.skillArray.useSwitch and ( '<tr><th colspan=2>'..d.skillArray.switchPPS..'</th></tr>' ) or '' )
			.. '<tr><td colspan=2><div class="aoc-skill-container">'
		for i = 1, #d.skillArray do
			skillString = skillString
				.. '<div class="aoc-skill"><div class="aoc-skill-img-name">'
				.. ( d.skillArray[i].icon and ( '[[File:' .. d.skillArray[i].icon .. '|80px|技能图标-'..(d.skillArray[i].skillName or ('技能'..i))..'|link=]]' ) or '' )
				.. '<div class="aoc-skill-name" style="width:-moz-fit-content;width:fit-content;">' .. ( d.skillArray[i].skillName or '' ) .. '</div>'
				.. '</div><div class="aoc-skill-activ-sp"><div class="aoc-skill-activation">'
				.. ( d.skillArray[i].activation or '' )
				.. '</div><div class="aoc-skill-sp">'
				.. ( d.skillArray[i].skillPoint or '' )
				.. '</div></div><div class="aoc-skill-desc">'
				.. ( d.skillArray[i].description or '' )
				.. '</div>'
				.. ( d.skillArray.useItem and d.skillArray[i].masterTabsPPS or '' ) -- aoc-skill-masterTabs
				.. '</div>'
		end
		skillString = skillString .. '</td></tr>'
		if d.skillArray.useItem then
			skillString = skillString
				.. "<tr><th colspan=2>需要材料</th></tr>"
				.. "<tr><td colspan=2>"
				.. '技能等级1→2:' .. akMatData( frame, { d.dataName, 'v1' } ) .. '<br/>'
				.. '技能等级2→3:' .. akMatData( frame, { d.dataName, 'v2' } ) .. '<br/>'
				.. '技能等级3→4:' .. akMatData( frame, { d.dataName, 'v3' } ) .. '</td></tr>'
				.. '<tr><td style="width:50px;text-align:center">[[File:精英1+ 图标.png|50px|alt=精英一图标|link=]]</td><td> 晋升材料:'.. akMatData( frame, { d.dataName, 'v10' } ) .. '</td></tr>'
				.. '<tr><td colspan=2>'
				.. '技能等级4→5:' .. akMatData( frame, { d.dataName, 'v4' } ) .. '<br/>'
				.. '技能等级5→6:' .. akMatData( frame, { d.dataName, 'v5' } ) .. '<br/>'
				.. '技能等级6→7:' .. akMatData( frame, { d.dataName, 'v6' } ) .. '</td></tr>'
				.. '<tr><td style="width:50px;text-align:center">[[File:精英2 图标.png|50px|alt=精英二图标|link=]]</td><td> '..( d.rarity >= 4 and '晋升材料:'..akMatData( frame, { d.dataName, 'v20' } ) or '该干员尚未得到精英二阶段的晋升。' )..'</td></tr>'
				if not isEmpty(d.altOpOverride)  then 
					skillString = skillString .. "<tr><th colspan=2>异格任务</th></tr>"
					skillString = skillString ..'<tr><td>解锁条件</td><td>拥有干员[[明日方舟:'.. d.altOpOverride .. '|'..d.altOpOverride..']]</td></tr>'
					skillString = skillString .. '<tr><td style="width:80px;">提升至精英阶段1等级1</td><td>'.. akMatData( frame, { d.dataName, 'v11' } ) .. '<br/></tr>'
                                        if #d.name > #d.altOpOverride then
						skillString = skillString .. '<tr><td style="width:80px;">提升至精英阶段2等级1</td><td>'.. akMatData( frame, { d.dataName, 'v21' } ) .. '</td></tr>'
					elseif d.rarity == 3 then
						skillString = skillString .. '<tr><td style="width:80px;">提升至精英阶段1等级55</td><td>'.. akMatData( frame, { d.dataName, 'v21' } ) .. '</td></tr>'
					elseif d.rarity == 4 then
						skillString = skillString .. '<tr><td style="width:80px;">提升至精英阶段1等级60</td><td>'.. akMatData( frame, { d.dataName, 'v21' } ) .. '</td></tr>'
					elseif d.rarity == 5 then
						skillString = skillString .. '<tr><td style="width:80px;">提升至精英阶段1等级70</td><td>'.. akMatData( frame, { d.dataName, 'v21' } ) .. '</td></tr>'
					elseif d.rarity == 6 then
						skillString = skillString .. '<tr><td style="width:80px;">提升至精英阶段1等级80</td><td>'.. akMatData( frame, { d.dataName, 'v21' } ) .. '</td></tr>'
				end
			end
		end
		outputString = outputString .. skillString
	else
		outputString = outputString .. '<tr><th colspan=2 style="text-align:center;font-style:italic;">该干员暂无技能。</th></tr>'
	end
	if d.baseSkillArray[1] ~= nil then
		local baseSkillString = '<tr><th colspan=2>后勤</th></tr>'
		for i = 1, #d.baseSkillArray do
			baseSkillString = baseSkillString .. '<tr><td style="width:50px;background:gray;text-align:center">'..( d.baseSkillArray[i].icon and ('[[File:'..d.baseSkillArray[i].icon..'|30px|后勤技能'..i..'图标|link=]]') or '' )..'</td><td>'..d.baseSkillArray[i].description..'</td></tr>'
		end
		outputString = outputString .. baseSkillString
	else	
		outputString = outputString .. '<tr><th colspan=2 style="text-align:center;font-style:italic;">该干员暂无后勤技能。</th></tr>'
	end
	-- END bottom table
	outputString = outputString .. '</table></div>'
	i = 1
	while d.categoryArray and d.categoryArray[i] do
		outputString = outputString .. '[[Category:'..d.categoryArray[i]..']]'
		i = i + 1
	end
	return outputString
end

return p