diff options
-rw-r--r-- | src/Mobs/Behaviors/BehaviorBreeder.cpp | 216 |
1 files changed, 170 insertions, 46 deletions
diff --git a/src/Mobs/Behaviors/BehaviorBreeder.cpp b/src/Mobs/Behaviors/BehaviorBreeder.cpp index b43b9da0e..cec7e6295 100644 --- a/src/Mobs/Behaviors/BehaviorBreeder.cpp +++ b/src/Mobs/Behaviors/BehaviorBreeder.cpp @@ -33,9 +33,7 @@ void cBehaviorBreeder::AttachToMonster(cMonster & a_Parent) -/* - * CODE to be used AFTER the lambda merge - * void cBehaviorBreeder::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) +void cBehaviorBreeder::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) { LOGD("mobDebug - Behavior Breeder: Tick"); UNUSED(a_Dt); @@ -56,17 +54,23 @@ void cBehaviorBreeder::AttachToMonster(cMonster & a_Parent) Vector3f Pos = (m_Parent->GetPosition() + m_LovePartner->GetPosition()) * 0.5; UInt32 BabyID = World->SpawnMob(Pos.x, Pos.y, Pos.z, m_Parent->GetMobType(), true); - cMonster * Baby = nullptr; - - m_Parent->GetWorld()->DoWithEntityByID(BabyID, [&](cEntity & a_Entity) + class cBabyInheritCallback : + public cEntityCallback { - Baby = static_cast<cMonster *>(&a_Entity); - return true; - }); - - if (Baby != nullptr) + 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) { - Baby->InheritFromParents(m_Parent, m_LovePartner); + Callback.Baby->InheritFromParents(m_Parent, m_LovePartner); } cFastRandom Random; @@ -76,9 +80,7 @@ void cBehaviorBreeder::AttachToMonster(cMonster & a_Parent) ResetLoveMode(); } } -}*/ - - +} @@ -106,8 +108,7 @@ void cBehaviorBreeder::PostTick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk -/*** CODE TO BE USED AFTER the lambda merge - * bool cBehaviorBreeder::IsControlDesired(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) +bool cBehaviorBreeder::IsControlDesired(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) { UNUSED(a_Dt); UNUSED(a_Chunk); @@ -122,41 +123,51 @@ void cBehaviorBreeder::PostTick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk // If we are in love mode and we have no partner, try to find one if (m_LoveTimer > 0) { - m_Parent->GetWorld()->ForEachEntityInBox(cBoundingBox(m_Parent->GetPosition(), 8, 8), [=](cEntity & a_Entity) + class LookForLover : public cEntityCallback { - // 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_Parent)) - { - 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_Parent->GetMobType()) + public: + cMonster * m_Me; + LookForLover(cMonster * a_Me) : + m_Me(a_Me) { - return false; } - auto PartnerBreedingBehavior = PotentialPartner->GetBehaviorBreeder(); - auto MyBreedingBehavior = m_Parent->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)) + virtual bool Item(cEntity * a_Entity) override { - return false; + // 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); - // All conditions met, let's breed! - PartnerBreedingBehavior->EngageLoveMode(m_Parent); - MyBreedingBehavior->EngageLoveMode(PotentialPartner); - return true; - }); - - + 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 @@ -164,7 +175,7 @@ void cBehaviorBreeder::PostTick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk } return false; -} **/ +} void cBehaviorBreeder::Destroyed() { @@ -239,3 +250,116 @@ bool cBehaviorBreeder::IsInLoveCooldown() const { return (m_LoveCooldown > 0); } + + + + +/*** CODE TO BE USED AFTER the lambda merge + * bool cBehaviorBreeder::IsControlDesired(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) +{ + UNUSED(a_Dt); + UNUSED(a_Chunk); + 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) + { + m_Parent->GetWorld()->ForEachEntityInBox(cBoundingBox(m_Parent->GetPosition(), 8, 8), [=](cEntity & a_Entity) + { + // 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_Parent)) + { + 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_Parent->GetMobType()) + { + return false; + } + + auto PartnerBreedingBehavior = PotentialPartner->GetBehaviorBreeder(); + auto MyBreedingBehavior = m_Parent->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_Parent); + MyBreedingBehavior->EngageLoveMode(PotentialPartner); + return true; + }); + + + if (m_LovePartner != nullptr) + { + return true; // We found love and took control of the monster, prevent other Behaviors from doing so + } + } + + return false; +} **/ + + + + + + +/* + * CODE to be used AFTER the lambda merge + * void cBehaviorBreeder::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) +{ + LOGD("mobDebug - Behavior Breeder: Tick"); + UNUSED(a_Dt); + UNUSED(a_Chunk); + 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); + + cMonster * Baby = nullptr; + + m_Parent->GetWorld()->DoWithEntityByID(BabyID, [&](cEntity & a_Entity) + { + Baby = static_cast<cMonster *>(&a_Entity); + return true; + }); + + if (Baby != nullptr) + { + 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(); + } + } +}*/ |