Handle death and respawn better
authorPerttu Ahola <celeron55@gmail.com>
Sat, 15 Oct 2011 11:46:59 +0000 (14:46 +0300)
committerPerttu Ahola <celeron55@gmail.com>
Sat, 15 Oct 2011 11:46:59 +0000 (14:46 +0300)
src/CMakeLists.txt
src/client.cpp
src/client.h
src/clientserver.h
src/game.cpp
src/guiDeathScreen.cpp [new file with mode: 0644]
src/guiDeathScreen.h [new file with mode: 0644]
src/server.cpp
src/server.h

index ab50394f7270850718d439980b19d7a643615e8b..019f5ad7b135b85646b939a3fa3b41899b745885 100644 (file)
@@ -152,6 +152,7 @@ set(minetest_SRCS
        guiInventoryMenu.cpp
        guiPauseMenu.cpp
        guiPasswordChange.cpp
+       guiDeathScreen.cpp
        client.cpp
        tile.cpp
        game.cpp
index c54bf34ce58ad2dde046cd4a6b3fa77d30d90d7e..1af91703ea63c1281696b5e29dced0e709cf802d 100644 (file)
@@ -431,7 +431,7 @@ void Client::step(float dtime)
                        snprintf((char*)&data[23], PASSWORD_SIZE, "%s", m_password.c_str());
                        
                        // This should be incremented in each version
-                       writeU16(&data[51], 2);
+                       writeU16(&data[51], 3);
 
                        // Send as unreliable
                        Send(0, data, false);
@@ -1477,6 +1477,22 @@ void Client::ProcessData(u8 *data, u32 datasize, u16 sender_peer_id)
                        }
                }
        }
+       else if(command == TOCLIENT_DEATHSCREEN)
+       {
+               std::string datastring((char*)&data[2], datasize-2);
+               std::istringstream is(datastring, std::ios_base::binary);
+               
+               bool set_camera_point_target = readU8(is);
+               v3f camera_point_target = readV3F1000(is);
+               
+               ClientEvent event;
+               event.type = CE_DEATHSCREEN;
+               event.deathscreen.set_camera_point_target = set_camera_point_target;
+               event.deathscreen.camera_point_target_x = camera_point_target.X;
+               event.deathscreen.camera_point_target_y = camera_point_target.Y;
+               event.deathscreen.camera_point_target_z = camera_point_target.Z;
+               m_client_event_queue.push_back(event);
+       }
        else
        {
                dout_client<<DTIME<<"WARNING: Client: Ignoring unknown command "
@@ -1712,6 +1728,20 @@ void Client::sendDamage(u8 damage)
        Send(0, data, true);
 }
 
+void Client::sendRespawn()
+{
+       DSTACK(__FUNCTION_NAME);
+       std::ostringstream os(std::ios_base::binary);
+
+       writeU16(os, TOSERVER_RESPAWN);
+
+       // Make data buffer
+       std::string s = os.str();
+       SharedBuffer<u8> data((u8*)s.c_str(), s.size());
+       // Send as reliable
+       Send(0, data, true);
+}
+
 void Client::sendPlayerPos()
 {
        //JMutexAutoLock envlock(m_env_mutex); //bulk comment-out
index 85e85dcd64014b123849867111731b6b9d39f9d0..07ac930c912b714d0f590ce03cbb256be8bdb434 100644 (file)
@@ -113,7 +113,8 @@ enum ClientEventType
 {
        CE_NONE,
        CE_PLAYER_DAMAGE,
-       CE_PLAYER_FORCE_MOVE
+       CE_PLAYER_FORCE_MOVE,
+       CE_DEATHSCREEN,
 };
 
 struct ClientEvent
@@ -129,6 +130,12 @@ struct ClientEvent
                        f32 pitch;
                        f32 yaw;
                } player_force_move;
+               struct{
+                       bool set_camera_point_target;
+                       f32 camera_point_target_x;
+                       f32 camera_point_target_y;
+                       f32 camera_point_target_z;
+               } deathscreen;
        };
 };
 
