Advertisement
Happypea

luakt3bosko

Nov 22nd, 2024
215
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 214.77 KB | Gaming | 0 0
  1.  
  2. settingsNotes = "Scoreboard Settings"
  3. dashboardTag = "Kill Team Dashboard"
  4. scoreboardTag = "Kill Team Scoreboard"
  5.  
  6. defaultSettings = [[{
  7.   "packet":{
  8.     "name":"Kill Team",
  9.     "players":[
  10.       "Red",
  11.       "Blue"
  12.     ],
  13.     "streamers":[
  14.       "Black",
  15.       "White"
  16.     ],
  17.     "autoPromote":false
  18.   },
  19.   "scoring":{
  20.     "maxRounds":4,
  21.     "max":18,
  22.     "limitRecordToMax":false,
  23.     "primary":{
  24.       "max":9,
  25.       "maxEach":0,
  26.       "objectives":[
  27.         "Hold 1+",
  28.         "Hold 2+",
  29.         "Hold More"
  30.       ],
  31.       "exclusive":[
  32.         false,
  33.         false,
  34.         true
  35.       ]
  36.     },
  37.     "secondary":{
  38.       "max":9,
  39.       "maxEach":3,
  40.       "objectives":[
  41.         "Attrition",
  42.         "Bounty Hunter",
  43.         "Cut Apart",
  44.         "Cut Off The Head",
  45.         "Death From Afar",
  46.         "Domination",
  47.         "Engage On All Fronts",
  48.         "High-Profile Targets",
  49.         "Proximity Alert",
  50.         "Recon Sweep",
  51.         "Scout the Field",
  52.         "Thin Their Ranks"
  53.       ],
  54.       "maxExemption":{
  55.       }
  56.     },
  57.     "bonus":{
  58.       "max":0,
  59.       "objectives":[
  60.       ]
  61.     }
  62.   },
  63.   "art":{
  64.     "graphics":{
  65.       "eventLogo":null,
  66.       "eventBanner":null,
  67.       "initiative":{
  68.         "Off":"https://steamusercontent-a.akamaihd.net/ugc/1750182972143392609/48283228AFC1906F43CD6D39A402B3DC29EAE371/",
  69.         "On":"https://steamusercontent-a.akamaihd.net/ugc/1750182972143393402/5BE39A862B6C1F71A467892906E21C0CD54C257E/"
  70.       },
  71.       "primary":{
  72.         "Off":"https://steamusercontent-a.akamaihd.net/ugc/1750182972137668614/C48602D532FC7C6974B12FDD1B8C27CC3A9F9C32/",
  73.         "On":"https://steamusercontent-a.akamaihd.net/ugc/1750182972137669364/44345B2435C44D87BB88DB3673E25ED6C4CB7F92/"
  74.       }
  75.     },
  76.     "colors":{
  77.       "lighter":"#9a9a9aff",
  78.       "background":"#555555ff",
  79.       "darker":"#3a3a3aff",
  80.       "darkest":"#000000ff",
  81.       "highlight":"#e74f0aff"
  82.     },
  83.     "gui":{
  84.       "overlay":{
  85.         "logoWidth":128,
  86.         "logoHeight":128
  87.       },
  88.       "scoreboard":{
  89.         "bannerWidth":740,
  90.         "bannerHeight":150,
  91.         "width":750,
  92.         "primaryColumns":3,
  93.         "layFlat":true
  94.       }
  95.     }
  96.   }
  97. }]]
  98. setupMessage = "Performing first time scoreboard setup. You can customize the scoreboard for this map by editing the " .. settingsNotes .. " tab in the notebook."
  99.  
  100. function atrName(s)
  101.   return "kts__" .. s
  102. end
  103.  
  104. function atrPrimary(player, rule, round, k)
  105.   return string.format("kts__primary_player%d_%d_%d_%s", player, rule, round, k)
  106. end
  107.  
  108. function atrInitiative(player, round, k)
  109.   return string.format("kts__initiative_player%d_%d_%s", player, round, k)
  110. end
  111.  
  112. function atrSecondary(player, secondary, k)
  113.   return string.format("kts__secondary_player%d_%d_%s", player, secondary, k)
  114. end
  115.  
  116. paramPlayer = {atrName("player1"), atrName("player2")}
  117.  
  118. players = {}
  119. playerNames = {}
  120. playerNumber = {}
  121.  
  122. dropdowns = {}
  123.  
  124. rules = {}
  125. scoring = {}
  126.  
  127. -- ADDED by ZAKA
  128. -- TODO Add here GUID of MegaDeck
  129. megaDeckGuid = "a2a37e"
  130. oldMegaDeckGuid = "18fcc4"
  131. masterBagOpen = "ebbb8c"
  132. masterBagItd = "ef8c27"
  133. -- TODO for the future -> if faction added, update
  134. imperiumFactions = {
  135.   "Ecclesiarchy",
  136.   "Novitiates",
  137.   "Talons of the Emperor",
  138.   "Forge World",
  139.   "Hunter Clade",
  140.   "Imperial Guard",
  141.   "Veteran Guard",
  142.   "Grey Knights",
  143.   "Space Marines",
  144.   "Phobos Strike Team",
  145.   "Intercession Squad Team",
  146.   "Imperial Navy Breachers",
  147.   "Elucidian Starstriders",
  148.   "Kasrkin",
  149. }
  150. chaosFactions = {
  151.   "Chaos Daemons",
  152.   "Legionary",
  153.   "Traitor Space Marines",
  154.   "Death Guard",
  155.   "Thousand Sons",
  156.   "Warp Coven",
  157.   "Blooded",
  158.   "Gellerpox Infected",
  159. }
  160. xenosFactions = {
  161.   "Brood Coven",
  162.   "Wyrmblade",
  163.   "Tomb World",
  164.   "Greenskins",
  165.   "Kommandos",
  166.   "Cadre Mercenary",
  167.   "Hunter Cadre",
  168.   "Pathfinders",
  169.   "Hive Fleet",
  170.   "Farstalker Kinband",
  171.   "Hierotek Circle",
  172.  
  173. }
  174. aeldariFactions = {
  175.   "Corsair Voidscarred",
  176.   "Craftworlds",
  177.   "Commorites",
  178.   "Troupe",
  179.   "Void-dancer Troupe",
  180. }
  181.  
  182. gameStateMachine = {
  183.   whoToPress="",
  184.   preGame={
  185.     active=true,
  186.   },
  187.   tp1={
  188.     init=false,
  189.     ploys=false,
  190.     tacops=false,
  191.     firefight=false,
  192.     scoring=false
  193.   },
  194.   tp2={
  195.     init=false,
  196.     ploys=false,
  197.     tacops=false,
  198.     firefight=false,
  199.     scoring=false
  200.   },
  201.   tp3={
  202.     init=false,
  203.     ploys=false,
  204.     tacops=false,
  205.     firefight=false,
  206.     scoring=false
  207.   },
  208.   tp4={
  209.     init=false,
  210.     ploys=false,
  211.     tacops=false,
  212.     firefight=false,
  213.     scoring=false
  214.   },
  215.   endGame={
  216.     active=false,
  217.   },
  218. }
  219. checkListPlayer = {
  220.   name = "",
  221.   allow = false,
  222.   superFaction = "Select One",
  223.   faction = "Select One",
  224.   tacOps = false,
  225.   equipment = false,
  226.   barricades = false,
  227.   deployed = false,
  228.   scouting = "Select One",
  229. }
  230. checkListStatus = {
  231.   killZoneLoaded = false,
  232.   allowOW = false,
  233.   gameType = "Open play",
  234.   edition= "KT 2021 - Open",
  235.   mission = "Select One",
  236.   tournament = "Select One",
  237.   rollOffWinner="Select One",
  238.   rollOffAttacker=false,
  239.   rollOffDefender=false,
  240.   revealed=false,
  241.   winner="",
  242. }
  243. result = {}
  244. missionIndexOpen = {}
  245. missionIndexItd = {}
  246. factionsInSuperDeck = {}
  247.  
  248. -- TODO if tournament added, update
  249. tournamentIndex = {
  250.   "III Liga Mercenaria",
  251. }
  252.  
  253. -- TODO if game type added, update
  254. gameTypeIndex = {
  255.   "Open Play",
  256.   "Matched Play",
  257.   "Narrative Play",
  258. }
  259.  
  260. -- TODO if edition added, update
  261. editionIndex = {
  262.   "KT 2021 - Open",
  263.   "KT 2022 - Critical Ops",
  264.   "KT 2022 - Into the Dark",
  265. }
  266.  
  267. -- TODO if mission added, update
  268. missionIndexOpen['8cc4c8'] = {
  269.   code=1.1,
  270.   name="Loot and Salvage",
  271.   objGuid='fef2fe'
  272. }
  273. missionIndexOpen['653576'] = {
  274.   code=1.2,
  275.   name="Consecration",
  276.   objGuid='aa55ae'
  277. }
  278. missionIndexOpen['2da116'] = {
  279.   code=1.3,
  280.   name="Awaken the data Spirits",
  281.   objGuid='6f0b59'
  282. }
  283. missionIndexOpen['cb09ac'] = {
  284.   code=2.1,
  285.   name="Escalating Hostilities",
  286.   objGuid='bcfd2c'
  287. }
  288. missionIndexOpen['ab2f17'] = {
  289.   code=2.2,
  290.   name="Seize Ground",
  291.   objGuid='082875'
  292. }
  293. missionIndexOpen['fd5afd'] = {
  294.   code=2.3,
  295.   name="Domination",
  296.   objGuid='db097f'
  297. }
  298. missionIndexOpen['c50020'] = {
  299.   code=3.1,
  300.   name="Secure Archeotech",
  301.   objGuid='91d284'
  302. }
  303. missionIndexOpen['d03785'] = {
  304.   code=3.2,
  305.   name="Duel of wits",
  306.   objGuid='edd0ad'
  307. }
  308. missionIndexOpen['5ec111'] = {
  309.   code=3.3,
  310.   name="Master the terminals",
  311.   objGuid='2fb4cc'
  312. }
  313. missionIndexItd = {}
  314. --TODO add guids
  315. missionIndexItd["25d8b1"] = {
  316.   code=1.1,
  317.   name="Command station control",
  318.   objGuid='7ce808',
  319.   terrainGuid='02f7ea',
  320.   primary = {
  321.     exclusive = JSON.decode('[false, false, false]'),
  322.     max = 12,
  323.     maxEach = 0,
  324.     objectives = JSON.decode('["1+", "2+", "3+"]')
  325.   },
  326.   bonus = {
  327.     max = 0,
  328.     objectives = JSON.decode('[]')
  329.   }
  330. }
  331. missionIndexItd["574334"] = {
  332.   code=1.2,
  333.   name="Power surge",
  334.   objGuid='65ed51',
  335.   terrainGuid='543851',
  336.   primary = {
  337.     exclusive = JSON.decode('[false, false, false]'),
  338.     max = 12,
  339.     maxEach = 0,
  340.     objectives = JSON.decode('["1+", "2+", "3+"]')
  341.   },
  342.   bonus = {
  343.     max = 0,
  344.     objectives = JSON.decode('[]')
  345.   }
  346. }
  347. missionIndexItd["4bd33e"] = {
  348.   code=1.3,
  349.   name="Supply raid",
  350.   objGuid='03d7e1',
  351.   terrainGuid='af8f16',
  352.   primary = {
  353.     exclusive = JSON.decode('[false]'),
  354.     max = 12,
  355.     maxEach = 0,
  356.     objectives = JSON.decode('["1+"]')
  357.   },
  358.   bonus = {
  359.     max = 8,
  360.     objectives = JSON.decode('["End battle"]')
  361.   }
  362. }
  363. missionIndexItd["e1bd09"] = { --NO first
  364.   code=2.1,
  365.   name="Junction assault",
  366.   objGuid='',
  367.   terrainGuid='b7e8a6',
  368.   primary = {
  369.     exclusive = JSON.decode('[false, false, false, false]'),
  370.     max = 12,
  371.     maxEach = 0,
  372.     objectives = JSON.decode('["1+", "2+", "3+", "4+"]')
  373.   },
  374.   bonus = {
  375.     max = 0,
  376.     objectives = JSON.decode('[]')
  377.   }
  378. }
  379. missionIndexItd["6ad39d"] = {
  380.   code=2.2,
  381.   name="Full-Scale attack",
  382.   objGuid='158e30',
  383.   terrainGuid='180b15',
  384.   primary = {
  385.     exclusive = JSON.decode('[false, false, false, false, false, false]'),
  386.     max = 12,
  387.     maxEach = 0,
  388.     objectives = JSON.decode('["1+", "2+", "3+", "4+", "5+", "6+"]')
  389.   },
  390.   bonus = {
  391.     max = 0,
  392.     objectives = JSON.decode('[]')
  393.   }
  394. }
  395. missionIndexItd["d23b90"] = {
  396.   code=2.3,
  397.   name="Mysterious signature",
  398.   objGuid='d49add',
  399.   terrainGuid='6e6c6b',
  400.   primary = {
  401.     exclusive = JSON.decode('[false]'),
  402.     max = 12,
  403.     maxEach = 0,
  404.     objectives = JSON.decode('["1+"]')
  405.   },
  406.   bonus = {
  407.     max = 6,
  408.     objectives = JSON.decode('["End battle"]')
  409.   }
  410. }
  411. missionIndexItd["451ffb"] = { --NO first
  412.   code=3.1,
  413.   name="Forge stronghold",
  414.   objGuid='ebe98e',
  415.   terrainGuid='e2fb73',
  416.   primary = {
  417.     exclusive = JSON.decode('[false, false, false, false]'),
  418.     max = 12,
  419.     maxEach = 0,
  420.     objectives = JSON.decode('["1+", "2+", "3+", "4+"]')
  421.   },
  422.   bonus = {
  423.     max = 0,
  424.     objectives = JSON.decode('[]')
  425.   }
  426. }
  427. missionIndexItd["72ceb4"] = {
  428.   code=3.2,
  429.   name="Vault plunder",
  430.   objGuid='04420d',
  431.   terrainGuid='00e169',
  432.   primary = {
  433.     exclusive = JSON.decode('[false, false, false, false]'),
  434.     max = 12,
  435.     maxEach = 0,
  436.     objectives = JSON.decode('["1+", "2+", "3+", "4+"]')
  437.   },
  438.   bonus = {
  439.     max = 8,
  440.     objectives = JSON.decode('["End battle"]')
  441.   }
  442. }
  443. missionIndexItd["b3a100"] = {
  444.   code=3.3,
  445.   name="Exposed trove",
  446.   objGuid='49d002',
  447.   terrainGuid='0a6ec7',
  448.   primary = {
  449.     exclusive = JSON.decode('[false, false, false]'),
  450.     max = 12,
  451.     maxEach = 0,
  452.     objectives = JSON.decode('["1+", "2+", "3+"]')
  453.   },
  454.   bonus = {
  455.     max = 4,
  456.     objectives = JSON.decode('["End battle"]')
  457.   }
  458. }
  459. missionSelectedForScoreboard = ""
  460. overwatchTable = {
  461.   checked=false
  462. }
  463.  
  464. function getUIAttribute(id, attr)
  465.   if UI.getAttribute(id, attr) ~= nil then
  466.     return UI.getAttribute(id, attr)
  467.   end
  468.   if self.UI.getAttribute(id, attr) ~= nil then
  469.     return self.UI.getAttribute(id, attr)
  470.   end
  471. end
  472. -- ADDED by ZAKA
  473.  
  474. function showUI(id)
  475.   UI.show(id)
  476.   self.UI.show(id)
  477. end
  478.  
  479. function hideUI(id)
  480.   UI.hide(id)
  481.   self.UI.hide(id)
  482. end
  483.  
  484. function setUIValue(id, value)
  485.   UI.setValue(id, value)
  486.   self.UI.setValue(id, value)
  487. end
  488.  
  489. function setUIAttribute(id, attr, value)
  490.   UI.setAttribute(id, attr, value)
  491.   self.UI.setAttribute(id, attr, value)
  492. end
  493.  
  494. function setUIAttributes(id, data)
  495.   UI.setAttributes(id, data)
  496.   --self.UI.setAttributes(id, data)
  497. end
  498.  
  499. function refresh()
  500.   for p, uiid in pairs(players) do
  501.     local player = Player[p]
  502.     if player.seated then
  503.       playerNames[p] = player.steam_name
  504.       if rules.packet.autoPromote and not (player.host or player.promoted) then
  505.         player.promote()
  506.       end
  507.     else
  508.       playerNames[p] = p
  509.     end
  510.     setUIValue(uiid, playerNames[p])
  511.     setUIValue(uiid.."_streamer", playerNames[p])
  512.     local color = Color.fromString(p)
  513.     local color1 = color:lerp(Color(1, 1, 1), 0.25)
  514.     local color2 = color:lerp(Color(1, 1, 1), 0.6)
  515.     setUIAttribute(uiid.."_panel", "color", "#"..color1:toHex())
  516.     setUIAttribute(uiid.."_panel2", "color", "#"..color2:toHex())
  517.     --ADDED by ZAKA
  518.     setUIValue("kts__red_faction_ui_text", "Red Faction")
  519.     setUIValue("kts__blue_faction_ui_text", "Blue Faction")
  520.     --ADDED by ZAKA
  521.   end
  522.   for pl=1,2 do
  523.     local plscore = scoring[pl]
  524.     for round=1,rules.scoring.maxRounds do
  525.       for rule,_ in pairs(rules.scoring.primary.objectives) do
  526.         setPrimaryUI(pl, rule, round, plscore.primary[rule][round])
  527.       end
  528.       setInitiativeUI(pl, round, plscore.initiative[round])
  529.     end
  530.     for secondary=1,3 do
  531.       local ssec = plscore.secondary[secondary]
  532.       if ssec[1] then setSecondaryObjective(pl, secondary, ssec[1]) end
  533.       refreshSecondaryUI(pl, secondary)
  534.     end
  535.     refreshBonusUI(pl)
  536.     updateScoreUI(pl)
  537.   end
  538.   updateInitiativeUI()
  539. end
  540.  
  541. function onPlayerChangeColor(pc)
  542.   if pc == "Red" or pc == "Blue" then
  543.  
  544.     --ADDED by ZAKA
  545.     if checkListStatus[Player[pc].steam_name] == nil then
  546.       checkListStatus[Player[pc].steam_name] = {
  547.         name = "",
  548.         allow = false,
  549.         superFaction = "Select One",
  550.         faction = "Select One",
  551.         tacOps = false,
  552.         equipment = false,
  553.         barricades = false,
  554.         deployed = false,
  555.         allowOW = false,
  556.         scouting = "Select One",
  557.       }
  558.     end
  559.     if (pc == "Red" and getUIAttribute("kts__blue_roloff_winner_text", "text") ~= Player[pc].steam_name) or
  560.        (pc == "Blue" and getUIAttribute("kts__red_roloff_winner_text", "text") ~= Player[pc].steam_name) then
  561.       setUIAttribute("kts__"..string.lower(pc).."_roloff_winner_text", "text", Player[pc].steam_name)
  562.       setUIAttribute("kts__toggle_"..string.lower(pc).."_accept_text", "text", Player[pc].steam_name)
  563.       setUIAttribute("kts__toggle_"..string.lower(pc).."_tacops_text", "text", Player[pc].steam_name)
  564.       setUIAttribute("kts__toggle_"..string.lower(pc).."_equipment_text", "text", Player[pc].steam_name)
  565.       setUIAttribute("kts__toggle_"..string.lower(pc).."_barricades_text", "text", Player[pc].steam_name)
  566.       setUIAttribute("kts__toggle_"..string.lower(pc).."_deployed_text", "text", Player[pc].steam_name)
  567.       setUIAttribute("kts__toggle_"..string.lower(pc).."_overwatch_funct_text", "text", Player[pc].steam_name)
  568.       setUIAttribute("kts__dropdown_"..string.lower(pc).."_faction_text", "text", "Faction "..Player[pc].steam_name)
  569.     end
  570.     if result[Player[pc].steam_name] == nil then
  571.       result[Player[pc].steam_name] = {}
  572.     end
  573.     result[Player[pc].steam_name].color = pc
  574.   --ADDED by ZAKA
  575.  
  576.     refresh()
  577.   end
  578. end
  579.  
  580. function onPlayerDisconnect(pc)
  581.   refresh()
  582. end
  583.  
  584. function makePrimaryScoreTable()
  585.   local primaryScore = {}
  586.   for k,_ in pairs(rules.scoring.primary.objectives) do
  587.     local scoreRow = {}
  588.     for i=1, rules.scoring.maxRounds do
  589.       scoreRow[i] = false
  590.     end
  591.     primaryScore[k] = scoreRow
  592.   end
  593.   return primaryScore
  594. end
  595.  
  596. function calculatePrimaryScore(pl)
  597.   local plPrimaries = scoring[pl].primary
  598.   local total = 0
  599.   local maxEach = rules.scoring.primary.maxEach
  600.   for k,_ in pairs(rules.scoring.primary.objectives) do
  601.     local orule = plPrimaries[k]
  602.     local ototal = 0
  603.     for v=1, rules.scoring.maxRounds do
  604.       ototal = ototal + (orule[v] and 1 or 0)
  605.     end
  606.     if maxEach > 0 then
  607.       total = total + math.min(ototal, maxEach)
  608.     else
  609.       total = total + ototal
  610.     end
  611.   end
  612.   -- ADDED by ZAKA
  613.   total = total + scoring[pl].secondary[4]
  614.   -- ADDED by ZAKA
  615.   return math.min(total, rules.scoring.primary.max)
  616. end
  617.  
  618. function makeSecondaryScoreTable()
  619.   local secondaryScore = {}
  620.   for i=1,3 do
  621.     secondaryScore[i]={nil, 0}
  622.   end
  623.   secondaryScore[4] = 0
  624.   return secondaryScore
  625. end
  626.  
  627. function makeInitiativeScoreTable()
  628.   local initiative = {}
  629.   for i=1, rules.scoring.maxRounds do
  630.     initiative[i]=false
  631.   end
  632.   return initiative
  633. end
  634.  
  635. function calculateSecondaryScore(pl)
  636.   local plSec = scoring[pl].secondary
  637.   return math.min(
  638.     plSec[1][2] +
  639.     plSec[2][2] +
  640.     plSec[3][2],
  641.     --DELETED by ZAKA +
  642.     --plSec[4],
  643.     --DELETED by ZAKA
  644.     rules.scoring.secondary.max)
  645. end
  646.  
  647. function calculateScore(pl)
  648.   local prime = calculatePrimaryScore(pl)
  649.   local sec = calculateSecondaryScore(pl)
  650.   return math.min(prime + sec, rules.scoring.max), prime, sec
  651. end
  652.  
  653. function resetScoring()
  654.   broadcastToAll("rules updated, resetting score")
  655.  
  656.   scoring = {
  657.     {
  658.       primary=makePrimaryScoreTable(),
  659.       secondary=makeSecondaryScoreTable(),
  660.       initiative=makeInitiativeScoreTable(),
  661.       command=0
  662.     },
  663.     {
  664.       primary=makePrimaryScoreTable(),
  665.       secondary=makeSecondaryScoreTable(),
  666.       initiative=makeInitiativeScoreTable(),
  667.       command=0
  668.     }
  669.   }
  670. end
  671.  
  672. function deepcopy(orig, copies)
  673.     copies = copies or {}
  674.     local orig_type = type(orig)
  675.     local copy
  676.     if orig_type == 'table' then
  677.         if copies[orig] then
  678.             copy = copies[orig]
  679.         else
  680.             copy = {}
  681.             copies[orig] = copy
  682.             for orig_key, orig_value in next, orig, nil do
  683.                 copy[deepcopy(orig_key, copies)] = deepcopy(orig_value, copies)
  684.             end
  685.             setmetatable(copy, deepcopy(getmetatable(orig), copies))
  686.         end
  687.     else -- number, string, boolean, etc
  688.         copy = orig
  689.     end
  690.     return copy
  691. end
  692.  
  693. function deepcompare(t1,t2,ignore_mt)
  694.   local ty1 = type(t1)
  695.   local ty2 = type(t2)
  696.   if ty1 ~= ty2 then return false end
  697.   -- non-table types can be directly compared
  698.   if ty1 ~= 'table' and ty2 ~= 'table' then return t1 == t2 end
  699.   -- as well as tables which have the metamethod __eq
  700.   local mt = getmetatable(t1)
  701.   if not ignore_mt and mt and mt.__eq then return t1 == t2 end
  702.   for k1,v1 in pairs(t1) do
  703.     local v2 = t2[k1]
  704.     if v2 == nil or not deepcompare(v1,v2) then return false end
  705.   end
  706.   for k2,v2 in pairs(t2) do
  707.     local v1 = t1[k2]
  708.     if v1 == nil or not deepcompare(v1,v2) then return false end
  709.   end
  710.   return true
  711. end
  712.  
  713. function setup(settings)
  714.  
  715.   if not deepcompare(settings, rules, true) then
  716.     local player1 = settings.packet.players[1]
  717.     local player2 = settings.packet.players[2]
  718.  
  719.     players[player1] = paramPlayer[1]
  720.     players[player2] = paramPlayer[2]
  721.     playerNumber[player1] = 1
  722.     playerNumber[player2] = 2
  723.     rules = settings
  724.     resetScoring()
  725.   end
  726. end
  727.  
  728. function buildScoreBanner(x, y, w, h)
  729.   local ch = {}
  730.   if rules.art.graphics.eventBanner then
  731.     ch = {{
  732.       tag="Image",
  733.       attributes={
  734.         image="eventBanner",
  735.         height=h
  736.       }
  737.     }}
  738.   else
  739.     ch = {{
  740.       tag="Text",
  741.       attributes={
  742.         class="title"
  743.       },
  744.       value=rules.packet.name
  745.     }}
  746.   end
  747.   return {
  748.     tag="Panel",
  749.     attributes={
  750.       class="bkgPanel",
  751.       rectAlignment="UpperCenter",
  752.       width = w,
  753.       height = h,
  754.       offsetXY = string.format("%f %f", tostring(x), tostring(y))
  755.     },
  756.     children=ch
  757.   }
  758. end
  759.  
  760. function buildNameplate(x, y, w, h, player)
  761.   local playerc = rules.packet.players[player]
  762.   local ch = {{
  763.     tag="Text",
  764.     attributes={
  765.       class="steamName",
  766.       id=paramPlayer[player],
  767.       color= string.format("#%s", Color.fromString(playerc):toHex())
  768.     },
  769.     value=playerc
  770.   }}
  771.   return {
  772.     tag="Panel",
  773.     attributes={
  774.       class="bkgPanel",
  775.       rectAlignment="UpperLeft",
  776.       width = w,
  777.       height = h,
  778.       offsetXY = string.format("%f %f", tostring(x), tostring(y))
  779.     },
  780.     children=ch
  781.   }
  782. end
  783.  
  784. function insertPrimaryCel(t, x, y, w, h, rule, round, player)
  785.   table.insert(t,{
  786.         tag="Panel",
  787.         attributes={
  788.           rectAlignment="UpperLeft",
  789.           width = w,
  790.           height = h,
  791.           offsetXY = string.format("%f %f", tostring(x), tostring(y))
  792.         },
  793.         children={
  794.           {
  795.             tag="Text",
  796.             attributes={
  797.               rectAlignment="UpperLeft",
  798.               width = w,
  799.               height = 32,
  800.               offsetXY = "0 0"
  801.             },
  802.             value=rules.scoring.primary.objectives[rule]
  803.           },
  804.           {
  805.             tag="Image",
  806.             attributes={
  807.               onClick="onPrimaryPressed",
  808.               id=atrPrimary(player, rule, round,"toggle"),
  809.               rectAlignment="UpperCenter",
  810.               class="scoreToggle",
  811.               width=w,
  812.               height=h - 36,
  813.               offsetXY= string.format("0 %f", tostring(-32))
  814.             }
  815.           }
  816.         }
  817.       } )
  818. end
  819.  
  820. function insertRoundPrimaries(ch, x, y, w, round, player, gap)
  821.   local objs = #rules.scoring.primary.objectives
  822.   local cols = math.min(objs, rules.art.gui.scoreboard.primaryColumns)
  823.   local rows = math.ceil(objs/cols)
  824.   local celw = math.floor(w/cols)
  825.   local celh = 100
  826.   local pch = {}
  827.   local h = celh * rows
  828.  
  829.   for i=1,rows do
  830.     local rcols = math.min(cols, objs-(i-1)*cols)
  831.     local rofs = (cols - rcols)*celw*0.5
  832.     for j=1,rcols do
  833.       local rule = ((i-1)*cols + j)
  834.         if round > 1 then
  835.           insertPrimaryCel(pch, celw*(j-1) + rofs, -celh*(i-1), celw, celh, rule, round, player)
  836.         else
  837.           break
  838.         end
  839.     end
  840.   end
  841.  
  842.   table.insert(ch, {
  843.     tag="Panel",
  844.     attributes={
  845.       class="bkgPanel",
  846.       rectAlignment="UpperLeft",
  847.       width = w,
  848.       height = h,
  849.       offsetXY = string.format("%f %f", tostring(x), tostring(y))
  850.     },
  851.     children=pch
  852.   })
  853.   return h
  854. end
  855.  
  856. function buildPrimaryRow(t, uy, x, y, w, round, gap)
  857.   local ch={}
  858.   local primaryHeight = insertRoundPrimaries(ch, 0, 0, (w-gap)/2, round, 1)
  859.   local h=primaryHeight
  860.   insertRoundPrimaries(ch, (w-gap)/2 + gap, 0, (w-gap)/2, round, 2)
  861.   table.insert(t, {
  862.     tag="Panel",
  863.     attributes={
  864.       rectAlignment="UpperLeft",
  865.       width = w,
  866.       height = h,
  867.       offsetXY = string.format("%f %f", tostring(x), tostring(y-uy))
  868.     },
  869.     children=ch
  870.   })
  871.   return h + uy-y
  872. end
  873.  
  874. function buildInitiativeRow(t, uy, x, y, w, h, round)
  875.   table.insert(t, {
  876.     tag="Panel",
  877.     attributes={
  878.       rectAlignment="UpperLeft",
  879.       width = w,
  880.       height = h,
  881.       offsetXY = string.format("%f %f", tostring(x), tostring(y-uy))
  882.     },
  883.     children={
  884.       {
  885.         tag="Panel",
  886.         attributes={
  887.           class="bkgPanel",
  888.           width=130,
  889.           height=h
  890.         },
  891.         children={
  892.           {
  893.             tag="Text",
  894.             attributes={
  895.               class="title2"
  896.             },
  897.             value=string.format("Round %d initiative", round)
  898.           }
  899.         }
  900.       },
  901.       {
  902.         tag="Image",
  903.         attributes={
  904.           class="initiativeToggle",
  905.           onClick="onInitiativePressed",
  906.           id=atrInitiative(1, round, "toggle"),
  907.           width=h*0.75, height=h*0.75,
  908.           offsetXY = string.format("%f 0", -w/4)
  909.         }
  910.       },
  911.       {
  912.         tag="Image",
  913.         attributes={
  914.           class="initiativeToggle",
  915.           onClick="onInitiativePressed",
  916.           id=atrInitiative(2, round, "toggle"),
  917.           width=h*0.75, height=h*0.75,
  918.           offsetXY = string.format("%f 0", w/4)
  919.         }
  920.       }
  921.     }
  922.   })
  923.   return uy-y + h
  924. end
  925.  
  926. function buildPrimaryTotalRow(t, uy, x, y, w, h)
  927.   table.insert(t, {
  928.     tag="Panel",
  929.     attributes={
  930.       rectAlignment="UpperLeft",
  931.       width = w,
  932.       height = h,
  933.       offsetXY = string.format("%f %f", tostring(x), tostring(y-uy))
  934.     },
  935.     children={
  936.       {
  937.         tag="Panel",
  938.         attributes={
  939.           class="bkgPanel",
  940.           width=130,
  941.           height=h
  942.         },
  943.         children={
  944.           {
  945.             tag="Text",
  946.             attributes={
  947.               class="title2"
  948.             },
  949.             value="Primary total"
  950.           }
  951.         }
  952.       },
  953.       {
  954.         tag="Text",
  955.         attributes={
  956.           class="title2",
  957.           fontSize=h*0.75,
  958.           id="kts__primarytotal_player1",
  959.           offsetXY = string.format("%f 0", -w/4)
  960.         },
  961.         value=string.format("0/%d", rules.scoring.primary.max)
  962.       },
  963.       {
  964.         tag="Text",
  965.         attributes={
  966.           class="title2",
  967.           fontSize=h*0.75,
  968.           id="kts__primarytotal_player2",
  969.           offsetXY = string.format("%f 0", w/4)
  970.         },
  971.         value=string.format("0/%d", rules.scoring.primary.max)
  972.       }
  973.     }
  974.   })
  975.   return uy-y+h
  976. end
  977.  
  978. function optionsFor(t, def, id)
  979.   local ddo = {}
  980.   local ddid = {}
  981.   local opt = {
  982.     {
  983.       tag="Option",
  984.       attributes={
  985.         selected=true
  986.       },
  987.       value=def
  988.     }
  989.   }
  990.  
  991.   for k, v in pairs(t) do
  992.     table.insert(opt, {
  993.       tag="Option",
  994.       value=v
  995.     })
  996.     ddo[v] = k
  997.     ddid[k] = id..k
  998.   end
  999.  
  1000.   dropdowns[id] = {
  1001.     items=ddo,
  1002.     ids=ddid,
  1003.     selected=1
  1004.   }
  1005.  
  1006.   return opt
  1007. end
  1008.  
  1009.  
  1010. function buildSecondarySelector(ch, uy, x, y, w, player, sec)
  1011.   local h = 90
  1012.   local dd = atrSecondary(player, sec, "dropdown")
  1013.   local cch = {
  1014.     {
  1015.       tag="Dropdown",
  1016.       attributes={
  1017.         onValueChanged="onSecondarySelected",
  1018.         id=dd,
  1019.         rectAlignment="UpperLeft",
  1020.         width=w,
  1021.         height=40,
  1022.         itemHeight=40
  1023.       },
  1024.       children=optionsFor(rules.scoring.secondary.objectives, "Hidden Secondary", dd)
  1025.     },
  1026.     {
  1027.       tag="Text",
  1028.       attributes={
  1029.         class="title2",
  1030.         id=atrSecondary(player, sec, "display"),
  1031.         rectAlignment="UpperLeft",
  1032.         width=w,
  1033.         height=40,
  1034.         active=false
  1035.       },
  1036.       value="u cant see this"
  1037.     },
  1038.     {
  1039.       tag="Text",
  1040.       attributes={
  1041.         class="title2",
  1042.         id=atrSecondary(player, sec, "amount"),
  1043.         rectAlignment="LowerCenter",
  1044.         width=w,
  1045.         height=40
  1046.       },
  1047.       value="0"
  1048.     },
  1049.     {
  1050.       tag="Button",
  1051.       attributes={
  1052.         id=atrSecondary(player, sec, "button_plus"),
  1053.         onClick="onIncreaseSecondary",
  1054.         width=80, height=32,
  1055.         fontSize=28,
  1056.         rectAlignment="LowerRight",
  1057.         offsetXY="-4 4",
  1058.         text="+"
  1059.       }
  1060.     },
  1061.     {
  1062.       tag="Button",
  1063.       attributes={
  1064.         id=atrSecondary(player, sec, "button_minus"),
  1065.         onClick="onDecreaseSecondary",
  1066.         width=80, height=32,
  1067.         fontSize=28,
  1068.         rectAlignment="LowerLeft",
  1069.         offsetXY="4 4",
  1070.         text="-"
  1071.       }
  1072.     }
  1073.   }
  1074.  
  1075.   table.insert(ch, {
  1076.     tag="Panel",
  1077.     attributes={
  1078.       rectAlignment="UpperLeft",
  1079.       width = w,
  1080.       height = h,
  1081.       offsetXY = string.format("%f %f", tostring(x), tostring(y-uy))
  1082.     },
  1083.     children=cch
  1084.   })
  1085.   return uy-y+h
  1086. end
  1087.  
  1088. function buildSecondaryCel(ch, uy, x, y, w, player)
  1089.   local h = 4
  1090.   local cch = {}
  1091.   for i=1,1 do
  1092.     h = buildSecondarySelector(cch, h, 4, 0, w-8, player, i) + 4
  1093.   end
  1094.  
  1095.   table.insert(ch, {
  1096.     tag="Panel",
  1097.     attributes={
  1098.       class="bkgPanel",
  1099.       rectAlignment="UpperLeft",
  1100.       width = w,
  1101.       height = h,
  1102.       offsetXY = string.format("%f %f", tostring(x), tostring(y-uy))
  1103.     },
  1104.     children=cch
  1105.   })
  1106.   return uy-y+h
  1107. end
  1108.  
  1109. function buildSecondaryRow(ch, uy, x, y, w)
  1110.   local cch = {}
  1111.   local celw = (w-4)/2
  1112.   local h = buildSecondaryCel(cch, 0, 0, 0, celw, 1)
  1113.   buildSecondaryCel(cch, 0, celw+4, 0, celw, 2)
  1114.  
  1115.   table.insert(ch, {
  1116.     tag="Panel",
  1117.     attributes={
  1118.       rectAlignment="UpperLeft",
  1119.       width=w,
  1120.       height=h,
  1121.       offsetXY = string.format("%f %f", tostring(x), tostring(y-uy))
  1122.     },
  1123.     children=cch
  1124.   })
  1125.  
  1126.   return uy-y+h
  1127. end
  1128.  
  1129. function buildBonusRow(ch, uy, x, y, w)
  1130.   local h = 160
  1131.   local sliderw = (w-8)/2-4
  1132.   local dd = "ktw__bonus_dropdown"
  1133.   local cch = {
  1134.     --ADDED by ZAKA
  1135.     {
  1136.       tag="Panel",
  1137.       attributes={
  1138.         class="bkgPanel",
  1139.         width=130,
  1140.         height=60,
  1141.         rectAlignment="UpperCenter",
  1142.       },
  1143.       children={
  1144.         {
  1145.           tag="Text",
  1146.           attributes={
  1147.             class="title2",
  1148.             rectAlignment="MiddleCenter",
  1149.           },
  1150.           value="End of the battle"
  1151.         }
  1152.       }
  1153.     },
  1154.     --ADDED by ZAKA
  1155.     --DELETED by ZAKA
  1156.     --{
  1157.     --  tag="Dropdown",
  1158.     --  attributes={
  1159.     --    rectAlignment="UpperCenter",
  1160.     --    id=dd,
  1161.     --    width=w/2,
  1162.     --    height=40,
  1163.     --    itemHeight=40,
  1164.     --    offsetXY="0 -4"
  1165.     --  },
  1166.     --  children=optionsFor(rules.scoring.bonus.objectives, "Select bonus objective...", dd)
  1167.     --},
  1168.     --DELETED by ZAKA
  1169.     {
  1170.       tag="Panel",
  1171.       attributes={
  1172.         rectAlignment="LowerLeft",
  1173.         --rectAlignment="MiddleLeft",
  1174.         width=sliderw,
  1175.         height=80,
  1176.         offsetXY="4 4"
  1177.       },
  1178.       children={
  1179.         {
  1180.           tag="Text",
  1181.           attributes={
  1182.             class="title2",
  1183.             id="kts__bonus_display_player1",
  1184.             --rectAlignment="LowerCenter",
  1185.             rectAlignment="MiddleCenter",
  1186.             width=w,
  1187.             height=40
  1188.           },
  1189.           value="0"
  1190.         },
  1191.         {
  1192.           tag="Button",
  1193.           attributes={
  1194.             id="kts__bonus_increase_player1",
  1195.             onClick="onIncreaseBonus",
  1196.             width=80, height=32,
  1197.             fontSize=28,
  1198.             --rectAlignment="LowerRight",
  1199.             rectAlignment="MiddleRight",
  1200.             offsetXY="-4 4",
  1201.             text="+"
  1202.           }
  1203.         },
  1204.         {
  1205.           tag="Button",
  1206.           attributes={
  1207.             id="kts__bonus_decrease_player1",
  1208.             onClick="onDecreaseBonus",
  1209.             width=80, height=32,
  1210.             fontSize=28,
  1211.             --rectAlignment="LowerLeft",
  1212.             rectAlignment="MiddleLeft",
  1213.             offsetXY="4 4",
  1214.             text="-"
  1215.           }
  1216.         }
  1217.       }
  1218.     },
  1219.     {
  1220.       tag="Panel",
  1221.       attributes={
  1222.         rectAlignment="LowerRight",
  1223.         --rectAlignment="MiddleRight",
  1224.         width=sliderw,
  1225.         height=80,
  1226.         offsetXY="-4 4"
  1227.       },
  1228.       children={
  1229.         {
  1230.           tag="Text",
  1231.           attributes={
  1232.             class="title2",
  1233.             id="kts__bonus_display_player2",
  1234.             --rectAlignment="LowerCenter",
  1235.             rectAlignment="MiddleCenter",
  1236.             width=w,
  1237.             height=40
  1238.           },
  1239.           value="0"
  1240.         },
  1241.         {
  1242.           tag="Button",
  1243.           attributes={
  1244.             id="kts__bonus_increase_player2",
  1245.             onClick="onIncreaseBonus",
  1246.             width=80, height=32,
  1247.             fontSize=28,
  1248.             --rectAlignment="LowerRight",
  1249.             rectAlignment="MiddleRight",
  1250.             offsetXY="-4 4",
  1251.             text="+"
  1252.           }
  1253.         },
  1254.         {
  1255.           tag="Button",
  1256.           attributes={
  1257.             id="kts__bonus_decrease_player2",
  1258.             onClick="onDecreaseBonus",
  1259.             width=80, height=32,
  1260.             fontSize=28,
  1261.             --rectAlignment="LowerLeft",
  1262.             rectAlignment="MiddleLeft",
  1263.             offsetXY="4 4",
  1264.             text="-"
  1265.           }
  1266.         }
  1267.       }
  1268.     }
  1269.   }
  1270.   --ADDED by ZAKA
  1271.   table.insert(ch, {
  1272.     tag="Panel",
  1273.     attributes={
  1274.       rectAlignment="UpperLeft",
  1275.       width=w,
  1276.       height=h,
  1277.       offsetXY = string.format("%f %f", tostring(x), tostring(y-uy))
  1278.     },
  1279.     children=cch
  1280.   })
  1281.   --ADDED by ZAKA
  1282.   --DELETED by ZAKA
  1283.   --table.insert(ch, {
  1284.   --  tag="Panel",
  1285.   --  attributes={
  1286.   --    class="bkgPanel",
  1287.   --    rectAlignment="UpperLeft",
  1288.   --    width=w,
  1289.   --    height=h,
  1290.   --    offsetXY = string.format("%f %f", tostring(x), tostring(y-uy))
  1291.   --  },
  1292.   --  children=cch
  1293.   --})
  1294.   --DELETED by ZAKA
  1295.   return uy-y+h
  1296. end
  1297.  
  1298. function buildSecondaryTotalRow(ch, uy, x, y, w)
  1299.   local h = 60
  1300.   table.insert(ch, {
  1301.     tag="Panel",
  1302.     attributes={
  1303.       rectAlignment="UpperLeft",
  1304.       width = w,
  1305.       height = h,
  1306.       offsetXY = string.format("%f %f", tostring(x), tostring(y-uy))
  1307.     },
  1308.     children={
  1309.       {
  1310.         tag="Panel",
  1311.         attributes={
  1312.           class="bkgPanel",
  1313.           width=130,
  1314.           height=h
  1315.         },
  1316.         children={
  1317.           {
  1318.             tag="Text",
  1319.             attributes={
  1320.               class="title2"
  1321.             },
  1322.             value="Secondary total"
  1323.           }
  1324.         }
  1325.       },
  1326.       {
  1327.         tag="Text",
  1328.         attributes={
  1329.           class="title2",
  1330.           fontSize=h*0.75,
  1331.           id="kts__secondarytotal_player1",
  1332.           offsetXY = string.format("%f 0", -w/4)
  1333.         },
  1334.         value=string.format("0/%d", rules.scoring.secondary.max)
  1335.       },
  1336.       {
  1337.         tag="Text",
  1338.         attributes={
  1339.           class="title2",
  1340.           fontSize=h*0.75,
  1341.           id="kts__secondarytotal_player2",
  1342.           offsetXY = string.format("%f 0", w/4)
  1343.         },
  1344.         value=string.format("0/%d", rules.scoring.secondary.max)
  1345.       }
  1346.     }
  1347.   })
  1348.   return uy-y+h
  1349. end
  1350.  
  1351. function buildGrandTotalRow(ch, uy, x, y, w)
  1352.   local h = 130
  1353.   table.insert(ch, {
  1354.     tag="Panel",
  1355.     attributes={
  1356.       rectAlignment="UpperLeft",
  1357.       width = w,
  1358.       height = h,
  1359.       offsetXY = string.format("%f %f", x, y-uy)
  1360.     },
  1361.     children={
  1362.       {
  1363.         tag="Panel",
  1364.         attributes={
  1365.           class="bkgPanel",
  1366.           width=130,
  1367.           outline=rules.art.colors.highlight,
  1368.           outlineSize="3 -3",
  1369.           offsetXY="-70, 0",
  1370.           height=h
  1371.         },
  1372.         children={
  1373.           {
  1374.             tag="Text",
  1375.             attributes={
  1376.               id="kts__grandtotal_player1",
  1377.               class="finalScore",
  1378.               fontSize=100
  1379.             },
  1380.             value="0"
  1381.           },
  1382.           {
  1383.             tag="Text",
  1384.             attributes={
  1385.               id="kts__grandtotal_max_player1",
  1386.               class="finalScore",
  1387.               fontSize=50,
  1388.               offsetXY="-163 0",
  1389.               active=false
  1390.             },
  1391.             value="MAX"
  1392.           }
  1393.         }
  1394.       },
  1395.       {
  1396.         tag="Panel",
  1397.         attributes={
  1398.           class="bkgPanel",
  1399.           width=130,
  1400.           outline=rules.art.colors.highlight,
  1401.           outlineSize="3 -3",
  1402.           offsetXY="70, 0",
  1403.           height=h
  1404.         },
  1405.         children={
  1406.           {
  1407.             tag="Text",
  1408.             attributes={
  1409.               id="kts__grandtotal_player2",
  1410.               class="finalScore",
  1411.               fontSize=100
  1412.             },
  1413.             value="0"
  1414.           },
  1415.           {
  1416.             tag="Text",
  1417.             attributes={
  1418.               id="kts__grandtotal_max_player2",
  1419.               class="finalScore",
  1420.               fontSize=50,
  1421.               offsetXY="163 0",
  1422.               active=false
  1423.             },
  1424.             value="MAX"
  1425.           }
  1426.         }
  1427.       }
  1428.     }
  1429.   })
  1430.   return uy-y+h
  1431. end
  1432.  
  1433. function buildScoreboard(def)
  1434.   local ch = {}
  1435.   local uiHeight = 0
  1436.   local uiPanelWidth = rules.art.gui.scoreboard.width
  1437.   local uiWidth = uiPanelWidth-10
  1438.   local halfPanel = (uiWidth-4)/2
  1439.   local bannerHeight = rules.art.gui.scoreboard.bannerHeight or 150
  1440.   local bannerWidth = rules.art.gui.scoreboard.bannerWidth or uiWidth
  1441.  
  1442.   --start ui parts
  1443.   table.insert(ch, buildScoreBanner(0,-5,bannerWidth, bannerHeight))
  1444.   uiHeight = uiHeight + bannerHeight + 10
  1445.  
  1446.  
  1447.   table.insert(ch, buildNameplate(5, -uiHeight, halfPanel, 60, 1))
  1448.   table.insert(ch, buildNameplate(halfPanel+9, -uiHeight, halfPanel, 60, 2))
  1449.   uiHeight = uiHeight + 64
  1450.  
  1451.   for round=1, rules.scoring.maxRounds do
  1452.     uiHeight = buildInitiativeRow(ch, uiHeight, 5, 0, uiWidth, 60, round, 4) + 4
  1453.     --ADDED by ZAKA
  1454.     if missionSelectedForScoreboard == "e1bd09" or missionSelectedForScoreboard == "451ffb" then
  1455.       if round > 1 then
  1456.         uiHeight = buildPrimaryRow(ch, uiHeight, 5, 0, uiWidth, round, 4) + 4
  1457.       end
  1458.     else
  1459.       uiHeight = buildPrimaryRow(ch, uiHeight, 5, 0, uiWidth, round, 4) + 4
  1460.     end
  1461.     --ADDED by ZAKA
  1462.  
  1463.     --DELETED by ZAKA
  1464.     --uiHeight = buildPrimaryRow(ch, uiHeight, 5, 0, uiWidth, round, 4) + 4
  1465.     --DELETED by ZAKA
  1466.   end
  1467.   --ADDED by ZAKA
  1468.   if #rules.scoring.bonus.objectives > 0 then
  1469.     uiHeight = buildBonusRow(ch, uiHeight, 5, 0, uiWidth)
  1470.   end
  1471.   --ADDED by ZAKA
  1472.   uiHeight = buildPrimaryTotalRow(ch, uiHeight, 5, -5, uiWidth, 60) + 9
  1473.  
  1474.   uiHeight = buildSecondaryRow(ch, uiHeight, 5, 0, uiWidth) + 4
  1475.  
  1476.   -- DELETED by ZAKA
  1477.   --if #rules.scoring.bonus.objectives > 0 then
  1478.   --  uiHeight = buildBonusRow(ch, uiHeight, 5, 0, uiWidth)
  1479.   --end
  1480.   -- DELETED by ZAKA
  1481.  
  1482.   uiHeight = buildSecondaryTotalRow(ch, uiHeight, 5, -5, uiWidth) + 9
  1483.   uiHeight = buildGrandTotalRow(ch, uiHeight, 5, 0, uiWidth) + 5
  1484.  
  1485.   local uiHalf = uiHeight/2
  1486.   local rotation
  1487.   local position
  1488.   if rules.art.gui.scoreboard.layFlat then
  1489.     rotation="0 0 180"
  1490.     position="0 0 -15"
  1491.   else
  1492.     rotation="45 0 180"
  1493.     position="0 0 -"..(math.sqrt((uiHalf*uiHalf)/2) + 150)
  1494.   end
  1495.   local xmt = {
  1496.     def,
  1497.     {
  1498.       tag="Panel",
  1499.       attributes={
  1500.         class="mainPanel",
  1501.         active=true,
  1502.         width=uiPanelWidth,
  1503.         height=uiHeight,
  1504.         rotation=rotation,
  1505.         position=position
  1506.       },
  1507.       children=ch
  1508.     }
  1509.   }
  1510.   self.UI.setXmlTable(xmt)
  1511. end
  1512.  
  1513. function buildDashboard(target, def)
  1514.   local dbCont = {}
  1515.   target.UI.setXmlTable({
  1516.     def,
  1517.     {
  1518.       tag="Panel",
  1519.       attributes={
  1520.         color=rules.art.colors.darker,
  1521.         width=1920,
  1522.         height=1080,
  1523.         scale="-0.33 0.33 0.33",
  1524.         rotation="20 0 180",
  1525.         position="0 -300 -100"
  1526.       },
  1527.       children=dbCont
  1528.     }
  1529.   })
  1530. end
  1531.  
  1532. function asd(typ, atr, cls)
  1533.   local atr = atr
  1534.   if cls then atr.class = cls end
  1535.   return {
  1536.     tag=typ,
  1537.     attributes=atr
  1538.   }
  1539. end
  1540.  
  1541. function makeDefaults(settings)
  1542.   local colors = settings.art.colors
  1543.  
  1544.   return {
  1545.     tag="Defaults",
  1546.     children={
  1547.       asd("Image", {
  1548.         raycastTarget=false,
  1549.         preserveAspect=true
  1550.       }),
  1551.       asd("Text", {
  1552.         fontSize=16,
  1553.         color=colors.lighter
  1554.       }),
  1555.       asd("Dropdown", {
  1556.         fontSize=24,
  1557.         color=colors.background,
  1558.         textColor=colors.lighter
  1559.       }),
  1560.       asd("Panel", {
  1561.         color=colors.darker
  1562.       }, "mainPanel"),
  1563.       asd("Panel", {
  1564.         color=colors.background
  1565.       }, "bkgPanel"),
  1566.       asd("Text", {
  1567.         fontSize=80,
  1568.         fontStyle="BoldAndItalic"
  1569.       }, "title"),
  1570.       asd("Text", {
  1571.         fontSize=24,
  1572.         fontStyle="Bold"
  1573.       }, "title2"),
  1574.       asd("Text", {
  1575.         resizeTextForBestFit=true,
  1576.         fontStyle="Bold",
  1577.         color=colors.highlight,
  1578.         outline=colors.darker
  1579.       }, "steamName"),
  1580.       asd("Text", {
  1581.         fontStyle="Bold",
  1582.         color=colors.highlight,
  1583.         outline=colors.darker
  1584.       }, "finalScore"),
  1585.       asd("Image", {
  1586.         raycastTarget=true,
  1587.         type="Simple",
  1588.         image="primaryOff"
  1589.       }, "scoreToggle"),
  1590.       asd("Image", {
  1591.         raycastTarget=true,
  1592.         tooltipPosition="Above",
  1593.         type="Simple",
  1594.         image="primaryOff"
  1595.       }, "streamerScore"),
  1596.       asd("Image", {
  1597.         raycastTarget=true,
  1598.         type="Simple",
  1599.         image="initiativeOff"
  1600.       }, "initiativeToggle"),
  1601.       asd("Image", {
  1602.         type="Simple",
  1603.         image="initiativeOff"
  1604.       }, "streamerInitiative"),
  1605.       asd("Button", {
  1606.         textColor=colors.darkest,
  1607.         color=colors.background
  1608.       }),
  1609.       asd("Image", {
  1610.         type="Simple",
  1611.         image="initiativeOn",
  1612.         showAnimation="Grow",
  1613.         hideAnimation="Shrink",
  1614.         active=false
  1615.       }, "initiativeDisplay")
  1616.     }
  1617.   }
  1618. end
  1619.  
  1620. function makeAsset(assets, n, u)
  1621.   table.insert(assets,{
  1622.     name=n,
  1623.     url=u
  1624.   })
  1625. end
  1626.  
  1627. function makeAssetButton(assets, graphics, name)
  1628.   for n, u in pairs(graphics[name]) do
  1629.     makeAsset(assets, name..n, u)
  1630.   end
  1631. end
  1632.  
  1633. --[[function debugLogUI(ui, level)
  1634.   local level = level or 0
  1635.   for _,e in pairs(ui) do
  1636.     local id = ""
  1637.     if e.attributes and e.attributes.id then
  1638.       id = e.attributes.id
  1639.     end
  1640.     log(string.rep("  ", level)..e.tag.." "..id)
  1641.     if e.children then
  1642.       debugLogUI(e.children, level + 1)
  1643.     end
  1644.   end
  1645. end]]
  1646.  
  1647. function loadAssets(graphics)
  1648.   local assets = {}
  1649.   if graphics.eventLogo then
  1650.     makeAsset(assets, "eventLogo", graphics.eventLogo)
  1651.   end
  1652.  
  1653.   if graphics.eventBanner then
  1654.     makeAsset(assets, "eventBanner", graphics.eventBanner)
  1655.   end
  1656.  
  1657.   makeAssetButton(assets, graphics, "initiative")
  1658.   makeAssetButton(assets, graphics, "primary")
  1659.  
  1660.  
  1661.   UI.setCustomAssets(assets)
  1662.   self.UI.setCustomAssets(assets)
  1663. end
  1664.  
  1665. function hudScoreElement(ch, x, y, s, layout, pl)
  1666.   local grandH = math.floor(s*0.75)
  1667.   local subH = s - grandH
  1668.   table.insert(ch, {
  1669.     tag="Panel",
  1670.     attributes={
  1671.       class="bkgPanel",
  1672.       outline=rules.art.colors.highlight,
  1673.       outlineSize="2 -2",
  1674.       rectAlignment=layout,
  1675.       offsetXY = string.format("%f %f", x, y),
  1676.       width=s,
  1677.       height=s
  1678.     },
  1679.     children={
  1680.       {
  1681.         tag="Text",
  1682.         attributes={
  1683.           id="kts__grandtotal_player"..pl,
  1684.           class="finalScore",
  1685.           rectAlignment="UpperCenter",
  1686.           height=grandH,
  1687.           fontSize=grandH-12
  1688.         },
  1689.         value="0"
  1690.       },
  1691.       {
  1692.         tag="Text",
  1693.         attributes={
  1694.           class="title2",
  1695.           height=subH,
  1696.           width=s/2,
  1697.           fontSize=subH-8,
  1698.           rectAlignment="LowerLeft",
  1699.           id="kts__primarytotal_player"..pl
  1700.         },
  1701.         value=string.format("0/%d", rules.scoring.primary.max)
  1702.       },
  1703.       {
  1704.         tag="Text",
  1705.         attributes={
  1706.           class="title2",
  1707.           height=subH,
  1708.           width=s/2,
  1709.           fontSize=subH-8,
  1710.           rectAlignment="LowerRight",
  1711.           id="kts__secondarytotal_player"..pl
  1712.         },
  1713.         value=string.format("0/%d", rules.scoring.primary.max)
  1714.       }
  1715.     }
  1716.   })
  1717. end
  1718.  
  1719. function hudInitiativeElement(ch, x, y, s, layout, pl)
  1720.   table.insert(ch,{
  1721.     tag="Image",
  1722.     attributes={
  1723.       class="initiativeDisplay",
  1724.       id="kts__initiative_display_player"..pl,
  1725.       width=s, height=s,
  1726.       rectAlignment=layout,
  1727.       offsetXY = string.format("%f %f", x, y)
  1728.     }
  1729.   })
  1730. end
  1731.  
  1732. function hudNameElement(ch, x, y, w, h, layout, pl, suffix)
  1733.   local playerc = rules.packet.players[pl]
  1734.   local suffix = suffix or ""
  1735.   table.insert(ch,{
  1736.     tag="Panel",
  1737.     attributes={
  1738.       class="bkgPanel",
  1739.       rectAlignment=layout,
  1740.       width = w,
  1741.       height = h,
  1742.       offsetXY = string.format("%f %f", x, y)
  1743.     },
  1744.     children={
  1745.       {
  1746.         tag="Text",
  1747.         attributes={
  1748.           class="steamName",
  1749.           id=paramPlayer[pl]..suffix,
  1750.           color= string.format("#%s", Color.fromString(playerc):toHex())
  1751.         },
  1752.         value=playerc
  1753.       }
  1754.     }
  1755.   })
  1756. end
  1757.  
  1758. function hudCommandElement(ch, x, y, w, h, layout, pl, suffix)
  1759.   local guid = self.getGUID()
  1760.   local vp = rules.packet.players[pl]
  1761.   local suffix = suffix or ""
  1762.   table.insert(ch,{
  1763.     tag="Panel",
  1764.     attributes={
  1765.       class="bkgPanel",
  1766.       rectAlignment=layout,
  1767.       width = w,
  1768.       height = h,
  1769.       offsetXY = string.format("%f %f", x, y)
  1770.     },
  1771.     children={
  1772.       {
  1773.         tag="Text",
  1774.         attributes={
  1775.           class="title2",
  1776.           id="kts__command_player"..pl..suffix
  1777.         },
  1778.         value="0 CP"
  1779.       },
  1780.       {
  1781.         tag="Button",
  1782.         attributes={
  1783.           onClick=guid.."/onCommandPointUpPressed",
  1784.           width=h-8, height=h-8,
  1785.           text="+", fontSize=h-8,
  1786.           rectAlignment="MiddleRight",
  1787.           visibility=vp,
  1788.           id="kts__command_increase_player"..pl
  1789.         }
  1790.       },
  1791.       {
  1792.         tag="Button",
  1793.         attributes={
  1794.           onClick=guid.."/onCommandPointDownPressed",
  1795.           width=h-8, height=h-8,
  1796.           text="-", fontSize=h-8,
  1797.           rectAlignment="MiddleLeft",
  1798.           visibility=vp,
  1799.           id="kts__command_increase_player"..pl
  1800.         }
  1801.       }
  1802.     }
  1803.   })
  1804. end
  1805.  
  1806. function getHudVisibilities()
  1807.   local players = Player.getColors()
  1808.   local isStreamer = {}
  1809.   local pvis = {}
  1810.   local svis = {}
  1811.  
  1812.   for _,v in pairs(rules.packet.streamers) do
  1813.     isStreamer[v] = true
  1814.   end
  1815.  
  1816.   for _,col in pairs(players) do
  1817.     if isStreamer[col] then
  1818.       table.insert(svis, col)
  1819.     else
  1820.       table.insert(pvis, col)
  1821.     end
  1822.   end
  1823.   return table.concat(pvis, "|"), table.concat(svis, "|")
  1824. end
  1825.  
  1826. function streamerUINameRow(ch, uiWidth, uiHeight, border, sep)
  1827.   local h = 35
  1828.   local nw = (uiWidth-border*2-sep)/2
  1829.   hudNameElement(ch, border, -uiHeight, nw, h, "UpperLeft", 1, "_streamer")
  1830.   hudNameElement(ch, border+nw+sep, -uiHeight, nw, h, "UpperLeft", 2, "_streamer")
  1831.   return uiHeight + h
  1832. end
  1833.  
  1834. function streamerUICPRow(ch, uiWidth, uiHeight, border, sep)
  1835.   local h = 30
  1836.   local nw = (uiWidth-border*2-sep)/2
  1837.   hudCommandElement(ch, border, -uiHeight, nw, h, "UpperLeft", 1, "_streamer")
  1838.   hudCommandElement(ch, border+nw+sep, -uiHeight, nw, h, "UpperLeft", 2, "_streamer")
  1839.   return uiHeight + h
  1840. end
  1841.  
  1842. function streamerUIRoundRow(ch, uiWidth, uiHeight, border, sep, round)
  1843.   local h = 25
  1844.   local nw = (uiWidth - border*2)
  1845.   local panel = {
  1846.     tag="Panel",
  1847.     attributes={
  1848.       width=nw,
  1849.       height = h,
  1850.       offsetXY=string.format("0 %f", -uiHeight),
  1851.       rectAlignment="UpperCenter"
  1852.     },
  1853.     children={
  1854.       {
  1855.         tag="Panel",
  1856.         attributes={
  1857.           class="bkgPanel",
  1858.           width=nw/2
  1859.         },
  1860.         children={
  1861.           {
  1862.             tag="Text",
  1863.             attributes={
  1864.               class="title2",
  1865.               fontSize=16,
  1866.               text="Round "..round
  1867.             }
  1868.           }
  1869.         }
  1870.       },
  1871.       {
  1872.         tag="Image",
  1873.         attributes={
  1874.           class="streamerInitiative",
  1875.           id=atrInitiative(1, round, "streamer"),
  1876.           width=h, height=h,
  1877.           rectAlignment="MiddleLeft",
  1878.           offsetXY="20 0"
  1879.         }
  1880.       },
  1881.       {
  1882.         tag="Image",
  1883.         attributes={
  1884.           class="streamerInitiative",
  1885.           id=atrInitiative(2, round, "streamer"),
  1886.           width=h, height=h,
  1887.           rectAlignment="MiddleRight",
  1888.           offsetXY="-20 0"
  1889.         }
  1890.       }
  1891.     }
  1892.   }
  1893.   table.insert(ch, panel)
  1894.   return uiHeight + h
  1895. end
  1896.  
  1897. function streamerPrimaryCel(t, x, y, w, h, rule, round, player)
  1898.   table.insert(t,
  1899.     {
  1900.       tag="Panel",
  1901.       attributes={
  1902.         rectAlignment="UpperLeft",
  1903.         width = w,
  1904.         height = h,
  1905.         offsetXY = string.format("%f %f", tostring(x), tostring(y))
  1906.       },
  1907.       children={
  1908.         {
  1909.           tag="Image",
  1910.           attributes={
  1911.             id=atrPrimary(player, rule, round,"streamer"),
  1912.             class="streamerScore",
  1913.             height=h-4,
  1914.             tooltip=rules.scoring.primary.objectives[rule]
  1915.           }
  1916.         }
  1917.       }
  1918.     }
  1919.   )
  1920. end
  1921.  
  1922. function streamerUIPrimaryRowPart(ch, x, y, w, pl, round)
  1923.   local objs = #rules.scoring.primary.objectives
  1924.   local cols = math.min(objs, rules.art.gui.scoreboard.primaryColumns)
  1925.   local rows = math.ceil(objs/cols)
  1926.   local celw = math.floor(w/cols)
  1927.   local celh = 26
  1928.   local pch = {}
  1929.   local h = celh * rows
  1930.  
  1931.   for i=1,rows do
  1932.     local rcols = math.min(cols, objs-(i-1)*cols)
  1933.     local rofs = (cols - rcols)*celw*0.5
  1934.     for j=1,rcols do
  1935.       local rule = ((i-1)*cols + j)
  1936.       streamerPrimaryCel(pch, celw*(j-1) + rofs, -celh*(i-1), celw, celh, rule, round, pl)
  1937.     end
  1938.   end
  1939.  
  1940.   table.insert(ch,{
  1941.     tag="Panel",
  1942.     attributes={
  1943.       class="bkgPanel",
  1944.       width=w, height=h,
  1945.       offsetXY=string.format("%f %f", x, y),
  1946.       rectAlignment="UpperLeft"
  1947.     },
  1948.     children=pch
  1949.   })
  1950.   return h
  1951. end
  1952.  
  1953. function streamerUIPrimaryRow(ch, uiWidth, uiHeight, border, sep, round)
  1954.   local nw = (uiWidth-border*2-sep)/2
  1955.   local h = streamerUIPrimaryRowPart(ch, border, -uiHeight, nw, 1, round)
  1956.   streamerUIPrimaryRowPart(ch, border+nw+sep, -uiHeight, nw, 2, round)
  1957.   return uiHeight + h
  1958. end
  1959.  
  1960. function streamerUIHiddenSecondary(ch, x, y, w, h, player)
  1961.   table.insert(ch,
  1962.   {
  1963.     tag="Panel",
  1964.     attributes={
  1965.       width=w,
  1966.       height = h,
  1967.       offsetXY=string.format("%f %f", x, y),
  1968.       color=rules.art.colors.darker,
  1969.       outline=rules.art.colors.background,
  1970.       rectAlignment="upperLeft"
  1971.     },
  1972.     children={
  1973.       {
  1974.         tag="Text",
  1975.         attributes={
  1976.           id="ktw__streamerSecondaries_player"..player,
  1977.           fontSize=16
  1978.         }
  1979.       }
  1980.     }
  1981.   }
  1982.   )
  1983. end
  1984.  
  1985. function streamerUIHiddenSecondaryRow(ch, uiWidth, uiHeight, border, sep)
  1986.   local nw = (uiWidth-border*2-sep)/2
  1987.   local h = 80
  1988.   streamerUIHiddenSecondary(ch, border, -uiHeight-20, nw, 60, 1)
  1989.   streamerUIHiddenSecondary(ch, border+sep+nw, -uiHeight-20, nw, 60, 2)
  1990.   table.insert(ch, {
  1991.     tag="Text",
  1992.     attributes={
  1993.       rectAlignment="UpperCenter",
  1994.       offsetXY=string.format("0 %f", -uiHeight),
  1995.       fontSize=16,
  1996.       width = uiWidth,
  1997.       height = 80,
  1998.       alignment="UpperCenter",
  1999.       text = "Hands"
  2000.     }
  2001.   })
  2002.   return uiHeight + h
  2003. end
  2004.  
  2005. function streamerUITotalRow(ch, uiWidth, uiHeight, border, sep, totalKind)
  2006.   local nw = (uiWidth-border*2-sep)/2
  2007.   local h = 40
  2008.  
  2009.   local panel = {
  2010.     tag="Panel",
  2011.     attributes={
  2012.       width=uiWidth,
  2013.       height = h,
  2014.       offsetXY=string.format("0 %f", -uiHeight),
  2015.       rectAlignment="UpperCenter"
  2016.     },
  2017.     children={
  2018.       {
  2019.         tag="Panel",
  2020.         attributes={
  2021.           class="bkgPanel",
  2022.           width=uiWidth/3
  2023.         },
  2024.         children={
  2025.           {
  2026.             tag="Text",
  2027.             attributes={
  2028.               class="title2",
  2029.               fontSize=16,
  2030.               text=(totalKind:gsub("^%l", string.upper))
  2031.             }
  2032.           }
  2033.         }
  2034.       },
  2035.       {
  2036.         tag="Text",
  2037.         attributes={
  2038.           class="title2",
  2039.           id=string.format("kts__%stotal_player1_streamer", totalKind),
  2040.           width=2*h, height=h,
  2041.           rectAlignment="MiddleLeft",
  2042.           offsetXY="20 0"
  2043.         },
  2044.         value="0/9"
  2045.       },
  2046.       {
  2047.         tag="Text",
  2048.         attributes={
  2049.           class="title2",
  2050.           id=string.format("kts__%stotal_player2_streamer", totalKind),
  2051.           width=2*h, height=h,
  2052.           rectAlignment="MiddleRight",
  2053.           offsetXY="-20 0"
  2054.         },
  2055.         value="0/9"
  2056.       }
  2057.     }
  2058.   }
  2059.   table.insert(ch, panel)
  2060.   return uiHeight + h
  2061. end
  2062.  
  2063. function streamerUISecondaryDisplay(ch, x, y, w, player, sec)
  2064.   local h = 40
  2065.   table.insert(ch,{
  2066.     tag="Panel",
  2067.     attributes={
  2068.       class="bkgPanel",
  2069.       width = w,
  2070.       height = h,
  2071.       rectAlignment="UpperLeft",
  2072.       offsetXY=string.format("%f %f", tostring(x), tostring(y))
  2073.     },
  2074.     children={
  2075.       {
  2076.         tag="Text",
  2077.         attributes={
  2078.           class="title2",
  2079.           id=atrSecondary(player, sec, "streamer"),
  2080.           rectAlignment="UpperCenter",
  2081.           fontSize=16,
  2082.           height=h/2
  2083.         },
  2084.         value="..."
  2085.       },
  2086.       {
  2087.         tag="Text",
  2088.         attributes={
  2089.           class="title2",
  2090.           id=atrSecondary(player, sec, "streamer_amount"),
  2091.           rectAlignment="LowerCenter",
  2092.           width=w,
  2093.           fontSize=16,
  2094.           height=h/2
  2095.         },
  2096.         value="0"
  2097.       }
  2098.     }
  2099.   })
  2100.   return h
  2101. end
  2102.  
  2103. function streamerUISecondary(ch, x, y, w, sep, player)
  2104.   local h = sep
  2105.   local cch = {}
  2106.   for i=1,3 do
  2107.     h = h + streamerUISecondaryDisplay(cch, 0, -h, w, player, i) + sep
  2108.   end
  2109.  
  2110.   table.insert(ch, {
  2111.     tag="Panel",
  2112.     attributes={
  2113.       rectAlignment="UpperLeft",
  2114.       width=w,
  2115.       height=h,
  2116.       offsetXY=string.format("%f %f", tostring(x), tostring(y))
  2117.     },
  2118.     children=cch
  2119.   })
  2120.   return h
  2121. end
  2122.  
  2123. function streamerUISecondaryRow(ch, uiWidth, uiHeight, border, sep)
  2124.   local nw = (uiWidth-border*2-sep)/2
  2125.   local h = streamerUISecondary(ch, border, -uiHeight, nw, sep, 1)
  2126.   streamerUISecondary(ch, border+sep+nw, -uiHeight, nw, sep, 2)
  2127.   return uiHeight + h
  2128. end
  2129.  
  2130. function streamerUIGrandTotal(ch, x, y, s, player)
  2131.   table.insert(ch, {
  2132.     tag="Panel",
  2133.     attributes={
  2134.       class="bkgPanel",
  2135.       outline=rules.art.colors.highlight,
  2136.       outlineSize="2 -2",
  2137.       rectAlignment="UpperLeft",
  2138.       offsetXY = string.format("%f %f", x, y),
  2139.       width=s,
  2140.       height=s
  2141.     },
  2142.     children={
  2143.       {
  2144.         tag="Text",
  2145.         attributes={
  2146.           id="kts__grandtotal_player"..player.."_streamer",
  2147.           class="finalScore",
  2148.           rectAlignment="UpperCenter",
  2149.           height=s,
  2150.           fontSize=s-12
  2151.         },
  2152.         value="0"
  2153.       }
  2154.     }
  2155.   })
  2156. end
  2157.  
  2158. function streamerUIGrandTotalRow(ch, uiWidth, uiHeight, border, sep)
  2159.   local h = 50
  2160.   local gtx1 = uiWidth/2 - h - 50
  2161.   local gtx2 = uiWidth/2 + 50
  2162.   streamerUIGrandTotal(ch, gtx1, -uiHeight, h, 1)
  2163.   streamerUIGrandTotal(ch, gtx2, -uiHeight, h, 2)
  2164.   return uiHeight + h
  2165. end
  2166.  
  2167. function streamerUIBonusRow(ch, uiWidth, uiHeight, border, sep)
  2168.   local h = 40
  2169.   local panelw = uiWidth-border*2
  2170.   table.insert(ch,{
  2171.     tag="Panel",
  2172.     attributes={
  2173.       class="bkgPanel",
  2174.       width=panelw,
  2175.       height = h,
  2176.       rectAlignment="UpperCenter",
  2177.       offsetXY=string.format("0 %f", -uiHeight)
  2178.     },
  2179.     children={
  2180.       {
  2181.         tag="Text",
  2182.         attributes={
  2183.           class="title2",
  2184.           fontSize=20
  2185.         },
  2186.         value="Bonus"
  2187.       },
  2188.       {
  2189.         tag="Text",
  2190.         attributes={
  2191.           class="title2",
  2192.           id="kts__bonus_display_player1_streamer",
  2193.           fontSize=16,
  2194.           rectAlignment="MiddleLeft",
  2195.           width=panelw/2
  2196.         },
  2197.         value="0"
  2198.       },
  2199.       {
  2200.         tag="Text",
  2201.         attributes={
  2202.           class="title2",
  2203.           id="kts__bonus_display_player2_streamer",
  2204.           fontSize=16,
  2205.           rectAlignment="MiddleRight",
  2206.           width=panelw/2
  2207.         },
  2208.         value="0"
  2209.       }
  2210.     }
  2211.   })
  2212.   return uiHeight + h
  2213. end
  2214.  
  2215. function buildStreamerUI(svis)
  2216.   local uiWidth = 360
  2217.   local uiHeight = 5
  2218.   local border = 5
  2219.   local sep = 2
  2220.   --ADDED by ZAKA
  2221.   local panelID = "kts__streamer_panel"..missionSelectedForScoreboard
  2222.   --ADDED by ZAKA
  2223.   --DELETED by ZAKA
  2224.   --local panelID = "kts__streamer_panel"
  2225.   --DELETED by ZAKA
  2226.   local uiSubWidth = uiWidth/2
  2227.   local ch = {}
  2228.  
  2229.   uiHeight = streamerUINameRow(ch, uiWidth, uiHeight, border, sep) + sep
  2230.   uiHeight = streamerUICPRow(ch, uiWidth, uiHeight, border, sep) + sep
  2231.   uiHeight = streamerUIHiddenSecondaryRow(ch, uiWidth, uiHeight, border, sep) + sep*2
  2232.   for i=1,rules.scoring.maxRounds do
  2233.     uiHeight = streamerUIRoundRow(ch, uiWidth, uiHeight, border, sep, i) + sep
  2234.  
  2235.     --ADDED by ZAKA
  2236.     if missionSelectedForScoreboard == "e1bd09" or missionSelectedForScoreboard == "451ffb" then
  2237.       if i > 1 then
  2238.         uiHeight = streamerUIPrimaryRow(ch, uiWidth, uiHeight, border, sep, i) + sep*2
  2239.       end
  2240.     else
  2241.       uiHeight = streamerUIPrimaryRow(ch, uiWidth, uiHeight, border, sep, i) + sep*2
  2242.     end
  2243.     --ADDED by ZAKA
  2244.  
  2245.     --DELETED by ZAKA
  2246.     --uiHeight = buildPrimaryRow(ch, uiHeight, 5, 0, uiWidth, round, 4) + 4
  2247.     --DELETED by ZAKA
  2248.   end
  2249.   --ADDED by ZAKA
  2250.   if #rules.scoring.bonus.objectives > 0 then
  2251.     uiHeight = streamerUIBonusRow(ch, uiWidth, uiHeight, border, sep) + sep
  2252.   end
  2253.   --ADDED by ZAKA
  2254.   uiHeight = streamerUITotalRow(ch, uiWidth, uiHeight, border, sep, "primary") + sep*3
  2255.   uiHeight = streamerUISecondaryRow(ch, uiWidth, uiHeight, border, sep) + sep
  2256.   --DELETED by ZAKA
  2257.   --if #rules.scoring.bonus.objectives > 0 then
  2258.   --  uiHeight = streamerUIBonusRow(ch, uiWidth, uiHeight, border, sep) + sep
  2259.   --end
  2260.   --DELETED by ZAKA
  2261.   uiHeight = streamerUITotalRow(ch, uiWidth, uiHeight, border, sep, "secondary") + sep*3
  2262.   uiHeight = streamerUIGrandTotalRow(ch, uiWidth, uiHeight, border, sep) + border
  2263.  
  2264.   return {
  2265.     tag="Panel",
  2266.     attributes={
  2267.       class="mainPanel",
  2268.       id=panelID,
  2269.       width=uiWidth,
  2270.       height=uiHeight,
  2271.       visibility=svis,
  2272.       allowDragging=true,
  2273.       returnToOriginalPositionWhenReleased=false,
  2274.       rectAlignment="LowerRight"
  2275.     },
  2276.     children=ch
  2277.   }
  2278. end
  2279.  
  2280. function buildHUD(def)
  2281.   local guid = self.getGUID()
  2282.   local uiWidth = 650
  2283.   local uiHeight = 90
  2284.   local panelID = "kts__hud_panel"
  2285.   local chl = {}
  2286.   local chr = {}
  2287.   local logoVisible = rules.art.graphics.eventLogo ~= nil
  2288.   local uiSubWidth = uiWidth*0.5
  2289.   local logoWidth = rules.art.gui.overlay.logoWidth
  2290.   local logoHeight = rules.art.gui.overlay.logoHeight
  2291.   local uiMiddleZone = 150
  2292.   local nameplateWidth = math.floor(uiSubWidth*0.5 + 32)
  2293.  
  2294.   local hudVisibility, streamVisibility = getHudVisibilities()
  2295.  
  2296.   if logoVisible then
  2297.     uiMiddleZone = math.max(uiMiddleZone, logoWidth+4)
  2298.   end
  2299.   uiWidth = uiWidth + uiMiddleZone
  2300.  
  2301.   hudScoreElement(chl, 0, 5, uiHeight, "LowerRight", 1)
  2302.   hudInitiativeElement(chl, -(uiHeight + 4), -4, 32, "UpperRight", 1)
  2303.   hudNameElement(chl, 2, -2, nameplateWidth, uiHeight*0.33, "UpperLeft", 1)
  2304.   hudCommandElement(chl, 2, 2, nameplateWidth, uiHeight*0.66-6, "LowerLeft", 1)
  2305.  
  2306.   hudScoreElement(chr, 0, 5, uiHeight, "LowerLeft", 2)
  2307.   hudInitiativeElement(chr, (uiHeight + 4), -4, 32, "UpperLeft", 2)
  2308.   hudNameElement(chr, -2, -2, nameplateWidth, uiHeight*0.33, "UpperRight", 2)
  2309.   hudCommandElement(chr, -2, 2, nameplateWidth, uiHeight*0.66-6, "LowerRight", 2)
  2310.  
  2311.   local ch = {
  2312.     {
  2313.       tag="Panel",
  2314.       attributes={
  2315.         id="scoreBoardGUI",
  2316.         class="mainPanel",
  2317.         width=uiMiddleZone,
  2318.         height=uiHeight/2,
  2319.         rectAlignment="LowerCenter"
  2320.       },
  2321.       children={
  2322.         {
  2323.           tag="Text",
  2324.           attributes={
  2325.             class="title2",
  2326.             fontSize=uiHeight*0.3,
  2327.             id="kts__round_current"
  2328.           },
  2329.           value="Pre game"
  2330.         }
  2331.       }
  2332.     },
  2333.  
  2334.     --ADDED by ZAKA
  2335.     --Activated / End TP buttons
  2336.     {
  2337.       tag="Panel",
  2338.       attributes={
  2339.         active=true,
  2340.         id="kts__pregame_panel",
  2341.         class="mainPanel",
  2342.         width=uiMiddleZone,
  2343.         height=uiHeight/2,
  2344.         offsetXY="0 "..(uiHeight/2),
  2345.         rectAlignment="LowerCenter"
  2346.       },
  2347.       children={
  2348.         {
  2349.           tag="Button",
  2350.           attributes={
  2351.             active=gameStateMachine.preGame.active,
  2352.             class="activated",
  2353.             fontSize=uiHeight*0.2,
  2354.             id="kts__show_checklist_button",
  2355.             onClick=self.getGUID().."/onShowChecklistBtn",
  2356.             tooltip="Click open the pre game checklist",
  2357.             width=uiMiddleZone,
  2358.           },
  2359.           value="Show Pre Game Checklist"
  2360.         },
  2361.         {
  2362.           tag="Button",
  2363.           attributes={
  2364.             active=gameStateMachine.tp1.firefight or gameStateMachine.tp2.firefight or gameStateMachine.tp3.firefight or gameStateMachine.tp4.firefight and true or false,
  2365.             class="activated",
  2366.             fontSize=10,
  2367.             id="kts__activated_button",
  2368.             onClick=self.getGUID().."/onActivatedBtn",
  2369.             tooltip="Click to ready Opts and save their positions",
  2370.             width=uiMiddleZone*0.5,
  2371.             offsetXY="-"..(uiMiddleZone*0.25).." 0",
  2372.           },
  2373.           value="Activated"
  2374.         },
  2375.         {
  2376.           tag="Button",
  2377.           attributes={
  2378.             active=gameStateMachine.tp1.firefight or gameStateMachine.tp2.firefight or gameStateMachine.tp3.firefight or gameStateMachine.tp4.firefight and true or false,
  2379.             class="activated",
  2380.             fontSize=10,
  2381.             id="kts__end_tp_button",
  2382.             onClick=self.getGUID().."/onEndTPBtn",
  2383.             tooltip="Click to end TP and ready all operatives",
  2384.             width=uiMiddleZone*0.5,
  2385.             offsetXY=(uiMiddleZone*0.25).." 0",
  2386.           },
  2387.           value="End TP"
  2388.         },
  2389.         {
  2390.           tag="Button",
  2391.           attributes={
  2392.             active=gameStateMachine.tp1.scoring or gameStateMachine.tp2.scoring or gameStateMachine.tp3.scoring or gameStateMachine.tp4.scoring and true or false,
  2393.             class="activated",
  2394.             fontSize=uiHeight*0.2,
  2395.             id="kts__scoring_button",
  2396.             onClick=self.getGUID().."/onScoringBtn",
  2397.             tooltip="Click to end scoring phase",
  2398.             width=uiMiddleZone,
  2399.           },
  2400.           value="End scoring"
  2401.         },
  2402.         {
  2403.           tag="Button",
  2404.           attributes={
  2405.             active=gameStateMachine.tp1.ploys or gameStateMachine.tp2.ploys or gameStateMachine.tp3.ploys or gameStateMachine.tp4.ploys and true or false,
  2406.             class="activated",
  2407.             fontSize=uiHeight*0.2,
  2408.             id="kts__end_ploys_button",
  2409.             onClick=self.getGUID().."/onEndPloysBtn",
  2410.             tooltip="Click to move to the tacops section",
  2411.             width=uiMiddleZone,
  2412.           },
  2413.           value="End Ploys section"
  2414.         },
  2415.         {
  2416.           tag="Button",
  2417.           attributes={
  2418.             active=gameStateMachine.tp1.tacops or gameStateMachine.tp2.tacops or gameStateMachine.tp3.tacops or gameStateMachine.tp4.tacops and true or false,
  2419.             class="activated",
  2420.             fontSize=uiHeight*0.2,
  2421.             id="kts__end_tacops_button",
  2422.             onClick=self.getGUID().."/onEndTacopsBtn",
  2423.             tooltip="Click to start firefight phase",
  2424.             width=uiMiddleZone,
  2425.           },
  2426.           value="End tacOps section"
  2427.         },
  2428.         {
  2429.           tag="Button",
  2430.           attributes={
  2431.             active=gameStateMachine.tp2.init or gameStateMachine.tp3.init or gameStateMachine.tp4.init and true or false,
  2432.             class="activated",
  2433.             fontSize=12,
  2434.             id="kts__end_init_1_button",
  2435.             onClick=self.getGUID().."/onEndInitP1Btn",
  2436.             tooltip="Click to start strategy phase",
  2437.             width=uiMiddleZone*0.5,
  2438.             offsetXY="-"..(uiMiddleZone*0.25).." 0",
  2439.           },
  2440.           value="Red Initiative"
  2441.         },
  2442.         {
  2443.           tag="Button",
  2444.           attributes={
  2445.             active=gameStateMachine.tp2.init or gameStateMachine.tp3.init or gameStateMachine.tp4.init and true or false,
  2446.             class="activated",
  2447.             fontSize=12,
  2448.             id="kts__end_init_2_button",
  2449.             onClick=self.getGUID().."/onEndInitP2Btn",
  2450.             tooltip="Click to start strategy phase",
  2451.             width=uiMiddleZone*0.5,
  2452.             offsetXY=(uiMiddleZone*0.25).." 0",
  2453.           },
  2454.           value="Blue Initiative"
  2455.         },
  2456.         {
  2457.           tag="Button",
  2458.           attributes={
  2459.             active=false,
  2460.             class="activated",
  2461.             fontSize=10,
  2462.             id="kts__loading_button",
  2463.             width=uiMiddleZone,
  2464.           },
  2465.           value="Loading..."
  2466.         },
  2467.         {
  2468.           tag="Button",
  2469.           attributes={
  2470.             active=gameStateMachine.endGame.active,
  2471.             class="activated",
  2472.             fontSize=uiHeight*0.2,
  2473.             id="kts__end_game_button",
  2474.             onClick=self.getGUID().."/onEndGame",
  2475.             tooltip="Click to send game data",
  2476.             width=uiMiddleZone,
  2477.           },
  2478.           value="Send Game Data"
  2479.         },
  2480.       }
  2481.     },
  2482.     {
  2483.       tag="Panel",
  2484.       attributes={
  2485.         id="kts__red_faction_ui",
  2486.         class="mainPanel",
  2487.         width=nameplateWidth,
  2488.         height=20,
  2489.         offsetXY="2 "..uiHeight,
  2490.         rectAlignment="lowerLeft"
  2491.       },
  2492.       children={
  2493.         {
  2494.           tag="Panel",
  2495.           attributes={
  2496.             width=nameplateWidth-4,
  2497.             height=16,
  2498.             class="bkgPanel",
  2499.             rectAlignment="middleCenter"
  2500.           },
  2501.           children={
  2502.             {
  2503.               tag="Text",
  2504.               attributes={
  2505.                 class="steamName",
  2506.                 id="kts__red_faction_ui_text",
  2507.                 resizeTextForBestFit=false,
  2508.                 color="Red",
  2509.                 fontStyle="",
  2510.                 fontSize=12,
  2511.               },
  2512.               value="Red Faction"
  2513.             }
  2514.           }
  2515.         }
  2516.       }
  2517.     },
  2518.     {
  2519.       tag="Panel",
  2520.       attributes={
  2521.         id="kts__blue_faction_ui",
  2522.         class="mainPanel",
  2523.         width=nameplateWidth,
  2524.         height=20,
  2525.         offsetXY="-2 "..uiHeight,
  2526.         rectAlignment="lowerRight"
  2527.       },
  2528.       children={
  2529.         {
  2530.           tag="Panel",
  2531.           attributes={
  2532.             width=nameplateWidth-4,
  2533.             height=16,
  2534.             class="bkgPanel",
  2535.             rectAlignment="middleCenter"
  2536.           },
  2537.           children={
  2538.             {
  2539.               tag="Text",
  2540.               attributes={
  2541.                 class="steamName",
  2542.                 id="kts__blue_faction_ui_text",
  2543.                 resizeTextForBestFit=false,
  2544.                 color="Blue",
  2545.                 fontStyle="",
  2546.                 fontSize=12,
  2547.               },
  2548.               value="Blue Faction"
  2549.             }
  2550.           }
  2551.         }
  2552.       }
  2553.     },
  2554.     --ADDED by ZAKA
  2555.  
  2556.     {
  2557.       tag="Panel",
  2558.       attributes={
  2559.         class="mainPanel",
  2560.         width=uiSubWidth,
  2561.         height=uiHeight,
  2562.         rectAlignment="LowerLeft"
  2563.       },
  2564.       children=chl
  2565.     },
  2566.     {
  2567.       tag="Panel",
  2568.       attributes={
  2569.         class="mainPanel",
  2570.         width=uiSubWidth,
  2571.         height=uiHeight,
  2572.         rectAlignment="LowerRight"
  2573.       },
  2574.       children=chr
  2575.     },
  2576.     {
  2577.       tag="Image",
  2578.       attributes={
  2579.         rectAlignment="LowerCenter",
  2580.         offsetXY="0 "..(uiHeight*0.5),
  2581.         image="eventLogo",
  2582.         width=logoWidth,
  2583.         height=logoHeight,
  2584.         active=logoVisible
  2585.       }
  2586.     }
  2587.   }
  2588.  
  2589.   local basePanel = {
  2590.     tag="Panel",
  2591.     attributes={
  2592.       id=panelID,
  2593.       width=uiWidth,
  2594.       --DELETED by ZAKA
  2595.       --height=uiHeight,
  2596.       --DELETED by ZAKA
  2597.       --ADDED by ZAKA
  2598.       height=uiHeight+30,
  2599.       --ADDED by ZAKA
  2600.       allowDragging=true,
  2601.       returnToOriginalPositionWhenReleased=false,
  2602.       visibility=hudVisibility,
  2603.       rectAlignment="LowerCenter"
  2604.     },
  2605.     children = ch
  2606.   }
  2607.  
  2608.   if Global.UI.getAttribute("scoreBoardGUI", "id") == nil then
  2609.     local oldUI = Global.UI.getXmlTable()
  2610.  
  2611.     if oldUI == nil then
  2612.             oldUI = {}
  2613.         end
  2614.     table.insert(oldUI, def)
  2615.     table.insert(oldUI, basePanel)
  2616.  
  2617.     --ADDED by ZAKA
  2618.     checkPanel = buildHUDCheck(def)
  2619.     table.insert(oldUI, checkPanel)
  2620.     --ADDED by ZAKA
  2621.  
  2622.     table.insert(oldUI, buildStreamerUI(streamVisibility))
  2623.     Wait.frames(function() Global.UI.setXmlTable(oldUI) end, 1)
  2624.   end
  2625. end
  2626.  
  2627. --ADDED by ZAKA
  2628. function buildDropdownUI(group, playerName)
  2629.   optionTable = {}
  2630.   for _,name in ipairs(group) do
  2631.     newFaction = {
  2632.       tag="Option",
  2633.       attributes={
  2634.         selected=playerName ~= nil and checkListStatus[playerName].faction == name and true or false or true,
  2635.       },
  2636.       value=name,
  2637.     }
  2638.     table.insert(optionTable, newFaction)
  2639.   end
  2640.   table.insert(optionTable, {
  2641.     tag="Option",
  2642.     attributes={
  2643.       selected=playerName ~= nil and checkListStatus[playerName].faction == "Select One" and true or false or true,
  2644.     },
  2645.     value="Select One",
  2646.   })
  2647.   return optionTable
  2648. end
  2649. function buildOpenMissionDropdownUI()
  2650.   optionTable = {}
  2651.   for k,v in pairs(missionIndexOpen) do
  2652.     newFaction = {
  2653.       tag="Option",
  2654.       attributes={
  2655.         selected=checkListStatus.mission == v.code.." "..v.name and true or false,
  2656.       },
  2657.       value=v.code.." "..v.name,
  2658.     }
  2659.     table.insert(optionTable, newFaction)
  2660.   end
  2661.   table.insert(optionTable, {
  2662.     tag="Option",
  2663.     attributes={
  2664.       selected=checkListStatus.mission == "Select One" and true or false,
  2665.     },
  2666.     value="Select One",
  2667.   })
  2668.   return optionTable
  2669. end
  2670. function buildItdMissionDropdownUI()
  2671.   optionTable = {}
  2672.   for k,v in pairs(missionIndexItd) do
  2673.     newFaction = {
  2674.       tag="Option",
  2675.       attributes={
  2676.         selected=checkListStatus.mission == v.code.." "..v.name and true or false,
  2677.       },
  2678.       value=v.code.." "..v.name,
  2679.     }
  2680.     table.insert(optionTable, newFaction)
  2681.   end
  2682.   table.insert(optionTable, {
  2683.     tag="Option",
  2684.     attributes={
  2685.       selected=checkListStatus.mission == "Select One" and true or false,
  2686.     },
  2687.     value="Select One",
  2688.   })
  2689.   return optionTable
  2690. end
  2691. function buildTournamentDropdownUI()
  2692.   optionTable = {}
  2693.   for _,name in ipairs(tournamentIndex) do
  2694.     table.insert(optionTable, {
  2695.       tag="Option",
  2696.       attributes={
  2697.         selected=checkListStatus.tournament == name and true or false,
  2698.       },
  2699.       value=name,
  2700.     })
  2701.   end
  2702.   table.insert(optionTable, {
  2703.     tag="Option",
  2704.     attributes={
  2705.       selected=true,
  2706.     },
  2707.     value="Select One",
  2708.   })
  2709.   return optionTable
  2710. end
  2711. function buildEditionDropdownUI()
  2712.   optionTable = {}
  2713.   for _,name in ipairs(editionIndex) do
  2714.     table.insert(optionTable, {
  2715.       tag="Option",
  2716.       attributes={
  2717.         selected=checkListStatus.edition == name and true or false,
  2718.       },
  2719.       value=name,
  2720.     })
  2721.   end
  2722.   table.insert(optionTable, {
  2723.     tag="Option",
  2724.     attributes={
  2725.       selected=true,
  2726.     },
  2727.     value="Select One",
  2728.   })
  2729.   return optionTable
  2730. end
  2731. function buildGameTypeDropdownUI()
  2732.   optionTable = {}
  2733.   for _,name in ipairs(gameTypeIndex) do
  2734.     table.insert(optionTable, {
  2735.       tag="Option",
  2736.       attributes={
  2737.         selected=checkListStatus.gameType == name and true or false,
  2738.       },
  2739.       value=name,
  2740.     })
  2741.   end
  2742.   table.insert(optionTable, {
  2743.     tag="Option",
  2744.     attributes={
  2745.       selected=true,
  2746.     },
  2747.     value="Select One",
  2748.   })
  2749.   return optionTable
  2750. end
  2751. function buildAllowDataCollection1(yPos, uiWidth, uiMiddleZone, panelHeight)
  2752.   return {
  2753.     tag="Panel",
  2754.     attributes={
  2755.       class="bkgPanel",
  2756.       height=panelHeight,
  2757.       rectAlignment="UpperCenter",
  2758.       offsetXY="0 "..yPos,
  2759.     },
  2760.     children={
  2761.       {
  2762.         tag="Panel",
  2763.         attributes={
  2764.           class="bkgPanel",
  2765.           width=uiMiddleZone,
  2766.           rectAlignment="UpperCenter",
  2767.           padding="10 0 0 0",
  2768.         },
  2769.         children={
  2770.           {
  2771.             tag="Text",
  2772.             attributes={
  2773.               fontSize=12,
  2774.             },
  2775.             value="Allow data collection?"
  2776.           },
  2777.         }
  2778.       }
  2779.     }
  2780.   }
  2781. end
  2782. function buildVideoTutorial1(yPos, uiWidth, uiMiddleZone, panelHeight)
  2783.   return {
  2784.     tag="Panel",
  2785.     attributes={
  2786.       class="bkgPanel",
  2787.       height=panelHeight,
  2788.       rectAlignment="UpperCenter",
  2789.       offsetXY="0 "..yPos,
  2790.     },
  2791.     children={
  2792.       {
  2793.         tag="Panel",
  2794.         attributes={
  2795.           class="bkgPanel",
  2796.           width=uiMiddleZone,
  2797.           rectAlignment="UpperCenter",
  2798.           padding="10 0 0 0",
  2799.         },
  2800.         children={
  2801.           {
  2802.             tag="Text",
  2803.             attributes={
  2804.               fontSize=12,
  2805.             },
  2806.             value="For a video tutorial, follow this link:"
  2807.           },
  2808.         }
  2809.       }
  2810.     }
  2811.   }
  2812. end
  2813. function buildVideoTutorial2(yPos, uiWidth, uiMiddleZone, panelHeight)
  2814.   return {
  2815.     tag="Panel",
  2816.     attributes={
  2817.       class="bkgPanel",
  2818.       height=panelHeight,
  2819.       rectAlignment="UpperCenter",
  2820.       onClick=self.getGUID().."/onTutorialClick",
  2821.       offsetXY="0 "..yPos,
  2822.     },
  2823.     children={
  2824.       {
  2825.         tag="Panel",
  2826.         attributes={
  2827.           class="bkgPanel",
  2828.           width=uiMiddleZone,
  2829.           rectAlignment="UpperCenter",
  2830.           padding="10 0 0 0",
  2831.         },
  2832.         children={
  2833.           {
  2834.             tag="Text",
  2835.             attributes={
  2836.               fontSize=12,
  2837.               color="White",
  2838.             },
  2839.             value="https://youtu.be/GV7AnrjQr9A"
  2840.           },
  2841.         }
  2842.       }
  2843.     }
  2844.   }
  2845. end
  2846. function buildAllowDataCollection2(yPos, uiWidth, uiMiddleZone, panelHeight)
  2847.   return {
  2848.       tag="Panel",
  2849.       attributes={
  2850.         class="bkgPanel",
  2851.         height=panelHeight,
  2852.         rectAlignment="UpperCenter",
  2853.         offsetXY="0 "..yPos,
  2854.       },
  2855.       children={
  2856.       {
  2857.         tag="Panel",
  2858.         attributes={
  2859.           class="bkgPanel",
  2860.           width=uiMiddleZone/2,
  2861.           rectAlignment="UpperLeft",
  2862.         },
  2863.         children={
  2864.           {
  2865.             tag="Toggle",
  2866.             attributes={
  2867.               id="kts__toggle_red_accept",
  2868.               rectAlignment="MiddleRight",
  2869.               offsetXY="10 0",
  2870.               tooltip="We will use your Steam name to help us getting the game data but only in game. Your name will not be sent to the database, and the data stored will be anonymous.",
  2871.               tooltipPosition="Above",
  2872.               onValueChanged=self.getGUID().."/onRedAcceptedDataCollection",
  2873.               isOn=Player['Red'].steam_name ~= nil and checkListStatus[Player['Red'].steam_name].allow == "True" and true or false or false,
  2874.             },
  2875.           },
  2876.           {
  2877.             tag="Text",
  2878.             attributes={
  2879.               id="kts__toggle_red_accept_text",
  2880.               offsetXY="-"..(uiMiddleZone/16).." 0",
  2881.               text=Player['Red'].steam_name ~= nil and Player['Red'].steam_name or "no_player",
  2882.               fontSize=12,
  2883.             },
  2884.           },
  2885.         }
  2886.       },
  2887.       {
  2888.         tag="Panel",
  2889.         attributes={
  2890.           class="bkgPanel",
  2891.           width=uiMiddleZone/2,
  2892.           rectAlignment="UpperRight",
  2893.         },
  2894.         children={
  2895.           {
  2896.             tag="Toggle",
  2897.             attributes={
  2898.               id="kts__toggle_blue_accept",
  2899.               rectAlignment="MiddleRight",
  2900.               offsetXY="10 0",
  2901.               tooltip="We will use your Steam name to help us getting the game data but only in game. Your name will not be sent to the database, and the data stored will be anonymous.",
  2902.               tooltipPosition="Above",
  2903.               onValueChanged=self.getGUID().."/onBlueAcceptedDataCollection",
  2904.               isOn=Player['Blue'].steam_name ~= nil and checkListStatus[Player['Blue'].steam_name].allow == "True" and true or false or false,
  2905.             },
  2906.           },
  2907.           {
  2908.             tag="Text",
  2909.             attributes={
  2910.               id="kts__toggle_blue_accept_text",
  2911.               text=Player['Blue'].steam_name ~= nil and Player['Blue'].steam_name or "no_player",
  2912.               fontSize=12,
  2913.               offsetXY="-"..(uiMiddleZone/16).." 0",
  2914.             },
  2915.           },
  2916.         }
  2917.       }
  2918.     }
  2919.   }
  2920. end
  2921. function buildSecondaryTitle(yPos, uiWidth, uiMiddleZone, panelHeight)
  2922.   return {
  2923.     tag="Panel",
  2924.     attributes={
  2925.       class="bkgPanel",
  2926.       height=30,
  2927.       rectAlignment="UpperCenter",
  2928.       offsetXY="0 "..yPos,
  2929.     },
  2930.     children={
  2931.       {
  2932.         tag="Text",
  2933.         attributes={
  2934.           class="title2",
  2935.           fontSize=15,
  2936.         },
  2937.         value="Game setup checklist - Complete all in order"
  2938.       },
  2939.     }
  2940.   }
  2941. end
  2942. function buildGameType1(yPos, uiWidth, uiMiddleZone, panelHeight)
  2943.   return {
  2944.     tag="Panel",
  2945.     attributes={
  2946.       class="bkgPanel",
  2947.       height=panelHeight,
  2948.       rectAlignment="UpperCenter",
  2949.       offsetXY="0 "..yPos,
  2950.     },
  2951.     children={
  2952.       {
  2953.         tag="Panel",
  2954.         attributes={
  2955.           class="bkgPanel",
  2956.           width=uiMiddleZone,
  2957.           rectAlignment="UpperCenter",
  2958.         },
  2959.         children={
  2960.           {
  2961.             tag="Text",
  2962.             attributes={
  2963.               fontSize=12,
  2964.               alignment="MiddleCenter"
  2965.             },
  2966.             value="Select Edition and Game type"
  2967.           },
  2968.         }
  2969.       },
  2970.     }
  2971.   }
  2972. end
  2973. function buildGameType2(yPos, uiWidth, uiMiddleZone, panelHeight)
  2974.   local optionsEd = buildEditionDropdownUI()
  2975.   local optionsGt = buildGameTypeDropdownUI()
  2976.   return {
  2977.     tag="Panel",
  2978.     attributes={
  2979.       class="bkgPanel",
  2980.       height=35,
  2981.       rectAlignment="UpperCenter",
  2982.       offsetXY="0 "..yPos,
  2983.     },
  2984.     children={
  2985.       {
  2986.         tag="Panel",
  2987.         attributes={
  2988.           class="bkgPanel",
  2989.           width=uiMiddleZone/2,
  2990.           rectAlignment="UpperLeft",
  2991.           padding="10 10 3 3",
  2992.         },
  2993.         children={
  2994.           {
  2995.             tag="Dropdown",
  2996.             attributes={
  2997.               id="kts__dropdown_edition",
  2998.               width=uiMiddleZone,
  2999.               fontSize=12,
  3000.               onValueChanged=self.getGUID().."/onEditionSelected",
  3001.             },
  3002.             children=optionsEd,
  3003.           },
  3004.         }
  3005.       },
  3006.       {
  3007.         tag="Panel",
  3008.         attributes={
  3009.           class="bkgPanel",
  3010.           width=uiMiddleZone/2,
  3011.           rectAlignment="UpperRight",
  3012.           padding="10 10 3 3",
  3013.         },
  3014.         children={
  3015.           {
  3016.             tag="Dropdown",
  3017.             attributes={
  3018.               id="kts__dropdown_game_type",
  3019.               width=uiMiddleZone,
  3020.               fontSize=12,
  3021.               onValueChanged=self.getGUID().."/onGameTypeSelected",
  3022.             },
  3023.             children=optionsGt,
  3024.           },
  3025.         }
  3026.       },
  3027.     }
  3028.   }
  3029. end
  3030. function buildTournament1(yPos, uiWidth, uiMiddleZone, panelHeight)
  3031.   return {
  3032.     tag="Panel",
  3033.     attributes={
  3034.       class="bkgPanel",
  3035.       height=panelHeight,
  3036.       rectAlignment="UpperCenter",
  3037.       offsetXY="0 "..yPos,
  3038.     },
  3039.     children={
  3040.       {
  3041.         tag="Panel",
  3042.         attributes={
  3043.           class="bkgPanel",
  3044.           width=uiMiddleZone,
  3045.           rectAlignment="UpperCenter",
  3046.         },
  3047.         children={
  3048.           {
  3049.             tag="Text",
  3050.             attributes={
  3051.               fontSize=12,
  3052.               alignment="MiddleCenter"
  3053.             },
  3054.             value="Select Tournament"
  3055.           },
  3056.         }
  3057.       },
  3058.     }
  3059.   }
  3060. end
  3061. function buildTournament2(yPos, uiWidth, uiMiddleZone, panelHeight)
  3062.   local options = buildTournamentDropdownUI()
  3063.   return {
  3064.     tag="Panel",
  3065.     attributes={
  3066.       class="bkgPanel",
  3067.       height=35,
  3068.       rectAlignment="UpperCenter",
  3069.       offsetXY="0 "..yPos,
  3070.     },
  3071.     children={
  3072.       {
  3073.         tag="Panel",
  3074.         attributes={
  3075.           class="bkgPanel",
  3076.           width=uiMiddleZone,
  3077.           rectAlignment="UpperRight",
  3078.           padding="10 10 3 3",
  3079.         },
  3080.         children={
  3081.           tag="Dropdown",
  3082.           attributes={
  3083.             id="kts__dropdown_tournament",
  3084.             width=uiMiddleZone,
  3085.             fontSize=12,
  3086.             onValueChanged=self.getGUID().."/onTournamentSelected",
  3087.           },
  3088.           children=options,
  3089.         },
  3090.       },
  3091.     }
  3092.   }
  3093. end
  3094. function buildKillZoneLoaded1(yPos, uiWidth, uiMiddleZone, panelHeight)
  3095.   return {
  3096.     tag="Panel",
  3097.     attributes={
  3098.       class="bkgPanel",
  3099.       height=panelHeight,
  3100.       rectAlignment="UpperCenter",
  3101.       offsetXY="0 "..yPos,
  3102.     },
  3103.     children={
  3104.       {
  3105.         tag="Text",
  3106.         attributes={
  3107.           fontSize=12,
  3108.           alignment="MiddleCenter",
  3109.         },
  3110.         value="Kill Zone additively loaded?"
  3111.       },
  3112.     }
  3113.   }
  3114. end
  3115. function buildKillZoneLoaded2(yPos, uiWidth, uiMiddleZone, panelHeight)
  3116.   return {
  3117.     tag="Panel",
  3118.     attributes={
  3119.       class="bkgPanel",
  3120.       height=panelHeight,
  3121.       rectAlignment="UpperCenter",
  3122.       offsetXY="0 "..yPos,
  3123.     },
  3124.     children={
  3125.       {
  3126.         tag="Toggle",
  3127.         attributes={
  3128.           id="kts__toggle_kz_loaded",
  3129.           tooltip="Did you load the Kill Zone?",
  3130.           tooltipPosition="Above",
  3131.           onValueChanged=self.getGUID().."/onKillZoneLoaded",
  3132.           isOn=checkListStatus.killZoneLoaded == "True" and true or false,
  3133.         },
  3134.       },
  3135.     }
  3136.   }
  3137. end
  3138. function buildSelectMission1(yPos, uiWidth, uiMiddleZone, panelHeight)
  3139.   return {
  3140.     tag="Panel",
  3141.     attributes={
  3142.       class="bkgPanel",
  3143.       height=panelHeight,
  3144.       rectAlignment="UpperCenter",
  3145.       offsetXY="0 "..yPos,
  3146.     },
  3147.     children={
  3148.       {
  3149.         tag="Panel",
  3150.         attributes={
  3151.           class="bkgPanel",
  3152.           width=uiMiddleZone,
  3153.           rectAlignment="UpperCenter",
  3154.         },
  3155.         children={
  3156.           {
  3157.             tag="Text",
  3158.             attributes={
  3159.               fontSize=12,
  3160.               alignment="MiddleCenter"
  3161.             },
  3162.             value="Select Mission"
  3163.           },
  3164.         }
  3165.       },
  3166.     }
  3167.   }
  3168. end
  3169. function buildSelectMission2(yPos, uiWidth, uiMiddleZone, panelHeight)
  3170.   local optionsOpen = buildOpenMissionDropdownUI()
  3171.   local optionsItd = buildItdMissionDropdownUI()
  3172.   return {
  3173.     tag="Panel",
  3174.     attributes={
  3175.       class="bkgPanel",
  3176.       height=35,
  3177.       rectAlignment="UpperCenter",
  3178.       offsetXY="0 "..yPos,
  3179.     },
  3180.     children={
  3181.       {
  3182.         tag="Panel",
  3183.         attributes={
  3184.           class="bkgPanel",
  3185.           width=uiMiddleZone,
  3186.           rectAlignment="UpperRight",
  3187.           padding="10 10 3 3",
  3188.         },
  3189.         children={
  3190.           {
  3191.             tag="Dropdown",
  3192.             attributes={
  3193.               id="kts__dropdown_mission_open",
  3194.               active=checkListStatus.edition == "KT 2021 - Open" and true or false,
  3195.               width=uiMiddleZone,
  3196.               fontSize=12,
  3197.               onValueChanged=self.getGUID().."/onOpenMissionSelected",
  3198.             },
  3199.             children=optionsOpen,
  3200.           },
  3201.           {
  3202.             tag="Dropdown",
  3203.             attributes={
  3204.               id="kts__dropdown_mission_itd",
  3205.               active=checkListStatus.edition == "KT 2022 - Into The Dark" and true or false,
  3206.               width=uiMiddleZone,
  3207.               fontSize=12,
  3208.               onValueChanged=self.getGUID().."/onItdMissionSelected",
  3209.             },
  3210.             children=optionsItd,
  3211.           },
  3212.         },
  3213.       },
  3214.     }
  3215.   }
  3216. end
  3217. function buildRollOffWinner1(yPos, uiWidth, uiMiddleZone, panelHeight)
  3218.   return {
  3219.     tag="Panel",
  3220.     attributes={
  3221.       class="bkgPanel",
  3222.       height=panelHeight,
  3223.       rectAlignment="UpperCenter",
  3224.       offsetXY="0 "..yPos,
  3225.     },
  3226.     children={
  3227.       {
  3228.         tag="Panel",
  3229.         attributes={
  3230.           class="bkgPanel",
  3231.           width=uiWidth/4,
  3232.           rectAlignment="UpperCenter",
  3233.         },
  3234.         children={
  3235.           {
  3236.             tag="Text",
  3237.             attributes={
  3238.               fontSize=12,
  3239.               alignment="MiddleCenter"
  3240.             },
  3241.             value="Dropzone Rolloff winner"
  3242.           },
  3243.         }
  3244.       },
  3245.     },
  3246.   }
  3247. end
  3248. function buildRollOffWinner2(yPos, uiWidth, uiMiddleZone, panelHeight)
  3249.   return {
  3250.     tag="Panel",
  3251.     attributes={
  3252.       class="bkgPanel",
  3253.       height=panelHeight,
  3254.       rectAlignment="UpperCenter",
  3255.       offsetXY="0 "..yPos,
  3256.     },
  3257.     children={
  3258.       {
  3259.         tag="Panel",
  3260.         attributes={
  3261.           class="bkgPanel",
  3262.           width=uiMiddleZone/2,
  3263.           rectAlignment="UpperLeft",
  3264.         },
  3265.         children={
  3266.           {
  3267.             tag="Toggle",
  3268.             attributes={
  3269.               id="kts__toggle_red_rolloff_winner",
  3270.               onValueChanged=self.getGUID().."/onRedWonRollOff",
  3271.               rectAlignment="MiddleRight",
  3272.               offsetXY="10 0",
  3273.               isOn=Player['Red'].steam_name ~= nil and Player['Red'].steam_name == checkListStatus.rollOffWinner and true or false or false,
  3274.             },
  3275.           },
  3276.           {
  3277.             tag="Text",
  3278.             attributes={
  3279.               id="kts__red_roloff_winner_text",
  3280.               text=Player['Red'].steam_name ~= nil and Player['Red'].steam_name or "no_player",
  3281.               fontSize=12,
  3282.               offsetXY="-"..(uiMiddleZone/16).." 0",
  3283.             },
  3284.           },
  3285.         }
  3286.       },
  3287.       {
  3288.         tag="Panel",
  3289.         attributes={
  3290.           class="bkgPanel",
  3291.           width=uiMiddleZone/2,
  3292.           rectAlignment="UpperRight",
  3293.         },
  3294.         children={
  3295.           {
  3296.             tag="Toggle",
  3297.             attributes={
  3298.               id="kts__toggle_blue_rolloff_winner",
  3299.               rectAlignment="MiddleRight",
  3300.               offsetXY="10 0",
  3301.               onValueChanged=self.getGUID().."/onBlueWonRollOff",
  3302.               isOn=Player['Blue'].steam_name ~= nil and Player['Blue'].steam_name == checkListStatus.rollOffWinner and true or false or false,
  3303.             },
  3304.           },
  3305.           {
  3306.             tag="Text",
  3307.             attributes={
  3308.               id="kts__blue_roloff_winner_text",
  3309.               text=Player['Blue'].steam_name ~= nil and Player['Blue'].steam_name or "no_player",
  3310.               fontSize=12,
  3311.               offsetXY="-"..(uiMiddleZone/16).." 0",
  3312.             },
  3313.           },
  3314.         }
  3315.       },
  3316.     },
  3317.   }
  3318. end
  3319. function buildRollOffSelection1(yPos, uiWidth, uiMiddleZone, panelHeight)
  3320.   return {
  3321.     tag="Panel",
  3322.     attributes={
  3323.       class="bkgPanel",
  3324.       height=panelHeight,
  3325.       rectAlignment="UpperCenter",
  3326.       offsetXY="0 "..yPos,
  3327.     },
  3328.     children={
  3329.       {
  3330.         tag="Panel",
  3331.         attributes={
  3332.           class="bkgPanel",
  3333.           width=uiMiddleZone,
  3334.           rectAlignment="UpperCenter",
  3335.           padding="10 0 0 0",
  3336.         },
  3337.         children={
  3338.           {
  3339.             tag="Text",
  3340.             attributes={
  3341.               fontSize=12,
  3342.             },
  3343.             value="Rolloff winner selection"
  3344.           },
  3345.         }
  3346.       },
  3347.     }
  3348.   }
  3349. end
  3350. function buildRollOffSelection2(yPos, uiWidth, uiMiddleZone, panelHeight)
  3351.   return {
  3352.     tag="Panel",
  3353.     attributes={
  3354.       class="bkgPanel",
  3355.       height=panelHeight,
  3356.       rectAlignment="UpperCenter",
  3357.       offsetXY="0 "..yPos,
  3358.     },
  3359.     children={
  3360.       {
  3361.         tag="Panel",
  3362.         attributes={
  3363.           class="bkgPanel",
  3364.           width=uiMiddleZone/2,
  3365.           rectAlignment="UpperLeft",
  3366.         },
  3367.         children={
  3368.           {
  3369.             tag="Toggle",
  3370.             attributes={
  3371.               id="kts__toggle_attacker_selected",
  3372.               onValueChanged=self.getGUID().."/onAttackerSelected",
  3373.               rectAlignment="MiddleRight",
  3374.               offsetXY="10 0",
  3375.               isOn=checkListStatus.rollOffAttacker,
  3376.             },
  3377.           },
  3378.           {
  3379.             tag="Text",
  3380.             attributes={
  3381.               fontSize=12,
  3382.               offsetXY="-"..(uiMiddleZone/16).." 0",
  3383.             },
  3384.             value="Attacker"
  3385.           },
  3386.         }
  3387.       },
  3388.       {
  3389.         tag="Panel",
  3390.         attributes={
  3391.           class="bkgPanel",
  3392.           width=uiMiddleZone/2,
  3393.           rectAlignment="UpperRight",
  3394.         },
  3395.         children={
  3396.           {
  3397.             tag="Toggle",
  3398.             attributes={
  3399.               id="kts__toggle_defender_selected",
  3400.               rectAlignment="MiddleRight",
  3401.               offsetXY="10 0",
  3402.               onValueChanged=self.getGUID().."/onDefenderSelected",
  3403.               isOn=checkListStatus.rollOffDefender,
  3404.             },
  3405.           },
  3406.           {
  3407.             tag="Text",
  3408.             attributes={
  3409.             fontSize=12,
  3410.             offsetXY="-"..(uiMiddleZone/16).." 0",
  3411.             },
  3412.             value="Defender"
  3413.           },
  3414.         }
  3415.       },
  3416.     }
  3417.   }
  3418. end
  3419. function buildFaction1(yPos, uiWidth, uiMiddleZone, panelHeight, player)
  3420.   return {
  3421.     tag="Panel",
  3422.     attributes={
  3423.       class="bkgPanel",
  3424.       height=panelHeight,
  3425.       rectAlignment="UpperCenter",
  3426.       offsetXY="0 "..yPos,
  3427.     },
  3428.     children={
  3429.       {
  3430.         tag="Panel",
  3431.         attributes={
  3432.           class="bkgPanel",
  3433.           width=uiMiddleZone,
  3434.           rectAlignment="UpperCenter",
  3435.         },
  3436.         children={
  3437.           {
  3438.             tag="Text",
  3439.             attributes={
  3440.               id="kts__dropdown_"..string.lower(player.color).."_faction_text",
  3441.               fontSize=12,
  3442.               text="Faction "..(player.steam_name ~= nil and player.steam_name or "no_player"),
  3443.             },
  3444.           },
  3445.         }
  3446.       },
  3447.     }
  3448.   }
  3449. end
  3450. function buildFaction2(yPos, uiWidth, uiMiddleZone, panelHeight, player)
  3451.   local imperiumFactionsOpts = buildDropdownUI(imperiumFactions, player.steam_name)
  3452.   local chaosFactionsOpts = buildDropdownUI(chaosFactions, player.steam_name)
  3453.   local xenosFactionsOpts = buildDropdownUI(xenosFactions, player.steam_name)
  3454.   local aeldariFactionsOpts = buildDropdownUI(aeldariFactions, player.steam_name)
  3455.   return {
  3456.     tag="Panel",
  3457.     attributes={
  3458.       class="bkgPanel",
  3459.       height=35,
  3460.       rectAlignment="UpperCenter",
  3461.       offsetXY="0 "..yPos,
  3462.       onMouseExit=self.getGUID().."/on"..player.color.."FactionPanelMouseExit",
  3463.       onMouseEnter=self.getGUID().."/on"..player.color.."FactionMouseEnter",
  3464.     },
  3465.     children={
  3466.       {
  3467.         tag="Panel",
  3468.         attributes={
  3469.           id="kts__dropdown_"..string.lower(player.color).."_faction",
  3470.           visibility="Blue|"..player.color.."|Black|Grey",
  3471.           onMouseExit=self.getGUID().."/on"..player.color.."FactionPanelMouseExit",
  3472.           onMouseEnter=self.getGUID().."/on"..player.color.."FactionMouseEnter",
  3473.           class="bkgPanel",
  3474.           width=uiMiddleZone/2,
  3475.           rectAlignment="UpperLeft",
  3476.           padding="10 10 3 3",
  3477.         },
  3478.         children={
  3479.           {
  3480.             tag="Dropdown",
  3481.             attributes={
  3482.               id="kts__dropdown_"..string.lower(player.color).."_super_faction",
  3483.               fontSize=12,
  3484.               onValueChanged=self.getGUID().."/on"..player.color.."SuperFactionSelected",
  3485.               onMouseEnter=self.getGUID().."/on"..player.color.."FactionMouseEnter",
  3486.             },
  3487.             children={
  3488.               {
  3489.                 tag="Option",
  3490.                 attributes={
  3491.                   selected=player.steam_name ~= nil and checkListStatus[player.steam_name].superFaction == "Select One" and true or false or true,
  3492.                 },
  3493.                 value="Select One",
  3494.               },
  3495.               {
  3496.                 tag="Option",
  3497.                 attributes={
  3498.                   selected=player.steam_name ~= nil and checkListStatus[player.steam_name].superFaction == "Imperium" and true or false or false,
  3499.                 },
  3500.                 value="Imperium",
  3501.               },
  3502.               {
  3503.                 tag="Option",
  3504.                 attributes={
  3505.                   selected=player.steam_name ~= nil and checkListStatus[player.steam_name].superFaction == "Chaos" and true or false or false,
  3506.                 },
  3507.                 value="Chaos",
  3508.               },
  3509.               {
  3510.                 tag="Option",
  3511.                 attributes={
  3512.                   selected=player.steam_name ~= nil and checkListStatus[player.steam_name].superFaction == "Xenos" and true or false or false,
  3513.                 },
  3514.                 value="Xenos",
  3515.               },
  3516.               {
  3517.                 tag="Option",
  3518.                 attributes={
  3519.                   selected=player.steam_name ~= nil and checkListStatus[player.steam_name].superFaction == "Aeldari" and true or false or false,
  3520.                 },
  3521.                 value="Aeldari",
  3522.               },
  3523.             }
  3524.           }
  3525.         }
  3526.       },
  3527.       {
  3528.         tag="Panel",
  3529.         attributes={
  3530.           id="kts__dropdown_"..string.lower(player.color).."_faction_1",
  3531.           visibility="Blue|"..player.color.."|Black|Grey",
  3532.           onMouseExit=self.getGUID().."/on"..player.color.."FactionPanelMouseExit",
  3533.           onMouseEnter=self.getGUID().."/on"..player.color.."FactionMouseEnter",
  3534.           class="bkgPanel",
  3535.           width=uiMiddleZone/2,
  3536.           rectAlignment="UpperRight",
  3537.           padding="10 10 3 3",
  3538.         },
  3539.         children={
  3540.           {
  3541.             tag="Dropdown",
  3542.             attributes={
  3543.               id="kts__dropdown_"..string.lower(player.color).."_faction_imperium",
  3544.               active=player.steam_name ~= nil and checkListStatus[player.steam_name].superFaction == "Imperium" and true or false or false,
  3545.               fontSize=12,
  3546.               onValueChanged=self.getGUID().."/on"..player.color.."FactionSelected",
  3547.               onMouseEnter=self.getGUID().."/on"..player.color.."FactionMouseEnter",
  3548.             },
  3549.             children=imperiumFactionsOpts,
  3550.           },
  3551.           {
  3552.             tag="Dropdown",
  3553.             attributes={
  3554.               id="kts__dropdown_"..string.lower(player.color).."_faction_chaos",
  3555.               active=player.steam_name ~= nil and checkListStatus[player.steam_name].superFaction == "Chaos" and true or false or false,
  3556.               fontSize=12,
  3557.               onValueChanged=self.getGUID().."/on"..player.color.."FactionSelected",
  3558.               onMouseEnter=self.getGUID().."/on"..player.color.."FactionMouseEnter",
  3559.             },
  3560.             children=chaosFactionsOpts,
  3561.           },
  3562.           {
  3563.             tag="Dropdown",
  3564.             attributes={
  3565.               id="kts__dropdown_"..string.lower(player.color).."_faction_aeldari",
  3566.               active=player.steam_name ~= nil and checkListStatus[player.steam_name].superFaction == "Aeldari" and true or false or false,
  3567.               fontSize=12,
  3568.               onValueChanged=self.getGUID().."/on"..player.color.."FactionSelected",
  3569.               onMouseEnter=self.getGUID().."/on"..player.color.."FactionMouseEnter",
  3570.             },
  3571.             children=aeldariFactionsOpts,
  3572.           },
  3573.           {
  3574.             tag="Dropdown",
  3575.             attributes={
  3576.               id="kts__dropdown_"..string.lower(player.color).."_faction_xenos",
  3577.               active=player.steam_name ~= nil and checkListStatus[player.steam_name].superFaction == "Xenos" and true or false or false,
  3578.               fontSize=12,
  3579.               onValueChanged=self.getGUID().."/on"..player.color.."FactionSelected",
  3580.               onMouseEnter=self.getGUID().."/on"..player.color.."FactionMouseEnter",
  3581.             },
  3582.             children=xenosFactionsOpts,
  3583.           },
  3584.         }
  3585.       },
  3586.     }
  3587.   }
  3588. end
  3589. function buildTacOpsSelected1(yPos, uiWidth, uiMiddleZone, panelHeight)
  3590.   return {
  3591.     tag="Panel",
  3592.     attributes={
  3593.       class="bkgPanel",
  3594.       height=panelHeight,
  3595.       rectAlignment="UpperCenter",
  3596.       offsetXY="0 "..yPos,
  3597.     },
  3598.     children={
  3599.       {
  3600.         tag="Panel",
  3601.         attributes={
  3602.           class="bkgPanel",
  3603.           rectAlignment="UpperCenter",
  3604.         },
  3605.         children={
  3606.           {
  3607.             tag="Text",
  3608.             attributes={
  3609.               fontSize=12,
  3610.             },
  3611.             value="Tac Ops Selected?"
  3612.           },
  3613.         }
  3614.       },
  3615.     }
  3616.   }
  3617. end
  3618. function buildTacOpsSelected2(yPos, uiWidth, uiMiddleZone, panelHeight)
  3619.   return {
  3620.     tag="Panel",
  3621.     attributes={
  3622.       class="bkgPanel",
  3623.       height=panelHeight,
  3624.       rectAlignment="UpperCenter",
  3625.       offsetXY="0 "..yPos,
  3626.     },
  3627.     children={
  3628.       {
  3629.         tag="Panel",
  3630.         attributes={
  3631.           class="bkgPanel",
  3632.           width=uiMiddleZone/2,
  3633.           rectAlignment="UpperLeft",
  3634.         },
  3635.         children={
  3636.           {
  3637.             tag="Text",
  3638.             attributes={
  3639.               id="kts__toggle_red_tacops_text",
  3640.               text=Player['Red'].steam_name ~= nil and Player['Red'].steam_name or "no_player",
  3641.               fontSize=12,
  3642.               offsetXY="-"..(uiMiddleZone/16).." 0",
  3643.             },
  3644.           },
  3645.           {
  3646.             tag="Toggle",
  3647.             attributes={
  3648.               id="kts__toggle_red_tacops",
  3649.               rectAlignment="MiddleRight",
  3650.               offsetXY="10 0",
  3651.               onValueChanged=self.getGUID().."/onRedTacOpsSelected",
  3652.               isOn=Player['Red'].steam_name ~= nil and checkListStatus[Player['Red'].steam_name].tacOps == "True" and true or false or false,
  3653.             },
  3654.           },
  3655.         }
  3656.       },
  3657.       {
  3658.         tag="Panel",
  3659.         attributes={
  3660.           class="bkgPanel",
  3661.           width=uiMiddleZone/2,
  3662.           rectAlignment="UpperRight",
  3663.         },
  3664.         children={
  3665.           {
  3666.             tag="Text",
  3667.             attributes={
  3668.               id="kts__toggle_blue_tacops_text",
  3669.               fontSize=12,
  3670.               offsetXY="-"..(uiMiddleZone/16).." 0",
  3671.               text=Player['Blue'].steam_name ~= nil and Player['Blue'].steam_name or "no_player",
  3672.             },
  3673.           },
  3674.           {
  3675.             tag="Toggle",
  3676.             attributes={
  3677.               id="kts__toggle_blue_tacops",
  3678.               rectAlignment="MiddleRight",
  3679.               offsetXY="10 0",
  3680.               onValueChanged=self.getGUID().."/onBlueTacOpsSelected",
  3681.               isOn=Player['Blue'].steam_name ~= nil and checkListStatus[Player['Blue'].steam_name].tacOps == "True" and true or false or false,
  3682.             },
  3683.           },
  3684.         }
  3685.       }
  3686.     }
  3687.   }
  3688. end
  3689. function buildEquipmentSelected1(yPos, uiWidth, uiMiddleZone, panelHeight)
  3690.   return {
  3691.     tag="Panel",
  3692.     attributes={
  3693.       class="bkgPanel",
  3694.       height=panelHeight,
  3695.       rectAlignment="UpperCenter",
  3696.       offsetXY="0 "..yPos,
  3697.     },
  3698.     children={
  3699.       {
  3700.         tag="Panel",
  3701.         attributes={
  3702.           class="bkgPanel",
  3703.           width=uiMiddleZone,
  3704.           rectAlignment="UpperCenter",
  3705.         },
  3706.         children={
  3707.           {
  3708.             tag="Text",
  3709.             attributes={
  3710.               fontSize=12,
  3711.             },
  3712.             value="Equipment selected?"
  3713.           },
  3714.         }
  3715.       },
  3716.     }
  3717.   }
  3718. end
  3719. function buildEquipmentSelected2(yPos, uiWidth, uiMiddleZone, panelHeight)
  3720.   return {
  3721.     tag="Panel",
  3722.     attributes={
  3723.       class="bkgPanel",
  3724.       height=panelHeight,
  3725.       rectAlignment="UpperCenter",
  3726.       offsetXY="0 "..yPos,
  3727.     },
  3728.     children={
  3729.       {
  3730.         tag="Panel",
  3731.         attributes={
  3732.           class="bkgPanel",
  3733.           width=uiMiddleZone/2,
  3734.           rectAlignment="UpperLeft",
  3735.         },
  3736.         children={
  3737.           {
  3738.             tag="Text",
  3739.             attributes={
  3740.               id="kts__toggle_red_equipment_text",
  3741.               text=Player['Red'].steam_name ~= nil and Player['Red'].steam_name or "no_player",
  3742.               fontSize=12,
  3743.               offsetXY="-"..(uiMiddleZone/16).." 0"
  3744.             },
  3745.           },
  3746.           {
  3747.             tag="Toggle",
  3748.             attributes={
  3749.               id="kts__toggle_red_equipment",
  3750.               rectAlignment="MiddleRight",
  3751.               offsetXY="10 0",
  3752.               onValueChanged=self.getGUID().."/onRedEquipmentSelected",
  3753.               isOn=Player['Red'].steam_name ~= nil and checkListStatus[Player['Red'].steam_name].equipment == "True" and true or false or false,
  3754.             },
  3755.           },
  3756.         }
  3757.       },
  3758.       {
  3759.         tag="Panel",
  3760.         attributes={
  3761.           class="bkgPanel",
  3762.           width=uiMiddleZone/2,
  3763.           rectAlignment="UpperRight",
  3764.         },
  3765.         children={
  3766.           {
  3767.             tag="Text",
  3768.             attributes={
  3769.               id="kts__toggle_blue_equipment_text",
  3770.               text=Player['Blue'].steam_name ~= nil and Player['Blue'].steam_name or "no_player",
  3771.               fontSize=12,
  3772.               offsetXY="-"..(uiMiddleZone/16).." 0"
  3773.             },
  3774.           },
  3775.           {
  3776.             tag="Toggle",
  3777.             attributes={
  3778.               id="kts__toggle_blue_equipment",
  3779.               offsetXY="10 0",
  3780.               rectAlignment="MiddleRight",
  3781.               onValueChanged=self.getGUID().."/onBlueEquipmentSelected",
  3782.               isOn=Player['Blue'].steam_name ~= nil and checkListStatus[Player['Blue'].steam_name].equipment == "True" and true or false or false,
  3783.             },
  3784.           },
  3785.         }
  3786.       }
  3787.     }
  3788.   }
  3789. end
  3790. function buildBarricadePlacing1(yPos, uiWidth, uiMiddleZone, panelHeight)
  3791.   return {
  3792.     tag="Panel",
  3793.     attributes={
  3794.       class="bkgPanel",
  3795.       height=panelHeight,
  3796.       rectAlignment="UpperCenter",
  3797.       offsetXY="0 "..yPos,
  3798.     },
  3799.     children={
  3800.       {
  3801.         tag="Panel",
  3802.         attributes={
  3803.           class="bkgPanel",
  3804.           width=uiMiddleZone,
  3805.           rectAlignment="UpperCenter",
  3806.         },
  3807.         children={
  3808.           {
  3809.             tag="Text",
  3810.             attributes={
  3811.               fontSize=12,
  3812.             },
  3813.             value="Barricades placed?"
  3814.           },
  3815.         }
  3816.       },
  3817.     }
  3818.   }
  3819. end
  3820. function buildBarricadePlacing2(yPos, uiWidth, uiMiddleZone, panelHeight)
  3821.   return {
  3822.     tag="Panel",
  3823.     attributes={
  3824.       class="bkgPanel",
  3825.       height=panelHeight,
  3826.       rectAlignment="UpperCenter",
  3827.       offsetXY="0 "..yPos,
  3828.     },
  3829.     children={
  3830.       {
  3831.         tag="Panel",
  3832.         attributes={
  3833.           class="bkgPanel",
  3834.           width=uiMiddleZone/2,
  3835.           rectAlignment="UpperLeft",
  3836.         },
  3837.         children={
  3838.           {
  3839.             tag="Text",
  3840.             attributes={
  3841.               id="kts__toggle_red_barricades_text",
  3842.               text=Player['Red'].steam_name ~= nil and Player['Red'].steam_name or "no_player",
  3843.               fontSize=12,
  3844.               offsetXY="-"..(uiMiddleZone/16).." 0"
  3845.             },
  3846.           },
  3847.           {
  3848.             tag="Toggle",
  3849.             attributes={
  3850.               id="kts__toggle_red_barricades",
  3851.               rectAlignment="MiddleRight",
  3852.               offsetXY="10 0",
  3853.               onValueChanged=self.getGUID().."/onRedBarricadesPlaced",
  3854.               isOn=Player['Red'].steam_name ~= nil and checkListStatus[Player['Red'].steam_name].barricades == "True" and true or false or false,
  3855.             },
  3856.           },
  3857.         }
  3858.       },
  3859.       {
  3860.         tag="Panel",
  3861.         attributes={
  3862.           class="bkgPanel",
  3863.           width=uiMiddleZone/2,
  3864.           rectAlignment="UpperRight",
  3865.         },
  3866.         children={
  3867.           {
  3868.             tag="Text",
  3869.             attributes={
  3870.               id="kts__toggle_blue_barricades_text",
  3871.               text=Player['Blue'].steam_name ~= nil and Player['Blue'].steam_name or "no_player",
  3872.               fontSize=12,
  3873.               offsetXY="-"..(uiMiddleZone/16).." 0"
  3874.             },
  3875.           },
  3876.           {
  3877.             tag="Toggle",
  3878.             attributes={
  3879.               id="kts__toggle_blue_barricades",
  3880.               offsetXY="10 0",
  3881.               rectAlignment="MiddleRight",
  3882.               onValueChanged=self.getGUID().."/onBlueBarricadesPlaced",
  3883.               isOn=Player['Blue'].steam_name ~= nil and checkListStatus[Player['Blue'].steam_name].barricades == "True" and true or false or false,
  3884.             },
  3885.           },
  3886.         }
  3887.       }
  3888.     }
  3889.   }
  3890. end
  3891. function buildDeploymentDone1(yPos, uiWidth, uiMiddleZone, panelHeight)
  3892.   return {
  3893.     tag="Panel",
  3894.     attributes={
  3895.       class="bkgPanel",
  3896.       height=panelHeight,
  3897.       rectAlignment="UpperCenter",
  3898.       offsetXY="0 "..yPos,
  3899.     },
  3900.     children={
  3901.       {
  3902.         tag="Panel",
  3903.         attributes={
  3904.           class="bkgPanel",
  3905.           rectAlignment="UpperCenter",
  3906.         },
  3907.         children={
  3908.           {
  3909.             tag="Text",
  3910.             attributes={
  3911.               fontSize=12,
  3912.             },
  3913.             value="Operatives deployed/orders given?"
  3914.           },
  3915.         }
  3916.       },
  3917.     }
  3918.   }
  3919. end
  3920. function buildDeploymentDone2(yPos, uiWidth, uiMiddleZone, panelHeight)
  3921.   return {
  3922.     tag="Panel",
  3923.     attributes={
  3924.       class="bkgPanel",
  3925.       height=panelHeight,
  3926.       rectAlignment="UpperCenter",
  3927.       offsetXY="0 "..yPos,
  3928.     },
  3929.     children={
  3930.       {
  3931.         tag="Panel",
  3932.         attributes={
  3933.           class="bkgPanel",
  3934.           width=uiMiddleZone/2,
  3935.           rectAlignment="UpperLeft",
  3936.         },
  3937.         children={
  3938.           {
  3939.             tag="Text",
  3940.             attributes={
  3941.               id="kts__toggle_red_deployed_text",
  3942.               text=Player['Red'].steam_name ~= nil and Player['Red'].steam_name or "no_player",
  3943.               fontSize=12,
  3944.               offsetXY="-"..(uiMiddleZone/16).." 0"
  3945.             },
  3946.           },
  3947.           {
  3948.             tag="Toggle",
  3949.             attributes={
  3950.               id="kts__toggle_red_deployed",
  3951.               offsetXY="10 0",
  3952.               rectAlignment="MiddleRight",
  3953.               onValueChanged=self.getGUID().."/onRedDeployed",
  3954.               isOn=Player['Red'].steam_name ~= nil and checkListStatus[Player['Red'].steam_name].deployed == "True" and true or false or false,
  3955.             },
  3956.           },
  3957.         }
  3958.       },
  3959.       {
  3960.         tag="Panel",
  3961.         attributes={
  3962.           class="bkgPanel",
  3963.           width=uiMiddleZone/2,
  3964.           rectAlignment="UpperRight",
  3965.         },
  3966.         children={
  3967.           {
  3968.             tag="Text",
  3969.             attributes={
  3970.               id="kts__toggle_blue_deployed_text",
  3971.               text=Player['Blue'].steam_name ~= nil and Player['Blue'].steam_name or "no_player",
  3972.               fontSize=12,
  3973.               offsetXY="-"..(uiMiddleZone/16).." 0"
  3974.             },
  3975.           },
  3976.           {
  3977.             tag="Toggle",
  3978.             attributes={
  3979.               id="kts__toggle_blue_deployed",
  3980.               rectAlignment="MiddleRight",
  3981.               offsetXY="10 0",
  3982.               onValueChanged=self.getGUID().."/onBlueDeployed",
  3983.               isOn=Player['Blue'].steam_name ~= nil and checkListStatus[Player['Blue'].steam_name].deployed == "True" and true or false or false,
  3984.             },
  3985.           },
  3986.         }
  3987.       }
  3988.     }
  3989.   }
  3990. end
  3991. function buildAllowOverwatch1(yPos, uiWidth, uiMiddleZone, panelHeight)
  3992.   return {
  3993.     tag="Panel",
  3994.     attributes={
  3995.       class="bkgPanel",
  3996.       height=panelHeight,
  3997.       rectAlignment="UpperCenter",
  3998.       offsetXY="0 "..yPos,
  3999.     },
  4000.     children={
  4001.       {
  4002.         tag="Panel",
  4003.         attributes={
  4004.           class="bkgPanel",
  4005.           rectAlignment="UpperCenter",
  4006.         },
  4007.         children={
  4008.           {
  4009.             tag="Text",
  4010.             attributes={
  4011.               fontSize=12,
  4012.             },
  4013.             value="Allow Overwatch functionallity"
  4014.           },
  4015.         }
  4016.       },
  4017.     }
  4018.   }
  4019. end
  4020. function buildAllowOverwatch2(yPos, uiWidth, uiMiddleZone, panelHeight)
  4021.   return {
  4022.     tag="Panel",
  4023.     attributes={
  4024.       class="bkgPanel",
  4025.       height=panelHeight,
  4026.       rectAlignment="UpperCenter",
  4027.       offsetXY="0 "..yPos,
  4028.     },
  4029.     children={
  4030.       {
  4031.         tag="Toggle",
  4032.         attributes={
  4033.           id="kts__toggle_overwatch",
  4034.           tooltip="Do you allow the mod to help you with Overwatch?",
  4035.           tooltipPosition="Above",
  4036.           onValueChanged=self.getGUID().."/onAllowOverwatchSelected",
  4037.           isOn=checkListStatus.allowOW == "True" and true or false,
  4038.         },
  4039.       },
  4040.     }
  4041.   }
  4042. end
  4043. function buildScoutingPhase1(yPos, uiWidth, uiMiddleZone, panelHeight)
  4044.   return {
  4045.     tag="Panel",
  4046.     attributes={
  4047.       class="bkgPanel",
  4048.       height=panelHeight,
  4049.       rectAlignment="UpperCenter",
  4050.       offsetXY="0 "..yPos,
  4051.     },
  4052.     children={
  4053.       {
  4054.         tag="Panel",
  4055.         attributes={
  4056.           class="bkgPanel",
  4057.           rectAlignment="UpperCenter",
  4058.         },
  4059.         children={
  4060.           {
  4061.             tag="Text",
  4062.             attributes={
  4063.               fontSize=12,
  4064.             },
  4065.             value="Scouting Phase"
  4066.           },
  4067.         }
  4068.       },
  4069.     }
  4070.   }
  4071. end
  4072. function buildScoutingPhase2(yPos, uiWidth, uiMiddleZone, panelHeight)
  4073.   return {
  4074.     tag="Panel",
  4075.     attributes={
  4076.       class="bkgPanel",
  4077.       height=35,
  4078.       rectAlignment="UpperCenter",
  4079.       offsetXY="0 "..yPos,
  4080.     },
  4081.     children={
  4082.       {
  4083.         tag="Panel",
  4084.         attributes={
  4085.           class="bkgPanel",
  4086.           width=uiMiddleZone/3,
  4087.           rectAlignment="UpperLeft",
  4088.           padding="10 10 3 3",
  4089.           visibility="Red|Black"
  4090.         },
  4091.         children={
  4092.           {
  4093.             tag="Dropdown",
  4094.             attributes={
  4095.               id="kts__dropdown_red_scouting",
  4096.               fontSize=12,
  4097.               onValueChanged=self.getGUID().."/onRedScoutingSelected",
  4098.             },
  4099.             children={
  4100.               {
  4101.                 tag="Option",
  4102.                 attributes={
  4103.                   selected=Player['Red'].steam_name ~= nil and checkListStatus[Player['Red'].steam_name].scouting == "Select One" and true or false or true,
  4104.                 },
  4105.                 value="Select One",
  4106.               },
  4107.               {
  4108.                 tag="Option",
  4109.                 attributes={
  4110.                   selected=Player['Red'].steam_name ~= nil and checkListStatus[Player['Red'].steam_name].scouting == "Fortify" and true or false or false,
  4111.                 },
  4112.                 value="Fortify",
  4113.               },
  4114.               {
  4115.                 tag="Option",
  4116.                 attributes={
  4117.                   selected=Player['Red'].steam_name ~= nil and checkListStatus[Player['Red'].steam_name].scouting == "Infiltrate" and true or false or false,
  4118.                 },
  4119.                 value="Infiltrate",
  4120.               },
  4121.               {
  4122.                 tag="Option",
  4123.                 attributes={
  4124.                   selected=Player['Red'].steam_name ~= nil and checkListStatus[Player['Red'].steam_name].scouting == "Recon" and true or false or false,
  4125.                 },
  4126.                 value="Recon",
  4127.               },
  4128.             }
  4129.           },
  4130.         }
  4131.       },
  4132.       {
  4133.         tag="Panel",
  4134.         attributes={
  4135.           class="bkgPanel",
  4136.           width=uiMiddleZone/3,
  4137.           rectAlignment="UpperLeft",
  4138.           padding="10 10 3 3",
  4139.           visibility="Blue|Black"
  4140.         },
  4141.         children={
  4142.           {
  4143.             tag="Dropdown",
  4144.             attributes={
  4145.               id="kts__dropdown_blue_scouting",
  4146.               fontSize=12,
  4147.               onValueChanged=self.getGUID().."/onBlueScoutingSelected",
  4148.             },
  4149.             children={
  4150.               {
  4151.                 tag="Option",
  4152.                 attributes={
  4153.                   selected=Player['Blue'].steam_name ~= nil and checkListStatus[Player['Blue'].steam_name].scouting == "Select One" and true or false or true,
  4154.                 },
  4155.                 value="Select One",
  4156.               },
  4157.               {
  4158.                 tag="Option",
  4159.                 attributes={
  4160.                   selected=Player['Blue'].steam_name ~= nil and checkListStatus[Player['Blue'].steam_name].scouting == "Fortify" and true or false or false,
  4161.                 },
  4162.                 value="Fortify",
  4163.               },
  4164.               {
  4165.                 tag="Option",
  4166.                 attributes={
  4167.                   selected=Player['Blue'].steam_name ~= nil and checkListStatus[Player['Blue'].steam_name].scouting == "Infiltrate" and true or false or false,
  4168.                 },
  4169.                 value="Infiltrate",
  4170.               },
  4171.               {
  4172.                 tag="Option",
  4173.                 attributes={
  4174.                   selected=Player['Blue'].steam_name ~= nil and checkListStatus[Player['Blue'].steam_name].scouting == "Recon" and true or false or false,
  4175.                 },
  4176.                 value="Recon",
  4177.               },
  4178.             }
  4179.           },
  4180.         }
  4181.       },
  4182.       {
  4183.         tag="Panel",
  4184.         attributes={
  4185.           class="bkgPanel",
  4186.           width=uiMiddleZone/3,
  4187.           rectAlignment="UpperCenter",
  4188.         },
  4189.         children={
  4190.           {
  4191.             tag="Toggle",
  4192.             attributes={
  4193.               id="kts__toggle_reveal_scouting",
  4194.               onValueChanged=self.getGUID().."/onRevealScouting",
  4195.               rectAlignment="MiddleRight",
  4196.               offsetXY="30 0",
  4197.               isOn=checkListStatus.revealed,
  4198.             },
  4199.           },
  4200.           {
  4201.             tag="Text",
  4202.             attributes={
  4203.               fontSize=12,
  4204.               rectAlignment="MiddleLeft",
  4205.             },
  4206.             value="Reveal"
  4207.           },
  4208.         }
  4209.       },
  4210.       {
  4211.         tag="Panel",
  4212.         attributes={
  4213.           class="bkgPanel",
  4214.           width=uiMiddleZone/3,
  4215.           rectAlignment="UpperRight",
  4216.         },
  4217.         children={
  4218.           {
  4219.             tag="Text",
  4220.             attributes={
  4221.               id="kts__scouting_resolution",
  4222.               fontSize=12,
  4223.             },
  4224.             value=checkListStatus.winner,
  4225.           },
  4226.         }
  4227.       },
  4228.     }
  4229.   }
  4230. end
  4231. function buildControlButtons(yPos, uiWidth, uiMiddleZone, panelHeight)
  4232.   return {
  4233.     tag="Panel",
  4234.     attributes={
  4235.       class="bkgPanel",
  4236.       height=panelHeight*2,
  4237.       rectAlignment="UpperCenter",
  4238.       offsetXY="0 "..yPos,
  4239.     },
  4240.     children={
  4241.       {
  4242.         tag="Button",
  4243.         attributes={
  4244.           id="kts__start_over_button",
  4245.           onClick=self.getGUID().."/onStartOverBtn",
  4246.           width=uiMiddleZone/3,
  4247.           rectAlignment="MiddleLeft",
  4248.         },
  4249.         value="Start Over"
  4250.       },
  4251.       {
  4252.         tag="Button",
  4253.         attributes={
  4254.           id="kts__hide_checklist_button",
  4255.           onClick=self.getGUID().."/onHideChecklistBtn",
  4256.           width=uiMiddleZone/3,
  4257.           rectAlignment="MiddleCenter",
  4258.         },
  4259.         value="Hide Checklist"
  4260.       },
  4261.       {
  4262.         tag="Button",
  4263.         attributes={
  4264.           id="kts__start_game_button",
  4265.           onClick=self.getGUID().."/onStartGameBtn",
  4266.           width=uiMiddleZone/3,
  4267.           rectAlignment="MiddleRight",
  4268.         },
  4269.         value="Let's WAAAAAAGH!!"
  4270.       },
  4271.     }
  4272.   }
  4273. end
  4274. function buildHUDCheck(def)
  4275.   local guid = self.getGUID()
  4276.   local uiWidth = 650
  4277.   local uiHeight = 990
  4278.   local panelHeight = 25
  4279.   local panelID = "kts__checklist_panel"
  4280.   local chl = {}
  4281.   local chr = {}
  4282.   local logoVisible = rules.art.graphics.eventLogo ~= nil
  4283.   local uiSubWidth = uiWidth*0.5
  4284.   local logoWidth = rules.art.gui.overlay.logoWidth
  4285.   local logoHeight = rules.art.gui.overlay.logoHeight
  4286.   local uiMiddleZone = 350
  4287.   local nameplateWidth = math.floor(uiSubWidth*0.5 + 32)
  4288.  
  4289.   if logoVisible then
  4290.     uiMiddleZone = math.max(uiMiddleZone, logoWidth+4)
  4291.   end
  4292.   uiWidth = uiWidth + uiMiddleZone
  4293.   local yPos = -31
  4294.   local yPosOffsS = 26
  4295.   local yPosOffsL1 = 36
  4296.   local yPosOffsL2 = 31
  4297.   local videoTutorialTitle = buildVideoTutorial1(yPos, uiWidth, uiMiddleZone, panelHeight)
  4298.   yPos = yPos - yPosOffsS
  4299.   local videoTutorial = buildVideoTutorial2(yPos, uiWidth, uiMiddleZone, panelHeight)
  4300.   yPos = yPos - yPosOffsS
  4301.   local allowDataCollectionTitle = buildAllowDataCollection1(yPos, uiWidth, uiMiddleZone, panelHeight)
  4302.   yPos = yPos - yPosOffsS
  4303.   local allowDataCollection = buildAllowDataCollection2(yPos, uiWidth, uiMiddleZone, panelHeight)
  4304.   yPos = yPos - yPosOffsS
  4305.   local secondaryTitle = buildSecondaryTitle(yPos, uiWidth, uiMiddleZone, panelHeight)
  4306.   yPos = yPos - yPosOffsL2
  4307.   local gameTypeTitle = buildGameType1(yPos, uiWidth, uiMiddleZone, panelHeight)
  4308.   yPos = yPos - yPosOffsS
  4309.   local gameType = buildGameType2(yPos, uiWidth, uiMiddleZone, panelHeight)
  4310.   yPos = yPos - yPosOffsL1
  4311.   local tournamentTitle = buildTournament1(yPos, uiWidth, uiMiddleZone, panelHeight)
  4312.   yPos = yPos - yPosOffsS
  4313.   local tournament = buildTournament2(yPos, uiWidth, uiMiddleZone, panelHeight)
  4314.   yPos = yPos - yPosOffsL1
  4315.   local killZoneLoadedTitle = buildKillZoneLoaded1(yPos, uiWidth, uiMiddleZone, panelHeight)
  4316.   yPos = yPos - yPosOffsS
  4317.   local killZoneLoaded = buildKillZoneLoaded2(yPos, uiWidth, uiMiddleZone, panelHeight)
  4318.   yPos = yPos - yPosOffsS
  4319.   local selectMissionTitle = buildSelectMission1(yPos, uiWidth, uiMiddleZone, panelHeight)
  4320.   yPos = yPos - yPosOffsS
  4321.   local selectMission = buildSelectMission2(yPos, uiWidth, uiMiddleZone, panelHeight)
  4322.   yPos = yPos - yPosOffsL1
  4323.   local rollOffWinnerTitle = buildRollOffWinner1(yPos, uiWidth, uiMiddleZone, panelHeight)
  4324.   yPos = yPos - yPosOffsS - 1
  4325.   local rollOffWinner = buildRollOffWinner2(yPos, uiWidth, uiMiddleZone, panelHeight)
  4326.   yPos = yPos - yPosOffsS
  4327.   local rollOffSelectionTitle = buildRollOffSelection1(yPos, uiWidth, uiMiddleZone, panelHeight)
  4328.   yPos = yPos - yPosOffsS
  4329.   local rollOffSelection = buildRollOffSelection2(yPos, uiWidth, uiMiddleZone, panelHeight)
  4330.   yPos = yPos - yPosOffsS
  4331.   local redFactionTitle = buildFaction1(yPos, uiWidth, uiMiddleZone, panelHeight, Player['Red'])
  4332.   yPos = yPos - yPosOffsS
  4333.   local redFaction = buildFaction2(yPos, uiWidth, uiMiddleZone, panelHeight, Player['Red'])
  4334.   yPos = yPos - yPosOffsL1
  4335.   local blueFactionTitle = buildFaction1(yPos, uiWidth, uiMiddleZone, panelHeight, Player['Blue'])
  4336.   yPos = yPos - yPosOffsS
  4337.   local blueFaction = buildFaction2(yPos, uiWidth, uiMiddleZone, panelHeight, Player['Blue'])
  4338.   yPos = yPos - yPosOffsL1
  4339.   local tacOpsSelectedTitle = buildTacOpsSelected1(yPos, uiWidth, uiMiddleZone, panelHeight)
  4340.   yPos = yPos - yPosOffsS
  4341.   local tacOpsSelected = buildTacOpsSelected2(yPos, uiWidth, uiMiddleZone, panelHeight)
  4342.   yPos = yPos - yPosOffsS
  4343.   local equipmentSelectedTitle = buildEquipmentSelected1(yPos, uiWidth, uiMiddleZone, panelHeight)
  4344.   yPos = yPos - yPosOffsS
  4345.   local equipmentSelected = buildEquipmentSelected2(yPos, uiWidth, uiMiddleZone, panelHeight)
  4346.   yPos = yPos - yPosOffsS
  4347.   local barricadePlacingTitle = buildBarricadePlacing1(yPos, uiWidth, uiMiddleZone, panelHeight)
  4348.   yPos = yPos - yPosOffsS
  4349.   local barricadePlacing = buildBarricadePlacing2(yPos, uiWidth, uiMiddleZone, panelHeight)
  4350.   yPos = yPos - yPosOffsS
  4351.   local deploymentDoneTitle = buildDeploymentDone1(yPos, uiWidth, uiMiddleZone, panelHeight)
  4352.   yPos = yPos - yPosOffsS
  4353.   local deploymentDone = buildDeploymentDone2(yPos, uiWidth, uiMiddleZone, panelHeight)
  4354.   yPos = yPos - yPosOffsS
  4355.   local allowOverwatchTitle = buildAllowOverwatch1(yPos, uiWidth, uiMiddleZone, panelHeight)
  4356.   yPos = yPos - yPosOffsS
  4357.   local allowOverwatch = buildAllowOverwatch2(yPos, uiWidth, uiMiddleZone, panelHeight)
  4358.   yPos = yPos - yPosOffsS
  4359.   local scoutingPhaseTitle = buildScoutingPhase1(yPos, uiWidth, uiMiddleZone, panelHeight)
  4360.   yPos = yPos - yPosOffsS
  4361.   local scoutingPhase = buildScoutingPhase2(yPos, uiWidth, uiMiddleZone, panelHeight)
  4362.   yPos = yPos - yPosOffsL1
  4363.   local controlButtons = buildControlButtons(yPos, uiWidth, uiMiddleZone, panelHeight)
  4364.  
  4365.   local checkPanel = {
  4366.     --Pregame Checklist
  4367.     --Title
  4368.     {
  4369.       tag="Panel",
  4370.       attributes={
  4371.         class="bkgPanel",
  4372.         height=30,
  4373.         rectAlignment="UpperCenter",
  4374.       },
  4375.       children={
  4376.         {
  4377.           tag="Text",
  4378.           attributes={
  4379.             class="title2",
  4380.             fontSize=20,
  4381.           },
  4382.           value="Pre-Game Checklist"
  4383.         },
  4384.       }
  4385.     },
  4386.     --Video tutorial
  4387.     videoTutorialTitle,
  4388.     videoTutorial,
  4389.     --Allow data collection
  4390.     allowDataCollectionTitle,
  4391.     allowDataCollection,
  4392.     --Secondary title
  4393.     secondaryTitle,
  4394.     --Game type
  4395.     gameTypeTitle,
  4396.     gameType,
  4397.     --Tournament
  4398.     tournamentTitle,
  4399.     tournament,
  4400.     --Kill Zone Loaded
  4401.     killZoneLoadedTitle,
  4402.     killZoneLoaded,
  4403.     --Mission
  4404.     selectMissionTitle,
  4405.     selectMission,
  4406.     --Roll off winner
  4407.     rollOffWinnerTitle,
  4408.     rollOffWinner,
  4409.     --Roll Off winner Selection
  4410.     rollOffSelectionTitle,
  4411.     rollOffSelection,
  4412.     --Red Faction
  4413.     redFactionTitle,
  4414.     redFaction,
  4415.     --Blue Faction
  4416.     blueFactionTitle,
  4417.     blueFaction,
  4418.     --Tac Ops Selected
  4419.     tacOpsSelectedTitle,
  4420.     tacOpsSelected,
  4421.     --Equipment selected
  4422.     equipmentSelectedTitle,
  4423.     equipmentSelected,
  4424.     --Barricades placed
  4425.     barricadePlacingTitle,
  4426.     barricadePlacing,
  4427.     --Operatives Deployed
  4428.     deploymentDoneTitle,
  4429.     deploymentDone,
  4430.     --Allow Overwatch
  4431.     allowOverwatchTitle,
  4432.     allowOverwatch,
  4433.     --Scouting Phase
  4434.     scoutingPhaseTitle,
  4435.     scoutingPhase,
  4436.     --Control Buttons
  4437.     controlButtons,
  4438.   }
  4439.  
  4440.   local mainCheckPanel = {
  4441.     tag="Panel",
  4442.     attributes={
  4443.       id=panelID,
  4444.       class="mainPanel",
  4445.       width=uiMiddleZone,
  4446.       height=uiHeight,
  4447.       visibility="White",
  4448.       rectAlignment="LowerLeft",
  4449.       offsetXY="80 30",
  4450.     },
  4451.     children = checkPanel
  4452.   }
  4453.   return mainCheckPanel
  4454. end
  4455. --ADDED by ZAKA
  4456.  
  4457. function buildUI()
  4458.   loadAssets(rules.art.graphics)
  4459.  
  4460.   --build the screen overlay
  4461.   --screen overlay should be generated instead of a flat xml file
  4462.   --it should be themed the same as everything else
  4463.   --UI.setXml(uiScreenOverlay)
  4464.  
  4465.   --generate default UI classes
  4466.   local defaults = makeDefaults(rules)
  4467.  
  4468.   Wait.frames(function() buildHUD(defaults) end, 20)
  4469.  
  4470.  
  4471.   --build the main scoreboard
  4472.   buildScoreboard(defaults)
  4473.  
  4474.   --[[
  4475.   build dashboards.
  4476.  
  4477.   local dashboards = getObjectsWithTag(dashboardTag)
  4478.   for _, board in pairs(dashboards) do
  4479.     board.UI.setCustomAssets(assets)
  4480.     buildDashboard(board, defaults)
  4481.   end
  4482.   showUI("kts_startHidden")]]
  4483. end
  4484.  
  4485. function loadGM()
  4486.   local tabs = Notes.getNotebookTabs()
  4487.   local gmn = nil
  4488.   for _,t in pairs(tabs) do
  4489.     if t.title == settingsNotes then
  4490.       gmn = t.body
  4491.       break
  4492.     end
  4493.   end
  4494.   if gmn == nil then
  4495.     broadcastToAll(setupMessage)
  4496.     gmn = defaultSettings
  4497.     Notes.addNotebookTab({
  4498.       title=settingsNotes,
  4499.       body=gmn,
  4500.       color="Black"
  4501.     })
  4502.   end
  4503.   local settings = JSON.decode(gmn)
  4504.  
  4505.   setup(settings)
  4506.   buildUI()
  4507.   Wait.frames(refresh, 10)
  4508.   Timer.create({
  4509.     identifier=self.getGUID(),
  4510.     function_name="checkPlayerHands",
  4511.     delay=1,
  4512.     repetitions=0
  4513.   })
  4514. end
  4515.  
  4516. function onSave()
  4517.   local save = {
  4518.     splayers=players,
  4519.     splayerNumber=playerNumber,
  4520.     srules=rules,
  4521.     sscoring=scoring,
  4522.  
  4523.     --ADDED by ZAKA
  4524.     sresult = result,
  4525.     schecklist = checkListStatus,
  4526.     sgamestate = gameStateMachine,
  4527.     soverwatch = overwatchTable,
  4528.     --ADDED by ZAKA
  4529.  
  4530.   }
  4531.   return JSON.encode(save)
  4532. end
  4533.  
  4534. function checkPlayerHands()
  4535.   for pl, c in pairs(rules.packet.players) do
  4536.     p = Player[c]
  4537.     hobjs = p.getHandObjects()
  4538.     honames = {}
  4539.     for n, o in pairs(hobjs) do
  4540.       table.insert(honames, o.getName())
  4541.     end
  4542.     uiid = "ktw__streamerSecondaries_player"..pl
  4543.     if #honames > 0 then
  4544.       if #honames > 3 then
  4545.         setUIValue(uiid, "Too many\nin hand")
  4546.       else
  4547.         setUIValue(uiid, table.concat(honames,"\n"))
  4548.       end
  4549.     else
  4550.       setUIValue(uiid, "")
  4551.     end
  4552.   end
  4553. end
  4554.  
  4555. function onLoad(state)
  4556.   self.setTags({scoreboardTag})
  4557.   if state then
  4558.     local state = JSON.decode(state)
  4559.     if state then
  4560.       players = state["splayers"] or players
  4561.       playerNumber = state["splayerNumber"] or playerNumber
  4562.       rules = state["srules"] or rules
  4563.       scoring = state["sscoring"] or scoring
  4564.  
  4565.       --ADDED by ZAKA
  4566.       result = state["sresult"] or result
  4567.       checkListStatus = state["schecklist"] or checkListStatus
  4568.       gameStateMachine = state["sgamestate"] or gameStateMachine
  4569.       overwatchTable = state["soverwatch"] or overwatchTable
  4570.       updateMegaDeck()
  4571.       --ADDED by ZAKA
  4572.  
  4573.     end
  4574.   end
  4575.  
  4576.   --ADDED by ZAKA
  4577.   if Player["Red"].steam_name ~= nil then
  4578.     if checkListStatus[Player["Red"].steam_name] == nil then
  4579.       checkListStatus[Player["Red"].steam_name] = {
  4580.         name = "",
  4581.         allow = false,
  4582.         faction = "Select One",
  4583.         tacOps = false,
  4584.         equipment = false,
  4585.         barricades = false,
  4586.         deployed = false,
  4587.         allowOW = false,
  4588.         scouting = "Select One",
  4589.       }
  4590.     end
  4591.   end
  4592.   if Player["Blue"].steam_name ~= nil then
  4593.     if checkListStatus[Player["Blue"].steam_name] == nil then
  4594.       checkListStatus[Player["Blue"].steam_name] = {
  4595.         name = "",
  4596.         allow = false,
  4597.         faction = "Select One",
  4598.         tacOps = false,
  4599.         equipment = false,
  4600.         barricades = false,
  4601.         deployed = false,
  4602.         allowOW = false,
  4603.         scouting = "Select One",
  4604.       }
  4605.     end
  4606.   end
  4607.   --ADDED by ZAKA
  4608.  
  4609.   loadGM()
  4610. end
  4611.  
  4612. function setSecondaryObjective(pl, sec, name)
  4613.   local selector = atrSecondary(pl, sec, "dropdown")
  4614.   local display = atrSecondary(pl, sec, "display")
  4615.   setUIValue(display, name)
  4616.   hideUI(selector)
  4617.   showUI(display)
  4618.  
  4619.   setUIValue(atrSecondary(pl, sec, "streamer"), name)
  4620.   scoring[pl].secondary[sec][1]=name
  4621.   refreshSecondaryUI(pl, sec)
  4622. end
  4623.  
  4624. function onSecondarySelected(pl, val, id)
  4625.   local pl, sec = string.gmatch(id, "(%d+)_(%d+)")()
  4626.   setSecondaryObjective(tonumber(pl), tonumber(sec), val)
  4627. end
  4628.  
  4629. function refreshSecondaryUI(pl, sec)
  4630.   local secondary = scoring[pl].secondary[sec]
  4631.   local max = rules.scoring.secondary.maxExemption[secondary[1]] or rules.scoring.secondary.maxEach
  4632.   local newstr
  4633.   if max > 0 then
  4634.     newstr = string.format("%d/%d", secondary[2], max)
  4635.   else
  4636.     newstr = string.format("%d", secondary[2])
  4637.   end
  4638.   setUIValue(atrSecondary(pl, sec, "amount"), newstr)
  4639.   setUIValue(atrSecondary(pl, sec, "streamer_amount"), newstr)
  4640. end
  4641.  
  4642. function setSecondaryScore(pl, sec, val)
  4643.   local secondary = scoring[pl].secondary[sec]
  4644.   local max = rules.scoring.secondary.maxExemption[secondary[1]] or rules.scoring.secondary.maxEach
  4645.   local newval = math.max(0, math.min(val, max))
  4646.   secondary[2] = newval
  4647.  
  4648.   --ADDED by ZAKA
  4649.   if val == newval then
  4650.     setSecondaryResult(pl, sec, 1)
  4651.   end
  4652.   --ADDED by ZAKA
  4653.  
  4654.   refreshSecondaryUI(pl, sec)
  4655.   updateScoreUI(pl)
  4656. end
  4657.  
  4658. function refreshBonusUI(pl)
  4659.   local value = scoring[pl].secondary[4]
  4660.   local max = rules.scoring.bonus.max
  4661.   local newstr
  4662.   if max > 0 then
  4663.     newstr = string.format("%d/%d", value, max)
  4664.   else
  4665.     newstr = string.format("%d", value)
  4666.   end
  4667.   setUIValue("kts__bonus_display_player"..pl, newstr)
  4668.   setUIValue("kts__bonus_display_player"..pl.."_streamer", newstr)
  4669. end
  4670.  
  4671. function setBonusScore(pl, val)
  4672.   local max = rules.scoring.bonus.max
  4673.   scoring[pl].secondary[4] = math.max(0, math.min(val, max))
  4674.  
  4675.   refreshBonusUI(pl)
  4676.   updateScoreUI(pl)
  4677. end
  4678.  
  4679. function onIncreaseSecondary(player, val, id)
  4680.   local pl, sec = string.gmatch(id, "(%d+)_(%d+)")()
  4681.   pl, sec = tonumber(pl), tonumber(sec)
  4682.   if allowRecord(pl, true) then
  4683.     setSecondaryScore(pl, sec, scoring[pl].secondary[sec][2] + 1)
  4684.   else
  4685.     showMaxRecordMessage(player)
  4686.   end
  4687. end
  4688.  
  4689. function onDecreaseSecondary(player, val, id)
  4690.   local pl, sec = string.gmatch(id, "(%d+)_(%d+)")()
  4691.   pl, sec = tonumber(pl), tonumber(sec)
  4692.   setSecondaryScore(pl, sec, scoring[pl].secondary[sec][2] - 1)
  4693. end
  4694.  
  4695. function onIncreaseBonus(player, val, id)
  4696.   local pl = tonumber(string.gmatch(id, "(%d+)")())
  4697.   if allowRecord(pl, true) then
  4698.     setBonusScore(pl, scoring[pl].secondary[4] + 1)
  4699.   else
  4700.     showMaxRecordMessage(player)
  4701.   end
  4702. end
  4703.  
  4704. function onDecreaseBonus(player, val, id)
  4705.   local pl = tonumber(string.gmatch(id, "(%d+)")())
  4706.   setBonusScore(pl, scoring[pl].secondary[4] - 1)
  4707. end
  4708.  
  4709. function updateScoreUI(pl)
  4710.   local score, ps, ss = calculateScore(pl)
  4711.   local primary = string.format("%d/%d", ps, rules.scoring.primary.max)
  4712.   local secondary = string.format("%d/%d", ss, rules.scoring.secondary.max)
  4713.   local grand = string.format("%d", ps + ss)
  4714.  
  4715.   setUIValue("kts__primarytotal_player"..pl, primary)
  4716.   setUIValue("kts__primarytotal_player"..pl.."_streamer", primary)
  4717.  
  4718.   setUIValue("kts__secondarytotal_player"..pl, secondary)
  4719.   setUIValue("kts__secondarytotal_player"..pl.."_streamer", secondary)
  4720.  
  4721.   setUIValue("kts__grandtotal_player"..pl, grand)
  4722.   setUIValue("kts__grandtotal_player"..pl.."_streamer", grand)
  4723.  
  4724.   if score == rules.scoring.max then
  4725.     showUI("kts__grandtotal_max_player"..pl)
  4726.   else
  4727.     hideUI("kts__grandtotal_max_player"..pl)
  4728.   end
  4729. end
  4730.  
  4731. function setPrimaryUI(pl, rule, round, value)
  4732.   local toggleID = atrPrimary(pl, rule, round, "toggle")
  4733.   local displayID = atrPrimary(pl, rule, round, "streamer")
  4734.   if value then
  4735.     setUIAttribute(toggleID, "image", "primaryOn")
  4736.     setUIAttribute(displayID, "image", "primaryOn")
  4737.   else
  4738.     setUIAttribute(toggleID, "image", "primaryOff")
  4739.     setUIAttribute(displayID, "image", "primaryOff")
  4740.   end
  4741. end
  4742.  
  4743. function togglePrimary(pl, rule, round)
  4744.   local otherPlayer = (pl==1) and 2 or 1
  4745.   local value = not scoring[pl].primary[rule][round]
  4746.   local exclusive = rules.scoring.primary.exclusive[rule]
  4747.   if allowRecord(pl, value, rule) then
  4748.     setPrimaryUI(pl, rule, round, value)
  4749.  
  4750.     scoring[pl].primary[rule][round] = value
  4751.     updateScoreUI(pl)
  4752.     if value and exclusive and scoring[otherPlayer].primary[rule][round] == true then
  4753.       togglePrimary(otherPlayer, rule, round)
  4754.     end
  4755.   else
  4756.     return false
  4757.   end
  4758.   return true
  4759. end
  4760.  
  4761. function onPrimaryPressed(player, val, id)
  4762.   local pl, rule, round = string.gmatch(id, "(%d+)_(%d+)_(%d+)")()
  4763.   if not togglePrimary(tonumber(pl), tonumber(rule), tonumber(round)) then
  4764.     showMaxRecordMessage(player)
  4765.   end
  4766. end
  4767.  
  4768. function setInitiativeUI(pl, round, value)
  4769.   local toggleID = atrInitiative(pl, round, "toggle")
  4770.   local displayID = atrInitiative(pl, round, "streamer")
  4771.   if value then
  4772.     setUIAttribute(toggleID, "image", "initiativeOn")
  4773.     setUIAttribute(displayID, "image", "initiativeOn")
  4774.   else
  4775.     setUIAttribute(toggleID, "image", "initiativeOff")
  4776.     setUIAttribute(displayID, "image", "initiativeOff")
  4777.   end
  4778. end
  4779.  
  4780. function updateInitiativeUI()
  4781.   local round = 0
  4782.   local ip, np = 0, 0
  4783.   local maxRounds = rules.scoring.maxRounds
  4784.   for i=maxRounds,1,-1 do
  4785.     if scoring[1].initiative[i] then
  4786.       round = i
  4787.       ip, np = 1, 2
  4788.       break
  4789.     end
  4790.     if scoring[2].initiative[i] then
  4791.       round = i
  4792.       ip, np = 2, 1
  4793.       break
  4794.     end
  4795.   end
  4796.  
  4797.   if round > 0 then
  4798.     showUI("kts__initiative_display_player"..ip)
  4799.     hideUI("kts__initiative_display_player"..np)
  4800.     setUIValue("kts__round_current", "Round "..round)
  4801.   else
  4802.     hideUI("kts__initiative_display_player1")
  4803.     hideUI("kts__initiative_display_player2")
  4804.     setUIValue("kts__round_current", "Pre game")
  4805.   end
  4806. end
  4807.  
  4808. function toggleInitiative(pl, round)
  4809.   local otherPlayer = (pl==1) and 2 or 1
  4810.   local si = scoring[pl].initiative
  4811.   local osi = scoring[otherPlayer].initiative
  4812.   local value = not si[round]
  4813.   setInitiativeUI(pl, round, value)
  4814.   si[round] = value
  4815.   if value and osi[round] then
  4816.     toggleInitiative(otherPlayer, round)
  4817.   end
  4818. end
  4819.  
  4820. function onInitiativePressed(player, val, id)
  4821.   local pl, round = string.gmatch(id, "(%d+)_(%d+)")()
  4822.   toggleInitiative(tonumber(pl), tonumber(round))
  4823.   updateInitiativeUI()
  4824. end
  4825.  
  4826. function setDropdownItem(id, value)
  4827.   local drop = dropdowns[id]
  4828.   if drop then
  4829.     local item = drop.items[value]
  4830.     if item and item ~= drop.selected then
  4831.       --setUIAttribute(id, "selectedIndex", item)
  4832.       setUIValue(id, item)
  4833.       drop.selected = item
  4834.     end
  4835.   end
  4836. end
  4837.  
  4838. function setCommandPoints(pl, val)
  4839.   scoring[pl].command = val
  4840.   local ncpv = string.format("%d CP", val)
  4841.   local uiid = "kts__command_player"..pl
  4842.   setUIValue(uiid, ncpv)
  4843.   setUIValue(uiid.."_streamer", ncpv)
  4844. end
  4845.  
  4846. function onCommandPointUpPressed(player, val, id)
  4847.   local pl = tonumber(string.gmatch(id, "player(%d+)")())
  4848.   setCommandPoints(pl, scoring[pl].command + 1)
  4849. end
  4850.  
  4851. function onCommandPointDownPressed(player, val, id)
  4852.   local pl = tonumber(string.gmatch(id, "player(%d+)")())
  4853.   setCommandPoints(pl, scoring[pl].command - 1)
  4854. end
  4855.  
  4856. function allowRecord(pl, increase, primary)
  4857.   local primary = primary or false
  4858.   if increase and rules.scoring.limitRecordToMax then
  4859.     local ts, ps, ss = calculateScore(pl)
  4860.     if ts < rules.scoring.max then
  4861.       if primary then
  4862.         local max = rules.scoring.primary.max
  4863.         local maxEach = rules.scoring.primary.maxEach
  4864.         if maxEach > 0 then
  4865.           local p = scoring[pl].primary[primary]
  4866.           local total = 0
  4867.           for k, v in pairs(p) do
  4868.             total = total + (v and 1 or 0)
  4869.           end
  4870.           if total >= maxEach then return false end
  4871.         end
  4872.         if max > 0 then
  4873.           return ps < max
  4874.         end
  4875.       else
  4876.         local max = rules.scoring.secondary.max
  4877.         if max > 0 then
  4878.           return ss < max
  4879.         end
  4880.       end
  4881.       return true
  4882.     end
  4883.     return false
  4884.   end
  4885.   return true
  4886. end
  4887.  
  4888. function comSetSecondary(params)
  4889.   local color = params.player
  4890.   local secondary = params.secondary
  4891.   local name = params.name
  4892.   if color and secondary and name then
  4893.     local p = playerNumber[color]
  4894.     if p then
  4895.       setSecondaryObjective(p, secondary, name)
  4896.     end
  4897.   end
  4898. end
  4899.  
  4900. function showMaxRecordMessage(pl)
  4901.   broadcastToColor("Can't record this point: a point limit has been reached", pl.color, Color.red)
  4902. end
  4903.  
  4904. function onChat(message, sender)
  4905.   if sender.color == "Black" and message == "reload scoreboard" then
  4906.     broadcastToAll("Reloading scoreboard rules...")
  4907.     loadGM()
  4908.   end
  4909.  
  4910.   --ADDED by ZAKA
  4911.   if sender.color == "Black" and message == "my turn" then
  4912.     gameStateMachine.whoToPress = sender.steam_name
  4913.     setUIAttribute("kts__activated_button", "textColor", sender.color)
  4914.     broadcastToAll("Now it's "..gameStateMachine.whoToPress.." turn")
  4915.   end
  4916.   if sender.color == "Black" and message == "reset pregame data" then
  4917.     checkListStatus = {
  4918.       killZoneLoaded = false,
  4919.       allowOW = false,
  4920.       gameType = "Select One",
  4921.       edition = "Select One",
  4922.       mission = "Select One",
  4923.       rollOffWinner="Select One",
  4924.       rollOffAttacker=false,
  4925.       rollOffDefender=false,
  4926.       revealed=false,
  4927.       winner="",
  4928.     }
  4929.     updateCheckList()
  4930.   end
  4931.   --ADDED by ZAKA
  4932.  
  4933. end
  4934.  
  4935. --ADDED by ZAKA
  4936. function onTutorialClick(player)
  4937.   showYoutubeLink(player)
  4938. end
  4939. function onRedAcceptedDataCollection(player, value)
  4940.   if player.color == "Red" or player.color == "Blue" then
  4941.     if player.steam_name == getUIAttribute("kts__toggle_red_accept_text", "text") then
  4942.       setAllowData(player, value)
  4943.       checkListStatus[player.steam_name].allow = value
  4944.       setUIAttribute("kts__toggle_red_accept", "isOn", value == "True" and true or false)
  4945.       setUIAttribute("kts__toggle_red_accept", "backgroundColor", value == "True" and player.color or "White")
  4946.     else
  4947.       player.broadcast("Only "..getUIAttribute("kts__toggle_red_accept_text", "text").." can check this")
  4948.     end
  4949.   end
  4950.   setUIAttribute("kts__toggle_red_accept", "isOn", checkListStatus[getUIAttribute("kts__toggle_red_accept_text", "text")] ~= nil and checkListStatus[getUIAttribute("kts__toggle_red_accept_text", "text")].allow or checkListPlayer.allow)
  4951. end
  4952. function onBlueAcceptedDataCollection(player, value)
  4953.   if player.color == "Red" or player.color == "Blue" then
  4954.     if player.steam_name == getUIAttribute("kts__toggle_blue_accept_text", "text") then
  4955.       setAllowData(player, value)
  4956.       checkListStatus[player.steam_name].allow = value
  4957.       setUIAttribute("kts__toggle_blue_accept", "isOn", value == "True" and true or false)
  4958.       setUIAttribute("kts__toggle_blue_accept", "backgroundColor", value == "True" and player.color or "White")
  4959.     else
  4960.       player.broadcast("Only "..getUIAttribute("kts__toggle_blue_accept_text", "text").." can check this")
  4961.     end
  4962.   end
  4963.   setUIAttribute("kts__toggle_blue_accept", "isOn", checkListStatus[getUIAttribute("kts__toggle_blue_accept_text", "text")] ~= nil and checkListStatus[getUIAttribute("kts__toggle_blue_accept_text", "text")].allow or checkListPlayer.allow)
  4964. end
  4965. function onEditionSelected(player, value)
  4966.   if player.color == "Red" or player.color == "Blue" then
  4967.     setUIAttribute("kts__dropdown_mission_open", "active", false)
  4968.     setUIAttribute("kts__dropdown_mission_itd", "active", false)
  4969.     result.edition = "Select One"
  4970.     checkListStatus.edition = "Select One"
  4971.     setUIAttribute("kts__dropdown_edition", "textColor", "#e74f0aff")
  4972.     if value ~= "Select One" then
  4973.       checkListStatus.edition = value
  4974.       result.edition = value
  4975.       if value == "KT 2021 - Open" then
  4976.         setUIAttribute("kts__dropdown_mission_open", "active", true)
  4977.         getObjectFromGUID(masterBagOpen).call("masterPlace")
  4978.       else
  4979.         setUIAttribute("kts__dropdown_mission_itd", "active", true)
  4980.         getObjectFromGUID(masterBagItd).call("masterPlace")
  4981.       end
  4982.       broadcastToAll("Edition: "..value.." selected")
  4983.       setUIAttribute("kts__dropdown_edition", "textColor", player.color)
  4984.     end
  4985.   end
  4986.   changeMultiDropdown({
  4987.     "kts__dropdown_edition",
  4988.     "kts__dropdown_mission_open",
  4989.     "kts__dropdown_mission_itd",
  4990.   },
  4991.   {
  4992.     checkListStatus.edition,
  4993.     "Select One",
  4994.     "Select One",
  4995.   })
  4996. end
  4997. function onGameTypeSelected(player, value)
  4998.   if player.color == "Red" or player.color == "Blue" then
  4999.     result.gameType = "Select One"
  5000.     checkListStatus.gameType = "Select One"
  5001.     setUIAttribute("kts__dropdown_game_type", "textColor", "#e74f0aff")
  5002.     if value ~= "Select One" then
  5003.       checkListStatus.gameType = value
  5004.       result.gameType = value
  5005.       broadcastToAll("Game type: "..value.." selected")
  5006.       setUIAttribute("kts__dropdown_game_type", "textColor", player.color)
  5007.     end
  5008.     if value ~= "Matched play" then
  5009.       result.tournament = "Select One"
  5010.       checkListStatus.tournament = "Select One"
  5011.       setUIAttribute("kts__dropdown_tournament", "textColor", "#e74f0aff")
  5012.       Wait.frames(function ()
  5013.         changeDropdown("kts__dropdown_tournament", "Select One")
  5014.       end, 50)
  5015.     end
  5016.   end
  5017.   changeDropdown("kts__dropdown_game_type", checkListStatus.gameType)
  5018. end
  5019. function onTournamentSelected(player, value)
  5020.   if player.color == "Red" or player.color == "Blue" then
  5021.     result.tournament = "Select One"
  5022.     checkListStatus.tournament = "Select One"
  5023.     setUIAttribute("kts__dropdown_tournament", "textColor", "#e74f0aff")
  5024.     if value ~= "Select One" then
  5025.       if result.gameType == "Matched Play" then
  5026.         checkListStatus.tournament = value
  5027.         result.tournament = value
  5028.         broadcastToAll("Tournament: "..value.." selected")
  5029.         setUIAttribute("kts__dropdown_tournament", "textColor", player.color)
  5030.       else
  5031.         broadcastToAll("To choose a tournament, select 'Matched play' on Game type")
  5032.       end
  5033.     end
  5034.   end
  5035.   changeDropdown("kts__dropdown_tournament", checkListStatus.tournament)
  5036. end
  5037. function onKillZoneLoaded(player, value)
  5038.   if player.color == "Red" or player.color == "Blue" then
  5039.     result.killZoneLoaded = value
  5040.     checkListStatus.killZoneLoaded = value
  5041.     setUIAttribute("kts__toggle_kz_loaded", "backgroundColor", value == "True" and player.color or "White")
  5042.   end
  5043.   setUIAttribute("kts__toggle_kz_loaded", "isOn", checkListStatus.killZoneLoaded == "True" and true or false)
  5044. end
  5045. function onOpenMissionSelected(player, value)
  5046.   if player.color == "Red" or player.color == "Blue" then
  5047.     for k,v in pairs(missionIndexOpen) do
  5048.       obj = getObjectFromGUID(k)
  5049.       if obj ~= nil then
  5050.         obj.call("buttonClick_recall")
  5051.       end
  5052.       obj = getObjectFromGUID(v.objGuid)
  5053.       if obj ~= nil then
  5054.         obj.call("buttonClick_recall")
  5055.       end
  5056.       if string.match(' '..value..' ', '%A'..v.code..'%A') ~= nil then
  5057.         setMission(missionIndexOpen[k])
  5058.         for k,v in pairs(missionIndexOpen) do
  5059.           if v == result.mission then
  5060.             Wait.frames(
  5061.               function()
  5062.                 obj = getObjectFromGUID(k)
  5063.                 if obj ~= nil then
  5064.                   obj.call("buttonClick_place")
  5065.                 end
  5066.                 obj = getObjectFromGUID(v.objGuid)
  5067.                 Wait.frames(
  5068.                 function ()
  5069.                   if obj ~= nil then
  5070.                     obj.call("buttonClick_place")
  5071.                   end
  5072.                 end, 30)
  5073.               end, 30
  5074.             )
  5075.             changeMissionScoreboard(k)
  5076.           end
  5077.         end
  5078.         checkListStatus.mission = value
  5079.         setUIAttribute("kts__dropdown_mission_open", "textColor", value == "Select One" and "#e74f0aff" or player.color)
  5080.       end
  5081.     end
  5082.   end
  5083.   Wait.frames(function()
  5084.     changeDropdown("kts__dropdown_mission_open", checkListStatus.mission)
  5085.   end, 10)
  5086. end
  5087. function onItdMissionSelected(player, value)
  5088.   if player.color == "Red" or player.color == "Blue" then
  5089.     for k,v in pairs(missionIndexItd) do
  5090.       obj = getObjectFromGUID(k)
  5091.       if obj ~= nil then
  5092.         obj.call("buttonClick_recall")
  5093.       end
  5094.       obj = getObjectFromGUID(v.objGuid)
  5095.       if obj ~= nil then
  5096.         obj.call("buttonClick_recall")
  5097.       end
  5098.       obj = getObjectFromGUID(v.terrainGuid)
  5099.       if obj ~= nil then
  5100.         obj.call("buttonClick_recall")
  5101.       end
  5102.       if string.match(' '..value..' ', '%A'..v.code..'%A') ~= nil then
  5103.         setMission(missionIndexItd[k])
  5104.         for k,v in pairs(missionIndexItd) do
  5105.           if v == result.mission then
  5106.             Wait.frames(
  5107.               function()
  5108.                 obj = getObjectFromGUID(k)
  5109.                 if obj ~= nil then
  5110.                   obj.call("buttonClick_place")
  5111.                 end
  5112.                 obj = getObjectFromGUID(v.objGuid)
  5113.                 Wait.frames(
  5114.                 function ()
  5115.                   if obj ~= nil then
  5116.                     obj.call("buttonClick_place")
  5117.                   end
  5118.                   obj = getObjectFromGUID(v.terrainGuid)
  5119.                   Wait.frames(
  5120.                   function ()
  5121.                     if obj ~= nil then
  5122.                       obj.call("buttonClick_place")
  5123.                     end
  5124.                   end, 30)
  5125.                 end, 30)
  5126.               end, 30
  5127.             )
  5128.             changeMissionScoreboard(k)
  5129.           end
  5130.         end
  5131.         checkListStatus.mission = value
  5132.         setUIAttribute("kts__dropdown_mission_itd", "textColor", value == "Select One" and "#e74f0aff" or player.color)
  5133.       end
  5134.     end
  5135.   end
  5136.   Wait.frames(function()
  5137.     changeDropdown("kts__dropdown_mission_itd", checkListStatus.mission)
  5138.   end, 10)
  5139. end
  5140. function onRedWonRollOff(player, value)
  5141.   if player.color == "Red" or player.color == "Blue" then
  5142.     if getUIAttribute("kts__red_rolloff_winner_text", "text") ~= "no_player" then
  5143.       checkListStatus.rollOffAttacker=false
  5144.       checkListStatus.rollOffDefender=false
  5145.       checkListStatus.rollOffWinner="Select One"
  5146.       result.rollOffWinner = nil
  5147.       result.rollOffLoser = nil
  5148.       setUIAttribute("kts__toggle_red_rolloff_winner", "backgroundColor", value == "True" and player.color or "White")
  5149.       if value == "True" then
  5150.         setUIAttribute("kts__toggle_blue_rolloff_winner", "isOn", false)
  5151.         setUIAttribute("kts__toggle_red_rolloff_winner", "isOn", true)
  5152.         setUIAttribute("kts__toggle_blue_rolloff_winner", "backgroundColor", "White")
  5153.         for _,pl in ipairs(Player.getPlayers()) do
  5154.           if pl.steam_name == getUIAttribute("kts__red_roloff_winner_text", "text") then
  5155.             checkListStatus.rollOffWinner = pl.steam_name
  5156.             setRollOffWinner(pl)
  5157.             if pl.color == "Red" then
  5158.               setRollOffLoser(Player["Blue"])
  5159.             else
  5160.               setRollOffLoser(Player["Red"])
  5161.             end
  5162.           end
  5163.         end
  5164.       end
  5165.       setUIAttribute("kts__toggle_attacker_selected", "isOn", checkListStatus.rollOffAttacker)
  5166.       setUIAttribute("kts__toggle_defender_selected", "isOn", checkListStatus.rollOffDefender)
  5167.     else
  5168.       broadcastToAll("No one is yet here")
  5169.     end
  5170.   else
  5171.     setUIAttribute("kts__toggle_red_rolloff_winner", "isOn", value=="True" and false or true)
  5172.   end
  5173. end
  5174. function onBlueWonRollOff(player, value)
  5175.   if player.color == "Red" or player.color == "Blue" then
  5176.     if getUIAttribute("kts__blue_rolloff_winner_text", "text") ~= "no_player" then
  5177.       checkListStatus.rollOffAttacker=false
  5178.       checkListStatus.rollOffDefender=false
  5179.       checkListStatus.rollOffWinner="Select One"
  5180.       result.rollOffWinner = nil
  5181.       result.rollOffLoser = nil
  5182.       setUIAttribute("kts__toggle_blue_rolloff_winner", "backgroundColor", value == "True" and player.color or "White")
  5183.       if value == "True" then
  5184.         setUIAttribute("kts__toggle_red_rolloff_winner", "isOn", false)
  5185.         setUIAttribute("kts__toggle_blue_rolloff_winner", "isOn", true)
  5186.         setUIAttribute("kts__toggle_red_rolloff_winner", "backgroundColor", "White")
  5187.         for _,pl in ipairs(Player.getPlayers()) do
  5188.           if pl.steam_name == getUIAttribute("kts__blue_roloff_winner_text", "text") then
  5189.             checkListStatus.rollOffWinner = pl.steam_name
  5190.             setRollOffWinner(pl)
  5191.             if pl.color == "Red" then
  5192.               setRollOffLoser(Player["Blue"])
  5193.             else
  5194.               setRollOffLoser(Player["Red"])
  5195.             end
  5196.           end
  5197.         end
  5198.       end
  5199.       setUIAttribute("kts__toggle_attacker_selected", "isOn", checkListStatus.rollOffAttacker)
  5200.       setUIAttribute("kts__toggle_defender_selected", "isOn", checkListStatus.rollOffDefender)
  5201.     else
  5202.       broadcastToAll("No one is yet here")
  5203.     end
  5204.   else
  5205.     setUIAttribute("kts__toggle_blue_rolloff_winner", "isOn", value=="True" and false or true)
  5206.   end
  5207. end
  5208. function onAttackerSelected(player, value)
  5209.   checkListStatus.rollOffAttacker=false
  5210.   checkListStatus.rollOffDefender=false
  5211.   if result.rollOffWinner ~= nil then
  5212.     if player.steam_name == result.rollOffWinner then
  5213.       result.rollOffWinnerSelection = "Attacker"
  5214.       checkListStatus.rollOffAttacker=true
  5215.       checkListStatus.rollOffDefender=false
  5216.     else
  5217.       broadcastToAll("Only "..result.rollOffWinner.." can select this")
  5218.     end
  5219.   else
  5220.     broadcastToAll("Select roll off winner")
  5221.   end
  5222.   setUIAttribute("kts__toggle_attacker_selected", "isOn", checkListStatus.rollOffAttacker)
  5223.   setUIAttribute("kts__toggle_defender_selected", "isOn", checkListStatus.rollOffDefender)
  5224. end
  5225. function onDefenderSelected(player, value)
  5226.   checkListStatus.rollOffAttacker=false
  5227.   checkListStatus.rollOffDefender=false
  5228.   if result.rollOffWinner ~= nil then
  5229.     if player.steam_name == result.rollOffWinner then
  5230.       result.rollOffWinnerSelection = "Defender"
  5231.       checkListStatus.rollOffAttacker=false
  5232.       checkListStatus.rollOffDefender=true
  5233.     else
  5234.       broadcastToAll("Only "..result.rollOffWinner.." can select this")
  5235.     end
  5236.   else
  5237.     broadcastToAll("Select roll off winner")
  5238.   end
  5239.   setUIAttribute("kts__toggle_attacker_selected", "isOn", checkListStatus.rollOffAttacker)
  5240.   setUIAttribute("kts__toggle_defender_selected", "isOn", checkListStatus.rollOffDefender)
  5241. end
  5242. function onRedSuperFactionSelected(player, value)
  5243.   if player.color == "Red" or player.color == "Blue" then
  5244.     if string.match(getUIAttribute("kts__dropdown_red_faction_text", "text"), player.steam_name) then
  5245.       setUIAttribute("kts__dropdown_red_faction_imperium", "active", false)
  5246.       setUIAttribute("kts__dropdown_red_faction_chaos", "active", false)
  5247.       setUIAttribute("kts__dropdown_red_faction_aeldari", "active", false)
  5248.       setUIAttribute("kts__dropdown_red_faction_xenos", "active", false)
  5249.       if checkListStatus[player.steam_name].superFaction ~= "Select One" then
  5250.         setFaction(player, "Select One")
  5251.       end
  5252.       setUIAttribute("kts__dropdown_red_faction_"..string.lower(value), "active", true)
  5253.       checkListStatus[player.steam_name].superFaction = value
  5254.       setUIAttribute("kts__dropdown_red_super_faction", "textColor", value == "Select One" and "#e74f0aff" or player.color)
  5255.     else
  5256.       broadcastToAll("Only "..split(getUIAttribute("kts__dropdown_red_faction_text", "text"), " ").." can select this")
  5257.     end
  5258.   end
  5259.   changeMultiDropdown({
  5260.     "kts__dropdown_red_super_faction",
  5261.     "kts__dropdown_red_faction_imperium",
  5262.     "kts__dropdown_red_faction_chaos",
  5263.     "kts__dropdown_red_faction_aeldari",
  5264.     "kts__dropdown_red_faction_xenos"
  5265.   },
  5266.   {
  5267.     checkListStatus[split(getUIAttribute("kts__dropdown_red_faction_text", "text"), " ")].superFaction,
  5268.     "Select One",
  5269.     "Select One",
  5270.     "Select One",
  5271.     "Select One"
  5272.   })
  5273. end
  5274. function onRedFactionSelected(player, value)
  5275.   if player.color == "Red" or player.color == "Blue" then
  5276.     if string.match(getUIAttribute("kts__dropdown_red_faction_text", "text"), player.steam_name) then
  5277.       setFaction(player, value)
  5278.       checkListStatus[player.steam_name].faction = value
  5279.       setUIAttribute("kts__dropdown_red_faction_imperium", "textColor", value == "Select One" and "#e74f0aff" or player.color)
  5280.       setUIAttribute("kts__dropdown_red_faction_chaos", "textColor", value == "Select One" and "#e74f0aff" or player.color)
  5281.       setUIAttribute("kts__dropdown_red_faction_aeldari", "textColor", value == "Select One" and "#e74f0aff" or player.color)
  5282.       setUIAttribute("kts__dropdown_red_faction_xenos", "textColor", value == "Select One" and "#e74f0aff" or player.color)
  5283.     else
  5284.       broadcastToAll("Only "..split(getUIAttribute("kts__dropdown_red_faction_text", "text"), " ").." can select this")
  5285.     end
  5286.   end
  5287.   changeDropdown("kts__dropdown_red_faction_"..string.lower(checkListStatus[split(getUIAttribute("kts__dropdown_red_faction_text", "text"), " ")].superFaction), checkListStatus[split(getUIAttribute("kts__dropdown_red_faction_text", "text"), " ")].faction)
  5288. end
  5289. function onRedFactionMouseEnter(player)
  5290.   if not string.match(getUIAttribute("kts__dropdown_red_faction_text", "text"), player.steam_name) then
  5291.     factVis = getUIAttribute("kts__dropdown_red_faction", "visibility")
  5292.     factVis1 = getUIAttribute("kts__dropdown_red_faction_1", "visibility")
  5293.     color = player.color
  5294.     if string.match(factVis, color.."|") then
  5295.       setUIAttribute("kts__dropdown_red_faction", "visibility", string.gsub(factVis, color.."|", ""))
  5296.     elseif string.match(factVis, color) then
  5297.       setUIAttribute("kts__dropdown_red_faction", "visibility", string.gsub(factVis, color, ""))
  5298.     end
  5299.     if string.match(factVis1, color.."|") then
  5300.       setUIAttribute("kts__dropdown_red_faction_1", "visibility", string.gsub(factVis1, color.."|", ""))
  5301.     elseif string.match(factVis1, color) then
  5302.       setUIAttribute("kts__dropdown_red_faction_1", "visibility", string.gsub(factVis1, color, ""))
  5303.     end
  5304.   end
  5305. end
  5306. function onRedFactionPanelMouseExit(player)
  5307.   factVis = getUIAttribute("kts__dropdown_red_faction", "visibility")
  5308.   factVis1 = getUIAttribute("kts__dropdown_red_faction_1", "visibility")
  5309.   color = player.color
  5310.   if not string.match(factVis, color) then
  5311.     setUIAttribute("kts__dropdown_red_faction", "visibility", color.."|"..factVis)
  5312.   end
  5313.   if not string.match(factVis1, color) then
  5314.     setUIAttribute("kts__dropdown_red_faction_1", "visibility", color.."|"..factVis1)
  5315.   end
  5316. end
  5317. function onBlueSuperFactionSelected(player, value)
  5318.   if player.color == "Red" or player.color == "Blue" then
  5319.     if string.match(getUIAttribute("kts__dropdown_blue_faction_text", "text"), player.steam_name) then
  5320.       setUIAttribute("kts__dropdown_blue_faction_imperium", "active", false)
  5321.       setUIAttribute("kts__dropdown_blue_faction_chaos", "active", false)
  5322.       setUIAttribute("kts__dropdown_blue_faction_aeldari", "active", false)
  5323.       setUIAttribute("kts__dropdown_blue_faction_xenos", "active", false)
  5324.       if checkListStatus[player.steam_name].superFaction ~= "Select One" then
  5325.         changeMultiDropdown({
  5326.           "kts__dropdown_blue_faction_imperium",
  5327.           "kts__dropdown_blue_faction_chaos",
  5328.           "kts__dropdown_blue_faction_aeldari",
  5329.           "kts__dropdown_blue_faction_xenos"
  5330.         },
  5331.         {
  5332.           "Select One",
  5333.           "Select One",
  5334.           "Select One",
  5335.           "Select One"
  5336.         })
  5337.         setFaction(player, "Select One")
  5338.       end
  5339.       setUIAttribute("kts__dropdown_blue_faction_"..string.lower(value), "active", true)
  5340.       checkListStatus[player.steam_name].superFaction = value
  5341.       setUIAttribute("kts__dropdown_blue_super_faction", "textColor", value == "Select One" and "#e74f0aff" or player.color)
  5342.     else
  5343.       broadcastToAll("Only "..split(getUIAttribute("kts__dropdown_blue_faction_text", "text"), " ").." can select this")
  5344.     end
  5345.   end
  5346.   changeMultiDropdown({
  5347.     "kts__dropdown_blue_super_faction",
  5348.     "kts__dropdown_blue_faction_imperium",
  5349.     "kts__dropdown_blue_faction_chaos",
  5350.     "kts__dropdown_blue_faction_aeldari",
  5351.     "kts__dropdown_blue_faction_xenos"
  5352.   },
  5353.   {
  5354.     checkListStatus[split(getUIAttribute("kts__dropdown_blue_faction_text", "text"), " ")].superFaction,
  5355.     "Select One",
  5356.     "Select One",
  5357.     "Select One",
  5358.     "Select One"
  5359.   })
  5360. end
  5361. function onBlueFactionSelected(player, value)
  5362.   if player.color == "Red" or player.color == "Blue" then
  5363.     if string.match(getUIAttribute("kts__dropdown_blue_faction_text", "text"), player.steam_name) then
  5364.       setFaction(player, value)
  5365.       checkListStatus[player.steam_name].faction = value
  5366.         setUIAttribute("kts__dropdown_blue_faction_imperium", "textColor", value == "Select One" and "#e74f0aff" or player.color)
  5367.         setUIAttribute("kts__dropdown_blue_faction_chaos", "textColor", value == "Select One" and "#e74f0aff" or player.color)
  5368.         setUIAttribute("kts__dropdown_blue_faction_aeldari", "textColor", value == "Select One" and "#e74f0aff" or player.color)
  5369.         setUIAttribute("kts__dropdown_blue_faction_xenos", "textColor", value == "Select One" and "#e74f0aff" or player.color)
  5370.     else
  5371.       broadcastToAll("Only "..split(getUIAttribute("kts__dropdown_blue_faction_text", "text"), " ").." can select this")
  5372.     end
  5373.   end
  5374.   changeDropdown("kts__dropdown_blue_faction_"..string.lower(checkListStatus[split(getUIAttribute("kts__dropdown_blue_faction_text", "text"), " ")].superFaction), checkListStatus[split(getUIAttribute("kts__dropdown_blue_faction_text", "text"), " ")].faction)
  5375. end
  5376. function onBlueFactionMouseEnter(player)
  5377.   if not string.match(getUIAttribute("kts__dropdown_blue_faction_text", "text"), player.steam_name) then
  5378.     factVis = getUIAttribute("kts__dropdown_blue_faction", "visibility")
  5379.     factVis1 = getUIAttribute("kts__dropdown_blue_faction_1", "visibility")
  5380.     color = player.color
  5381.     if string.match(factVis, color.."|") then
  5382.       setUIAttribute("kts__dropdown_blue_faction", "visibility", string.gsub(factVis, color.."|", ""))
  5383.     elseif string.match(factVis, color) then
  5384.       setUIAttribute("kts__dropdown_blue_faction", "visibility", string.gsub(factVis, color, ""))
  5385.     end
  5386.     if string.match(factVis1, color.."|") then
  5387.       setUIAttribute("kts__dropdown_blue_faction_1", "visibility", string.gsub(factVis1, color.."|", ""))
  5388.     elseif string.match(factVis1, color) then
  5389.       setUIAttribute("kts__dropdown_blue_faction_1", "visibility", string.gsub(factVis1, color, ""))
  5390.     end
  5391.   end
  5392. end
  5393. function onBlueFactionPanelMouseExit(player)
  5394.   factVis = getUIAttribute("kts__dropdown_blue_faction", "visibility")
  5395.   factVis1 = getUIAttribute("kts__dropdown_blue_faction_1", "visibility")
  5396.   color = player.color
  5397.   if not string.match(factVis, color) then
  5398.     setUIAttribute("kts__dropdown_blue_faction", "visibility", color.."|"..factVis)
  5399.   end
  5400.   if not string.match(factVis1, color) then
  5401.     setUIAttribute("kts__dropdown_blue_faction_1", "visibility", color.."|"..factVis1)
  5402.   end
  5403. end
  5404. function onRedTacOpsSelected(player, value)
  5405.   if player.color == "Red" or player.color == "Blue" then
  5406.     if player.steam_name == getUIAttribute("kts__toggle_red_tacops_text", "text") then
  5407.       printToAll(player.steam_name.." selected TacOps")
  5408.       checkListStatus[player.steam_name].tacOps = value
  5409.       setUIAttribute("kts__toggle_red_tacops", "isOn", value == "True" and true or false)
  5410.       setUIAttribute("kts__toggle_red_tacops", "backgroundColor", value == "True" and player.color or "White")
  5411.     else
  5412.       player.broadcast("Only "..getUIAttribute("kts__toggle_red_tacops_text", "text").." can check this")
  5413.     end
  5414.   end
  5415.   setUIAttribute("kts__toggle_red_tacops", "isOn", checkListStatus[getUIAttribute("kts__toggle_red_tacops_text", "text")] ~= nil and checkListStatus[getUIAttribute("kts__toggle_red_tacops_text", "text")].tacOps or checkListPlayer.tacOps)
  5416. end
  5417. function onBlueTacOpsSelected(player, value)
  5418.   if player.color == "Red" or player.color == "Blue" then
  5419.     if player.steam_name == getUIAttribute("kts__toggle_blue_tacops_text", "text") then
  5420.       printToAll(player.steam_name.." selected TacOps")
  5421.       checkListStatus[player.steam_name].tacOps = value
  5422.       setUIAttribute("kts__toggle_blue_tacops", "isOn", value == "True" and true or false)
  5423.       setUIAttribute("kts__toggle_blue_tacops", "backgroundColor", value == "True" and player.color or "White")
  5424.     else
  5425.       player.broadcast("Only "..getUIAttribute("kts__toggle_blue_tacops_text", "text").." can check this")
  5426.     end
  5427.   end
  5428.   setUIAttribute("kts__toggle_blue_tacops", "isOn", checkListStatus[getUIAttribute("kts__toggle_blue_tacops_text", "text")] ~= nil and checkListStatus[getUIAttribute("kts__toggle_blue_tacops_text", "text")].tacOps or checkListPlayer.tacOps)
  5429. end
  5430. function onRedEquipmentSelected(player, value)
  5431.   if player.color == "Red" or player.color == "Blue" then
  5432.     if player.steam_name == getUIAttribute("kts__toggle_red_equipment_text", "text") then
  5433.       printToAll(player.steam_name.." selected equipment")
  5434.       checkListStatus[player.steam_name].equipment = value
  5435.       setUIAttribute("kts__toggle_red_equipment", "isOn", value == "True" and true or false)
  5436.       setUIAttribute("kts__toggle_red_equipment", "backgroundColor", value == "True" and player.color or "White")
  5437.     else
  5438.       player.broadcast("Only "..getUIAttribute("kts__toggle_red_equipment_text", "text").." can check this")
  5439.     end
  5440.   end
  5441.   setUIAttribute("kts__toggle_red_equipment", "isOn", checkListStatus[getUIAttribute("kts__toggle_red_equipment_text", "text")] ~= nil and checkListStatus[getUIAttribute("kts__toggle_red_equipment_text", "text")].equipment or checkListPlayer.equipment)
  5442. end
  5443. function onBlueEquipmentSelected(player, value)
  5444.   if player.color == "Red" or player.color == "Blue" then
  5445.     if player.steam_name == getUIAttribute("kts__toggle_blue_equipment_text", "text") then
  5446.       printToAll(player.steam_name.." selected equipment")
  5447.       checkListStatus[player.steam_name].equipment = value
  5448.       setUIAttribute("kts__toggle_blue_equipment", "isOn", value == "True" and true or false)
  5449.       setUIAttribute("kts__toggle_blue_equipment", "backgroundColor", value == "True" and player.color or "White")
  5450.     else
  5451.       player.broadcast("Only "..getUIAttribute("kts__toggle_blue_equipment_text", "text").." can check this")
  5452.     end
  5453.   end
  5454.   setUIAttribute("kts__toggle_blue_equipment", "isOn", checkListStatus[getUIAttribute("kts__toggle_blue_equipment_text", "text")] ~= nil and checkListStatus[getUIAttribute("kts__toggle_blue_equipment_text", "text")].equipment or checkListPlayer.equipment)
  5455. end
  5456. function onRedBarricadesPlaced(player, value)
  5457.   if player.color == "Red" or player.color == "Blue" then
  5458.     if player.steam_name == getUIAttribute("kts__toggle_red_barricades_text", "text") then
  5459.       printToAll(player.steam_name.." placed barricades")
  5460.       checkListStatus[player.steam_name].barricades = value
  5461.       setUIAttribute("kts__toggle_red_barricades", "isOn", value == "True" and true or false)
  5462.       setUIAttribute("kts__toggle_red_barricades", "backgroundColor", value == "True" and player.color or "White")
  5463.     else
  5464.       player.broadcast("Only "..getUIAttribute("kts__toggle_red_barricades_text", "text").." can check this")
  5465.     end
  5466.   end
  5467.   setUIAttribute("kts__toggle_red_barricades", "isOn", checkListStatus[getUIAttribute("kts__toggle_red_barricades_text", "text")] ~= nil and checkListStatus[getUIAttribute("kts__toggle_red_barricades_text", "text")].barricades or checkListPlayer.barricades)
  5468. end
  5469. function onBlueBarricadesPlaced(player, value)
  5470.   if player.color == "Red" or player.color == "Blue" then
  5471.     if player.steam_name == getUIAttribute("kts__toggle_blue_barricades_text", "text") then
  5472.       printToAll(player.steam_name.." placed barricades")
  5473.       checkListStatus[player.steam_name].barricades = value
  5474.       setUIAttribute("kts__toggle_blue_barricades", "isOn", value == "True" and true or false)
  5475.       setUIAttribute("kts__toggle_blue_barricades", "backgroundColor", value == "True" and player.color or "White")
  5476.     else
  5477.       player.broadcast("Only "..getUIAttribute("kts__toggle_blue_barricades_text", "text").." can check this")
  5478.     end
  5479.   end
  5480.   setUIAttribute("kts__toggle_blue_barricades", "isOn", checkListStatus[getUIAttribute("kts__toggle_blue_barricades_text", "text")] ~= nil and checkListStatus[getUIAttribute("kts__toggle_blue_barricades_text", "text")].barricades or checkListPlayer.barricades)
  5481. end
  5482. function onRedDeployed(player, value)
  5483.   if player.color == "Red" or player.color == "Blue" then
  5484.     if player.steam_name == getUIAttribute("kts__toggle_red_deployed_text", "text") then
  5485.       printToAll(player.steam_name.." has deployed")
  5486.       checkListStatus[player.steam_name].deployed = value
  5487.       setUIAttribute("kts__toggle_red_deployed", "isOn", value == "True" and true or false)
  5488.       setUIAttribute("kts__toggle_red_deployed", "backgroundColor", value == "True" and player.color or "White")
  5489.       Wait.frames(function()
  5490.         if value == "True" then
  5491.           showOperativeSelection(player)
  5492.         else
  5493.           deselectOperatives(player)
  5494.         end
  5495.       end, 1)
  5496.     else
  5497.       player.broadcast("Only "..getUIAttribute("kts__toggle_red_deployed_text", "text").." can check this")
  5498.     end
  5499.   end
  5500.   setUIAttribute("kts__toggle_red_deployed", "isOn", checkListStatus[getUIAttribute("kts__toggle_red_deployed_text", "text")] ~= nil and checkListStatus[getUIAttribute("kts__toggle_red_deployed_text", "text")].deployed or checkListPlayer.deployed)
  5501. end
  5502. function onBlueDeployed(player, value)
  5503.   if player.color == "Red" or player.color == "Blue" then
  5504.     if player.steam_name == getUIAttribute("kts__toggle_blue_deployed_text", "text") then
  5505.       printToAll(player.steam_name.." has deployed")
  5506.       checkListStatus[player.steam_name].deployed = value
  5507.       setUIAttribute("kts__toggle_blue_deployed", "isOn", value == "True" and true or false)
  5508.       setUIAttribute("kts__toggle_blue_deployed", "backgroundColor", value == "True" and player.color or "White")
  5509.       Wait.frames(function()
  5510.         if value == "True" then
  5511.           showOperativeSelection(player)
  5512.         else
  5513.           deselectOperatives(player)
  5514.         end
  5515.       end, 1)
  5516.     else
  5517.       player.broadcast("Only "..getUIAttribute("kts__toggle_blue_deployed_text", "text").." can check this")
  5518.     end
  5519.   end
  5520.   setUIAttribute("kts__toggle_blue_deployed", "isOn", checkListStatus[getUIAttribute("kts__toggle_blue_deployed_text", "text")] ~= nil and checkListStatus[getUIAttribute("kts__toggle_blue_deployed_text", "text")].deployed or checkListPlayer.deployed)
  5521. end
  5522. function onAllowOverwatchSelected(player, value)
  5523.   if player.color == "Red" or player.color == "Blue" then
  5524.     result.allowOW = value
  5525.     checkListStatus.allowOW = value
  5526.     setUIAttribute("kts__toggle_overwatch", "backgroundColor", value == "True" and player.color or "White")
  5527.   end
  5528.   setUIAttribute("kts__toggle_overwatch", "isOn", checkListStatus.allowOW == "True" and true or false)
  5529. end
  5530. function onRedScoutingSelected(player, value)
  5531.   if player.color == "Red" or player.color == "Blue" then
  5532.     setScouting(player, value)
  5533.     checkListStatus[player.steam_name].scouting = value
  5534.   end
  5535.   changeDropdown("kts__dropdown_red_scouting", checkListStatus[Player['Red'].steam_name].scouting)
  5536. end
  5537. function onBlueScoutingSelected(player, value)
  5538.   if player.color == "Red" or player.color == "Blue" then
  5539.     setScouting(player, value)
  5540.     checkListStatus[player.steam_name].scouting = value
  5541.   end
  5542.   changeDropdown("kts__dropdown_blue_scouting", checkListStatus[Player['Blue'].steam_name].scouting)
  5543. end
  5544. function onRevealScouting(player, value)
  5545.   if player.color == "Red" or player.color == "Blue" then
  5546.     checkListStatus.revealed = false
  5547.     if Player["Blue"].steam_name ~= nil then
  5548.       blueName = Player["Blue"].steam_name
  5549.     else
  5550.       blueName = "no_player"
  5551.     end
  5552.     if Player["Red"].steam_name ~= nil then
  5553.       redName = Player["Red"].steam_name
  5554.     else
  5555.       redName = "no_player"
  5556.     end
  5557.     if result[blueName] ~= nil and result[redName] ~= nil then
  5558.       if result[blueName].scouting ~= nil and result[redName].scouting ~= nil and
  5559.       result[blueName].scouting ~= "Select One" and result[redName].scouting ~= "Select One" and
  5560.       checkListStatus.rollOffWinner ~= "Select One" and
  5561.       (checkListStatus.rollOffAttacker or checkListStatus.rollOffDefender) then
  5562.         checkListStatus.revealed = true
  5563.         if result[blueName].scouting == "Fortify" and result[redName].scouting == "Infiltrate" or
  5564.         result[blueName].scouting == "Infiltrate" and result[redName].scouting == "Recon" or
  5565.         result[blueName].scouting == "Recon" and result[redName].scouting == "Fortify" then
  5566.           result.scoutingWinner = blueName
  5567.           checkListStatus.winner = blueName
  5568.         elseif result[blueName].scouting == result[redName].scouting then
  5569.           if result.rollOffWinnerSelection == "Attacker" then
  5570.             result.scoutingWinner = result.rollOffWinner
  5571.             checkListStatus.winner = result.rollOffWinner
  5572.           else
  5573.             result.scoutingWinner = result.rollOffLoser
  5574.             checkListStatus.winner = result.rollOffLoser
  5575.           end
  5576.         else
  5577.           result.scoutingWinner = redName
  5578.           checkListStatus.winner = redName
  5579.         end
  5580.         setUIAttribute("kts__toggle_reveal_scouting", "backgroundColor", value == "True" and player.color or "White")
  5581.         gameStateMachine.whoToPress = checkListStatus.winner
  5582.         setUIValue("kts__scouting_resolution", checkListStatus.winner)
  5583.         printToAll("-----------")
  5584.         printToAll("Scouting...")
  5585.         printToAll(redName.." selected "..result[redName].scouting)
  5586.         printToAll(blueName.." selected "..result[blueName].scouting)
  5587.         printToAll("And the winner is "..result.scoutingWinner)
  5588.         printToAll("-----------")
  5589.         broadcastToAll("The scouting winner is "..result.scoutingWinner)
  5590.       else
  5591.         broadcastToAll("Both players must select a value for scouting and select roll off winner")
  5592.       end
  5593.     else
  5594.       broadcastToAll("Both players must be seated")
  5595.     end
  5596.   end
  5597.   setUIAttribute("kts__toggle_reveal_scouting", "isOn", checkListStatus.revealed)
  5598. end
  5599. function onHideChecklistBtn(player)
  5600.   if player.color == "Red" or player.color == "Blue" then
  5601.     setUIAttribute("kts__checklist_panel", "visibility", string.gsub(getUIAttribute("kts__checklist_panel", "visibility"), player.color.."|", ""))
  5602.   end
  5603. end
  5604. function onShowChecklistBtn(player)
  5605.   if player.color == "Red" or player.color == "Blue" then
  5606.     if not string.find(getUIAttribute("kts__checklist_panel", "visibility"), player.color) then
  5607.       setUIAttribute("kts__checklist_panel", "visibility", getUIAttribute("kts__checklist_panel", "visibility") == "" and player.color.."|".."Black|White|Grey" or player.color.."|"..getUIAttribute("kts__checklist_panel", "visibility"))
  5608.     end
  5609.   end
  5610. end
  5611. function onStartGameBtn(player)
  5612.   if (player.color == "Red" or player.color == "Blue") then
  5613.     printToAll(checkListStatus.gameType)
  5614.     if checkListStatus.gameType == "Select One" then
  5615.       broadcastToAll("Select Game Type")
  5616.       return nil
  5617.     end
  5618.     if string.lower(tostring(checkListStatus.killZoneLoaded)) ~= "true" then
  5619.       broadcastToAll("Check Kill Zone Loaded")
  5620.       return nil
  5621.     end
  5622.     if checkListStatus.edition == "Select One" then
  5623.       broadcastToAll("Select Edition")
  5624.       return nil
  5625.     end
  5626.     if checkListStatus.mission == "Select One" then
  5627.       broadcastToAll("Select Mission")
  5628.       return nil
  5629.     end
  5630.     if checkListStatus.rollOffWinner == "Select One" then
  5631.       broadcastToAll("Select Roll Off winner")
  5632.       return nil
  5633.     end
  5634.     if (not checkListStatus.rollOffAttacker and not checkListStatus.rollOffDefender) then
  5635.       broadcastToAll("Select Attacker or Defender")
  5636.       return nil
  5637.     end
  5638.     if checkListStatus[Player["Red"].steam_name].faction == "Select One" then
  5639.       broadcastToAll("Select Red Faction")
  5640.       return nil
  5641.     end
  5642.     if checkListStatus[Player["Blue"].steam_name].faction == "Select One" then
  5643.       broadcastToAll("Select Blue Faction")
  5644.       return nil
  5645.     end
  5646.     if string.lower(tostring(checkListStatus[Player["Red"].steam_name].tacOps)) ~= "true" then
  5647.       broadcastToAll("Select Red TacOps")
  5648.       return nil
  5649.     end
  5650.     if string.lower(tostring(checkListStatus[Player["Red"].steam_name].equipment)) ~= "true" then
  5651.       broadcastToAll("Select Red equipment")
  5652.       return nil
  5653.     end
  5654.     if string.lower(tostring(checkListStatus[Player["Red"].steam_name].barricades)) ~= "true" then
  5655.       broadcastToAll("Place Red Barricades")
  5656.       return nil
  5657.     end
  5658.     if string.lower(tostring(checkListStatus[Player["Red"].steam_name].deployed)) ~= "true" then
  5659.       broadcastToAll("Deploy red team")
  5660.       return nil
  5661.     end
  5662.     if string.lower(tostring(checkListStatus[Player["Blue"].steam_name].tacOps)) ~= "true" then
  5663.       broadcastToAll("Select Blue TacOps")
  5664.       return nil
  5665.     end
  5666.     if string.lower(tostring(checkListStatus[Player["Blue"].steam_name].equipment)) ~= "true" then
  5667.       broadcastToAll("Select Blue equipment")
  5668.       return nil
  5669.     end
  5670.     if string.lower(tostring(checkListStatus[Player["Blue"].steam_name].barricades)) ~= "true" then
  5671.       broadcastToAll("Place Blue Barricades")
  5672.       return nil
  5673.     end
  5674.     if string.lower(tostring(checkListStatus[Player["Blue"].steam_name].deployed)) ~= "true" then
  5675.       broadcastToAll("Deploy Blue team")
  5676.       return nil
  5677.     end
  5678.     if checkListStatus[Player["Red"].steam_name].scouting == "Select One" then
  5679.       broadcastToAll("Red select scouting")
  5680.       return nil
  5681.     end
  5682.     if checkListStatus[Player["Blue"].steam_name].scouting == "Select One" then
  5683.       broadcastToAll("Blue select scouting")
  5684.       return nil
  5685.     end
  5686.     if not checkListStatus.revealed then
  5687.       broadcastToAll("Reveal scouting resolution")
  5688.       return nil
  5689.     end
  5690.     if checkListStatus.winner == "" then
  5691.       broadcastToAll("Reveal scouting resolution")
  5692.       return nil
  5693.     end
  5694.     if string.lower(checkListStatus.killZoneLoaded) == "true" and
  5695.     checkListStatus.gameType ~= "Select One" and
  5696.     checkListStatus.edition ~= "Select One" and
  5697.     checkListStatus.mission ~= "Select One" and
  5698.     checkListStatus.rollOffWinner ~= "Select One" and
  5699.     (checkListStatus.rollOffAttacker or checkListStatus.rollOffDefender) and
  5700.     (player.color == "Red" or player.color == "Blue") and
  5701.     checkListStatus[Player["Red"].steam_name].faction ~= "Select One" and
  5702.     checkListStatus[Player["Blue"].steam_name].faction ~= "Select One" and
  5703.     string.lower(checkListStatus[Player["Red"].steam_name].tacOps) == "true" and
  5704.     string.lower(checkListStatus[Player["Red"].steam_name].equipment) == "true" and
  5705.     string.lower(checkListStatus[Player["Red"].steam_name].barricades) == "true" and
  5706.     string.lower(checkListStatus[Player["Red"].steam_name].deployed) == "true" and
  5707.     string.lower(checkListStatus[Player["Blue"].steam_name].tacOps) == "true" and
  5708.     string.lower(checkListStatus[Player["Blue"].steam_name].equipment) == "true" and
  5709.     string.lower(checkListStatus[Player["Blue"].steam_name].barricades) == "true" and
  5710.     string.lower(checkListStatus[Player["Blue"].steam_name].deployed) == "true" and
  5711.     checkListStatus[Player["Red"].steam_name].scouting ~= "Select One" and
  5712.     checkListStatus[Player["Blue"].steam_name].scouting ~= "Select One" and
  5713.     checkListStatus.revealed and
  5714.     checkListStatus.winner ~= "" then
  5715.       setUIAttribute("kts__show_checklist_button", "active", false)
  5716.       setUIAttribute("kts__checklist_panel", "active", false)
  5717.       result.timestamp = os.time(os.date("!*t"))
  5718.       setUIAttribute("kts__loading_button", "active", true)
  5719.       setUIAttribute("kts__loading_button", "textColor", "Orange")
  5720.       Wait.frames(function()
  5721.         setUIAttribute("kts__loading_button", "active", false)
  5722.         setStateMachine("tp1", "init")
  5723.         setUIAttribute("kts__end_init_1_button", "active", true)
  5724.         setUIAttribute("kts__end_init_1_button", "textColor", "Orange")
  5725.         setUIAttribute("kts__end_init_2_button", "active", true)
  5726.         setUIAttribute("kts__end_init_2_button", "textColor", "Orange")
  5727.       end, 100)
  5728.       readyOperatives()
  5729.       readyLooseOrders()
  5730.       savePositions()
  5731.     else
  5732.       broadcastToAll("Please complete all fields to start")
  5733.     end
  5734.   end
  5735. end
  5736. function onStartOverBtn(player)
  5737.   if player.color == "Red" or player.color == "Blue" then
  5738.     if checkListStatus[Player["Red"].steam_name] ~= nil then
  5739.       checkListStatus[Player["Red"].steam_name].allow = "False"
  5740.       checkListStatus[Player["Red"].steam_name].faction="Select One"
  5741.       checkListStatus[Player["Red"].steam_name].superFaction="Select One"
  5742.       checkListStatus[Player["Red"].steam_name].tacOps="False"
  5743.       checkListStatus[Player["Red"].steam_name].equipment="False"
  5744.       checkListStatus[Player["Red"].steam_name].barricades="False"
  5745.       checkListStatus[Player["Red"].steam_name].deployed="False"
  5746.       checkListStatus[Player["Red"].steam_name].scouting="Select One"
  5747.       setFaction(Player["Red"], "Select One")
  5748.       setScouting(Player["Red"], "Select One")
  5749.       setAllowData(Player["Red"], false)
  5750.       result[Player["Red"].steam_name] = {}
  5751.       Wait.frames(function()
  5752.         deselectOperatives(Player["Red"])
  5753.       end, 10)
  5754.     end
  5755.     if checkListStatus[Player["Blue"].steam_name] ~= nil then
  5756.       checkListStatus[Player["Blue"].steam_name].allow = "False"
  5757.       checkListStatus[Player["Blue"].steam_name].faction="Select One"
  5758.       checkListStatus[Player["Blue"].steam_name].superFaction="Select One"
  5759.       checkListStatus[Player["Blue"].steam_name].tacOps="False"
  5760.       checkListStatus[Player["Blue"].steam_name].equipment="False"
  5761.       checkListStatus[Player["Blue"].steam_name].barricades="False"
  5762.       checkListStatus[Player["Blue"].steam_name].deployed="False"
  5763.       checkListStatus[Player["Blue"].steam_name].scouting="Select One"
  5764.       setFaction(Player["Blue"], "Select One")
  5765.       setScouting(Player["Blue"], "Select One")
  5766.       setAllowData(Player["Blue"], false)
  5767.       result[Player["Blue"].steam_name] = {}
  5768.       Wait.frames(function()
  5769.         deselectOperatives(Player["Blue"])
  5770.       end, 10)
  5771.     end
  5772.     checkListStatus.killZoneLoaded = false
  5773.     checkListStatus.allowOW = false
  5774.     checkListStatus.gameType = "Select One"
  5775.     checkListStatus.edition = "Select One"
  5776.     checkListStatus.mission = "Select One"
  5777.     checkListStatus.rollOffWinner=false
  5778.     checkListStatus.rollOffLoser=false
  5779.     checkListStatus.rollOffAttacker=false
  5780.     checkListStatus.rollOffDefender=false
  5781.     checkListStatus.revealed=false
  5782.     checkListStatus.winner=""
  5783.     result.killZoneLoaded = nil
  5784.     result.allowOW = nil
  5785.     result.gameType = nil
  5786.     result.mission = nil
  5787.     result.scoutingWinner = nil
  5788.     result.rollOffWinner = nil
  5789.     result.rollOffLoser = nil
  5790.     result.rollOffWinnerSelection= nil
  5791.     onOpenMissionSelected(Player["Red"], "Select One")
  5792.     onItdMissionSelected(Player["Red"], "Select One")
  5793.     updateCheckList()
  5794.   end
  5795. end
  5796. function updateCheckList()
  5797.   setUIAttribute("kts__toggle_red_accept", "isOn", false)
  5798.   setUIAttribute("kts__toggle_red_accept", "backgroundColor", "White")
  5799.   setUIAttribute("kts__toggle_blue_accept", "isOn", false)
  5800.   setUIAttribute("kts__toggle_blue_accept", "backgroundColor", "White")
  5801.   setUIAttribute("kts__toggle_kz_loaded", "isOn", false)
  5802.   setUIAttribute("kts__toggle_kz_loaded", "backgroundColor", "White")
  5803.   setUIAttribute("kts__toggle_red_rolloff_winner", "isOn", false)
  5804.   setUIAttribute("kts__toggle_red_rolloff_winner", "backgroundColor", "White")
  5805.   setUIAttribute("kts__toggle_blue_rolloff_winner", "isOn", false)
  5806.   setUIAttribute("kts__toggle_blue_rolloff_winner", "backgroundColor", "White")
  5807.   setUIAttribute("kts__toggle_defender_selected", "isOn", false)
  5808.   setUIAttribute("kts__toggle_defender_selected", "backgroundColor", "White")
  5809.   setUIAttribute("kts__toggle_attacker_selected", "isOn", false)
  5810.   setUIAttribute("kts__toggle_attacker_selected", "backgroundColor", "White")
  5811.   setUIAttribute("kts__toggle_red_tacops", "isOn", false)
  5812.   setUIAttribute("kts__toggle_red_tacops", "backgroundColor", "White")
  5813.   setUIAttribute("kts__toggle_blue_tacops", "isOn", false)
  5814.   setUIAttribute("kts__toggle_blue_tacops", "backgroundColor", "White")
  5815.   setUIAttribute("kts__toggle_red_equipment", "isOn", false)
  5816.   setUIAttribute("kts__toggle_red_equipment", "backgroundColor", "White")
  5817.   setUIAttribute("kts__toggle_blue_equipment", "isOn", false)
  5818.   setUIAttribute("kts__toggle_blue_equipment", "backgroundColor", "White")
  5819.   setUIAttribute("kts__toggle_red_barricades", "isOn", false)
  5820.   setUIAttribute("kts__toggle_red_barricades", "backgroundColor", "White")
  5821.   setUIAttribute("kts__toggle_blue_barricades", "isOn", false)
  5822.   setUIAttribute("kts__toggle_blue_barricades", "backgroundColor", "White")
  5823.   setUIAttribute("kts__toggle_red_deployed", "isOn", false)
  5824.   setUIAttribute("kts__toggle_red_deployed", "backgroundColor", "White")
  5825.   setUIAttribute("kts__toggle_blue_deployed", "isOn", false)
  5826.   setUIAttribute("kts__toggle_blue_deployed", "backgroundColor", "White")
  5827.   setUIAttribute("kts__toggle_overwatch", "isOn", false)
  5828.   setUIAttribute("kts__toggle_overwatch", "backgroundColor", "White")
  5829.   setUIAttribute("kts__toggle_reveal_scouting", "isOn", false)
  5830.   setUIAttribute("kts__toggle_reveal_scouting", "backgroundColor", "White")
  5831.   setUIValue("kts__scouting_resolution", "")
  5832.   changeMultiDropdown({
  5833.     "kts__dropdown_game_type",
  5834.     "kts__dropdown_edition",
  5835.     "kts__dropdown_mission_open",
  5836.     "kts__dropdown_mission_itd",
  5837.     "kts__dropdown_red_super_faction",
  5838.     "kts__dropdown_red_faction_imperium",
  5839.     "kts__dropdown_red_faction_chaos",
  5840.     "kts__dropdown_red_faction_aeldari",
  5841.     "kts__dropdown_red_faction_xenos",
  5842.     "kts__dropdown_red_scouting",
  5843.     "kts__dropdown_blue_super_faction",
  5844.     "kts__dropdown_blue_faction_imperium",
  5845.     "kts__dropdown_blue_faction_chaos",
  5846.     "kts__dropdown_blue_faction_aeldari",
  5847.     "kts__dropdown_blue_faction_xenos",
  5848.     "kts__dropdown_blue_scouting"
  5849.   },
  5850.   {
  5851.     "Select One",
  5852.     "Select One",
  5853.     "Select One",
  5854.     "Select One",
  5855.     "Select One",
  5856.     "Select One",
  5857.     "Select One",
  5858.     "Select One",
  5859.     "Select One",
  5860.     "Select One",
  5861.     "Select One",
  5862.     "Select One",
  5863.     "Select One",
  5864.     "Select One",
  5865.     "Select One"
  5866.   })
  5867.   setUIAttribute("kts__dropdown_game_type", "textColor", "#e74f0aff")
  5868.   setUIAttribute("kts__dropdown_edition", "textColor", "#e74f0aff")
  5869.   setUIAttribute("kts__dropdown_mission_open", "textColor", "#e74f0aff")
  5870.   setUIAttribute("kts__dropdown_mission_itd", "textColor", "#e74f0aff")
  5871.   setUIAttribute("kts__dropdown_red_super_faction", "textColor", "#e74f0aff")
  5872.   setUIAttribute("kts__dropdown_red_faction_imperium", "textColor", "#e74f0aff")
  5873.   setUIAttribute("kts__dropdown_red_faction_chaos", "textColor", "#e74f0aff")
  5874.   setUIAttribute("kts__dropdown_red_faction_aeldari", "textColor", "#e74f0aff")
  5875.   setUIAttribute("kts__dropdown_red_faction_xenos", "textColor", "#e74f0aff")
  5876.   setUIAttribute("kts__dropdown_red_scouting", "textColor", "#e74f0aff")
  5877.   setUIAttribute("kts__dropdown_blue_super_faction", "textColor", "#e74f0aff")
  5878.   setUIAttribute("kts__dropdown_blue_faction_imperium", "textColor", "#e74f0aff")
  5879.   setUIAttribute("kts__dropdown_blue_faction_chaos", "textColor", "#e74f0aff")
  5880.   setUIAttribute("kts__dropdown_blue_faction_aeldari", "textColor", "#e74f0aff")
  5881.   setUIAttribute("kts__dropdown_blue_faction_xenos", "textColor", "#e74f0aff")
  5882.   setUIAttribute("kts__dropdown_blue_scouting", "textColor", "#e74f0aff")
  5883.  
  5884.   setUIAttribute("kts__dropdown_blue_faction_imperium", "active", false)
  5885.   setUIAttribute("kts__dropdown_blue_faction_chaos", "active", false)
  5886.   setUIAttribute("kts__dropdown_blue_faction_aeldari", "active", false)
  5887.   setUIAttribute("kts__dropdown_blue_faction_xenos", "active", false)
  5888.   setUIAttribute("kts__dropdown_red_faction_imperium", "active", false)
  5889.   setUIAttribute("kts__dropdown_red_faction_chaos", "active", false)
  5890.   setUIAttribute("kts__dropdown_red_faction_aeldari", "active", false)
  5891.   setUIAttribute("kts__dropdown_red_faction_xenos", "active", false)
  5892. end
  5893. function onEndInitP1Btn(player)
  5894.   if player.color == "Red" then
  5895.     oldOp1, oldOp2 = getStateMachine()
  5896.     if oldOp2 == "init" then
  5897.       for i=1, 4, 1 do
  5898.         if oldOp1 == "tp"..i then
  5899.           onInitiativePressed(player, true, "kts__initiative_player1_"..i.."_toggle")
  5900.           gameStateMachine.whoToPress = player.steam_name
  5901.           break
  5902.         end
  5903.       end
  5904.       setUIAttribute("kts__scoring_button", "active", false)
  5905.       setUIAttribute("kts__end_init_1_button", "active", false)
  5906.       setUIAttribute("kts__end_init_2_button", "active", false)
  5907.       setUIAttribute("kts__loading_button", "active", true)
  5908.       setUIAttribute("kts__loading_button", "textColor", "Orange")
  5909.       Wait.frames(function ()
  5910.         setUIAttribute("kts__loading_button", "active", false)
  5911.         setStateMachine(oldOp1, "ploys")
  5912.         setUIAttribute("kts__end_ploys_button", "active", true)
  5913.         setUIAttribute("kts__end_ploys_button", "textColor", "Orange")
  5914.       end, 100)
  5915.     end
  5916.   end
  5917. end
  5918. function onEndInitP2Btn(player)
  5919.   if player.color == "Blue" then
  5920.     oldOp1, oldOp2 = getStateMachine()
  5921.     if oldOp2 == "init" then
  5922.       for i=1, 4, 1 do
  5923.         if oldOp1 == "tp"..i then
  5924.           onInitiativePressed(player, true, "kts__initiative_player2_"..i.."_toggle")
  5925.           gameStateMachine.whoToPress = player.steam_name
  5926.           break
  5927.         end
  5928.       end
  5929.       setUIAttribute("kts__scoring_button", "active", false)
  5930.       setUIAttribute("kts__end_init_1_button", "active", false)
  5931.       setUIAttribute("kts__end_init_2_button", "active", false)
  5932.       setUIAttribute("kts__loading_button", "active", true)
  5933.       setUIAttribute("kts__loading_button", "textColor", "Orange")
  5934.       Wait.frames(function ()
  5935.         setUIAttribute("kts__loading_button", "active", false)
  5936.         setStateMachine(oldOp1, "ploys")
  5937.         setUIAttribute("kts__end_ploys_button", "active", true)
  5938.         setUIAttribute("kts__end_ploys_button", "textColor", "Orange")
  5939.       end, 100)
  5940.     end
  5941.   end
  5942. end
  5943. function onEndPloysBtn(player)
  5944.   if player.color == "Red" or player.color == "Blue" then
  5945.     oldOp1, oldOp2 = getStateMachine()
  5946.     if oldOp2 == "ploys" then
  5947.       setUIAttribute("kts__end_ploys_button", "active", false)
  5948.       setUIAttribute("kts__loading_button", "active", true)
  5949.       setUIAttribute("kts__loading_button", "textColor", "Orange")
  5950.       Wait.frames(function ()
  5951.         setUIAttribute("kts__loading_button", "active", false)
  5952.         setStateMachine(oldOp1, "tacops")
  5953.         setUIAttribute("kts__end_tacops_button", "active", true)
  5954.         setUIAttribute("kts__end_tacops_button", "textColor", "Orange")
  5955.       end, 100)
  5956.     end
  5957.   end
  5958. end
  5959. function onEndTacopsBtn(player)
  5960.   if player.color == "Red" or player.color == "Blue" then
  5961.     oldOp1, oldOp2 = getStateMachine()
  5962.     if oldOp2 == "tacops" then
  5963.       pressStopWatch(Player[scoring[1].initiative[getCurrentRound()] and 'Blue' or 'Red'])
  5964.       setUIAttribute("kts__end_tacops_button", "active", false)
  5965.       setUIAttribute("kts__loading_button", "active", true)
  5966.       setUIAttribute("kts__loading_button", "textColor", "Orange")
  5967.       Wait.frames(function ()
  5968.         setUIAttribute("kts__loading_button", "active", false)
  5969.         setStateMachine(oldOp1, "firefight")
  5970.         setUIAttribute("kts__activated_button", "active", true)
  5971.         setUIAttribute("kts__activated_button", "textColor", Player["Red"].steam_name == gameStateMachine.whoToPress and "Red" or "Blue")
  5972.         setUIAttribute("kts__end_tp_button", "active", true)
  5973.         setUIAttribute("kts__end_tp_button", "textColor", "Orange")
  5974.         broadcastToAll(gameStateMachine.whoToPress.."'s turn")
  5975.       end, 100)
  5976.     end
  5977.   end
  5978. end
  5979. function onActivatedBtn(player)
  5980.   if player.steam_name == gameStateMachine.whoToPress then
  5981.     if Player['Red'].steam_name ~= nil and Player['Blue'].steam_name ~= nil then
  5982.       local oldOp1, oldOp2 = getStateMachine()
  5983.       if oldOp2 == "firefight" then
  5984.         savePositions()
  5985.         pressStopWatch(player)
  5986.         if checkOrdersCoherency() and string.lower(result.allowOW) == "true" then
  5987.           checkOverwatch(player)
  5988.         end
  5989.         gameStateMachine.whoToPress = player.color == "Red" and Player['Blue'].steam_name or Player['Red'].steam_name
  5990.         setUIAttribute("kts__activated_button", "textColor", player.color == "Red" and "Blue" or "Red")
  5991.         broadcastToAll(gameStateMachine.whoToPress.."'s turn")
  5992.       end
  5993.     else
  5994.       broadcastToAll("Both players need to be seated to continue")
  5995.     end
  5996.   else
  5997.     broadcastToAll("It's "..gameStateMachine.whoToPress.." turn")
  5998.   end
  5999. end
  6000. function onEndTPBtn(player)
  6001.   if player.color == "Red" or player.color == "Blue" then
  6002.     local oldOp1, oldOp2 = getStateMachine()
  6003.     if oldOp2 == "firefight" then
  6004.       if Player['Red'].steam_name ~= nil and Player['Blue'].steam_name ~= nil then
  6005.         isOk = checkAllOperativesActivated() and checkAllLooseOrdersActivated()
  6006.         if isOk then
  6007.           local objs = getCMOperativesOnBoard()
  6008.           for _, obj in ipairs(objs) do
  6009.             for i, color in ipairs({"Red", "Blue"}) do
  6010.               if string.find(obj.getDescription(), "Owned by "..Player[color].steam_name) then
  6011.                 if result[Player[color].steam_name] == nil then
  6012.                   result[Player[color].steam_name] = {}
  6013.                 end
  6014.                 if result[Player[color].steam_name].operatives == nil then
  6015.                   result[Player[color].steam_name].operatives = {}
  6016.                 end
  6017.                 result[Player[color].steam_name].operatives[obj.getGUID()] = {
  6018.                   name=obj.getName(),
  6019.                   desc=obj.getDescription(),
  6020.                 }
  6021.                 local pos = obj.getPosition()
  6022.                 if pos.x < 15 and pos.x > -15 and pos.z < 11 and pos.z > -11 then
  6023.                   result[Player[color].steam_name].operatives[obj.getGUID()].killed = false
  6024.                 else
  6025.                   round = getCurrentRound()
  6026.                   result[Player[color].steam_name].operatives[obj.getGUID()].killed = true
  6027.                   result[Player[color].steam_name].operatives[obj.getGUID()].roundKilled = round
  6028.                 end
  6029.               end
  6030.             end
  6031.           end
  6032.           stopStopWatch()
  6033.           setUIAttribute("kts__activated_button", "active", false)
  6034.           setUIAttribute("kts__end_tp_button", "active", false)
  6035.           setUIAttribute("kts__loading_button", "active", true)
  6036.           setUIAttribute("kts__loading_button", "textColor", "Orange")
  6037.           Wait.frames(function()
  6038.             setUIAttribute("kts__loading_button", "active", false)
  6039.             setStateMachine(oldOp1, "scoring")
  6040.             setUIAttribute("kts__scoring_button", "active", true)
  6041.             setUIAttribute("kts__scoring_button", "textColor", "Orange")
  6042.           end, 100)
  6043.         else
  6044.           broadcastToAll("There still are ready operatives")
  6045.         end
  6046.       else
  6047.         broadcastToAll("Need both players seated to continue")
  6048.       end
  6049.     end
  6050.   end
  6051. end
  6052. function onScoringBtn(player)
  6053.   if player.color == "Red" or player.color == "Blue" then
  6054.     oldOp1, oldOp2 = getStateMachine()
  6055.     if oldOp2 == "scoring" then
  6056.       setUIAttribute("kts__scoring_button", "active", false)
  6057.       setUIAttribute("kts__loading_button", "active", true)
  6058.       setUIAttribute("kts__loading_button", "textColor", "Orange")
  6059.       if oldOp1 ~= "tp4" then
  6060.         savePositions()
  6061.         readyOperatives()
  6062.         readyLooseOrders()
  6063.         unsetHighLights()
  6064.         overwatchTable = {}
  6065.         overwatchTable.checked = false
  6066.         oldTable = Global.UI.getXmlTable()
  6067.         for i, uiTable in ipairs(oldTable) do
  6068.           if uiTable.attributes.id == "kts__red_overwatch" then
  6069.             table.remove(oldTable, i)
  6070.           end
  6071.           if uiTable.attributes.id == "kts__blue_overwatch" then
  6072.             table.remove(oldTable, i)
  6073.           end
  6074.         end
  6075.         local defaults = makeDefaults(rules)
  6076.         table.insert(oldTable, defaults)
  6077.         Wait.frames(function ()
  6078.           Global.UI.setXmlTable(oldTable)
  6079.           setUIAttribute("kts__loading_button", "active", false)
  6080.           setUIAttribute("kts__scoring_button", "active", false)
  6081.           for i=1, 3, 1 do
  6082.             if oldOp1 == "tp"..i then
  6083.               setStateMachine("tp"..(i+1), "init")
  6084.               break
  6085.             end
  6086.           end
  6087.           setUIAttribute("kts__end_init_1_button", "active", true)
  6088.           setUIAttribute("kts__end_init_1_button", "textColor", "Orange")
  6089.           setUIAttribute("kts__end_init_2_button", "active", true)
  6090.           setUIAttribute("kts__end_init_2_button", "textColor", "Orange")
  6091.         end, 100)
  6092.       else
  6093.         Wait.frames(function()
  6094.           setUIAttribute("kts__loading_button", "active", false)
  6095.           setStateMachine("endGame", "active")
  6096.           setUIAttribute("kts__end_game_button", "active", true)
  6097.           setUIAttribute("kts__end_game_button", "textColor", "Orange")
  6098.           broadcastToAll("End Game. Press 'Send Data' button to send your game information.")
  6099.         end, 100)
  6100.       end
  6101.     end
  6102.   end
  6103. end
  6104. function onEndGame(player)
  6105.   if player.color == "Red" or player.color == "Blue" then
  6106.     if Player['Red'].steam_name ~= nil and Player['Blue'].steam_name ~= nil then
  6107.       if result[Player['Red'].steam_name].allow == "True" and result[Player['Blue'].steam_name].allow == "True" then
  6108.         local rounds = {
  6109.           "first",
  6110.           "second",
  6111.           "third",
  6112.           "fourth"
  6113.         }
  6114.         for _, player in ipairs(Player.getPlayers()) do
  6115.           if result[player.steam_name] == nil then
  6116.             result[player.steam_name] = {}
  6117.           end
  6118.           result[player.steam_name].color = player.color
  6119.         end
  6120.  
  6121.         auxNames = {}
  6122.         for i, play in ipairs({"Red", "Blue"}) do
  6123.           pl = Player[play].steam_name
  6124.           if pl == nil then
  6125.             pl = "no_player"
  6126.           end
  6127.           auxNames[play] = pl
  6128.           if result[pl] == nil then
  6129.             result[pl] = {}
  6130.             result[pl].color = Player[play].color
  6131.           end
  6132.           result[pl].initiative = {}
  6133.           result[pl].primaries = {}
  6134.           if result[pl].secondaries == nil then
  6135.             result[pl].secondaries = {}
  6136.           end
  6137.           result[pl].primaries.total = 0
  6138.           for round=1, rules.scoring.maxRounds do
  6139.             result[pl].initiative[round] = scoring[i].initiative[round]
  6140.             result[pl].primaries[rounds[round]] = 0
  6141.             for k,_ in pairs(rules.scoring.primary.objectives) do
  6142.               result[pl].primaries[rounds[round]] = result[pl].primaries[rounds[round]] + (scoring[i].primary[k][round] and 1 or 0)
  6143.             end
  6144.             if rules.scoring.primary.maxEach > 0 then
  6145.               result[pl].primaries.total = result[pl].primaries.total + math.min(result[pl].primaries[rounds[round]], rules.scoring.primary.maxEach)
  6146.             else
  6147.               result[pl].primaries.total = result[pl].primaries.total + result[pl].primaries[rounds[round]]
  6148.             end
  6149.           end
  6150.           result[pl].primaries["end"] = scoring[i].secondary[4]
  6151.           result[pl].primaries.total = result[pl].primaries.total + result[pl].primaries["end"]
  6152.  
  6153.           result[pl].secondaries.total = 0
  6154.           for s=1, 3 do
  6155.             if result[pl].secondaries[rounds[s]] == nil then
  6156.               result[pl].secondaries[rounds[s]] = {}
  6157.               result[pl].secondaries[rounds[s]].name = scoring[i].secondary[s][1]
  6158.               result[pl].secondaries[rounds[s]].score = scoring[i].secondary[s][2]
  6159.               result[pl].secondaries[rounds[s]].none = 0
  6160.               result[pl].secondaries[rounds[s]].first = 0
  6161.               result[pl].secondaries[rounds[s]].second = 0
  6162.               result[pl].secondaries[rounds[s]].third = 0
  6163.               result[pl].secondaries[rounds[s]].fourth = 0
  6164.             else
  6165.               result[pl].secondaries[rounds[s]].name = scoring[i].secondary[s][1]
  6166.             end
  6167.           end
  6168.           result[pl].secondaries.total = result[pl].secondaries[rounds[1]].score + result[pl].secondaries[rounds[2]].score + result[pl].secondaries[rounds[3]].score
  6169.           result[pl].total = result[pl].primaries.total + result[pl].secondaries.total
  6170.         end
  6171.  
  6172.         if result[auxNames["Red"]].total > result[auxNames["Blue"]].total then
  6173.           result.winner = auxNames["Red"]
  6174.           result.loser = auxNames["Blue"]
  6175.           result.tie = false
  6176.         elseif result[auxNames["Red"]].total < result[auxNames["Blue"]].total then
  6177.           result.winner = auxNames["Blue"]
  6178.           result.loser = auxNames["Red"]
  6179.           result.tie = false
  6180.         else
  6181.           result.winner = auxNames["Red"]
  6182.           result.loser = auxNames["Blue"]
  6183.           result.tie = true
  6184.         end
  6185.         result[auxNames["Red"]].steamId = Player['Red'].steam_id
  6186.         result[auxNames["Blue"]].steamId = Player['Blue'].steam_id
  6187.         result['tournament'] = ""
  6188.         --result.rollOffWinner = Player["Red"].steam_name == result.rollOffWinner and "red" or "blue"
  6189.         --result.rollOffLoser = Player["Red"].steam_name == result.rollOffLoser and "red" or "blue"
  6190.         --result.scoutingWinner = Player["Red"].steam_name == result.scoutingWinner and "red" or "blue"
  6191.  
  6192.         --result.red = result[Player['Red'].steam_name ~= nil and Player['Red'].steam_name or "no_player"]
  6193.         --result.blue = result[Player['Blue'].steam_name ~= nil and Player['Blue'].steam_name or "no_player"]
  6194.  
  6195.         --result[Player['Red'].steam_name ~= nil and Player['Red'].steam_name or "no_player"] = nil
  6196.         --result[Player['Blue'].steam_name ~= nil and Player['Blue'].steam_name or "no_player"] = nil
  6197.  
  6198.         local headers = {
  6199.           -- We're sending a JSON body in the request
  6200.           ["Content-Type"] = "application/json",
  6201.           -- We're expecting a JSON body in the response
  6202.           Accept = "application/json",
  6203.         }
  6204.         local url = "https://killteamdata.com/gamedata"
  6205.         WebRequest.custom(url, "POST", true, JSON.encode(result), headers, returnEndGame)
  6206.       else
  6207.         setUIAttribute("kts__checklist_panel", "visibility", "Red|Blue|Black|White|Grey")
  6208.         setUIAttribute("kts__checklist_panel", "active", true)
  6209.         broadcastToAll("Both players must accept data allowing")
  6210.       end
  6211.     else
  6212.       broadcastToAll("Both players must seated")
  6213.     end
  6214.   end
  6215. end
  6216.  
  6217. function returnEndGame(request)
  6218.   local resp = JSON.decode(request.text)
  6219.   broadcastToAll(resp.status)
  6220. end
  6221.  
  6222. function setMission(mission)
  6223.   result.mission = mission
  6224.   printToAll(result.mission.name.." selected as mission")
  6225. end
  6226. function setAllowData(player, value)
  6227.   if result[player.steam_name] == nil then
  6228.     result[player.steam_name] = {}
  6229.   end
  6230.   result[player.steam_name].color = player.color
  6231.   result[player.steam_name].allow = value
  6232. end
  6233.  
  6234. function setFaction(player, faction)
  6235.   if result[player.steam_name] == nil then
  6236.     result[player.steam_name] = {}
  6237.   end
  6238.   result[player.steam_name].color = player.color
  6239.   result[player.steam_name].faction = faction
  6240.   if faction ~= "Select One" then
  6241.     printToAll(player.steam_name.." chose "..faction)
  6242.     setUIValue("kts__"..string.lower(player.color).."_faction_ui_text", faction)
  6243.   else
  6244.     setUIValue("kts__"..string.lower(player.color).."_faction_ui_text", player.color.." Faction")
  6245.   end
  6246.   if checkListStatus[player.steam_name].factionGUID ~= nil then
  6247.     oldFaction = getObjectFromGUID(checkListStatus[player.steam_name].factionGUID)
  6248.     if oldFaction ~= nil then
  6249.       oldFaction.call("click_recall")
  6250.       oldFaction.destruct()
  6251.     else
  6252.       for _, obj in ipairs(getAllObjects()) do
  6253.         if string.find(obj.getDescription(), "faction chosen by "..player.steam_name) then
  6254.           obj.call("click_recall")
  6255.           obj.destruct()
  6256.           break
  6257.         end
  6258.       end
  6259.     end
  6260.     checkListStatus[player.steam_name].factionGUID = nil
  6261.   end
  6262.   obj = getObjectFromGUID(megaDeckGuid)
  6263.   objects = {}
  6264.   for _, containedObject in ipairs(obj.getObjects()) do
  6265.     spawnedObject = obj.takeObject()
  6266.     table.insert(objects, spawnedObject)
  6267.     if spawnedObject.getName() == faction then
  6268.       clonedObject = spawnedObject.clone()
  6269.       clonedObject.setDescription("faction chosen by "..player.steam_name)
  6270.       if player.color == "Blue" then
  6271.         clonedObject.setPosition({-20, 4, -16}, false, false)
  6272.         clonedObject.setRotation({0, -90, 0})
  6273.       else
  6274.         clonedObject.setPosition({20, 4, 16}, false, false)
  6275.         clonedObject.setRotation({0, 90, 0})
  6276.       end
  6277.       checkListStatus[player.steam_name].factionGUID = clonedObject.getGUID()
  6278.       break
  6279.     end
  6280.   end
  6281.   for _, objectToPut in ipairs(objects) do
  6282.     obj.putObject(objectToPut)
  6283.   end
  6284. end
  6285. function setScouting(player, option)
  6286.   if result[player.steam_name] == nil then
  6287.     result[player.steam_name] = {}
  6288.   end
  6289.   result[player.steam_name].color = player.color
  6290.   result[player.steam_name].scouting = option
  6291. end
  6292. function setRollOffWinner(player)
  6293.   if player.steam_name ~= nil then
  6294.     if result[player.steam_name] == nil then
  6295.       result[player.steam_name] = {}
  6296.     end
  6297.     result.rollOffWinner = player.steam_name
  6298.     result[player.steam_name].color = player.color
  6299.   else
  6300.     if result["no_player"] == nil then
  6301.       result["no_player"] = {}
  6302.     end
  6303.     result.rollOffWinner = "no_player"
  6304.     result["no_player"].color = player.color
  6305.   end
  6306.   printToAll(result.rollOffWinner.." Won the Roll off")
  6307. end
  6308. function setRollOffLoser(player)
  6309.   if player.steam_name ~= nil then
  6310.     if result[player.steam_name] == nil then
  6311.       result[player.steam_name] = {}
  6312.     end
  6313.     result.rollOffLoser = player.steam_name
  6314.     result[player.steam_name].color = player.color
  6315.   else
  6316.     if result["no_player"] == nil then
  6317.       result["no_player"] = {}
  6318.     end
  6319.     result.rollOffLoser = "no_player"
  6320.     result["no_player"].color = player.color
  6321.   end
  6322.   printToAll(result.rollOffLoser.." Lose the Roll off")
  6323. end
  6324. function setSecondaryResult(player, secondary, score)
  6325.   colors = {"Red", "Blue"}
  6326.   secs = {"first", "second", "third"}
  6327.   rounds = {"none", "first", "second", "third", "fourth"}
  6328.   pl = Player[colors[player]].steam_name
  6329.   if pl ~= nil and scoring[player].secondary[secondary][1] ~= nil then
  6330.     round = getCurrentRound()
  6331.     if result[pl].secondaries == nil then
  6332.       result[pl].secondaries = {}
  6333.     end
  6334.     if result[pl].secondaries[secs[secondary]] == nil then
  6335.       result[pl].secondaries[secs[secondary]] = {}
  6336.       result[pl].secondaries[secs[secondary]].name = scoring[player].secondary[secondary][1]
  6337.       result[pl].secondaries[secs[secondary]].score = scoring[player].secondary[secondary][2]
  6338.       result[pl].secondaries[secs[secondary]].none = 0
  6339.       result[pl].secondaries[secs[secondary]].first = 0
  6340.       result[pl].secondaries[secs[secondary]].second = 0
  6341.       result[pl].secondaries[secs[secondary]].third = 0
  6342.       result[pl].secondaries[secs[secondary]].fourth = 0
  6343.       mult = 1
  6344.     else
  6345.       mult = result[pl].secondaries[secs[secondary]].score < scoring[player].secondary[secondary][2] and 1 or -1
  6346.       result[pl].secondaries[secs[secondary]].name = scoring[player].secondary[secondary][1]
  6347.       result[pl].secondaries[secs[secondary]].score = scoring[player].secondary[secondary][2]
  6348.     end
  6349.     result[pl].secondaries[secs[secondary]][rounds[round+1]] = result[pl].secondaries[secs[secondary]][rounds[round+1]] + (1*mult)
  6350.   end
  6351. end
  6352. function changeDropdown(id, value)
  6353.   Wait.frames(function()
  6354.     local oldUI = Global.UI.getXmlTable()
  6355.     for k1, v1 in ipairs(oldUI) do
  6356.       ch1 = oldUI[k1].children
  6357.       for k2, v2 in ipairs(ch1) do
  6358.         ch2 = oldUI[k1].children[k2].children
  6359.         for k3, v3 in ipairs(ch2) do
  6360.           ch3 = oldUI[k1].children[k2].children[k3].children
  6361.           for k4, v4 in ipairs(ch3) do
  6362.             if v4.attributes.id == id then
  6363.               options = v4.children
  6364.               for k5, v5 in ipairs(options) do
  6365.                 if v5.value == value then
  6366.                   oldUI[k1].children[k2].children[k3].children[k4].children[k5].attributes.selected = true
  6367.                 else
  6368.                   oldUI[k1].children[k2].children[k3].children[k4].children[k5].attributes.selected = false
  6369.                 end
  6370.               end
  6371.             end
  6372.           end
  6373.         end
  6374.       end
  6375.     end
  6376.     Wait.frames(function() Global.UI.setXmlTable(oldUI) end, 10)
  6377.   end, 10)
  6378. end
  6379. function changeMultiDropdown(id, value)
  6380.   Wait.frames(function()
  6381.     local oldUI = Global.UI.getXmlTable()
  6382.     for k, v in ipairs(id) do
  6383.       for k1, v1 in ipairs(oldUI) do
  6384.         ch1 = oldUI[k1].children
  6385.         for k2, v2 in ipairs(ch1) do
  6386.           ch2 = oldUI[k1].children[k2].children
  6387.           for k3, v3 in ipairs(ch2) do
  6388.             ch3 = oldUI[k1].children[k2].children[k3].children
  6389.             for k4, v4 in ipairs(ch3) do
  6390.               if v4.attributes.id == v then
  6391.                 options = v4.children
  6392.                 for k5, v5 in ipairs(options) do
  6393.                   if v5.value == value[k] then
  6394.                     oldUI[k1].children[k2].children[k3].children[k4].children[k5].attributes.selected = true
  6395.                   else
  6396.                     oldUI[k1].children[k2].children[k3].children[k4].children[k5].attributes.selected = false
  6397.                   end
  6398.                 end
  6399.               end
  6400.             end
  6401.           end
  6402.         end
  6403.       end
  6404.     end
  6405.     Wait.frames(function() Global.UI.setXmlTable(oldUI) end, 10)
  6406.   end, 10)
  6407. end
  6408. function setStateMachine(op1, op2)
  6409.   local oldOp1, oldOp2 = getStateMachine()
  6410.   if oldOp1 ~= "" then
  6411.     gameStateMachine[oldOp1][oldOp2]=false
  6412.   end
  6413.   gameStateMachine[op1][op2]=true
  6414.   broadcastToAll(op1.." "..op2)
  6415. end
  6416. function getStateMachine()
  6417.   for k1, v1 in pairs(gameStateMachine) do
  6418.     for k2, v2 in pairs(gameStateMachine[k1]) do
  6419.       if v2 then
  6420.         return k1, k2
  6421.       end
  6422.     end
  6423.   end
  6424.   return "", ""
  6425. end
  6426. function readyOperatives()
  6427.   for _, obj in ipairs(getCMOperativesOnBoard()) do
  6428.     if obj.hasTag('Operative') and obj.hasTag('Not Mustered') ~= true then
  6429.       if obj.getVar('KTUI_ReadyOperative') then
  6430.         obj.call('KTUI_ReadyOperative')
  6431.       end
  6432.     end
  6433.   end
  6434. end
  6435. function readyLooseOrders()
  6436.   for _, obj in ipairs(getLooseOrdersOnBoard()) do
  6437.     if string.find(obj.getName(), "_activated") then
  6438.       obj.setState(obj.getStateId()-1)
  6439.     end
  6440.   end
  6441. end
  6442. function getCMOperativesOnBoard()
  6443.   objs = {}
  6444.   for _, obj in ipairs(getAllObjects()) do
  6445.     if obj.getPosition().x < 15 and obj.getPosition().x > -15 and obj.getPosition().z < 11 and obj.getPosition().z > -11 then
  6446.       if obj.hasTag('Operative') and obj.hasTag('Not Mustered') ~= true then
  6447.         if obj.getVar('KTUI_ReadyOperative') then
  6448.           table.insert(objs, obj)
  6449.         end
  6450.       end
  6451.     end
  6452.   end
  6453.   return objs
  6454. end
  6455. function getNotCMOperativesOnBoard()
  6456.   objs = {}
  6457.   for _, obj in ipairs(getAllObjects()) do
  6458.     if obj.getPosition().x < 15 and obj.getPosition().x > -15 and obj.getPosition().z < 11 and obj.getPosition().z > -11 then
  6459.       if obj.hasTag('Operative') and obj.hasTag('Not Mustered') ~= true then
  6460.         if not obj.getVar('KTUI_ReadyOperative') then
  6461.           table.insert(objs, obj)
  6462.         end
  6463.       end
  6464.     end
  6465.   end
  6466.   return objs
  6467. end
  6468. function getLooseOrdersOnBoard()
  6469.   objs = {}
  6470.   for _, obj in ipairs(getAllObjects()) do
  6471.     if obj.getPosition().x < 15 and obj.getPosition().x > -15 and obj.getPosition().z < 11 and obj.getPosition().z > -11 then
  6472.       if string.find(obj.getName(), "Engage_ready") or
  6473.       string.find(obj.getName(), "Engage_activated") or
  6474.       string.find(obj.getName(), "Conceal_ready") or
  6475.       string.find(obj.getName(), "Conceal_activated") then
  6476.         table.insert(objs, obj)
  6477.       end
  6478.     end
  6479.   end
  6480.   return objs
  6481. end
  6482. function pressStopWatch(pl)
  6483.   local stopWatch = getObjectFromGUID("f4ee71")
  6484.   if pl.color == "Red" then
  6485.     stopWatch.call("Click_2", {player=pl})
  6486.   end
  6487.   if pl.color == "Blue" then
  6488.     stopWatch.call("Click_1", {player=pl})
  6489.   end
  6490. end
  6491. function stopStopWatch()
  6492.   local stopWatch = getObjectFromGUID("f4ee71")
  6493.   stopWatch.call("Pause")
  6494. end
  6495. function savePositions()
  6496.   for _, obj in ipairs(getNotCMOperativesOnBoard()) do
  6497.     if obj.getVar('savePosition') then
  6498.       obj.call("savePosition")
  6499.     end
  6500.   end
  6501.   for _, obj in ipairs(getCMOperativesOnBoard()) do
  6502.     if obj.getVar('savePosition') then
  6503.       obj.call("savePosition")
  6504.     end
  6505.   end
  6506. end
  6507. function onObjectDrop(player_color, dropped_object)
  6508.   if dropped_object.hasTag('Operative') and dropped_object.hasTag('Not Mustered') ~= true then
  6509.     op1, op2 = getStateMachine()
  6510.     if op1 ~= "preGame" then
  6511.       local newDesc = dropped_object.getDescription()
  6512.       if string.find(newDesc, Player[player_color].steam_name) then
  6513.         if result[Player[player_color].steam_name] == nil then
  6514.           result[Player[player_color].steam_name] = {}
  6515.         end
  6516.         if result[Player[player_color].steam_name].operatives == nil then
  6517.           result[Player[player_color].steam_name].operatives = {}
  6518.         end
  6519.         result[Player[player_color].steam_name].operatives[dropped_object.getGUID()] = {
  6520.           name=dropped_object.getName(),
  6521.           desc=dropped_object.getDescription(),
  6522.         }
  6523.         local pos = dropped_object.getPosition()
  6524.         if pos.x < 15 and pos.x > -15 and pos.z < 11 and pos.z > -11 then
  6525.           result[Player[player_color].steam_name].operatives[dropped_object.getGUID()].killed = false
  6526.         else
  6527.           round = getCurrentRound()
  6528.           result[Player[player_color].steam_name].operatives[dropped_object.getGUID()].killed = true
  6529.           result[Player[player_color].steam_name].operatives[dropped_object.getGUID()].roundKilled = round
  6530.         end
  6531.       end
  6532.     end
  6533.   end
  6534. end
  6535. function getCurrentRound()
  6536.   local round = 0
  6537.   local maxRounds = rules.scoring.maxRounds
  6538.   for i=maxRounds,1,-1 do
  6539.     if scoring[1].initiative[i] then
  6540.       round = i
  6541.       break
  6542.     end
  6543.     if scoring[2].initiative[i] then
  6544.       round = i
  6545.       break
  6546.     end
  6547.   end
  6548.   return round
  6549. end
  6550. function checkOverwatch(pl)
  6551.   if not overwatchTable.checked then
  6552.     if pl.color == "Red" then
  6553.       oPl = Player["Blue"]
  6554.     else
  6555.       oPl = Player["Red"]
  6556.     end
  6557.     overwatchTable[pl.steam_name] = {}
  6558.     overwatchTable[oPl.steam_name] = {}
  6559.     local overObjs = {}
  6560.     local objs = getCMOperativesOnBoard()
  6561.     local readyOps = {}
  6562.     local oReadyOps = {}
  6563.     local activatedOps = {}
  6564.     local oActivatedOps = {}
  6565.     for _, obj in ipairs(objs) do
  6566.       if obj.hasTag('Operative') and obj.hasTag('Not Mustered') ~= true then
  6567.         desc = obj.getDescription()
  6568.         objUI = obj.UI.getXmlTable()
  6569.         if string.find(desc, "Owned by "..pl.steam_name) then
  6570.           if string.find(getOperativeOrder(objUI), "_ready") then
  6571.             table.insert(readyOps, obj.getGUID())
  6572.           else
  6573.             table.insert(activatedOps, obj.getGUID())
  6574.           end
  6575.         end
  6576.         if oPl.steam_name ~= nil then
  6577.           if string.find(desc, "Owned by "..oPl.steam_name) then
  6578.             if string.find(getOperativeOrder(objUI), "_ready") then
  6579.               table.insert(oReadyOps, obj.getGUID())
  6580.             else
  6581.               table.insert(oActivatedOps, obj.getGUID())
  6582.             end
  6583.           end
  6584.         end
  6585.       end
  6586.     end
  6587.     if (next(oReadyOps) == nil and next(oActivatedOps) ~= nil) and (next(readyOps) ~= nil or not checkAllLooseOrdersActivated()) and next(overwatchTable[oPl.steam_name]) == nil then
  6588.         overwatchTable.checked = true
  6589.         for _, actObj in ipairs(oActivatedOps) do
  6590.           obj = getObjectFromGUID(actObj)
  6591.           objUI = obj.UI.getXmlTable()
  6592.           if string.find(getOperativeOrder(objUI), "Engage") then
  6593.             table.insert(overwatchTable[oPl.steam_name], actObj)
  6594.           end
  6595.         end
  6596.         local defaults = makeDefaults(rules)
  6597.         Wait.frames(function() updateOWXML(defaults, oPl) end, 20)
  6598.     else
  6599.       overwatchTable[oPl.steam_name] = {}
  6600.       overwatchTable[pl.steam_name] = {}
  6601.       overwatchTable.checked = false
  6602.     end
  6603.   end
  6604. end
  6605. function getOperativeOrder(objTable)
  6606.   for k1, v1 in ipairs(objTable) do
  6607.     ch1 = objTable[k1].children
  6608.     if objTable[k1].children ~= nil then
  6609.       for k2, v2 in ipairs(ch1) do
  6610.         if objTable[k1].children[k2].children ~= nil then
  6611.           ch2 = objTable[k1].children[k2].children
  6612.           for k3, v3 in ipairs(ch2) do
  6613.             if v3.attributes.id == "ktcnid-status-order" then
  6614.               return v3.attributes.image
  6615.             end
  6616.           end
  6617.         end
  6618.       end
  6619.     end
  6620.   end
  6621.   return ""
  6622. end
  6623. function updateOWXML(def, pl)
  6624.   oldTable = Global.UI.getXmlTable()
  6625.   if next(overwatchTable[pl.steam_name]) ~= nil then
  6626.     buttonCh = {}
  6627.     for _, actObj in ipairs(overwatchTable[pl.steam_name]) do
  6628.       addOverwatchToggle(pl, buttonCh, actObj, _)
  6629.     end
  6630.     for i, uiTable in ipairs(oldTable) do
  6631.       if uiTable.attributes.id == "kts__"..string.lower(pl.color).."_overwatch" then
  6632.         table.remove(oldTable, i)
  6633.         break
  6634.       end
  6635.     end
  6636.     table.insert(buttonCh, {
  6637.       tag="Text",
  6638.       attributes={
  6639.         class="title2",
  6640.         text=pl.steam_name.." Overwatch",
  6641.         fontSize=13,
  6642.         offsetXY="0 30"
  6643.       },
  6644.     })
  6645.     OWTable = {
  6646.       tag="Panel",
  6647.       attributes={
  6648.         id="kts__"..string.lower(pl.color).."_overwatch",
  6649.         rectAlignment="LowerRight",
  6650.         class="bkgPanel",
  6651.         height=80,
  6652.         width=300,
  6653.         offsetXY="-10 10",
  6654.         visibility=pl.color,
  6655.         active=true,
  6656.         allowDragging=true,
  6657.         returnToOriginalPositionWhenReleased=false
  6658.       },
  6659.       children=buttonCh
  6660.     }
  6661.     table.insert(oldTable, def)
  6662.     table.insert(oldTable, OWTable)
  6663.     Wait.frames(function() Global.UI.setXmlTable(oldTable) end, 1)
  6664.   end
  6665. end
  6666. function addOverwatchToggle(pl, tab, guid, ind)
  6667.   for line in getObjectFromGUID(guid).getDescription():gmatch("([^\n]*)\n?") do
  6668.     operativeName=line
  6669.     break
  6670.   end
  6671.   table.insert(tab,
  6672.     {
  6673.       tag="Panel",
  6674.       attributes={
  6675.         class="bkgPanel",
  6676.         height=80,
  6677.         width=300/#overwatchTable[pl.steam_name],
  6678.         offsetXY=(300*(ind-1)/#overwatchTable[pl.steam_name]).." 0",
  6679.         rectAlignment="MiddleLeft"
  6680.       },
  6681.       children={
  6682.         {
  6683.           tag="Button",
  6684.           attributes={
  6685.             id="kts__toggle_"..string.lower(pl.color).."_overwatch_"..guid,
  6686.             onClick=self.getGUID().."/onOverWatchTogglePressed("..ind..")",
  6687.             onMouseEnter=self.getGUID().."/onOverWatchToggleHover("..guid..")",
  6688.             tooltip=operativeName,
  6689.             rectAlignment="LowerCenter",
  6690.             offsetXY="0 -8",
  6691.           },
  6692.         },
  6693.         {
  6694.           tag="Text",
  6695.           attributes={
  6696.             id="kts__toggle_"..string.lower(pl.color).."_overwatch_text_"..guid,
  6697.             text="Operative",
  6698.             fontSize=12,
  6699.             offsetXY="0 -20",
  6700.           },
  6701.         },
  6702.       }
  6703.     })
  6704. end
  6705. function onOverWatchTogglePressed(player, value)
  6706.   local obj = getObjectFromGUID(overwatchTable[player.steam_name][tonumber(value)])
  6707.   obj.highlightOn(player.color)
  6708.   table.remove(overwatchTable[player.steam_name], tonumber(value))
  6709.   local defaults = makeDefaults(rules)
  6710.   if next(overwatchTable[player.steam_name]) == nil then
  6711.     setUIAttribute("kts__"..string.lower(player.color).."_overwatch", "active", false)
  6712.   else
  6713.     Wait.frames(function() updateOWXML(defaults, player) end, 20)
  6714.   end
  6715. end
  6716. function onOverWatchToggleHover(player, value)
  6717.   getObjectFromGUID(value).highlightOn(player.color, 0.2)
  6718. end
  6719. function checkAllOperativesActivated()
  6720.   allOpsActivated = true
  6721.   for _, obj in ipairs(getCMOperativesOnBoard()) do
  6722.     if obj.hasTag('Operative') and obj.hasTag('Not Mustered') ~= true then
  6723.       if string.find(getOperativeOrder(obj.UI.getXmlTable()), "_ready") then
  6724.         allOpsActivated = false
  6725.       end
  6726.     end
  6727.   end
  6728.   return allOpsActivated
  6729. end
  6730. function checkAllLooseOrdersActivated()
  6731.   allOrdsActivated = true
  6732.   for _, obj in ipairs(getLooseOrdersOnBoard()) do
  6733.     if string.find(obj.getName(), "_ready") then
  6734.       allOrdsActivated = false
  6735.     end
  6736.   end
  6737.   return allOrdsActivated
  6738. end
  6739. function checkOrdersCoherency()
  6740.   notCMObj = getNotCMOperativesOnBoard()
  6741.   looseOrders = getLooseOrdersOnBoard()
  6742.   if #looseOrders ~= #notCMObj then
  6743.     broadcastToAll("Did any of you forgot to remove a loose order?")
  6744.     return false
  6745.   end
  6746.   return true
  6747. end
  6748. function split(s, delimiter)
  6749.   stringResult = {};
  6750.   for match in (s..delimiter):gmatch("(.-)"..delimiter) do
  6751.       table.insert(stringResult, match);
  6752.   end
  6753.   name = ""
  6754.   for i=2, #stringResult do
  6755.     if name == "" then
  6756.       name = stringResult[i]
  6757.     else
  6758.       name = name.." "..stringResult[i]
  6759.     end
  6760.   end
  6761.   return name
  6762. end
  6763. function unsetHighLights()
  6764.   for _, obj in ipairs(getCMOperativesOnBoard()) do
  6765.     obj.highlightOff()
  6766.   end
  6767. end
  6768. function showYoutubeLink(pl)
  6769.   tabletObj = spawnObject({
  6770.       type = "Tablet",
  6771.       position = {-50, 10, 0},
  6772.       rotation = {70, 90, 0},
  6773.       scale = {2, 2, 2}
  6774.   })
  6775.   tabletObj.setLock(true)
  6776.   Player["Red"].lookAt({
  6777.       position = {x=-50,y=10,z=0},
  6778.       pitch    = 25,
  6779.       yaw      = 90,
  6780.       distance = 20,
  6781.   })
  6782.   Player["Blue"].lookAt({
  6783.       position = {x=-50,y=10,z=0},
  6784.       pitch    = 25,
  6785.       yaw      = -90,
  6786.       distance = 20,
  6787.   })
  6788.   Wait.frames(function() tabletObj.Browser.url = 'https://www.youtube.com/watch?v=GV7AnrjQr9A' end, 50)
  6789. end
  6790. function showOperativeSelection(pl)
  6791.   if getUIAttribute("kts__"..string.lower(pl.steam_name).."_operatives_selected", "width") ~= "400" then
  6792.     oldTable = Global.UI.getXmlTable()
  6793.     selectOpTable = {
  6794.       tag="Panel",
  6795.       attributes={
  6796.         id="kts__"..string.lower(pl.steam_name).."_operatives_selected",
  6797.         rectAlignment="MiddleCenter",
  6798.         allowDragging=true,
  6799.         returnToOriginalPositionWhenReleased=false,
  6800.         class="bkgPanel",
  6801.         height=100,
  6802.         width=400,
  6803.         offsetXY="-20 10",
  6804.         visibility=pl.color,
  6805.         active=true,
  6806.       },
  6807.       children={
  6808.         {
  6809.           tag="Text",
  6810.           attributes={
  6811.             fontSize=16,
  6812.             offsetXY="0 20"
  6813.           },
  6814.           value=[[Select your operatives with area selection
  6815.           (left click and drag) then press OK.
  6816.             No matter if you select other objects like orders, etc.]]
  6817.         },
  6818.         {
  6819.           tag="Button",
  6820.           attributes={
  6821.             onClick=self.guid.."/onOperativesSelected",
  6822.             height=30,
  6823.             width=100,
  6824.             offsetXY="0 -25"
  6825.           },
  6826.           value="OK"
  6827.         },
  6828.       }
  6829.     }
  6830.     local defaults = makeDefaults(rules)
  6831.     table.insert(oldTable, defaults)
  6832.     table.insert(oldTable, selectOpTable)
  6833.     Wait.frames(function() Global.UI.setXmlTable(oldTable) end, 1)
  6834.   else
  6835.     Global.UI.show("kts__"..string.lower(pl.steam_name).."_operatives_selected")
  6836.   end
  6837. end
  6838. function onOperativesSelected(player)
  6839.   local selectedObjects = player.getSelectedObjects()
  6840.   local count = 0
  6841.   for _, obj in ipairs(selectedObjects) do
  6842.     if obj.hasTag('Operative') and obj.hasTag('Not Mustered') ~= true then
  6843.       local oldDesc = obj.getDescription()
  6844.       if not string.find(oldDesc, "Owned by ") then
  6845.         newDesc = oldDesc.." Owned by "..player.steam_name
  6846.         obj.setDescription(newDesc)
  6847.         count = count + 1
  6848.       end
  6849.     end
  6850.   end
  6851.   broadcastToAll(player.steam_name.." has "..count.." operatives")
  6852.   Global.UI.hide("kts__"..string.lower(player.steam_name).."_operatives_selected")
  6853. end
  6854. function deselectOperatives(pl)
  6855.   Global.UI.hide("kts__"..string.lower(pl.steam_name).."_operatives_selected")
  6856.   for _, obj in ipairs(getCMOperativesOnBoard()) do
  6857.     local oldDesc = obj.getDescription()
  6858.     i, j = string.find(oldDesc, "Owned by "..pl.steam_name)
  6859.     if i then
  6860.       obj.setDescription(string.sub(oldDesc, 1, i-1))
  6861.     end
  6862.   end
  6863.   for _, obj in ipairs(getNotCMOperativesOnBoard()) do
  6864.     local oldDesc = obj.getDescription()
  6865.     i, j = string.find(oldDesc, "Owned by "..pl.steam_name)
  6866.     if i then
  6867.       obj.setDescription(string.sub(oldDesc, 1, i-1))
  6868.     end
  6869.   end
  6870. end
  6871. function changeMissionScoreboard(missionGUID)
  6872.   if missionIndexItd[missionGUID] ~= nil then
  6873.     setUIAttribute("kts__streamer_panel"..missionSelectedForScoreboard, "active", false)
  6874.     missionSelectedForScoreboard = missionGUID
  6875.     local tabs = Notes.getNotebookTabs()
  6876.     for _,t in pairs(tabs) do
  6877.       if t.title == settingsNotes then
  6878.         gmn = t.body
  6879.         break
  6880.       end
  6881.     end
  6882.     newSettings = JSON.decode(gmn)
  6883.     newSettings.scoring.primary = missionIndexItd[missionGUID].primary
  6884.     newSettings.scoring.bonus = missionIndexItd[missionGUID].bonus
  6885.     gmn = JSON.encode(newSettings)
  6886.     Notes.editNotebookTab({
  6887.       title=settingsNotes,
  6888.       body=gmn,
  6889.       color="Black"
  6890.     })
  6891.     setup(newSettings)
  6892.     buildUI()
  6893.     Wait.frames(refresh, 10)
  6894.     Wait.frames(function()
  6895.       if Global.UI.getAttribute("kts__streamer_panel"..missionSelectedForScoreboard, "id") == nil then
  6896.         local oldUI = Global.UI.getXmlTable()
  6897.         local hudVisibility, streamVisibility = getHudVisibilities()
  6898.         if oldUI == nil then
  6899.                 oldUI = {}
  6900.             end
  6901.         table.insert(oldUI, buildStreamerUI(streamVisibility))
  6902.         Wait.frames(function() Global.UI.setXmlTable(oldUI) end, 1)
  6903.       else
  6904.         setUIAttribute("kts__streamer_panel"..missionSelectedForScoreboard, "active", true)
  6905.       end
  6906.     end, 20)
  6907.   else
  6908.     if missionSelectedForScoreboard ~= "" then
  6909.       setUIAttribute("kts__streamer_panel"..missionSelectedForScoreboard, "active", false)
  6910.       setUIAttribute("kts__streamer_panel", "active", true)
  6911.       missionSelectedForScoreboard = ""
  6912.       local tabs = Notes.getNotebookTabs()
  6913.       for _,t in pairs(tabs) do
  6914.         if t.title == settingsNotes then
  6915.           gmn = t.body
  6916.           break
  6917.         end
  6918.       end
  6919.       newSettings = JSON.decode(gmn)
  6920.       newSettings.scoring.primary = {
  6921.         exclusive = JSON.decode('[false, false, false, false]'),
  6922.         max = 12,
  6923.         maxEach = 0,
  6924.         objectives = JSON.decode('["1+", "2+", "3+", "4+"]')
  6925.       }
  6926.       newSettings.scoring.bonus = {
  6927.         max = 0,
  6928.         objectives = JSON.decode('[]')
  6929.       }
  6930.       gmn = JSON.encode(newSettings)
  6931.       Notes.editNotebookTab({
  6932.         title=settingsNotes,
  6933.         body=gmn,
  6934.         color="Black"
  6935.       })
  6936.       setup(newSettings)
  6937.       buildUI()
  6938.       Wait.frames(refresh, 10)
  6939.     end
  6940.   end
  6941. end
  6942. function onObjectLeaveContainer(container, object)
  6943.   if missionIndexItd[container.getGUID()] ~= nil then
  6944.     if missionSelectedForScoreboard ~= container.getGUID() then
  6945.       changeMissionScoreboard(container.getGUID())
  6946.     end
  6947.   end
  6948. end
  6949. function updateMegaDeck()
  6950.   megaDeck = getObjectFromGUID(megaDeckGuid)
  6951.   oldMegaDeck = getObjectFromGUID(oldMegaDeckGuid)
  6952.   for _, containedObject in ipairs(megaDeck.getObjects()) do
  6953.     spawnedObject = megaDeck.takeObject()
  6954.     spawnedObject.destruct()
  6955.   end
  6956.   objectsToPut = {}
  6957.   for _, containedObject in ipairs(oldMegaDeck.getObjects()) do
  6958.     table.insert(objectsToPut, oldMegaDeck.takeObject())
  6959.   end
  6960.   for _, objectToPut in ipairs(objectsToPut) do
  6961.     oldMegaDeck.putObject(objectToPut)
  6962.     megaDeck.putObject(objectToPut)
  6963.   end
  6964. end
  6965. --ADDED by ZAKA
  6966.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement