on_newplayer and on_respawnplayer callbacks
authorPerttu Ahola <celeron55@gmail.com>
Sat, 26 Nov 2011 01:20:19 +0000 (03:20 +0200)
committerPerttu Ahola <celeron55@gmail.com>
Tue, 29 Nov 2011 17:13:53 +0000 (19:13 +0200)
data/mods/default/init.lua
src/player.h
src/scriptapi.cpp
src/scriptapi.h
src/server.cpp

index 29ec6abb86bb9026462d1410e4f26ab7e69ce3e5..6512f55ebef2487a3fd03515ad9f9476f8d2b850 100644 (file)
@@ -15,6 +15,9 @@
 -- minetest.register_on_placenode(func(pos, newnode, placer))
 -- minetest.register_on_dignode(func(pos, oldnode, digger))
 -- minetest.register_on_punchnode(func(pos, node, puncher))
+-- minetest.register_on_newplayer(func(ObjectRef))
+-- minetest.register_on_respawnplayer(func(ObjectRef))
+-- ^ return true in func to disable regular player placement
 --
 -- Global objects:
 -- minetest.env - environment reference
@@ -1304,6 +1307,12 @@ function on_punchnode(p, node)
 end
 minetest.register_on_punchnode(on_punchnode)
 
+minetest.register_on_respawnplayer(function(player)
+       print("on_respawnplayer")
+       -- player:setpos({x=0, y=30, z=0})
+       -- return true
+end)
+
 --
 -- Done, print some random stuff
 --
@@ -1311,65 +1320,4 @@ minetest.register_on_punchnode(on_punchnode)
 print("minetest.registered_entities:")
 dump2(minetest.registered_entities)
 
