Don't call on_dieplayer callback two times (#11874)

This commit is contained in:
savilli 2022-01-15 17:44:55 +01:00 committed by GitHub
parent 76e97e85a0
commit 72b14bd994
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 41 additions and 60 deletions

@ -819,8 +819,7 @@ void Server::handleCommand_Damage(NetworkPacket* pkt)
<< std::endl; << std::endl;
PlayerHPChangeReason reason(PlayerHPChangeReason::FALL); PlayerHPChangeReason reason(PlayerHPChangeReason::FALL);
playersao->setHP((s32)playersao->getHP() - (s32)damage, reason, false); playersao->setHP((s32)playersao->getHP() - (s32)damage, reason, true);
SendPlayerHPOrDie(playersao, reason); // correct client side prediction
} }
} }

@ -1095,11 +1095,12 @@ PlayerSAO* Server::StageTwoClientInit(session_t peer_id)
// Send inventory // Send inventory
SendInventory(playersao, false); SendInventory(playersao, false);
// Send HP or death screen // Send HP
SendPlayerHP(playersao);
// Send death screen
if (playersao->isDead()) if (playersao->isDead())
SendDeathscreen(peer_id, false, v3f(0,0,0)); SendDeathscreen(peer_id, false, v3f(0,0,0));
else
SendPlayerHP(peer_id);
// Send Breath // Send Breath
SendPlayerBreath(playersao); SendPlayerBreath(playersao);
@ -1365,18 +1366,21 @@ void Server::SendMovement(session_t peer_id)
Send(&pkt); Send(&pkt);
} }
void Server::SendPlayerHPOrDie(PlayerSAO *playersao, const PlayerHPChangeReason &reason) void Server::HandlePlayerHPChange(PlayerSAO *playersao, const PlayerHPChangeReason &reason)
{ {
if (playersao->isImmortal()) m_script->player_event(playersao, "health_changed");
return; SendPlayerHP(playersao);
session_t peer_id = playersao->getPeerID(); // Send to other clients
bool is_alive = !playersao->isDead(); playersao->sendPunchCommand();
if (is_alive) if (playersao->isDead())
SendPlayerHP(peer_id); HandlePlayerDeath(playersao, reason);
else }
DiePlayer(peer_id, reason);
void Server::SendPlayerHP(PlayerSAO *playersao)
{
SendHP(playersao->getPeerID(), playersao->getHP());
} }
void Server::SendHP(session_t peer_id, u16 hp) void Server::SendHP(session_t peer_id, u16 hp)
@ -1810,18 +1814,6 @@ void Server::SendTimeOfDay(session_t peer_id, u16 time, f32 time_speed)
} }
} }
void Server::SendPlayerHP(session_t peer_id)
{
PlayerSAO *playersao = getPlayerSAO(peer_id);
assert(playersao);
SendHP(peer_id, playersao->getHP());
m_script->player_event(playersao,"health_changed");
// Send to other clients
playersao->sendPunchCommand();
}
void Server::SendPlayerBreath(PlayerSAO *sao) void Server::SendPlayerBreath(PlayerSAO *sao)
{ {
assert(sao); assert(sao);
@ -2750,23 +2742,18 @@ void Server::sendDetachedInventories(session_t peer_id, bool incremental)
Something random Something random
*/ */
void Server::DiePlayer(session_t peer_id, const PlayerHPChangeReason &reason) void Server::HandlePlayerDeath(PlayerSAO *playersao, const PlayerHPChangeReason &reason)
{ {
PlayerSAO *playersao = getPlayerSAO(peer_id);
assert(playersao);
infostream << "Server::DiePlayer(): Player " infostream << "Server::DiePlayer(): Player "
<< playersao->getPlayer()->getName() << playersao->getPlayer()->getName()
<< " dies" << std::endl; << " dies" << std::endl;
playersao->setHP(0, reason);
playersao->clearParentAttachment(); playersao->clearParentAttachment();
// Trigger scripted stuff // Trigger scripted stuff
m_script->on_dieplayer(playersao, reason); m_script->on_dieplayer(playersao, reason);
SendPlayerHP(peer_id); SendDeathscreen(playersao->getPeerID(), false, v3f(0,0,0));
SendDeathscreen(peer_id, false, v3f(0,0,0));
} }
void Server::RespawnPlayer(session_t peer_id) void Server::RespawnPlayer(session_t peer_id)
@ -2787,8 +2774,6 @@ void Server::RespawnPlayer(session_t peer_id)
// setPos will send the new position to client // setPos will send the new position to client
playersao->setPos(findSpawnPos()); playersao->setPos(findSpawnPos());
} }
SendPlayerHP(peer_id);
} }

