/*
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
}
/*
- 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);
// 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(
SendChatMessage(peer_id, L"# Server: WARNING: YOUR CLIENT IS OLD AND MAY WORK PROPERLY WITH THIS SERVER");
}
- /*
- Check HP, respawn if necessary
- */
- HandlePlayerHP(player, 0);
-
/*
Print out action
*/
return;
}
+ /*
+ Note: Always set inventory not sent, to repair cases
+ where the client made a bad prediction.
+ */
+
/*
Handle restrictions and special cases of the move action
*/
ma->from_inv.applyCurrentPlayer(player->getName());
ma->to_inv.applyCurrentPlayer(player->getName());
+ setInventoryModified(ma->from_inv);
+ setInventoryModified(ma->to_inv);
+
bool from_inv_is_current_player =
(ma->from_inv.type == InventoryLocation::PLAYER) &&
(ma->from_inv.name == player->getName());
da->from_inv.applyCurrentPlayer(player->getName());
+ setInventoryModified(da->from_inv);
+
// Disallow dropping items if not allowed to interact
if((getPlayerPrivs(player) & PRIV_INTERACT) == 0)
{
ca->craft_inv.applyCurrentPlayer(player->getName());
+ setInventoryModified(ca->craft_inv);
+
//bool craft_inv_is_current_player =
// (ca->craft_inv.type == InventoryLocation::PLAYER) &&
// (ca->craft_inv.name == player->getName());
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);
}
}
if(player->hp != 0)
return;
- srp->m_respawn_active = false;
-
RespawnPlayer(player);
actionstream<<player->getName()<<" respawns at "
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
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);
}
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());
// 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"))
{
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 */