@@ -191,6 +198,7 @@ public:
        void sendChangePassword(const std::wstring oldpassword,
                const std::wstring newpassword);
        void sendDamage(u8 damage);
+       void sendRespawn();
        
        // locks envlock
        void removeNode(v3s16 p);
index 9d319275488725b10e1ba7b3a3c1af50812d2290..b96cc61aa15421a150494e212ab10f8842762a35 100644 (file)
@@ -172,6 +172,13 @@ enum ToClientCommand
                        string serialized item
                }
        */
+
+       TOCLIENT_DEATHSCREEN = 0x37,
+       /*
+               u16 command
+               u8 bool set camera point target
+               v3f1000 camera point target (to point the death cause or whatever)
+       */
 };
 
 enum ToServerCommand
@@ -320,7 +327,11 @@ enum ToServerCommand
                [0] u16 TOSERVER_PLAYERITEM
                [2] u16 item
        */
-
+       
+       TOSERVER_RESPAWN=0x38,
+       /*
+               u16 TOSERVER_RESPAWN
+       */
 };
 
 inline SharedBuffer<u8> makePacket_TOCLIENT_TIME_OF_DAY(u16 time)
index 926a169774f2a82c5a088c2fc84a6248a966423e..16cbb463720cfe608f6e24b0f2827abed298e5de 100644 (file)
@@ -30,6 +30,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "guiPasswordChange.h"
 #include "guiInventoryMenu.h"
 #include "guiTextInputMenu.h"
+#include "guiDeathScreen.h"
 #include "materials.h"
 #include "config.h"
 #include "clouds.h"
@@ -39,6 +40,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "settings.h"
 #include "profiler.h"
 #include "mainmenumanager.h"
+#include "gettext.h"
 
 /*
        TODO: Move content-aware stuff to separate file by adding properties
@@ -129,6 +131,26 @@ struct TextDestSignNode : public TextDest
        Client *m_client;
 };
 
+/* Respawn menu callback */
+
+class MainRespawnInitiator: public IRespawnInitiator
+{
+public:
+       MainRespawnInitiator(bool *active, Client *client):
+               m_active(active), m_client(client)
+       {
+               *m_active = true;
+       }
+       void respawn()
+       {
+               *m_active = false;
+               m_client->sendRespawn();
+       }
+private:
+       bool *m_active;
+       Client *m_client;
+};
+
 /*
        Hotbar draw routine
 */
