diff options
Diffstat (limited to 'src/Entities')
-rw-r--r-- | src/Entities/Pawn.cpp | 52 | ||||
-rw-r--r-- | src/Entities/Pawn.h | 10 |
2 files changed, 60 insertions, 2 deletions
diff --git a/src/Entities/Pawn.cpp b/src/Entities/Pawn.cpp index 990ea8096..cf2dd274f 100644 --- a/src/Entities/Pawn.cpp +++ b/src/Entities/Pawn.cpp @@ -8,6 +8,7 @@ #include "../Bindings/PluginManager.h" #include "../BoundingBox.h" #include "../Blocks/BlockHandler.h" +#include "../Blocks/BlockFarmland.h" #include "../EffectID.h" #include "../Mobs/Monster.h" @@ -430,7 +431,9 @@ void cPawn::HandleFalling(void) if (OnGround) { - auto Damage = static_cast<int>(m_LastGroundHeight - GetPosY() - 3.0); + auto FallHeight = m_LastGroundHeight - GetPosY(); + auto Damage = static_cast<int>(FallHeight - 3.0); + if ((Damage > 0) && !FallDamageAbsorbed) { if (IsElytraFlying()) @@ -438,7 +441,6 @@ void cPawn::HandleFalling(void) Damage = static_cast<int>(static_cast<float>(Damage) * 0.33); } - // Fall particles: if (const auto Below = POS_TOINT.addedY(-1); Below.y >= 0) { const auto BlockBelow = GetWorld()->GetBlock(Below); @@ -448,6 +450,7 @@ void cPawn::HandleFalling(void) Damage = std::clamp(static_cast<int>(static_cast<float>(Damage) * 0.2), 1, 20); } + // Fall particles GetWorld()->BroadcastParticleEffect( "blockdust", GetPosition(), @@ -463,6 +466,15 @@ void cPawn::HandleFalling(void) m_bTouchGround = true; m_LastGroundHeight = GetPosY(); + + // Farmland trampling. Mobs smaller than 0.512 cubic blocks won't trample (Java Edition's behavior) + // We only have width and height, so we have to calculate Width^2 + if (GetWorld()->IsFarmlandTramplingEnabled() && + (BlockAtFoot == E_BLOCK_FARMLAND) && + (GetWidth() * GetWidth() * GetHeight() >= 0.512)) + { + HandleFarmlandTrampling(FallHeight); + } } else { @@ -478,6 +490,42 @@ void cPawn::HandleFalling(void) +void cPawn::HandleFarmlandTrampling(double a_FallHeight) +{ + bool ShouldTrample = true; + auto & Random = GetRandomProvider(); + + // No trampling if FallHeight <= 0.6875 + if (a_FallHeight <= 0.6875) + { + ShouldTrample = false; + } + // For FallHeight <= 1.5625 we need to get a random bool + else if (a_FallHeight <= 1.0625) + { + ShouldTrample = Random.RandBool(0.25); + } + else if (a_FallHeight <= 1.5625) + { + ShouldTrample = Random.RandBool(0.66); + } + // For FallHeight > 1.5625 we always trample - ShouldTrample remains true + + if (ShouldTrample) + { + auto AbsPos = GetPosition().Floor(); + GetWorld()->DoWithChunkAt(AbsPos, [&](cChunk & Chunk) + { + cBlockFarmlandHandler::TurnToDirt(Chunk, AbsPos); + return true; + }); + } +} + + + + + void cPawn::OnRemoveFromWorld(cWorld & a_World) { StopEveryoneFromTargetingMe(); diff --git a/src/Entities/Pawn.h b/src/Entities/Pawn.h index 222e8f3b8..c0801ebb3 100644 --- a/src/Entities/Pawn.h +++ b/src/Entities/Pawn.h @@ -33,6 +33,16 @@ public: virtual void HandleFalling(void); virtual void OnRemoveFromWorld(cWorld & a_World) override; + /** Handles farmland trampling when hitting the ground. + Algorithm: + fall height <= 0.6875 blocks: no trampling + fall height > 0.6875 and <= 1.0625: 25% chance of trampling + fall height > 1.0625 and <= 1.5625: 66% chance of trampling + fall height > 1.5625: always trample + The values may differ from vanilla, they were determined experimentally. + */ + void HandleFarmlandTrampling(double a_FallHeight); + /** Tells all pawns which are targeting us to stop targeting us. */ void StopEveryoneFromTargetingMe(); |