Module:Girls

-- The following pages are related: https://fapceo.wikia.com/wiki/Module:Girls https://fapceo.wikia.com/wiki/Module:Girls/data

local p = {} p.girls = mw.loadData('Module:Girls/data') p.config = { types = { f = { small = { sort_value = 1, link = "small" },           medium = { sort_value = 2, link = "medium" },           large = { sort_value = 3, link = "large" }       },        b = { small = { sort_value = 1, link = "small" },           medium = { sort_value = 2, link = "medium" },           large = { sort_value = 3, link = "large" }       },        h = { small = { sort_value = 1, link = "small" },           medium = { sort_value = 2, link = "medium" },           large = { sort_value = 3, link = "large" }       }    },    image = { ruby = 25, icon = 100, info = 256, },   style={ flex='display:flex;flex-wrap:wrap;', pbox='position:relative;'.. 'margin: 1px;'.. 'border: 2px solid #008eff;'.. 'width: 100px;'.. 'align-items: center;'.. 'height: 100px;'.. 'border-radius: 3px;', pboxtext = 'position:absolute;'.. 'bottom:0;'.. 'background:#00000090;'.. 'width:100%;'.. 'text-align:center;', outfit='display:flex;'.. 'border: 2px solid #008eff;'.. 'border-radius:3px;'.. 'flex-direction: column;'.. 'align-items: center;'.. 'margin:1px;'.. 'width:300px;', outfitgirlname='width: 100%;'.. 'font-size: 150%;'.. 'text-align: center;'.. 'border-top: 2px solid black;'.. 'border-bottom: 2px solid black;'.. 'margin-bottom: 10px;'.. 'margin-top: 10px;', }

}

local f = require('Module:Functions')

function check(stat) if stat == nil then return " Please insert data to Module:Girls/data." elseif stat == "" then return "Unknown" end return stat end

function link_the_stat(stat,typ,only) if stat == nil then return "Add data here" end stat = f.split(stat," - ")[1] if only == true then return 'data-sort-value="'..p.config.types[typ][stat].sort_value..'"|'..p.config.types[typ][stat].link end return p.config.types[typ][stat].link end

function p.header(frame) local name = mw.title.getCurrentTitle.text local char_data = p.girls[name] if char_data == nil then return " Please insert data to Module:Girls/data." end local occupation = check(char_data.occupation) if name=="Tasha" then occupation="Heiress" end local data = {} table.insert(data, " ")   table.insert(data, name)    table.insert(data, ", the ") table.insert(data, occupation) table.insert(data, ".") return table.concat(data, "") end

function p.infobox(frame) local name = mw.title.getCurrentTitle.text local char_data = p.girls[name] if char_data == nil then return " Please insert data to Module:Girls/data." end local data = {} local infobox = { image = name..'_icon.jpg', height = check(link_the_stat(char_data.height,"h")), breast = check(link_the_stat(char_data.breast,"b")), feet = check(link_the_stat(char_data.feet,"f")), age = check(char_data.age), occupation = check(char_data.occupation), likes = check(char_data.likes), dislikes = check(char_data.dislikes) }   table.insert(data, frame:expandTemplate { title = 'Girl info', args = infobox }) table.insert(data, ""..check(char_data.desc)) table.insert(data, frame:expandTemplate { title = 'Clear'}) return table.concat(data, '\n') end

function p.description(frame) local name = mw.title.getCurrentTitle.text local char_data = p.girls[name] if char_data == nil then return " Please insert data to Module:Girls/data." end local data = {} table.insert(data, ""..check(char_data.desc)) return table.concat(data, '\n') end

function p.fullDescription(frame) local data = {'{| style="margin-left: 320px; margin-top: 30px;"', "|Description:", "|-",               "|"..p.description(frame), "|}"} return table.concat(data, "\n") end

function p.table(frame) local data = { '==Girls List==', '{| class="wikitable mw-datatable sortable" style="text-align: center;"', '|-',       '! Name', '! class="unsortable" | Picture', '! data-sort-type="number" | Height', '! data-sort-type="number" | Breast Size', '! data-sort-type="number" | Feet', '! class="sortable" | Unlocks At ', '! class="sortable" | Release Date ', '|-'   }

for _, name in ipairs(sorted(p.girls)) do       local girl_data = p.girls[name] table.insert(data, '| '..name ..'') table.insert(data, '| ') table.insert(data, '|'..check(link_the_stat(girl_data.height,"h",true))) table.insert(data, '|'..check(link_the_stat(girl_data.breast,"b",true))) table.insert(data, '|'..check(link_the_stat(girl_data.feet,"f",true)))

