mirror of
https://github.com/minetest/minetest.git
synced 2024-11-27 18:13:46 +01:00
Improve LuaEntity velocity/acceleration handling (by kahrl); implement staticdata interface to Lua
This commit is contained in:
parent
811ac5ac3a
commit
0ce0c8fcfb
@ -101,6 +101,7 @@ end
|
|||||||
-- - add_node(pos, node)
|
-- - add_node(pos, node)
|
||||||
-- - remove_node(pos)
|
-- - remove_node(pos)
|
||||||
-- - get_node(pos)
|
-- - get_node(pos)
|
||||||
|
-- - add_luaentity(pos, name)
|
||||||
--
|
--
|
||||||
-- ObjectRef is basically ServerActiveObject.
|
-- ObjectRef is basically ServerActiveObject.
|
||||||
-- ObjectRef methods:
|
-- ObjectRef methods:
|
||||||
@ -114,6 +115,12 @@ end
|
|||||||
-- - Functions receive a "luaentity" as self:
|
-- - Functions receive a "luaentity" as self:
|
||||||
-- - It has the member .object, which is an ObjectRef pointing to the object
|
-- - It has the member .object, which is an ObjectRef pointing to the object
|
||||||
-- - The original prototype stuff is visible directly via a metatable
|
-- - The original prototype stuff is visible directly via a metatable
|
||||||
|
-- - Callbacks:
|
||||||
|
-- - on_activate(self, staticdata)
|
||||||
|
-- - on_step(self, dtime)
|
||||||
|
-- - on_punch(self, hitter)
|
||||||
|
-- - on_rightclick(self, clicker)
|
||||||
|
-- - get_staticdata(self): return string
|
||||||
--
|
--
|
||||||
-- MapNode representation:
|
-- MapNode representation:
|
||||||
-- {name="name", param1=num, param2=num}
|
-- {name="name", param1=num, param2=num}
|
||||||
@ -654,11 +661,20 @@ local TNT = {
|
|||||||
--textures = {"mese.png^[forcesingle"},
|
--textures = {"mese.png^[forcesingle"},
|
||||||
-- Initial value for our timer
|
-- Initial value for our timer
|
||||||
timer = 0,
|
timer = 0,
|
||||||
|
-- Number of punches required to defuse
|
||||||
|
health = 3,
|
||||||
-- List names of state variables, for serializing object state
|
-- List names of state variables, for serializing object state
|
||||||
-- (NOTE: not implemented and implementation will not be like this)
|
-- (NOTE: not implemented and implementation will not be like this)
|
||||||
-- state_variables = {"timer"},
|
-- state_variables = {"timer"},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
-- Called when a TNT object is created
|
||||||
|
function TNT:on_activate(staticdata)
|
||||||
|
print("TNT:on_activate()")
|
||||||
|
self.object:setvelocity({x=0, y=1, z=0})
|
||||||
|
self.object:setacceleration({x=0, y=-5, z=0})
|
||||||
|
end
|
||||||
|
|
||||||
-- Called periodically
|
-- Called periodically
|
||||||
function TNT:on_step(dtime)
|
function TNT:on_step(dtime)
|
||||||
--print("TNT:on_step()")
|
--print("TNT:on_step()")
|
||||||
@ -667,15 +683,18 @@ end
|
|||||||
-- Called when object is punched
|
-- Called when object is punched
|
||||||
function TNT:on_punch(hitter)
|
function TNT:on_punch(hitter)
|
||||||
print("TNT:on_punch()")
|
print("TNT:on_punch()")
|
||||||
self.object:remove()
|
self.health = self.health - 1
|
||||||
hitter:add_to_inventory("CraftItem testobject1 1")
|
if self.health <= 0 then
|
||||||
|
self.object:remove()
|
||||||
|
hitter:add_to_inventory("NodeItem TNT 1")
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Called when object is right-clicked
|
-- Called when object is right-clicked
|
||||||
function TNT:on_rightclick(clicker)
|
function TNT:on_rightclick(clicker)
|
||||||
pos = self.object:getpos()
|
--pos = self.object:getpos()
|
||||||
pos = {x=pos.x, y=pos.y+0.1, z=pos.z}
|
--pos = {x=pos.x, y=pos.y+0.1, z=pos.z}
|
||||||
self.object:moveto(pos, false)
|
--self.object:moveto(pos, false)
|
||||||
end
|
end
|
||||||
|
|
||||||
print("TNT dump: "..dump(TNT))
|
print("TNT dump: "..dump(TNT))
|
||||||
@ -694,16 +713,13 @@ function register_falling_node(nodename, texture)
|
|||||||
visual = "cube",
|
visual = "cube",
|
||||||
textures = {texture,texture,texture,texture,texture,texture},
|
textures = {texture,texture,texture,texture,texture,texture},
|
||||||
-- State
|
-- State
|
||||||
fallspeed = 0,
|
|
||||||
-- Methods
|
-- Methods
|
||||||
on_step = function(self, dtime)
|
on_step = function(self, dtime)
|
||||||
-- Apply gravity manually
|
-- Set gravity
|
||||||
self.fallspeed = self.fallspeed + dtime * 5
|
self.object:setacceleration({x=0, y=-10, z=0})
|
||||||
fp = self.object:getpos()
|
|
||||||
fp.y = fp.y - self.fallspeed * dtime
|
|
||||||
self.object:moveto(fp, true)
|
|
||||||
-- Turn to actual sand when collides to ground or just move
|
-- Turn to actual sand when collides to ground or just move
|
||||||
bcp = {x=fp.x, y=fp.y-0.5, z=fp.z} -- Position of bottom center point
|
pos = self.object:getpos()
|
||||||
|
bcp = {x=pos.x, y=pos.y-0.5, z=pos.z} -- Position of bottom center point
|
||||||
bcn = minetest.env:get_node(bcp)
|
bcn = minetest.env:get_node(bcp)
|
||||||
if bcn.name ~= "air" then
|
if bcn.name ~= "air" then
|
||||||
-- Turn to a sand node
|
-- Turn to a sand node
|
||||||
@ -772,6 +788,16 @@ function on_dignode(p, node)
|
|||||||
end
|
end
|
||||||
minetest.register_on_dignode(on_dignode)
|
minetest.register_on_dignode(on_dignode)
|
||||||
|
|
||||||
|
function on_punchnode(p, node)
|
||||||
|
print("on_punchnode")
|
||||||
|
if node.name == "TNT" then
|
||||||
|
minetest.env:remove_node(p)
|
||||||
|
minetest.env:add_luaentity(p, "TNT")
|
||||||
|
nodeupdate(p)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
minetest.register_on_punchnode(on_punchnode)
|
||||||
|
|
||||||
--
|
--
|
||||||
-- Done, print some random stuff
|
-- Done, print some random stuff
|
||||||
--
|
--
|
||||||
|
@ -1278,6 +1278,8 @@ LuaEntityCAO::LuaEntityCAO(IGameDef *gamedef):
|
|||||||
m_meshnode(NULL),
|
m_meshnode(NULL),
|
||||||
m_spritenode(NULL),
|
m_spritenode(NULL),
|
||||||
m_position(v3f(0,10*BS,0)),
|
m_position(v3f(0,10*BS,0)),
|
||||||
|
m_velocity(v3f(0,0,0)),
|
||||||
|
m_acceleration(v3f(0,0,0)),
|
||||||
m_yaw(0),
|
m_yaw(0),
|
||||||
m_prop(new LuaEntityProperties)
|
m_prop(new LuaEntityProperties)
|
||||||
{
|
{
|
||||||
@ -1455,6 +1457,9 @@ void LuaEntityCAO::updateNodePos()
|
|||||||
|
|
||||||
void LuaEntityCAO::step(float dtime, ClientEnvironment *env)
|
void LuaEntityCAO::step(float dtime, ClientEnvironment *env)
|
||||||
{
|
{
|
||||||
|
m_position += dtime * m_velocity + 0.5 * dtime * dtime * m_acceleration;
|
||||||
|
m_velocity += dtime * m_acceleration;
|
||||||
|
pos_translator.update(m_position, pos_translator.aim_is_end, pos_translator.anim_time);
|
||||||
pos_translator.translate(dtime);
|
pos_translator.translate(dtime);
|
||||||
updateNodePos();
|
updateNodePos();
|
||||||
}
|
}
|
||||||
@ -1471,6 +1476,10 @@ void LuaEntityCAO::processMessage(const std::string &data)
|
|||||||
bool do_interpolate = readU8(is);
|
bool do_interpolate = readU8(is);
|
||||||
// pos
|
// pos
|
||||||
m_position = readV3F1000(is);
|
m_position = readV3F1000(is);
|
||||||
|
// velocity
|
||||||
|
m_velocity = readV3F1000(is);
|
||||||
|
// acceleration
|
||||||
|
m_acceleration = readV3F1000(is);
|
||||||
// yaw
|
// yaw
|
||||||
m_yaw = readF1000(is);
|
m_yaw = readF1000(is);
|
||||||
// is_end_position (for interpolation)
|
// is_end_position (for interpolation)
|
||||||
|
@ -428,6 +428,8 @@ private:
|
|||||||
scene::IMeshSceneNode *m_meshnode;
|
scene::IMeshSceneNode *m_meshnode;
|
||||||
scene::MyBillboardSceneNode *m_spritenode;
|
scene::MyBillboardSceneNode *m_spritenode;
|
||||||
v3f m_position;
|
v3f m_position;
|
||||||
|
v3f m_velocity;
|
||||||
|
v3f m_acceleration;
|
||||||
float m_yaw;
|
float m_yaw;
|
||||||
struct LuaEntityProperties *m_prop;
|
struct LuaEntityProperties *m_prop;
|
||||||
SmoothTranslator pos_translator;
|
SmoothTranslator pos_translator;
|
||||||
|
@ -1550,6 +1550,8 @@ LuaEntitySAO::LuaEntitySAO(ServerEnvironment *env, v3f pos,
|
|||||||
m_init_state(state),
|
m_init_state(state),
|
||||||
m_registered(false),
|
m_registered(false),
|
||||||
m_prop(new LuaEntityProperties),
|
m_prop(new LuaEntityProperties),
|
||||||
|
m_velocity(0,0,0),
|
||||||
|
m_acceleration(0,0,0),
|
||||||
m_yaw(0),
|
m_yaw(0),
|
||||||
m_last_sent_yaw(0),
|
m_last_sent_yaw(0),
|
||||||
m_last_sent_position(0,0,0),
|
m_last_sent_position(0,0,0),
|
||||||
@ -1610,6 +1612,9 @@ void LuaEntitySAO::step(float dtime, bool send_recommended)
|
|||||||
{
|
{
|
||||||
m_last_sent_position_timer += dtime;
|
m_last_sent_position_timer += dtime;
|
||||||
|
|
||||||
|
m_base_position += dtime * m_velocity + 0.5 * dtime * dtime * m_acceleration;
|
||||||
|
m_velocity += dtime * m_acceleration;
|
||||||
|
|
||||||
if(m_registered){
|
if(m_registered){
|
||||||
lua_State *L = m_env->getLua();
|
lua_State *L = m_env->getLua();
|
||||||
scriptapi_luaentity_step(L, m_id, dtime);
|
scriptapi_luaentity_step(L, m_id, dtime);
|
||||||
@ -1618,6 +1623,7 @@ void LuaEntitySAO::step(float dtime, bool send_recommended)
|
|||||||
if(send_recommended == false)
|
if(send_recommended == false)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
// TODO: force send when velocity/acceleration changes enough
|
||||||
float minchange = 0.2*BS;
|
float minchange = 0.2*BS;
|
||||||
if(m_last_sent_position_timer > 1.0){
|
if(m_last_sent_position_timer > 1.0){
|
||||||
minchange = 0.01*BS;
|
minchange = 0.01*BS;
|
||||||
@ -1659,7 +1665,7 @@ std::string LuaEntitySAO::getStaticData()
|
|||||||
// state
|
// state
|
||||||
if(m_registered){
|
if(m_registered){
|
||||||
lua_State *L = m_env->getLua();
|
lua_State *L = m_env->getLua();
|
||||||
std::string state = scriptapi_luaentity_get_state(L, m_id);
|
std::string state = scriptapi_luaentity_get_staticdata(L, m_id);
|
||||||
os<<serializeLongString(state);
|
os<<serializeLongString(state);
|
||||||
} else {
|
} else {
|
||||||
os<<serializeLongString(m_init_state);
|
os<<serializeLongString(m_init_state);
|
||||||
@ -1709,6 +1715,16 @@ float LuaEntitySAO::getMinimumSavedMovement()
|
|||||||
return 0.1 * BS;
|
return 0.1 * BS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LuaEntitySAO::setVelocity(v3f velocity)
|
||||||
|
{
|
||||||
|
m_velocity = velocity;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LuaEntitySAO::setAcceleration(v3f acceleration)
|
||||||
|
{
|
||||||
|
m_acceleration = acceleration;
|
||||||
|
}
|
||||||
|
|
||||||
void LuaEntitySAO::sendPosition(bool do_interpolate, bool is_movement_end)
|
void LuaEntitySAO::sendPosition(bool do_interpolate, bool is_movement_end)
|
||||||
{
|
{
|
||||||
m_last_sent_move_precision = m_base_position.getDistanceFrom(
|
m_last_sent_move_precision = m_base_position.getDistanceFrom(
|
||||||
@ -1716,6 +1732,8 @@ void LuaEntitySAO::sendPosition(bool do_interpolate, bool is_movement_end)
|
|||||||
m_last_sent_position_timer = 0;
|
m_last_sent_position_timer = 0;
|
||||||
m_last_sent_yaw = m_yaw;
|
m_last_sent_yaw = m_yaw;
|
||||||
m_last_sent_position = m_base_position;
|
m_last_sent_position = m_base_position;
|
||||||
|
//m_last_sent_velocity = m_velocity;
|
||||||
|
//m_last_sent_acceleration = m_acceleration;
|
||||||
|
|
||||||
float update_interval = m_env->getSendRecommendedInterval();
|
float update_interval = m_env->getSendRecommendedInterval();
|
||||||
|
|
||||||
@ -1727,6 +1745,10 @@ void LuaEntitySAO::sendPosition(bool do_interpolate, bool is_movement_end)
|
|||||||
writeU8(os, do_interpolate);
|
writeU8(os, do_interpolate);
|
||||||
// pos
|
// pos
|
||||||
writeV3F1000(os, m_base_position);
|
writeV3F1000(os, m_base_position);
|
||||||
|
// velocity
|
||||||
|
writeV3F1000(os, m_velocity);
|
||||||
|
// acceleration
|
||||||
|
writeV3F1000(os, m_acceleration);
|
||||||
// yaw
|
// yaw
|
||||||
writeF1000(os, m_yaw);
|
writeF1000(os, m_yaw);
|
||||||
// is_end_position (for interpolation)
|
// is_end_position (for interpolation)
|
||||||
|
@ -216,6 +216,8 @@ public:
|
|||||||
void setPos(v3f pos);
|
void setPos(v3f pos);
|
||||||
void moveTo(v3f pos, bool continuous);
|
void moveTo(v3f pos, bool continuous);
|
||||||
float getMinimumSavedMovement();
|
float getMinimumSavedMovement();
|
||||||
|
void setVelocity(v3f velocity);
|
||||||
|
void setAcceleration(v3f acceleration);
|
||||||
private:
|
private:
|
||||||
void sendPosition(bool do_interpolate, bool is_movement_end);
|
void sendPosition(bool do_interpolate, bool is_movement_end);
|
||||||
|
|
||||||
@ -224,6 +226,8 @@ private:
|
|||||||
bool m_registered;
|
bool m_registered;
|
||||||
struct LuaEntityProperties *m_prop;
|
struct LuaEntityProperties *m_prop;
|
||||||
|
|
||||||
|
v3f m_velocity;
|
||||||
|
v3f m_acceleration;
|
||||||
float m_yaw;
|
float m_yaw;
|
||||||
float m_last_sent_yaw;
|
float m_last_sent_yaw;
|
||||||
v3f m_last_sent_position;
|
v3f m_last_sent_position;
|
||||||
|
@ -61,6 +61,7 @@ TODO:
|
|||||||
meta.set("owner", playername)
|
meta.set("owner", playername)
|
||||||
meta.get("owner")
|
meta.get("owner")
|
||||||
- Item definition (actually, only CraftItem)
|
- Item definition (actually, only CraftItem)
|
||||||
|
- (not scripting) Putting items in node metadata (virtual)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void stackDump(lua_State *L, std::ostream &o)
|
static void stackDump(lua_State *L, std::ostream &o)
|
||||||
@ -424,24 +425,21 @@ static int l_register_craft(lua_State *L)
|
|||||||
return 0; /* number of results */
|
return 0; /* number of results */
|
||||||
}
|
}
|
||||||
|
|
||||||
// Register a global step function
|
static int register_lua_callback(lua_State *L, const char *tablename)
|
||||||
// register_globalstep(function)
|
|
||||||
static int l_register_globalstep(lua_State *L)
|
|
||||||
{
|
{
|
||||||
luaL_checktype(L, 1, LUA_TFUNCTION);
|
luaL_checktype(L, 1, LUA_TFUNCTION);
|
||||||
infostream<<"register_globalstep"<<std::endl;
|
|
||||||
|
|
||||||
lua_getglobal(L, "table");
|
lua_getglobal(L, "table");
|
||||||
lua_getfield(L, -1, "insert");
|
lua_getfield(L, -1, "insert");
|
||||||
int table_insert = lua_gettop(L);
|
int table_insert = lua_gettop(L);
|
||||||
// Get minetest.registered_globalsteps
|
// Get minetest.registered_globalsteps
|
||||||
lua_getglobal(L, "minetest");
|
lua_getglobal(L, "minetest");
|
||||||
lua_getfield(L, -1, "registered_globalsteps");
|
lua_getfield(L, -1, tablename);
|
||||||
luaL_checktype(L, -1, LUA_TTABLE);
|
luaL_checktype(L, -1, LUA_TTABLE);
|
||||||
int registered_globalsteps = lua_gettop(L);
|
int registered = lua_gettop(L);
|
||||||
// table.insert(registered_globalsteps, func)
|
// table.insert(registered_globalsteps, func)
|
||||||
lua_pushvalue(L, table_insert);
|
lua_pushvalue(L, table_insert);
|
||||||
lua_pushvalue(L, registered_globalsteps);
|
lua_pushvalue(L, registered);
|
||||||
lua_pushvalue(L, 1); // push function from argument 1
|
lua_pushvalue(L, 1); // push function from argument 1
|
||||||
// Call insert
|
// Call insert
|
||||||
if(lua_pcall(L, 2, 0, 0))
|
if(lua_pcall(L, 2, 0, 0))
|
||||||
@ -450,54 +448,33 @@ static int l_register_globalstep(lua_State *L)
|
|||||||
return 0; /* number of results */
|
return 0; /* number of results */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Register a global step function
|
||||||
|
// register_globalstep(function)
|
||||||
|
static int l_register_globalstep(lua_State *L)
|
||||||
|
{
|
||||||
|
infostream<<"register_globalstep"<<std::endl;
|
||||||
|
return register_lua_callback(L, "registered_globalsteps");
|
||||||
|
}
|
||||||
|
|
||||||
// register_on_placenode(function)
|
// register_on_placenode(function)
|
||||||
static int l_register_on_placenode(lua_State *L)
|
static int l_register_on_placenode(lua_State *L)
|
||||||
{
|
{
|
||||||
luaL_checktype(L, 1, LUA_TFUNCTION);
|
|
||||||
infostream<<"register_on_placenode"<<std::endl;
|
infostream<<"register_on_placenode"<<std::endl;
|
||||||
|
return register_lua_callback(L, "registered_on_placenodes");
|
||||||
lua_getglobal(L, "table");
|
|
||||||
lua_getfield(L, -1, "insert");
|
|
||||||
int table_insert = lua_gettop(L);
|
|
||||||
// Get minetest.registered_on_placenodes
|
|
||||||
lua_getglobal(L, "minetest");
|
|
||||||
lua_getfield(L, -1, "registered_on_placenodes");
|
|
||||||
luaL_checktype(L, -1, LUA_TTABLE);
|
|
||||||
int registered_on_placenodes = lua_gettop(L);
|
|
||||||
// table.insert(registered_on_placenodes, func)
|
|
||||||
lua_pushvalue(L, table_insert);
|
|
||||||
lua_pushvalue(L, registered_on_placenodes);
|
|
||||||
lua_pushvalue(L, 1); // push function from argument 1
|
|
||||||
// Call insert
|
|
||||||
if(lua_pcall(L, 2, 0, 0))
|
|
||||||
script_error(L, "error: %s\n", lua_tostring(L, -1));
|
|
||||||
|
|
||||||
return 0; /* number of results */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// register_on_dignode(function)
|
// register_on_dignode(function)
|
||||||
static int l_register_on_dignode(lua_State *L)
|
static int l_register_on_dignode(lua_State *L)
|
||||||
{
|
{
|
||||||
luaL_checktype(L, 1, LUA_TFUNCTION);
|
|
||||||
infostream<<"register_on_dignode"<<std::endl;
|
infostream<<"register_on_dignode"<<std::endl;
|
||||||
|
return register_lua_callback(L, "registered_on_dignodes");
|
||||||
|
}
|
||||||
|
|
||||||
lua_getglobal(L, "table");
|
// register_on_punchnode(function)
|
||||||
lua_getfield(L, -1, "insert");
|
static int l_register_on_punchnode(lua_State *L)
|
||||||
int table_insert = lua_gettop(L);
|
{
|
||||||
// Get minetest.registered_on_dignodes
|
infostream<<"register_on_punchnode"<<std::endl;
|
||||||
lua_getglobal(L, "minetest");
|
return register_lua_callback(L, "registered_on_punchnodes");
|
||||||
lua_getfield(L, -1, "registered_on_dignodes");
|
|
||||||
luaL_checktype(L, -1, LUA_TTABLE);
|
|
||||||
int registered_on_dignodes = lua_gettop(L);
|
|
||||||
// table.insert(registered_on_dignodes, func)
|
|
||||||
lua_pushvalue(L, table_insert);
|
|
||||||
lua_pushvalue(L, registered_on_dignodes);
|
|
||||||
lua_pushvalue(L, 1); // push function from argument 1
|
|
||||||
// Call insert
|
|
||||||
if(lua_pcall(L, 2, 0, 0))
|
|
||||||
script_error(L, "error: %s\n", lua_tostring(L, -1));
|
|
||||||
|
|
||||||
return 0; /* number of results */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct luaL_Reg minetest_f [] = {
|
static const struct luaL_Reg minetest_f [] = {
|
||||||
@ -508,6 +485,7 @@ static const struct luaL_Reg minetest_f [] = {
|
|||||||
{"register_globalstep", l_register_globalstep},
|
{"register_globalstep", l_register_globalstep},
|
||||||
{"register_on_placenode", l_register_on_placenode},
|
{"register_on_placenode", l_register_on_placenode},
|
||||||
{"register_on_dignode", l_register_on_dignode},
|
{"register_on_dignode", l_register_on_dignode},
|
||||||
|
{"register_on_punchnode", l_register_on_punchnode},
|
||||||
{NULL, NULL}
|
{NULL, NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -583,8 +561,9 @@ private:
|
|||||||
// content
|
// content
|
||||||
MapNode n = readnode(L, 3, env->getGameDef()->ndef());
|
MapNode n = readnode(L, 3, env->getGameDef()->ndef());
|
||||||
// Do it
|
// Do it
|
||||||
env->getMap().addNodeWithEvent(pos, n);
|
bool succeeded = env->getMap().addNodeWithEvent(pos, n);
|
||||||
return 0;
|
lua_pushboolean(L, succeeded);
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// EnvRef:remove_node(pos)
|
// EnvRef:remove_node(pos)
|
||||||
@ -598,8 +577,9 @@ private:
|
|||||||
// pos
|
// pos
|
||||||
v3s16 pos = readpos(L, 2);
|
v3s16 pos = readpos(L, 2);
|
||||||
// Do it
|
// Do it
|
||||||
env->getMap().removeNodeWithEvent(pos);
|
bool succeeded = env->getMap().removeNodeWithEvent(pos);
|
||||||
return 0;
|
lua_pushboolean(L, succeeded);
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// EnvRef:get_node(pos)
|
// EnvRef:get_node(pos)
|
||||||
@ -810,6 +790,32 @@ private:
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// setvelocity(self, velocity)
|
||||||
|
static int l_setvelocity(lua_State *L)
|
||||||
|
{
|
||||||
|
ObjectRef *ref = checkobject(L, 1);
|
||||||
|
LuaEntitySAO *co = getluaobject(ref);
|
||||||
|
if(co == NULL) return 0;
|
||||||
|
// pos
|
||||||
|
v3f pos = readFloatPos(L, 2);
|
||||||
|
// Do it
|
||||||
|
co->setVelocity(pos);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// setacceleration(self, acceleration)
|
||||||
|
static int l_setacceleration(lua_State *L)
|
||||||
|
{
|
||||||
|
ObjectRef *ref = checkobject(L, 1);
|
||||||
|
LuaEntitySAO *co = getluaobject(ref);
|
||||||
|
if(co == NULL) return 0;
|
||||||
|
// pos
|
||||||
|
v3f pos = readFloatPos(L, 2);
|
||||||
|
// Do it
|
||||||
|
co->setAcceleration(pos);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
// add_to_inventory(self, itemstring)
|
// add_to_inventory(self, itemstring)
|
||||||
// returns: true if item was added, false otherwise
|
// returns: true if item was added, false otherwise
|
||||||
static int l_add_to_inventory(lua_State *L)
|
static int l_add_to_inventory(lua_State *L)
|
||||||
@ -902,6 +908,8 @@ const luaL_reg ObjectRef::methods[] = {
|
|||||||
method(ObjectRef, getpos),
|
method(ObjectRef, getpos),
|
||||||
method(ObjectRef, setpos),
|
method(ObjectRef, setpos),
|
||||||
method(ObjectRef, moveto),
|
method(ObjectRef, moveto),
|
||||||
|
method(ObjectRef, setvelocity),
|
||||||
|
method(ObjectRef, setacceleration),
|
||||||
method(ObjectRef, add_to_inventory),
|
method(ObjectRef, add_to_inventory),
|
||||||
{0,0}
|
{0,0}
|
||||||
};
|
};
|
||||||
@ -957,6 +965,9 @@ void scriptapi_export(lua_State *L, Server *server)
|
|||||||
lua_newtable(L);
|
lua_newtable(L);
|
||||||
lua_setfield(L, -2, "registered_on_dignodes");
|
lua_setfield(L, -2, "registered_on_dignodes");
|
||||||
|
|
||||||
|
lua_newtable(L);
|
||||||
|
lua_setfield(L, -2, "registered_on_punchnodes");
|
||||||
|
|
||||||
lua_newtable(L);
|
lua_newtable(L);
|
||||||
lua_setfield(L, -2, "object_refs");
|
lua_setfield(L, -2, "object_refs");
|
||||||
|
|
||||||
@ -1159,12 +1170,45 @@ void scriptapi_environment_on_dignode(lua_State *L, v3s16 p, MapNode oldnode)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void scriptapi_environment_on_punchnode(lua_State *L, v3s16 p, MapNode oldnode)
|
||||||
|
{
|
||||||
|
realitycheck(L);
|
||||||
|
assert(lua_checkstack(L, 20));
|
||||||
|
//infostream<<"scriptapi_environment_on_punchnode"<<std::endl;
|
||||||
|
StackUnroller stack_unroller(L);
|
||||||
|
|
||||||
|
// Get server from registry
|
||||||
|
lua_getfield(L, LUA_REGISTRYINDEX, "minetest_server");
|
||||||
|
Server *server = (Server*)lua_touserdata(L, -1);
|
||||||
|
// And get the writable node definition manager from the server
|
||||||
|
IWritableNodeDefManager *ndef =
|
||||||
|
server->getWritableNodeDefManager();
|
||||||
|
|
||||||
|
// Get minetest.registered_on_punchnodes
|
||||||
|
lua_getglobal(L, "minetest");
|
||||||
|
lua_getfield(L, -1, "registered_on_punchnodes");
|
||||||
|
luaL_checktype(L, -1, LUA_TTABLE);
|
||||||
|
int table = lua_gettop(L);
|
||||||
|
// Foreach
|
||||||
|
lua_pushnil(L);
|
||||||
|
while(lua_next(L, table) != 0){
|
||||||
|
// key at index -2 and value at index -1
|
||||||
|
luaL_checktype(L, -1, LUA_TFUNCTION);
|
||||||
|
// Call function
|
||||||
|
pushpos(L, p);
|
||||||
|
pushnode(L, oldnode, ndef);
|
||||||
|
if(lua_pcall(L, 2, 0, 0))
|
||||||
|
script_error(L, "error: %s\n", lua_tostring(L, -1));
|
||||||
|
// value removed, keep key for next iteration
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
luaentity
|
luaentity
|
||||||
*/
|
*/
|
||||||
|
|
||||||
bool scriptapi_luaentity_add(lua_State *L, u16 id, const char *name,
|
bool scriptapi_luaentity_add(lua_State *L, u16 id, const char *name,
|
||||||
const char *init_state)
|
const std::string &staticdata)
|
||||||
{
|
{
|
||||||
realitycheck(L);
|
realitycheck(L);
|
||||||
assert(lua_checkstack(L, 20));
|
assert(lua_checkstack(L, 20));
|
||||||
@ -1172,8 +1216,6 @@ bool scriptapi_luaentity_add(lua_State *L, u16 id, const char *name,
|
|||||||
<<name<<"\""<<std::endl;
|
<<name<<"\""<<std::endl;
|
||||||
StackUnroller stack_unroller(L);
|
StackUnroller stack_unroller(L);
|
||||||
|
|
||||||
// Create object as a dummy string (TODO: Create properly)
|
|
||||||
|
|
||||||
// Get minetest.registered_entities[name]
|
// Get minetest.registered_entities[name]
|
||||||
lua_getglobal(L, "minetest");
|
lua_getglobal(L, "minetest");
|
||||||
lua_getfield(L, -1, "registered_entities");
|
lua_getfield(L, -1, "registered_entities");
|
||||||
@ -1213,17 +1255,19 @@ bool scriptapi_luaentity_add(lua_State *L, u16 id, const char *name,
|
|||||||
lua_pushvalue(L, object); // Copy object to top of stack
|
lua_pushvalue(L, object); // Copy object to top of stack
|
||||||
lua_settable(L, -3);
|
lua_settable(L, -3);
|
||||||
|
|
||||||
// This callback doesn't really make sense
|
// Get on_activate function
|
||||||
/*// Get on_activate function
|
|
||||||
lua_pushvalue(L, object);
|
lua_pushvalue(L, object);
|
||||||
lua_getfield(L, -1, "on_activate");
|
lua_getfield(L, -1, "on_activate");
|
||||||
luaL_checktype(L, -1, LUA_TFUNCTION);
|
if(!lua_isnil(L, -1)){
|
||||||
lua_pushvalue(L, object); // self
|
luaL_checktype(L, -1, LUA_TFUNCTION);
|
||||||
// Call with 1 arguments, 0 results
|
lua_pushvalue(L, object); // self
|
||||||
if(lua_pcall(L, 1, 0, 0))
|
lua_pushlstring(L, staticdata.c_str(), staticdata.size());
|
||||||
script_error(L, "error running function %s:on_activate: %s\n",
|
// Call with 2 arguments, 0 results
|
||||||
name, lua_tostring(L, -1));*/
|
if(lua_pcall(L, 2, 0, 0))
|
||||||
|
script_error(L, "error running function %s:on_activate: %s\n",
|
||||||
|
name, lua_tostring(L, -1));
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1247,13 +1291,33 @@ void scriptapi_luaentity_rm(lua_State *L, u16 id)
|
|||||||
lua_pop(L, 2); // pop luaentities, minetest
|
lua_pop(L, 2); // pop luaentities, minetest
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string scriptapi_luaentity_get_state(lua_State *L, u16 id)
|
std::string scriptapi_luaentity_get_staticdata(lua_State *L, u16 id)
|
||||||
{
|
{
|
||||||
realitycheck(L);
|
realitycheck(L);
|
||||||
assert(lua_checkstack(L, 20));
|
assert(lua_checkstack(L, 20));
|
||||||
infostream<<"scriptapi_luaentity_get_state: id="<<id<<std::endl;
|
infostream<<"scriptapi_luaentity_get_staticdata: id="<<id<<std::endl;
|
||||||
|
StackUnroller stack_unroller(L);
|
||||||
|
|
||||||
|
// Get minetest.luaentities[id]
|
||||||
|
luaentity_get(L, id);
|
||||||
|
int object = lua_gettop(L);
|
||||||
|
|
||||||
return "";
|
// Get get_staticdata function
|
||||||
|
lua_pushvalue(L, object);
|
||||||
|
lua_getfield(L, -1, "get_staticdata");
|
||||||
|
if(lua_isnil(L, -1))
|
||||||
|
return "";
|
||||||
|
|
||||||
|
luaL_checktype(L, -1, LUA_TFUNCTION);
|
||||||
|
lua_pushvalue(L, object); // self
|
||||||
|
// Call with 1 arguments, 1 results
|
||||||
|
if(lua_pcall(L, 1, 1, 0))
|
||||||
|
script_error(L, "error running function get_staticdata: %s\n",
|
||||||
|
lua_tostring(L, -1));
|
||||||
|
|
||||||
|
size_t len=0;
|
||||||
|
const char *s = lua_tolstring(L, -1, &len);
|
||||||
|
return std::string(s, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
void scriptapi_luaentity_get_properties(lua_State *L, u16 id,
|
void scriptapi_luaentity_get_properties(lua_State *L, u16 id,
|
||||||
@ -1344,7 +1408,7 @@ void scriptapi_luaentity_step(lua_State *L, u16 id, float dtime)
|
|||||||
lua_pushnumber(L, dtime); // dtime
|
lua_pushnumber(L, dtime); // dtime
|
||||||
// Call with 2 arguments, 0 results
|
// Call with 2 arguments, 0 results
|
||||||
if(lua_pcall(L, 2, 0, 0))
|
if(lua_pcall(L, 2, 0, 0))
|
||||||
script_error(L, "error running function 'step': %s\n", lua_tostring(L, -1));
|
script_error(L, "error running function 'on_step': %s\n", lua_tostring(L, -1));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calls entity:on_punch(ObjectRef puncher)
|
// Calls entity:on_punch(ObjectRef puncher)
|
||||||
|
@ -44,13 +44,15 @@ void scriptapi_environment_step(lua_State *L, float dtime);
|
|||||||
void scriptapi_environment_on_placenode(lua_State *L, v3s16 p, MapNode newnode);
|
void scriptapi_environment_on_placenode(lua_State *L, v3s16 p, MapNode newnode);
|
||||||
// After removing node
|
// After removing node
|
||||||
void scriptapi_environment_on_dignode(lua_State *L, v3s16 p, MapNode oldnode);
|
void scriptapi_environment_on_dignode(lua_State *L, v3s16 p, MapNode oldnode);
|
||||||
|
// When punching node
|
||||||
|
void scriptapi_environment_on_punchnode(lua_State *L, v3s16 p, MapNode node);
|
||||||
|
|
||||||
/* luaentity */
|
/* luaentity */
|
||||||
// Returns true if succesfully added into Lua; false otherwise.
|
// Returns true if succesfully added into Lua; false otherwise.
|
||||||
bool scriptapi_luaentity_add(lua_State *L, u16 id, const char *name,
|
bool scriptapi_luaentity_add(lua_State *L, u16 id, const char *name,
|
||||||
const char *init_state);
|
const std::string &staticdata);
|
||||||
void scriptapi_luaentity_rm(lua_State *L, u16 id);
|
void scriptapi_luaentity_rm(lua_State *L, u16 id);
|
||||||
std::string scriptapi_luaentity_get_state(lua_State *L, u16 id);
|
std::string scriptapi_luaentity_get_staticdata(lua_State *L, u16 id);
|
||||||
void scriptapi_luaentity_get_properties(lua_State *L, u16 id,
|
void scriptapi_luaentity_get_properties(lua_State *L, u16 id,
|
||||||
LuaEntityProperties *prop);
|
LuaEntityProperties *prop);
|
||||||
void scriptapi_luaentity_step(lua_State *L, u16 id, float dtime);
|
void scriptapi_luaentity_step(lua_State *L, u16 id, float dtime);
|
||||||
|
@ -2501,6 +2501,32 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
|
|||||||
NOTE: This can be used in the future to check if
|
NOTE: This can be used in the future to check if
|
||||||
somebody is cheating, by checking the timing.
|
somebody is cheating, by checking the timing.
|
||||||
*/
|
*/
|
||||||
|
bool cannot_punch_node = false;
|
||||||
|
|
||||||
|
MapNode n(CONTENT_IGNORE);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
n = m_env->getMap().getNode(p_under);
|
||||||
|
}
|
||||||
|
catch(InvalidPositionException &e)
|
||||||
|
{
|
||||||
|
infostream<<"Server: Not punching: Node not found."
|
||||||
|
<<" Adding block to emerge queue."
|
||||||
|
<<std::endl;
|
||||||
|
m_emerge_queue.addBlock(peer_id,
|
||||||
|
getNodeBlockPos(p_over), BLOCK_EMERGE_FLAG_FROMDISK);
|
||||||
|
cannot_punch_node = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(cannot_punch_node)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Run script hook
|
||||||
|
*/
|
||||||
|
scriptapi_environment_on_punchnode(m_lua, p_under, n);
|
||||||
|
|
||||||
} // action == 0
|
} // action == 0
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Loading…
Reference in New Issue
Block a user