diff --git a/src/Entities/Entity.cpp b/src/Entities/Entity.cpp index ea20fc8da..a051b3ffc 100644 --- a/src/Entities/Entity.cpp +++ b/src/Entities/Entity.cpp @@ -532,7 +532,6 @@ bool cEntity::DoTakeDamage(TakeDamageInfo & a_TDI) } m_Health -= static_cast(a_TDI.FinalDamage); - m_Health = std::max(m_Health, 0.0f); // Add knockback: @@ -872,7 +871,7 @@ void cEntity::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) // Handle cactus damage or destruction: if ( - IsMob() || IsPickup() || IsExpOrb() || + IsMob() || IsPickup() || (IsPlayer() && !((reinterpret_cast(this))->IsGameModeCreative() || (reinterpret_cast(this))->IsGameModeSpectator())) ) { @@ -1281,20 +1280,27 @@ void cEntity::TickInVoid(cChunk & a_Chunk) void cEntity::DetectCacti(void) { - int X = POSX_TOINT, Y = POSY_TOINT, Z = POSZ_TOINT; - double w = m_Width / 2; - if ( - ((Y > 0) && (Y < cChunkDef::Height)) && - ((((X + 1) - GetPosX() < w) && (GetWorld()->GetBlock(X + 1, Y, Z) == E_BLOCK_CACTUS)) || - ((GetPosX() - X < w) && (GetWorld()->GetBlock(X - 1, Y, Z) == E_BLOCK_CACTUS)) || - (((Z + 1) - GetPosZ() < w) && (GetWorld()->GetBlock(X, Y, Z + 1) == E_BLOCK_CACTUS)) || - ((GetPosZ() - Z < w) && (GetWorld()->GetBlock(X, Y, Z - 1) == E_BLOCK_CACTUS)) || - (((Y + 1) - GetPosY() < w) && (GetWorld()->GetBlock(X, Y + 1, Z) == E_BLOCK_CACTUS)) || - ((GetPosY() - Y < 1) && (GetWorld()->GetBlock(X, Y - 1, Z) == E_BLOCK_CACTUS))) - ) + int MinX = FloorC(GetPosX() - m_Width / 2); + int MaxX = FloorC(GetPosX() + m_Width / 2); + int MinZ = FloorC(GetPosZ() - m_Width / 2); + int MaxZ = FloorC(GetPosZ() + m_Width / 2); + int MinY = Clamp(POSY_TOINT, 0, cChunkDef::Height - 1); + int MaxY = Clamp(FloorC(GetPosY() + m_Height), 0, cChunkDef::Height - 1); + + for (int x = MinX; x <= MaxX; x++) { - TakeDamage(dtCactusContact, nullptr, 1, 0); - } + for (int z = MinZ; z <= MaxZ; z++) + { + for (int y = MinY; y <= MaxY; y++) + { + if (GetWorld()->GetBlock(x, y, z) == E_BLOCK_CACTUS) + { + TakeDamage(dtCactusContact, nullptr, 1, 0); + return; + } + } // for y + } // for z + } // for x } diff --git a/src/Entities/ExpOrb.cpp b/src/Entities/ExpOrb.cpp index 4ae847bf8..dd16a4762 100644 --- a/src/Entities/ExpOrb.cpp +++ b/src/Entities/ExpOrb.cpp @@ -46,6 +46,8 @@ void cExpOrb::SpawnOn(cClientHandle & a_Client) void cExpOrb::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) { + DetectCacti(); + // Check player proximity no more than twice per second if ((m_TicksAlive % 10) == 0) { @@ -79,3 +81,14 @@ void cExpOrb::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) Destroy(true); } } + +bool cExpOrb::DoTakeDamage(TakeDamageInfo & a_TDI) +{ + if (a_TDI.DamageType == dtCactusContact) + { + Destroy(true); + return true; + } + + return super::DoTakeDamage(a_TDI); +} diff --git a/src/Entities/ExpOrb.h b/src/Entities/ExpOrb.h index 83672ea02..20ac6e304 100644 --- a/src/Entities/ExpOrb.h +++ b/src/Entities/ExpOrb.h @@ -23,6 +23,9 @@ public: // Override functions virtual void Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override; + + virtual bool DoTakeDamage(TakeDamageInfo & a_TDI) override; + virtual void SpawnOn(cClientHandle & a_Client) override; // tolua_begin diff --git a/src/Entities/Pickup.cpp b/src/Entities/Pickup.cpp index be6f3ebe3..629f5d189 100644 --- a/src/Entities/Pickup.cpp +++ b/src/Entities/Pickup.cpp @@ -195,6 +195,21 @@ void cPickup::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) +bool cPickup::DoTakeDamage(TakeDamageInfo & a_TDI) +{ + if (a_TDI.DamageType == dtCactusContact) + { + Destroy(true); + return true; + } + + return super::DoTakeDamage(a_TDI); +} + + + + + bool cPickup::CollectedBy(cPlayer & a_Dest) { if (m_bCollected) diff --git a/src/Entities/Pickup.h b/src/Entities/Pickup.h index 61e433e07..6b3d9f9f2 100644 --- a/src/Entities/Pickup.h +++ b/src/Entities/Pickup.h @@ -36,6 +36,8 @@ public: virtual void Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override; + virtual bool DoTakeDamage(TakeDamageInfo & a_TDI) override; + virtual bool DoesPreventBlockPlacement(void) const override { return false; } /** Returns whether this pickup is allowed to combine with other similar pickups */