Lua API: on_respawnplayer doesn't work

User avatar
sfan5
Member
 
Posts: 3636
Joined: Wed Aug 24, 2011 09:44
GitHub: sfan5
IRC: sfan5

Lua API: on_respawnplayer doesn't work

by sfan5 » Sat Jan 14, 2012 09:10

I'm trying to make a Fixed-Spawn Mod, but on_respawnplayer always gets called with nil.
My Code:
Your phone or window isn't wide enough to display the code box. If it's a phone, try rotating it to landscape mode.
Code: Select all
local function readspawn()
    local inp = io.open(minetest.get_modpath('fixed_spawn')..'/spawn')
    local x = inp:read("*n")
    if x == nil then
        io.close(inp)
        return {x = 0,y = 0,z = 0}
    end
    local y = inp:read("*n")
    local z = inp:read("*n")
    io.close(inp)
    return {x = x,y = y,z = z}
end

minetest.register_on_newplayer(function(player)
    if player ~= nil then
        player:setpos(readspawn())
        return true
    end
    return false
end)
minetest.register_on_respawnplayer(function(player)
    print(dump(player))
    if player ~= nil then
        player:setpos(readspawn())
        return true
    end
    return false
end)
Mods: Mesecons | WorldEdit | Nuke
Minetest builds for Windows (32-bit & 64-bit)
 

User avatar
IPushButton2653
Member
 
Posts: 666
Joined: Wed Nov 16, 2011 22:47

by IPushButton2653 » Sat Jan 14, 2012 20:58

I think someone already did that. I kept respawning at the same place on his server..........i forgot who though..
 

User avatar
redcrab
Member
 
Posts: 831
Joined: Tue Dec 13, 2011 13:45

by redcrab » Sat Jan 14, 2012 23:25

got same issue.
0.4 for serious builder click here
Dedicated Minetest redcrab server forum at http://minetestbb.suret.net

It's nice to be important but it is more important to be nice.
 

randomproof
Member
 
Posts: 214
Joined: Thu Nov 17, 2011 06:31

by randomproof » Sun Jan 15, 2012 05:15

I tried your code on my computer and it works fine. 'player' is not nil for me.

Edit1: The first time I cut and pasted just the "register_on_respawnplayer" function and it worked. Now that I copied all of the code it doesn't.

Edit2: Make readspawn() not local and try again. I don't know why that would make player nil, but you can't call a local function from another function like that.
Last edited by randomproof on Sun Jan 15, 2012 05:37, edited 1 time in total.
 

kahrl
Member
 
Posts: 236
Joined: Fri Sep 02, 2011 07:51

by kahrl » Sun Jan 15, 2012 06:46

I don't think it has anything to do with "local".

I suspect there are some weird issues with active objects going on here. When a player dies, its m_remove flag is set to true, so the environment might remove it. When respawning, the player gets a new ID but that isn't properly registered on the Lua side... or something strange like that. (Disclaimer; I haven't actually read the code so all of that might be wrong.)
 

User avatar
sfan5
Member
 
Posts: 3636
Joined: Wed Aug 24, 2011 09:44
GitHub: sfan5
IRC: sfan5

by sfan5 » Sun Jan 15, 2012 08:55

randomproof wrote:I tried your code on my computer and it works fine. 'player' is not nil for me.

Edit1: The first time I cut and pasted just the "register_on_respawnplayer" function and it worked. Now that I copied all of the code it doesn't.

Edit2: Make readspawn() not local and try again. I don't know why that would make player nil, but you can't call a local function from another function like that.

Doesn't help
Mods: Mesecons | WorldEdit | Nuke
Minetest builds for Windows (32-bit & 64-bit)
 

randomproof
Member
 
Posts: 214
Joined: Thu Nov 17, 2011 06:31

by randomproof » Thu Jan 19, 2012 15:31

Added some debug code to the function involved and found that the player is being removed from "object_refs" before the on_respawn code is run.

Your phone or window isn't wide enough to display the code box. If it's a phone, try rotating it to landscape mode.
Code: Select all
07:25:19: ACTION[ServerThread]: Steven5 damaged by 34 hp at (-25.045,15.942,29.322)
07:25:19: INFO[ServerThread]: Server::HandlePlayerHP(): Player Steven5 dies
07:25:19: INFO[ServerThread]: Server: Sent object remove/add: 1 removed, 0 added, packet size is 8     <---Here
07:25:19: INFO[main]: ClientEnvironment::removeActiveObject(): id=1      <--- And here
07:25:20: INFO[ServerThread]: Server::RespawnPlayer(): Player Steven5 respawns
07:25:20: ACTION[ServerThread]: Server::RespawnPlayer(): srp != NULL
07:25:20: ACTION[ServerThread]: scriptapi_on_respawnplayer(): player != NULL  id=1     <---See, same id that was removed


I'll look some more for a code, now that I know what functions are involved.
 

User avatar
sfan5
Member
 
Posts: 3636
Joined: Wed Aug 24, 2011 09:44
GitHub: sfan5
IRC: sfan5

by sfan5 » Thu Jan 19, 2012 15:49

randomproof wrote:Added some debug code to the function involved and found that the player is being removed from "object_refs" before the on_respawn code is run.

