Difference between revisions of "Lua API:Elements"

From The Powder Toy
Jump to: navigation, search
(Add Update and Graphics function details)
(Link renderer wiki so the renderer constants make sense)
Line 102: Line 102:
 
<code>elements.property(number el_number, "Graphics", function newfunction)</code>
 
<code>elements.property(number el_number, "Graphics", function newfunction)</code>
  
The pixel mode values you can use are:
+
The pixel mode values in [https://powdertoy.co.uk/Wiki/W/Lua_API:Renderer.html the <code>ren</code> table] you can use are:
 
<pre>
 
<pre>
 
PMODE_NONE 0x00000000 --prevents anything from being drawn
 
PMODE_NONE 0x00000000 --prevents anything from being drawn

Revision as of 13:51, 18 September 2023

The Elements API contains methods and constants for modifying and creating elements. If you want to add an update function or graphics function, use Update and Graphics properties. See the properties section for an example.

Methods

elements.allocate

number elements.allocate(string group, string name)

Use this function to create a new element. This function will return the id of your element, and create a unique identifier that can be used to modify the properties later. The identifier is in the form GROUP_PT_NAME, where group is the name of the mod or script (or just anything unique, like your username), and name is the name of the element. For example, elements.allocate("mymod", "virus") would create the identifier MYMOD_PT_VIRUS.

The identifier is added as a constant in the elements table, so elements.MYMOD_PT_VIRUS would be equivalent to the new element's id, and can be used as the elementID argument to any of the functions below.

The new element is created with all the default properties, and won't be visible until you modify it to show up in the menu.

Returns -1 on failure (there are no free spaces to create a new element).

elements.free

elements.free(number elementID)

Free a previously allocated element, so it will disappear from the game. The element id will be freed and can used later by another script. elementID must be a non-default element (i.e you cannot free the default WATR element)

elements.exists

elements.exists(number elementID)

Returns true if an element under this ID exists and is Enabled, otherwise returns false

elements.loadDefault

elements.loadDefault()

Resets all elements to the original state. This will also erase any elements created with any scripts, only the default elements will be available.

elements.loadDefault(number elementID)

Reset an element to its original state before it was modified

elements.element

table elements.element(number elementID)

Returns a table containing all of an element's properties (Name, Description, etc)

elements.element(number elementID, table properties)

Sets the properties from the given table onto the element.

These two functions are useful for copying or templating from already present elements, for example

local myNewElement = elements.allocate("wiki", "expl")
elements.element(myNewElement, elements.element(elements.DEFAULT_PT_WATR))
elements.property(myNewElement, "Name", "EXPL")
elements.property(myNewElement, "Description", "This is an example element from the Wiki")

In this example, the element properties for our new element (EXPL) are copied from WATR

local star = elements.allocate("ELEMENT", "STAR")
elements.element(star, elements.element(elements.DEFAULT_PT_DMND))
elements.property(star, "Name", "STAR")
elements.property(star, "Description", "STAR. Enough Pressure Makes It Explode Into LAVA.")
elements.property(star, "Colour", 0xFFFFFF)
elements.property(star, "MenuSection", elem.SC_SOLIDS)
elements.property(star, "HotAir", -0.009)
elements.property(star, "Weight", 333)
elements.property(star, "Temperature", 4556)
elements.property(star, "HighPressure", 200)
elements.property(star, "HighPressureTransition", elements.DEFAULT_PT_LAVA)
local function graphics1(i, colr, colg, colb) 
    return 1,ren.FIRE_ADD,255,100,155,210,255,255,255,255
end
elements.property(star, "Graphics", graphics1)

Another Example, from an actual script. For more info on graphics functions, see the legacy api page

elements.property

object elements.property(number elementID, string property)

Gets the value of an element property

elements.property(number elementID, string property, object value)

Sets the value of an element property

Properties

After creating an element, you can modify many properties. Be sure to at a minimum set set Name, Description, Color, MenuVisible, and MenuSection.

For more information on what properties there are to use in elements.property, and how to use them, see this page: Element_Properties

"Update" and "Graphics" are special properties, these can be used to set the update functions or graphics functions. Use a function as the value of the property to set. They are not included in the tables created with elements.element, and the functions can't be returned with elements.property either. This means copying all of an elements properties using elements.element will not set these two for the new element.

Update

Allows you to replace or add on to an element's update function. Write a function like normal, and then put its name into this command. Use your element's ID or elem.*_PT_* constants for el_number. If replace is set to 1, the new function will be called after the original update function. If replace is set to 2, the original function will be overwritten. If replace is set to 3, the new function will be called before the original update function. Replace automatically defaults to 1.

newfunction arguments: index, x, y, surround_space, nt

Returns: return 1 from your function if the particle is killed.

elements.property(number el_number, "Update", function newfunction)

elements.property(number el_number, "Update", function newfunction, number replace)

Graphics

Allows you to replace an element's graphics function. Write a function like normal, and then put its name into this command. Use your element's ID or elem.*_PT_* constants for el_number.

Function arguments: index, colr, colg, colb

Returns: cache, pixel_mode, cola, colr, colg, colb, firea, firer, fireg, and fireb.

Set cache to 1 if you don't want the function to ever be called again, preventing lag. Don't do this if you need the way your element looks to change depending on its properties.

colr/g/b are the red, green, and blue colors of your element. firea/r/g/b set the fire colors, but pixel_mode needs to be set to 0x00022000 for them to work.

elements.property(number el_number, "Graphics", function newfunction)

The pixel mode values in the ren table you can use are:

PMODE_NONE	0x00000000 --prevents anything from being drawn
PMODE_FLAT	0x00000001 --draw a basic pixel, overwriting the color under it. Doesn't support cola.
PMODE_BLOB	0x00000002 --adds a blobby effect, like you were using blob (5) display mode
PMODE_BLUR	0x00000004 --used in liquids in fancy display mode
PMODE_GLOW	0x00000008 --Glow effect, used in elements like DEUT and TRON in fancy display mode
PMODE_SPARK	0x00000010 -- used for things such as GBMB at first, dimmer than other modes
PMODE_FLARE	0x00000020 --BOMB and other similar elements, brighter than PMODE_SPARK
PMODE_LFLARE	0x00000040 --brightest spark mode, used when DEST hits something
PMODE_ADD	0x00000080 --like PMODE_FLAT, but adds color to a pixel, instead of overwriting it.
PMODE_BLEND	0x00000100 --basically the same thing as PMODE_ADD, but has better OpenGL support
PSPEC_STICKMAN	0x00000200 --does nothing, because the stickmen won't get drawn unless it actually is one

NO_DECO		0x00001000 --prevents decoration from showing on the element (used in LCRY)
DECO_FIRE	0x00002000 --Allow decoration to be drawn on using the fire effect (gasses have this set)

FIRE_ADD	0x00010000 --adds a weak fire effect around the element (ex. LAVA/LIGH)
FIRE_BLEND	0x00020000 --adds a stronger fire effect around the element, default for gasses

EFFECT_GRAVIN	0x01000000 --adds a PRTI effect. Might take some coding in an update function to get it to work properly, PRTI uses life and ctype to create the effects
EFFECT_GRAVOUT	0x02000000 --adds a PRTO effect. Might take some coding in an update function to get it to work properly, PRTI uses life and ctype to create the effects

You can combine them in any way you want, you probably need more than one anyway. Radioactive elements default to PMODE_FLAT+PMODE_GLOW, liquids to PMODE_FLAT+PMODE_BLUR, and gasses to FIRE_BLEND+DECO_FIRE, with a firea of 125 and firer/g/b of colr/g/b divided by 2

See this for a picture of what they look like: https://powdertoy.co.uk/Wiki/W/File:Particle_Drawing_Modes.png.html

Some examples

 local function funcUpdate(i,x,y,s,nt)
     for r in sim.neighbors(x,y,1,1) do
        if sim.partProperty(r, "type") == elem.DEFAULT_PT_COAL then
            sim.partChangeType(r, elem.DEFAULT_PT_GOLD)
        end
    end
 end
 
 local function funcGraphics(i, colr, colg, colb)
    return 1,ren.FIRE_ADD,255,colr,colg,colb,255,100,0,255
 end
 
 elements.property(ELEM, "Update", funcUpdate) 
 elements.property(ELEM, "Graphics", funcGraphics)

Constants

Any of these constants can be accessed with elements.<constant name here>

Element identifiers

All of the default element identifiers are prefixed with DEFAULT_PT_, for example, the identifier for WATR is DEFAULT_PT_WATR. Do not assume all elements identifiers are the same as their names, TNT has the identifier BANG, for example. To find an elements identifier, you can check the source file for any given element in src/simulation/elements/.

Properties

More info on the properties can be found here: Element_Properties

TYPE_PART
TYPE_LIQUID
TYPE_GAS
TYPE_SOLID
TYPE_ENERGY
PROP_CONDUCTS
PROP_BLACK
PROP_NEUTPENETRATE
PROP_NEUTABSORB
PROP_NEUTPASS
PROP_DEADLY
PROP_HOT_GLOW
PROP_LIFE
PROP_RADIOACTIVE
PROP_LIFE_DEC
PROP_LIFE_KILL
PROP_LIFE_KILL_DEC
PROP_SPARKSETTLE
PROP_NOAMBHEAT
PROP_DRAWONCTYPE
PROP_NOCTYPEDRAW

Menu sections

These are used for the menusection property

SC_WALL
SC_ELEC
SC_POWERED
SC_SENSOR
SC_FORCE
SC_EXPLOSIVE
SC_GAS
SC_LIQUID
SC_POWDERS
SC_SOLIDS
SC_NUCLEAR
SC_SPECIAL
SC_LIFE
SC_TOOL
SC_DECO

SC_CRACKER and SC_CRACKER2 are not accessible from lua or in the game, but have id numbers of 15 and 16

Flags

set in parts[i].flags

FLAG_STAGNANT
Used by liquids and powders to speed up simulation by moving them less
FLAG_SKIPMOVE
Given to PHOT by PCLN and PBCN to fix gaps in lasers, only useable by energy particles
FLAG_WATEREQUAL
Used internally for water equalization
FLAG_MOVABLE
Can be used to re-enable moving sponge
FLAG_PHOTDECO
Re-enables deco on photons for compatibility. Defined as the same value as FLAG_MOVABLE (they only apply to different elements)