@ -350,7 +350,8 @@ public:
void printToConsoleOnly(const std::string &text); void printToConsoleOnly(const std::string &text);
void SendPlayerHPOrDie(PlayerSAO *player, const PlayerHPChangeReason &reason); void HandlePlayerHPChange(PlayerSAO *sao, const PlayerHPChangeReason &reason);
void SendPlayerHP(PlayerSAO *sao);
void SendPlayerBreath(PlayerSAO *sao); void SendPlayerBreath(PlayerSAO *sao);
void SendInventory(PlayerSAO *playerSAO, bool incremental); void SendInventory(PlayerSAO *playerSAO, bool incremental);
void SendMovePlayer(session_t peer_id); void SendMovePlayer(session_t peer_id);
@ -438,7 +439,6 @@ private:
virtual void SendChatMessage(session_t peer_id, const ChatMessage &message); virtual void SendChatMessage(session_t peer_id, const ChatMessage &message);
void SendTimeOfDay(session_t peer_id, u16 time, f32 time_speed); void SendTimeOfDay(session_t peer_id, u16 time, f32 time_speed);
void SendPlayerHP(session_t peer_id);
void SendLocalPlayerAnimations(session_t peer_id, v2s32 animation_frames[4], void SendLocalPlayerAnimations(session_t peer_id, v2s32 animation_frames[4],
f32 animation_speed); f32 animation_speed);
@ -510,7 +510,7 @@ private:
Something random Something random
*/ */
void DiePlayer(session_t peer_id, const PlayerHPChangeReason &reason); void HandlePlayerDeath(PlayerSAO* sao, const PlayerHPChangeReason &reason);
void RespawnPlayer(session_t peer_id); void RespawnPlayer(session_t peer_id);
void DeleteClient(session_t peer_id, ClientDeletionReason reason); void DeleteClient(session_t peer_id, ClientDeletionReason reason);
void UpdateCrafting(RemotePlayer *player); void UpdateCrafting(RemotePlayer *player);

@ -463,36 +463,33 @@ void PlayerSAO::rightClick(ServerActiveObject *clicker)
m_env->getScriptIface()->on_rightclickplayer(this, clicker); m_env->getScriptIface()->on_rightclickplayer(this, clicker);
} }
void PlayerSAO::setHP(s32 hp, const PlayerHPChangeReason &reason, bool send) void PlayerSAO::setHP(s32 target_hp, const PlayerHPChangeReason &reason, bool from_client)
{ {
if (hp == (s32)m_hp) target_hp = rangelim(target_hp, 0, U16_MAX);
if (target_hp == m_hp)
return; // Nothing to do return; // Nothing to do
if (m_hp <= 0 && hp < (s32)m_hp) s32 hp_change = m_env->getScriptIface()->on_player_hpchange(this, target_hp - (s32)m_hp, reason);
return; // Cannot take more damage
{ s32 hp = (s32)m_hp + std::min(hp_change, U16_MAX); // Protection against s32 overflow
s32 hp_change = m_env->getScriptIface()->on_player_hpchange(this, hp - m_hp, reason); hp = rangelim(hp, 0, U16_MAX);
if (hp_change == 0)
return;
hp = m_hp + hp_change; if (hp > m_prop.hp_max)
} hp = m_prop.hp_max;
s32 oldhp = m_hp; if (hp < m_hp && isImmortal())
hp = rangelim(hp, 0, m_prop.hp_max); hp = m_hp; // Do not allow immortal players to be damaged
if (hp < oldhp && isImmortal())
return; // Do not allow immortal players to be damaged
m_hp = hp;
// Update properties on death // Update properties on death
if ((hp == 0) != (oldhp == 0)) if ((hp == 0) != (m_hp == 0))
m_properties_sent = false; m_properties_sent = false;
if (send) if (hp != m_hp) {
m_env->getGameDef()->SendPlayerHPOrDie(this, reason); m_hp = hp;
m_env->getGameDef()->HandlePlayerHPChange(this, reason);
} else if (from_client)
m_env->getGameDef()->SendPlayerHP(this);
} }
void PlayerSAO::setBreath(const u16 breath, bool send) void PlayerSAO::setBreath(const u16 breath, bool send)

@ -114,9 +114,9 @@ public:
void rightClick(ServerActiveObject *clicker); void rightClick(ServerActiveObject *clicker);
void setHP(s32 hp, const PlayerHPChangeReason &reason) override void setHP(s32 hp, const PlayerHPChangeReason &reason) override
{ {
return setHP(hp, reason, true); return setHP(hp, reason, false);
} }
void setHP(s32 hp, const PlayerHPChangeReason &reason, bool send); void setHP(s32 hp, const PlayerHPChangeReason &reason, bool from_client);
void setHPRaw(u16 hp) { m_hp = hp; } void setHPRaw(u16 hp) { m_hp = hp; }
u16 getBreath() const { return m_breath; } u16 getBreath() const { return m_breath; }
void setBreath(const u16 breath, bool send = true); void setBreath(const u16 breath, bool send = true);