Lua API:Tools
The tools
API contains methods for creating and reading properties of custom tools and built-in tools.
"Tools" in a general sense refers to any selectable tool in the game, including elements, tools, walls, and decoration tools. If you can select it and it gets a red border around it, it's a tool, and you can read its properties with this API.
Most of the usefulness of the API comes from creating custom tools. Custom tools receive the same callbacks as everything in the Tools menu. They interact with locations the user is drawing the brush at.
Contents
Methods
tools.allocate
Create a new tool.
toolIndex = tools.allocate(group, name)
-
group
: string without underscores (_
), the group the tool belongs to; gets uppercased by the function -
name
: string without underscores (_
), the internal name of the tool; gets uppercased by the function -
toolIndex
: the number of the tool index allocated for this tool
group
should be something unique to your script, and should be the same across the entire script. It is common to use a simpler version of your username or the script’s name. If your script has any custom elements, you should use the same group as those. You can never create custom tools in the DEFAULT
group, trying to do so results in an error.
name
should be unique to the tool within your script, and ideally should resemble the Name
property of your tool.
The resulting tool identifier must be unique across all scripts in use at any point in time.
The new tool is created with all the default properties, and will not be visible until you modify it to show up in the menu.
tools.free
Free a previously allocated tool.
tools.free(toolIndex)
-
toolIndex
: tool index of the tool to be freed
This function will ONLY free custom Lua tools. Built-in tools, i.e. tools in the group DEFAULT
, and custom elements from other scripts cannot be freed.
tools.property
Query or update a property of a tool.
propValue = tools.property(toolIndex, propName) -- query variant tools.property(toolIndex, propName, propValue) -- update variant
-
toolIndex
: tool index of the tool whose property is to be queried or updated -
propName
: string, name of the property to be queried or updated -
propValue
: various types, value of the property to be queried or updated
For more information on what properties there are to use in elements.property, and how to use them, see Tool properties.
Several event callback functions are implemented, such as "Perform" and "Select". These are critical for making your tool actually do anything when used. To set these, use a function for propValue
. For more info on all the callbacks, see Tool callback functions.
tools.exists
Check whether a number is a real tool index
exists = tools.exists(toolIndex)
-
toolIndex
: number of the tool to be checked -
exists
: boolean,true
iftoolIndex
refers to a valid tool
If a tool exists, there exists a corresponding tools.index.[group]_PT_[name]
constant, and conversely, if there exists such a constant, there exists a corresponding tool.
tools.isCustom
Checks whether a number is a real tool index that refers to a custom Lua tool
custom = tools.isCustom(toolIndex)
-
toolIndex
: number of the tool to be checked -
custom
: boolean,true
iftoolIndex
refers to a valid tool, for a tool that was previously allocated with tools.allocate.
Constants
tools.index
A table that maps Identifiers to their tool indices.
airTool = tools.index.DEFAULT_TOOL_AIR
Tool indices are arbitrary and not guaranteed to be constant for any particular tool between versions.
The identifiers for all built-in and custom tools are in this table. The format for an Identifier depends on the type of tool. It is roughly [group]_[type]_[name]
, where [group] is DEFAULT for built-in tools, and [type] could be PT, TOOL, WL, or more depending on the type.
You can get an identifier by selecting it and checking ui.activeTool(0). Every selectable tool is available in tools.index for lookup.
Tool properties
Name | Name, it is recommended to use 4 letters or less. 5 or more will probably not fit on the buttons. |
Description | A short one-two sentence description of the tool, shown when you mouse over it in-game. |
Color | Tool button color, in hexadecimal (0xRRGGBB). |
MenuSection | The menu section it's in. See here for a list of possible values. For example, use elem.SC_TOOL to put it in the tools menu. |
MenuVisible | If it's visible in the menu, if 0 then it is hidden. 0 by default. |
Tool callback functions
Perform
Called for every position when drawing a tool.
Perform(i, x, y, strength, shift, ctrl, alt, brushX, brushY)
-
i
: Particle ID under the brush, or nil if there is no particle in that position -
x
: X position being drawn on -
y
: Y position being drawn on -
strength
: Tool strength. TPT sets strength to 10 when holding shift and to 0.1 when holding ctrl. -
shift
: true if shift is held, otherwise false -
ctrl
: true if ctrl is held, otherwise false -
alt
: true if alt is held, otherwise false -
brushX
: Center X position of the brush -
brushY
: Center Y position of the brush
When doing standard brush drawing, every point along the lines as you move your mouse has the tool applied at every brush position. This means Perform can be called a large number of times in every position, depending on how big the brush is. When doing box drawing, every position is called only once. Flood fill doesn't trigger any Perform calls at all.
If the Draw, DrawLine, or DrawRect callbacks have custom handlers, then Perform() won't be called in certain situations.
Click
Called at the last position when normal brush drawing ends.
Click(brushID, x, y, strength, shift, ctrl, alt)
-
brushID
: brush index of the brush being drawn -
x
: X position where the mouse was clicked (mouseup) -
y
: Y position where the mouse was clicked (mouseup) -
strength
: Tool strength. TPT sets strength to 10 when holding shift and to 0.1 when holding ctrl. -
shift
: true if shift is held, otherwise false -
ctrl
: true if ctrl is held, otherwise false -
alt
: true if alt is held, otherwise false
Click can be used to implement one-time events when your tool is clicked somewhere. During the whole drawing process, it is only sent once at the end, when the mouse is released. It's sent immediately after the last DrawLine callback.
Drag
Called every frame while the brush is in line preview mode. In vanilla, this is used only for WIND tool.
Drag(brushID, x, y, strength, shift, ctrl, alt)
-
brushID
: brush index of the brush being drawn -
x1
: X position where line started -
y1
: Y position where the line started -
x2
: X position where the line currently is now -
y2
: Y position where the line currently is now -
strength
: Tool strength. TPT sets strength to 10 when holding shift and to 0.1 when holding ctrl. -
shift
: true if shift is held, otherwise false -
ctrl
: true if ctrl is held, otherwise false -
alt
: true if alt is held, otherwise false
This callback exists purely to implement WIND-tool behavior where air is created prior to the mouse actually being released. It is called every frame for as long as the mouse is held down.
Draw
Called at the first position when normal brush drawing begins.
Draw(brushID, x, y, strength, shift, ctrl, alt)
-
brushID
: brush index of the brush being drawn -
x
: X position where the mouse was clicked (mousedown) -
y
: Y position where the mouse was clicked (mousedown) -
strength
: Tool strength. TPT sets strength to 10 when holding shift and to 0.1 when holding ctrl. -
shift
: true if shift is held, otherwise false -
ctrl
: true if ctrl is held, otherwise false -
alt
: true if alt is held, otherwise false
Draw can be used to implement one-time events when tool drawing begins. It's sent at the beginning, on the first frame the mouse is down. Every following frame, DrawLine is sent instead.
Adding a listener to this callback will suppress default behavior. The default behavior of a tool is to call the Perform callback for every position in the brush. Without this default behavior, Perform won't be called at all for the first frame of brush drawing.
DrawLine
While the brush is being drawn, called every time the mouse moves, when it's released, and also every frame while the mouse is stationary.
DrawLine(brushID, x1, y1, x2, y2, strength, shift, ctrl, alt)
-
brushID
: brush index of the brush being drawn -
x1
: X position where the line starts -
y1
: Y position where the line starts -
x2
: X position where the line ends -
y2
: Y position where the line ends -
strength
: Tool strength. TPT sets strength to 10 when holding shift and to 0.1 when holding ctrl. -
shift
: true if shift is held, otherwise false -
ctrl
: true if ctrl is held, otherwise false -
alt
: true if alt is held, otherwise false
DrawLine is used to track mouse movement from point to point. It tracks mouse movement, and if the game receives multiple mouse movement events in a frame, this will be called multiple times. This callback is also called once per frame on frames where the mouse didn't move, to ensure the tool keeps being drawn.
When called during stationary ticks, the first and second points are be the same. mouseup events could draw a line from the last position to the position of the mouseup event.
Adding a listener to this callback will suppress default behavior. The default behavior of a tool is to iterate over every position in the line from (x1, y1) to (x2, y2) and then call the default draw function for every point. Listening to this event would prevent Perform from being called at all, except for the first frame of mouse drawing.
DrawRect
Called when releasing the mouse while in rect drawing mode
DrawRect(brushID, x1, y1, x2, y2, strength, shift, ctrl, alt)
-
brushID
: brush index of the brush being drawn -
x1
: X position where the line starts -
y1
: Y position where the line starts -
x2
: X position where the line ends -
y2
: Y position where the line ends -
strength
: Tool strength. TPT sets strength to 10 when holding shift and to 0.1 when holding ctrl. -
shift
: true if shift is held, otherwise false -
ctrl
: true if ctrl is held, otherwise false -
alt
: true if alt is held, otherwise false
Adding a listener to this callback will suppress default behavior. The default behavior of a tool is to iterate over every position in the rect inclusive and call Perform. Listening to this event would prevent Perform from being called at all when the user draws a rectangle.
DrawFill
While the flood-fill brush is being drawn, called every time the mouse moves, when it's released, and also every frame while the mouse is stationary.
DrawFill(brushID, x, y, strength, shift, ctrl, alt)
-
brushID
: brush index of the brush being drawn -
x
: X position where the flood-fill is happening -
y
: Y position where the flood-fill is happening -
x2
: X position where the line ends -
y2
: Y position where the line ends -
strength
: Tool strength. TPT sets strength to 10 when holding shift and to 0.1 when holding ctrl. -
shift
: true if shift is held, otherwise false -
ctrl
: true if ctrl is held, otherwise false -
alt
: true if alt is held, otherwise false
This callback is run in the exact same situations where Draw and DrawLines would be called, just when the flood-fill brush is active instead.
Normally, tools don't handle flood-fill, but custom sim tools still show the flood-fill brush when holding ctrl + shift.
Select
Called whenever the tool is selected.
Select(toolIndex)
-
toolIndex
: tool index of the tool that was selected.
Can be used to perform some action when you tool is selected, such as opening a popup or initializing some data.