@@ -916,6 +938,8 @@ void the_game(
        
        bool invert_mouse = g_settings->getBool("invert_mouse");
 
+       bool respawn_menu_active = false;
+
        /*
                Main loop
        */
@@ -1388,9 +1412,24 @@ void the_game(
 
                /*
                        Player speed control
-                       TODO: Cache the keycodes from getKeySetting
                */
                
+               if(!noMenuActive() || !device->isWindowActive())
+               {
+                       PlayerControl control(
+                               false,
+                               false,
+                               false,
+                               false,
+                               false,
+                               false,
+                               false,
+                               camera_pitch,
+                               camera_yaw
+                       );
+                       client.setPlayerControl(control);
+               }
+               else
                {
                        /*bool a_up,
                        bool a_down,
@@ -1435,24 +1474,56 @@ void the_game(
                        //client.step(dtime_avg1);
                }
 
-               // Read client events
-               for(;;)
                {
-                       ClientEvent event = client.getClientEvent();
-                       if(event.type == CE_NONE)
-                       {
-                               break;
-                       }
-                       else if(event.type == CE_PLAYER_DAMAGE)
+                       // Read client events
+                       for(;;)
                        {
-                               //u16 damage = event.player_damage.amount;
-                               //dstream<<"Player damage: "<<damage<<std::endl;
-                               damage_flash_timer = 0.05;
-                       }
-                       else if(event.type == CE_PLAYER_FORCE_MOVE)
-                       {
-                               camera_yaw = event.player_force_move.yaw;
-                               camera_pitch = event.player_force_move.pitch;
+                               ClientEvent event = client.getClientEvent();
+                               if(event.type == CE_NONE)
+                               {
+                                       break;
+                               }
+                               else if(event.type == CE_PLAYER_DAMAGE)
+                               {
+                                       //u16 damage = event.player_damage.amount;
+                                       //dstream<<"Player damage: "<<damage<<std::endl;
+                                       damage_flash_timer = 0.05;
+                                       if(event.player_damage.amount >= 2){
+                                               damage_flash_timer += 0.05 * event.player_damage.amount;
+                                       }
+                               }
+                               else if(event.type == CE_PLAYER_FORCE_MOVE)
+                               {
+                                       camera_yaw = event.player_force_move.yaw;
+                                       camera_pitch = event.player_force_move.pitch;
+                               }
+                               else if(event.type == CE_DEATHSCREEN)
+                               {
+                                       if(respawn_menu_active)
+                                               continue;
+
+                                       /*bool set_camera_point_target =
+                                                       event.deathscreen.set_camera_point_target;
+                                       v3f camera_point_target;
+                                       camera_point_target.X = event.deathscreen.camera_point_target_x;
+                                       camera_point_target.Y = event.deathscreen.camera_point_target_y;
+                                       camera_point_target.Z = event.deathscreen.camera_point_target_z;*/
+                                       MainRespawnInitiator *respawner =
+                                                       new MainRespawnInitiator(
+                                                                       &respawn_menu_active, &client);
+                                       GUIDeathScreen *menu =
+                                                       new GUIDeathScreen(guienv, guiroot, -1, 
+                                                               &g_menumgr, respawner);
+                                       menu->drop();
+                                       
+                                       /* Handle visualization */
+
+                                       damage_flash_timer = 0;
+
+                                       /*LocalPlayer* player = client.getLocalPlayer();
+                                       player->setPosition(player->getPosition() + v3f(0,-BS,0));
+                                       camera.update(player, busytime, screensize);*/
+                               }
                        }
                }
                
