summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/client.cpp10
-rw-r--r--src/content_cao.cpp35
-rw-r--r--src/environment.cpp19
-rw-r--r--src/player.cpp9
-rw-r--r--src/server.cpp82
-rw-r--r--src/server.h2
-rw-r--r--src/serverremoteplayer.cpp16
-rw-r--r--src/serverremoteplayer.h1
8 files changed, 104 insertions, 70 deletions
diff --git a/src/client.cpp b/src/client.cpp
index 0463aa81c..bc303bc4b 100644
--- a/src/client.cpp
+++ b/src/client.cpp
@@ -1171,8 +1171,18 @@ void Client::ProcessData(u8 *data, u32 datasize, u16 sender_peer_id)
std::istringstream is(datastring, std::ios_base::binary);
Player *player = m_env.getLocalPlayer();
assert(player != NULL);
+ u8 oldhp = player->hp;
u8 hp = readU8(is);
player->hp = hp;
+
+ if(hp < oldhp)
+ {
+ // Add to ClientEvent queue
+ ClientEvent event;
+ event.type = CE_PLAYER_DAMAGE;
+ event.player_damage.amount = oldhp - hp;
+ m_client_event_queue.push_back(event);
+ }
}
else if(command == TOCLIENT_MOVE_PLAYER)
{
diff --git a/src/content_cao.cpp b/src/content_cao.cpp
index a2708674b..3c30a0819 100644
--- a/src/content_cao.cpp
+++ b/src/content_cao.cpp
@@ -2067,6 +2067,7 @@ private:
bool m_is_local_player;
LocalPlayer *m_local_player;
float m_damage_visual_timer;
+ bool m_dead;
public:
PlayerCAO(IGameDef *gamedef, ClientEnvironment *env):
@@ -2078,7 +2079,8 @@ public:
m_yaw(0),
m_is_local_player(false),
m_local_player(NULL),
- m_damage_visual_timer(0)
+ m_damage_visual_timer(0),
+ m_dead(false)
{
if(gamedef == NULL)
ClientActiveObject::registerType(getType(), create);
@@ -2100,6 +2102,8 @@ public:
m_position = readV3F1000(is);
// yaw
m_yaw = readF1000(is);
+ // dead
+ m_dead = readU8(is);
pos_translator.init(m_position);
@@ -2129,6 +2133,8 @@ public:
{
if(m_is_local_player)
return NULL;
+ if(m_dead)
+ return NULL;
return &m_selection_box;
}
v3f getPosition()
@@ -2204,6 +2210,7 @@ public:
m_text->setPosition(v3f(0, (f32)BS*2.1, 0));
updateTextures("");
+ updateVisibility();
updateNodePos();
}
@@ -2221,11 +2228,11 @@ public:
if(m_node == NULL)
return;
- m_node->setVisible(true);
-
u8 li = decode_light(light_at_pos);
video::SColor color(255,li,li,li);
setMeshColor(m_node->getMesh(), color);
+
+ updateVisibility();
}
v3s16 getLightPosition()
@@ -2233,6 +2240,14 @@ public:
return floatToInt(m_position+v3f(0,BS*1.5,0), BS);
}
+ void updateVisibility()
+ {
+ if(m_node == NULL)
+ return;
+
+ m_node->setVisible(!m_dead);
+ }
+
void updateNodePos()
{
if(m_node == NULL)
@@ -2248,6 +2263,7 @@ public:
void step(float dtime, ClientEnvironment *env)
{
pos_translator.translate(dtime);
+ updateVisibility();
updateNodePos();
if(m_damage_visual_timer > 0){
@@ -2279,13 +2295,16 @@ public:
{
// damage
s16 damage = readS16(is);
-
- if(m_is_local_player)
- m_env->damageLocalPlayer(damage, false);
-
- m_damage_visual_timer = 0.5;
+ m_damage_visual_timer = 0.05;
+ if(damage >= 2)
+ m_damage_visual_timer += 0.05 * damage;
updateTextures("^[brighten");
}
+ else if(cmd == 2) // died or respawned
+ {
+ m_dead = readU8(is);
+ updateVisibility();
+ }
}
void updateTextures(const std::string &mod)
diff --git a/src/environment.cpp b/src/environment.cpp
index 7c2aef272..6f1d8ff55 100644
--- a/src/environment.cpp
+++ b/src/environment.cpp
@@ -797,6 +797,8 @@ void ServerEnvironment::clearAllObjects()
i.atEnd()==false; i++)
{
ServerActiveObject* obj = i.getNode()->getValue();
+ if(obj->getType() == ACTIVEOBJECT_TYPE_PLAYER)
+ continue;
u16 id = i.getNode()->getKey();
v3f objectpos = obj->getBasePosition();
// Delete static object if block is loaded
@@ -1983,16 +1985,7 @@ void ClientEnvironment::step(float dtime)
{
f32 damage_f = (info.speed - tolerance)/BS*factor;
u16 damage = (u16)(damage_f+0.5);
- if(lplayer->hp > damage)
- lplayer->hp -= damage;
- else
- lplayer->hp = 0;
-
- ClientEnvEvent event;
- event.type = CEE_PLAYER_DAMAGE;
- event.player_damage.amount = damage;
- event.player_damage.send_to_server = true;
- m_client_event_queue.push_back(event);
+ damageLocalPlayer(damage, true);
}
}
}
@@ -2022,11 +2015,7 @@ void ClientEnvironment::step(float dtime)
if(damage_per_second != 0)
{
- ClientEnvEvent event;
- event.type = CEE_PLAYER_DAMAGE;
- event.player_damage.amount = damage_per_second;
- event.player_damage.send_to_server = true;
- m_client_event_queue.push_back(event);
+ damageLocalPlayer(damage_per_second, true);
}
}
diff --git a/src/player.cpp b/src/player.cpp
index 6506c43c3..068b51790 100644
--- a/src/player.cpp
+++ b/src/player.cpp
@@ -713,14 +713,17 @@ void LocalPlayer::applyControl(float dtime)
}
else if(touching_ground)
{
- v3f speed = getSpeed();
/*
NOTE: The d value in move() affects jump height by
raising the height at which the jump speed is kept
at its starting value
*/
- speed.Y = 6.5*BS;
- setSpeed(speed);
+ v3f speed = getSpeed();
+ if(speed.Y >= -0.5*BS)
+ {
+ speed.Y = 6.5*BS;
+ setSpeed(speed);
+ }
}
// Use the oscillating value for getting out of water
// (so that the player doesn't fly on the surface)
diff --git a/src/server.cpp b/src/server.cpp
index a0c8a0092..bf90b2aa7 100644
--- a/src/server.cpp
+++ b/src/server.cpp
@@ -1270,7 +1270,8 @@ void Server::AsyncRunStep()
/*
Handle player HPs (die if hp=0)
*/
- HandlePlayerHP(player, 0);
+ if(player->hp == 0 && player->m_hp_not_sent)
+ DiePlayer(player);
/*
Send player inventories and HPs if necessary
@@ -1284,9 +1285,9 @@ void Server::AsyncRunStep()
}
/*
- Add to environment if is not in respawn screen
+ Add to environment
*/
- if(!player->m_is_in_environment && !player->m_respawn_active){
+ if(!player->m_is_in_environment){
player->m_removed = false;
player->setId(0);
m_env->addActiveObject(player);
@@ -2129,6 +2130,10 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
// Send HP
SendPlayerHP(player);
+ // Show death screen if necessary
+ if(player->hp == 0)
+ SendDeathscreen(m_con, player->peer_id, false, v3f(0,0,0));
+
// Send time of day
{
SharedBuffer<u8> data = makePacket_TOCLIENT_TIME_OF_DAY(
@@ -2160,11 +2165,6 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
}
/*
- Check HP, respawn if necessary
- */
- HandlePlayerHP(player, 0);
-
- /*
Print out action
*/
{
@@ -2662,16 +2662,25 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
std::istringstream is(datastring, std::ios_base::binary);
u8 damage = readU8(is);
+ ServerRemotePlayer *srp = static_cast<ServerRemotePlayer*>(player);
+
if(g_settings->getBool("enable_damage"))
{
actionstream<<player->getName()<<" damaged by "
<<(int)damage<<" hp at "<<PP(player->getPosition()/BS)
<<std::endl;
-
- HandlePlayerHP(player, damage);
+
+ srp->setHP(srp->getHP() - damage);
+
+ if(srp->getHP() == 0 && srp->m_hp_not_sent)
+ DiePlayer(srp);
+
+ if(srp->m_hp_not_sent)
+ SendPlayerHP(player);
}
else
{
+ // Force send (to correct the client's predicted HP)
SendPlayerHP(player);
}
}
@@ -2751,8 +2760,6 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
if(player->hp != 0)
return;
- srp->m_respawn_active = false;
-
RespawnPlayer(player);
actionstream<<player->getName()<<" respawns at "
@@ -2811,6 +2818,13 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
infostream<<"TOSERVER_INTERACT: action="<<(int)action<<", item="<<item_i<<", pointed="<<pointed.dump()<<std::endl;
+ if(player->hp == 0)
+ {
+ infostream<<"TOSERVER_INTERACT: "<<srp->getName()
+ <<" tried to interact, but is dead!"<<std::endl;
+ return;
+ }
+
v3f player_pos = srp->m_last_good_position;
// Update wielded item
@@ -3968,26 +3982,14 @@ void Server::SendTexturesRequested(u16 peer_id,core::list<TextureRequest> tosend
Something random
*/
-void Server::HandlePlayerHP(Player *player, s16 damage)
+void Server::DiePlayer(Player *player)
{
ServerRemotePlayer *srp = static_cast<ServerRemotePlayer*>(player);
- if(srp->m_respawn_active)
- return;
-
- if(player->hp > damage)
- {
- if(damage != 0){
- player->hp -= damage;
- SendPlayerHP(player);
- }
- return;
- }
-
- infostream<<"Server::HandlePlayerHP(): Player "
+ infostream<<"Server::DiePlayer(): Player "
<<player->getName()<<" dies"<<std::endl;
- player->hp = 0;
+ srp->setHP(0);
// Trigger scripted stuff
scriptapi_on_dieplayer(m_lua, srp);
@@ -3999,24 +4001,13 @@ void Server::HandlePlayerHP(Player *player, s16 damage)
}
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;
- srp->m_respawn_active = true;
- }
- else
- {
- RespawnPlayer(player);
- }
+ SendDeathscreen(m_con, player->peer_id, false, v3f(0,0,0));
}
void Server::RespawnPlayer(Player *player)
{
- player->hp = 20;
ServerRemotePlayer *srp = static_cast<ServerRemotePlayer*>(player);
+ srp->setHP(20);
bool repositioned = scriptapi_on_respawnplayer(m_lua, srp);
if(!repositioned){
v3f pos = findSpawnPos(m_env->getServerMap());
@@ -4268,6 +4259,14 @@ ServerRemotePlayer *Server::emergePlayer(const char *name, u16 peer_id)
// Got one.
player->peer_id = peer_id;
+ // Re-add player to environment
+ if(player->m_removed)
+ {
+ player->m_removed = false;
+ player->setId(0);
+ m_env->addActiveObject(player);
+ }
+
// Reset inventory to creative if in creative mode
if(g_settings->getBool("creative_mode"))
{
@@ -4305,12 +4304,13 @@ ServerRemotePlayer *Server::emergePlayer(const char *name, u16 peer_id)
v3f pos = findSpawnPos(m_env->getServerMap());
player = new ServerRemotePlayer(m_env, pos, peer_id, name);
+ ServerRemotePlayer *srp = static_cast<ServerRemotePlayer*>(player);
/* Add player to environment */
m_env->addPlayer(player);
+ m_env->addActiveObject(srp);
/* Run scripts */
- ServerRemotePlayer *srp = static_cast<ServerRemotePlayer*>(player);
scriptapi_on_newplayer(m_lua, srp);
/* Add stuff to inventory */
diff --git a/src/server.h b/src/server.h
index 4fdb60065..40f0fe582 100644
--- a/src/server.h
+++ b/src/server.h
@@ -592,7 +592,7 @@ private:
Something random
*/
- void HandlePlayerHP(Player *player, s16 damage);
+ void DiePlayer(Player *player);
void RespawnPlayer(Player *player);
void UpdateCrafting(u16 peer_id);
diff --git a/src/serverremoteplayer.cpp b/src/serverremoteplayer.cpp
index b4dbbdb1b..728ffe026 100644
--- a/src/serverremoteplayer.cpp
+++ b/src/serverremoteplayer.cpp
@@ -34,7 +34,6 @@ ServerRemotePlayer::ServerRemotePlayer(ServerEnvironment *env):
m_wield_index(0),
m_inventory_not_sent(false),
m_hp_not_sent(false),
- m_respawn_active(false),
m_is_in_environment(false),
m_time_from_last_punch(0),
m_position_not_sent(false)
@@ -159,6 +158,8 @@ std::string ServerRemotePlayer::getClientInitializationData()
writeV3F1000(os, getPosition());
// yaw
writeF1000(os, getYaw());
+ // dead
+ writeU8(os, getHP() == 0);
return os.str();
}
@@ -247,6 +248,19 @@ void ServerRemotePlayer::setHP(s16 hp_)
if(hp != oldhp)
m_hp_not_sent = true;
+
+ // On death or reincarnation send an active object message
+ if((hp == 0) != (oldhp == 0))
+ {
+ std::ostringstream os(std::ios::binary);
+ // command (2 = update death state)
+ writeU8(os, 2);
+ // dead?
+ writeU8(os, hp == 0);
+ // create message and add to list
+ ActiveObjectMessage aom(getId(), false, os.str());
+ m_messages_out.push_back(aom);
+ }
}
s16 ServerRemotePlayer::getHP()
{
diff --git a/src/serverremoteplayer.h b/src/serverremoteplayer.h
index 9d9437646..94926c824 100644
--- a/src/serverremoteplayer.h
+++ b/src/serverremoteplayer.h
@@ -90,7 +90,6 @@ public:
int m_wield_index;
bool m_inventory_not_sent;
bool m_hp_not_sent;
- bool m_respawn_active;
bool m_is_in_environment;
// Incremented by step(), read and reset by Server
float m_time_from_last_punch;