Module:Neighbor Journey

Module documentation

This module implements {{Neighbor Journey}}.

local p = {}

local Arguments = require('Module:Arguments')

-- Converts a group title into its parameter key.
-- Example:
-- "Neighbor Events" -> "neighbor_events"
-- "Starsea Voyages" -> "starsea_voyages"
local function getKey(group)
	group = mw.ustring.lower(mw.text.trim(group))
	group = mw.ustring.gsub(group, "%s+", "_")
	return group
end

-- Splits a reward string into:
-- quantity // title // dough
local function parseReward(value)
	local parts = mw.text.split(value, "//", true)

	return {
		quantity = mw.text.trim(parts[1] or ""),
		title = mw.text.trim(parts[2] or ""),
		dough = mw.text.trim(parts[3] or "")
	}
end

-- Gets all numbered rewards for a group.
-- Stops at the first missing number.
local function getRewards(args, key)
	local rewards = {}
	local i = 1

	while args[key .. "_" .. i] do
		local value = mw.text.trim(args[key .. "_" .. i])

		if value ~= "" then
			table.insert(rewards, parseReward(value))
		end

		i = i + 1
	end

	return rewards
end

function p.main(frame)
	local args = Arguments.getArgs(frame, {
		wrapper = "Template:Neighbor Journey"
	})

	return p._main(args, frame)
end

function p._main(args, frame)
	local neighbor = args.neighbor or ""
	local groupsString = args.groups or ""

	if neighbor == "" then
		return ""
	end

	-- Split groups on semicolons.
	local groups = mw.text.split(groupsString, ";", true)

	-- Remove empty groups.
	local validGroups = {}

	for _, group in ipairs(groups) do
		group = mw.text.trim(group)

		if group ~= "" then
			table.insert(validGroups, group)
		end
	end

	-- Start table.
	local output = {
		"{| class=\"wikitable wikitable--stripe\"",
		"! width=155px | Node !! Quantity !! Title !! {{Item|Dough|notext=1}}"
	}

	----------------------------------------------------------------
	-- Meet
	----------------------------------------------------------------

	table.insert(output, "|-")
	table.insert(output,
		"! rowspan=\"1\" | {{Icon/Journey|Meet}} Meet<br>" ..
		"<small>''Meet " .. neighbor .. " for the very first time''</small>"
	)
	table.insert(output,
		"| 1 || '''A Chance Encounter''' || 30"
	)

	----------------------------------------------------------------
	-- Groups
	----------------------------------------------------------------

	local hasGroup = false

	for _, group in ipairs(validGroups) do
		local key = getKey(group)
		local description = args[key .. "_desc"] or ""
		local rewards = getRewards(args, key)

		-- Don't output groups that have no rewards.
		if #rewards > 0 then

			-- Add a separator after Meet / between groups.
			table.insert(output, "|-")
			table.insert(output,
				'! colspan="4" style="height:10px; min-height:5px; padding:0; border:0;" |'
			)

			hasGroup = true

			-- Replace {name} with the neighbor's name.
			description = mw.text.trim(description)
			description = mw.ustring.gsub(description, "{name}", neighbor)

			-- First row of the group.
			table.insert(output, "|-")

			local nodeCell =
				"! rowspan=\"" .. #rewards .. "\" | " ..
				"{{Icon/Journey|" .. group .. "}} " .. group

			if description ~= "" then
				nodeCell = nodeCell ..
					"<br><small>''" .. description .. "''</small>"
			end

			table.insert(output, nodeCell)

			-- First reward.
			local first = rewards[1]

			table.insert(output,
				"| " .. first.quantity ..
				" || '''" .. first.title .. "''' || " ..
				first.dough
			)

			-- Remaining rewards.
			for i = 2, #rewards do
				local reward = rewards[i]

				table.insert(output, "|-")
				table.insert(output,
					"| " .. reward.quantity ..
					" || '''" .. reward.title .. "''' || " ..
					reward.dough
				)
			end
		end
	end

	-- End table.
	table.insert(output, "|}")

	-- Process generated wikitext so that templates
	-- such as {{Icon/Journey}} and {{Item}} are evaluated.
	local result = table.concat(output, "\n")

	return frame:preprocess(result)
end

return p