@@ -1466,16 +1537,12 @@ void the_game(
                v3f camera_position = camera.getPosition();
                v3f camera_direction = camera.getDirection();
                f32 camera_fov = camera.getFovMax();
-
+               
                if(FIELD_OF_VIEW_TEST)
-               {
                        client.updateCamera(v3f(0,0,0), v3f(0,0,1), camera_fov);
-               }
                else
-               {
                        client.updateCamera(camera_position,
                                camera_direction, camera_fov);
-               }
 
                //timer2.stop();
                //TimeTaker //timer3("//timer3");
diff --git a/src/guiDeathScreen.cpp b/src/guiDeathScreen.cpp
new file mode 100644 (file)
index 0000000..7a84126
--- /dev/null
@@ -0,0 +1,179 @@
+/*
+Minetest-c55
+Copyright (C) 2011 celeron55, Perttu Ahola <celeron55@gmail.com>
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#include "guiDeathScreen.h"
+#include "debug.h"
+#include "serialization.h"
+#include <string>
+#include <IGUICheckBox.h>
+#include <IGUIEditBox.h>
+#include <IGUIButton.h>
+#include <IGUIStaticText.h>
+#include <IGUIFont.h>
+#include "gettext.h"
+#include "client.h"
+
+GUIDeathScreen::GUIDeathScreen(gui::IGUIEnvironment* env,
+               gui::IGUIElement* parent, s32 id,
+               IMenuManager *menumgr, IRespawnInitiator *respawner
+):
+       GUIModalMenu(env, parent, id, menumgr),
+       m_respawner(respawner),
+       m_screensize(1,1)
+{
+}
+
+GUIDeathScreen::~GUIDeathScreen()
+{
+       removeChildren();
+       delete m_respawner;
+}
+
+void GUIDeathScreen::removeChildren()
+{
+       const core::list<gui::IGUIElement*> &children = getChildren();
+       core::list<gui::IGUIElement*> children_copy;
+       for(core::list<gui::IGUIElement*>::ConstIterator
+                       i = children.begin(); i != children.end(); i++)
+       {
+               children_copy.push_back(*i);
+       }
+       for(core::list<gui::IGUIElement*>::Iterator
+                       i = children_copy.begin();
+                       i != children_copy.end(); i++)
+       {
+               (*i)->remove();
+       }
+}
+
+void GUIDeathScreen::regenerateGui(v2u32 screensize)
+{
+       m_screensize = screensize;
+
+       /*
+               Remove stuff
+       */
+       removeChildren();
+       
+       /*
+               Calculate new sizes and positions
+       */
+       core::rect<s32> rect(
+                       screensize.X/2 - 500/2,
+                       screensize.Y/2 - 200/2,
+                       screensize.X/2 + 500/2,
+                       screensize.Y/2 + 200/2
+       );
+       
+       DesiredRect = rect;
+       recalculateAbsolutePosition(false);
+
+       v2s32 size = rect.getSize();
+
+       /*
+               Add stuff
+       */
+       changeCtype("");
+       {
+               core::rect<s32> rect(0, 0, 400, 50);
+               rect = rect + v2s32(size.X/2-400/2, size.Y/2-50/2-25);
+               Environment->addStaticText(wgettext("You died."), rect, false,
+                               true, this, 256);
+       }
+       {
+               core::rect<s32> rect(0, 0, 140, 30);
+               rect = rect + v2s32(size.X/2-140/2, size.Y/2-30/2+25);
+               gui::IGUIElement *e = 
+               Environment->addButton(rect, this, 257,
+                       wgettext("Respawn"));
+               Environment->setFocus(e);
+       }
+       changeCtype("C");
+}
+
+void GUIDeathScreen::drawMenu()
+{
+       gui::IGUISkin* skin = Environment->getSkin();
+       if (!skin)
+               return;
+       video::IVideoDriver* driver = Environment->getVideoDriver();
+       
+       {
+               video::SColor color(180,50,0,0);
+               driver->draw2DRectangle(color,
+                               core::rect<s32>(0,0,m_screensize.X,m_screensize.Y), NULL);
+       }
+       {
+               video::SColor bgcolor(50,0,0,0);
+               driver->draw2DRectangle(bgcolor, AbsoluteRect, &AbsoluteClippingRect);
+       }
+
+       gui::IGUIElement::draw();
+}
+
+bool GUIDeathScreen::OnEvent(const SEvent& event)
+{
+       if(event.EventType==EET_KEY_INPUT_EVENT)
+       {
+               if(event.KeyInput.Key==KEY_ESCAPE && event.KeyInput.PressedDown)
+               {
+                       respawn();
+                       quitMenu();
+                       return true;
+               }
+               if(event.KeyInput.Key==KEY_RETURN && event.KeyInput.PressedDown)
+               {
+                       respawn();
+                       quitMenu();
+                       return true;
+               }
+       }
+       if(event.EventType==EET_GUI_EVENT)
+       {
+               if(event.GUIEvent.EventType==gui::EGET_ELEMENT_FOCUS_LOST
+                               && isVisible())
+               {
+                       if(!canTakeFocus(event.GUIEvent.Element))
+                       {
+                               dstream<<"GUIDeathScreen: Not allowing focus change."
+                                               <<std::endl;
+                               // Returning true disables focus change
+                               return true;
+                       }
+               }
+               if(event.GUIEvent.EventType==gui::EGET_BUTTON_CLICKED)
+               {
+                       switch(event.GUIEvent.Caller->getID())
+                       {
+                       case 257:
+                               respawn();
+                               quitMenu();
+                               return true;
+                       }
+               }
+       }
+
+       return Parent ? Parent->OnEvent(event) : false;
+}
+
+void GUIDeathScreen::respawn()
+{
+       m_respawner->respawn();
+}
+
diff --git a/src/guiDeathScreen.h b/src/guiDeathScreen.h
new file mode 100644 (file)
index 0000000..10a97d7
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+Minetest-c55
+Copyright (C) 2011 celeron55, Perttu Ahola <celeron55@gmail.com>
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#ifndef GUIMESSAGEMENU_HEADER
+#define GUIMESSAGEMENU_HEADER
+
+#include "common_irrlicht.h"
+#include "modalMenu.h"
+#include "utility.h"
+#include <string>
+
+class IRespawnInitiator
+{
+public:
+       virtual void respawn() = 0;
+};
+
+class GUIDeathScreen : public GUIModalMenu
+{
+public:
+       GUIDeathScreen(gui::IGUIEnvironment* env,
+                       gui::IGUIElement* parent, s32 id,
+                       IMenuManager *menumgr, IRespawnInitiator *respawner);
+       ~GUIDeathScreen();
+       
+       void removeChildren();
+       /*
+               Remove and re-add (or reposition) stuff
+       */
+       void regenerateGui(v2u32 screensize);
+
+       void drawMenu();
+
+       bool OnEvent(const SEvent& event);
+
+       void respawn();
+
+private:
+       IRespawnInitiator *m_respawner;
+       v2u32 m_screensize;
+};
+
+#endif
+
index ba4921dd050f9e938e851cc62f03ce4914f4fbe9..59f7477a9e3749ef90056996381f53cde5de2e4c 100644 (file)
@@ -2026,16 +2026,6 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
                // Get player
                Player *player = emergePlayer(playername, password, peer_id);
 
