summaryrefslogtreecommitdiffstats
path: root/src/Mobs
diff options
context:
space:
mode:
Diffstat (limited to 'src/Mobs')
-rw-r--r--src/Mobs/Creeper.cpp15
-rw-r--r--src/Mobs/Enderman.cpp17
-rw-r--r--src/Mobs/Ocelot.cpp61
-rw-r--r--src/Mobs/PassiveMonster.cpp49
-rw-r--r--src/Mobs/Wither.cpp19
-rw-r--r--src/Mobs/Wolf.cpp45
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);
}
}
}