Module:Gifts

-- -- Module:Gifts -- local Self = {}                            -- table of functions local Helper = require("Module:Helper")    -- basic helper functions local Image = require("Module:ImageUnifier")-- image functions local ustr = mw.ustring                    -- quick/short access to ustring table local TI = table.insert                    -- quick/short access to table inserting

-- -- Constants -- local DB = mw.loadData("Module:Gifts/data") local VERSION = "2.0.137882" local SEASONS = {"Spring","Summer","Autumn","Winter"} local RP_GROUPS = {"Love","Like","Neutral","Dislike","Hate"} local RP_CHAR = { -- love,like,neutral,dislike,hate = Minimum RP for each group -- generic = Generic item rp value for "Everything Else" default            = {Love=10, Like=2, Neutral=0, Dislike=-2, Hate=-1000, generic= 1}, ["Ginger"]         = {Love= 2, Like=1, Neutral=0, Dislike=-2, Hate=-1000, generic= 0}, ["Pinky"]          = {Love=12, Like=2, Neutral=0, Dislike=-2, Hate=-1000, generic=-2}, } local RP_ITEM = { -- default item values default                =  1, ["Roses"]              = 10, ["Ruby"]               =  8, ["Sapphire"]           =  5, ["Topaz"]              =  4, ["Asteria (bouquet)"]  =  3, ["Power Stone"]        =  3, ["Wasted Food"]        = -1, ["Caterpillar"]        = -2, ["Hardwood"]           = -2, ["Sand"]               = -2, ["Soil"]               = -2, ["Stone"]              = -2, ["Wildflowers"]        = -2, ["Wood"]               = -2, ["Aluminum Ore"]       = -5, ["Animal Feces"]       = -5, ["Copper Ore"]         = -5, ["Iron Ore"]           = -5, ["Lead Ore"]           = -5, ["Magnesium Ore"]      = -5, ["Manganese Ore"]      = -5, ["Tin Ore"]            = -5, ["Titanium Ore"]       = -5, ["Abandon Tag"]        = -9999,--Skip, not normally giftable ["Dog Tag"]            = -9999,--Skip, not normally giftable ["Cat Tag"]            = -9999,--Skip, not normally giftable ["Pig Tag"]            = -9999,--Skip, not normally giftable ["Yoyo's Pet Tag"]     = -9999,--Skip, not normally giftable }

local UNIMPLEMENTED_GIFTS = { ["Banner Fish Sushi"] = true, ["Concave Mirror"] = true, ["Convex Mirror"] = true, ["Deep Fried Ribs"] = true, ["Elegant Fur"] = true, ["Orange"] = true, ["Painting: Carp and Lotus"] = true, ["Pinecock Costume"] = true, ["Red Lamp"] = true, ["Sashimi"] = true, ["Ship in a Bottle"] = true, ["Twisted Window Origamy"] = true, }

-- -- Character Infobox Gifts -- Self.CharInfobox = function(frame) return Self.CharInfoboxMain(Helper.GetArgs(frame)) end

function Self.CharInfoboxMain(args) local char = mw.text.decode(args[2]) --Name of Character local groupTable = RP_CHAR[char] or RP_CHAR.default local minRp = groupTable.Love local itemArray = {} for item, rp in pairs(DB[char]) do       if not UNIMPLEMENTED_GIFTS[item] and rp >= minRp then TI(itemArray, {item=item,rp=rp}) end end for item, rp in pairs(RP_ITEM) do       if item ~= "default" and not DB[char][item] and rp >= minRp then TI(itemArray, {item=item,rp=rp}) end end table.sort(itemArray, function(a,b)       if a.rp ~= b.rp then            return a.rp > b.rp        else            return a.item < b.item        end    end) local code = "" for _, entry in ipairs(itemArray) do       code = code..Image.GetImagesMain({entry.item}, {link=entry.item, caption=entry.item}, "text") code = code..""..entry.item.." ("..Self.GetRpText(entry.rp)..") " end return code end

