summaryrefslogtreecommitdiffstats
path: root/src/Entities
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/Entities/Pawn.cpp52
-rw-r--r--src/Entities/Pawn.h10
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();