diff options
Diffstat (limited to '')
-rw-r--r-- | src/Entities/Entity.cpp | 33 | ||||
-rw-r--r-- | src/Entities/Floater.cpp | 45 | ||||
-rw-r--r-- | src/Entities/LeashKnot.cpp | 61 | ||||
-rw-r--r-- | src/Entities/Minecart.cpp | 23 | ||||
-rw-r--r-- | src/Entities/Pawn.cpp | 68 | ||||
-rw-r--r-- | src/Entities/Pickup.cpp | 23 | ||||
-rw-r--r-- | src/Entities/Player.cpp | 73 | ||||
-rw-r--r-- | src/Entities/ProjectileEntity.cpp | 40 | ||||
-rw-r--r-- | src/Entities/SplashPotionEntity.cpp | 80 | ||||
-rw-r--r-- | src/Entities/ThrownEnderPearlEntity.cpp | 25 |
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); + ); } |