Naturalslopeslib Lua API
========================

Table of contents
-- Introduction
-- Definitions
---- ReplacementTable
-- Registration API
---- naturalslopeslib.register_slope
---- naturalslopeslib.set_slopes
---- naturalslopeslib.register_sloped_stomp
-- Getters
---- naturalslopeslib.get_regular_node_name
---- naturalslopeslib.get_replacement
---- naturalslopeslib.get_replacement_id
---- naturalslopeslib.get_all_shapes
-- Shape update API
---- naturalslopeslib.is_free_for_shape_update
---- naturalslopeslib.area_is_free_for_erosion
---- naturalslopeslib.get_replacement_node
---- naturalslopeslib.chance_update_shape
---- naturalslopeslib.update_shape
---- naturalslopeslib.area_chance_update_shape
-- Chat commands
---- updshape


Introduction
------------

Naturalslopeslib adds the ability for given nodes to turn into slopes and back to full block shape by itself according to the surroundings and the material hardness. It creates natural landscape and smoothes movements.

Slopes can be generated in various ways. Those events can be turned on or off in settings. The shape is updated on generation, with time, by stepping on edges or when digging and placing nodes.

As Minetest main unit is the block, having half-sized blocks can break a lot of things. Thus half-blocks like slopes are still considered as a single block. A single slope can turn back to a full node and vice-versa and half-blocks are not considered buildable upon (they will transform back into full block).


Definitions
-----------

### ReplacementTable

A table containing references to various shape. The type of references can either be a name or an internal id.
{
	source   = full node reference,
	straight = straight slope reference,
	inner    = inner corner reference,
	outer    = outer corner reference,
	pike     = pike/slab reference,
	chance   = inverted chance of happening
}


Registration API
----------------

### naturalslopeslib.register_slope(base_node_name, def_changes, update_chance)

* Registers all slope shapes and automatic stomping for a full node.
* `base_node_name` the full block node name.
* `def_changes` changes to apply from the base node definition.
  * All the attributes are copied to the sloped nodes expect those ones which are replaced:
    * `drawtype` set to "nodebox" or "mesh" according to the rendering mode
    * `nodebox` or `mesh` is replaced
    * `selection_box` and `collision_box` matching to the according mesh
    * `paramtype` and `paramtype2` set to "light" and "facedir" respectively
    * the group "natural_slope" is added (1 = straight, 2 = inner corner, 3 = outer corner, 4 = pike)
    * the group "family:<full node name>" is added
  * Then they are changed from def_changes. Use "nil" string to explicitely erase a value (an not nil).
* `update_chance` inverted chance for the node to be updated.
* returns ReplacementTable.

### naturalslopeslib.set_slopes(base_node_name, straight_name, inner_name, outer_name, pike_name, update_chance)

* Link existing nodes. Same as register_slopes but without registering new nodes. Use it when the shapes are already registered from eslewhere. The node definitions are not changed at all.
* `base_node_name` the full node name.
* `straight_name` the straight slope node name.
* `inner_name` the inner corner node name.
* `outer_name` the outer corner node name.
* `pike_name` the pike/slab node name.
* `update_chance` the inverted chance of happening. 
* returns ReplacementTable.

### naturalslopeslib.register_sloped_stomp(source_node_name, dest_node_name, stomp_desc)

* Requires `poschangelib`. If the mod is not installed, this function will do nothing.
* Register `stomp_desc` from all shapes of `source_node_name` to `dest_node_name`.

Getters
-------

### naturalslopeslib.get_regular_node_name(slope_node_name)

* `slope_node_name` a node name.
* returns the name of the regular node (the unslopped one). Nil if it is not a slope node.
* It may be unnaccurate as it checks only if the name follows the internal pattern for slope names.

### naturalslopeslib.get_replacement(source_node_name)

* `source_node_name` a registered node name.
* returns a SlopeDef. Nil if no slopes are registered.

### naturalslopeslib.get_replacement_id(source_id)

* `source_id` the id of the node.
* returns a ReplacementTable with node ids as values. Nil if no slopes are registered.

### naturalslopeslib.get_all_shapes(source_node_name)

Returns the node and all it's slope names in a table {source, straight, inner corner, outer corner, pike}. Returns {source} if there are no slopes for this node.
* `source_node_name` The full block node name.


Shape update API
----------------

### naturalslopeslib.is_free_for_shape_update(pos)

* Checks if a node is considered free for defining which shape could be picked.
* `pos` the position of the node to check (probably a neighbour of a candidate to shape update).
* returns true or false

### naturalslopeslib.area_is_free_for_erosion(area, data, index)

* Checks if a node is considered free for defining which shape could be picked.
* `area` VoxelArea to use.
* `data` Data from VoxelManip.
* `index` position in area.

### naturalslopeslib.get_replacement_node(pos, node, area, data, param2_data)

* Get the replacement node according to it's surroundings.
* `pos` the position of the node or index with VoxelArea.
* `node` the node at that position or content id with VoxelArea.
* `area` the VoxelArea, nil for single position update (determines which type of the two previous arguments are).
* `data` Data from VoxelManip, nil for single position update.
* `param2_data` param2 data from VoxelManip, nil for single position update.
* returns the parameters to update the node.
  * a node to use with minetest.set_node when called without area;
  * a table with id and param2_data when called with an area;
  * nil if no replacement is found.

### naturalslopeslib.chance_update_shape(pos, node, factor)

* Do shape update when random roll passes on a single node.
* `pos` the position to update.
* `node` the node at pos.
* `factor` optional chance factor, when > 1 it have more chances to happen
* returns true if an update was done, false otherwise.

### naturalslopeslib.update_shape(pos, node)

* Do shape update disregarding chances.
* `pos` the position to update.
* `node` the node at pos.
* returns true if an update was done, false otherwise.

### naturalslopeslib.area_chance_update_shape(minp, maxp, factor, skip)

* Massive shape update with VoxelManip.
* `minp` lower boundary of area.
* `mapx` higher boundary of area.
* `factor` Inverted factor for chance (0.1 means 10 times more likely to update)
* `skip` optional random skip, roughfly ignore skip/2 to skip nodes.


Chat commands
-------------

### updshape

* requires `server` privilege.
* Force updating the node the player is standing upon.
