poschangelib/README.txt
2017-08-03 23:12:36 +02:00

199 lines
7.0 KiB
Plaintext

Minetest mod library: poschangelib
==================================
version 0.2
See LICENSE for license information
This lib adds utilities to watch player movements and trigger things when they are
spotted moving.
It does nothing by itself but aim to ease event based upon players or item
moving.
All positions are rounded to node position (integer coordinates).
Summary
- General warning
- Watch players' movements
- Watch players walking on particular nodes
- Add _on_walk on nodes
- Configuration/Performances tweaking
General warning
---------------
This mod may be resources consuming. The mods relying upon this lib should use
small functions not to decrease the server performances too much.
The more functions are provided, the more the server can lag (but probably a little
less than running every of them without the lib).
Watch player's movements
------------------------
Use poschangelib.add_player_pos_listener(name, my_callback)
Name is the identifier the listener, to use in remove_player_pos_listener. You should
follow the naming convention like for node names. See http://dev.minetest.net/Intro
The my_callback is a function that takes 4 arguments: the player, last known position,
new position and some metadata.
On first call (once a player joins) the last known position will be nil. If your
listener does something in that case, it will be called shortly after the player
reconnects. It may so be triggered twice from the same position, before leaving and
after joining.
Be aware that the new position may not always be a neigrbor of the old one.
When on teleporting, programatic moves with setpos or moving fast it may be far away.
Quick code sample:
local function my_callback(player, old_pos, new_pos, meta)
if old_pos == nil then
minetest.chat_send_player(player:get_player_name(), 'Welcome to the world!')
else
minetest.chat_send_player(player:get_player_name(),
"You are now at x:" .. new_pos.x .. ", y:" .. new_pos.y ..
"z:" .. new_pos.z)
end
end
poschangelib.add_player_pos_listener("sample:pos_listener", my_callback)
Watch player walking on particular nodes, the rough way
-------------------------------------------------------
Use poschangelib.add_player_walk_listener(name, my_callback, nodenames)
The name is used in the same way as for player position listeners. It aims at reducing
the number of time the stepped node is fetched to share it accross all listeners.
The callback is a function that takes 4 arguments: the player, the position, the node
stepped on and that node description.
See http://dev.minetest.net/minetest.register_node for node description.
You can register the listener for a list of node name or groups, in the same way you
do it to register an ABM. See http://dev.minetest.net/register_abm
For example:
local function flop(player, pos, node, desc)
minetest.chat_send_player(player:get_player_name(), 'Flop flop')
end
poschangelib.add_player_walk_listener('sample:flop', flop, {'default:dirt_with_grass'})
local function toptop(player, pos, node, desc)
minetest.chat_send_player(player:get_player_name(), 'Top top top')
end
poschangelib.add_player_walk_listener('sample:top', toptop, {'group:choppy'})
Watch player walking on particular nodes, the fine way
------------------------------------------------------
When dealing with non-filled blocks like slab and snow, the trigger may give some
false positives and be triggered twice for the same movement. This is because you can
hook to a nearby full block and stand above snow without touching it, which messes
with the walk detection of regular blocks (which checks for walkable nodes).
Moreover it can't be enough. With the example of slabs, lower slabs can be triggered
by hanging to a nearby full block and should not be triggered that way, but higher
slabs must be considered like full blocks, because the player is walking on the above
node.
If you don't require an accurate checking, just ignore the call when trigger_meta.redo
is true like in the example below:
local function toptop(player, pos, node, desc, trigger_meta)
if trigger_meta.redo then return end
... do your regular stuff
end
If you want to make fine position checking, you can use the 5th argument which holds
the trigger metadata. It is a table with the following keys
- redo: always true when defined
- player_pos: rounded position of the player
- source: either the node name or the group that ran the trigger
- source_level: when source is a group, the associated level
When trigger_meta.player_pos is equal to pos it means the player is currently inside
the node. It can be true only with non-filled blocks. With full blocks, player_pos is
always one unit above.
After hanging nearby, the player will trigger the callback when falling on that block.
When it happens the redo flag is raised in the meta for the callback to know if it
should ignore it (because it has already processed the effects) or proceed because the
previous call was ignored by checking player_pos.
For example to roughly prevent false positive with snow:
local function snow_walk(player, pos, node, desc, trigger_meta)
if trigger_meta.player_pos != pos then return end
... do your regular stuff
Add _on_walk_over to nodes
-------------------------
This behaviour is ported from the walkover mod only for compatibility.
https://forum.minetest.net/viewtopic.php?f=9&t=15991
A new node property can be added in node definitions:
_on_walk_over = <function>
This function takes the position, the node and the player as argument.
For compatibility with walkover, you can use on_walk_over (without the underscore
prefix) but it is discouraged as stated in the forum post. This support may be dropped
at any time when most mods have updated the name.
_on_walk is affected by the same issue about non-filled nodes. You can use the 4th
argument to check the trigger metadata to adjust your callback.
More on metadata
----------------
The metadata are a table that can contain the following elements:
interpolated
Is true when the position was assumed and not observed. Most of the time because the
player moved too fast to check all nodes in real time.
player_pos
Is set for walk listeners, it contains the player's position. Not set when
interpolated.
source
Contains the name of the node or group that triggered the walk listener.
This is one of thoses passed on registration.
source_level
Contains the level of the group when source is a node group.
redo
Is true when it was detected that the listener was previously called on that position.
See <Watch player walking on particular nodes, the fine way>.
Configuration/Performances tweaking
-----------------------------------
The lib checks for position at a given interval. Default is every 0.3 seconds.
This can be changed by setting poschangelib.check_interval in minetest.conf
or in advanced settings.
Setting a lower value will make the lib more accurate but will be more demanding
on resources (down to 0.05 which is a every server tick).
If the server is lagging, try increasing the interval. If the server can afford
more precise checks you can decrease the value.