模块:Random world names

来自Terraria Wiki
跳到导航 跳到搜索
亦可参看英文模块:Module:Random world names。那边可能有更完整或更正确的信息。

This module is used to display the table body on World/Name. It uses a seed that changes each second to generate the random examples, hence simply purging the page generates new random examples.

The module has one function to be called, go. It takes a $lang argument that is used for generating the {{gameText}} strings, so it should be set to the wiki's language code (as returned by {{lang|}}). It also takes a $compositions argument, which should be set to a comma-separated list of world name composition IDs. The compositions are defined in the RandomWorldName_Composition group of {{gameText}} (i.e. RandomWorldName_Composition.1 through RandomWorldName_Composition.8). Depending on the language, there may be multiple compositions that are identical, so only the IDs of distinct compositions should be passed to the module function. This avoids duplicate table rows in the output. For example, when using the module in English, it would be sensible to set the parameter to |compositions=1,3,5,6,7,8 because the compositions 2 and 4 are duplicates of 1 and 3, respectively.

Furthermore, the go function takes several arguments for properly displaying the "generic" composition in the left cell: $adjective, $location, and $noun, as replacements for the respective placeholders. The values of these arguments are used for all compositions, but it is possible to overwrite them for specific compositions with arguments of the format <composition>:<adjective/location/noun>. For instance, using |3:adjective=foo in the module invocation sets the adjective placeholder in composition 3 (and only in composition 3) to "foo".

Lastly, the $count argument defines the number of random world names that are generated for each composition. It defaults to 3 if omitted.


local getData = require('Module:GameText').getData
local getText = require('Module:GameText').getText

-- credit: http://richard.warburton.it
-- this version is with trim.
local function explode(div,str) 
	if (div=='') then return false end
	local pos,arr = 0,{}
	-- for each divider found
	for st,sp in function() return string.find(str,div,pos,true) end do
		table.insert(arr,string.sub(str,pos,st-1)) -- Attach chars left of current divider
		pos = sp + 1 -- Jump past current divider
	end
	table.insert(arr, string.sub(str,pos)) -- Attach chars right of last divider
	return arr
end

local function getListOfKeys(key, lang)
	local arr = {}
	for _, v in pairs(getData(key, lang)) do
		arr[#arr+1] = v
	end
	return arr
end


return {

go = function(frame)

	local lang = frame.args['lang']

	-- load lists of all available strings
	local adjectivelist = getListOfKeys('RandomWorldName_Adjective', lang)
	local locationlist = getListOfKeys('RandomWorldName_Location', lang)
	local nounlist = getListOfKeys('RandomWorldName_Noun', lang)

	-- default strings for the generic composition displayed in the left cell
	local arg_adj = frame.args['adjective']
	local arg_loc = frame.args['location']
	local arg_nou = frame.args['noun']

	-- number of random world names to generate for each composition, default to 3.
	local worldcount = frame.args['count'] or 3

	-- init the RNG: seed is based on current date and time and changes every second
	local seed = os.time();
	math.randomseed(seed)

	-- invisible info string
	local output = '<span style="display:none;">Random world names seed: ' .. seed .. ' (' .. os.date() .. ' UTC)</span>'

	for _, composition in pairs(explode(',', frame.args['compositions'])) do
		-- print a table row for each composition
		output = output .. '<tr><td>'

		-- left cell: generic composition

		-- use the default strings for adjective, location, and noun as defined above,
		-- but overwrite where there is a definition for this specific composition
		-- (e.g. "|3:adjective=...") for the adjective of composition 3
		local x_Adj = frame.args[composition .. ':adjective'] or arg_adj
		local x_Loc = frame.args[composition .. ':location'] or arg_loc
		local x_Nou = frame.args[composition .. ':noun'] or arg_nou
		local replaceArgs = {
			['{Adjective}'] = '<i>&lt;' .. x_Adj .. '&gt;</i>',
			['{Location}'] = '<i>&lt;' .. x_Loc .. '&gt;</i>',
			['{Noun}'] = '<i>&lt;' .. x_Nou .. '&gt;</i>'
		}

		output = output .. getText('RandomWorldName_Composition.' .. composition, lang, replaceArgs)
		output = output .. '</td><td><ul>'

		-- right cell: list of some random examples for the composition

		for _ = 1, worldcount do -- generate a world name the defined number of times
			local worldname = ''

			-- keep generating random world names until one is found that is at max 27 chars in length
			-- (this is the same behavior as in-game)
			repeat
				-- select a random adjective, location, and noun
				local arg_adj = adjectivelist[math.random(1, #adjectivelist)]
				local arg_loc = locationlist[math.random(1, #locationlist)]
				local arg_nou = nounlist[math.random(1, #nounlist)]

				if arg_adj and arg_loc and arg_nou then
					-- make world name
					local replaceArgs = {['{Adjective}'] = arg_adj, ['{Location}'] = arg_loc, ['{Noun}'] = arg_nou}
					worldname = getText('RandomWorldName_Composition.' .. composition, lang, replaceArgs)
				end
			until worldname ~= '' and #worldname <= 27

			output = output .. '<li>' .. worldname .. '</li>'
		end

		output = output .. '</ul></td></tr>'
	end

	return output

end

}