Tabletop Simulator

Tabletop Simulator

评价数不足
Using Rotational Values (with Scripting) to Add Multiple Values to an Object
由 DeVoto 制作
This guide is my solution to easily attacking additional values to objects, without the need to hard code values in a script.
   
奖励
收藏
已收藏
取消收藏
Introduction
This guide is my solution to easily attacking additional values to objects, without the need to hard code values in a script. This solution offers a few benefits to hard-coding:

  • Allows non-scripting co-creators the ability to easily add or edit objects and their values which effect scripting
  • Object values can be changed in-game, and do not require a reload of scripts
  • Allows multiple values to be placed on an object (can be done by hard-coding and grabbing through tags)
  • Removes the need to connect hard-coded values with an object, instead, values are on on the object.
  • Removes the need to scroll through scripts to find a speicfic object (or edit the huge TTS json save file)

How It Works

Tabletop simulator allows multiple rotational values for an object. Usually, this is used for dice where specific rotations are associated with a number. However, we can have multiple rotational values for the same rotation.

When multiple rotational values share the same rotation, then only the one to the left is displayed.

This solution hijacks that fact, and uses
object.getRotationalValues()
to grab additional values for an object. That way, we can add or alter variables on an object using the UI and have our scripting grab those values.

Adding Rotational Values to Objects
Use the Rotational Value tool to access the rotation values of an object.



Click the red `+` (plus button) to open up the 'Rotational Value' dialog window. For this example, we will add three values, all with the same rotation of: `0, 0, 0`.

Add the Name you wish to appear on the on-hover tool-tip

For the first value, we will add the value that we want to have displayed in the tool-tip, this is optional. In this example, I've placed the name to be '4 of Hearts'.


As you can see, if you hover over it the name appears. If there are multiple rotational values for the same rotation, the value to the left, will be what is displayed in the tool tip.

Note: If there are multiple rotational values for the same rotation, the value to the left, will be what is displayed in the tool tip.

You can use the options on a rotational value to move it either to the left, or the right using the `<--` or `-->`.


Add Name, Value pairs to your objects

Next, add name value pairs to your objects. Here I've added two additional name, value pairs. 'suit' and 'amount' and assigned them values by using an '=' sign. For the x, y, and z variables, set them to the same thing as you did the name (in this example, 0).


The '=' here can be any other type of separator you wish, but you'll need to update the `SPLITTER` global variable to match it accordingly.

For this guide, the code is written to evaluate any 'name' given, so the name can be whatever you'd like. The value, on the right hand side, will be converted into an actual lua number if it can be converted to a number (using Lua's `tonumber` built-in function).

The '#' at the front of the values will hide that value from appearing from the tool-tip. Since we have the name to the very left (top of the stack), the other values will never display, thus the '#' is optional. The code I've included in this guide removes the `#`.
Code
Here is the code that demonstrates reading the rotational values and placing them into a table for later use.

In this example, I'm expecting the names "suit", and "amount" to be variables in the rotational values list, but they could be whatever you wish them to be.

The code is doing a simple parse of a lhs=rhs assignment parse (left hand side, right hand sign) and should be straight forward.

Anyone is welcome to use, modify or distribute code as they wish. Have fun!

SPLITTER = '=' CARD_TAG = "Cards" SUIT = "suit" AMOUNT = "amount" function onLoad() cards = getObjectsWithTag(CARD_TAG) for _, card in pairs(cards) do card_values = getCardValues(card) print("This card is of suit: '", card_values[SUIT], "' and has a value of: '", card_values[AMOUNT], "'") end end -- This function will parse a simple name, value pair syntax, where names and -- values are seperated by a '=' (Or whatever is set in the SPLITTER global -- variable above) and place them into a table: -- -- name=value -- -- If a value can be converted into a number (tonumber(value) does not return nil) -- this function will convert it into a number. function getCardValues(card) values = {} for _, rotationValuePairs in pairs(card.getRotationValues()) do -- getRotationValues() rotationValue = rotationValuePairs['value'] -- Skip rotational values that are not name-value pairs if not isNameValuePair(rotationValue) then goto continue end -- Remove leading '#', if present rotationValue = string.gsub(rotationValue, "#", "") name, value = splitValue(rotationValue) table.insert(values, name) values[name] = value ::continue:: end return values end function isNameValuePair(value) return string.find(value, SPLITTER) end function splitValue(value) s = split(value, SPLITTER) name = string.lower(s[1]) value = s[2] -- Convert the string to a number, if it is if isStringNumber(value) then value = tonumber(value) end return name, value end function isStringNumber(str) if tonumber(str) == nil then return false end return true end -- Lua does not have a built-in string split function. Thus we use this to split strings. -- Taken from, https://stackoverflow.com/a/7615129 function split(inputstr, sep) if sep == nil then sep = "%s" end local t = {} for str in string.gmatch(inputstr, "([^"..sep.."]+)") do table.insert(t, str) end return t end