diff options
Diffstat (limited to 'src/Mobs')
-rw-r--r-- | src/Mobs/Creeper.cpp | 15 | ||||
-rw-r--r-- | src/Mobs/Enderman.cpp | 17 | ||||
-rw-r--r-- | src/Mobs/Ocelot.cpp | 61 | ||||
-rw-r--r-- | src/Mobs/PassiveMonster.cpp | 49 | ||||
-rw-r--r-- | src/Mobs/Wither.cpp | 19 | ||||
-rw-r--r-- | src/Mobs/Wolf.cpp | 45 |
6 files changed, 131 insertions, 75 deletions
diff --git a/src/Mobs/Creeper.cpp b/src/Mobs/Creeper.cpp index adab8c5aa..84b68cf7c 100644 --- a/src/Mobs/Creeper.cpp +++ b/src/Mobs/Creeper.cpp @@ -81,16 +81,21 @@ void cCreeper::GetDrops(cItems & a_Drops, cEntity * a_Killer) a_Killer->IsProjectile() && ((reinterpret_cast<cProjectileEntity *>(a_Killer))->GetCreatorUniqueID() != cEntity::INVALID_ID)) { - auto ProjectileCreatorCallback = [](cEntity & a_Entity) + class cProjectileCreatorCallback : public cEntityCallback + { + public: + cProjectileCreatorCallback(void) {} + + virtual bool Item(cEntity * a_Entity) override { - if (a_Entity.IsMob() && ((static_cast<cMonster &>(a_Entity)).GetMobType() == mtSkeleton)) + if (a_Entity->IsMob() && ((reinterpret_cast<cMonster *>(a_Entity))->GetMobType() == mtSkeleton)) { return true; } return false; - }; - - if (GetWorld()->DoWithEntityByID(static_cast<cProjectileEntity *>(a_Killer)->GetCreatorUniqueID(), ProjectileCreatorCallback)) + } + } PCC; + if (GetWorld()->DoWithEntityByID((reinterpret_cast<cProjectileEntity *>(a_Killer))->GetCreatorUniqueID(), PCC)) { AddRandomDropItem(a_Drops, 1, 1, static_cast<short>(m_World->GetTickRandomNumber(11) + E_ITEM_FIRST_DISC)); } diff --git a/src/Mobs/Enderman.cpp b/src/Mobs/Enderman.cpp index 000496df0..5cfe0d4cd 100644 --- a/src/Mobs/Enderman.cpp +++ b/src/Mobs/Enderman.cpp @@ -10,7 +10,8 @@ //////////////////////////////////////////////////////////////////////////////// // cPlayerLookCheck -class cPlayerLookCheck +class cPlayerLookCheck : + public cPlayerListCallback { public: cPlayerLookCheck(Vector3d a_EndermanPos, int a_SightDistance) : @@ -20,29 +21,29 @@ public: { } - bool operator () (cPlayer & a_Player) + virtual bool Item(cPlayer * a_Player) override { // Don't check players who cannot be targeted - if (!a_Player.CanMobsTarget()) + if (!a_Player->CanMobsTarget()) { return false; } // Don't check players who are more than SightDistance (64) blocks away - auto Direction = m_EndermanPos - a_Player.GetPosition(); + auto Direction = m_EndermanPos - a_Player->GetPosition(); if (Direction.Length() > m_SightDistance) { return false; } // Don't check if the player has a pumpkin on his head - if (a_Player.GetEquippedHelmet().m_ItemType == E_BLOCK_PUMPKIN) + if (a_Player->GetEquippedHelmet().m_ItemType == E_BLOCK_PUMPKIN) { return false; } // If the player's crosshair is within 5 degrees of the enderman, it counts as looking - auto LookVector = a_Player.GetLookVector(); + auto LookVector = a_Player->GetLookVector(); auto dot = Direction.Dot(LookVector); if (dot <= cos(0.09)) // 0.09 rad ~ 5 degrees { @@ -50,13 +51,13 @@ public: } // TODO: Check if endermen are angered through water in Vanilla - if (!cLineBlockTracer::LineOfSightTrace(*a_Player.GetWorld(), m_EndermanPos, a_Player.GetPosition(), cLineBlockTracer::losAirWater)) + if (!cLineBlockTracer::LineOfSightTrace(*a_Player->GetWorld(), m_EndermanPos, a_Player->GetPosition(), cLineBlockTracer::losAirWater)) { // No direct line of sight return false; } - m_Player = &a_Player; + m_Player = a_Player; return true; } diff --git a/src/Mobs/Ocelot.cpp b/src/Mobs/Ocelot.cpp index 50dd249c0..e5004a1d1 100644 --- a/src/Mobs/Ocelot.cpp +++ b/src/Mobs/Ocelot.cpp @@ -90,25 +90,30 @@ void cOcelot::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) void cOcelot::TickFollowPlayer() { - Vector3d OwnerPos; - bool OwnerFlying = false; - auto Callback = [&](cPlayer & a_Player) + class cCallback : + public cPlayerListCallback { - OwnerPos = a_Player.GetPosition(); - OwnerFlying = a_Player.IsFlying(); - return true; - }; + virtual bool Item(cPlayer * a_Player) override + { + OwnerPos = a_Player->GetPosition(); + OwnerFlying = a_Player->IsFlying(); + return true; + } + public: + Vector3d OwnerPos; + bool OwnerFlying; + } Callback; if (m_World->DoWithPlayerByUUID(m_OwnerUUID, Callback)) { // The player is present in the world, follow him: - double Distance = (OwnerPos - GetPosition()).Length(); + double Distance = (Callback.OwnerPos - GetPosition()).Length(); if (Distance > 12) { - if (!OwnerFlying) + if (!Callback.OwnerFlying) { - OwnerPos.y = FindFirstNonAirBlockPosition(OwnerPos.x, OwnerPos.z); - TeleportToCoords(OwnerPos.x, OwnerPos.y, OwnerPos.z); + Callback.OwnerPos.y = FindFirstNonAirBlockPosition(Callback.OwnerPos.x, Callback.OwnerPos.z); + TeleportToCoords(Callback.OwnerPos.x, Callback.OwnerPos.y, Callback.OwnerPos.z); } } if (Distance < 2) @@ -117,9 +122,9 @@ void cOcelot::TickFollowPlayer() } else { - if (!OwnerFlying) + if (!Callback.OwnerFlying) { - MoveToPosition(OwnerPos); + MoveToPosition(Callback.OwnerPos); } } } @@ -200,19 +205,27 @@ void cOcelot::SpawnOn(cClientHandle & a_ClientHandle) +class cFindSittingCat : + public cEntityCallback +{ + virtual bool Item(cEntity * a_Entity) override + { + return ( + (a_Entity->GetEntityType() == cEntity::etMonster) && + (static_cast<cMonster *>(a_Entity)->GetMobType() == eMonsterType::mtOcelot) && + (static_cast<cOcelot *>(a_Entity)->IsSitting()) + ); + } +}; + + + + + bool cOcelot::IsCatSittingOnBlock(cWorld * a_World, Vector3d a_BlockPosition) { - return a_World->ForEachEntityInBox( - cBoundingBox(Vector3d(a_BlockPosition.x, a_BlockPosition.y + 1, a_BlockPosition.z), 1), - [=](cEntity & a_Entity) - { - return ( - (a_Entity.GetEntityType() == cEntity::etMonster) && - (static_cast<cMonster &>(a_Entity).GetMobType() == eMonsterType::mtOcelot) && - (static_cast<cOcelot &>(a_Entity).IsSitting()) - ); - } - ); + cFindSittingCat FindSittingCat; + return a_World->ForEachEntityInBox(cBoundingBox(Vector3d(a_BlockPosition.x, a_BlockPosition.y + 1, a_BlockPosition.z), 1), FindSittingCat); } diff --git a/src/Mobs/PassiveMonster.cpp b/src/Mobs/PassiveMonster.cpp index c9345662d..a2089e13f 100644 --- a/src/Mobs/PassiveMonster.cpp +++ b/src/Mobs/PassiveMonster.cpp @@ -109,18 +109,23 @@ void cPassiveMonster::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) Vector3f Pos = (GetPosition() + m_LovePartner->GetPosition()) * 0.5; UInt32 BabyID = m_World->SpawnMob(Pos.x, Pos.y, Pos.z, GetMobType(), true); - cPassiveMonster * Baby = nullptr; - - m_World->DoWithEntityByID(BabyID, [&](cEntity & a_Entity) + class cBabyInheritCallback : + public cEntityCallback + { + public: + cPassiveMonster * Baby; + cBabyInheritCallback() : Baby(nullptr) { } + virtual bool Item(cEntity * a_Entity) override { - Baby = static_cast<cPassiveMonster *>(&a_Entity); + Baby = static_cast<cPassiveMonster *>(a_Entity); return true; } - ); + } Callback; - if (Baby != nullptr) + m_World->DoWithEntityByID(BabyID, Callback); + if (Callback.Baby != nullptr) { - Baby->InheritFromParents(this, m_LovePartner); + Callback.Baby->InheritFromParents(this, m_LovePartner); } m_World->SpawnExperienceOrb(Pos.x, Pos.y, Pos.z, GetRandomProvider().RandInt(1, 6)); @@ -154,37 +159,49 @@ void cPassiveMonster::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) { if (m_LovePartner == nullptr) { - m_World->ForEachEntityInBox(cBoundingBox(GetPosition(), 8, 8), [=](cEntity & a_Entity) + class LookForLover : public cEntityCallback + { + public: + cEntity * m_Me; + + LookForLover(cEntity * a_Me) : + m_Me(a_Me) + { + } + + virtual bool Item(cEntity * a_Entity) override { // If the entity is not a monster, don't breed with it // Also, do not self-breed - if ((a_Entity.GetEntityType() != etMonster) || (&a_Entity == this)) + if ((a_Entity->GetEntityType() != etMonster) || (a_Entity == m_Me)) { return false; } - auto & Me = static_cast<cPassiveMonster&>(*this); - auto & PotentialPartner = static_cast<cPassiveMonster&>(a_Entity); + cPassiveMonster * Me = static_cast<cPassiveMonster*>(m_Me); + cPassiveMonster * PotentialPartner = static_cast<cPassiveMonster*>(a_Entity); // If the potential partner is not of the same species, don't breed with it - if (PotentialPartner.GetMobType() != Me.GetMobType()) + if (PotentialPartner->GetMobType() != Me->GetMobType()) { return false; } // If the potential partner is not in love // Or they already have a mate, do not breed with them - if ((!PotentialPartner.IsInLove()) || (PotentialPartner.GetPartner() != nullptr)) + if ((!PotentialPartner->IsInLove()) || (PotentialPartner->GetPartner() != nullptr)) { return false; } // All conditions met, let's breed! - PotentialPartner.EngageLoveMode(&Me); - Me.EngageLoveMode(&PotentialPartner); + PotentialPartner->EngageLoveMode(Me); + Me->EngageLoveMode(PotentialPartner); return true; } - ); + } Callback(this); + + m_World->ForEachEntityInBox(cBoundingBox(GetPosition(), 8, 8, -4), Callback); } m_LoveTimer--; diff --git a/src/Mobs/Wither.cpp b/src/Mobs/Wither.cpp index 2cf564fca..dd85d7d2b 100644 --- a/src/Mobs/Wither.cpp +++ b/src/Mobs/Wither.cpp @@ -101,19 +101,28 @@ void cWither::KilledBy(TakeDamageInfo & a_TDI) { super::KilledBy(a_TDI); - Vector3d Pos = GetPosition(); - m_World->ForEachPlayer([=](cPlayer & a_Player) + class cPlayerCallback : public cPlayerListCallback + { + Vector3f m_Pos; + + virtual bool Item(cPlayer * a_Player) { // TODO 2014-05-21 xdot: Vanilla minecraft uses an AABB check instead of a radius one - double Dist = (a_Player.GetPosition() - Pos).Length(); + double Dist = (a_Player->GetPosition() - m_Pos).Length(); if (Dist < 50.0) { // If player is close, award achievement - a_Player.AwardAchievement(achKillWither); + a_Player->AwardAchievement(achKillWither); } return false; } - ); + + public: + cPlayerCallback(const Vector3f & a_Pos) : m_Pos(a_Pos) {} + + } PlayerCallback(GetPosition()); + + m_World->ForEachPlayer(PlayerCallback); } diff --git a/src/Mobs/Wolf.cpp b/src/Mobs/Wolf.cpp index 45df3dd05..f3b859c76 100644 --- a/src/Mobs/Wolf.cpp +++ b/src/Mobs/Wolf.cpp @@ -80,13 +80,19 @@ void cWolf::NotifyAlliesOfFight(cPawn * a_Opponent) return; } m_NotificationCooldown = 15; - - m_World->DoWithPlayerByUUID(m_OwnerUUID, [=](cPlayer & a_Player) + class cCallback : public cPlayerListCallback + { + virtual bool Item(cPlayer * a_Player) override { - a_Player.NotifyNearbyWolves(a_Opponent, false); + a_Player->NotifyNearbyWolves(m_Opponent, false); return false; } - ); + public: + cPawn * m_Opponent; + } Callback; + + Callback.m_Opponent = a_Opponent; + m_World->DoWithPlayerByUUID(m_OwnerUUID, Callback); } bool cWolf::Attack(std::chrono::milliseconds a_Dt) @@ -341,25 +347,30 @@ void cWolf::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) void cWolf::TickFollowPlayer() { - Vector3d OwnerPos; - bool OwnerFlying; - auto Callback = [&](cPlayer & a_Player) + class cCallback : + public cPlayerListCallback { - OwnerPos = a_Player.GetPosition(); - OwnerFlying = a_Player.IsFlying(); - return true; - }; + virtual bool Item(cPlayer * a_Player) override + { + OwnerPos = a_Player->GetPosition(); + OwnerFlying = a_Player->IsFlying(); + return true; + } + public: + Vector3d OwnerPos; + bool OwnerFlying; + } Callback; if (m_World->DoWithPlayerByUUID(m_OwnerUUID, Callback)) { // The player is present in the world, follow him: - double Distance = (OwnerPos - GetPosition()).Length(); + double Distance = (Callback.OwnerPos - GetPosition()).Length(); if (Distance > 20) { - if (!OwnerFlying) + if (!Callback.OwnerFlying) { - OwnerPos.y = FindFirstNonAirBlockPosition(OwnerPos.x, OwnerPos.z); - TeleportToCoords(OwnerPos.x, OwnerPos.y, OwnerPos.z); + Callback.OwnerPos.y = FindFirstNonAirBlockPosition(Callback.OwnerPos.x, Callback.OwnerPos.z); + TeleportToCoords(Callback.OwnerPos.x, Callback.OwnerPos.y, Callback.OwnerPos.z); SetTarget(nullptr); } } @@ -374,9 +385,9 @@ void cWolf::TickFollowPlayer() { if (GetTarget() == nullptr) { - if (!OwnerFlying) + if (!Callback.OwnerFlying) { - MoveToPosition(OwnerPos); + MoveToPosition(Callback.OwnerPos); } } } |