-- -- Character Page Gifts -- Self.CharPref = function(frame) return Self.CharPrefMain(Helper.GetArgs(frame)) end

function Self.CharPrefMain(args) local char = mw.text.decode(args[2]) --Name of Character local groupTable = RP_CHAR[char] or RP_CHAR.default local eeRp = groupTable.generic local itemArray = --Add a dummy entry with everything else rank to ensure it gets added for item, rp in pairs(DB[char]) do       if not UNIMPLEMENTED_GIFTS[item] then TI(itemArray, {item=item,rp=rp}) end end for item, rp in pairs(RP_ITEM) do       if item ~= "default" and not DB[char][item] and rp >= -1000 then TI(itemArray, {item=item,rp=rp}) end end table.sort(itemArray, function(a,b)       if a.rp ~= b.rp then            return a.rp > b.rp        else            return a.item < b.item        end    end) -- Table Header local c = "{|class='prettytable' style='width:100%; text-align:center;'\n|-style='font-size:120%'\n" c=c.."!style='width:18%;'|"..Image.GetImagesMain({"Social gift"}, {link="Gifting"}, "header").." Gifting\n" c=c.."!Items" -- Table Body local cRp = 9999 local eeDone = false local r = {} for _, entry in ipairs(itemArray) do       if cRp ~= entry.rp then cRp = entry.rp           local rpGroup = Self.GetRpGroup(groupTable, cRp) local tbl = { header = "\n|-\n|style='padding-top:4px; padding-bottom:2px;'|"..Image.GetImagesMain({"Gift "..rpGroup}, {link=""}, "text")..rpGroup..": "..Self.GetRpText(cRp).."\n|", items = {}, }           TI(r, tbl) end if cRp == eeRp then --Everything Else if not eeDone then eeDone = true TI(r[#r].items, Image.GetImagesMain({"Gift icon"}, {link=""}, "text").."Everything Else ") end else local flag = (RP_ITEM[entry.item] == cRp) and "''" or "" TI(r[#r].items, Image.GetImagesMain({entry.item}, {link=entry.item, caption=entry.item}, "text") ..flag..""..entry.item..""..flag.." ") end end for _, row in ipairs(r) do       local max = #row.items local mid = math.floor((max+1)/2) c=c..row.header c=c.." " c=c..table.concat(row.items, "", 1, mid).." " c=c.." " c=c..table.concat(row.items, "", mid+1, max).." " end -- Table Footer c=c.."\n|-\n!Version "..VERSION.."\n" c=c.."!Listed values are without The Giver skill, which gives an extra point.\n|}" return c end

-- -- Master Gifts by Character -- Self.GiftsByChar = function(frame) return Self.GiftsByCharMain(Helper.GetArgs(frame)) end

function Self.GiftsByCharMain(args) local charArray = {} local charTable = {} --Gather item data for char, items in pairs(DB) do       local groupTable = RP_CHAR[char] or RP_CHAR.default local genericGroup = Self.GetRpGroup(groupTable, groupTable.generic) TI(charArray, char) charTable[char] = { groupTable = groupTable, genericGroup = genericGroup, items = {}, }       local tbl = charTable[char] for item, rp in pairs(items) do           if not UNIMPLEMENTED_GIFTS[item] and groupTable.generic ~= rp then local rpGroup = Self.GetRpGroup(tbl.groupTable, rp) TI(tbl.items, {item=item, rp=rp, rpGroup=rpGroup}) end end for item, rp in pairs(RP_ITEM) do           if not items[item] and item ~= "default" and rp >= -1000 and groupTable.generic ~= rp then local rpGroup = Self.GetRpGroup(tbl.groupTable, rp) TI(tbl.items, {item=item, rp=rp, rpGroup=rpGroup}) end end table.sort(tbl.items, function(a,b)           if a.rp ~= b.rp then                return a.rp > b.rp            else                return a.item < b.item            end        end) end --shorthand for ease of ternary operator local D = Helper.IfDesktop local M = not D   -- Construct Table Header local c = "Below are the unique gift preferences of all characters, as of PC version "..VERSION.."." c=c.."\n{|class='prettytable sortable' style='width:100%; text-align:center;'" c=c.."\n!style='width:7%; font-size:75%' |Name" c=c.."\n!style='width:7%; font-size:75%' |"..(M and "BD" or "Birthday") c=c.."\n!style='width:86%; font-size:125%' class='unsortable' |Gift Preferences\n|-\n" -- Construct Character Entries table.sort(charArray) local borderLine = "1px solid #6EBBFF80;" local itemColumn = " " local InfoBoxData = require("Module:GetInfoboxData") for _, char in ipairs(charArray) do       local birthday = "Varies" if char ~= "Child" then birthday = InfoBoxData.GetDataMain({char, "birthday"}) end local season = tonumber(ustr.sub(birthday,1,1)) if season then season = SEASONS[season] end -- Construct Character Column c=c.."!data-sort-value='"..char.."'|\n" if char == "Child" then c=c..Image.ImageFixedMain({"Baby boy", "large", "w", link=char}).." " c=c..Image.ImageFixedMain({"Baby girl", "large", "w", link=char}).." " else c=c..Image.ImageFixedMain({char, "large", "w", link=char}).." " end c=c..""..char.."\n" c=c.."|data-sort-value='"..birthday.."'|\n" if season then c=c..Image.ImageFixedMain({"Season "..season, "medium", link=season.." (season)"}).." " c=c..""..birthday.."" else c=c..birthday end c=c.."\n|\n" c=c..(M and "{|\n|" or "") -- Construct Gift List local tbl = charTable[char] local r = {[tbl.genericGroup] = {}} local cGroup for _, item in ipairs(tbl.items) do           if not r[item.rpGroup] then r[item.rpGroup] = {} end local flag = ((RP_ITEM[item.item] or RP_ITEM.default) == item.rp) and "''" or "" local str = Image.GetImagesMain({item.item}, {link=item.item, caption=item.item}, "text") str = str..flag..""..item.item..""..flag.." ("..Self.GetRpText(item.rp)..") " TI(r[item.rpGroup], str) end for _, rpGroup in ipairs(RP_GROUPS) do           if r[rpGroup] then if rpGroup ~= "Love" then -- Divider for each group after Love c=c..(M and "|-\n|" or "\n") end if rpGroup == tbl.genericGroup then local str = Image.GetImagesMain({"Gift icon"}, {link=""}, "text") str = str.."Everything Else ("..Self.GetRpText(tbl.groupTable.generic)..") " TI(r[rpGroup], str) end local max = #r[rpGroup] local mid = math.floor((max+1)/2) -- Group Header c=c.." " c=c..Image.GetImagesMain({"Gift "..rpGroup}, {link=""}, "text")..(M and "&#32;" or " ")..""..rpGroup.." \n" -- Column 1 c=c..itemColumn..table.concat(r[rpGroup], "", 1, mid).." \n" -- Column 2 c=c..itemColumn..table.concat(r[rpGroup], "", mid+1, max).." \n" end end c=c..(M and "|}\n" or "").."|-\n" end c=c.."|}" return c end

-- -- Item Page Gifts -- Self.ItemPref = function(frame) return Self.ItemPrefMain(Helper.GetArgs(frame)) end

function Self.ItemPrefMain(args) local item = mw.text.decode(args[2]) local eeRp = RP_ITEM[item] or RP_ITEM.default local eeGroup = Self.GetRpGroup(RP_CHAR.default, eeRp) local charArray = {} for char, items in pairs(DB) do       local tbl = { char = char, rp = items[item] or RP_ITEM[item] or (RP_CHAR[char] and RP_CHAR[char].generic) or 1, }       tbl.group = Self.GetRpGroup(RP_CHAR[char] or RP_CHAR.default, tbl.rp) TI(charArray, tbl) end table.sort(charArray, function(a,b)       if a.rp ~= b.rp then            return a.rp > b.rp        else            return a.char < b.char        end    end) -- Table Header local c = "{|class='prettytable' style='width:100%; text-align:center;'\n|-style='font-size:120%'\n" c=c.."!style='width:18%;'|"..Image.GetImagesMain({"Social gift"}, {link="Gifting"}, "header").." Gifting\n" c=c.."!Characters" -- Table Body local cRp = 9999 local eeDone = false local r={Love="",Like="",Neutral="",Dislike="",Hate=""} for _, entry in ipairs(charArray) do       if cRp ~= entry.rp then cRp = entry.rp           c=c..r.Love..r.Like..r.Neutral..r.Dislike..r.Hate r={Love="",Like="",Neutral="",Dislike="",Hate=""} end local g = entry.group if r[g] then if r[g] == "" then r[g]=r[g].."\n|-\n|style='padding-top:4px; padding-bottom:2px;'|" r[g]=r[g]..Image.ImageFixedMain({"Gift "..g, "small", link=""}).." "..g..": "..Self.GetRpText(cRp).."\n|" r[g]=r[g].."style='text-align:left; padding-top:4px; padding-bottom:2px;'|" end if cRp == eeRp and g == eeGroup then --Everyone Else if not eeDone then eeDone = true r[g]=r[g]..Image.ImageFixedMain({"Prompt city", "medium", link=""}).."Everyone Else" end elseif entry.char == "Child" then r[g]=r[g]..Image.ImageFixedMain({"Baby boy", "medium", link=entry.char}) r[g]=r[g]..Image.ImageFixedMain({"Baby girl", "medium", link=entry.char}) else r[g]=r[g]..Image.ImageFixedMain({entry.char, "medium", link=entry.char}) end end end c=c..r.Love..r.Like..r.Neutral..r.Dislike..r.Hate -- Table Footer c=c.."\n|-\n!Version "..VERSION.."\n" c=c.."!Listed values are without The Giver skill, which gives an extra point.\n|}" return c end

-- -- Dump Gift Item List -- Self.ItemList = function(frame) local itemArray = {} local itemTable = {} for char, items in pairs(DB) do       for item, rp in pairs(items) do            if not itemTable[item] then itemTable[item] = { item = item, i2 = "# "..Image.GetImagesMain({item}, {link=item, caption=item}, "text")..""..item.."\n", rp = 0, count = 0, }               TI(itemArray, item) end itemTable[item].rp = itemTable[item].rp + rp           itemTable[item].count = itemTable[item].count + 1 end end table.sort(itemArray, function(a,b)       if itemTable[a].count ~= itemTable[b].count then            return itemTable[a].count > itemTable[b].count        elseif itemTable[a].rp ~= itemTable[b].rp then            return itemTable[a].rp > itemTable[b].rp        else            return itemTable[a].item < itemTable[b].item        end    end) local text = "" for _, item in ipairs(itemArray) do       text = text..itemTable[item].i2    end return text end

Self.Test1 = function(frame) local args = {} for i, item in ipairs(Helper.GetArgs(frame)) do       item = ustr.match(item, "%[%[(.-)[#%]]") or item if i <= 100 then local title = mw.title.new(item) if title then title = title:getContent end if title and not ustr.match(title, "ItemPref") then table.insert(args, item) end else table.insert(args, item) end end local text = "" for _, item in ipairs(args) do       text = text.."|"..item.."" end return "" end -- -- -- Common Functions -- function Self.GetRpGroup(groupTable, rp) if rp >= groupTable.Love then return "Love" elseif rp >= groupTable.Like then return "Like" elseif rp >= groupTable.Neutral then return "Neutral" elseif rp >= groupTable.Dislike then return "Dislike" elseif rp >= groupTable.Hate then return "Hate" else return "Skip" end end

function Self.GetRpText(rp) if rp > 0 then return "+"..rp   else return rp   end end

-- -- Required for Modules to function -- return Self