summaryrefslogtreecommitdiffstats
path: root/src/Entities
diff options
context:
space:
mode:
authorLogicParrot <LogicParrot@users.noreply.github.com>2017-09-01 21:12:44 +0200
committerLogicParrot <LogicParrot@users.noreply.github.com>2017-09-01 21:12:44 +0200
commit6e3e7552e67dfc0254c3e99bcd32fea02f10d062 (patch)
tree84bfd40d2c2693cab44a47d4902aa601d8a715e6 /src/Entities
parentd (diff)
parentSetSwimState now takes into account head height (diff)
downloadcuberite-6e3e7552e67dfc0254c3e99bcd32fea02f10d062.tar
cuberite-6e3e7552e67dfc0254c3e99bcd32fea02f10d062.tar.gz
cuberite-6e3e7552e67dfc0254c3e99bcd32fea02f10d062.tar.bz2
cuberite-6e3e7552e67dfc0254c3e99bcd32fea02f10d062.tar.lz
cuberite-6e3e7552e67dfc0254c3e99bcd32fea02f10d062.tar.xz
cuberite-6e3e7552e67dfc0254c3e99bcd32fea02f10d062.tar.zst
cuberite-6e3e7552e67dfc0254c3e99bcd32fea02f10d062.zip
Diffstat (limited to 'src/Entities')
-rw-r--r--src/Entities/Entity.cpp33
-rw-r--r--src/Entities/Floater.cpp45
-rw-r--r--src/Entities/LeashKnot.cpp61
-rw-r--r--src/Entities/Minecart.cpp23
-rw-r--r--src/Entities/Pawn.cpp68
-rw-r--r--src/Entities/Pickup.cpp23
-rw-r--r--src/Entities/Player.cpp73
-rw-r--r--src/Entities/ProjectileEntity.cpp40
-rw-r--r--src/Entities/SplashPotionEntity.cpp80
-rw-r--r--src/Entities/ThrownEnderPearlEntity.cpp25
10 files changed, 146 insertions, 325 deletions
diff --git a/src/Entities/Entity.cpp b/src/Entities/Entity.cpp
index 38443793e..956534856 100644
--- a/src/Entities/Entity.cpp
+++ b/src/Entities/Entity.cpp
@@ -306,38 +306,22 @@ void cEntity::TakeDamage(eDamageType a_DamageType, cEntity * a_Attacker, int a_R
void cEntity::TakeDamage(eDamageType a_DamageType, UInt32 a_AttackerID, int a_RawDamage, double a_KnockbackAmount)
{
- class cFindEntity : public cEntityCallback
- {
- public:
-
- cEntity * m_Entity;
- eDamageType m_DamageType;
- int m_RawDamage;
- double m_KnockbackAmount;
-
- virtual bool Item(cEntity * a_Attacker) override
+ m_World->DoWithEntityByID(a_AttackerID, [=](cEntity & a_Attacker)
{
cPawn * Attacker;
- if (a_Attacker->IsPawn())
+ if (a_Attacker.IsPawn())
{
- Attacker = static_cast<cPawn*>(a_Attacker);
+ Attacker = static_cast<cPawn*>(&a_Attacker);
}
else
{
Attacker = nullptr;
}
-
- m_Entity->TakeDamage(m_DamageType, Attacker, m_RawDamage, m_KnockbackAmount);
+ TakeDamage(a_DamageType, Attacker, a_RawDamage, a_KnockbackAmount);
return true;
}
- } Callback;
-
- Callback.m_Entity = this;
- Callback.m_DamageType = a_DamageType;
- Callback.m_RawDamage = a_RawDamage;
- Callback.m_KnockbackAmount = a_KnockbackAmount;
- m_World->DoWithEntityByID(a_AttackerID, Callback);
+ );
}
@@ -668,7 +652,7 @@ bool cEntity::ArmorCoversAgainst(eDamageType a_DamageType)
int cEntity::GetEnchantmentCoverAgainst(const cEntity * a_Attacker, eDamageType a_DamageType, int a_Damage)
{
- int TotalEPF = 0.0;
+ int TotalEPF = 0;
const cItem ArmorItems[] = { GetEquippedHelmet(), GetEquippedChestplate(), GetEquippedLeggings(), GetEquippedBoots() };
for (size_t i = 0; i < ARRAYCOUNT(ArmorItems); i++)
@@ -1684,7 +1668,8 @@ void cEntity::SetSwimState(cChunk & a_Chunk)
m_IsSwimming = IsBlockWater(BlockIn);
// Check if the player is submerged:
- VERIFY(a_Chunk.UnboundedRelGetBlockType(RelX, RelY + 1, RelZ, BlockIn));
+ int HeadHeight = CeilC(GetPosY() + GetHeight()) - 1;
+ VERIFY(a_Chunk.UnboundedRelGetBlockType(RelX, HeadHeight, RelZ, BlockIn));
m_IsSubmerged = IsBlockWater(BlockIn);
}
@@ -1716,7 +1701,7 @@ void cEntity::DoSetSpeed(double a_SpeedX, double a_SpeedY, double a_SpeedZ)
void cEntity::HandleAir(void)
{
// Ref.: https://minecraft.gamepedia.com/Chunk_format
- // See if the entity is /submerged/ water (block above is water)
+ // See if the entity is /submerged/ water (head is in water)
// Get the type of block the entity is standing in:
int RespirationLevel = static_cast<int>(GetEquippedHelmet().m_Enchantments.GetLevel(cEnchantments::enchRespiration));
diff --git a/src/Entities/Floater.cpp b/src/Entities/Floater.cpp
index eeaa6cf3d..de5824068 100644
--- a/src/Entities/Floater.cpp
+++ b/src/Entities/Floater.cpp
@@ -13,8 +13,7 @@
////////////////////////////////////////////////////////////////////////////////
// cFloaterEntityCollisionCallback
-class cFloaterEntityCollisionCallback :
- public cEntityCallback
+class cFloaterEntityCollisionCallback
{
public:
cFloaterEntityCollisionCallback(cFloater * a_Floater, const Vector3d & a_Pos, const Vector3d & a_NextPos) :
@@ -25,14 +24,14 @@ public:
m_HitEntity(nullptr)
{
}
- virtual bool Item(cEntity * a_Entity) override
+ bool operator () (cEntity & a_Entity)
{
- if (!a_Entity->IsMob()) // Floaters can only pull mobs not other entities.
+ if (!a_Entity.IsMob()) // Floaters can only pull mobs not other entities.
{
return false;
}
- cBoundingBox EntBox(a_Entity->GetPosition(), a_Entity->GetWidth() / 2, a_Entity->GetHeight());
+ cBoundingBox EntBox(a_Entity.GetPosition(), a_Entity.GetWidth() / 2, a_Entity.GetHeight());
double LineCoeff;
eBlockFace Face;
@@ -47,7 +46,7 @@ public:
{
// The entity is closer than anything we've stored so far, replace it as the potential victim
m_MinCoeff = LineCoeff;
- m_HitEntity = a_Entity;
+ m_HitEntity = &a_Entity;
}
// Don't break the enumeration, we want all the entities
@@ -75,32 +74,6 @@ protected:
-////////////////////////////////////////////////////////////////////////////////
-// cFloaterCheckEntityExist
-class cFloaterCheckEntityExist :
- public cEntityCallback
-{
-public:
- cFloaterCheckEntityExist(void) :
- m_EntityExists(false)
- {
- }
-
- bool Item(cEntity * a_Entity) override
- {
- m_EntityExists = true;
- return false;
- }
-
- bool DoesExist(void) const { return m_EntityExists; }
-protected:
- bool m_EntityExists;
-} ;
-
-
-
-
-
cFloater::cFloater(double a_X, double a_Y, double a_Z, Vector3d a_Speed, UInt32 a_PlayerID, int a_CountDownTime) :
cEntity(etFloater, a_X, a_Y, a_Z, 0.2, 0.2),
m_BitePos(Vector3d(a_X, a_Y, a_Z)),
@@ -200,18 +173,16 @@ void cFloater::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
}
}
- cFloaterCheckEntityExist EntityCallback;
- m_World->DoWithEntityByID(m_PlayerID, EntityCallback);
- if (!EntityCallback.DoesExist()) // The owner doesn't exist anymore. Destroy the floater entity.
+ if (!m_World->DoWithEntityByID(m_PlayerID, [](cEntity &) { return true; })) // The owner doesn't exist anymore. Destroy the floater entity.
{
Destroy(true);
}
if (m_AttachedMobID != cEntity::INVALID_ID)
{
- m_World->DoWithEntityByID(m_AttachedMobID, EntityCallback); // The mob the floater was attached to doesn't exist anymore.
- if (!EntityCallback.DoesExist())
+ if (!m_World->DoWithEntityByID(m_AttachedMobID, [](cEntity &) { return true; }))
{
+ // The mob the floater was attached to doesn't exist anymore.
m_AttachedMobID = cEntity::INVALID_ID;
}
}
diff --git a/src/Entities/LeashKnot.cpp b/src/Entities/LeashKnot.cpp
index a86dc9d53..51002531d 100644
--- a/src/Entities/LeashKnot.cpp
+++ b/src/Entities/LeashKnot.cpp
@@ -1,4 +1,4 @@
-
+
#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
#include "LeashKnot.h"
@@ -38,58 +38,42 @@ void cLeashKnot::OnRightClicked(cPlayer & a_Player)
-void cLeashKnot::TiePlayersLeashedMobs(cPlayer & a_Player, bool a_ShouldBroadCast)
+void cLeashKnot::TiePlayersLeashedMobs(cPlayer & a_Player, bool a_ShouldBroadcast)
{
// Check leashed nearby mobs to tie them to this knot
- class LookForLeasheds : public cEntityCallback
- {
- public:
- cLeashKnot * m_Knot;
- cPlayer * m_Player;
- bool m_ShouldBroadcast;
-
- LookForLeasheds(cLeashKnot * a_Knot, cPlayer * a_PlayerLeashedTo, bool a_ShouldBroadcast) :
- m_Knot(a_Knot),
- m_Player(a_PlayerLeashedTo),
- m_ShouldBroadcast(a_ShouldBroadcast)
- {
- }
-
- virtual bool Item(cEntity * a_Entity) override
+ // taking world from player (instead from this) because this can be called before entity was initialized
+ a_Player.GetWorld()->ForEachEntityInBox(cBoundingBox(GetPosition(), 8, 8, -4), [&](cEntity & a_Entity)
{
// If the entity is not a monster skip it
- if (a_Entity->GetEntityType() != cEntity::eEntityType::etMonster)
+ if (a_Entity.GetEntityType() != cEntity::eEntityType::etMonster)
{
return false;
}
- cMonster * PotentialLeashed = static_cast<cMonster*>(a_Entity);
+ auto & PotentialLeashed = static_cast<cMonster&>(a_Entity);
// If can't be leashed skip it
- if (!PotentialLeashed->CanBeLeashed())
+ if (!PotentialLeashed.CanBeLeashed())
{
return false;
}
// If it's not leashed to the player skip it
if (
- !PotentialLeashed->IsLeashed() ||
- !PotentialLeashed->GetLeashedTo()->IsPlayer() ||
- (PotentialLeashed->GetLeashedTo()->GetUniqueID() != m_Player->GetUniqueID())
+ !PotentialLeashed.IsLeashed() ||
+ !PotentialLeashed.GetLeashedTo()->IsPlayer() ||
+ (PotentialLeashed.GetLeashedTo()->GetUniqueID() != a_Player.GetUniqueID())
)
{
return false;
}
// All conditions met, unleash from player and leash to fence
- PotentialLeashed->Unleash(false, false);
- PotentialLeashed->LeashTo(*m_Knot, m_ShouldBroadcast);
+ PotentialLeashed.Unleash(false, false);
+ PotentialLeashed.LeashTo(*this, a_ShouldBroadcast);
return false;
}
- } LookForLeashedsCallback(this, &a_Player, a_ShouldBroadCast);
-
- // taking world from player (instead from this) because this can be called before entity was initialized
- a_Player.GetWorld()->ForEachEntityInBox(cBoundingBox(GetPosition(), 8, 8, -4), LookForLeashedsCallback);
+ );
}
@@ -158,26 +142,19 @@ void cLeashKnot::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
cLeashKnot * cLeashKnot::FindKnotAtPos(cWorldInterface & a_WorldInterface, Vector3i a_BlockPos)
{
- class LookForKnot : public cEntityCallback
- {
- public:
- cLeashKnot * m_LeashKnot = nullptr;
-
- virtual bool Item(cEntity * a_Entity) override
+ cLeashKnot * LeashKnot = nullptr;
+ a_WorldInterface.ForEachEntityInBox(cBoundingBox(a_BlockPos, 0.5, 1), [&](cEntity & a_Entity)
{
- if (a_Entity->IsLeashKnot())
+ if (a_Entity.IsLeashKnot())
{
- m_LeashKnot = reinterpret_cast<cLeashKnot *>(a_Entity);
+ LeashKnot = static_cast<cLeashKnot *>(&a_Entity);
return true;
}
return false;
}
+ );
- } CallbackFindKnot;
-
- a_WorldInterface.ForEachEntityInBox(cBoundingBox(a_BlockPos, 0.5, 1), CallbackFindKnot);
-
- return CallbackFindKnot.m_LeashKnot;
+ return LeashKnot;
}
diff --git a/src/Entities/Minecart.cpp b/src/Entities/Minecart.cpp
index 7f32dc910..8921f8894 100644
--- a/src/Entities/Minecart.cpp
+++ b/src/Entities/Minecart.cpp
@@ -20,8 +20,7 @@
-class cMinecartCollisionCallback :
- public cEntityCallback
+class cMinecartCollisionCallback
{
public:
cMinecartCollisionCallback(Vector3d a_Pos, double a_Height, double a_Width, UInt32 a_UniqueID, UInt32 a_AttacheeUniqueID) :
@@ -35,33 +34,31 @@ public:
{
}
- virtual bool Item(cEntity * a_Entity) override
+ bool operator () (cEntity & a_Entity)
{
- ASSERT(a_Entity != nullptr);
-
if (
(
- !a_Entity->IsPlayer() ||
- reinterpret_cast<cPlayer *>(a_Entity)->IsGameModeSpectator() // Spectators doesn't collide with anything
+ !a_Entity.IsPlayer() ||
+ static_cast<cPlayer &>(a_Entity).IsGameModeSpectator() // Spectators doesn't collide with anything
) &&
- !a_Entity->IsMob() &&
- !a_Entity->IsMinecart() &&
- !a_Entity->IsBoat()
+ !a_Entity.IsMob() &&
+ !a_Entity.IsMinecart() &&
+ !a_Entity.IsBoat()
)
{
return false;
}
- else if ((a_Entity->GetUniqueID() == m_UniqueID) || (a_Entity->GetUniqueID() == m_AttacheeUniqueID))
+ else if ((a_Entity.GetUniqueID() == m_UniqueID) || (a_Entity.GetUniqueID() == m_AttacheeUniqueID))
{
return false;
}
- cBoundingBox bbEntity(a_Entity->GetPosition(), a_Entity->GetWidth() / 2, a_Entity->GetHeight());
+ cBoundingBox bbEntity(a_Entity.GetPosition(), a_Entity.GetWidth() / 2, a_Entity.GetHeight());
cBoundingBox bbMinecart(Vector3d(m_Pos.x, floor(m_Pos.y), m_Pos.z), m_Width / 2, m_Height);
if (bbEntity.DoesIntersect(bbMinecart))
{
- m_CollidedEntityPos = a_Entity->GetPosition();
+ m_CollidedEntityPos = a_Entity.GetPosition();
m_DoesIntersect = true;
return true;
}
diff --git a/src/Entities/Pawn.cpp b/src/Entities/Pawn.cpp
index 0fa11997b..ac8e4b1ab 100644
--- a/src/Entities/Pawn.cpp
+++ b/src/Entities/Pawn.cpp
@@ -1,4 +1,4 @@
-
+
#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
#include "Pawn.h"
@@ -79,49 +79,37 @@ void cPawn::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
Effect->OnTick(*this);
}
- class Pusher : public cEntityCallback
+ // Spectators cannot push entities around
+ if ((!IsPlayer()) || (!static_cast<cPlayer *>(this)->IsGameModeSpectator()))
{
- public:
- cEntity * m_Pusher;
-
- Pusher(cEntity * a_Pusher) :
- m_Pusher(a_Pusher)
- {
- }
-
- virtual bool Item(cEntity * a_Entity) override
- {
- if (a_Entity->GetUniqueID() == m_Pusher->GetUniqueID())
- {
- return false;
- }
-
- // we only push other mobs, boats and minecarts
- if ((a_Entity->GetEntityType() != etMonster) && (a_Entity->GetEntityType() != etMinecart) && (a_Entity->GetEntityType() != etBoat))
+ m_World->ForEachEntityInBox(cBoundingBox(GetPosition(), GetWidth(), GetHeight()), [=](cEntity & a_Entity)
{
+ if (a_Entity.GetUniqueID() == GetUniqueID())
+ {
+ return false;
+ }
+
+ // we only push other mobs, boats and minecarts
+ if ((a_Entity.GetEntityType() != etMonster) && (a_Entity.GetEntityType() != etMinecart) && (a_Entity.GetEntityType() != etBoat))
+ {
+ return false;
+ }
+
+ // do not push a boat / minecart you're sitting in
+ if (IsAttachedTo(&a_Entity))
+ {
+ return false;
+ }
+
+ Vector3d v3Delta = a_Entity.GetPosition() - GetPosition();
+ v3Delta.y = 0.0; // we only push sideways
+ v3Delta *= 1.0 / (v3Delta.Length() + 0.01); // we push harder if we're close
+ // QUESTION: is there an additional multiplier for this? current shoving seems a bit weak
+
+ a_Entity.AddSpeed(v3Delta);
return false;
}
-
- // do not push a boat / minecart you're sitting in
- if (m_Pusher->IsAttachedTo(a_Entity))
- {
- return false;
- }
-
- Vector3d v3Delta = a_Entity->GetPosition() - m_Pusher->GetPosition();
- v3Delta.y = 0.0; // we only push sideways
- v3Delta *= 1.0 / (v3Delta.Length() + 0.01); // we push harder if we're close
- // QUESTION: is there an additional multiplier for this? current shoving seems a bit weak
-
- a_Entity->AddSpeed(v3Delta);
- return false;
- }
- } Callback(this);
-
- // Spectators cannot push entities around
- if ((!IsPlayer()) || (!reinterpret_cast<cPlayer *>(this)->IsGameModeSpectator()))
- {
- m_World->ForEachEntityInBox(cBoundingBox(GetPosition(), GetWidth(), GetHeight()), Callback);
+ );
}
super::Tick(a_Dt, a_Chunk);
diff --git a/src/Entities/Pickup.cpp b/src/Entities/Pickup.cpp
index 0c6c8feab..fcae586f6 100644
--- a/src/Entities/Pickup.cpp
+++ b/src/Entities/Pickup.cpp
@@ -17,8 +17,7 @@
-class cPickupCombiningCallback :
- public cEntityCallback
+class cPickupCombiningCallback
{
public:
cPickupCombiningCallback(Vector3d a_Position, cPickup * a_Pickup) :
@@ -28,21 +27,21 @@ public:
{
}
- virtual bool Item(cEntity * a_Entity) override
+ bool operator () (cEntity & a_Entity)
{
- ASSERT(a_Entity->IsTicking());
- if (!a_Entity->IsPickup() || (a_Entity->GetUniqueID() <= m_Pickup->GetUniqueID()) || !a_Entity->IsOnGround())
+ ASSERT(a_Entity.IsTicking());
+ if (!a_Entity.IsPickup() || (a_Entity.GetUniqueID() <= m_Pickup->GetUniqueID()) || !a_Entity.IsOnGround())
{
return false;
}
- Vector3d EntityPos = a_Entity->GetPosition();
+ Vector3d EntityPos = a_Entity.GetPosition();
double Distance = (EntityPos - m_Position).Length();
- cPickup * OtherPickup = static_cast<cPickup *>(a_Entity);
- cItem & Item = OtherPickup->GetItem();
- if ((Distance < 1.2) && Item.IsEqual(m_Pickup->GetItem()) && OtherPickup->CanCombine())
+ auto & OtherPickup = static_cast<cPickup &>(a_Entity);
+ cItem & Item = OtherPickup.GetItem();
+ if ((Distance < 1.2) && Item.IsEqual(m_Pickup->GetItem()) && OtherPickup.CanCombine())
{
short CombineCount = Item.m_ItemCount;
if ((CombineCount + m_Pickup->GetItem().m_ItemCount) > Item.GetMaxStackSize())
@@ -64,16 +63,16 @@ public:
int DiffX = FloorC(m_Pickup->GetPosX() * 32.0) - FloorC(EntityPos.x * 32.0);
int DiffY = FloorC(m_Pickup->GetPosY() * 32.0) - FloorC(EntityPos.y * 32.0);
int DiffZ = FloorC(m_Pickup->GetPosZ() * 32.0) - FloorC(EntityPos.z * 32.0);
- a_Entity->GetWorld()->BroadcastEntityRelMove(*a_Entity, static_cast<char>(DiffX), static_cast<char>(DiffY), static_cast<char>(DiffZ));
+ a_Entity.GetWorld()->BroadcastEntityRelMove(a_Entity, static_cast<char>(DiffX), static_cast<char>(DiffY), static_cast<char>(DiffZ));
/* End of experimental animation */
- a_Entity->Destroy();
+ a_Entity.Destroy();
// Reset the timer
m_Pickup->SetAge(0);
}
else
{
- a_Entity->GetWorld()->BroadcastEntityMetadata(*a_Entity);
+ a_Entity.GetWorld()->BroadcastEntityMetadata(a_Entity);
}
m_FoundMatchingPickup = true;
}
diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp
index 4189841b8..f17d53b42 100644
--- a/src/Entities/Player.cpp
+++ b/src/Entities/Player.cpp
@@ -1005,36 +1005,21 @@ bool cPlayer::DoTakeDamage(TakeDamageInfo & a_TDI)
void cPlayer::NotifyNearbyWolves(cPawn * a_Opponent, bool a_IsPlayerInvolved)
{
ASSERT(a_Opponent != nullptr);
- class LookForWolves : public cEntityCallback
- {
- public:
- cPlayer * m_Player;
- cPawn * m_Attacker;
- bool m_IsPlayerInvolved;
-
- LookForWolves(cPlayer * a_Me, cPawn * a_MyAttacker, bool a_PlayerInvolved) :
- m_Player(a_Me),
- m_Attacker(a_MyAttacker),
- m_IsPlayerInvolved(a_PlayerInvolved)
- {
- }
- virtual bool Item(cEntity * a_Entity) override
+ m_World->ForEachEntityInBox(cBoundingBox(GetPosition(), 16), [&] (cEntity & a_Entity)
{
- if (a_Entity->IsMob())
+ if (a_Entity.IsMob())
{
- cMonster * Mob = static_cast<cMonster*>(a_Entity);
- if (Mob->GetMobType() == mtWolf)
+ auto & Mob = static_cast<cMonster&>(a_Entity);
+ if (Mob.GetMobType() == mtWolf)
{
- cWolf * Wolf = static_cast<cWolf*>(Mob);
- Wolf->ReceiveNearbyFightInfo(m_Player->GetUUID(), m_Attacker, m_IsPlayerInvolved);
+ auto & Wolf = static_cast<cWolf&>(Mob);
+ Wolf.ReceiveNearbyFightInfo(GetUUID(), a_Opponent, a_IsPlayerInvolved);
}
}
return false;
}
- } Callback(this, a_Opponent, a_IsPlayerInvolved);
-
- m_World->ForEachEntityInBox(cBoundingBox(GetPosition(), 16), Callback);
+ );
}
@@ -2432,17 +2417,12 @@ void cPlayer::HandleFloater()
{
return;
}
- class cFloaterCallback :
- public cEntityCallback
- {
- public:
- virtual bool Item(cEntity * a_Entity) override
+ m_World->DoWithEntityByID(m_FloaterID, [](cEntity & a_Entity)
{
- a_Entity->Destroy(true);
+ a_Entity.Destroy(true);
return true;
}
- } Callback;
- m_World->DoWithEntityByID(m_FloaterID, Callback);
+ );
SetIsFishing(false);
}
@@ -2686,29 +2666,18 @@ bool cPlayer::DoesPlacingBlocksIntersectEntity(const sSetBlockVector & a_Blocks)
cWorld * World = GetWorld();
// Check to see if any entity intersects any block being placed
- class DoesIntersectBlock : public cEntityCallback
- {
- public:
- const std::vector<cBoundingBox> & m_BoundingBoxes;
-
- // The distance inside the block the entity can still be.
- const double EPSILON = 0.0005;
-
- DoesIntersectBlock(const std::vector<cBoundingBox> & a_BoundingBoxes) :
- m_BoundingBoxes(a_BoundingBoxes)
+ return !World->ForEachEntityInBox(PlacingBounds, [&](cEntity & a_Entity)
{
- }
+ // The distance inside the block the entity can still be.
+ const double EPSILON = 0.0005;
- virtual bool Item(cEntity * a_Entity) override
- {
- if (!a_Entity->DoesPreventBlockPlacement())
+ if (!a_Entity.DoesPreventBlockPlacement())
{
return false;
}
- cBoundingBox EntBox(a_Entity->GetPosition(), a_Entity->GetWidth() / 2, a_Entity->GetHeight());
- for (auto BlockBox: m_BoundingBoxes)
+ cBoundingBox EntBox(a_Entity.GetPosition(), a_Entity.GetWidth() / 2, a_Entity.GetHeight());
+ for (auto BlockBox : PlacementBoxes)
{
-
// Put in a little bit of wiggle room
BlockBox.Expand(-EPSILON, -EPSILON, -EPSILON);
if (EntBox.DoesIntersect(BlockBox))
@@ -2718,15 +2687,7 @@ bool cPlayer::DoesPlacingBlocksIntersectEntity(const sSetBlockVector & a_Blocks)
}
return false;
}
- } Callback(PlacementBoxes);
-
- // See if any entities in that bounding box collide with anyone
- if (!World->ForEachEntityInBox(PlacingBounds, Callback))
- {
- return true;
- }
-
- return false;
+ );
}
diff --git a/src/Entities/ProjectileEntity.cpp b/src/Entities/ProjectileEntity.cpp
index c2a1f782d..13ebe31bc 100644
--- a/src/Entities/ProjectileEntity.cpp
+++ b/src/Entities/ProjectileEntity.cpp
@@ -126,8 +126,7 @@ protected:
////////////////////////////////////////////////////////////////////////////////
// cProjectileEntityCollisionCallback:
-class cProjectileEntityCollisionCallback :
- public cEntityCallback
+class cProjectileEntityCollisionCallback
{
public:
cProjectileEntityCollisionCallback(cProjectileEntity * a_Projectile, const Vector3d & a_Pos, const Vector3d & a_NextPos) :
@@ -140,11 +139,11 @@ public:
}
- virtual bool Item(cEntity * a_Entity) override
+ bool operator () (cEntity & a_Entity)
{
if (
- (a_Entity == m_Projectile) || // Do not check collisions with self
- (a_Entity->GetUniqueID() == m_Projectile->GetCreatorUniqueID()) // Do not check whoever shot the projectile
+ (&a_Entity == m_Projectile) || // Do not check collisions with self
+ (a_Entity.GetUniqueID() == m_Projectile->GetCreatorUniqueID()) // Do not check whoever shot the projectile
)
{
// Don't check creator only for the first 5 ticks so that projectiles can collide with the creator
@@ -154,7 +153,7 @@ public:
}
}
- cBoundingBox EntBox(a_Entity->GetPosition(), a_Entity->GetWidth() / 2, a_Entity->GetHeight());
+ cBoundingBox EntBox(a_Entity.GetPosition(), a_Entity.GetWidth() / 2, a_Entity.GetHeight());
// Instead of colliding the bounding box with another bounding box in motion, we collide an enlarged bounding box with a hairline.
// The results should be good enough for our purposes
@@ -168,20 +167,20 @@ public:
}
if (
- !a_Entity->IsMob() &&
- !a_Entity->IsMinecart() &&
+ !a_Entity.IsMob() &&
+ !a_Entity.IsMinecart() &&
(
- !a_Entity->IsPlayer() ||
- static_cast<cPlayer *>(a_Entity)->IsGameModeSpectator()
+ !a_Entity.IsPlayer() ||
+ static_cast<cPlayer &>(a_Entity).IsGameModeSpectator()
) &&
- !a_Entity->IsBoat()
+ !a_Entity.IsBoat()
)
{
// Not an entity that interacts with a projectile
return false;
}
- if (cPluginManager::Get()->CallHookProjectileHitEntity(*m_Projectile, *a_Entity))
+ if (cPluginManager::Get()->CallHookProjectileHitEntity(*m_Projectile, a_Entity))
{
// A plugin disagreed.
return false;
@@ -191,7 +190,7 @@ public:
{
// The entity is closer than anything we've stored so far, replace it as the potential victim
m_MinCoeff = LineCoeff;
- m_HitEntity = a_Entity;
+ m_HitEntity = &a_Entity;
}
// Don't break the enumeration, we want all the entities
@@ -327,20 +326,13 @@ void cProjectileEntity::OnHitEntity(cEntity & a_EntityHit, const Vector3d & a_Hi
// If we were created by a player and we hit a pawn, notify attacking player's wolves
if (a_EntityHit.IsPawn() && (GetCreatorName() != ""))
{
- class cNotifyWolves : public cEntityCallback
- {
- public:
- cPawn * m_EntityHit;
-
- virtual bool Item(cEntity * a_Hitter) override
+ auto EntityHit = static_cast<cPawn *>(&a_EntityHit);
+ m_World->DoWithEntityByID(GetCreatorUniqueID(), [=](cEntity & a_Hitter)
{
- static_cast<cPlayer*>(a_Hitter)->NotifyNearbyWolves(m_EntityHit, true);
+ static_cast<cPlayer&>(a_Hitter).NotifyNearbyWolves(EntityHit, true);
return true;
}
- } Callback;
-
- Callback.m_EntityHit = static_cast<cPawn*>(&a_EntityHit);
- m_World->DoWithEntityByID(GetCreatorUniqueID(), Callback);
+ );
}
}
diff --git a/src/Entities/SplashPotionEntity.cpp b/src/Entities/SplashPotionEntity.cpp
index af4008e83..35afe0fea 100644
--- a/src/Entities/SplashPotionEntity.cpp
+++ b/src/Entities/SplashPotionEntity.cpp
@@ -17,60 +17,6 @@
////////////////////////////////////////////////////////////////////////////////
-// cSplashPotionEntityCallback:
-
-/** Used to distribute the splashed potion effect among nearby entities */
-class cSplashPotionCallback :
- public cEntityCallback
-{
-public:
- /** Creates the callback.
- @param a_HitPos The position where the splash potion has splashed
- @param a_EntityEffectType The effect type of the potion
- @param a_EntityEffect The effect description */
- cSplashPotionCallback(const Vector3d & a_HitPos, cEntityEffect::eType a_EntityEffectType, const cEntityEffect & a_EntityEffect) :
- m_HitPos(a_HitPos),
- m_EntityEffectType(a_EntityEffectType),
- m_EntityEffect(a_EntityEffect)
- {
- }
-
- /** Called by cWorld::ForEachEntity(), adds the stored entity effect to the entity, if it is close enough. */
- virtual bool Item(cEntity * a_Entity) override
- {
- if (!a_Entity->IsPawn())
- {
- // Not an entity that can take effects
- return false;
- }
-
- double SplashDistance = (a_Entity->GetPosition() - m_HitPos).Length();
- if (SplashDistance >= 20)
- {
- // Too far away
- return false;
- }
-
- // y = -0.25x + 1, where x is the distance from the player. Approximation for potion splash.
- // TODO: better equation
- double Reduction = -0.25 * SplashDistance + 1.0;
- Reduction = std::max(Reduction, 0.0);
-
- static_cast<cPawn *>(a_Entity)->AddEntityEffect(m_EntityEffectType, m_EntityEffect.GetDuration(), m_EntityEffect.GetIntensity(), Reduction);
- return false;
- }
-
-private:
- const Vector3d & m_HitPos;
- cEntityEffect::eType m_EntityEffectType;
- const cEntityEffect & m_EntityEffect;
-};
-
-
-
-
-
-////////////////////////////////////////////////////////////////////////////////
// cSplashPotionEntity:
cSplashPotionEntity::cSplashPotionEntity(
@@ -119,8 +65,30 @@ void cSplashPotionEntity::OnHitEntity(cEntity & a_EntityHit, const Vector3d & a_
void cSplashPotionEntity::Splash(const Vector3d & a_HitPos)
{
- cSplashPotionCallback Callback(a_HitPos, m_EntityEffectType, m_EntityEffect);
- m_World->ForEachEntity(Callback);
+ m_World->ForEachEntity([=](cEntity & a_Entity)
+ {
+ if (!a_Entity.IsPawn())
+ {
+ // Not an entity that can take effects
+ return false;
+ }
+
+ double SplashDistance = (a_Entity.GetPosition() - a_HitPos).Length();
+ if (SplashDistance >= 20)
+ {
+ // Too far away
+ return false;
+ }
+
+ // y = -0.25x + 1, where x is the distance from the player. Approximation for potion splash.
+ // TODO: better equation
+ double Reduction = -0.25 * SplashDistance + 1.0;
+ Reduction = std::max(Reduction, 0.0);
+
+ static_cast<cPawn &>(a_Entity).AddEntityEffect(m_EntityEffectType, m_EntityEffect.GetDuration(), m_EntityEffect.GetIntensity(), Reduction);
+ return false;
+ }
+ );
m_World->BroadcastSoundParticleEffect(
EffectID::PARTICLE_SPLASH_POTION,
diff --git a/src/Entities/ThrownEnderPearlEntity.cpp b/src/Entities/ThrownEnderPearlEntity.cpp
index 4b2e2f9ff..cb0b3ada0 100644
--- a/src/Entities/ThrownEnderPearlEntity.cpp
+++ b/src/Entities/ThrownEnderPearlEntity.cpp
@@ -74,29 +74,12 @@ void cThrownEnderPearlEntity::TeleportCreator(const Vector3d & a_HitPos)
return;
}
- class cProjectileCreatorCallbackForPlayers : public cPlayerListCallback
- {
- public:
- cProjectileCreatorCallbackForPlayers(cEntity * a_Attacker, Vector3i a_CallbackHitPos) :
- m_Attacker(a_Attacker),
- m_HitPos(a_CallbackHitPos)
- {
- }
-
- virtual bool Item(cPlayer * a_Entity) override
+ GetWorld()->FindAndDoWithPlayer(m_CreatorData.m_Name, [=](cPlayer & a_Entity)
{
// Teleport the creator here, make them take 5 damage:
- a_Entity->TeleportToCoords(m_HitPos.x, m_HitPos.y + 0.2, m_HitPos.z);
- a_Entity->TakeDamage(dtEnderPearl, m_Attacker, 5, 0);
+ a_Entity.TeleportToCoords(a_HitPos.x, a_HitPos.y + 0.2, a_HitPos.z);
+ a_Entity.TakeDamage(dtEnderPearl, this, 5, 0);
return true;
}
-
- private:
-
- cEntity * m_Attacker;
- Vector3i m_HitPos;
- };
-
- cProjectileCreatorCallbackForPlayers PCCFP(this, a_HitPos);
- GetWorld()->FindAndDoWithPlayer(m_CreatorData.m_Name, PCCFP);
+ );
}