Your phone or window isn't wide enough to display the code box. If it's a phone, try rotating it to landscape mode.
Code: Select all
07:25:19: ACTION[ServerThread]: Steven5 damaged by 34 hp at (-25.045,15.942,29.322)
07:25:19: INFO[ServerThread]: Server::HandlePlayerHP(): Player Steven5 dies
07:25:19: INFO[ServerThread]: Server: Sent object remove/add: 1 removed, 0 added, packet size is 8     <---Here
07:25:19: INFO[main]: ClientEnvironment::removeActiveObject(): id=1      <--- And here
07:25:20: INFO[ServerThread]: Server::RespawnPlayer(): Player Steven5 respawns
07:25:20: ACTION[ServerThread]: Server::RespawnPlayer(): srp != NULL
07:25:20: ACTION[ServerThread]: scriptapi_on_respawnplayer(): player != NULL  id=1     <---See, same id that was removed


I'll look some more for a code, now that I know what functions are involved.

Can you make a Patch which fixed this?
Last edited by sfan5 on Thu Jan 19, 2012 15:49, edited 1 time in total.
Mods: Mesecons | WorldEdit | Nuke
Minetest builds for Windows (32-bit & 64-bit)
 

randomproof
Member
 
Posts: 214
Joined: Thu Nov 17, 2011 06:31

by randomproof » Thu Jan 19, 2012 15:50

Here I found the problem:

function: void Server::HandlePlayerHP(Player *player, s16 damage)
Your phone or window isn't wide enough to display the code box. If it's a phone, try rotating it to landscape mode.
Code: Select all
    // Trigger scripted stuff
    scriptapi_on_dieplayer(m_lua, srp);
   
    // Handle players that are not connected
    if(player->peer_id == PEER_ID_INEXISTENT){
        RespawnPlayer(player);
        return;
    }

    SendPlayerHP(player);
   
    RemoteClient *client = getClient(player->peer_id);
    if(client->net_proto_version >= 3)
    {
        SendDeathscreen(m_con, player->peer_id, false, v3f(0,0,0));
        srp->m_removed = true;            <--  HERE
        srp->m_respawn_active = true;
    }
    else
    {
        RespawnPlayer(player);
    }
}

m_removed is set to 'true' here. On the next server:step the object ref is deleted from LUA. I think this is to remove a players character from the environment so other players can't see him anymore. So the problem is that 'void Server::RespawnPlayer(Player *player)' is called before the player ref is re-added to LUA.
 

randomproof
Member
 
Posts: 214
Joined: Thu Nov 17, 2011 06:31

by randomproof » Thu Jan 19, 2012 15:55

sfan5 wrote:Can you make a Patch which fixed this?

I'm working on it. I think you could just comment out the "srp->m_removed = true;" line.
The other option is to find where the player obj is added back into LUA and make sure that happens before on_respawn is called.
Last edited by randomproof on Thu Jan 19, 2012 15:56, edited 1 time in total.
 

randomproof
Member
 
Posts: 214
Joined: Thu Nov 17, 2011 06:31

by randomproof » Thu Jan 19, 2012 16:08

Ok, here is what I think needs to be changed:
Your phone or window isn't wide enough to display the code box. If it's a phone, try rotating it to landscape mode.
Code: Select all
diff --git a/src/server.cpp b/src/server.cpp
index d704bf8..92f8815 100644
--- a/src/server.cpp
+++ b/src/server.cpp
@@ -1291,6 +1291,11 @@ void Server::AsyncRunStep()
                 player->m_removed = false;
                 player->setId(0);
                 m_env->addActiveObject(player);
+                 if (player->hp == 0)
+                 {
+                                 RespawnPlayer(player);
+                                 
+                                actionstream<<player->getName()<<" respawns at "
+                              <<PP(player->getPosition()/BS)<<std::endl;
+                }

             }
         }
     }
@@ -2819,10 +2824,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
         
         srp->m_respawn_active = false;
 
-        RespawnPlayer(player);
         
-        actionstream<<player->getName()<<" respawns at "
-                <<PP(player->getPosition()/BS)<<std::endl;
 
         // ActiveObject is added to environment in AsyncRunStep after
         // the previous addition has been succesfully removed
@@ -4520,7 +4524,7 @@ void Server::HandlePlayerHP(Player *player, s16 damage)
 {
     ServerRemotePlayer *srp = static_cast<ServerRemotePlayer*>(player);
 
-    if(srp->m_respawn_active)
+    if(srp->m_respawn_active || !srp->m_is_in_environment)
         return;
     
     if(player->hp > damage)


This moves the call to RespawnPlayer to after the player's obj ref is added back into the environment. I'll start testing this and get back to you in a few if it seems to work.

EDIT1: Nope. One minute.
EDIT2: OK. I think this works. Someone try it and tell me if it is good.
Last edited by randomproof on Fri Jan 20, 2012 20:37, edited 1 time in total.
 

randomproof
Member
 
Posts: 214
Joined: Thu Nov 17, 2011 06:31

by randomproof » Fri Jan 20, 2012 20:20

Hmm, noticed that my changes are causing you to be "respawned" when you login instead of being placed where you were when you logout.

EDIT: Ok, fixed it.
Last edited by randomproof on Fri Jan 20, 2012 20:38, edited 1 time in total.
 


Return to Minetest Engine

Who is online

Users browsing this forum: No registered users and 4 guests

cron