本站文本内容除另有声明外,转载时均必须注明出处,并遵守CC BY-NC-SA 3.0协议。(转载须知
本站是中文Minecraft Wiki的镜像站,与Mojang Studios、Weird Gloop没有从属关系。(免责声明

全站通知:

模块:Spawn table

来自我的世界地下城WIKI_BWIKI_哔哩哔哩
跳到导航 跳到搜索

此模块用于实现{{Spawn table}}

local p = {}

local i18n = {
	processArgsModule = 'Module:ProcessArgs',
	entityLinkTemplate = 'EntityLink',
	editionsTemplate = 'Template:Editions',
	mobColumn = '生物',
	chanceColumn = mw.getCurrentFrame():expandTemplate{title='Tooltip', args={'生成概率', '相对于所属族群中其他生成项的概率'}},
	groupSizeColumn = mw.getCurrentFrame():expandTemplate{title='Tooltip', args={'每群数量', '每次尝试生成生物的数量'}},
	chargeColumn = mw.getCurrentFrame():expandTemplate{title='Tooltip', args={'生成势', '生物提高的生成势'}},
	budgetColumn = mw.getCurrentFrame():expandTemplate{title='Tooltip', args={'最大生成势', '允许生物生成的最大生成势'}},
	spawnCostNote = '当生成有最大生成势的生物时,生成系统会使用已存在的生物计算生成点的生成势。如果生成点生成势大于最大生成势,则此次生成失败。详见[[生成#生成势]]。'
}

local spawnData = {}  -- contains mob spawn info

local groupArgs = {
	['monster'] = '怪物',
	['creature'] = '动物',
	['ambient'] = '环境生物',
	['axolotl'] = '美西螈',
	['underground'] = '地下水生生物',
	['watercreature'] = '水生生物',
	['waterambient'] = '水下环境生物',
	['misc'] = '其他'
}

local hasNotes = false
local hasSpawnCost = false

-- parses input arguments into spawnData table
local function parseInput(args)
	for argName in pairs(groupArgs) do
		local groupArg = args[argName]
		
		if groupArg then
			local currentGroup = {}
			local totalWeight = 0
			currentGroup.mobs = {}
			
			groupArg = groupArg .. '\n'  -- allow last line to be matched like the rest
			
			-- parse input of group parameter
			for line in mw.ustring.gmatch(groupArg, '[^\r\n]+[\r\n]') do  -- split on newline
				local parsedLine = {}
				for key, value in mw.ustring.gmatch(line, '([%a]+)%s*=%s*(.-)%s*[,\r\n]') do
					if value ~= '' then
						parsedLine[key:lower()] = value
					end
				end
				
				parsedLine.note = mw.ustring.match(line, 'note=%s*(.-)%s*[\r\n]')
				
				local currentMob = {}
				
				-- convert weight to number; becomes nil if conversion fails
				if parsedLine.weight then
					weightNum = tonumber(parsedLine.weight)
					-- if converted to number successfully
					if weightNum then
						currentMob.weight = weightNum
						totalWeight = totalWeight + weightNum
					end
				end
				
				if parsedLine.size then
					currentMob.size = parsedLine.size
				end

				if parsedLine.charge then
					hasSpawnCost = true
					currentMob.charge = parsedLine.charge
				end

				if parsedLine.budget then
					hasSpawnCost = true
					currentMob.budget = parsedLine.budget
				end
				
				if parsedLine.note then
					hasNotes = true
					currentMob.note = parsedLine.note
				end
				
				if parsedLine.notename then
					currentMob.notename = parsedLine.notename
				end
				
				if parsedLine.mob then
					currentMob.mob = parsedLine.mob
					table.insert(currentGroup.mobs, currentMob)
				end
			end
			currentGroup.totalWeight = totalWeight
			spawnData[argName] = currentGroup
		end
	end
end


-- takes root <table> html object and adds table body using info in spawnData 
local function addTableBody(tableRoot, numberOfColumns)
	local frame = mw.getCurrentFrame()
	local groupNumber = 1
	
	for groupArg, groupTable in pairs(spawnData) do
		local groupHeader = mw.html.create('tr')
		groupHeader:tag('th')
			:attr('colspan', numberOfColumns)
			:wikitext(groupArgs[groupArg])
			
		tableRoot:node(groupHeader)
		
		for _, mobData in ipairs(groupTable.mobs) do
			local tableRow = mw.html.create('tr')
			
			local mobCellText = frame:expandTemplate{title=i18n.entityLinkTemplate, args={mobData.mob}}
			
			if mobData.note then 
				mobCellText = mobCellText .. frame:extensionTag{name='ref', content=mobData.note, args={name=mobData.mob:lower(), group='生成'}}
			elseif mobData.notename then
				mobCellText = mobCellText .. frame:extensionTag{name='ref', args={name=mobData.notename:lower(), group='生成'}}
			end
			
			tableRow:tag('th')
				:css('text-align', 'left')
				:css('font-weight', 'normal')
				:wikitext(mobCellText)
			
			-- Simplify weights for pools with single entries to avoid confusion from e.g. 10/10 and 25/25
			local weightText = '1'
			if mobData.weight ~= groupTable.totalWeight then
				weightText = '<sup>' .. mobData.weight .. '</sup>&frasl;<sub>' .. groupTable.totalWeight .. '</sub>'
		    end
			
			tableRow:tag('td')
				:css('text-align', 'center')
				:wikitext(weightText)
			
			tableRow:tag('td')
				:css('text-align', 'center')
				:wikitext(mobData.size)

			if hasSpawnCost then
				tableRow:tag('td')
					:css('text-align', 'center')
					:wikitext(mobData.charge)
				tableRow:tag('td')
					:css('text-align', 'center')
					:wikitext(mobData.budget)
			end

			tableRoot:node(tableRow)
		end
	end
end


-- function called from template
function p.mobSpawnTable(frame)
	local args = frame
	if frame == mw.getCurrentFrame() then
		args = require(i18n.processArgsModule).merge( true )
	else
		frame = mw.getCurrentFrame()
	end
	
	parseInput(args)

	local columns = {i18n.mobColumn, i18n.chanceColumn, i18n.groupSizeColumn}
	
	local tableRoot = mw.html.create('table'):attr('class', 'wikitable')
	
	local titleStr = args.title

	if hasSpawnCost then
		hasNotes = true
		table.insert( columns, i18n.chargeColumn .. frame:extensionTag{name='ref', content=i18n.spawnCostNote, args={name='spawn-cost', group='生成'}} )
		table.insert( columns, i18n.budgetColumn .. frame:extensionTag{name='ref', args={name='spawn-cost', group='生成'}} )
	end
	
	if args.edition then
		local editionStr = frame:expandTemplate{title=i18n.editionsTemplate, args={args.edition}}
		if titleStr then
			titleStr = titleStr .. '(' .. editionStr .. ')'
		else
			titleStr = editionStr
		end
	end
	
	if titleStr then
		tableRoot
			:tag('caption')
				:wikitext(titleStr)
	end
	
	local colHeaders = mw.html.create('tr')
	
	for _, value in pairs(columns) do
		colHeaders:tag('th'):wikitext(value)
	end
	
	tableRoot:node(colHeaders)
	
	addTableBody(tableRoot, #columns)
	
	local outputWikitext = tostring(tableRoot)

	if hasNotes then
		outputWikitext = outputWikitext .. '\n\n' .. frame:extensionTag{name='references', args={group='生成'}}
	end
	
	return outputWikitext
end

return p