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 +++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 50 insertions(+), 2 deletions(-) (limited to 'src/Entities/Pawn.cpp') 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(); -- cgit v1.2.3