Table Creator
- "-- Bundled by luabundle {\"version\":\"1.7.0\"}\nlocal __bundle_require, __bundle_loaded, __bundle_register, __bundle_modules = (function(superRequire)\n\tlocal loadingPlaceholder = {[{}] = true}\n\n\tlocal register\n\tlocal modules = {}\n\n\tlocal require\n\tlocal loaded = {}\n\n\tregister = function(name, body)\n\t\tif not modules[name] then\n\t\t\tmodules[name] = body\n\t\tend\n\tend\n\n\trequire = function(name)\n\t\tlocal loadedModule = loaded[name]\n\n\t\tif loadedModule then\n\t\t\tif loadedModule == loadingPlaceholder then\n\t\t\t\treturn nil\n\t\t\tend\n\t\telse\n\t\t\tif not modules[name] then\n\t\t\t\tif not superRequire then\n\t\t\t\t\tlocal identifier = type(name) == 'string' and '\\\"' .. name .. '\\\"' or tostring(name)\n\t\t\t\t\terror('Tried to require ' .. identifier .. ', but no such module has been registered')\n\t\t\t\telse\n\t\t\t\t\treturn superRequire(name)\n\t\t\t\tend\n\t\t\tend\n\n\t\t\tloaded[name] = loadingPlaceholder\n\t\t\tloadedModule = modules[name](require, loaded, register, modules)\n\t\t\tloaded[name] = loadedModule\n\t\tend\n\n\t\treturn loadedModule\n\tend\n\n\treturn require, loaded, register, modules\nend)(nil)\n__bundle_register(\"__root\", function(require, _LOADED, __bundle_register, __bundle_modules)\n--[[ Lua code. See documentation: api.tabletopsimulator.com\r\n\r\nIMPORTANT! PLEASE READ THIS!\r\n\r\nNOTE1: All TABLE CREATOR-related variables/functions use the naming convention \"<variable>_TC\" or \"TC.<function>\"\r\n- ie. don't worry about variable/function naming conflicts so long as you do *not* use a suffix of \"_TC\" or prefix of \"TC.\"\r\n\r\nNOTE2: The library of utilities (useful functions for coding in TTS) use the prefix \"Util.\" (ex. Util.get -> get object from GUID)\r\n- see the fully documented list of available functions in the [UTILITIES] section\r\n \r\nFor built-in TABLE CREATOR-related functions, you can assign variables in the [TABLE CREATOR VARIABLES] section; here's what they do:\r\n\r\n AUTO-DRAW CARDS = Variables for automatically replenishing drawn cards from a row/column (see mod for live example)\r\n\r\n gSetupBoard_TC = GUID of custom board used for buttons (required: Objects -> Components -> Boards -> Custom Board)\r\n gSetupButton_TC = GUID of object used for setup button (example: Objects -> Components -> Go -> Black Piece)\r\n gRoundButton_TC = GUID of object used for round button (example: Objects -> Components -> Go -> Black Piece)\r\n gStartMarker_TC = GUID of object used as the start player marker (example: Objects -> Components -> Chess -> Wood -> King Light)\r\n gTurnMarker_TC = GUID of object used as the turn marker (example: Objects -> Components -> Chess -> Wood -> Pawn Light)\r\n\r\n tTurnOrder_TC = Indexed table of player colors (ex. \"Red\") used to change the turn order for the next round\r\n NOTE: Any seated/hotseat player colors *not* in this table will be appended to the end in their existing turn order\r\n\r\n tTurnOrder_TC Example #1:\r\n - Set new start player for the next round based on seated positions (ie. clockwise from start player)\r\n ---8<---8<---8<---\r\n 1. Current round player turn order = [ Red, Blue, Green, White, Yellow ]\r\n 2. tTurnOrder_TC = {\"Green\"}\r\n 3. Next round player turn order = [ Green, White, Yellow, Red, Blue ]\r\n ---8<---8<---8<--- \r\n\r\n tTurnOrder_TC Example #2:\r\n - Set a player turn order *not* based on seated positions (ie. not *just* clockwise from start player)\r\n ---8<---8<---8<---\r\n 1. Current round player turn order = [ Red, Blue, Green, White, Yellow ]\r\n 2. tTurnOrder_TC = {\"Red\", \"Green\", \"Yellow\"}\r\n 3. Next round player turn order = [ Red, Green, Yellow, Blue, White ]\r\n ---8<---8<---8<--- \r\n\r\n vSetupBoardURL_TC = URL of your custom image for the setup board (image size of 1024 x 1024 or greater recommended)\r\n \r\nThis global script is divided into the following sections:\r\n\r\n SAVE: Variable assignments entered in this section are saved to the JSON (see this section on how to save data between saving & loading the mod)\r\n LOAD: Variable assignments entered in this section are loaded from the JSON; also, use this section to assign any other global variables \r\n STARTUP: After your global variables are assigned in the [LOAD] section, your code entered into the following sections is executed:\r\n 1. STARTUP: Every time the mod is loaded your code entered in this section is executed \r\n 2. NO SETUP: If setup has *not* been completed your code entered in this section is executed\r\n 3. SETUP: If setup has been completed your code entered in this section is executed\r\n SETUP: When the SETUP button is clicked your code entered in this section is executed\r\n ROUND: When the END ROUND button is clicked your code entered in this section is executed\r\n FUNCTIONS: Enter your functions that support your code in this section\r\n CREATE BUTTONS: Enter your button properties (position, size, color, function, etc.) in this section\r\n BUTTON FUNCTIONS: Enter the functions your buttons trigger, when clicked, in this section\r\n CREATE INPUTS: Enter your input properties (position, size, color, function, etc.) in this section\r\n INPUT FUNCTIONS: Enter the functions your inputs trigger, when text is entered, in this section\r\n TABLE CREATOR VARIABLES: Assign variables (GUIDs, positions, URLs, etc.) for TABLE CREATOR-related functions in this section\r\n EVENTS: For specific TTS events (ex. when an object leaves a container), your code entered into this section is executed\r\n UTILTIES: Functions in the utilities module (prefix \"Util.\") are documented (ex. Util.get -> get object from GUID) in this section\r\n\r\nFor mod-specific inquiries (ie. additions, requests, bugs, etc.), please feel free to comment on my steam profile here:\r\nhttps://steamcommunity.com (must be logged into steam)\r\n\r\nFor all other scripting-related inquiries, please join the Official Tabletop Simulator discord scripting channel found here:\r\nhttps://discord.com Util = require(\"lib.Util\") -- Utilities module (table of functions)\r\nlocal TC = require(\"lib.Table\") -- Table creator (TC) module (table of functions)\r\n\r\n-- Set all players as spectators\r\nfor _, oPlayer in pairs(Player.getPlayers()) do oPlayer.changeColor(\"Grey\") end\r\nbroadcastToAll(\"IMPORTANT! *AFTER* MOD IS LOADED:\\nSelect a player color to begin\", \"Grey\")\r\n\r\n--[[ SAVE ]]--\r\n\r\nfunction onSave() -- Triggered when mod is saved\r\n\r\n --[[\r\n \r\n HOW TO SAVE DATA WHEN SAVING/LOADING THE MOD\r\n \r\n 1. Enter data (variables, tables, etc.) in the [SET DATA] section below (see \"bHappy = true\" example)\r\n NOTE1: This is not necessary if the data has already been loaded into memory (ie. through code execution) before saving\r\n NOTE2: Object references (ex. oToken) can *not* be saved; save the object's GUID instead (ex. gToken)\r\n - Use the GUID to \"get\" the object reference in the onLoad section -> ex. oToken = Util.get(gToken)\r\n 2. Enter variables as <JSON variable> = <CODE variable> into the [SAVE DATA] table below (see \"Happy = bHappy\" example)\r\n 3. Enter variables as <CODE variable> = tData.<JSON variable> into the [LOAD DATA] section below (see \"bHappy = tData.Happy\" example)\r\n NOTE: Just in case the JSON's data isn't detected on load, enter data into the [DEFAULT DATA] section below (see \"bHappy = true\" example)\r\n 4. Send script to TTS -> VSCode = [Ctrl]+[Alt]+[S]\r\n NOTE: Skip steps 5 & 6 if you didn't enter any data into the SET DATA section\r\n 5. Save & reload the mod then remove data from the SET DATA section below (see \"bHappy = true\" example)\r\n 6. Send script to TTS -> VSCode = [Ctrl]+[Alt]+[S]\r\n 7. Voila! Data will now be saved to the JSON when saving the mod & loaded back into memory when loading the mod\r\n \r\n ]]--\r\n\r\n --[[ SET DATA ]]--\r\n -- bHappy = true\r\n\r\n local tSaveData = { -- Data to be saved to JSON file\r\n\r\n -- [[ SAVE DATA ]]--\r\n -- <JSON variable> (ex. Happy) = <CODE variable> (ex. bHappy) \r\n -- Happy = bHappy\r\n\r\n }\r\n return JSON.encode(TC.onSave(tSaveData)) -- Encode data into JSON file\r\n end\r\n\r\n--[[ LOAD ]]--\r\n\r\nfunction onLoad(tEncodedData) -- Triggered when mod finishes loading\r\n if Util.is(tEncodedData) then\r\n local tData = JSON.decode(tEncodedData) -- Decode data from JSON file\r\n\r\n --[[ LOAD DATA ]]--\r\n -- <CODE variable> (ex. bHappy) = tData.<JSON variable> (ex. tData.Happy) \r\n -- bHappy = tData.Happy\r\n\r\n TC.onLoad(tData) -- DO NOT DELETE! Load table-related data as well\r\n else\r\n\r\n --[[ DEFAULT DATA ]]--\r\n -- bHappy = true\r\n\r\n TC.defaults() -- DO NOT DELETE! Set table-related defaults as well\r\n end\r\n\r\n --[[ VARIABLES ]]--\r\n\r\n setVariables_TC() -- DO NOT DELETE! Table-related variables; see [TABLE CREATOR VARIABLES] below\r\n\r\n -- GUID: use \"g\" prefix to denote a GUID\r\n -- ex. gToken = \"123456\"\r\n\r\n -- OBJECT: use \"o\" prefix to denote an object\r\n -- ex. oToken = Util.get(gToken)\r\n\r\n -- TABLE: use \"t\" prefix to denote a table\r\n -- ex. tFruit = {\"apple\",\"orange\",\"banana\"}\r\n\r\n -- VARIABLE: use \"v\" prefix to denote a string (or combination of types)\r\n -- ex. vFruit = \"apple\"\r\n\r\n -- INTEGER: use \"n\" prefix to denote a number\r\n -- ex. nFruit = 3\r\n\r\n\t-- BOOLEAN: use \"b\" prefix to denote boolean\r\n -- ex. bFruit = true\r\n\r\n startLuaCoroutine(Global, \"doStartup_TC\") -- Triggers startup code (coroutine)\r\nend\r\n\r\n--[[ STARTUP ]]--\r\n\r\nfunction doStartup_TC() -- Triggered after variables initialized (coroutine)\r\n TC.table(\"Startup\") -- DO NOT DELETE! Table-related startup tasks\r\n if not tGameData_TC.setup then\r\n\r\n --[[\r\n\r\n \"NO SETUP\" CODE (COROUTINE):\r\n Enter code here to be executed every time the mod is loaded\r\n *AND* if setup has *NOT* been completed (ie. setup button *NOT* clicked)\r\n \r\n NOTE1: Saving the mod after setup is complete will encode that into the JSON file\r\n *AND* prevent this code from executing when the mod is loaded\r\n\r\n NOTE2: See [SETUP] section (below) to enter code to be executed\r\n when setup is triggered (ie. setup button is clicked)\r\n\r\n NOTE3: See [CREATE BUTTONS] section (below) to configure buttons\r\n for the setup board or table\r\n \r\n NOTE4: See [BUTTON FUNCTIONS] section (below) to enter functions\r\n to be performed when buttons are clicked\r\n\r\n ]]--\r\n\r\n TC.table(\"No-Setup\") -- DO NOT DELETE! Table-related tasks if setup not yet triggered\r\n else\r\n\r\n --[[\r\n\r\n \"SETUP DONE\" CODE (COROUTINE):\r\n Enter code here to be executed every time the mod is loaded\r\n *AND* if setup *HAS* been completed (ie. setup button clicked)\r\n \r\n NOTE1: Saving the mod after setup is complete will encode that into the JSON file\r\n *AND* ensure the code in this section is executed when the mod is loaded\r\n\r\n NOTE2: See [ROUND] section (below) to enter code to be executed\r\n when the next round is triggered (ie. end round button clicked)\r\n\r\n ]]--\r\n\r\n TC.table(\"Setup-Done\") -- DO NOT DELETE! Table-related tasks if setup has been triggered\r\n end\r\n\r\n --[[\r\n\r\n STARTUP CODE (COROUTINE):\r\n Enter code here to be executed every time the mod is loaded\r\n (ie. regardless of whether setup has been completed)\r\n\r\n NOTE1: See [EVENTS] section (below) to enter code to be executed\r\n when TTS-related events are triggered\r\n\r\n ]]--\r\n\r\n return 1\r\nend\r\n\r\n--[[ SETUP ]]--\r\n\r\nfunction doSetup_TC() -- Executed when setup button clicked (coroutine)\r\n if #Util.seated() > 0 then\r\n TC.table(\"Pre-Setup\") -- DO NOT DELETE! Table-related setup tasks *before* setup code routine\r\n\r\n --[[\r\n\r\n SETUP CODE (COROUTINE):\r\n Enter code here to be executed when the setup button is clicked\r\n\r\n ]]--\r\n\r\n TC.table(\"Post-Setup\") -- DO NOT DELETE! Table-related setup tasks *after* setup code routine\r\n else\r\n Util.broadcast(\"Please select a player color!\", \"All\", \"Grey\")\r\n end\r\n return 1\r\nend\r\n\r\n--[[ ROUND ]]--\r\n\r\nfunction doRound_TC() -- Executed when end round button clicked (coroutine)\r\n if tGameData_TC.setup then\r\n TC.table(\"Pre-Round\") -- DO NOT DELETE! Table-related round tasks *before* round code routine\r\n\r\n --[[\r\n\r\n ROUND CODE (COROUTINE):\r\n Enter code here to be executed when the end round button is clicked\r\n\r\n ]]--\r\n\r\n TC.table(\"Post-Round\") -- DO NOT DELETE! Table-related round tasks *after* round code routine\r\n else\r\n Util.broadcast(\"Please perform setup first!\", \"All\", \"Grey\")\r\n end\r\n return 1\r\nend\r\n\r\n--[[ FUNCTIONS ]]--\r\n\r\n-- Enter your functions that support your code in this section\r\n\r\n--[[ CREATE BUTTONS ]]--\r\n\r\n-- Enter your button properties (position, size, color, function, etc.) in this section\r\n\r\nfunction createButtons_TC(vType) -- Create buttons by type\r\n\r\n\tlocal tButton = { -- Default button parameters\r\n function_owner = Global, -- or \"self\" for objects\r\n click_function = \"none\", -- name of function triggered by click\r\n label = \"\", -- displayed name of button\r\n tooltip = \"\", -- text displayed during mouse-over\r\n width = 2750, -- width of button (relative to object)\r\n height = 1000, -- height of button (relative to object)\r\n color = \"Green\", -- color of button; either rgb (table) or player color (string)\r\n font_size = 400, -- size of label (relative to object)\r\n font_color = \"Black\", -- color of label; either rgb (table) or player color (string)\r\n --hover_color = \"Grey\", -- background color of button during mouse-over\r\n --press_color = \"Black\", -- background color of button when clicked\r\n position = {0, 0, 0}, -- position of button (relative to object center)\r\n rotation = {0, 0, 0}, -- rotation of button (relative to object's rotation)\r\n scale = {1, 1, 1}, -- scale of button (relative to object's scale)\r\n }\r\n\r\n -- Setup board buttons\r\n\r\n if vType == \"SetupBoard\" then\r\n -- NOTE: tButton.position -> set y = 0 to hide buttons but still clickable for customized setup boards (ex. {3, 0, 1.5})\r\n if Util.get(gSetupBoard_TC) then\r\n local oSetupBoard = Util.get(gSetupBoard_TC)\r\n\r\n\t\t\t-- DO NOT DELETE! This button required to execute setup\r\n tButton.click_function = \"click_doSetup_TC\" -- OK button (index 0)\r\n\t\t\ttButton.label = \"OK\"\r\n\t\t\ttButton.position = {0, 0.6, 5}\r\n\t\t\ttButton.tooltip = \"Click after all players are seated\"\r\n\t\t\toSetupBoard.createButton(tButton)\r\n\r\n -- MODIFY/DELETE! Just here as examples ...\r\n\t\t\ttButton.click_function = \"click_selectOption1_TC\" -- Option #1 button (index 1)\r\n\t\t\ttButton.label = \"[ ] Option #1\"\r\n\t\t\ttButton.position = {-3, 0.6, 1.5}\r\n\t\t\ttButton.color = \"Yellow\"\r\n\t\t\ttButton.tooltip = \"Example option button #1\"\r\n\t\t\toSetupBoard.createButton(tButton)\r\n\r\n\t\t\ttButton.click_function = \"click_selectOption2_TC\" -- Option #2 button 2 (index 2)\r\n\t\t\ttButton.label = \"[ ] Option #2\"\r\n\t\t\ttButton.position = {3, 0.6, 1.5}\r\n\t\t\ttButton.tooltip = \"Example option button #2\"\r\n\t\t\toSetupBoard.createButton(tButton)\r\n\t\tend\r\n end\r\nend\r\n\r\n--[[ BUTTON FUNCTIONS ]]--\r\n\r\n-- Enter the functions your buttons trigger, when clicked, in this section\r\n\r\n-- Sets a global variable (boolean) to true/false if option enabled/disabled (see bBoardOption1_TC)\r\nfunction click_selectOption1_TC(oButton, vPlayerColor, bAltClick) -- Executed when option button is clicked\r\n if not bAltClick then\r\n local oSetupBoard = Util.get(gSetupBoard_TC)\r\n\t\tif bBoardOption1_TC then -- Disable option\r\n oSetupBoard.editButton({ index = 1, label = \"[ ] Option #1\" })\r\n Util.broadcast(\"Option #1: Disabled\", \"All\", \"Yellow\")\r\n\t\t\tbBoardOption1_TC = false\r\n\t\telse -- Enable option\r\n oSetupBoard.editButton({ index = 1, label = \"[x] Option #1\" })\r\n Util.broadcast(\"Option #1: Enabled\", \"All\", \"Yellow\")\r\n\t\t\tbBoardOption1_TC = true\r\n\t\tend\r\n end\r\nend\r\n\r\n-- Sets a global variable (boolean) to true/false if option enabled/disabled (see bBoardOption2_TC)\r\nfunction click_selectOption2_TC(oButton, vPlayerColor, bAltClick) -- Executed when option button is clicked\r\n if not bAltClick then\r\n local oSetupBoard = Util.get(gSetupBoard_TC)\r\n\t\tif bBoardOption2_TC then -- Disable option\r\n oSetupBoard.editButton({ index = 2, label = \"[ ] Option #2\" })\r\n Util.broadcast(\"Option #2: Disabled\", \"All\", \"Yellow\")\r\n\t\t\tbBoardOption2_TC = false\r\n\t\telse -- Enable option\r\n oSetupBoard.editButton({ index = 2, label = \"[x] Option #2\" })\r\n Util.broadcast(\"Option #2: Enabled\", \"All\", \"Yellow\")\r\n\t\t\tbBoardOption2_TC = true\r\n\t\tend\r\n end\r\nend\r\n\r\n--[[ CREATE INPUTS ]]--\r\n\r\n-- Enter your input properties (position, size, color, function, etc.) in this section\r\n\r\nfunction createInputs_TC(vType) -- Create inputs by type\r\n\r\n local tInput = { -- Default input parameters\r\n function_owner = Global, -- or \"self\" for objects\r\n label = \"\", -- greyed out text if no value input\r\n input_function = \"none\", -- name of function triggered by every letter typed\r\n value = \"\", -- text entered into input\r\n tooltip = \"\", -- text displayed during mouse-over\r\n width = 400, -- width of input (relative to object)\r\n height = 400, -- height of input (relative to object)\r\n color = \"White\", -- input's background color; either rgb (table) or player color (string)\r\n font_size = 100, -- size of label (relative to object)\r\n font_color = {0, 0, 0}, -- color of input text; either rgb (table) or player color (string)\r\n position = {0, 0, 0}, -- position of input (relative to object center)\r\n rotation = {0, 0, 0}, -- rotation of input (relative to object's rotation)\r\n scale = {1, 1, 1}, -- scale of input (relative to object's scale)\r\n alignment = 1, -- text alignment (1=Automatic, 2=Left, 3=Center, 4=Right, 5=Justified)\r\n validation = 1, -- permitted character types (1=All, 2=Integer, 3=Float, 4=Alphanumeric, 5=Username, 6=Name)\r\n tab = 1, -- if TAB is pressed (1=Nothing, 2=Next Input, 3=Indent)\r\n }\r\n\r\nend\r\n\r\n--[[ INPUT FUNCTIONS ]]--\r\n\r\n-- Enter the functions your inputs trigger, when text is entered, in this section\r\n\r\n--[[ TABLE CREATOR VARIABLES ]]--\r\n\r\nfunction setVariables_TC() -- Set TABLE CREATOR-related variables here\r\n\r\n -- AUTO-DRAW CARDS\r\n -- Place decks on Deck GUID Fixer, click FIX DECK, then save/reload mod to ensure each deck's cards have a unique GUID\r\n\r\n nCardPiles_TC = 2 -- # of auto-drawn card piles\r\n\r\n -- Card Pile #1\r\n bDrawEndTurn1_TC = false -- auto-draw cards end of player turn only?\r\n gDiscardZone1_TC = \"4aedaf\" -- GUID of scripted zone of discard pile\r\n gDrawZone1_TC = \"59f9f2\" -- GUID of scripted zone of draw pile\r\n gCardZone1_TC = \"98040b\" -- GUID of scripted zone of auto-drawn cards\r\n tDrawPos1_TC = {-3.75, 1.23, -9.75} -- Position of draw pile\r\n tCardPos1_TC = { -- Position of each auto-drawn card (sequential order)\r\n {-1.25, 1.00, -9.75},\r\n {1.25, 1.00, -9.75},\r\n {3.75, 1.00, -9.75},\r\n {6.25, 1.00, -9.75},\r\n }\r\n\r\n -- Card Pile #2\r\n bDrawEndTurn2_TC = false -- auto-draw cards end of player turn only?\r\n gDiscardZone2_TC = \"925645\" -- GUID of scripted zone of discard pile\r\n gDrawZone2_TC = \"c80609\" -- GUID of scripted zone of draw pile\r\n gCardZone2_TC = \"1cead9\" -- GUID of scripted zone for auto-drawn cards\r\n tDrawPos2_TC = {-9.75, 1.02, 2.25} -- Position of draw pile\r\n tCardPos2_TC = { -- Position of each auto-drawn card (sequential order)\r\n {-9.75, 1.00, -0.25},\r\n {-9.75, 1.00, -2.75},\r\n {-9.75, 1.00, -5.25},\r\n }\r\n\r\n -- GUID\r\n\r\n gSetupBoard_TC = \"be5bbe\" -- GUID of custom board used for buttons (required: Objects -> Components -> Boards -> Custom Board)\r\n gSetupButton_TC = \"dbb918\" -- GUID of object used for setup button (example: Objects -> Components -> Go -> Black Piece)\r\n gRoundButton_TC = \"43fc13\" -- GUID of object used for round button (example: Objects -> Components -> Go -> Black Piece)\r\n\tgStartMarker_TC = \"20075b\" -- GUID of object used as the start player marker (example: Objects -> Components -> Chess -> Wood -> King Light)\r\n gTurnMarker_TC = \"8d6851\" -- GUID of object used as the turn marker (example: Objects -> Components -> Chess -> Wood -> Pawn Light) \r\n\r\n -- OBJECT\r\n\r\n -- TABLE\r\n\r\n tTurnOrder_TC = {} -- Indexed table of player colors (ex. \"Red\") used to change the turn order for the next round\r\n\r\n -- VARIABLE\r\n\r\n -- URL of your custom image for the setup board (image size of 1024 x 1024 or greater recommended)\r\n vSetupBoardURL_TC = \"steamusercontent-a.akamaihd.net -- INTEGER\r\n\r\n\t-- BOOLEAN\r\n\r\n\tbBoardOption1_TC = false\r\n\tbBoardOption2_TC = false\r\n\r\nend\r\n\r\n--[[ EVENTS ]]--\r\n\r\n-- Triggered when a player chooses/changes color (returns \"Grey\" upon disconnect)\r\nfunction onPlayerChangeColor(vPlayerColor)\r\n TC.onChangeColor(vPlayerColor) -- DO NOT DELETE! Table-related player tasks\r\n\r\n -- Enter code here\r\n\r\nend\r\n\r\n-- Triggered when on object leaves a container\r\nfunction onObjectLeaveContainer(oContainer, obj)\r\n -- Assigns deck tags to cards drawn from deck\r\n\tif oContainer.type == \"Deck\" then obj.setTags(oContainer.getTags()) end\r\n\r\n -- Enter code here\r\n\r\nend\r\n\r\n-- Triggered when an object enters a zone (scripting, hand, etc.)\r\nfunction onObjectEnterZone(oZone, obj)\r\n if obj then -- Object still exists?\r\n\r\n -- Object type: card, deck, tile, etc. \r\n\t\tif obj.type == \"Card\" then\r\n\r\n -- Enter code here\r\n\r\n\t\tend\r\n\tend\r\nend\r\n\r\n-- Triggered at the start of a player's turn (only with turns enabled)\r\nfunction onPlayerTurn(oPlayer, oPrevPlayer)\r\n TC.onPlayerTurn(oPlayer, oPrevPlayer) -- DO NOT DELETE! Table-related player tasks\r\n\r\n -- Enter code here\r\n\r\nend\r\n\r\n--[[ UTILITIES]]\r\n\r\n-- DOIT\nend)\n__bundle_register(\"lib.Table\", function(require, _LOADED, __bundle_register, __bundle_modules)\n-- Table Creator Ver: 1.0.1\r\n\r\nlocal Util = require(\"lib.Util\") -- Utilities module\r\n\r\nlocal tc = {} -- Library of functions for table creator lua module\r\n\r\n--[[ TABLE CREATOR (TC) ]]--\r\n\r\n-- SAVE/LOAD\r\n\r\nfunction tc.onSave(tSaveData_TC) -- Save provided variables at end of onSave()\r\n tGameData_TC.player = tGamePlayer_TC\r\n tGameData_TC.guid = tGameGUID_TC\r\n tGameData_TC.option = tGameOption_TC\r\n tSaveData_TC.tid = tImageData_TC\r\n tSaveData_TC.ftd = tTableData_TC\r\n tSaveData_TC.gtd = tGameData_TC\r\n return tSaveData_TC\r\nend\r\n\r\nfunction tc.onLoad(tData) -- Load JSON-provided variables at end of onLoad()\r\n tGameData_TC = tData.gtd\r\n tTableData_TC = tData.ftd\r\n tImageData_TC = tData.tid\r\n tGameOption_TC = tGameData_TC.option\r\n tGameGUID_TC = tGameData_TC.guid\r\n tGamePlayer_TC = tGameData_TC.player\r\nend\r\n\r\nfunction tc.defaults() -- Use defaults if encoded JSON data not found\r\n tImageData_TC = {}\r\n tTableData_TC = {\r\n config = \"Wide10\",\r\n move = true,\r\n scale = true,\r\n hide = false,\r\n grid = false\r\n }\r\n tGameData_TC = {\r\n guid = {\r\n hotseat = {},\r\n sboard = \"\",\r\n sbutton = \"\",\r\n rbutton = \"\",\r\n smarker = \"\",\r\n tmarker = \"\"\r\n },\r\n option = {\r\n hotseat = true,\r\n banners = true,\r\n hbuttons = true,\r\n sboard = true,\r\n sbutton = true,\r\n rbutton = true,\r\n smarker = true,\r\n tmarker = true,\r\n clockwise = true,\r\n autodraw = true,\r\n scripts = true\r\n },\r\n player = {},\r\n setup = false,\r\n start = \"\",\r\n turn = \"\",\r\n ver = \"\"\r\n }\r\nend\r\n\r\n-- TABLE\r\n\r\nfunction tc.table(vType) -- Triggered after onLoad()\r\n\r\n -- Table-related startup tasks\r\n if vType == \"Startup\" then\r\n\r\n --[[ BEGIN: VARIABLES ]]--\r\n\r\n -- GUID\r\n\r\n gClearTableButton_TC = \"4ca09c\"\r\n\r\n -- OBJECT\r\n\r\n oLeg1_TC = Util.get(\"afc863\") -- left front\r\n oLeg2_TC = Util.get(\"c8edca\") -- left back\r\n oLeg3_TC = Util.get(\"393bf7\") -- right back\r\n oLeg4_TC = Util.get(\"12c65e\") -- right front\r\n oSurface_TC = Util.get(\"4ee1f2\")\r\n oRailTop_TC = Util.get(\"35b95f\")\r\n oRailBottom_TC = Util.get(\"f938a2\")\r\n oRailLeft_TC = Util.get(\"9f95fd\")\r\n oRailRight_TC = Util.get(\"5af8f2\")\r\n\r\n oPanel_TC = Util.get(\"bd69bd\") -- Table control panel\r\n\r\n -- TABLE\r\n\r\n tPartGUIDs_TC = {\r\n \"afc863\", \"c8edca\", \"393bf7\", \"12c65e\", \"4ee1f2\",\r\n \"35b95f\", \"f938a2\", \"9f95fd\", \"5af8f2\", \"bd69bd\"\r\n }\r\n\r\n tConfigs_TC = {\r\n \"XWide10\", \"XTall10\", \"Wide10\", \"Tall8\",\r\n \"Full10\", \"Square8\", \"Square4\"\r\n }\r\n\r\n tGridURLs_TC = {\r\n \"steamusercontent-a.akamaihd.net \"steamusercontent-a.akamaihd.net \"steamusercontent-a.akamaihd.net \"steamusercontent-a.akamaihd.net \"132C346C3266432F470AB5352264722FCD80CEA1/\",\r\n" target="_blank" rel="noopener">steamusercontent-a.akamaihd.net \"steamusercontent-a.akamaihd.net \"steamusercontent-a.akamaihd.net }\r\n\r\n tGridConfig_TC = {\r\n {},\r\n {},\r\n {size = 0.75, x = 0.7, y = 0.43},\r\n {},\r\n {size = 0.72, x = 0.68, y = 0.76},\r\n {},\r\n {}\r\n }\r\n\r\n tBannerData_TC = {\r\n Name = \"Custom_Token\",\r\n Transform = {posX = 0, posY = 0, posZ = 0, rotX = 0, rotY = 0, rotZ = 0, scaleX = 1, scaleY = 1, scaleZ = 1},\r\n Tags = {\"Banner_TC\", \"HandZone_TC\"},\r\n Locked = true,\r\n CustomImage = {\r\n ImageURL = \"steamusercontent-a.akamaihd.net CustomToken = {Thickness = 0.1}\r\n },\r\n XmlUI = \"<Defaults>\\r\\n <Text\\r\\n color=\\\"#ffffff\\\"\\r\\n fontStyle=\\\"Bold\\\"\\r\\n fontSize=\\\"80\\\"\\r\\n outline=\\\"#000000\\\"\\r\\n outlineSize=\\\"2 -2\\\"\\r\\n shadow=\\\"#000000\\\"\\r\\n shadowDistance=\\\"5 -5\\\"\\r\\n position=\\\"0 0 -15\\\"\\r\\n rotation=\\\"0 0 180\\\"\\r\\n scale=\\\"0.5 1 0.75\\\"\\r\\n />\\r\\n <Image\\r\\n active=\\\"false\\\"\\r\\n image=\\\"XML_Pass\\\"\\r\\n width=\\\"300\\\"\\r\\n height=\\\"300\\\"\\r\\n outline=\\\"#000000\\\"\\r\\n position=\\\"0 7 -15\\\"\\r\\n rotation=\\\"0 0 185\\\" \\r\\n scale=\\\"0.5 1 0.75\\\"\\r\\n preserveAspect=\\\"true\\\"\\r\\n />\\r\\n</Defaults>\\r\\n\\r\\n<Text id=\\\"name\\\"></Text>\\r\\n\\r\\n<Image id=\\\"pass\\\"></Image>\"\r\n }\r\n\r\n tButtonData_TC = {\r\n Name = \"Custom_Assetbundle\",\r\n Transform = {posX = 0, posY = 0, posZ = 0, rotX = 0, rotY = 0, rotZ = 0, scaleX = 1, scaleY = 1, scaleZ = 1},\r\n Tags = {\"HandZone_TC\", \"HotseatButton_TC\"},\r\n Locked = true,\r\n CustomAssetbundle = {\r\n AssetbundleURL = \"steamusercontent-a.akamaihd.net },\r\n LuaScript = \"function onload()\\r\\n -- Button\\r\\n\\tlocal tButton = { -- Default button parameters\\r\\n function_owner = Global,\\r\\n click_function = \\\"click_Hotseat_TC\\\",\\r\\n label = \\\"\\\",\\r\\n color = {0,0,0},\\r\\n width = 1400,\\r\\n height = 1400,\\r\\n position = {0,0,0},\\r\\n }\\r\\n self.createButton(tButton)\\r\\nend\"\r\n }\r\n\r\n tPosHandZones_TC = {\r\n XTall10 = {\r\n Pink = {-54, 1.05, 110.49}, Purple = {-27, 1.05, 110.49}, Teal = {0, 1.05, 110.49}, Brown = {27, 1.05, 110.49}, Orange = {54, 1.05, 110.49}, -- Top\r\n Green = {-54, 1.05, -110.49}, Blue = {-27, 1.05, -110.49}, Red = {0, 1.05, -110.49}, Yellow = {27, 1.05, -110.49}, White = {54, 1.05, -110.49}, -- Bottom\r\n },\r\n Tall8 = {\r\n Purple = {-42.19, 1.05, 92.5}, Teal = {-14.06, 1.05, 92.5}, Brown = {14.06, 1.05, 92.5}, Orange = {42.19, 1.05, 92.5}, -- Top\r\n Green = {-42.19, 1.05, -92.5}, Blue = {-14.06, 1.05, -92.5}, Red = {14.06, 1.05, -92.5}, Yellow = {42.19, 1.05, -92.5}, -- Bottom\r\n },\r\n XWide10 = {\r\n Pink = {-86.40, 1.05, 48.78}, Purple = {-43.20, 1.05, 48.78}, Teal = {0, 1.05, 48.78}, Brown = {43.20, 1.05, 48.78}, Orange = {86.40, 1.05, 48.78}, -- Top\r\n Green = {-86.40, 1.05, -48.78}, Blue = {-43.20, 1.05, -48.78}, Red = {0, 1.05, -48.78}, Yellow = {43.20, 1.05, -48.78}, White = {86.40, 1.05, -48.78}, -- Bottom\r\n },\r\n Wide10 = {\r\n Purple = {-67.5, 1.05, 53.12}, Teal = {-22.5, 1.05, 53.12}, Brown = {22.5, 1.05, 53.12}, Orange = {67.5, 1.05, 53.12}, -- Top\r\n Green = {-67.5, 1.05, -53.12}, Blue = {-22.5, 1.05, -53.12}, Red = {22.5, 1.05, -53.12}, Yellow = {67.5, 1.05, -53.12}, -- Bottom\r\n Pink = {-92.50, 1.05, 0}, -- Left\r\n White = {92.50, 1.05, 0}, -- Right\r\n },\r\n Full10 = {\r\n Teal = {-36, 1.05, 56.5}, Brown = {0, 1.05, 56.5}, Orange = {36, 1.05, 56.5}, -- Top\r\n Green = {-36, 1.05, -56.5}, Blue = {0, 1.05, -56.5}, Red = {36, 1.05, -56.5}, -- Bottom\r\n Purple = {-74.50, 1.05, 18}, Pink = {-74.50, 1.05, -18}, -- Left\r\n White = {74.50, 1.05, 18}, Yellow = {74.50, 1.05, -18}, -- Right\r\n },\r\n Square8 = {\r\n Green = {-18, 1.05, 56.5}, Orange = {18, 1.05, 56.5}, -- Top\r\n Blue = {-18, 1.05, -56.5}, Red = {18, 1.05, -56.5}, -- Bottom\r\n Purple = {-56.5, 1.05, 18}, Pink = {-56.5, 1.05, -18}, -- Left\r\n White = {56.5, 1.05, 18}, Yellow = {56.5, 1.05, -18}, -- Right\r\n },\r\n Square4 = {\r\n Yellow = {0, 1.05, 38.5}, -- Top\r\n Blue = {0, 1.05, -38.5}, -- Bottom\r\n Green = {-38.5, 1.05, 0}, -- Left\r\n Red = {38.5, 1.05, 0}, -- Right\r\n }\r\n }\r\n\r\n tRotHandZones_TC = {\r\n XTall10 = {\r\n Pink = {0, 180, 0}, Purple = {0, 180, 0}, Teal = {0, 180, 0}, Brown = {0, 180, 0}, Orange = {0, 180, 0}, -- Top\r\n Green = {0, 0, 0}, Blue = {0, 0, 0}, Red = {0, 0, 0}, Yellow = {0, 0, 0}, White = {0, 0, 0}, -- Bottom\r\n },\r\n Tall8 = {\r\n Purple = {0, 180, 0}, Teal = {0, 180, 0}, Brown = {0, 180, 0}, Orange = {0, 180, 0}, -- Top\r\n Green = {0, 0, 0}, Blue = {0, 0, 0}, Red = {0, 0, 0}, Yellow = {0, 0, 0}, -- Bottom\r\n },\r\n XWide10 = {\r\n Pink = {0, 180, 0}, Purple = {0, 180, 0}, Teal = {0, 180, 0}, Brown = {0, 180, 0}, Orange = {0, 180, 0}, -- Top\r\n Green = {0, 0, 0}, Blue = {0, 0, 0}, Red = {0, 0, 0}, Yellow = {0, 0, 0}, White = {0, 0, 0}, -- Bottom\r\n },\r\n Wide10 = {\r\n Purple = {0, 180, 0}, Teal = {0, 180, 0}, Brown = {0, 180, 0}, Orange = {0, 180, 0}, -- Top\r\n Green = {0, 0, 0}, Blue = {0, 0, 0}, Red = {0, 0, 0}, Yellow = {0, 0, 0}, -- Bottom\r\n Pink = {0, 90, 0}, -- Left\r\n White = {0, 270, 0}, -- Right\r\n },\r\n Full10 = {\r\n Teal = {0, 180, 0}, Brown = {0, 180, 0}, Orange = {0, 180, 0}, -- Top\r\n Green = {0, 0, 0}, Blue = {0, 0, 0}, Red = {0, 0, 0}, -- Bottom\r\n Purple = {0, 90, 0}, Pink = {0, 90, 0}, -- Left\r\n White = {0, 270, 0}, Yellow = {0, 270, 0}, -- Right\r\n },\r\n Square8 = {\r\n Green = {0, 180, 0}, Orange = {0, 180, 0}, -- Top\r\n Blue = {0, 0, 0}, Red = {0, 0, 0}, -- Bottom\r\n Purple = {0, 90, 0}, Pink = {0, 90, 0}, -- Left\r\n White = {0, 270, 0}, Yellow = {0, 270, 0}, -- Right\r\n },\r\n Square4 = {\r\n Yellow = {0, 180, 0}, -- Top\r\n Blue = {0, 0, 0}, -- Bottom\r\n Green = {0, 90, 0}, -- Left\r\n Red = {0, 270, 0}, -- Right\r\n }\r\n }\r\n\r\n tScaHandZones_TC = {\r\n XTall10 = {18, 12, 5},\r\n Tall8 = {18.75, 12, 5},\r\n XWide10 = {28.80, 12, 5},\r\n Wide10 = {30, 12, 5},\r\n Full10 = {24, 12, 5},\r\n Square8 = {24, 12, 5},\r\n Square4 = {24, 12, 5},\r\n }\r\n\r\n tPosBanners_TC = {\r\n XTall10 = {\r\n Pink = {-54, 1.05, 109.99}, Purple = {-27, 1.05, 109.99}, Teal = {0, 1.05, 109.99}, Brown = {27, 1.05, 109.99}, Orange = {54, 1.05, 109.99}, -- Top\r\n Green = {-54, 1.05, -109.99}, Blue = {-27, 1.05, -109.99}, Red = {0, 1.05, -109.99}, Yellow = {27, 1.05, -109.99}, White = {54, 1.05, -109.99}, -- Bottom\r\n },\r\n Tall8 = {\r\n Purple = {-42.19, 1.05, 92}, Teal = {-14.06, 1.05, 92}, Brown = {14.06, 1.05, 92}, Orange = {42.19, 1.05, 92}, -- Top\r\n Green = {-42.19, 1.05, -92}, Blue = {-14.06, 1.05, -92}, Red = {14.06, 1.05, -92}, Yellow = {42.19, 1.05, -92}, -- Bottom\r\n },\r\n XWide10 = {\r\n Pink = {-86.40, 1.05, 48.28}, Purple = {-43.20, 1.05, 48.28}, Teal = {0, 1.05, 48.28}, Brown = {43.20, 1.05, 48.28}, Orange = {86.40, 1.05, 48.28}, -- Top\r\n Green = {-86.40, 1.05, -48.28}, Blue = {-43.20, 1.05, -48.28}, Red = {0, 1.05, -48.28}, Yellow = {43.20, 1.05, -48.28}, White = {86.40, 1.05, -48.28}, -- Bottom\r\n },\r\n Wide10 = {\r\n Purple = {-67.5, 1.05, 52.62}, Teal = {-22.5, 1.05, 52.62}, Brown = {22.5, 1.05, 52.62}, Orange = {67.5, 1.05, 52.62}, -- Top\r\n Green = {-67.5, 1.05, -52.62}, Blue = {-22.5, 1.05, -52.62}, Red = {22.5, 1.05, -52.62}, Yellow = {67.5, 1.05, -52.62}, -- Bottom\r\n Pink = {-92, 1.05, 0}, -- Left\r\n White = {92, 1.05, 0}, -- Right\r\n },\r\n Full10 = {\r\n Teal = {-36, 1.05, 56}, Brown = {0, 1.05, 56}, Orange = {36, 1.05, 56}, -- Top\r\n Green = {-36, 1.05, -56}, Blue = {0, 1.05, -56}, Red = {36, 1.05, -56}, -- Bottom\r\n Purple = {-74, 1.05, 18}, Pink = {-74, 1.05, -18}, -- Left\r\n White = {74, 1.05, 18}, Yellow = {74, 1.05, -18}, -- Right\r\n },\r\n Square8 = {\r\n Green = {-18, 1.05, 56}, Orange = {18, 1.05, 56}, -- Top\r\n Blue = {-18, 1.05, -56}, Red = {18, 1.05, -56}, -- Bottom\r\n Purple = {-56, 1.05, 18}, Pink = {-56, 1.05, -18}, -- Left\r\n White = {56, 1.05, 18}, Yellow = {56, 1.05, -18}, -- Right\r\n },\r\n Square4 = {\r\n Yellow = {0, 1.05, 38}, -- Top\r\n Blue = {0, 1.05, -38}, -- Bottom\r\n Green = {-38, 1.05, 0}, -- Left\r\n Red = {38, 1.05, 0}, -- Right\r\n }\r\n }\r\n\r\n tRotBanners_TC = {\r\n XTall10 = {\r\n Pink = {0, 0, 0}, Purple = {0, 0, 0}, Teal = {0, 0, 0}, Brown = {0, 0, 0}, Orange = {0, 0, 0}, -- Top\r\n Green = {0, 180, 0}, Blue = {0, 180, 0}, Red = {0, 180, 0}, Yellow = {0, 180, 0}, White = {0, 180, 0}, -- Bottom\r\n },\r\n Tall8 = {\r\n Purple = {0, 0, 0}, Teal = {0, 0, 0}, Brown = {0, 0, 0}, Orange = {0, 0, 0}, -- Top\r\n Green = {0, 180, 0}, Blue = {0, 180, 0}, Red = {0, 180, 0}, Yellow = {0, 180, 0}, -- Bottom\r\n },\r\n XWide10 = {\r\n Pink = {0, 0, 0}, Purple = {0, 0, 0}, Teal = {0, 0, 0}, Brown = {0, 0, 0}, Orange = {0, 0, 0}, -- Top\r\n Green = {0, 180, 0}, Blue = {0, 180, 0}, Red = {0, 180, 0}, Yellow = {0, 180, 0}, White = {0, 180, 0}, -- Bottom\r\n },\r\n Wide10 = {\r\n Purple = {0, 0, 0}, Teal = {0, 0, 0}, Brown = {0, 0, 0}, Orange = {0, 0, 0}, -- Top\r\n Green = {0, 180, 0}, Blue = {0, 180, 0}, Red = {0, 180, 0}, Yellow = {0, 180, 0}, -- Bottom\r\n Pink = {0, 270, 0}, -- Left\r\n White = {0, 90, 0}, -- Right\r\n },\r\n Full10 = {\r\n Teal = {0, 0, 0}, Brown = {0, 0, 0}, Orange = {0, 0, 0}, -- Top\r\n Green = {0, 180, 0}, Blue = {0, 180, 0}, Red = {0, 180, 0}, -- Bottom\r\n Purple = {0, 270, 0}, Pink = {0, 270, 0}, -- Left\r\n White = {0, 90, 0}, Yellow = {0, 90, 0}, -- Right\r\n },\r\n Square8 = {\r\n Green = {0, 0, 0}, Orange = {0, 0, 0}, -- Top\r\n Blue = {0, 180, 0}, Red = {0, 180, 0}, -- Bottom\r\n Purple = {0, 270, 0}, Pink = {0, 270, 0}, -- Left\r\n White = {0, 90, 0}, Yellow = {0, 90, 0}, -- Right\r\n },\r\n Square4 = {\r\n Yellow = {0, 0, 0}, -- Top\r\n Blue = {0, 180, 0}, -- Bottom\r\n Green = {0, 270, 0}, -- Left\r\n Red = {0, 90, 0}, -- Right\r\n }\r\n }\r\n\r\n tScaBanners_TC = {\r\n XTall10 = {3, 1, 3},\r\n Tall8 = {3.13, 1, 3},\r\n XWide10 = {4.8, 1, 3},\r\n Wide10 = {5, 1, 3},\r\n Full10 = {4, 1, 3},\r\n Square8 = {4, 1, 3},\r\n Square4 = {4, 1, 3},\r\n }\r\n\r\n tPosButtons_TC = {\r\n XTall10 = {\r\n Pink = {-54, -0.65, 112.09}, Purple = {-27, -0.65, 112.09}, Teal = {0, -0.65, 112.09}, Brown = {27, -0.65, 112.09}, Orange = {54, -0.65, 112.09}, -- Top\r\n Green = {-54, -0.65, -112.09}, Blue = {-27, -0.65, -112.09}, Red = {0, -0.65, -112.09}, Yellow = {27, -0.65, -112.09}, White = {54, -0.65, -112.09}, -- Bottom\r\n },\r\n Tall8 = {\r\n Purple = {-42.19, -0.65, 94.10}, Teal = {-14.06, -0.65, 94.10}, Brown = {14.06, -0.65, 94.10}, Orange = {42.19, -0.65, 94.10}, -- Top\r\n Green = {-42.19, -0.65, -94.10}, Blue = {-14.06, -0.65, -94.10}, Red = {14.06, -0.65, -94.10}, Yellow = {42.19, -0.65, -94.10}, -- Bottom\r\n },\r\n XWide10 = {\r\n Pink = {-86.40, -0.65, 50.38}, Purple = {-43.20, -0.65, 50.38}, Teal = {0, -0.65, 50.38}, Brown = {43.20, -0.65, 50.38}, Orange = {86.40, -0.65, 50.38}, -- Top\r\n Green = {-86.40, -0.65, -50.38}, Blue = {-43.20, -0.65, -50.38}, Red = {0, -0.65, -50.38}, Yellow = {43.20, -0.65, -50.38}, White = {86.40, -0.65, -50.38}, -- Bottom\r\n },\r\n Wide10 = {\r\n Purple = {-67.5, -0.65, 54.72}, Teal = {-22.5, -0.65, 54.72}, Brown = {22.5, -0.65, 54.72}, Orange = {67.5, -0.65, 54.72}, -- Top\r\n Green = {-67.5, -0.65, -54.72}, Blue = {-22.5, -0.65, -54.72}, Red = {22.5, -0.65, -54.72}, Yellow = {67.5, -0.65, -54.72}, -- Bottom\r\n Pink = {-94.1, -0.65, 0}, -- Left\r\n White = {94.1, -0.65, 0}, -- Right\r\n },\r\n Full10 = {\r\n Teal = {-36, -0.65, 58.1}, Brown = {0, -0.65, 58.1}, Orange = {36, -0.65, 58.1}, -- Top\r\n Green = {-36, -0.65, -58.1}, Blue = {0, -0.65, -58.1}, Red = {36, -0.65, -58.1}, -- Bottom\r\n Purple = {-76.1, -0.65, 18}, Pink = {-76.1, -0.65, -18}, -- Left\r\n White = {76.1, -0.65, 18}, Yellow = {76.1, -0.65, -18}, -- Right\r\n },\r\n Square8 = {\r\n Green = {-18, -0.65, 58.1}, Orange = {18, -0.65, 58.1}, -- Top\r\n Blue = {-18, -0.65, -58.1}, Red = {18, -0.65, -58.1}, -- Bottom\r\n Purple = {-58.1, -0.65, 18}, Pink = {-58.1, -0.65, -18}, -- Left\r\n White = {58.1, -0.65, 18}, Yellow = {58.1, -0.65, -18}, -- Right\r\n },\r\n Square4 = {\r\n Yellow = {0, -0.65, 40.1}, -- Top\r\n Blue = {0, -0.65, -40.1}, -- Bottom\r\n Green = {-40.1, -0.65, 0}, -- Left\r\n Red = {40.1, -0.65, 0}, -- Right\r\n }\r\n }\r\n\r\n tRotButtons_TC = {\r\n XTall10 = {\r\n Pink = {270, 180, 0}, Purple = {270, 180, 0}, Teal = {270, 180, 0}, Brown = {270, 180, 0}, Orange = {270, 180, 0}, -- Top\r\n Green = {90, 180, 0}, Blue = {90, 180, 0}, Red = {90, 180, 0}, Yellow = {90, 180, 0}, White = {90, 180, 0}, -- Bottom\r\n },\r\n Tall8 = {\r\n Purple = {270, 180, 0}, Teal = {270, 180, 0}, Brown = {270, 180, 0}, Orange = {270, 180, 0}, -- Top\r\n Green = {90, 180, 0}, Blue = {90, 180, 0}, Red = {90, 180, 0}, Yellow = {90, 180, 0}, -- Bottom\r\n },\r\n XWide10 = {\r\n Pink = {270, 180, 0}, Purple = {270, 180, 0}, Teal = {270, 180, 0}, Brown = {270, 180, 0}, Orange = {270, 180, 0}, -- Top\r\n Green = {90, 180, 0}, Blue = {90, 180, 0}, Red = {90, 180, 0}, Yellow = {90, 180, 0}, White = {90, 180, 0}, -- Bottom\r\n },\r\n Wide10 = {\r\n Purple = {270, 180, 0}, Teal = {270, 180, 0}, Brown = {270, 180, 0}, Orange = {270, 180, 0}, -- Top\r\n Green = {90, 180, 0}, Blue = {90, 180, 0}, Red = {90, 180, 0}, Yellow = {90, 180, 0}, -- Bottom\r\n Pink = {0, 180, 270}, -- Left\r\n White = {0, 180, 90}, -- Right\r\n },\r\n Full10 = {\r\n Teal = {270, 180, 0}, Brown = {270, 180, 0}, Orange = {270, 180, 0}, -- Top\r\n Green = {90, 180, 0}, Blue = {90, 180, 0}, Red = {90, 180, 0}, -- Bottom\r\n Purple = {0, 180, 270}, Pink = {0, 180, 270}, -- Left\r\n White = {0, 180, 90}, Yellow = {0, 180, 90}, -- Right\r\n },\r\n Square8 = {\r\n Green = {270, 180, 0}, Orange = {270, 180, 0}, -- Top\r\n Blue = {90, 180, 0}, Red = {90, 180, 0}, -- Bottom\r\n Purple = {0, 180, 270}, Pink = {0, 180, 270}, -- Left\r\n White = {0, 180, 90}, Yellow = {0, 180, 90}, -- Right\r\n },\r\n Square4 = {\r\n Yellow = {270, 180, 0}, -- Top\r\n Blue = {90, 180, 0}, -- Bottom\r\n Green = {0, 180, 270}, -- Left\r\n Red = {0, 180, 90}, -- Right\r\n }\r\n }\r\n\r\n tScaButtons_TC = {\r\n XTall10 = {0.5, 0.5, 0.5},\r\n Tall8 = {0.5, 0.5, 0.5},\r\n XWide10 = {0.5, 0.5, 0.5},\r\n Wide10 = {0.5, 0.5, 0.5},\r\n Full10 = {0.5, 0.5, 0.5},\r\n Square8 = {0.5, 0.5, 0.5},\r\n Square4 = {0.5, 0.5, 0.5},\r\n }\r\n\r\n local tColor = {0.25, 0.25, 0.25} -- Vector line color (grey)\r\n local nT = 0.1 -- Vector line thickness\r\n\r\n tVectorLines_TC = {\r\n {points = {{7.5,1,-8},{7.5,1,-11.5}},color = tColor,thickness = nT},\r\n {points = {{-7.5,1,-8},{7.5,1,-8}},color = tColor,thickness = nT},\r\n {points = {{-7.5,1,-8},{-7.5,1,-11.5}},color = tColor,thickness = nT},\r\n {points = {{-5,1,-8},{-5,1,-11.5}},color = tColor,thickness = nT},\r\n {points = {{-2.5,1,-8},{-2.5,1,-11.5}},color = tColor,thickness = nT},\r\n {points = {{-7.5,1,-11.5},{7.5,1,-11.5}},color = tColor,thickness = nT},\r\n {points = {{-8,1,-6.5},{-11.5,1,-6.5}},color = tColor,thickness = nT},\r\n {points = {{-11.5,1,-6.5},{-11.5,1,6}},color = tColor,thickness = nT},\r\n {points = {{-11.5,1,6},{-8,1,6}},color = tColor,thickness = nT},\r\n {points = {{-8,1,6},{-8,1,-6.5}},color = tColor,thickness = nT},\r\n {points = {{-11.5,1,3.5},{-8,1,3.5}},color = tColor,thickness = nT},\r\n {points = {{-11.5,1,1},{-8,1,1}},color = tColor,thickness = nT},\r\n }\r\n\r\n -- Turn order xml button bar colors (indexed by id #)\r\n tXmlBtnColors_TC = {}\r\n\r\n -- Passing player's colors\r\n tPassColors_TC = {}\r\n\r\n -- VARIABLE\r\n\r\n vTableCreatorVer_TC = tGameData_TC.ver\r\n vColorBaseURL_TC = \"steamusercontent-a.akamaihd.net vSetupGridURL_TC = \"steamusercontent-a.akamaihd.net -- INTEGER\r\n\r\n nHeightOffset_TC = -9.5\r\n nAutoDrawID_TC = nil\r\n nAutoCardID_TC = nil\r\n nAutoPileID_TC = nil\r\n nHandZoneID_TC = nil\r\n\r\n \t-- BOOLEAN\r\n\r\n bScaleDepth_TC = true\r\n bPanelActive_TC = false\r\n\r\n --[[ END: VARIABLES ]]--\r\n\r\n -- Set table parts non-interactable\r\n for _, gPart in ipairs(tPartGUIDs_TC) do\r\n local oPart = Util.get(gPart)\r\n if oPart then\r\n oPart.interactable = false\r\n ---@diagnostic disable-next-line: inject-field\r\n oPart.gizmo_selectable = false\r\n end\r\n end\r\n\r\n -- Set banners non-interactable\r\n if tGameOption_TC.banners then tc.setInteractable(\"Banner_TC\", false) end\r\n\r\n -- Set hotseat buttons non-interactable\r\n if tGameOption_TC.hbuttons then tc.setInteractable(\"HotseatButton_TC\", false) end\r\n\r\n -- Create table vector lines \r\n Global.setVectorLines(tVectorLines_TC)\r\n\r\n -- Hand zones\r\n tc.heightHand() -- Set hand zone height (ie. hides default player names under banners)\r\n tc.timedFunc(\"checkHandZone\", true) -- Start check for hand zone color change\r\n\r\n -- Hide table?\r\n tc.hideTable(tTableData_TC.hide, false)\r\n\r\n -- Buttons\r\n if tGameOption_TC.rbutton then tc.createButtons(\"Round\") end -- Create round button?\r\n tc.createButtons(\"Panel\") -- Create table control panel button\r\n tc.createButtons(\"Table\") -- Create other table-related button(s) (ex. clear table)\r\n\r\n -- Add xml player names to banners (if enabled)\r\n tc.setXmlPlayerNames()\r\n\r\n -- Deactivate xml setup button\r\n if tGameData_TC.setup then Global.UI.setAttribute(\"setup\", \"active\", false) end\r\n \r\n -- Auto-draw cards\r\n if tGameOption_TC.autodraw then tc.timedFunc(\"autoDrawCards\", true) end -- Start auto-draw cards timed function?\r\n end\r\n\r\n -- Table-related tasks if setup not yet triggered\r\n if vType == \"No-Setup\" then\r\n if tGameOption_TC.sboard then tc.setupBoard(true, vSetupBoardURL_TC) end -- Create setup board?\r\n if tGameOption_TC.sbutton then tc.setupButton(true) end -- Create setup button?\r\n end\r\n\r\n -- Table-related tasks if setup has been triggered\r\n if vType == \"Setup-Done\" then\r\n\r\n -- No code\r\n\r\n end\r\n\r\n -- Table-related setup tasks *before* setup code routine\r\n if vType == \"Pre-Setup\" then\r\n if tGameOption_TC.sboard then tc.setupBoard(false) end -- Destroy setup board?\r\n if tGameOption_TC.sbutton then tc.setupButton(false) end -- Destroy setup button?\r\n if Util.get(gClearTableButton_TC) then tc.del(\"SetupText\") end -- Delete setup text?\r\n end\r\n\r\n -- Table-related setup tasks *after* setup code routine\r\n if vType == \"Post-Setup\" then\r\n tc.playerTurn() -- Set turn order & active player then trigger turn\r\n if tGameOption_TC.autodraw then tc.drawInitialCards() end -- Draw initial auto-draw cards?\r\n Global.UI.setAttribute(\"setup\", \"active\", false) -- Hide xml setup button\r\n tGameData_TC.setup = true -- Setup done\r\n end\r\n\r\n -- Table-related round tasks *before* round code routine\r\n if vType == \"Pre-Round\" then\r\n\r\n -- No code\r\n\r\n end\r\n\r\n -- Table-related round tasks *after* round code routine\r\n if vType == \"Post-Round\" then\r\n tc.playerTurn() -- Set turn order & active player then trigger turn\r\n end\r\nend\r\n\r\nfunction tc.del(vType) -- Delete objects et al. based on provided type\r\n -- Delete setup-related text\r\n if vType == \"SetupText\" then\r\n local tText = {\"e710f6\", \"0f6bf1\", \"20e1cc\", \"1ce285\", \"e03f08\", \"dd9a9c\", \"13599c\"}\r\n for _, gText in ipairs(tText) do\r\n if Util.get(gText) then Util.del(gText) end\r\n end\r\n end\r\n\r\n -- Delete banners\r\n if vType == \"Banners\" then\r\n for _, oHandZone in ipairs(Hands.getHands()) do\r\n for _, obj in ipairs(oHandZone.getObjects(true)) do\r\n if obj.hasTag(\"Banner_TC\") then Util.del(obj) end\r\n end\r\n end\r\n end\r\n\r\n -- Delete hotseat buttons\r\n if vType == \"HotseatButtons\" then\r\n for _, oHandZone in ipairs(Hands.getHands()) do\r\n for _, obj in ipairs(oHandZone.getObjects(true)) do\r\n if obj.hasTag(\"HotseatButton_TC\") then Util.del(obj) end\r\n end\r\n end\r\n end\r\n\r\n -- Delete everything on table (except tagged with \"_TC\" suffix)\r\n if vType == \"Table\" then\r\n for _, obj in ipairs(getObjects()) do\r\n if obj.type ~= \"Hand\" then\r\n local bDelete = true\r\n for _, vTag in ipairs(obj.getTags()) do\r\n if string.match(vTag, \"_TC$\") then\r\n bDelete = false\r\n break\r\n end\r\n end\r\n if bDelete then Util.del(obj) end\r\n end\r\n end\r\n -- Delete all vector lines\r\n Global.setVectorLines({})\r\n end\r\n\r\n -- Delete hand zones & objects\r\n if vType == \"Hands\" then\r\n for _, oHandZone in ipairs(Hands.getHands()) do\r\n for _, obj in ipairs(oHandZone.getObjects(true)) do\r\n if obj.hasTag(\"HandZone_TC\") then Util.del(obj) end\r\n end\r\n Util.del(oHandZone)\r\n end\r\n end\r\nend\r\n\r\n-- PLAYER\r\n\r\nfunction tc.onChangeColor(vPlayerColor) -- Table-related tasks when onPlayerChangeColor() event triggered\r\n if vPlayerColor ~= \"Grey\" and vPlayerColor ~= \"Black\" then\r\n local oPlayer = Player[vPlayerColor]\r\n local nSteamID = oPlayer.steam_id\r\n -- Create player using steam id\r\n if not Util.is(tGamePlayer_TC[nSteamID]) then\r\n tGamePlayer_TC[nSteamID] = {\r\n name = \"\",\r\n color = \"\",\r\n hotseat = {}\r\n }\r\n Util.broadcast(\"Welcome \"..oPlayer.steam_name..\"!\", \"All\", vPlayerColor)\r\n end\r\n -- Update player's steam name\r\n tGamePlayer_TC[nSteamID].name = oPlayer.steam_name\r\n -- Banners enabled?\r\n if tGameOption_TC.banners then\r\n -- Add/remove xml name & update player's color\r\n tc.xmlName(nSteamID, vPlayerColor)\r\n else\r\n -- Update player's color\r\n tGamePlayer_TC[nSteamID].color = vPlayerColor\r\n end\r\n -- Remove xml name from players \r\n tc.removeXmlNames()\r\n end\r\nend\r\n\r\nfunction tc.onPlayerTurn(oPlayer, oPrevPlayer) -- Table-related tasks when onPlayerTurn() event triggered\r\n -- Move turn marker\r\n if Util.is(oPlayer) then\r\n tGameData_TC.turn = oPlayer.color\r\n tc.moveTurn(oPlayer.color)\r\n end\r\n -- Auto-draw cards enabled?\r\n if tGameOption_TC.autodraw then\r\n -- Auto-draw cards end of turn (if indicated)\r\n for nPile = 1, nCardPiles_TC do\r\n -- Draw end turn boolean exists?\r\n if Util.is(_G[\"bDrawEndTurn\"..nPile..\"_TC\"]) then\r\n -- Draw end turn only?\r\n if _G[\"bDrawEndTurn\"..nPile..\"_TC\"] then\r\n -- Card positions exist?\r\n if Util.is(_G[\"tCardPos\"..nPile..\"_TC\"]) then\r\n local tCardPos = _G[\"tCardPos\"..nPile..\"_TC\"]\r\n -- Card zone exists?\r\n if Util.get(_G[\"gCardZone\"..nPile..\"_TC\"]) then\r\n local oCardZone = Util.get(_G[\"gCardZone\"..nPile..\"_TC\"])\r\n -- Trigger auto-draw card functions\r\n _G[\"bDrawEndTurn\"..nPile..\"_TC\"] = false\r\n Wait.condition(\r\n -- Set draw end of turn boolean true once card zone is filled\r\n function() _G[\"bDrawEndTurn\"..nPile..\"_TC\"] = true end,\r\n function()\r\n local nCount = 0\r\n -- Count deck/card objects in card zone\r\n for _, obj in ipairs(oCardZone.getObjects()) do\r\n if obj.type == \"Deck\" or obj.type == \"Card\" then nCount = nCount + 1 end\r\n end\r\n -- Return true if # of cards in card zone equals # of card positions\r\n if nCount >= #tCardPos then return true end\r\n -- Otherwise, return false\r\n return false\r\n end\r\n )\r\n end\r\n end\r\n end\r\n end\r\n end\r\n end\r\nend\r\n\r\nfunction tc.xmlName(nSteamID1, vNewPlayerColor)-- Add/remove xml name & update player's color\r\n local oPlayer = Player[vNewPlayerColor]\r\n local vOldPlayerColor = tGamePlayer_TC[nSteamID1].color\r\n local nSteamID2 = nil\r\n local bHotseat = false\r\n -- Hotseat enabled?\r\n if tGameOption_TC.hotseat then\r\n -- Is new player's color a hotseat?\r\n for nSteamID, tPlayer in pairs(tGamePlayer_TC) do\r\n if Util.is(tPlayer.hotseat) then\r\n for vColor, vName in pairs(tPlayer.hotseat) do\r\n if vColor == vNewPlayerColor then\r\n nSteamID2 = nSteamID\r\n bHotseat = true\r\n break\r\n end\r\n end\r\n end\r\n end\r\n -- Is new player's color a player with their hotseat seated?\r\n for nSteamID, tPlayer in pairs(tGamePlayer_TC) do\r\n if tPlayer.color == vNewPlayerColor then\r\n if Util.is(tPlayer.hotseat) then\r\n for vColor1, vName in pairs(tPlayer.hotseat) do\r\n for _, vColor2 in ipairs(Util.seated()) do\r\n if vColor1 == vColor2 then\r\n bHotseat = true\r\n break\r\n end\r\n end\r\n end\r\n end\r\n end\r\n end\r\n end\r\n -- If hotseat detected, don't remove xml from banner\r\n if bHotseat then\r\n -- If a player attempts to change color to another player's hotseat, change back to previous color\r\n if nSteamID1 ~= nSteamID2 then\r\n oPlayer.changeColor(vOldPlayerColor)\r\n else\r\n -- If setup not done, no players can change color to their hotseats\r\n if not tGameData_TC.setup then oPlayer.changeColor(vOldPlayerColor) end\r\n end\r\n else\r\n local bDetect = false\r\n -- Don't remove xml name if duplicate color assignments\r\n for nSteamID, tPlayer in pairs(tGamePlayer_TC) do\r\n if nSteamID ~= nSteamID1 then\r\n if tPlayer.color == vOldPlayerColor then\r\n bDetect = true\r\n break\r\n end\r\n end\r\n end\r\n if not bDetect then\r\n -- Remove xml name from old banner color\r\n if Util.is(vOldPlayerColor) then\r\n local oOldBanner = tc.getBanner(vOldPlayerColor)\r\n if oOldBanner then oOldBanner.UI.setAttribute(\"name\", \"text\", \"\") end\r\n end\r\n end\r\n -- Add xml name to new banner color\r\n local oNewBanner = tc.getBanner(vNewPlayerColor)\r\n if oNewBanner then oNewBanner.UI.setAttribute(\"name\", \"text\", oPlayer.steam_name) end\r\n -- Set player to new player color \r\n tGamePlayer_TC[nSteamID1].color = vNewPlayerColor\r\n end\r\nend\r\n\r\nfunction tc.migratePlayerColor(nSteamID1, vNewPlayerColor) -- Migrate player color & hotseats to new player\r\n for nSteamID, tPlayer in pairs(tGamePlayer_TC) do\r\n -- Old player color?\r\n if vNewPlayerColor == tPlayer.color then\r\n -- If existing, migrate hotseats to new player\r\n if Util.is(tPlayer.hotseat) then\r\n tGamePlayer_TC[nSteamID1].hotseat = tPlayer.hotseat\r\n tPlayer.hotseat = \"\"\r\n end\r\n -- Remove color from previous player\r\n tPlayer.color = \"\"\r\n break\r\n end\r\n end\r\n -- Set player to new player color \r\n tGamePlayer_TC[nSteamID1].color = vNewPlayerColor\r\nend\r\n\r\nfunction tc.removeXmlNames() -- Remove xml name from players\r\n -- Check to remove xml names from valid seat colors\r\n for _, vColor1 in ipairs(Player.getAvailableColors()) do\r\n local bSeated = false\r\n -- Is a player seated in this valid seat color? \r\n for _, vColor2 in ipairs(Util.seated()) do\r\n if vColor1 == vColor2 then\r\n -- Player seated in this valid seat color; do not remove\r\n bSeated = true\r\n break\r\n end\r\n end\r\n -- Player not seated in this valid seat color\r\n if not bSeated then\r\n local bHotseat = false\r\n -- Hotseat mode?\r\n if tGameOption_TC.hotseat then\r\n -- Is hotseat seated in this valid seat color?\r\n for _, vColor3 in ipairs(tc.hotseatColor()) do\r\n if vColor1 == vColor3 then\r\n -- Hotseat seated in this valid seat color; do not remove\r\n bHotseat = true\r\n break\r\n end\r\n end\r\n end\r\n -- Hotseat not seated at this valid seat color\r\n if not bHotseat then\r\n local bPlayer = false\r\n -- Hotseat mode?\r\n if tGameOption_TC.hotseat then\r\n -- Is this player color seated in one of their hotseats? If so, do not remove\r\n bPlayer = tc.isHotseatSeated(vColor1)\r\n end\r\n -- Player color not seated in one of their hotseats\r\n if not bPlayer then\r\n -- Remove xml name for this valid seat color\r\n local oBanner = tc.getBanner(vColor1)\r\n if oBanner then oBanner.UI.setAttribute(\"name\", \"text\", \"\") end\r\n end\r\n end\r\n end\r\n end\r\nend\r\n\r\nfunction tc.isHotseatSeated(vColor) -- Return true if this player color is seated in one of their hotseats\r\n for _, tPlayer in pairs(tGamePlayer_TC) do\r\n if tPlayer.color == vColor then\r\n if Util.is(tPlayer.hotseat) then\r\n for vColor1, vName in pairs(tPlayer.hotseat) do\r\n for _, vColor2 in ipairs(Util.seated()) do\r\n if vColor1 == vColor2 then return true end\r\n end\r\n end\r\n end\r\n end\r\n end\r\nend\r\n\r\nfunction tc.hotseatColor() -- Returns an indexed table of hotseat colors\r\n local tHotseat = {}\r\n for nSteamID, tPlayer in pairs(tGamePlayer_TC) do\r\n if Util.is(tPlayer.hotseat) then\r\n for vColor, vName in pairs(tPlayer.hotseat) do\r\n tHotseat[#tHotseat+1] = vColor\r\n end\r\n end\r\n end\r\n return tHotseat\r\nend\r\n\r\nfunction tc.getBanner(vPlayerColor) -- Return banner object for player's color\r\n for gZone, vColor in pairs(tc.handGUID_Color()) do\r\n if vPlayerColor == vColor then\r\n local oHandZone = Util.get(gZone)\r\n for _, obj in ipairs(oHandZone.getObjects(true)) do\r\n if obj.hasTag(\"Banner_TC\") then return obj end\r\n end\r\n end\r\n end\r\nend\r\n\r\nfunction tc.setXmlPlayerNames() -- Add xml player names to banners if player banners enabled\r\n if tGameOption_TC.banners then\r\n for _, tPlayer in pairs(tGamePlayer_TC) do\r\n -- Add xml player name to banner\r\n if Util.is(tPlayer.color) and tPlayer.color ~= \"Black\" then\r\n local oBanner1 = tc.getBanner(tPlayer.color)\r\n if oBanner1 then oBanner1.UI.setAttribute(\"name\", \"text\", tPlayer.name) end\r\n end\r\n if Util.is(tPlayer.hotseat) then\r\n -- Add xml hotseat name to banner \r\n for vColor, vName in pairs(tPlayer.hotseat) do\r\n local oBanner2 = tc.getBanner(vColor)\r\n if oBanner2 then oBanner2.UI.setAttribute(\"name\", \"text\", vName) end\r\n end\r\n end\r\n end\r\n end\r\nend\r\n\r\nfunction tc.getPlayerName(vPlayerColor)\r\n -- Players\r\n for nSteamID, tPlayer in pairs(tGamePlayer_TC) do\r\n if vPlayerColor == tPlayer.color then return tPlayer.name end\r\n end\r\n -- Hotseats\r\n for nSteamID, tPlayer in pairs(tGamePlayer_TC) do\r\n if Util.is(tP
Pasted 2026-04-03 21:22:31
Short link:
Short link: