summaryrefslogtreecommitdiffstats
path: root/src/Mobs/Behaviors/BehaviorBreeder.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/Mobs/Behaviors/BehaviorBreeder.cpp')
-rw-r--r--src/Mobs/Behaviors/BehaviorBreeder.cpp310
1 files changed, 160 insertions, 150 deletions
diff --git a/src/Mobs/Behaviors/BehaviorBreeder.cpp b/src/Mobs/Behaviors/BehaviorBreeder.cpp
index 8ba991989..34f5142e0 100644
--- a/src/Mobs/Behaviors/BehaviorBreeder.cpp
+++ b/src/Mobs/Behaviors/BehaviorBreeder.cpp
@@ -10,153 +10,163 @@
#include "../../BoundingBox.h"
cBehaviorBreeder::cBehaviorBreeder(cMonster * a_Parent) :
- m_Parent(a_Parent),
- m_LovePartner(nullptr),
- m_LoveTimer(0),
- m_LoveCooldown(0),
- m_MatingTimer(0)
+ m_Parent(a_Parent),
+ m_LovePartner(nullptr),
+ m_LoveTimer(0),
+ m_LoveCooldown(0),
+ m_MatingTimer(0)
{
- m_Parent = a_Parent;
- ASSERT(m_Parent != nullptr);
+ m_Parent = a_Parent;
+ ASSERT(m_Parent != nullptr);
}
-bool cBehaviorBreeder::ActiveTick()
+void cBehaviorBreeder::Tick()
{
- cWorld * World = m_Parent->GetWorld();
- // if we have a partner, mate
- if (m_LovePartner != nullptr)
- {
- if (m_MatingTimer > 0)
- {
- // If we should still mate, keep bumping into them until baby is made
- Vector3d Pos = m_LovePartner->GetPosition();
- m_Parent->MoveToPosition(Pos);
- }
- else
- {
- // Mating finished. Spawn baby
- Vector3f Pos = (m_Parent->GetPosition() + m_LovePartner->GetPosition()) * 0.5;
- UInt32 BabyID = World->SpawnMob(Pos.x, Pos.y, Pos.z, m_Parent->GetMobType(), true);
-
- class cBabyInheritCallback :
- public cEntityCallback
- {
- public:
- cMonster * Baby;
- cBabyInheritCallback() : Baby(nullptr) { }
- virtual bool Item(cEntity * a_Entity) override
- {
- Baby = static_cast<cMonster *>(a_Entity);
- return true;
- }
- } Callback;
-
- m_Parent->GetWorld()->DoWithEntityByID(BabyID, Callback);
- if (Callback.Baby != nullptr)
- {
- Callback.Baby->InheritFromParents(m_Parent, m_LovePartner);
- }
-
- cFastRandom Random;
- World->SpawnExperienceOrb(Pos.x, Pos.y, Pos.z, 1 + (Random.RandInt() % 6));
-
- m_LovePartner->GetBehaviorBreeder()->ResetLoveMode();
- ResetLoveMode();
- }
- return true;
- }
-
- // If we are in love mode and we have no partner
- if (m_LoveTimer > 0)
- {
- class LookForLover : public cEntityCallback
- {
- public:
- cMonster * m_Me;
- LookForLover(cMonster * 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() != cEntity::eEntityType::etMonster) || (a_Entity == m_Me))
- {
- return false;
- }
-
- auto PotentialPartner = static_cast<cMonster*>(a_Entity);
-
- // If the potential partner is not of the same species, don't breed with it
- if (PotentialPartner->GetMobType() != m_Me->GetMobType())
- {
- return false;
- }
-
- auto PartnerBreedingBehavior = PotentialPartner->GetBehaviorBreeder();
- auto MyBreedingBehavior = m_Me->GetBehaviorBreeder();
-
- // If the potential partner is not in love
- // Or they already have a mate, do not breed with them
-
- if ((!PartnerBreedingBehavior->IsInLove()) || (PartnerBreedingBehavior->GetPartner() != nullptr))
- {
- return false;
- }
-
- // All conditions met, let's breed!
- PartnerBreedingBehavior->EngageLoveMode(m_Me);
- MyBreedingBehavior->EngageLoveMode(PotentialPartner);
- return true;
- }
- } Callback(m_Parent);
-
- World->ForEachEntityInBox(cBoundingBox(m_Parent->GetPosition(), 8, 8), Callback);
- if (m_LovePartner != nullptr)
- {
- return true; // We found love and took control of the monster, prevent other Behaviors from doing so
- }
- }
-
- return false;
+ cWorld * World = m_Parent->GetWorld();
+ // if we have a partner, mate
+ if (m_LovePartner != nullptr)
+ {
+ if (m_MatingTimer > 0)
+ {
+ // If we should still mate, keep bumping into them until baby is made
+ Vector3d Pos = m_LovePartner->GetPosition();
+ m_Parent->MoveToPosition(Pos);
+ }
+ else
+ {
+ // Mating finished. Spawn baby
+ Vector3f Pos = (m_Parent->GetPosition() + m_LovePartner->GetPosition()) * 0.5;
+ UInt32 BabyID = World->SpawnMob(Pos.x, Pos.y, Pos.z, m_Parent->GetMobType(), true);
+
+ class cBabyInheritCallback :
+ public cEntityCallback
+ {
+ public:
+ cMonster * Baby;
+ cBabyInheritCallback() : Baby(nullptr) { }
+ virtual bool Item(cEntity * a_Entity) override
+ {
+ Baby = static_cast<cMonster *>(a_Entity);
+ return true;
+ }
+ } Callback;
+
+ m_Parent->GetWorld()->DoWithEntityByID(BabyID, Callback);
+ if (Callback.Baby != nullptr)
+ {
+ Callback.Baby->InheritFromParents(m_Parent, m_LovePartner);
+ }
+
+ cFastRandom Random;
+ World->SpawnExperienceOrb(Pos.x, Pos.y, Pos.z, 1 + (Random.RandInt() % 6));
+
+ m_LovePartner->GetBehaviorBreeder()->ResetLoveMode();
+ ResetLoveMode();
+ }d
+ }
}
-void cBehaviorBreeder::Tick()
+void cBehaviorBreeder::PostTick()
{
- if (m_MatingTimer > 0)
- {
- m_MatingTimer--;
- }
- if (m_LoveCooldown > 0)
- {
- m_LoveCooldown--;
- }
- if (m_LoveTimer > 0)
- {
- m_LoveTimer--;
- }
+ if (m_MatingTimer > 0)
+ {
+ m_MatingTimer--;
+ }
+ if (m_LoveCooldown > 0)
+ {
+ m_LoveCooldown--;
+ }
+ if (m_LoveTimer > 0)
+ {
+ m_LoveTimer--;
+ }
}
+bool cBehaviorBreeder::IsControlDesired()
+{
+ cWorld * World = m_Parent->GetWorld();
+
+ // if we have a love partner, we should control the mob
+ if (m_LovePartner != nullptr)
+ {
+ return true;
+ }
+
+ // If we are in love mode and we have no partner, try to find one
+ if (m_LoveTimer > 0)
+ {
+ class LookForLover : public cEntityCallback
+ {
+ public:
+ cMonster * m_Me;
+ LookForLover(cMonster * 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() != cEntity::eEntityType::etMonster) || (a_Entity == m_Me))
+ {
+ return false;
+ }
+
+ auto PotentialPartner = static_cast<cMonster*>(a_Entity);
+
+ // If the potential partner is not of the same species, don't breed with it
+ if (PotentialPartner->GetMobType() != m_Me->GetMobType())
+ {
+ return false;
+ }
+
+ auto PartnerBreedingBehavior = PotentialPartner->GetBehaviorBreeder();
+ auto MyBreedingBehavior = m_Me->GetBehaviorBreeder();
+
+ // If the potential partner is not in love
+ // Or they already have a mate, do not breed with them
+
+ if ((!PartnerBreedingBehavior->IsInLove()) || (PartnerBreedingBehavior->GetPartner() != nullptr))
+ {
+ return false;
+ }
+
+ // All conditions met, let's breed!
+ PartnerBreedingBehavior->EngageLoveMode(m_Me);
+ MyBreedingBehavior->EngageLoveMode(PotentialPartner);
+ return true;
+ }
+ } Callback(m_Parent);
+
+ World->ForEachEntityInBox(cBoundingBox(m_Parent->GetPosition(), 8, 8), Callback);
+ if (m_LovePartner != nullptr)
+ {
+ return true; // We found love and took control of the monster, prevent other Behaviors from doing so
+ }
+ }
+
+ return false;
+}
+
void cBehaviorBreeder::Destroyed()
{
- if (m_LovePartner != nullptr)
- {
- m_LovePartner->GetBehaviorBreeder()->ResetLoveMode();
- }
+ if (m_LovePartner != nullptr)
+ {
+ m_LovePartner->GetBehaviorBreeder()->ResetLoveMode();
+ }
}
@@ -165,30 +175,30 @@ void cBehaviorBreeder::Destroyed()
void cBehaviorBreeder::OnRightClicked(cPlayer & a_Player)
{
- // If a player holding breeding items right-clicked me, go into love mode
- if ((m_LoveCooldown == 0) && !IsInLove() && !m_Parent->IsBaby())
- {
- short HeldItem = a_Player.GetEquippedItem().m_ItemType;
- cItems BreedingItems;
- m_Parent->GetFollowedItems(BreedingItems);
- if (BreedingItems.ContainsType(HeldItem))
- {
- if (!a_Player.IsGameModeCreative())
- {
- a_Player.GetInventory().RemoveOneEquippedItem();
- }
- m_LoveTimer = 20 * 30; // half a minute
- m_Parent->GetWorld()->BroadcastEntityStatus(*m_Parent, cEntity::eEntityStatus::esMobInLove);
- }
- }
+ // If a player holding breeding items right-clicked me, go into love mode
+ if ((m_LoveCooldown == 0) && !IsInLove() && !m_Parent->IsBaby())
+ {
+ short HeldItem = a_Player.GetEquippedItem().m_ItemType;
+ cItems BreedingItems;
+ m_Parent->GetFollowedItems(BreedingItems);
+ if (BreedingItems.ContainsType(HeldItem))
+ {
+ if (!a_Player.IsGameModeCreative())
+ {
+ a_Player.GetInventory().RemoveOneEquippedItem();
+ }
+ m_LoveTimer = 20 * 30; // half a minute
+ m_Parent->GetWorld()->BroadcastEntityStatus(*m_Parent, cEntity::eEntityStatus::esMobInLove);
+ }
+ }
}
void cBehaviorBreeder::EngageLoveMode(cMonster * a_Partner)
{
- m_LovePartner = a_Partner;
- m_MatingTimer = 50; // about 3 seconds of mating
+ m_LovePartner = a_Partner;
+ m_MatingTimer = 50; // about 3 seconds of mating
}
@@ -197,13 +207,13 @@ void cBehaviorBreeder::EngageLoveMode(cMonster * a_Partner)
void cBehaviorBreeder::ResetLoveMode()
{
- m_LovePartner = nullptr;
- m_LoveTimer = 0;
- m_MatingTimer = 0;
- m_LoveCooldown = 20 * 60 * 5; // 5 minutes
+ m_LovePartner = nullptr;
+ m_LoveTimer = 0;
+ m_MatingTimer = 0;
+ m_LoveCooldown = 20 * 60 * 5; // 5 minutes
- // when an animal is in love mode, the client only stops sending the hearts if we let them know it's in cooldown, which is done with the "age" metadata
- m_Parent->GetWorld()->BroadcastEntityMetadata(*m_Parent);
+ // when an animal is in love mode, the client only stops sending the hearts if we let them know it's in cooldown, which is done with the "age" metadata
+ m_Parent->GetWorld()->BroadcastEntityMetadata(*m_Parent);
}
@@ -212,7 +222,7 @@ void cBehaviorBreeder::ResetLoveMode()
bool cBehaviorBreeder::IsInLove() const
{
- return m_LoveTimer > 0;
+ return m_LoveTimer > 0;
}
@@ -221,5 +231,5 @@ bool cBehaviorBreeder::IsInLove() const
bool cBehaviorBreeder::IsInLoveCooldown() const
{
- return (m_LoveCooldown > 0);
+ return (m_LoveCooldown > 0);
}