-- Sets up and returns coordinates for all possible spawn zones. Because Lua assigns tables by reference -- and there is no built-in function to copy a table this is relatively brute force. -- -- Positions are all relative to the player mat, and most are consistent. The -- exception are the SetAside# zones, which are placed to the left of the mat -- for White/Green, and the right of the mat for Orange/Red. -- -- Investigator: Investigator card area. -- Minicard: Placement for the investigator's minicard, just above the player mat -- Deck, Discard: Standard locations for the deck and discard piles. -- BlankTop: used for assets that start in play (e.g. Duke) -- Tarot, Hand1, Hand2, Ally, BlankBottom, Accessory, Arcane1, Arcane2, Body: Asset slot positions -- Threat[1-4]: Threat area slots. Threat[1-3] correspond to the named threat area slots, and Threat4 is the blank threat area slot. -- SetAside[1-3]: Column closest to the player mat, with 1 at the top and 3 at the bottom. -- SetAside[4-6]: Column farther away from the mat, with 4 at the top and 6 at the bottom. -- SetAside1: Permanent cards -- SetAside2: Bonded cards -- SetAside3: Ancestral Knowledge / Underworld Market -- SetAside4: Upgrade sheets for customizable cards -- SetAside5: Hunch Deck for Joe Diamond -- SetAside6: currently unused local playerMatGuids = {} playerMatGuids["Red"] = "0840d5" playerMatGuids["Orange"] = "bd0ff4" playerMatGuids["White"] = "8b081b" playerMatGuids["Green"] = "383d8b" commonZones = {} commonZones["Investigator"] = { -1.17702, 0, 0.00209 } commonZones["Minicard"] = { -0.4668214, 0, -1.222326 } commonZones["Deck"] = { -1.822724, 0, -0.02940192 } commonZones["Discard"] = { -1.822451, 0, 0.6092291 } commonZones["Ally"] = { -0.6157398, 0, 0.02435675 } commonZones["Body"] = { -0.6306521, 0, 0.553170 } commonZones["Hand1"] = { 0.2155387, 0, 0.04257287 } commonZones["Hand2"] = { -0.1803701, 0, 0.03745948 } commonZones["Arcane1"] = { 0.2124223, 0, 0.5596902 } commonZones["Arcane2"] = { -0.1711275, 0, 0.5567944 } commonZones["Tarot"] = { 0.6016169, 0, 0.03273106 } commonZones["Accessory"] = { 0.6049907, 0, 0.5546234 } commonZones["BlankTop"] = { 1.758446, 0, 0.03965336 } commonZones["BlankBottom"] = { 1.754469, 0, 0.5634764 } commonZones["Threat1"] = { -0.9116555, 0, -0.6446251 } commonZones["Threat2"] = { -0.4544126, 0, -0.6428719 } commonZones["Threat3"] = { 0.002246313, 0, -0.6430681 } commonZones["Threat4"] = { 0.4590618, 0, -0.6432732 } Zones = {} Zones["White"] = {} Zones["White"]["Investigator"] = commonZones["Investigator"] Zones["White"]["Minicard"] = commonZones["Minicard"] Zones["White"]["Deck"] = commonZones["Deck"] Zones["White"]["Discard"] = commonZones["Discard"] Zones["White"]["Ally"] = commonZones["Ally"] Zones["White"]["Body"] = commonZones["Body"] Zones["White"]["Hand1"] = commonZones["Hand1"] Zones["White"]["Hand2"] = commonZones["Hand2"] Zones["White"]["Arcane1"] = commonZones["Arcane1"] Zones["White"]["Arcane2"] = commonZones["Arcane2"] Zones["White"]["Tarot"] = commonZones["Tarot"] Zones["White"]["Accessory"] = commonZones["Accessory"] Zones["White"]["BlankTop"] = commonZones["BlankTop"] Zones["White"]["BlankBottom"] = commonZones["BlankBottom"] Zones["White"]["Threat1"] = commonZones["Threat1"] Zones["White"]["Threat2"] = commonZones["Threat2"] Zones["White"]["Threat3"] = commonZones["Threat3"] Zones["White"]["Threat4"] = commonZones["Threat4"] Zones["White"]["SetAside1"] = { 2.345893, 0, -0.520315 } Zones["White"]["SetAside2"] = { 2.345893, 0, 0.042552 } Zones["White"]["SetAside3"] = { 2.345893, 0, 0.605419 } Zones["White"]["UnderSetAside3"] = { 2.495893, 0, 0.805419 } Zones["White"]["SetAside4"] = { 2.775893, 0, -0.520315 } Zones["White"]["SetAside5"] = { 2.775893, 0, 0.042552 } Zones["White"]["SetAside6"] = { 2.775893, 0, 0.605419 } Zones["White"]["UnderSetAside6"] = { 2.925893, 0, 0.805419 } Zones["Orange"] = {} Zones["Orange"]["Investigator"] = commonZones["Investigator"] Zones["Orange"]["Minicard"] = commonZones["Minicard"] Zones["Orange"]["Deck"] = commonZones["Deck"] Zones["Orange"]["Discard"] = commonZones["Discard"] Zones["Orange"]["Ally"] = commonZones["Ally"] Zones["Orange"]["Body"] = commonZones["Body"] Zones["Orange"]["Hand1"] = commonZones["Hand1"] Zones["Orange"]["Hand2"] = commonZones["Hand2"] Zones["Orange"]["Arcane1"] = commonZones["Arcane1"] Zones["Orange"]["Arcane2"] = commonZones["Arcane2"] Zones["Orange"]["Tarot"] = commonZones["Tarot"] Zones["Orange"]["Accessory"] = commonZones["Accessory"] Zones["Orange"]["BlankTop"] = commonZones["BlankTop"] Zones["Orange"]["BlankBottom"] = commonZones["BlankBottom"] Zones["Orange"]["Threat1"] = commonZones["Threat1"] Zones["Orange"]["Threat2"] = commonZones["Threat2"] Zones["Orange"]["Threat3"] = commonZones["Threat3"] Zones["Orange"]["Threat4"] = commonZones["Threat4"] Zones["Orange"]["SetAside1"] = { -2.350362, 0, -0.520315 } Zones["Orange"]["SetAside2"] = { -2.350362, 0, 0.042552 } Zones["Orange"]["SetAside3"] = { -2.350362, 0, 0.605419 } Zones["Orange"]["UnderSetAside3"] = { -2.500362, 0, 0.80419 } Zones["Orange"]["SetAside4"] = { -2.7803627, 0, -0.520315 } Zones["Orange"]["SetAside5"] = { -2.7803627, 0, 0.042552 } Zones["Orange"]["SetAside6"] = { -2.7803627, 0, 0.605419 } Zones["Orange"]["UnderSetAside6"] = { -2.9303627, 0, 0.80419 } -- Green positions are the same as White and Red the same as Orange Zones["Red"] = Zones["Orange"] Zones["Green"] = Zones["White"] -- Gets the global position for the given zone on the specified player mat. ---@param playerColor: Color name of the player mat to get the zone position for (e.g. "Red") ---@param zoneName: Name of the zone to get the position for. See Zones object documentation for a list of valid zones. ---@return: Global position table, or nil if an invalid player color or zone is specified function Zones.getZonePosition(playerColor, zoneName) if (playerColor ~= "Red" and playerColor ~= "Orange" and playerColor ~= "White" and playerColor ~= "Green") then return nil end return getObjectFromGUID(playerMatGuids[playerColor]).positionToWorld(Zones[playerColor][zoneName]) end -- Return the global rotation for a card on the given player mat, based on its metadata. ---@param playerColor: Color name of the player mat to get the rotation for (e.g. "Red") ---@param cardMetadata: Table of card metadata. Metadata fields type and permanent are required; all others are optional. ---@return: Global rotation vector for the given card. This will include the -- Y rotation to orient the card on the given player mat as well as a -- Z rotation to place the card face up or face down. function Zones.getDefaultCardRotation(playerColor, zone) local deckRotation = getObjectFromGUID(playerMatGuids[playerColor]).getRotation() if zone == "Investigator" then deckRotation = deckRotation + Vector(0, 270, 0) elseif zone == "Deck" then deckRotation = deckRotation + Vector(0, 0, 180) end return deckRotation end