From 4f554e91abd861323aaf9f46d75ff0350a519cef Mon Sep 17 00:00:00 2001 From: DarkoGNU <42816979+DarkoGNU@users.noreply.github.com> Date: Thu, 21 Apr 2022 20:56:21 +0200 Subject: Implement farmland trampling (#5401) * Add DarkoGNU to CONTRIBUTORS * HandleFarmlandTrampling function & its docs * Fix decimal separators (, -> .) * Fix style. Adjust thresholds. Make function non-virtual * Adjust thresholds again. Prepare for fixing #5402 * Trying to fix falling through farmlands * Another style fix * Add FarmlandTramplingEnabled to world.ini * Docs for IsFarmlandTramplingEnabled * Style * Farmland trampling - handling the random chance * Trampling kinda works, very buggy * Trying to fix clang-tidy * Fix trampling * Trying to fix the 'undocumented API symbol' * Implement bearbin's suggestions * Calculate volume properly * Don't use std::pow for squaring * Improved comments * Really, should comments' style be checked? --- src/Entities/Pawn.cpp | 52 +++++++++++++++++++++++++++++++++++++++++++++++++-- src/Entities/Pawn.h | 10 ++++++++++ 2 files changed, 60 insertions(+), 2 deletions(-) (limited to 'src/Entities') 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(m_LastGroundHeight - GetPosY() - 3.0); + auto FallHeight = m_LastGroundHeight - GetPosY(); + auto Damage = static_cast(FallHeight - 3.0); + if ((Damage > 0) && !FallDamageAbsorbed) { if (IsElytraFlying()) @@ -438,7 +441,6 @@ void cPawn::HandleFalling(void) Damage = static_cast(static_cast(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(static_cast(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(); -- cgit v1.2.3