Difference between revisions of "Module:Tag Force present responses"
Dinoguy1000 (talk | contribs) (fix grammar if gender is unspecified) |
(Don't know why this isn't working. Just taking shots in the dark now.) |
||
(5 intermediate revisions by the same user not shown) | |||
Line 164: | Line 164: | ||
return difference | return difference | ||
+ | end | ||
+ | |||
+ | -- Render a "trust" effect for displaying | ||
+ | -- (Shows how much the score increases/decreases by. Hover to see what percentage of a heart that equates to.) | ||
+ | -- | ||
+ | -- @param difference number | ||
+ | -- @return {string|number} | ||
+ | local function renderTrustEffect(difference) | ||
+ | local diff = renderEffect(difference) | ||
+ | local heartDiff = renderEffect(difference / 10) .. '%' | ||
+ | |||
+ | return '<abbr title="' .. heartDiff .. ' of a heart">' .. diff .. '</abbr>' | ||
end | end | ||
Line 210: | Line 222: | ||
table.insert(self.responses, response) | table.insert(self.responses, response) | ||
end | end | ||
+ | end | ||
+ | |||
+ | self:setSmwData() | ||
+ | end | ||
+ | |||
+ | -- Store Semantic MediaWiki data | ||
+ | function Character:setSmwData() | ||
+ | for _, response in pairs(self.responses) do | ||
+ | -- Get an array of page names for each of the response's items | ||
+ | local itemLinks = {} | ||
+ | for _, item in pairs(response.items) do | ||
+ | table.insert(itemLinks, getItemLink(item)) | ||
+ | end | ||
+ | |||
+ | -- Create a subobject for the response | ||
+ | mw.smw.subobject({ | ||
+ | 'Owner name = ' .. self.name, | ||
+ | 'Game = ' .. self.game, | ||
+ | 'Description = ' .. response.message, | ||
+ | 'Numeric rating = ' .. response.rating, | ||
+ | 'Has items = ' .. table.concat(itemLinks, '*'), | ||
+ | '+sep=*' | ||
+ | }) | ||
end | end | ||
end | end | ||
Line 215: | Line 250: | ||
-- Get a character's pronoun | -- Get a character's pronoun | ||
-- @return string "he", "she", or "they" | -- @return string "he", "she", or "they" | ||
− | function Character | + | function Character:getPronoun() |
− | + | local map = { ['male'] = 'he', ['female'] = 'she' } | |
− | + | ||
− | return 'they' | + | return map[self.gender] or 'they' |
end | end | ||
-- Get a character's objective pronoun | -- Get a character's objective pronoun | ||
-- @return string "him", "her", or "them" | -- @return string "him", "her", or "them" | ||
− | function Character | + | function Character:getObjectivePronoun() |
− | + | local map = { ['male'] = 'him', ['female'] = 'her' } | |
− | + | ||
− | return 'them' | + | return map[self.gender] or 'them' |
end | end | ||
Line 233: | Line 268: | ||
function Character:renderResponses() | function Character:renderResponses() | ||
local intro = '<p>In <i>[[' .. self.game .. ']]</i>, ' .. (self.name) .. ' has the following responses when the player gives ' .. (self:getObjectivePronoun()) .. ' a present.</p>' | local intro = '<p>In <i>[[' .. self.game .. ']]</i>, ' .. (self.name) .. ' has the following responses when the player gives ' .. (self:getObjectivePronoun()) .. ' a present.</p>' | ||
− | intro = intro .. '<p>The "Trust" column shows how much of a heart the present will increase in the level of trust. ' | + | intro = intro .. '<p>The "Trust" column shows how much of a heart the present will increase in the level of trust by. ' |
intro = intro .. 'The "Card", "Dueling", and "Them" columns show the effect it has on how many more times ' .. (self:getPronoun()) | intro = intro .. 'The "Card", "Dueling", and "Them" columns show the effect it has on how many more times ' .. (self:getPronoun()) | ||
intro = intro .. (self:getPronoun() == 'they' and ' are' or ' is') ..' willing to talk about that topic (maximum 5).</p>' | intro = intro .. (self:getPronoun() == 'they' and ' are' or ' is') ..' willing to talk about that topic (maximum 5).</p>' | ||
− | local chart = mw.html.create('table'):attr('class', 'wikitable') | + | local chart = mw.html.create('table'):attr('class', 'wikitable hlist sortable toggleable-columns-table') |
local theadRow = chart:tag('tr') | local theadRow = chart:tag('tr') | ||
Line 266: | Line 301: | ||
row:tag('td'):wikitext(response and response:renderItemList()) | row:tag('td'):wikitext(response and response:renderItemList()) | ||
row:tag('td'):wikitext(response and response.message) | row:tag('td'):wikitext(response and response.message) | ||
− | row:tag('td'):wikitext( | + | row:tag('td'):wikitext(renderTrustEffect(group.trust[rating])) |
row:tag('td'):wikitext(renderEffect(group.mood[rating])) | row:tag('td'):wikitext(renderEffect(group.mood[rating])) | ||
row:tag('td'):wikitext(renderEffect(group.card[rating])) | row:tag('td'):wikitext(renderEffect(group.card[rating])) | ||
Line 301: | Line 336: | ||
-- @return string | -- @return string | ||
function Response:renderItemList() | function Response:renderItemList() | ||
− | local list = mw.html.create('ul | + | local list = mw.html.create('ul') |
for _, item in pairs(self.items) do | for _, item in pairs(self.items) do |
Latest revision as of 23:12, 3 May 2024
local InputParser = require('Module:Input parser')
-- Object for the character
-- (main object for this module)
--
-- @field pageName string
-- @field name string
-- @field gender string 'male' or 'female' (needed for pronouns, otherwise will use they/them)
-- @field game string
-- @field responses table<Response>
local Character = {
pageName = mw.title.getCurrentTitle().text,
name = nil,
gender = nil,
game = nil,
responses = {}
}
-- Object for a response the character makes
-- (A character should have a response for each group-rating combination)
--
-- @field group string The name of the item group the response is to
-- @field rating number Number between 1 and 5
-- @field message string What the character says when giving this reaction
-- @field items table<string> The items that trigger this response
local Response = {
group = nil,
rating = nil,
message = nil,
items = nil,
}
-- Object for an item group
-- @field name string
-- @field trust table<number> Five numbers showing the effect each rating has on the "trust" score
-- @field mood table<number> Five numbers showing the effect each rating has on the "mood" score
-- @field card table<number> Five numbers showing the effect each rating has on the "card" score
-- @field dueling table<number> Five numbers showing the effect each rating has on the "dueling" score
-- @field them table<number> Five numbers showing the effect each rating has on the "them" score
local Group = {
name = nil,
trust = {},
mood = {},
card = {},
dueling = {},
them = {}
}
-- List of each group
local groups = {
['duel'] = {
name = 'Duel',
trust = { -25, -10, 5, 10, 25 },
mood = { -1.2, 0, 0.8, 1, 1.2 },
card = { 0, 1, 1, 2, 2 },
dueling = { 3, 3, 4, 4, 5 },
them = { 0, 1, 1, 2, 2 }
},
['hobby'] = {
name = 'Hobby',
trust = { -25, -10, 5, 10, 25 },
mood = { -1.2, 0, 0.8, 1, 1.2 },
card = { 3, 3, 4, 4, 5 },
dueling = { 0, 1, 1, 2, 2 },
them = { 0, 1, 1, 2, 2 },
},
['sundry_goods'] = {
name = 'Sundry Goods',
trust = { -25, -10, 5, 10, 25 },
mood = { -1.2, 0, 0.8, 1, 1.2 },
card = { 0, 1, 1, 2, 2 },
dueling = { 0, 1, 1, 2, 2 },
them = { 3, 3, 4, 4, 5 },
},
['food'] = {
name = 'Food',
trust = { -0, 25, 50, 75, 100 },
mood = { -1.2, 0, 0, 0, 0 },
card = { -1, -1, 0, 0, 0 },
dueling = { -1, -1, 0, 0, 0 },
them = { -1, -1, 0, 0, 0 },
},
['figures'] = {
name = 'Figures',
trust = { -50, -25, 0, 5, 10 },
mood = { 0.5, 1, 1.5, 2, 2.5 },
card = { -2, -1, 0, 0, 0 },
dueling = { -2, -1, 0, 0, 0 },
them = { -2, -1, 0, 0, 0 },
messageGroup = 'hobby'
}
}
-- Normalize input
--
-- @param table args
-- @return table
local function normalizeArgs(args)
local normalizedArgs = {}
-- If a parameter just contains whitespace, ignore it
for param, value in pairs(args or {}) do
if (value and mw.text.trim(value) ~= '') then
normalizedArgs[param] = value
end
end
return normalizedArgs
end
-- Get the page name for a given item
--
-- @param name string The name of the item
-- @return string
local function getItemLink(name)
-- Map names to page names for items where the two are different
local map = {
['Amplifier'] = 'Amplifier (Tag Force item)',
['Atlas Rising'] = 'Atlas Rising (Tag Force item)',
['Bandanna'] = 'Bandanna (5D\'s Tag Force)',
['Bat'] = 'Bat (item)',
['Beef Bowl'] = 'Beef Bowl (item)',
['Card Ejector Figure'] = 'Card Ejector Figure (Tag Force)',
['Cyber Tutu Figure'] = 'Cyber Tutu Figure (Tag Force)',
['Dark Magician Girl Figure'] = 'Dark Magician Girl Figure (Tag Force)',
['Death Match Duel Rope'] = 'Death Match Duel Rope (Tag Force)',
['Duel Calculator'] = 'Duel Calculator (Tag Force)',
['Ebon Magician Curran Figure'] = 'Ebon Magician Curran Figure (Tag Force)',
['Gold Coin'] = 'Gold Coin (item)',
['Junk'] = 'Junk (item)',
['Red Dragon Archfiend Figure'] = 'Red Dragon Archfiend Figure (Tag Force)',
['Sandwich (Green)'] = 'Sandwich (5D\'s Tag Force Green)',
['Sandwich (Gold)'] = 'Sandwich (5D\'s Tag Force Gold)',
['Tea'] = 'Tea (item)',
['The Daily Duel'] = 'The Daily Duel (Tag Force)',
['Toothbush'] = 'Toothbush (Tag Force)',
['Water'] = 'Water (item)',
['White Magician Pikeru Figure'] = 'White Magician Pikeru Figure (Tag Force)',
}
-- Get the page name from the map
-- If it's not in the map, use the item name as the page name
return map[name] or name
end
-- Get the color for a given rating
-- (The higher the number, the more green. The lower the number, the more red)
--
-- @param rating number Integer between 1 and 5
-- @return string HSL color string
local function getRatingColor(rating)
return 'hsl(' .. ((rating - 1) * 30) .. 'deg, 100%, 75%)'
end
-- Render an effect for displaying
-- (Basically add a "+" before positive numbers. Negative numbers already have a "-")
--
-- @param difference number
-- @return {string|number}
local function renderEffect(difference)
if (difference > 0) then
return '+' .. difference
end
return difference
end
-- Render a "trust" effect for displaying
-- (Shows how much the score increases/decreases by. Hover to see what percentage of a heart that equates to.)
--
-- @param difference number
-- @return {string|number}
local function renderTrustEffect(difference)
local diff = renderEffect(difference)
local heartDiff = renderEffect(difference / 10) .. '%'
return '<abbr title="' .. heartDiff .. ' of a heart">' .. diff .. '</abbr>'
end
-- Create a new instance of the `Character` object
--
-- @param args table
-- @return Character
function Character:new(args)
local character = mw.clone(Character)
character:setData(args)
return character
end
-- Populate character attributes based on input
--
-- @param args table
function Character:setData(args)
args = normalizeArgs(args)
-- If name isn't specified, default to the page name, without parenthetical text
self.name = args['character_name'] or mw.text.split(self.pageName, ' %(')[1]
self.game = args['game']
self.gender = args['gender'] and args['gender']:lower()
self.responses = {}
local groupNames = { 'duel', 'hobby', 'figures', 'sundry_goods', 'food' }
-- Loop through each group and rating combination
for _, groupName in pairs(groupNames) do
for rating = 5, 1, -1 do
local group = groups[groupName]
-- Create a response for each combination
-- And fill with data from input params
local response = Response:new()
-- If a group shares its messages with another group
-- ("Figures" uses the same messages as "Hobby")
local messageGroup = group.messageGroup or groupName
response.group = groupName
response.rating = rating
response.message = args[messageGroup .. '_' .. rating .. '_response']
response.items = InputParser.ulToArray(args[groupName .. '_' .. rating .. '_items'])
table.insert(self.responses, response)
end
end
self:setSmwData()
end
-- Store Semantic MediaWiki data
function Character:setSmwData()
for _, response in pairs(self.responses) do
-- Get an array of page names for each of the response's items
local itemLinks = {}
for _, item in pairs(response.items) do
table.insert(itemLinks, getItemLink(item))
end
-- Create a subobject for the response
mw.smw.subobject({
'Owner name = ' .. self.name,
'Game = ' .. self.game,
'Description = ' .. response.message,
'Numeric rating = ' .. response.rating,
'Has items = ' .. table.concat(itemLinks, '*'),
'+sep=*'
})
end
end
-- Get a character's pronoun
-- @return string "he", "she", or "they"
function Character:getPronoun()
local map = { ['male'] = 'he', ['female'] = 'she' }
return map[self.gender] or 'they'
end
-- Get a character's objective pronoun
-- @return string "him", "her", or "them"
function Character:getObjectivePronoun()
local map = { ['male'] = 'him', ['female'] = 'her' }
return map[self.gender] or 'them'
end
-- Render all the information as wikitext
-- @return string
function Character:renderResponses()
local intro = '<p>In <i>[[' .. self.game .. ']]</i>, ' .. (self.name) .. ' has the following responses when the player gives ' .. (self:getObjectivePronoun()) .. ' a present.</p>'
intro = intro .. '<p>The "Trust" column shows how much of a heart the present will increase in the level of trust by. '
intro = intro .. 'The "Card", "Dueling", and "Them" columns show the effect it has on how many more times ' .. (self:getPronoun())
intro = intro .. (self:getPronoun() == 'they' and ' are' or ' is') ..' willing to talk about that topic (maximum 5).</p>'
local chart = mw.html.create('table'):attr('class', 'wikitable hlist sortable toggleable-columns-table')
local theadRow = chart:tag('tr')
theadRow:tag('th'):attr('scope', 'col'):tag('abbr'):attr('title', 'Rating'):wikitext('★')
theadRow:tag('th'):attr('data-col-group', 'Group'):wikitext('Group')
theadRow:tag('th'):attr('data-col-group', 'Items'):wikitext('Items')
theadRow:tag('th'):attr('data-col-group', 'Response'):wikitext('Response')
theadRow:tag('th'):attr('data-col-group', 'Effects'):wikitext('Trust')
theadRow:tag('th'):attr('data-col-group', 'Effects'):wikitext('Mood')
theadRow:tag('th'):attr('data-col-group', 'Effects'):wikitext('Card')
theadRow:tag('th'):attr('data-col-group', 'Effects'):wikitext('Dueling')
theadRow:tag('th'):attr('data-col-group', 'Effects'):wikitext('Them')
local groupNames = { 'duel', 'hobby', 'figures', 'sundry_goods', 'food' }
for rating = 5, 1, -1 do
for groupNumber, groupName in pairs(groupNames) do
local group = groups[groupName]
local response = self:getResponse(groupName, rating)
local row = chart:tag('tr')
if groupNumber == 1 then
row:tag('td'):attr('rowspan', 5):css('background-color', getRatingColor(rating)):css('color', '#000'):css('text-align', 'center'):wikitext(rating)
end
row:tag('td'):wikitext(group.name)
row:tag('td'):wikitext(response and response:renderItemList())
row:tag('td'):wikitext(response and response.message)
row:tag('td'):wikitext(renderTrustEffect(group.trust[rating]))
row:tag('td'):wikitext(renderEffect(group.mood[rating]))
row:tag('td'):wikitext(renderEffect(group.card[rating]))
row:tag('td'):wikitext(renderEffect(group.dueling[rating]))
row:tag('td'):wikitext(renderEffect(group.them[rating]))
end
end
return intro .. tostring(chart)
end
-- Get a particular response
--
-- @field groupName string The group that the response is for
-- @field rating number The rating from 1 to 5 the character is giving
function Character:getResponse(groupName, rating)
-- Loop through all responses
for _, response in pairs(self.responses) do
-- Stop on the one with the matching group and rating
if (response.rating == rating and response.group == groupName) then
return response
end
end
end
-- Create a new instance of a `Response` object
-- @return Response
function Response:new(args)
local r = mw.clone(Response)
return r
end
-- Render a response's items as a list in wikitext
-- @return string
function Response:renderItemList()
local list = mw.html.create('ul')
for _, item in pairs(self.items) do
local link = getItemLink(item)
list:tag('li'):wikitext('[[' .. link .. '|' .. item .. ']]')
end
return tostring(list)
end
-- The main method that gets invoked by templates
-- @return string
function Character.main(frame)
-- `frame:getParent().args` should get the template parameters
-- Default to just `frame`, so the params can be passed directly when debugging
local args = frame.getParent and frame:getParent().args or frame
-- Create instance of the character
local character = Character:new(args)
-- Render responses for the character
return tostring(character:renderResponses())
end
return Character