---
--- Some random pre-implementation planning and drafting
---
-
---[[
-function TNT:on_rightclick(clicker)
-       print("TNT:on_rightclick()")
-       print("self: "..dump(self))
-       print("getmetatable(self): "..dump(getmetatable(self)))
-       print("getmetatable(getmetatable(self)): "..dump(getmetatable(getmetatable(self))))
-       pos = self.object:getpos()
-       print("TNT:on_rightclick(): object position: "..dump(pos))
-       pos = {x=pos.x+0.5+1, y=pos.y+0.5, z=pos.z+0.5}
-       --minetest.env:add_node(pos, {name="stone")
-end
---]]
-
---[=[
-
-register_block(0, {
-       textures = "stone.png",
-       makefacetype = 0,
-       get_dig_duration = function(env, pos, digger)
-               -- Check stuff like digger.current_tool
-               return 1.5
-       end,
-       on_dig = function(env, pos, digger)
-               env:remove_node(pos)
-               digger.inventory.put("MaterialItem2 0");
-       end,
-})
-
-register_block(1, {
-       textures = {"grass.png","mud.png","mud_grass_side.png","mud_grass_side.png","mud_grass_side.png","mud_grass_side.png"},
-       makefacetype = 0,
-       get_dig_duration = function(env, pos, digger)
-               -- Check stuff like digger.current_tool
-               return 0.5
-       end,
-       on_dig = function(env, pos, digger)
-               env:remove_node(pos)
-               digger.inventory.put("MaterialItem2 1");
-       end,
-})
-
--- Consider the "miscellaneous block namespace" to be 0xc00...0xfff = 3072...4095
-register_block(3072, {
-       textures = {"tnt_top.png","tnt_bottom.png","tnt_side.png","tnt_side.png","tnt_side.png","tnt_side.png"},
-       makefacetype = 0,
-       get_dig_duration = function(env, pos, digger)
-               -- Cannot be dug
-               return nil
-       end,
-       -- on_dig = function(env, pos, digger) end, -- Not implemented
-       on_hit = function(env, pos, hitter)
-               -- Replace with TNT object, which will explode after timer, follow gravity, blink and stuff
-               env:add_object("tnt", pos)
-               env:remove_node(pos)
-       end,
-})
---]=]
-
+-- END
index 56bb5083cce17adb84ed678e0b167689f6689d80..e133c7afb208acb296bb7bd822f1b61169d4887c 100644 (file)
@@ -208,6 +208,12 @@ public:
 
        u8 getType() const
                {return ACTIVEOBJECT_TYPE_PLAYER;}
+       
+       virtual void setPos(v3f pos)
+               { setPosition(pos); }
+       virtual void moveTo(v3f pos, bool continuous)
+               { setPosition(pos); }
+       
        virtual std::string getDescription(){return getName();}
        // Returns a reference
        virtual InventoryItem* getWieldedItem();
index 4a746c8f42854c2c22faeb48773a5d6a9ac5c9f0..fd9d10195d78e38ec1c77ae8c0da4b2b94831269 100644 (file)
@@ -41,9 +41,8 @@ extern "C" {
 
 /*
 TODO:
-- Node definition
 - Random node triggers (like grass growth)
-- Deterministic node triggers (like falling sand)
+- All kinds of callbacks
 - Object visual client-side stuff
        - Blink effect
        - Spritesheets and animation
@@ -848,6 +847,20 @@ static int l_register_on_punchnode(lua_State *L)
        return register_lua_callback(L, "registered_on_punchnodes");
 }
 
+// register_on_newplayer(function)
+static int l_register_on_newplayer(lua_State *L)
+{
+       infostream<<"register_on_newplayer"<<std::endl;
+       return register_lua_callback(L, "registered_on_newplayers");
+}
+
+// register_on_respawnplayer(function)
+static int l_register_on_respawnplayer(lua_State *L)
+{
+       infostream<<"register_on_respawnplayer"<<std::endl;
+       return register_lua_callback(L, "registered_on_respawnplayers");
+}
+
 static const struct luaL_Reg minetest_f [] = {
        {"register_nodedef_defaults", l_register_nodedef_defaults},
        {"register_entity", l_register_entity},
@@ -858,6 +871,8 @@ static const struct luaL_Reg minetest_f [] = {
        {"register_on_placenode", l_register_on_placenode},
        {"register_on_dignode", l_register_on_dignode},
        {"register_on_punchnode", l_register_on_punchnode},
+       {"register_on_newplayer", l_register_on_newplayer},
+       {"register_on_respawnplayer", l_register_on_respawnplayer},
        {"get_nodedef", l_get_nodedef},
        {NULL, NULL}
 };
@@ -1327,30 +1342,25 @@ void scriptapi_export(lua_State *L, Server *server)
 
        // Add tables to minetest
        
-       /*lua_newtable(L);
-       lua_setfield(L, -2, "registered_blocks");*/
-
        lua_newtable(L);
        lua_setfield(L, -2, "registered_nodes");
-
        lua_newtable(L);
        lua_setfield(L, -2, "registered_entities");
-
        lua_newtable(L);
        lua_setfield(L, -2, "registered_globalsteps");
-
        lua_newtable(L);
        lua_setfield(L, -2, "registered_on_placenodes");
-
        lua_newtable(L);
        lua_setfield(L, -2, "registered_on_dignodes");
-
        lua_newtable(L);
        lua_setfield(L, -2, "registered_on_punchnodes");
-
+       lua_newtable(L);
+       lua_setfield(L, -2, "registered_on_newplayers");
+       lua_newtable(L);
+       lua_setfield(L, -2, "registered_on_respawnplayers");
+       
        lua_newtable(L);
        lua_setfield(L, -2, "object_refs");
-
        lua_newtable(L);
        lua_setfield(L, -2, "luaentities");
 
@@ -1455,6 +1465,65 @@ void scriptapi_rm_object_reference(lua_State *L, ServerActiveObject *cobj)
        lua_settable(L, objectstable);
 }
 
+
+/*
+       misc
+*/
+
+void scriptapi_on_newplayer(lua_State *L, ServerActiveObject *player)
+{
+       realitycheck(L);
+       assert(lua_checkstack(L, 20));
+       StackUnroller stack_unroller(L);
+
+       // Get minetest.registered_on_newplayers
+       lua_getglobal(L, "minetest");
+       lua_getfield(L, -1, "registered_on_newplayers");
+       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
+               objectref_get_or_create(L, player);
+               if(lua_pcall(L, 1, 0, 0))
+                       script_error(L, "error: %s\n", lua_tostring(L, -1));
+               // value removed, keep key for next iteration
+       }
+}
+bool scriptapi_on_respawnplayer(lua_State *L, ServerActiveObject *player)
+{
+       realitycheck(L);
+       assert(lua_checkstack(L, 20));
+       StackUnroller stack_unroller(L);
+
+       bool positioning_handled_by_some = false;
+
+       // Get minetest.registered_on_respawnplayers
+       lua_getglobal(L, "minetest");
+       lua_getfield(L, -1, "registered_on_respawnplayers");
+       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
+               objectref_get_or_create(L, player);
+               if(lua_pcall(L, 1, 1, 0))
+                       script_error(L, "error: %s\n", lua_tostring(L, -1));
+               bool positioning_handled = lua_toboolean(L, -1);
+               lua_pop(L, 1);
+               if(positioning_handled)
+                       positioning_handled_by_some = true;
+               // value removed, keep key for next iteration
+       }
+       return positioning_handled_by_some;
+}
+
 /*
        environment
 */