-               /*{
-                       // DEBUG: Test serialization
-                       std::ostringstream test_os;
-                       player->serialize(test_os);
-                       dstream<<"Player serialization test: \""<<test_os.str()
-                                       <<"\""<<std::endl;
-                       std::istringstream test_is(test_os.str());
-                       player->deSerialize(test_is);
-               }*/
-
                // If failed, cancel
                if(player == NULL)
                {
@@ -2044,32 +2034,6 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
                        return;
                }
 
-               /*
-               // If a client is already connected to the player, cancel
-               if(player->peer_id != 0)
-               {
-                       derr_server<<DTIME<<"Server: peer_id="<<peer_id
-                                       <<" tried to connect to "
-                                       "an already connected player (peer_id="
-                                       <<player->peer_id<<")"<<std::endl;
-                       return;
-               }
-               // Set client of player
-               player->peer_id = peer_id;
-               */
-
-               // Check if player doesn't exist
-               if(player == NULL)
-                       throw con::InvalidIncomingDataException
-                               ("Server::ProcessData(): INIT: Player doesn't exist");
-
-               /*// update name if it was supplied
-               if(datasize >= 20+3)
-               {
-                       data[20+3-1] = 0;
-                       player->updateName((const char*)&data[3]);
-               }*/
-               
                /*
                        Answer with a TOCLIENT_INIT
                */
@@ -2146,10 +2110,18 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
                }
                
                // Warnings about protocol version can be issued here
-               /*if(getClient(peer->id)->net_proto_version == 0)
+               if(getClient(peer->id)->net_proto_version < 3)
                {
-                       SendChatMessage(peer_id, L"# Server: NOTE: YOUR CLIENT IS OLD AND DOES NOT WORK PROPERLY WITH THIS SERVER");
-               }*/
+                       SendChatMessage(peer_id, L"# Server: WARNING: YOUR CLIENT IS OLD AND DOES NOT WORK PROPERLY WITH THIS SERVER");
+               }
+
+               /*
+                       Check HP, respawn if necessary
+               */
+               {
+                       Player *player = m_env.getPlayer(peer_id);
+                       HandlePlayerHP(player, 0);
+               }
 
                return;
        }
