Handle death and respawn better
parent
857fe0551c
commit
74febd5c31
|
@ -152,6 +152,7 @@ set(minetest_SRCS
|
||||||
guiInventoryMenu.cpp
|
guiInventoryMenu.cpp
|
||||||
guiPauseMenu.cpp
|
guiPauseMenu.cpp
|
||||||
guiPasswordChange.cpp
|
guiPasswordChange.cpp
|
||||||
|
guiDeathScreen.cpp
|
||||||
client.cpp
|
client.cpp
|
||||||
tile.cpp
|
tile.cpp
|
||||||
game.cpp
|
game.cpp
|
||||||
|
|
|
@ -431,7 +431,7 @@ void Client::step(float dtime)
|
||||||
snprintf((char*)&data[23], PASSWORD_SIZE, "%s", m_password.c_str());
|
snprintf((char*)&data[23], PASSWORD_SIZE, "%s", m_password.c_str());
|
||||||
|
|
||||||
// This should be incremented in each version
|
// This should be incremented in each version
|
||||||
writeU16(&data[51], 2);
|
writeU16(&data[51], 3);
|
||||||
|
|
||||||
// Send as unreliable
|
// Send as unreliable
|
||||||
Send(0, data, false);
|
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
|
else
|
||||||
{
|
{
|
||||||
dout_client<<DTIME<<"WARNING: Client: Ignoring unknown command "
|
dout_client<<DTIME<<"WARNING: Client: Ignoring unknown command "
|
||||||
|
@ -1712,6 +1728,20 @@ void Client::sendDamage(u8 damage)
|
||||||
Send(0, data, true);
|
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()
|
void Client::sendPlayerPos()
|
||||||
{
|
{
|
||||||
//JMutexAutoLock envlock(m_env_mutex); //bulk comment-out
|
//JMutexAutoLock envlock(m_env_mutex); //bulk comment-out
|
||||||
|
|
10
src/client.h
10
src/client.h
|
@ -113,7 +113,8 @@ enum ClientEventType
|
||||||
{
|
{
|
||||||
CE_NONE,
|
CE_NONE,
|
||||||
CE_PLAYER_DAMAGE,
|
CE_PLAYER_DAMAGE,
|
||||||
CE_PLAYER_FORCE_MOVE
|
CE_PLAYER_FORCE_MOVE,
|
||||||
|
CE_DEATHSCREEN,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ClientEvent
|
struct ClientEvent
|
||||||
|
@ -129,6 +130,12 @@ struct ClientEvent
|
||||||
f32 pitch;
|
f32 pitch;
|
||||||
f32 yaw;
|
f32 yaw;
|
||||||
} player_force_move;
|
} 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,
|
void sendChangePassword(const std::wstring oldpassword,
|
||||||
const std::wstring newpassword);
|
const std::wstring newpassword);
|
||||||
void sendDamage(u8 damage);
|
void sendDamage(u8 damage);
|
||||||
|
void sendRespawn();
|
||||||
|
|
||||||
// locks envlock
|
// locks envlock
|
||||||
void removeNode(v3s16 p);
|
void removeNode(v3s16 p);
|
||||||
|
|
|
@ -172,6 +172,13 @@ enum ToClientCommand
|
||||||
string serialized item
|
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
|
enum ToServerCommand
|
||||||
|
@ -321,6 +328,10 @@ enum ToServerCommand
|
||||||
[2] u16 item
|
[2] u16 item
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
TOSERVER_RESPAWN=0x38,
|
||||||
|
/*
|
||||||
|
u16 TOSERVER_RESPAWN
|
||||||
|
*/
|
||||||
};
|
};
|
||||||
|
|
||||||
inline SharedBuffer<u8> makePacket_TOCLIENT_TIME_OF_DAY(u16 time)
|
inline SharedBuffer<u8> makePacket_TOCLIENT_TIME_OF_DAY(u16 time)
|
||||||
|
|
109
src/game.cpp
109
src/game.cpp
|
@ -30,6 +30,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
#include "guiPasswordChange.h"
|
#include "guiPasswordChange.h"
|
||||||
#include "guiInventoryMenu.h"
|
#include "guiInventoryMenu.h"
|
||||||
#include "guiTextInputMenu.h"
|
#include "guiTextInputMenu.h"
|
||||||
|
#include "guiDeathScreen.h"
|
||||||
#include "materials.h"
|
#include "materials.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "clouds.h"
|
#include "clouds.h"
|
||||||
|
@ -39,6 +40,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
#include "settings.h"
|
#include "settings.h"
|
||||||
#include "profiler.h"
|
#include "profiler.h"
|
||||||
#include "mainmenumanager.h"
|
#include "mainmenumanager.h"
|
||||||
|
#include "gettext.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
TODO: Move content-aware stuff to separate file by adding properties
|
TODO: Move content-aware stuff to separate file by adding properties
|
||||||
|
@ -129,6 +131,26 @@ struct TextDestSignNode : public TextDest
|
||||||
Client *m_client;
|
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
|
Hotbar draw routine
|
||||||
*/
|
*/
|
||||||
|
@ -916,6 +938,8 @@ void the_game(
|
||||||
|
|
||||||
bool invert_mouse = g_settings->getBool("invert_mouse");
|
bool invert_mouse = g_settings->getBool("invert_mouse");
|
||||||
|
|
||||||
|
bool respawn_menu_active = false;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Main loop
|
Main loop
|
||||||
*/
|
*/
|
||||||
|
@ -1388,9 +1412,24 @@ void the_game(
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Player speed control
|
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_up,
|
||||||
bool a_down,
|
bool a_down,
|
||||||
|
@ -1435,24 +1474,56 @@ void the_game(
|
||||||
//client.step(dtime_avg1);
|
//client.step(dtime_avg1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read client events
|
|
||||||
for(;;)
|
|
||||||
{
|
{
|
||||||
ClientEvent event = client.getClientEvent();
|
// Read client events
|
||||||
if(event.type == CE_NONE)
|
for(;;)
|
||||||
{
|
{
|
||||||
break;
|
ClientEvent event = client.getClientEvent();
|
||||||
}
|
if(event.type == CE_NONE)
|
||||||
else if(event.type == CE_PLAYER_DAMAGE)
|
{
|
||||||
{
|
break;
|
||||||
//u16 damage = event.player_damage.amount;
|
}
|
||||||
//dstream<<"Player damage: "<<damage<<std::endl;
|
else if(event.type == CE_PLAYER_DAMAGE)
|
||||||
damage_flash_timer = 0.05;
|
{
|
||||||
}
|
//u16 damage = event.player_damage.amount;
|
||||||
else if(event.type == CE_PLAYER_FORCE_MOVE)
|
//dstream<<"Player damage: "<<damage<<std::endl;
|
||||||
{
|
damage_flash_timer = 0.05;
|
||||||
camera_yaw = event.player_force_move.yaw;
|
if(event.player_damage.amount >= 2){
|
||||||
camera_pitch = event.player_force_move.pitch;
|
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);*/
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1468,14 +1539,10 @@ void the_game(
|
||||||
f32 camera_fov = camera.getFovMax();
|
f32 camera_fov = camera.getFovMax();
|
||||||
|
|
||||||
if(FIELD_OF_VIEW_TEST)
|
if(FIELD_OF_VIEW_TEST)
|
||||||
{
|
|
||||||
client.updateCamera(v3f(0,0,0), v3f(0,0,1), camera_fov);
|
client.updateCamera(v3f(0,0,0), v3f(0,0,1), camera_fov);
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
|
||||||
client.updateCamera(camera_position,
|
client.updateCamera(camera_position,
|
||||||
camera_direction, camera_fov);
|
camera_direction, camera_fov);
|
||||||
}
|
|
||||||
|
|
||||||
//timer2.stop();
|
//timer2.stop();
|
||||||
//TimeTaker //timer3("//timer3");
|
//TimeTaker //timer3("//timer3");
|
||||||
|
|
|
@ -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();
|
||||||
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
154
src/server.cpp
154
src/server.cpp
|
@ -2026,16 +2026,6 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
|
||||||
// Get player
|
// Get player
|
||||||
Player *player = emergePlayer(playername, password, peer_id);
|
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 failed, cancel
|
||||||
if(player == NULL)
|
if(player == NULL)
|
||||||
{
|
{
|
||||||
|
@ -2044,32 +2034,6 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
|
||||||
return;
|
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
|
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
|
// 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;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -3208,33 +3180,18 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
|
||||||
}
|
}
|
||||||
else if(command == TOSERVER_DAMAGE)
|
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"))
|
if(g_settings->getBool("enable_damage"))
|
||||||
{
|
{
|
||||||
std::string datastring((char*)&data[2], datasize-2);
|
HandlePlayerHP(player, damage);
|
||||||
std::istringstream is(datastring, std::ios_base::binary);
|
}
|
||||||
u8 damage = readU8(is);
|
else
|
||||||
if(player->hp > damage)
|
{
|
||||||
{
|
SendPlayerHP(player);
|
||||||
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
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SendPlayerHP(player);
|
|
||||||
}
|
}
|
||||||
else if(command == TOSERVER_PASSWORD)
|
else if(command == TOSERVER_PASSWORD)
|
||||||
{
|
{
|
||||||
|
@ -3296,7 +3253,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
|
||||||
<<std::endl;
|
<<std::endl;
|
||||||
SendChatMessage(peer_id, L"Password change successful");
|
SendChatMessage(peer_id, L"Password change successful");
|
||||||
}
|
}
|
||||||
else if (command == TOSERVER_PLAYERITEM)
|
else if(command == TOSERVER_PLAYERITEM)
|
||||||
{
|
{
|
||||||
if (datasize < 2+2)
|
if (datasize < 2+2)
|
||||||
return;
|
return;
|
||||||
|
@ -3305,6 +3262,13 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
|
||||||
player->wieldItem(item);
|
player->wieldItem(item);
|
||||||
SendWieldedItem(player);
|
SendWieldedItem(player);
|
||||||
}
|
}
|
||||||
|
else if(command == TOSERVER_RESPAWN)
|
||||||
|
{
|
||||||
|
if(player->hp != 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
RespawnPlayer(player);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
derr_server<<"WARNING: Server::ProcessData(): Ignoring "
|
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);
|
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
|
Non-static send methods
|
||||||
*/
|
*/
|
||||||
|
@ -3955,6 +3936,51 @@ void Server::SendBlocks(float dtime)
|
||||||
Something random
|
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)
|
void Server::UpdateCrafting(u16 peer_id)
|
||||||
{
|
{
|
||||||
DSTACK(__FUNCTION_NAME);
|
DSTACK(__FUNCTION_NAME);
|
||||||
|
|
|
@ -488,6 +488,8 @@ private:
|
||||||
static void SendHP(con::Connection &con, u16 peer_id, u8 hp);
|
static void SendHP(con::Connection &con, u16 peer_id, u8 hp);
|
||||||
static void SendAccessDenied(con::Connection &con, u16 peer_id,
|
static void SendAccessDenied(con::Connection &con, u16 peer_id,
|
||||||
const std::wstring &reason);
|
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
|
Non-static send methods
|
||||||
|
@ -526,6 +528,9 @@ private:
|
||||||
Something random
|
Something random
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
void HandlePlayerHP(Player *player, s16 damage);
|
||||||
|
void RespawnPlayer(Player *player);
|
||||||
|
|
||||||
void UpdateCrafting(u16 peer_id);
|
void UpdateCrafting(u16 peer_id);
|
||||||
|
|
||||||
// When called, connection mutex should be locked
|
// When called, connection mutex should be locked
|
||||||
|
|
Loading…
Reference in New Issue