index 33f090f744877e832ed0b52dd43b67f8055c1c30..08c83517238f914965640663ad892e49c4c33108 100644 (file)
@@ -50,6 +50,10 @@ void scriptapi_environment_on_dignode(lua_State *L, v3s16 p, MapNode oldnode,
 void scriptapi_environment_on_punchnode(lua_State *L, v3s16 p, MapNode node,
                ServerActiveObject *puncher);
 
+/* misc */
+void scriptapi_on_newplayer(lua_State *L, ServerActiveObject *player);
+bool scriptapi_on_respawnplayer(lua_State *L, ServerActiveObject *player);
+
 /* luaentity */
 // Returns true if succesfully added into Lua; false otherwise.
 bool scriptapi_luaentity_add(lua_State *L, u16 id, const char *name,
index 6cb125aa816d72b8fec3fbcc32b7252c082c2e82..78b7e79bd660daae443493ad2f9d0de9da023a71 100644 (file)
@@ -4348,9 +4348,13 @@ void Server::HandlePlayerHP(Player *player, s16 damage)
 
 void Server::RespawnPlayer(Player *player)
 {
-       v3f pos = findSpawnPos(m_env->getServerMap());
-       player->setPosition(pos);
        player->hp = 20;
+       ServerRemotePlayer *srp = (ServerRemotePlayer*)player;
+       bool repositioned = scriptapi_on_respawnplayer(m_lua, srp);
+       if(!repositioned){
+               v3f pos = findSpawnPos(m_env->getServerMap());
+               player->setPosition(pos);
+       }
        SendMovePlayer(player);
        SendPlayerHP(player);
 }
@@ -4617,9 +4621,7 @@ Player *Server::emergePlayer(const char *name, const char *password, u16 peer_id
                m_authmanager.setPrivs(name,
                                stringToPrivs(g_settings->get("default_privs")));
 
-               /*
-                       Set player position
-               */
+               /* Set player position */
                
                infostream<<"Server: Finding spawn place for player \""
                                <<name<<"\""<<std::endl;
@@ -4628,16 +4630,14 @@ Player *Server::emergePlayer(const char *name, const char *password, u16 peer_id
 
                player = new ServerRemotePlayer(m_env, pos, peer_id, name);
 
-               /*
-                       Add player to environment
-               */
-
+               /* Add player to environment */
                m_env->addPlayer(player);
 
-               /*
-                       Add stuff to inventory
-               */
-               
+               /* Run scripts */
+               ServerRemotePlayer *srp = (ServerRemotePlayer*)player;
+               scriptapi_on_newplayer(m_lua, srp);
+
+               /* Add stuff to inventory */
                if(g_settings->getBool("creative_mode"))
                {
                        // Warning: double code above