Implement node timers
parent
829f262c79
commit
cd6becd442
|
@ -979,11 +979,13 @@ methods:
|
||||||
- punch_node(pos)
|
- punch_node(pos)
|
||||||
^ Punch node with the same effects that a player would cause
|
^ Punch node with the same effects that a player would cause
|
||||||
|
|
||||||
|
- get_meta(pos) -- Get a NodeMetaRef at that position
|
||||||
|
- get_node_timer(pos) -- Get NodeTimerRef
|
||||||
|
|
||||||
- add_entity(pos, name): Spawn Lua-defined entity at position
|
- add_entity(pos, name): Spawn Lua-defined entity at position
|
||||||
^ Returns ObjectRef, or nil if failed
|
^ Returns ObjectRef, or nil if failed
|
||||||
- add_item(pos, item): Spawn item
|
- add_item(pos, item): Spawn item
|
||||||
^ Returns ObjectRef, or nil if failed
|
^ Returns ObjectRef, or nil if failed
|
||||||
- get_meta(pos) -- Get a NodeMetaRef at that position
|
|
||||||
- get_player_by_name(name) -- Get an ObjectRef to a player
|
- get_player_by_name(name) -- Get an ObjectRef to a player
|
||||||
- get_objects_inside_radius(pos, radius)
|
- get_objects_inside_radius(pos, radius)
|
||||||
- set_timeofday(val): val: 0...1; 0 = midnight, 0.5 = midday
|
- set_timeofday(val): val: 0...1; 0 = midnight, 0.5 = midday
|
||||||
|
@ -1013,6 +1015,26 @@ methods:
|
||||||
- from_table(nil or {})
|
- from_table(nil or {})
|
||||||
^ See "Node Metadata"
|
^ See "Node Metadata"
|
||||||
|
|
||||||
|
NodeTimerRef: Node Timers - a high resolution persistent per-node timer
|
||||||
|
- Can be gotten via minetest.env:get_node_timer(pos)
|
||||||
|
methods:
|
||||||
|
- set(timeout,elapsed)
|
||||||
|
^ set a timer's state
|
||||||
|
^ timeout is in seconds, and supports fractional values (0.1 etc)
|
||||||
|
^ elapsed is in seconds, and supports fractional values (0.1 etc)
|
||||||
|
^ will trigger the node's on_timer function after timeout-elapsed seconds
|
||||||
|
- start(timeout)
|
||||||
|
^ start a timer
|
||||||
|
^ equivelent to set(timeout,0)
|
||||||
|
- stop()
|
||||||
|
^ stops the timer
|
||||||
|
- get_timeout() -> current timeout in seconds
|
||||||
|
^ if timeout is 0, timer is inactive
|
||||||
|
- get_elapsed() -> current elapsed time in seconds
|
||||||
|
^ the node's on_timer function will be called after timeout-elapsed seconds
|
||||||
|
- is_started() -> boolean state of timer
|
||||||
|
^ returns true if timer is started, otherwise false
|
||||||
|
|
||||||
ObjectRef: Moving things in the game are generally these
|
ObjectRef: Moving things in the game are generally these
|
||||||
(basically reference to a C++ ServerActiveObject)
|
(basically reference to a C++ ServerActiveObject)
|
||||||
methods:
|
methods:
|
||||||
|
@ -1319,10 +1341,16 @@ Node definition (register_node)
|
||||||
on_punch = func(pos, node, puncher),
|
on_punch = func(pos, node, puncher),
|
||||||
^ default: minetest.node_punch
|
^ default: minetest.node_punch
|
||||||
^ By default: does nothing
|
^ By default: does nothing
|
||||||
on_dig = func(pos, node, digger),
|
on_dig = func(pos, node, digger),
|
||||||
^ default: minetest.node_dig
|
^ default: minetest.node_dig
|
||||||
^ By default: checks privileges, wears out tool and removes node
|
^ By default: checks privileges, wears out tool and removes node
|
||||||
|
|
||||||
|
on_timer = function(pos,elapsed),
|
||||||
|
^ default: nil
|
||||||
|
^ called by NodeTimers, see EnvRef and NodeTimerRef
|
||||||
|
^ elapsed is the total time passed since the timer was started
|
||||||
|
^ return true to run the timer for another cycle with the same timeout value
|
||||||
|
|
||||||
on_receive_fields = func(pos, formname, fields, sender),
|
on_receive_fields = func(pos, formname, fields, sender),
|
||||||
^ fields = {name1 = value1, name2 = value2, ...}
|
^ fields = {name1 = value1, name2 = value2, ...}
|
||||||
^ Called when an UI form (eg. sign text input) returns data
|
^ Called when an UI form (eg. sign text input) returns data
|
||||||
|
|
|
@ -774,10 +774,18 @@ void ServerEnvironment::activateBlock(MapBlock *block, u32 additional_dtime)
|
||||||
activateObjects(block);
|
activateObjects(block);
|
||||||
|
|
||||||
// Run node timers
|
// Run node timers
|
||||||
std::map<v3s16, f32> elapsed_timers =
|
std::map<v3s16, NodeTimer> elapsed_timers =
|
||||||
block->m_node_timers.step((float)dtime_s);
|
block->m_node_timers.step((float)dtime_s);
|
||||||
if(!elapsed_timers.empty())
|
if(!elapsed_timers.empty()){
|
||||||
errorstream<<"Node timers don't work yet!"<<std::endl;
|
MapNode n;
|
||||||
|
for(std::map<v3s16, NodeTimer>::iterator
|
||||||
|
i = elapsed_timers.begin();
|
||||||
|
i != elapsed_timers.end(); i++){
|
||||||
|
n = block->getNodeNoEx(i->first);
|
||||||
|
if(scriptapi_node_on_timer(m_lua,i->first,n,i->second.elapsed))
|
||||||
|
block->setNodeTimer(i->first,NodeTimer(i->second.timeout,0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Handle ActiveBlockModifiers */
|
/* Handle ActiveBlockModifiers */
|
||||||
ABMHandler abmhandler(m_abms, dtime_s, this, false);
|
ABMHandler abmhandler(m_abms, dtime_s, this, false);
|
||||||
|
@ -1058,10 +1066,18 @@ void ServerEnvironment::step(float dtime)
|
||||||
"Timestamp older than 60s (step)");
|
"Timestamp older than 60s (step)");
|
||||||
|
|
||||||
// Run node timers
|
// Run node timers
|
||||||
std::map<v3s16, f32> elapsed_timers =
|
std::map<v3s16, NodeTimer> elapsed_timers =
|
||||||
block->m_node_timers.step(dtime);
|
block->m_node_timers.step((float)dtime);
|
||||||
if(!elapsed_timers.empty())
|
if(!elapsed_timers.empty()){
|
||||||
errorstream<<"Node timers don't work yet!"<<std::endl;
|
MapNode n;
|
||||||
|
for(std::map<v3s16, NodeTimer>::iterator
|
||||||
|
i = elapsed_timers.begin();
|
||||||
|
i != elapsed_timers.end(); i++){
|
||||||
|
n = block->getNodeNoEx(i->first);
|
||||||
|
if(scriptapi_node_on_timer(m_lua,i->first,n,i->second.elapsed))
|
||||||
|
block->setNodeTimer(i->first,NodeTimer(i->second.timeout,0));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
53
src/map.cpp
53
src/map.cpp
|
@ -1881,6 +1881,59 @@ void Map::removeNodeMetadata(v3s16 p)
|
||||||
block->m_node_metadata.remove(p_rel);
|
block->m_node_metadata.remove(p_rel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NodeTimer Map::getNodeTimer(v3s16 p)
|
||||||
|
{
|
||||||
|
v3s16 blockpos = getNodeBlockPos(p);
|
||||||
|
v3s16 p_rel = p - blockpos*MAP_BLOCKSIZE;
|
||||||
|
MapBlock *block = getBlockNoCreateNoEx(blockpos);
|
||||||
|
if(!block){
|
||||||
|
infostream<<"Map::getNodeTimer(): Need to emerge "
|
||||||
|
<<PP(blockpos)<<std::endl;
|
||||||
|
block = emergeBlock(blockpos, false);
|
||||||
|
}
|
||||||
|
if(!block)
|
||||||
|
{
|
||||||
|
infostream<<"WARNING: Map::getNodeTimer(): Block not found"
|
||||||
|
<<std::endl;
|
||||||
|
return NodeTimer();
|
||||||
|
}
|
||||||
|
NodeTimer t = block->m_node_timers.get(p_rel);
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Map::setNodeTimer(v3s16 p, NodeTimer t)
|
||||||
|
{
|
||||||
|
v3s16 blockpos = getNodeBlockPos(p);
|
||||||
|
v3s16 p_rel = p - blockpos*MAP_BLOCKSIZE;
|
||||||
|
MapBlock *block = getBlockNoCreateNoEx(blockpos);
|
||||||
|
if(!block){
|
||||||
|
infostream<<"Map::setNodeTimer(): Need to emerge "
|
||||||
|
<<PP(blockpos)<<std::endl;
|
||||||
|
block = emergeBlock(blockpos, false);
|
||||||
|
}
|
||||||
|
if(!block)
|
||||||
|
{
|
||||||
|
infostream<<"WARNING: Map::setNodeTimer(): Block not found"
|
||||||
|
<<std::endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
block->m_node_timers.set(p_rel, t);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Map::removeNodeTimer(v3s16 p)
|
||||||
|
{
|
||||||
|
v3s16 blockpos = getNodeBlockPos(p);
|
||||||
|
v3s16 p_rel = p - blockpos*MAP_BLOCKSIZE;
|
||||||
|
MapBlock *block = getBlockNoCreateNoEx(blockpos);
|
||||||
|
if(block == NULL)
|
||||||
|
{
|
||||||
|
infostream<<"WARNING: Map::removeNodeTimer(): Block not found"
|
||||||
|
<<std::endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
block->m_node_timers.remove(p_rel);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
ServerMap
|
ServerMap
|
||||||
*/
|
*/
|
||||||
|
|
10
src/map.h
10
src/map.h
|
@ -32,6 +32,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
#include "voxel.h"
|
#include "voxel.h"
|
||||||
#include "modifiedstate.h"
|
#include "modifiedstate.h"
|
||||||
#include "util/container.h"
|
#include "util/container.h"
|
||||||
|
#include "nodetimer.h"
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#include "sqlite3.h"
|
#include "sqlite3.h"
|
||||||
|
@ -310,6 +311,15 @@ public:
|
||||||
void setNodeMetadata(v3s16 p, NodeMetadata *meta);
|
void setNodeMetadata(v3s16 p, NodeMetadata *meta);
|
||||||
void removeNodeMetadata(v3s16 p);
|
void removeNodeMetadata(v3s16 p);
|
||||||
|
|
||||||
|
/*
|
||||||
|
Node Timers
|
||||||
|
These are basically coordinate wrappers to MapBlock
|
||||||
|
*/
|
||||||
|
|
||||||
|
NodeTimer getNodeTimer(v3s16 p);
|
||||||
|
void setNodeTimer(v3s16 p, NodeTimer t);
|
||||||
|
void removeNodeTimer(v3s16 p);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Misc.
|
Misc.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -621,9 +621,9 @@ void MapBlock::serialize(std::ostream &os, u8 version, bool disk)
|
||||||
// (this field should have not been added)
|
// (this field should have not been added)
|
||||||
if(version == 23)
|
if(version == 23)
|
||||||
writeU8(os, 0);
|
writeU8(os, 0);
|
||||||
// Node timers (uncomment when node timers are taken into use)
|
// Node timers are in version 24
|
||||||
/*if(version >= 24)
|
if(version >= 24)
|
||||||
m_node_timers.serialize(os);*/
|
m_node_timers.serialize(os);
|
||||||
|
|
||||||
// Static objects
|
// Static objects
|
||||||
m_static_objects.serialize(os);
|
m_static_objects.serialize(os);
|
||||||
|
@ -703,15 +703,15 @@ void MapBlock::deSerialize(std::istream &is, u8 version, bool disk)
|
||||||
if(disk)
|
if(disk)
|
||||||
{
|
{
|
||||||
// Node timers
|
// Node timers
|
||||||
if(version == 23)
|
if(version == 23){
|
||||||
// Read unused zero
|
// Read unused zero
|
||||||
readU8(is);
|
readU8(is);
|
||||||
// Uncomment when node timers are taken into use
|
}
|
||||||
/*else if(version >= 24){
|
else if(version >= 24){
|
||||||
TRACESTREAM(<<"MapBlock::deSerialize "<<PP(getPos())
|
TRACESTREAM(<<"MapBlock::deSerialize "<<PP(getPos())
|
||||||
<<": Node timers"<<std::endl);
|
<<": Node timers"<<std::endl);
|
||||||
m_node_timers.deSerialize(is);
|
m_node_timers.deSerialize(is);
|
||||||
}*/
|
}
|
||||||
|
|
||||||
// Static objects
|
// Static objects
|
||||||
TRACESTREAM(<<"MapBlock::deSerialize "<<PP(getPos())
|
TRACESTREAM(<<"MapBlock::deSerialize "<<PP(getPos())
|
||||||
|
|
|
@ -431,6 +431,26 @@ public:
|
||||||
return m_usage_timer;
|
return m_usage_timer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Node Timers
|
||||||
|
*/
|
||||||
|
// Get timer
|
||||||
|
NodeTimer getNodeTimer(v3s16 p){
|
||||||
|
return m_node_timers.get(p);
|
||||||
|
}
|
||||||
|
// Deletes timer
|
||||||
|
void removeNodeTimer(v3s16 p){
|
||||||
|
m_node_timers.remove(p);
|
||||||
|
}
|
||||||
|
// Deletes old timer and sets a new one
|
||||||
|
void setNodeTimer(v3s16 p, NodeTimer t){
|
||||||
|
m_node_timers.set(p,t);
|
||||||
|
}
|
||||||
|
// Deletes all timers
|
||||||
|
void clearNodeTimers(){
|
||||||
|
m_node_timers.clear();
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Serialization
|
Serialization
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -28,13 +28,13 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
|
||||||
void NodeTimer::serialize(std::ostream &os) const
|
void NodeTimer::serialize(std::ostream &os) const
|
||||||
{
|
{
|
||||||
writeF1000(os, duration);
|
writeF1000(os, timeout);
|
||||||
writeF1000(os, elapsed);
|
writeF1000(os, elapsed);
|
||||||
}
|
}
|
||||||
|
|
||||||
void NodeTimer::deSerialize(std::istream &is)
|
void NodeTimer::deSerialize(std::istream &is)
|
||||||
{
|
{
|
||||||
duration = readF1000(is);
|
timeout = readF1000(is);
|
||||||
elapsed = readF1000(is);
|
elapsed = readF1000(is);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -94,7 +94,7 @@ void NodeTimerList::deSerialize(std::istream &is)
|
||||||
NodeTimer t;
|
NodeTimer t;
|
||||||
t.deSerialize(is);
|
t.deSerialize(is);
|
||||||
|
|
||||||
if(t.duration <= 0)
|
if(t.timeout <= 0)
|
||||||
{
|
{
|
||||||
infostream<<"WARNING: NodeTimerList::deSerialize(): "
|
infostream<<"WARNING: NodeTimerList::deSerialize(): "
|
||||||
<<"invalid data at position"
|
<<"invalid data at position"
|
||||||
|
@ -116,9 +116,9 @@ void NodeTimerList::deSerialize(std::istream &is)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::map<v3s16, f32> NodeTimerList::step(float dtime)
|
std::map<v3s16, NodeTimer> NodeTimerList::step(float dtime)
|
||||||
{
|
{
|
||||||
std::map<v3s16, f32> elapsed_timers;
|
std::map<v3s16, NodeTimer> elapsed_timers;
|
||||||
// Increment timers
|
// Increment timers
|
||||||
for(std::map<v3s16, NodeTimer>::iterator
|
for(std::map<v3s16, NodeTimer>::iterator
|
||||||
i = m_data.begin();
|
i = m_data.begin();
|
||||||
|
@ -126,13 +126,13 @@ std::map<v3s16, f32> NodeTimerList::step(float dtime)
|
||||||
v3s16 p = i->first;
|
v3s16 p = i->first;
|
||||||
NodeTimer t = i->second;
|
NodeTimer t = i->second;
|
||||||
t.elapsed += dtime;
|
t.elapsed += dtime;
|
||||||
if(t.elapsed >= t.duration)
|
if(t.elapsed >= t.timeout)
|
||||||
elapsed_timers.insert(std::make_pair(p, t.elapsed));
|
elapsed_timers.insert(std::make_pair(p, t));
|
||||||
else
|
else
|
||||||
i->second = t;
|
i->second = t;
|
||||||
}
|
}
|
||||||
// Delete elapsed timers
|
// Delete elapsed timers
|
||||||
for(std::map<v3s16, f32>::const_iterator
|
for(std::map<v3s16, NodeTimer>::const_iterator
|
||||||
i = elapsed_timers.begin();
|
i = elapsed_timers.begin();
|
||||||
i != elapsed_timers.end(); i++){
|
i != elapsed_timers.end(); i++){
|
||||||
v3s16 p = i->first;
|
v3s16 p = i->first;
|
||||||
|
|
|
@ -35,15 +35,15 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
class NodeTimer
|
class NodeTimer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
NodeTimer(): duration(0.), elapsed(0.) {}
|
NodeTimer(): timeout(0.), elapsed(0.) {}
|
||||||
NodeTimer(f32 duration_, f32 elapsed_):
|
NodeTimer(f32 timeout_, f32 elapsed_):
|
||||||
duration(duration_), elapsed(elapsed_) {}
|
timeout(timeout_), elapsed(elapsed_) {}
|
||||||
~NodeTimer() {}
|
~NodeTimer() {}
|
||||||
|
|
||||||
void serialize(std::ostream &os) const;
|
void serialize(std::ostream &os) const;
|
||||||
void deSerialize(std::istream &is);
|
void deSerialize(std::istream &is);
|
||||||
|
|
||||||
f32 duration;
|
f32 timeout;
|
||||||
f32 elapsed;
|
f32 elapsed;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -81,7 +81,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
// A step in time. Returns map of elapsed timers.
|
// A step in time. Returns map of elapsed timers.
|
||||||
std::map<v3s16, f32> step(float dtime);
|
std::map<v3s16, NodeTimer> step(float dtime);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::map<v3s16, NodeTimer> m_data;
|
std::map<v3s16, NodeTimer> m_data;
|
||||||
|
|
|
@ -3118,6 +3118,162 @@ const luaL_reg LuaPerlinNoise::methods[] = {
|
||||||
{0,0}
|
{0,0}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
NodeTimerRef
|
||||||
|
*/
|
||||||
|
|
||||||
|
class NodeTimerRef
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
v3s16 m_p;
|
||||||
|
ServerEnvironment *m_env;
|
||||||
|
|
||||||
|
static const char className[];
|
||||||
|
static const luaL_reg methods[];
|
||||||
|
|
||||||
|
static int gc_object(lua_State *L) {
|
||||||
|
NodeTimerRef *o = *(NodeTimerRef **)(lua_touserdata(L, 1));
|
||||||
|
delete o;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static NodeTimerRef *checkobject(lua_State *L, int narg)
|
||||||
|
{
|
||||||
|
luaL_checktype(L, narg, LUA_TUSERDATA);
|
||||||
|
void *ud = luaL_checkudata(L, narg, className);
|
||||||
|
if(!ud) luaL_typerror(L, narg, className);
|
||||||
|
return *(NodeTimerRef**)ud; // unbox pointer
|
||||||
|
}
|
||||||
|
|
||||||
|
static int l_set(lua_State *L)
|
||||||
|
{
|
||||||
|
NodeTimerRef *o = checkobject(L, 1);
|
||||||
|
ServerEnvironment *env = o->m_env;
|
||||||
|
if(env == NULL) return 0;
|
||||||
|
f32 t = luaL_checknumber(L,2);
|
||||||
|
f32 e = luaL_checknumber(L,3);
|
||||||
|
env->getMap().setNodeTimer(o->m_p,NodeTimer(t,e));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int l_start(lua_State *L)
|
||||||
|
{
|
||||||
|
NodeTimerRef *o = checkobject(L, 1);
|
||||||
|
ServerEnvironment *env = o->m_env;
|
||||||
|
if(env == NULL) return 0;
|
||||||
|
f32 t = luaL_checknumber(L,2);
|
||||||
|
env->getMap().setNodeTimer(o->m_p,NodeTimer(t,0));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int l_stop(lua_State *L)
|
||||||
|
{
|
||||||
|
NodeTimerRef *o = checkobject(L, 1);
|
||||||
|
ServerEnvironment *env = o->m_env;
|
||||||
|
if(env == NULL) return 0;
|
||||||
|
env->getMap().removeNodeTimer(o->m_p);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int l_is_started(lua_State *L)
|
||||||
|
{
|
||||||
|
NodeTimerRef *o = checkobject(L, 1);
|
||||||
|
ServerEnvironment *env = o->m_env;
|
||||||
|
if(env == NULL) return 0;
|
||||||
|
|
||||||
|
NodeTimer t = env->getMap().getNodeTimer(o->m_p);
|
||||||
|
lua_pushboolean(L,(t.timeout != 0));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int l_get_timeout(lua_State *L)
|
||||||
|
{
|
||||||
|
NodeTimerRef *o = checkobject(L, 1);
|
||||||
|
ServerEnvironment *env = o->m_env;
|
||||||
|
if(env == NULL) return 0;
|
||||||
|
|
||||||
|
NodeTimer t = env->getMap().getNodeTimer(o->m_p);
|
||||||
|
lua_pushnumber(L,t.timeout);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int l_get_elapsed(lua_State *L)
|
||||||
|
{
|
||||||
|
NodeTimerRef *o = checkobject(L, 1);
|
||||||
|
ServerEnvironment *env = o->m_env;
|
||||||
|
if(env == NULL) return 0;
|
||||||
|
|
||||||
|
NodeTimer t = env->getMap().getNodeTimer(o->m_p);
|
||||||
|
lua_pushnumber(L,t.elapsed);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
NodeTimerRef(v3s16 p, ServerEnvironment *env):
|
||||||
|
m_p(p),
|
||||||
|
m_env(env)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
~NodeTimerRef()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// Creates an NodeTimerRef and leaves it on top of stack
|
||||||
|
// Not callable from Lua; all references are created on the C side.
|
||||||
|
static void create(lua_State *L, v3s16 p, ServerEnvironment *env)
|
||||||
|
{
|
||||||
|
NodeTimerRef *o = new NodeTimerRef(p, env);
|
||||||
|
*(void **)(lua_newuserdata(L, sizeof(void *))) = o;
|
||||||
|
luaL_getmetatable(L, className);
|
||||||
|
lua_setmetatable(L, -2);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void set_null(lua_State *L)
|
||||||
|
{
|
||||||
|
NodeTimerRef *o = checkobject(L, -1);
|
||||||
|
o->m_env = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void Register(lua_State *L)
|
||||||
|
{
|
||||||
|
lua_newtable(L);
|
||||||
|
int methodtable = lua_gettop(L);
|
||||||
|
luaL_newmetatable(L, className);
|
||||||
|
int metatable = lua_gettop(L);
|
||||||
|
|
||||||
|
lua_pushliteral(L, "__metatable");
|
||||||
|
lua_pushvalue(L, methodtable);
|
||||||
|
lua_settable(L, metatable); // hide metatable from Lua getmetatable()
|
||||||
|
|
||||||
|
lua_pushliteral(L, "__index");
|
||||||
|
lua_pushvalue(L, methodtable);
|
||||||
|
lua_settable(L, metatable);
|
||||||
|
|
||||||
|
lua_pushliteral(L, "__gc");
|
||||||
|
lua_pushcfunction(L, gc_object);
|
||||||
|
lua_settable(L, metatable);
|
||||||
|
|
||||||
|
lua_pop(L, 1); // drop metatable
|
||||||
|
|
||||||
|
luaL_openlib(L, 0, methods, 0); // fill methodtable
|
||||||
|
lua_pop(L, 1); // drop methodtable
|
||||||
|
|
||||||
|
// Cannot be created from Lua
|
||||||
|
//lua_register(L, className, create_object);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const char NodeTimerRef::className[] = "NodeTimerRef";
|
||||||
|
const luaL_reg NodeTimerRef::methods[] = {
|
||||||
|
method(NodeTimerRef, start),
|
||||||
|
method(NodeTimerRef, set),
|
||||||
|
method(NodeTimerRef, stop),
|
||||||
|
method(NodeTimerRef, is_started),
|
||||||
|
method(NodeTimerRef, get_timeout),
|
||||||
|
method(NodeTimerRef, get_elapsed),
|
||||||
|
{0,0}
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
EnvRef
|
EnvRef
|
||||||
*/
|
*/
|
||||||
|
@ -3351,6 +3507,31 @@ private:
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// EnvRef:get_meta(pos)
|
||||||
|
static int l_get_meta(lua_State *L)
|
||||||
|
{
|
||||||
|
//infostream<<"EnvRef::l_get_meta()"<<std::endl;
|
||||||
|
EnvRef *o = checkobject(L, 1);
|
||||||
|
ServerEnvironment *env = o->m_env;
|
||||||
|
if(env == NULL) return 0;
|
||||||
|
// Do it
|
||||||
|
v3s16 p = read_v3s16(L, 2);
|
||||||
|
NodeMetaRef::create(L, p, env);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// EnvRef:get_node_timer(pos)
|
||||||
|
static int l_get_node_timer(lua_State *L)
|
||||||
|
{
|
||||||
|
EnvRef *o = checkobject(L, 1);
|
||||||
|
ServerEnvironment *env = o->m_env;
|
||||||
|
if(env == NULL) return 0;
|
||||||
|
// Do it
|
||||||
|
v3s16 p = read_v3s16(L, 2);
|
||||||
|
NodeTimerRef::create(L, p, env);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
// EnvRef:add_entity(pos, entityname) -> ObjectRef or nil
|
// EnvRef:add_entity(pos, entityname) -> ObjectRef or nil
|
||||||
// pos = {x=num, y=num, z=num}
|
// pos = {x=num, y=num, z=num}
|
||||||
static int l_add_entity(lua_State *L)
|
static int l_add_entity(lua_State *L)
|
||||||
|
@ -3431,19 +3612,6 @@ private:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// EnvRef:get_meta(pos)
|
|
||||||
static int l_get_meta(lua_State *L)
|
|
||||||
{
|
|
||||||
//infostream<<"EnvRef::l_get_meta()"<<std::endl;
|
|
||||||
EnvRef *o = checkobject(L, 1);
|
|
||||||
ServerEnvironment *env = o->m_env;
|
|
||||||
if(env == NULL) return 0;
|
|
||||||
// Do it
|
|
||||||
v3s16 p = read_v3s16(L, 2);
|
|
||||||
NodeMetaRef::create(L, p, env);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// EnvRef:get_player_by_name(name)
|
// EnvRef:get_player_by_name(name)
|
||||||
static int l_get_player_by_name(lua_State *L)
|
static int l_get_player_by_name(lua_State *L)
|
||||||
{
|
{
|
||||||
|
@ -3713,6 +3881,7 @@ const luaL_reg EnvRef::methods[] = {
|
||||||
method(EnvRef, add_rat),
|
method(EnvRef, add_rat),
|
||||||
method(EnvRef, add_firefly),
|
method(EnvRef, add_firefly),
|
||||||
method(EnvRef, get_meta),
|
method(EnvRef, get_meta),
|
||||||
|
method(EnvRef, get_node_timer),
|
||||||
method(EnvRef, get_player_by_name),
|
method(EnvRef, get_player_by_name),
|
||||||
method(EnvRef, get_objects_inside_radius),
|
method(EnvRef, get_objects_inside_radius),
|
||||||
method(EnvRef, set_timeofday),
|
method(EnvRef, set_timeofday),
|
||||||
|
@ -4729,6 +4898,7 @@ void scriptapi_export(lua_State *L, Server *server)
|
||||||
LuaItemStack::Register(L);
|
LuaItemStack::Register(L);
|
||||||
InvRef::Register(L);
|
InvRef::Register(L);
|
||||||
NodeMetaRef::Register(L);
|
NodeMetaRef::Register(L);
|
||||||
|
NodeTimerRef::Register(L);
|
||||||
ObjectRef::Register(L);
|
ObjectRef::Register(L);
|
||||||
EnvRef::Register(L);
|
EnvRef::Register(L);
|
||||||
LuaPseudoRandom::Register(L);
|
LuaPseudoRandom::Register(L);
|
||||||
|
@ -5482,6 +5652,29 @@ void scriptapi_node_after_destruct(lua_State *L, v3s16 p, MapNode node)
|
||||||
script_error(L, "error: %s", lua_tostring(L, -1));
|
script_error(L, "error: %s", lua_tostring(L, -1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool scriptapi_node_on_timer(lua_State *L, v3s16 p, MapNode node, f32 dtime)
|
||||||
|
{
|
||||||
|
realitycheck(L);
|
||||||
|
assert(lua_checkstack(L, 20));
|
||||||
|
StackUnroller stack_unroller(L);
|
||||||
|
|
||||||
|
INodeDefManager *ndef = get_server(L)->ndef();
|
||||||
|
|
||||||
|
// Push callback function on stack
|
||||||
|
if(!get_item_callback(L, ndef->get(node).name.c_str(), "on_timer"))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Call function
|
||||||
|
push_v3s16(L, p);
|
||||||
|
lua_pushnumber(L,dtime);
|
||||||
|
if(lua_pcall(L, 2, 1, 0))
|
||||||
|
script_error(L, "error: %s", lua_tostring(L, -1));
|
||||||
|
if(lua_isboolean(L,-1) && lua_toboolean(L,-1) == true)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void scriptapi_node_on_receive_fields(lua_State *L, v3s16 p,
|
void scriptapi_node_on_receive_fields(lua_State *L, v3s16 p,
|
||||||
const std::string &formname,
|
const std::string &formname,
|
||||||
const std::map<std::string, std::string> &fields,
|
const std::map<std::string, std::string> &fields,
|
||||||
|
|
|
@ -94,6 +94,8 @@ void scriptapi_node_on_construct(lua_State *L, v3s16 p, MapNode node);
|
||||||
void scriptapi_node_on_destruct(lua_State *L, v3s16 p, MapNode node);
|
void scriptapi_node_on_destruct(lua_State *L, v3s16 p, MapNode node);
|
||||||
// Node post-destructor
|
// Node post-destructor
|
||||||
void scriptapi_node_after_destruct(lua_State *L, v3s16 p, MapNode node);
|
void scriptapi_node_after_destruct(lua_State *L, v3s16 p, MapNode node);
|
||||||
|
// Node Timer event
|
||||||
|
bool scriptapi_node_on_timer(lua_State *L, v3s16 p, MapNode node, f32 dtime);
|
||||||
// Called when a metadata form returns values
|
// Called when a metadata form returns values
|
||||||
void scriptapi_node_on_receive_fields(lua_State *L, v3s16 p,
|
void scriptapi_node_on_receive_fields(lua_State *L, v3s16 p,
|
||||||
const std::string &formname,
|
const std::string &formname,
|
||||||
|
|
|
@ -58,12 +58,13 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
20: many existing content types translated to extended ones
|
20: many existing content types translated to extended ones
|
||||||
21: dynamic content type allocation
|
21: dynamic content type allocation
|
||||||
22: minerals removed, facedir & wallmounted changed
|
22: minerals removed, facedir & wallmounted changed
|
||||||
23: NodeTimers, new node metadata format
|
23: new node metadata format
|
||||||
|
24: NodeTimers
|
||||||
*/
|
*/
|
||||||
// This represents an uninitialized or invalid format
|
// This represents an uninitialized or invalid format
|
||||||
#define SER_FMT_VER_INVALID 255
|
#define SER_FMT_VER_INVALID 255
|
||||||
// Highest supported serialization version
|
// Highest supported serialization version
|
||||||
#define SER_FMT_VER_HIGHEST 23
|
#define SER_FMT_VER_HIGHEST 24
|
||||||
// Lowest supported serialization version
|
// Lowest supported serialization version
|
||||||
#define SER_FMT_VER_LOWEST 0
|
#define SER_FMT_VER_LOWEST 0
|
||||||
|
|
||||||
|
|
|
@ -843,7 +843,7 @@ queue_full_break:
|
||||||
|
|
||||||
/*timer_result = timer.stop(true);
|
/*timer_result = timer.stop(true);
|
||||||
if(timer_result != 0)
|
if(timer_result != 0)
|
||||||
infostream<<"GetNextBlocks duration: "<<timer_result<<" (!=0)"<<std::endl;*/
|
infostream<<"GetNextBlocks timeout: "<<timer_result<<" (!=0)"<<std::endl;*/
|
||||||
}
|
}
|
||||||
|
|
||||||
void RemoteClient::GotBlock(v3s16 p)
|
void RemoteClient::GotBlock(v3s16 p)
|
||||||
|
|
Loading…
Reference in New Issue