@@ -3208,33 +3180,18 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
        }
        else if(command == TOSERVER_DAMAGE)
        {
+               std::string datastring((char*)&data[2], datasize-2);
+               std::istringstream is(datastring, std::ios_base::binary);
+               u8 damage = readU8(is);
+
                if(g_settings->getBool("enable_damage"))
                {
-                       std::string datastring((char*)&data[2], datasize-2);
-                       std::istringstream is(datastring, std::ios_base::binary);
-                       u8 damage = readU8(is);
-                       if(player->hp > damage)
-                       {
-                               player->hp -= damage;
-                       }
-                       else
-                       {
-                               player->hp = 0;
-
-                               dstream<<"TODO: Server: TOSERVER_HP_DECREMENT: Player dies"
-                                               <<std::endl;
-                               
-                               v3f pos = findSpawnPos(m_env.getServerMap());
-                               player->setPosition(pos);
-                               player->hp = 20;
-                               SendMovePlayer(player);
-                               SendPlayerHP(player);
-                               
-                               //TODO: Throw items around
-                       }
+                       HandlePlayerHP(player, damage);
+               }
+               else
+               {
+                       SendPlayerHP(player);
                }
-
-               SendPlayerHP(player);
        }
        else if(command == TOSERVER_PASSWORD)
        {
@@ -3296,7 +3253,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
                                <<std::endl;
                SendChatMessage(peer_id, L"Password change successful");
        }
-       else if (command == TOSERVER_PLAYERITEM)
+       else if(command == TOSERVER_PLAYERITEM)
        {
                if (datasize < 2+2)
                        return;
@@ -3305,6 +3262,13 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
                player->wieldItem(item);
                SendWieldedItem(player);
        }
+       else if(command == TOSERVER_RESPAWN)
+       {
+               if(player->hp != 0)
+                       return;
+
+               RespawnPlayer(player);
+       }
        else
        {
                derr_server<<"WARNING: Server::ProcessData(): Ignoring "
@@ -3501,6 +3465,23 @@ void Server::SendAccessDenied(con::Connection &con, u16 peer_id,
        con.Send(peer_id, 0, data, true);
 }
 
+void Server::SendDeathscreen(con::Connection &con, u16 peer_id,
+               bool set_camera_point_target, v3f camera_point_target)
+{
+       DSTACK(__FUNCTION_NAME);
+       std::ostringstream os(std::ios_base::binary);
+
+       writeU16(os, TOCLIENT_DEATHSCREEN);
+       writeU8(os, set_camera_point_target);
+       writeV3F1000(os, camera_point_target);
+
+       // Make data buffer
+       std::string s = os.str();
+       SharedBuffer<u8> data((u8*)s.c_str(), s.size());
+       // Send as reliable
+       con.Send(peer_id, 0, data, true);
+}
+
 /*
        Non-static send methods
 */
@@ -3955,6 +3936,51 @@ void Server::SendBlocks(float dtime)
        Something random
 */
 
+void Server::HandlePlayerHP(Player *player, s16 damage)
+{
+       if(player->hp > damage)
+       {
+               player->hp -= damage;
+               SendPlayerHP(player);
+       }
+       else
+       {
+               dstream<<"Server::HandlePlayerHP(): Player "
+                               <<player->getName()<<" dies"<<std::endl;
+               
+               player->hp = 0;
+               
+               //TODO: Throw items around
+               
+               // 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));
+               }
+               else
+               {
+                       RespawnPlayer(player);
+               }
+       }
+}
+
+void Server::RespawnPlayer(Player *player)
+{
+       v3f pos = findSpawnPos(m_env.getServerMap());
+       player->setPosition(pos);
+       player->hp = 20;
+       SendMovePlayer(player);
+       SendPlayerHP(player);
+}
+
 void Server::UpdateCrafting(u16 peer_id)
 {
        DSTACK(__FUNCTION_NAME);
index d51f910682805a6c1e3ba0a76487903aab6e529d..f65bd1957186a9ca9ea1be3b643bfa3b0b36b5c5 100644 (file)
@@ -488,6 +488,8 @@ private:
        static void SendHP(con::Connection &con, u16 peer_id, u8 hp);
        static void SendAccessDenied(con::Connection &con, u16 peer_id,
                        const std::wstring &reason);
+       static void SendDeathscreen(con::Connection &con, u16 peer_id,
+                       bool set_camera_point_target, v3f camera_point_target);
        
        /*
                Non-static send methods
@@ -526,6 +528,9 @@ private:
                Something random
        */
        
+       void HandlePlayerHP(Player *player, s16 damage);
+       void RespawnPlayer(Player *player);
+       
        void UpdateCrafting(u16 peer_id);
        
        // When called, connection mutex should be locked