-- The MIT License (MIT) http://opensource.org/licenses/MIT -- Copyright (c) 2014-2020 His Dad -- Some code from the luatz project (MIT Licence) -- Configuration ========== --local dateformat = "%Y-%m-%d, %H:%M" dateformat_log = "%Y-%m-%d, %H:%M:%S" FG_Colour_Not_Complete = "#FFB67D" FG_Colour_Complete = "#000000" BG_Colour_Not_Complete = "#FFB67D" BG_Colour_Complete = "#A4FF5A" Colour_Heading_Complete = "#58FA58" Settings_s ="./my/visibility.lua" debug=false log = function (msg) if debug then print(msg) end end --force_lang = "ru" -- or "de" or "fr" or "ru" for debugging --force_lang = "de" --force_lang = "fr" -- ======================== version= "85" update="42" require( "iuplua" ) require( "iupluacontrols" ) if (iup._VERSION_NUMBER < 326000) then iup.Message("Old Version of IUP-LUA", "Upgrade to 3.26 or later.") iup.Close() end iup.SetGlobal("UTF8MODE","YES") log("Starting to load Saved Data") dofile "../../SavedVariables/History.lua" log("Loaded.") Trials_Order={"Trials Norm","Trials Vet","Trials Hard"} Group_Dat={} Group_Order={"Group 1N","Group 1V","Group 1VH","Group 2N","Group 2V","Group 2VH"} Grp1_Order={"Group 1N","Group 1V","Group 1VH"} Grp2_Order={"Group 2N","Group 2V","Group 2VH"} Ach_Detail = {} --Forward Reference accounts = {} dofile "./Prog/utility.lua" -- utility functions dofile "./Prog/Strings.lua" -- String Handling dofile "./data/DLC_Grp.lua" dofile "./data/DLC.lua" dofile "./data/Group1.lua" -- Grp Mode 1 data, N, V, VH dofile "./data/Group2.lua" -- Grp Mode 2 data, N, V, VH dofile "./data/Public.lua" dofile "./data/Quest.lua" dofile "./data/Veteran.lua" -- Auxiliary Achievements for Vet Dungeons dofile "./data/WB.lua" dofile "./data/Trials.lua" dofile "./data/Special.lua" -- Record of non standard Achievement ID's we need to keep. log("Data Files loaded Ok") --generate_id () -- Generate the file the addon uses to filter Achievement ID's -- This is used by the in game part history.lua to only record achievements that are used. -- Uncomment when need to run. lingua= {} -- Translated data load_lang = function (lang) if lingua[lang] ~= nil then return end local path = "./data/" .. lang .. "/" log("loading lang " .. lang) dofile (path .. lang .. ".lua") dofile (path .. lang .."-data.lua") --Achievement Data from game lingua[lang] = {} lingua[lang].Area_names = Area_names -- dofile writes to global variables lingua[lang].L = L lingua[lang].Ach_Detail = Ach_Detail -- --Do this once at start up log("Add WB to Area_names table.") --Add all WB to Area_name so we can get them by Area in one pass. --Wb_Dat [197] = {Area=1}, --Shipwreck Strand --Area_Names [16]={ name="Coldharbor"}, --Becomes [16]={ name="Coldharbor", WB[1]=ACH_ID}, for Ach,Data in pairs(WB_dat) do if Area_names[Data.Area] == nil then print("Error: with WB_Dat. Area ".. Data.Area .. " Not in Area_names. Ach = " .. Ach) break end local Area = Area_names[Data.Area] if Area.WB == nil then Area.WB={} end table.insert(Area.WB,Ach) end log("Add SQ to Area_names table.") --Add all SQ to Area_name so we can get them by Area in one pass. --SQ_Dat [201] = {Area=1, ["link1"] ="http://www.uesp.net/wiki/Online:The_Death_of_Balreth" }, --Area_Names [16]={ name="Coldharbor"}, --Becomes [16]={ name="Coldharbor", SQ[1]=ACH_ID}, for Ach,Data in pairs(SQ_dat) do if Area_names[Data.Area] == nil then print("Error: with SQ_Dat. Area ".. Data.Area .. " Not in Area_names. Ach = " .. Ach) break end local Area = Area_names[Data.Area] if Area.SQ == nil then Area.SQ={} end table.insert(Area.SQ,Ach) end end accounts_list = {} -- String list for selection dialog playerNames = {} -- Get name from ID. for acc,_ in pairs(History_SV["Default"]) do log("Account: " .. acc) accounts[acc] = {} accounts[acc].worlds = {} accounts[acc].hasblankworlds = false accounts[acc].player = {} accounts[acc].playerIDs = {} -- intermediate table for sorting. WIP. Controls presentation order accounts[acc].AllplayerIDs = {} -- Unfiltered accounts[acc].playerIDs_vet= {} -- subset of names which are >L50 table.insert(accounts_list, acc) -- === Load Language Tables accounts[acc].lang = (History_SV["Default"][acc]["$AccountWide"].lang) if accounts[acc].lang == nil then accounts[acc].lang = "en" end if force_lang ~= nil then accounts[acc].lang = force_lang -- Force the language for testing end load_lang(accounts[acc].lang) -- Reset Globals Area_names = lingua[accounts[acc].lang].Area_names L = lingua[accounts[acc].lang].L Ach_Detail = lingua[accounts[acc].lang].Ach_Detail -- load worlds nworlds = 0 if History_SV["Default"][acc]["$AccountWide"]["worlds"] ~= nil then for i,j in pairs(History_SV["Default"][acc]["$AccountWide"]["worlds"]) do nworlds = nworlds +1 table.insert(accounts[acc].worlds, i) log("World " .. i) end end -- Load Character Data log("Starting player Load.") for playerID, _ in pairs(History_SV["Default"][acc]["$AccountWide"]["data"]) do if playerID == "" then print("Error: account: " .. acc .. " has blank playerID") end log("playerID: " .. playerID) table.insert (accounts[acc].AllplayerIDs, playerID) accounts[acc].player[playerID] = {} -- stub table to hold char data, later becomes "me" -- local me = accounts[acc].player[playerID] -- shorter reference: our code local thischar = History_SV["Default"][acc]["$AccountWide"]["data"][playerID] -- shorter reference: History DB me.visible = true --enable for display -- Pull in some char data for processing if thischar.name == nil then -- Old Format log(print("Old Format " .. playerID)) me.name = playerID else me.name = thischar.name end playerNames[playerID]=me.name log("playerID: " .. playerID .. " is " .. me.name) -- == Gender if thischar.Gender =="M" then me.gender = L.Male elseif thischar.Gender == "F" then me.gender = L.Female end -- ==Level local level = thischar.level me.level = level if (level <=50) then me.levelstr = tostring(level) me.isvet = false else me.levelstr = "V" .. tostring(level -50) me.isvet = true table.insert(accounts[acc].playerIDs_vet,playerID) end -- == Cumulative TimePlayed if thischar.timeplayed == nil then me.timeplayed =0 thischar.timeplayed = 0 else me.timeplayed = math.floor(thischar.timeplayed/60) end -- world if thischar.world == nil then accounts[acc].hasblankworlds = true -- causes display of "##NEITHER## else me.world = thischar.world -- server end -- a quick link to my Achievements me.ach = thischar.ach end table.sort(accounts[acc].AllplayerIDs,function(a,b) return (playerNames[a] < playerNames[b]) end) table.sort(accounts[acc].playerIDs_vet,function(a,b) return (playerNames[a] < playerNames[b]) end) end load_visibility() --[[ ========================================== Iterate over all accounts and PlayerIDs creating display items --]] for acc,_ in pairs (accounts) do -- ==== Accountwide Data -- Setup Log data accounts[acc].logtabs =iup.tabs{} -- Log Display table presentation accounts[acc].logtable = {} accounts[acc].logtable=iup.matrix{numcol=2, numcol_visible=2, numlin=0,numlin_visible=8} accounts[acc].logtable:setcell(0,0, L.TStamp) iup.SetAttribute(accounts[acc].logtable, "ALIGNMENT0", "ACENTER") iup.SetAttribute(accounts[acc].logtable, "ALIGNMENT2", "ALEFT") iup.SetAttribute(accounts[acc].logtable, "WIDTH0", 80) iup.SetAttribute(accounts[acc].logtable, "WIDTH1", 100) iup.SetAttribute(accounts[acc].logtable, "WIDTH2", 300) iup.SetAttribute(accounts[acc].logtable, "READONLY", "YES") -- Load log data local Line=0 local TimeStr = "" accounts[acc].logtable.numlin = Line for _,j in ipairs (History_SV["Default"][acc]["$AccountWide"]["log"]) do Line= Line +1 accounts[acc].logtable.numlin = Line TimeStr = os.date(dateformat_log,j["TimeStamp"]) accounts[acc].logtable:setcell( Line,0, TimeStr) if j["Char"] ~= nil then accounts[acc].logtable:setcell( Line,1, j["Char"]) end accounts[acc].logtable:setcell( Line,2, j["text"]) end -- Setup Log Display accounts[acc].log_tab=iup.vbox { ["tabtitle"] =L.LogTab, accounts[acc].logtable, iup.fill{} } -- Top Level Panels -- accounts[acc].world_zbox = iup.zbox{} -- display main panel containing worlds (servers) -- not used ATM accounts[acc].mode_zbox = iup.zbox{} -- display submain panel containing tabs and dungeons accounts[acc].char_tabs = iup.tabs{} -- Top level of Char_Tabs, Character Info in Here accounts[acc].dung_tabs = iup.tabs{} -- Top level of Dung_Tabs, Dungeon Info in Here iup.Append(accounts[acc].mode_zbox, accounts[acc].char_tabs) detail_name = iup.label {title="",expand = "HORIZONTAL"} detail_desc = iup.label {title="",expand = "HORIZONTAL"} Status_bar = iup.label{title=L.Welcome .. " " .. L.Version .. " " .. version .. ", for update " .. update .. ". Rage Quit Edition. Still Raging.", expand = "HORIZONTAL"} iup.Append(accounts[acc].mode_zbox, accounts[acc].dung_tabs) -- Mode Buttons (Toggles) --[[ These control the display. Char mode lists the characters and information for them (default for prior versions) Dung Mode lists the dungeons and which characters have done them. Buttons are arranged in radio mode --]] accounts[acc].char_tog = iup.toggle{ title = L.Characters} accounts[acc].dung_tog = iup.toggle{ title = L.Dungeons} accounts[acc].filter_but = iup.button{title=L.Filter} local tog = accounts[acc].char_tog function tog:action(x) if x == 1 then accounts[acc].mode_zbox.value =accounts[acc].char_tabs end end tog = accounts[acc].dung_tog function tog:action(x) if x == 1 then accounts[acc].mode_zbox.value = accounts[acc].dung_tabs end end accounts[acc].mode = iup.frame { iup.hbox{ iup.radio { iup.hbox{ accounts[acc].char_tog, accounts[acc].dung_tog, }, }, accounts[acc].filter_but, } } accounts[acc].mode.title = L.Mode accounts[acc].mode.margin = "15x5" accounts[acc].alldungeons = {} -- Prepare for Dungeon data recording as we iterate through characters. accounts[acc].dung = {} -- put all dungeon mode stuff here. Populate it with character data. -- N Normal, V Vet, VH Vet hard mode dung = accounts[acc].dung local button = accounts[acc].filter_but function button:action(x) select_box(accounts[acc]) end -- ================ END Accountwide Data log("Account Wide for Account " .. acc .. " Done") --================= START OF CHARACTER MODE DISPLAY -- Creates boxes, stage from names to allow sorting for _,playerID in ipairs(accounts[acc].AllplayerIDs) do me = accounts[acc].player[playerID] -- shorter reference: our code me.data_tabs = iup.tabs{} --Data tabs for Char thischar = History_SV["Default"][acc]["$AccountWide"]["data"][playerID] -- shorter reference: History DB log("Account " .. acc .. " PlayerID " .. playerID .. ", Leveling Box") -- Generate the leveling box. ============================ me.leveling_box = iup.matrix {numcol=6, numcol_visible=6, widthdef=60} me.leveling_box:setcell(0,1, L.Level) me.leveling_box:setcell(0,2, L.PTime) me.leveling_box:setcell(0,3, L.Start) me.leveling_box:setcell(0,4, L.Deaths) me.leveling_box:setcell(0,5, L.APts) me.leveling_box:setcell(0,6, L.Location) iup.SetAttribute(me.leveling_box, "WIDTH6", "100") iup.SetAttribute(me.leveling_box, "READONLY", "YES") -- levels as stored are unsorted, so create a level table which is sorted, local levels = {} for i,_ in pairs(thischar.levels) do table.insert(levels, i) end table.sort(levels) for i,j in ipairs(levels) do -- traverse in sorted order local timelevel = math.floor(thischar.levels[j].time) me.leveling_box.numlin = i me.leveling_box:setcell(i,1, j) me.leveling_box:setcell(i,2, math.floor(timelevel/60)) me.leveling_box:setcell(i,3, os.date("%Y-%m-%d",thischar.levels[j].begin)) me.leveling_box:setcell(i,4, thischar.levels[j].deaths) me.leveling_box:setcell(i,5, thischar.levels[j].Ach_Points) -- Do we have map name for this level? if thischar.levels[j].map ~= nil then me.leveling_box:setcell(i,6, thischar.levels[j].map) end end dofile "./Prog/make_box.lua" make_a_tab(playerID, dung, accounts[acc], "Public",Pub_Dat_Char) for _,i in ipairs(Trials_Order) do make_a_tab(playerID, dung, accounts[acc], i,Trials_Dat[i]) end for _,i in ipairs(Group_Order) do make_a_tab(playerID, dung, accounts[acc], i,Group_Dat[i]) end make_a_tab(playerID, dung, accounts[acc], "DLC Group" , DLC_Grp_Dat) -- Create Locations Box============================================== me.Map_box= iup.matrix {numcol=6, numcol_visible=6, numlin=0, widthdef=70} me.Map_box:setcell(0,0, L.Location) me.Map_box:setcell(0,1, L.Visits) me.Map_box:setcell(0,2, L.FirstVisited) me.Map_box:setcell(0,3, L.FirstLevel) me.Map_box:setcell(0,4, L.TimesLeveled) me.Map_box:setcell(0,5, L.FirstDeath) me.Map_box:setcell(0,6, L.Deaths) iup.SetAttribute(me.Map_box, "READONLY", "YES") iup.SetAttribute(me.Map_box, "ALIGNMENT0", "ALEFT") iup.SetAttribute(me.Map_box, "WIDTH0", "110") iup.SetAttribute(me.Map_box, "WIDTH1", "40") iup.SetAttribute(me.Map_box, "WIDTH4", "55") iup.SetAttribute(me.Map_box, "WIDTH6", "40") local map_names = {} for map,_ in pairs(thischar.maps) do table.insert(map_names,map) end table.sort(map_names) local Line =1 for _, map in ipairs(map_names) do me.Map_box.numlin = Line me.Map_box:setcell( Line,0, map) if thischar.maps[map].visit ~= nil then me.Map_box:setcell( Line,1, thischar.maps[map].visit) end if thischar.maps[map].firstvisitdate ~= nil then local firstvisit = os.date(dateformat,thischar.maps[map].firstvisitdate) me.Map_box:setcell( Line,2, firstvisit) end if thischar.maps[map].firstlevel ~= nil then me.Map_box:setcell( Line,3, thischar.maps[map].firstlevel) end if thischar.maps[map].timeslevel ~= nil then me.Map_box:setcell( Line,4, thischar.maps[map].timeslevel) end if thischar.maps[map].firstdeathlevel ~= nil then me.Map_box:setcell( Line,5, thischar.maps[map].firstdeathlevel) end if thischar.maps[map].deaths ~= nil then me.Map_box:setcell( Line,6, thischar.maps[map].deaths ) end Line= Line +1 end -- Create WorldBoss Achievements Box========================== log("Starting WB Box") me.WB_box= Location_Box("WB") -- Create SkillQuest Achievements Box========================== log("Starting SQ Box") me.SQ_box= Location_Box("SQ") log("Done SQ Box") --========== DLC me.DLC2 = {} me.DLC2_tabs = iup.flattabs{} -- we add our tabs to here for display. (list of vboxes) local wrap_size = math.floor(250/3.7) -- print ("wrap_size: " .. wrap_size) for i,dlc in ipairs (DLC_Order) do me.DLC2[dlc] = {} me.DLC2[dlc].box = iup.matrixex {READONLY="YES", numcol=4, numcol_visible=4, numlin=#DLC_Dat[dlc].line} iup.SetAttribute(me.DLC2[dlc].box,"WIDTH1", 50) iup.SetAttribute(me.DLC2[dlc].box,"WIDTH2", 130) iup.SetAttribute(me.DLC2[dlc].box,"WIDTH3", 260) --Size is about 1/4 of character iup.SetAttribute(me.DLC2[dlc].box,"ALIGNMENT1", "ACENTER") iup.SetAttribute(me.DLC2[dlc].box,"ALIGNMENT2", "ALEFT") iup.SetAttribute(me.DLC2[dlc].box,"ALIGNMENT3", "ALEFT") iup.SetAttribute(me.DLC2[dlc].box,"ALIGNMENT4", "ALEFT") me.DLC2[dlc].box:setcell(0, 1, L.Ach_ID) me.DLC2[dlc].box:setcell(0, 2, L.Achievement) me.DLC2[dlc].box:setcell(0, 4, L.Completed) me.DLC2[dlc].box.name = dlc2 -- Filter for text on DLC2 me.DLC2[dlc].filter_l = iup.list{editbox="YES", SIZE="80x60"} me.DLC2[dlc].filter_r = iup.list{editbox="YES", SIZE="80x60"} me.DLC2[dlc].filter_tog = iup.toggle{title=L.Filter} me.DLC2[dlc].filter_vet = iup.toggle{title=L.Vet} me.DLC2[dlc].filter_vanq = iup.toggle{title=L.Vanquisher} me.DLC2[dlc].filter_conq = iup.toggle{title=L.Conqueror} me.DLC2[dlc].filter_f = iup.frame { iup.hbox{ me.DLC2[dlc].filter_l, iup.space{size=20}, me.DLC2[dlc].filter_r, iup.space{size=20}, iup.vbox { me.DLC2[dlc].filter_tog, me.DLC2[dlc].filter_vet, me.DLC2[dlc].filter_vanq, me.DLC2[dlc].filter_conq, }, }, } me.DLC2[dlc].filter_f.title = L.Filter me.DLC2[dlc].filter_f.margin = "15x5" me.DLC2[dlc].filter = function (v) -- vi is 1 or 0 for l =1, #DLC_Dat[dlc].line do -- print("Get:" .. me.DLC2[dlc].box:getcell(l, 3)) if v == 1 then if string.find (me.DLC2[dlc].box:getcell(l, 3), L.Vet) ~= nil then iup.SetAttribute(me.DLC2[dlc].box,"VISIBLELIN" .. tostring(l) , "NO") else iup.SetAttribute(me.DLC2[dlc].box,"VISIBLELIN" .. tostring(l) , "YES") end else iup.SetAttribute(me.DLC2[dlc].box,"VISIBLELIN" .. tostring(l) , "YES") end end end local thistog=me.DLC2[dlc].filter_vet function thistog:action(v) me.DLC2[dlc].filter(v) end --Add data for line,id in ipairs(DLC_Dat[dlc].line) do if Ach_Detail[id] == nil then print("Ach id: " .. id .. " in DLC but not in master data.") break end me.DLC2[dlc].box:setcell(line, 1, tostring(id)) me.DLC2[dlc].box:setcell(line, 2, Ach_Detail[id].name) local split = split_w(Ach_Detail[id].description) -- Split into array of words local flow = flow_w(split, wrap_size) -- print(join_s(flow)) -- print("") me.DLC2[dlc].box:setcell(line, 3, join_s(flow)) iup.SetAttribute(me.DLC2[dlc].box,"FITTOTEXT", "L".. tostring(line)) local bgcolour1 = "BGCOLOR" .. tostring(line) .. ":1" --Detail and Description Columns local bgcolour2 = "BGCOLOR" .. tostring(line) .. ":2" local bgcolour3 = "BGCOLOR" .. tostring(line) .. ":3" local bgcolour4 = "BGCOLOR" .. tostring(line) .. ":4" if thischar.ach[id] ~= nil then iup.SetAttribute(me.DLC2[dlc].box, bgcolour1, BG_Colour_Complete) iup.SetAttribute(me.DLC2[dlc].box, bgcolour2, BG_Colour_Complete) iup.SetAttribute(me.DLC2[dlc].box, bgcolour3, BG_Colour_Complete) iup.SetAttribute(me.DLC2[dlc].box, bgcolour4, BG_Colour_Complete) me.DLC2[dlc].box:setcell(line, 4, os.date(dateformat,thischar.ach[id].time)) -- Add char to dungeon -- key = tostring(DLC_Dat.id[id].L .. DLC_Dat.id[id].C) -- dung.DLC.key[key][playerID] = true else iup.SetAttribute(me.DLC2[dlc].box, bgcolour1, BG_Colour_Not_Complete) iup.SetAttribute(me.DLC2[dlc].box, bgcolour2, BG_Colour_Not_Complete) iup.SetAttribute(me.DLC2[dlc].box, bgcolour3, BG_Colour_Not_Complete) iup.SetAttribute(me.DLC2[dlc].box, bgcolour4, BG_Colour_Not_Complete) end end --lines in box -- make a tab out that DLC. me.DLC2[dlc].tab = iup.vbox{ iup.hbox{ me.DLC2[dlc].box, -- me.DLC2[dlc].filter_f, }, iup.fill{} } me.DLC2[dlc].tab.tabtitle=DLC_Names[i] --Check for Special Completion if (DLC_Dat[dlc].complete ~= nil and thischar.ach[DLC_Dat[dlc].complete]) then -- print(me.name .. " Complete.") end iup.Append(me.DLC2_tabs,me.DLC2[dlc].tab) --Accumulate here for display --]] end --==================================== -- == Prepare for the character data display tabs me.tab = iup.vbox{ ["tabtitle"] = me.name, -- This vbox will be a tab and the tab text is this iup.hbox{ --Top Information bar Alignment = "ACENTER", iup.label{title=thischar.world,PADDING="10X0"}, iup.label{title=me.gender, FONT="Times,BOLD,10"}, iup.label{title=thischar.Race .." / ".. thischar.Class, PADDING="10X0", FONT="Times,BOLD,10"}, iup.label{title=thischar.Alliance, PADDING="10X0"}, iup.label{title=L.Level .. ": ".. me.levelstr, PADDING="10X0"}, iup.label{title=L.Created .. os.date(dateformat,thischar.Created), PADDING="10X0"}, iup.label{title=L.LLog .. os.date(dateformat,thischar.LoginTime), PADDING="10X0"}, iup.label{title=L.TPlayed .. me.timeplayed .." " .. L.Hrs}, iup.fill{} }, iup.label{SEPARATOR="HORIZONTAL"} } if me.isvet then --[[ iup.Append(me.data_tabs, iup.vbox { ["tabtitle"] =L.VetDungeon, iup.label{title=L.VetLab,expand="HORIZONTAL"}, me.Vet_box, iup.fill{} }) --]] end iup.Append(me.data_tabs, iup.vbox { ["tabtitle"] =L.Leveling, -- iup.label{title="LevLabel",expand="HORIZONTAL"}, me.leveling_box, iup.fill{} }) iup.Append(me.data_tabs, iup.vbox { ["tabtitle"] =L.Locations, -- iup.label{title="LevLabel",expand="HORIZONTAL"}, me.Map_box, iup.fill{} }) iup.Append(me.data_tabs, iup.vbox { ["tabtitle"] =L.WBosses, iup.label{title=L.WBLab,expand="HORIZONTAL"}, me.WB_box, iup.fill{} }) iup.Append(me.data_tabs, iup.vbox { ["tabtitle"] =L.SkillQuests, iup.label{title=L.SkillLab,expand="HORIZONTAL"}, me.SQ_box, iup.fill{} }) --]] iup.Append(me.data_tabs, iup.vbox { ["tabtitle"] ="DLC2", iup.label{title=L.DLCLab,expand="HORIZONTAL"}, me.DLC2_tabs, iup.fill{}, }) iup.Append(me.tab,me.data_tabs) -- Add Dungeons/Data under the Character iup.Append(accounts[acc].char_tabs,me.tab) -- Add Char tab to Account local wide =((#accounts[acc].AllplayerIDs+1) * 110) if wide < 690 then wide = 690 elseif wide >960 then wide = 960 end accounts[acc].panelsize = tostring(wide) .. "x350" end -- Chars -- Add to end of Characters iup.Append(accounts[acc].char_tabs, accounts[acc].log_tab) --================= END OF CHARACTER MODE DISPLAY --================= START OF DUNGEON MODE DISPLAY -- Generic function for populating dungeon mode boxes populate = function(ADung) -- For the Dungeon Mode Dungeon, process the keys table and set the Box contents. if ADung == nil then print("Populate: ADung is nil") return end if ADung.box == nil then print("Populate: ADung.box is nil") return end ADung.ShowColumn = {} -- Save Column Completion Information -- Set Column Show Information to false for col,playerID in ipairs(accounts[acc].AllplayerIDs) do ADung.ShowColumn[col] = false end -- does that char exist in the keys table. Check by PlayerID for col,playerID in ipairs(accounts[acc].AllplayerIDs) do -- over each char in order -- print("Populate2: " .. "col: " .. col ..", playerID: " .. playerID) for line, Ach in ipairs(ADung.box.dat.id) do local line_bool = ADung.keys[line][playerID] -- print(" Populate: " .. "line " .. line) if line_bool then -- print(" Populate2: " .. "key: " .. key ..", key_bool: true") ADung.box:setcell(line, col, L.YesLabel) iup.SetAttribute(ADung.box,"BGCOLOR" .. tostring(line) .. ":" .. tostring(col), BG_Colour_Complete) else -- print(" Populate2: " .. "key: " .. key ..", key_bool: false") ADung.box:setcell(line,col, L.NoLabel) iup.SetAttribute(ADung.box,"BGCOLOR" .. tostring(line) .. ":" .. tostring(col), BG_Colour_Not_Complete) ADung.ShowColumn[col] = true -- flag entire column as not complete, thus to show it. end end end --Ok, Set the Column Width flag Hide sometimes --And column Heading background Always for col,state in pairs(ADung.ShowColumn) do if state then iup.SetAttribute(ADung.box,"BGCOLOR" .. "0:" .. tostring(col), BG_Colour_Not_Complete) else iup.SetAttribute(ADung.box,"BGCOLOR" .. "0:" .. tostring(col), BG_Colour_Complete) end end end -- Populate dungeons boxes with character data ============================ populate(dung["Public"]) populate(dung["DLC Group"]) for _,i in pairs(Trials_Order) do populate(dung[i]) end for _,i in pairs(Group_Order) do populate(dung[i]) end -- Commented out because we expect all dung to be populated -- if #accounts[acc].playerIDs_vet > 0 then -- skip vet and trials if no eligible chars --end -- has vet chars end -- Accounts table.sort(accounts_list) function select_account() local selected local account if #accounts_list > 1 then selected = iup.ListDialog (1, L.SelectA, #accounts_list, --Size accounts_list, 1, --Initial 1,#accounts_list --MaxCol MaxLine ) if selected <0 then return nil -- Canceled iup.SetAttribute(ADung.box,"BGCOLOR" .. "0:" .. tostring(col), BG_Colour_Not_Complete) else account = accounts_list[selected+1] log("Account " ..account .. " selected.") return account end else account = accounts_list[1] -- only 1 account, no need for Dialog log("Account " ..account .. " selected.") return account end end -- Create dialog to choose account myaccount=select_account() if myaccount ~=nil then -- Create dialog if not cancelled dlg = iup.dialog{iup.vbox{ accounts[myaccount].mode, accounts[myaccount].mode_zbox, detail_name, -- Hover over information detail_desc, Status_bar, -- Bottom Status bar. margin="5x5", ngap="3", }, title=L.title .. myaccount , size=accounts[myaccount].panelsize, } -- Shows dialog in the centre of the screen dlg:showxy(iup.CENTER, iup.CENTER) if (iup.MainLoopLevel()==0) then iup.MainLoop() end end