1
0
Fork 0

Fixed fall damage

* Fixes #3216
This commit is contained in:
Tiger Wang 2016-06-01 23:46:24 +01:00
parent 5618e453e6
commit a5ec2d8ca2
4 changed files with 17 additions and 44 deletions

View File

@ -215,7 +215,7 @@ public:
void SetPosY (double a_PosY) { SetPosition({m_Position.x, a_PosY, m_Position.z}); }
void SetPosZ (double a_PosZ) { SetPosition({m_Position.x, m_Position.y, a_PosZ}); }
void SetPosition(double a_PosX, double a_PosY, double a_PosZ) { SetPosition({a_PosX, a_PosY, a_PosZ}); }
virtual void SetPosition(const Vector3d & a_Position);
void SetPosition(const Vector3d & a_Position);
void SetYaw (double a_Yaw); // In degrees, normalizes to [-180, +180)
void SetPitch (double a_Pitch); // In degrees, normalizes to [-180, +180)
void SetRoll (double a_Roll); // In degrees, normalizes to [-180, +180)

View File

@ -250,24 +250,6 @@ void cPawn::TargetingMe(cMonster * a_Monster)
void cPawn::SetPosition(double a_PosX, double a_PosY, double a_PosZ)
{
SetPosition({a_PosX, a_PosY, a_PosZ});
}
void cPawn::SetPosition(const Vector3d & a_Position)
{
super::SetPosition(a_Position);
m_LastGroundHeight = a_Position.y; // Prevent fall damage on teleport
}
void cPawn::HandleFalling(void)
{
@ -324,8 +306,8 @@ void cPawn::HandleFalling(void)
int x, y, z;
} BlockSampleOffsets[] =
{
{ 0, 0, 0 },
{ 0, -1, 0 },
{ 0, 0, 0 }, // TODO: something went wrong here (offset 0?)
{ 0, -1, 0 }, // Potentially causes mis-detection (IsFootInWater) when player stands on block diagonal to water (i.e. on side of pool)
};
/* Here's the rough outline of how this mechanism works:
@ -368,12 +350,6 @@ void cPawn::HandleFalling(void)
}
}
// Update the ground height to have the highest position of the player (i.e. jumping up adds to the eventual fall damage)
if (!OnGround)
{
m_LastGroundHeight = std::max(m_LastGroundHeight, GetPosY());
}
/* So here's the use of the rules above: */
/* 1. Falling in water absorbs all fall damage */
bool FallDamageAbsorbed = IsFootInWater;
@ -381,17 +357,14 @@ void cPawn::HandleFalling(void)
/* 2. Falling in liquid (lava, water, cobweb) or hitting a slime block resets the "fall zenith".
Note: Even though the pawn bounces back with no damage after hitting the slime block,
the "fall zenith" will continue to increase back up when flying upwards - which is good */
bool FallDistanceReset = IsFootOnSlimeBlock || IsFootInLiquid;
bool IsFlying = false;
bool ShouldBounceOnSlime = true;
if (GetEntityType() == eEntityType::etPlayer)
if (IsPlayer())
{
cPlayer * Player = static_cast<cPlayer *>(this);
IsFlying = Player->IsFlying();
auto Player = static_cast<cPlayer *>(this);
/* 3. If the player is flying or climbing, absorb fall damage */
FallDamageAbsorbed |= IsFlying || Player->IsClimbing();
FallDamageAbsorbed |= Player->IsFlying() || Player->IsClimbing();
/* 4. If the player is about to bounce on a slime block and is not crouching, absorb all fall damage */
ShouldBounceOnSlime = !Player->IsCrouched();
@ -407,10 +380,18 @@ void cPawn::HandleFalling(void)
NOTE: this will only work in some cases; should be done in HandlePhysics() */
if (IsFootOnSlimeBlock && ShouldBounceOnSlime)
{
SetSpeedY(-GetSpeedY());
// TODO: doesn't work too well, causes dissatisfactory experience for players on slime blocks - SetSpeedY(-GetSpeedY());
}
if (!IsFlying && OnGround)
// TODO: put player speed into GetSpeedY, and use that.
// If flying, climbing, swimming, or going up...
if (FallDamageAbsorbed || ((GetPosition() - m_LastPosition).y > 0))
{
// ...update the ground height to have the highest position of the player (i.e. jumping up adds to the eventual fall damage)
m_LastGroundHeight = GetPosY();
}
if (OnGround)
{
auto Damage = static_cast<int>(m_LastGroundHeight - GetPosY() - 3.0);
if ((Damage > 0) && !FallDamageAbsorbed)
@ -434,10 +415,6 @@ void cPawn::HandleFalling(void)
/* Note: it is currently possible to fall through lava and still die from fall damage
because of the client skipping an update about the lava block. This can only be resolved by
somehow integrating these above checks into the tracer in HandlePhysics. */
if (FallDistanceReset)
{
m_LastGroundHeight = GetPosY();
}
}

View File

@ -69,10 +69,6 @@ public:
/** Add the monster to the list of monsters targeting this pawn. (Does not check if already in list!) */
void TargetingMe(cMonster * a_Monster);
void SetPosition(double a_PosX, double a_PosY, double a_PosZ);
virtual void SetPosition(const Vector3d & a_Position) override;
protected:
typedef std::map<cEntityEffect::eType, cEntityEffect *> tEffectMap;
tEffectMap m_EntityEffects;

View File

@ -1439,7 +1439,7 @@ void cPlayer::TeleportToCoords(double a_PosX, double a_PosY, double a_PosZ)
{
SetPosition(a_PosX, a_PosY, a_PosZ);
FreezeInternal(GetPosition(), false);
m_LastGroundHeight = static_cast<float>(a_PosY);
m_LastGroundHeight = a_PosY;
m_bIsTeleporting = true;
m_World->BroadcastTeleportEntity(*this, GetClientHandle());