local u = {} for i, unlock in ipairs(girl_data.unlock) do           if unlock.other ~= nil then -- Enter data as is. u[#u+1] = unlock.other elseif unlock.event ~= nil and unlock.name ~= nil then -- Enter link to event with different display name. u[#u+1] = ..unlock.name.. elseif unlock.event ~= nil then -- Enter link to event with default name. u[#u+1] = ..unlock.event.. else u[#u+1] = 'Wrong Event_Type in Module:Girls/data' end end table.insert(data, '|'..table.concat(u, " "))

if type(check(girl_data.release)) == "number" then e=girl_data.release elseif check(girl_data.release)==" Please insert data to Module:Girls/data." then e=girl_data.release else e=..girl_data.release.. end table.insert(data, '|'..e)       table.insert(data, '|-') end table.insert(data, '|}') --for i, d in pairs(data) do mw.log(d) end return table.concat(data, "\n") end

function p.basic_info(frame) local name = mw.title.getCurrentTitle.text local char_data= p.girls[name] if char_data == nil then return " Please insert data to Module:Girls/data." end local data = { '{| class="wikitable" style="float:left; width: 300px;"', '|-',       }    table.insert(data, '| scope="col" colspan="2" | ') table.insert(data, '|-') table.insert(data, '| Height || '..link_the_stat(char_data.height, "h",true)) table.insert(data, '|-') table.insert(data, '| Breast || '..link_the_stat(char_data.breast, "b",true)) table.insert(data, '|-') table.insert(data, '| Feet || '..link_the_stat(char_data.feet, "f",true)) table.insert(data, '|-') table.insert(data, '| Age || '..check(char_data.age)) table.insert(data, '|-') table.insert(data, '| Occupation || '..check(char_data.occupation)) table.insert(data, '|-') table.insert(data, '| Likes || '..check(char_data.likes)) table.insert(data, '|-') table.insert(data, '| Dislikes || '..check(char_data.dislikes)) table.insert(data, '|-') local u = {} for i, unlock in ipairs(char_data.unlock) do       if unlock.other ~= nil then -- Enter data as is. u[#u+1] = unlock.other elseif unlock.event ~= nil and unlock.name ~= nil then -- Enter link to event with different display name. u[#u+1] = ..unlock.name.. elseif unlock.event ~= nil then -- Enter link to event with default name. u[#u+1] = ..unlock.event.. else u[#u+1] = 'Wrong Event_Type in Module:Girls/data' end end table.insert(data, '| Unlocked || '..table.concat(u, " ")) table.insert(data, '|}') return table.concat(data, '\n') end

function bold(str) return ""..str.."" end

-- Create data for each cell. function outfit_name_cell(outfit) return bold(outfit.name) end

function outfit_name_cell_link(outfit, name) if string.match(outfit.name, name) then return bold(outfit.name:gsub(name, ""..name.."")) end if p.girls[name].alt_names ~= nil then for _, alt_name in ipairs(p.girls[name].alt_names) do     if string.match(outfit.name, alt_name) then return bold(outfit.name:gsub(alt_name, ""..alt_name.."")) end end end return " Girl name not in the outfit name \""..outfit.name.."\" looking for \""..name.."\".Please fix Module:Girls/data. Possibly add 'alt_names = {\"some_other_name\"}' for girl." end

function outfit_picture_cell(outfit, size) return "" end

function outfit_hired_cell(outfit, size) return "" end

function add_ruby_symbol(str) if string.match(str, "Rubies") then str = str:gsub("Rubies", "Rubies ") end if string.match(str, "Wardrobe Tokens") then str = str:gsub("Wardrobe Tokens", "Wardrobe Tokens ") end return str end

-- Event in BOLD font. function add_event(event, name) if name ~= nil then return ""..name.."" end return ""..event.."" end

-- Add thumbnail in newline function add_thumbnail(thumbnail, size, link) return " " end

-- function add_outfit_unlock(unlock, thumbnail) local data = {} -- Add cost and 'from' part if necessary. if unlock.cost ~= nil then table.insert(data, add_ruby_symbol(unlock.cost)) if unlock.event ~= nil or unlock.other ~= nil then table.insert(data, "from") end end -- Add event link if unlock.event ~= nil then table.insert(data, add_event(unlock.event, unlock.name)) -- Add new line for other as note/comment in new line. end -- Add other as comment or ending for alone 'cost' variable. if unlock.other ~= nil then table.insert(data, unlock.other) end if thumbnail ~= nil and unlock.thumbnail then local size = "300px" if unlock.event == "Tournament" or unlock.event == "Tutorial" then size = "100px" end table.insert(data, add_thumbnail(unlock.thumbnail, size, unlock.event)) end return table.concat(data, " "); end

-- thumbnails, if not nil - thumbnails of events will be added. function outfit_unlock_cell(outfit, thumbnails) local cell = {} for _, unlock in ipairs(outfit.unlock) do   table.insert(cell, add_outfit_unlock(unlock, thumbnails)) end return table.concat(cell, " ") end

function cell_style(styles) local style = {} -- Include width with cell. if styles.width ~= nil then table.insert(style, "width: "..styles.width..";") end if styles.color_top ~= nil then table.insert(style, "border-top:solid 3px "..styles.color_top..";") end

if styles.color ~= nil then table.insert(style, "background-color: "..styles.color..";") end

return "style=\""..table.concat(style, " ").."\" | " end

function count_elems(arr) local count = 0 for _, elem in pairs(arr) do   count = count + 1 end return count end

function girl_outfits_table_single(girl_data) -- 5 outfits in a row can make table unreadable for lower resolutions. local outfits_max_length = 4 local outfits_num = count_elems(girl_data.outfits) -- Determine number of columns in Outfits table. if (outfits_num < outfits_max_length) then outfits_max_length = outfits_num end

-- Beginning of the table with all settings. local data = { '{| class="wikitable" style="float:right; margin-left:auto; margin-right:0px; text-align: center;"', '! colspan="'..(outfits_max_length + 1)..'" | Outfits', '|-',     }  local column = 0 local row = 1; -- Helper lists to not iterate through the same data all the time. local outfit_name_row = {'! scope="row" '..cell_style({ width = "100px" })..'Outfit name'} local unlock_row = {'! scope="row" | Unlock'} local picture_row = {'! scope="row" | Picture'} local hired_row = {'! scope="row" | Hired'} for _, outfit in ipairs(girl_data.outfits) do   local name_style = cell_style({width = "250px", color_top = "grey"}) if row == 1 then name_style = cell_style({width = "250px"}) end table.insert(outfit_name_row, "| "..name_style..outfit_name_cell(outfit)) table.insert(unlock_row, "| "..cell_style({width = "250px"})..outfit_unlock_cell(outfit)) table.insert(picture_row, "| "..outfit_picture_cell(outfit, "100px")) table.insert(hired_row, "| "..outfit_hired_cell(outfit, "250px")) column = column + 1 if column == outfits_max_length then column = 0 row = row + 1 -- Add End of the row. table.insert(outfit_name_row, "|-") table.insert(unlock_row, "|-") table.insert(picture_row, "|-") table.insert(hired_row, "|-") -- Add full rows to the table. table.insert(data, table.concat(outfit_name_row, "\n")) table.insert(data, table.concat(unlock_row, "\n")) table.insert(data, table.concat(picture_row, "\n")) table.insert(data, table.concat(hired_row, "\n")) -- Reset Rows to default value. outfit_name_row = {'! scope="row"'..cell_style({width = "100px", color_top = "grey"})..'Outfit name'} unlock_row = {'! scope="row" | Unlock'} picture_row = {'! scope="row" | Picture'} hired_row = {'! scope="row" | Hired'} end end -- Add last outfits. if column > 0 then -- Add End of the row. table.insert(outfit_name_row, "|-") table.insert(unlock_row, "|-") table.insert(picture_row, "|-") table.insert(hired_row, "|-")

-- Add full rows to the table. table.insert(data, table.concat(outfit_name_row, "\n")) table.insert(data, table.concat(unlock_row, "\n")) table.insert(data, table.concat(picture_row, "\n")) table.insert(data, table.concat(hired_row, "\n")) end table.insert(data, '|}') --for i,j in pairs(data) do mw.log(j) end return table.concat(data, '\n') end

function p.outfits(frame) local name = mw.title.getCurrentTitle.text local char_data=p.girls[name] if char_data == nil then return " Please insert data to Module:Girls/data." end

return girl_outfits_table_single(char_data) end

function girl_outfits_table_all(girl_data, name, outfits_columns) -- Beginning of the table with all settings. local data = {'! colspan="'..outfits_columns..'" '..cell_style({color = "#99EEFF"})..' '..name..' ', '|-',     }  local column = 0 -- Helper lists to not iterate through the same data all the time. local outfit_name_row = {} local picture_row = {} local unlock_row = {} local cell_width = (100 / outfits_columns).."%" for _, outfit in ipairs(girl_data.outfits) do   local name_style = cell_style({width = cell_width, color = "#E3E3E3"}) table.insert(outfit_name_row, "| "..name_style..outfit_name_cell_link(outfit, name)) --table.insert(picture_row, "| "..cell_style({width = cell_width})..   --                          " "..outfit_picture_cell(outfit, "150px")..    --                          " "..outfit_hired_cell(outfit, "300px")) table.insert(picture_row, "| "..cell_style({width = cell_width})..                             " "..outfit_hired_cell(outfit, "300px")) table.insert(unlock_row, "| "..cell_style({width = cell_width})..outfit_unlock_cell(outfit, true))

column = column + 1 if column == outfits_columns then column = 0 -- Add End of the row. table.insert(outfit_name_row, "|-") table.insert(picture_row, "|-") table.insert(unlock_row, "|-") -- Add full rows to the table. table.insert(data, table.concat(outfit_name_row, "\n")) table.insert(data, table.concat(picture_row, "\n")) table.insert(data, table.concat(unlock_row, "\n")) -- Reset Rows to default value. outfit_name_row = {} picture_row = {} unlock_row = {}

end end -- Add last outfits. if column > 0 then -- Add End of the row. table.insert(outfit_name_row, "|-") table.insert(picture_row, "|-") table.insert(unlock_row, "|-")

-- Add full rows to the table. table.insert(data, table.concat(outfit_name_row, "\n")) table.insert(data, table.concat(picture_row, "\n")) table.insert(data, table.concat(unlock_row, "\n")) end return table.concat(data, '\n') end

function sorted(girls_data) local list = {} for name, _ in pairs(girls_data) do   table.insert(list, name) end table.sort(list) return list end

function p.outfits_all(frame) local data = { '==Outfits==', ' '     }  for _, name in ipairs(sorted(p.girls)) do    girl_data = p.girls[name] table.insert(data, ' '..       ' '..name..' '..        ' '    ) for _, outfit in ipairs(girl_data.outfits) do       table.insert(data,' '..                ' '..outfit_name_cell_link(outfit, name)..' '..                ' '..outfit_hired_cell(outfit, "300px")..' '..                ' '..outfit_unlock_cell(outfit, true)..' '..                ' ') end table.insert(data, ' ') end table.insert(data,' ') return table.concat(data, "\n") end

function p.outfits_legendary(frame) local data = { ' ' } for _, name in ipairs(sorted(p.girls)) do   girl_data = p.girls[name]

for _, outfit in ipairs(girl_data.outfits) do     if outfit.legendary ~= nil and outfit == true then table.insert(data,' '..               ' '..outfit_name_cell_link(outfit, name)..' '..                ' '..outfit_hired_cell(outfit, "300px")..' '..                ' ') end end table.insert(data, ' ') end table.insert(data,' ') return table.concat(data, "\n") end

function p.count_outfits(frame) local counted = 0 local default = false for _, name in ipairs(sorted(p.girls)) do   girl_data=p.girls[name] for _, outfit in ipairs(girl_data.outfits) do     default = false for _, unlock in ipairs(outfit.unlock) do       if unlock.other == "Starting Outfit" then default = true end end if default == false then counted = counted + 1 end end end return counted end

function p.link_colored(name, color) return ' '..name..' ' end

function p.box(frame) local data = { ' Overview - Click her name or image to see her section '.. ' '   }    for _, name in ipairs(sorted(p.girls)) do        table.insert(data,' '..            ' '..p.link_colored(name, "#FFFFFF")..' '..            ' '        ) end table.insert(data,' ') -- mw.log(table.concat(data,"\n")) return table.concat(data,"\n") end

function p.generateGirlPage(frame) local data = {} table.insert(data, p.header(frame)) table.insert(data, p.basic_info(frame)) table.insert(data, p.fullDescription(frame)) table.insert(data, p.outfits(frame))

table.insert(data,    frame:callParserFunction('#invoke:Messages', {'main', 'GenerateInbox'})) table.insert(data,   frame:callParserFunction('#invoke:Messages', {'main', 'GenerateGirlPresent'}))

-- Not possible to add tag in the modules. Add this part on the page itself. --table.insert(data, '')

return table.concat(data, '\n') end

return p