diff options
Diffstat (limited to 'src/Mobs/Behaviors')
-rw-r--r-- | src/Mobs/Behaviors/BehaviorBreeder.cpp | 304 | ||||
-rw-r--r-- | src/Mobs/Behaviors/BehaviorBreeder.h | 54 | ||||
-rw-r--r-- | src/Mobs/Behaviors/BehaviorItemFollower.cpp | 2 | ||||
-rw-r--r-- | src/Mobs/Behaviors/BehaviorItemFollower.h | 10 |
4 files changed, 177 insertions, 193 deletions
diff --git a/src/Mobs/Behaviors/BehaviorBreeder.cpp b/src/Mobs/Behaviors/BehaviorBreeder.cpp index ea3e10026..ddca1715a 100644 --- a/src/Mobs/Behaviors/BehaviorBreeder.cpp +++ b/src/Mobs/Behaviors/BehaviorBreeder.cpp @@ -9,25 +9,15 @@ #include "../../Item.h" #include "../../BoundingBox.h" -iBehaviorBreeder::~iBehaviorBreeder() +cBehaviorBreeder::cBehaviorBreeder(cMonster * a_Parent) : + m_Parent(a_Parent), + m_LovePartner(nullptr), + m_LoveTimer(0), + m_LoveCooldown(0), + m_MatingTimer(0), { - -} - - - - - -cBehaviorBreeder::cBehaviorBreeder(cMonster * a_Parent, cItems & a_BreedingItems) : - m_Parent(a_Parent), - m_LovePartner(nullptr), - m_LoveTimer(0), - m_LoveCooldown(0), - m_MatingTimer(0), - m_BreedingItems(a_BreedingItems) -{ - m_Parent = dynamic_cast<cMonster *>(m_ParentInterface); - ASSERT(m_Parent != nullptr); + m_Parent = a_Parent; + ASSERT(m_Parent != nullptr); } @@ -36,105 +26,105 @@ cBehaviorBreeder::cBehaviorBreeder(cMonster * a_Parent, cItems & a_BreedingItems bool cBehaviorBreeder::ActiveTick() { - 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.NextInt(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.NextInt(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; } @@ -143,18 +133,18 @@ bool cBehaviorBreeder::ActiveTick() void cBehaviorBreeder::Tick() { - 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--; + } } @@ -163,10 +153,10 @@ void cBehaviorBreeder::Tick() void cBehaviorBreeder::Destroyed() { - if (m_LovePartner != nullptr) - { - m_LovePartner->GetBehaviorBreeder()->ResetLoveMode(); - } + if (m_LovePartner != nullptr) + { + m_LovePartner->GetBehaviorBreeder()->ResetLoveMode(); + } } @@ -175,28 +165,28 @@ 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; - if (m_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; + if (m_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 } @@ -205,13 +195,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); } @@ -220,7 +210,7 @@ void cBehaviorBreeder::ResetLoveMode() bool cBehaviorBreeder::IsInLove() const { - return m_LoveTimer > 0; + return m_LoveTimer > 0; } @@ -229,5 +219,5 @@ bool cBehaviorBreeder::IsInLove() const bool cBehaviorBreeder::IsInLoveCooldown() const { - return (m_LoveCooldown > 0); + return (m_LoveCooldown > 0); } diff --git a/src/Mobs/Behaviors/BehaviorBreeder.h b/src/Mobs/Behaviors/BehaviorBreeder.h index 4d7dc1aa4..fa52a40d4 100644 --- a/src/Mobs/Behaviors/BehaviorBreeder.h +++ b/src/Mobs/Behaviors/BehaviorBreeder.h @@ -17,44 +17,42 @@ class cBehaviorBreeder { public: - cBehaviorBreeder(cMonster * a_Parent, cItems & a_BreedingItems); + cBehaviorBreeder(cMonster * a_Parent, cItems & a_BreedingItems); - // Functions our host Monster should invoke: - void Tick(); - bool ActiveTick(); - void OnRightClicked(cPlayer & a_Player); - void Destroyed(); + // Functions our host Monster should invoke: + void Tick(); + bool ActiveTick(); + void OnRightClicked(cPlayer & a_Player); + void Destroyed(); - /** Returns the partner which the monster is currently mating with. */ - cMonster * GetPartner(void) const { return m_LovePartner; } + /** Returns the partner which the monster is currently mating with. */ + cMonster * GetPartner(void) const { return m_LovePartner; } - /** Start the mating process. Causes the monster to keep bumping into the partner until m_MatingTimer reaches zero. */ - void EngageLoveMode(cMonster * a_Partner); + /** Start the mating process. Causes the monster to keep bumping into the partner until m_MatingTimer reaches zero. */ + void EngageLoveMode(cMonster * a_Partner); - /** Finish the mating process. Called after a baby is born. Resets all breeding related timers and sets m_LoveCooldown to 20 minutes. */ - void ResetLoveMode(); + /** Finish the mating process. Called after a baby is born. Resets all breeding related timers and sets m_LoveCooldown to 20 minutes. */ + void ResetLoveMode(); - /** Returns whether the monster has just been fed and is ready to mate. If this is "true" and GetPartner isn't "nullptr", then the monster is mating. */ - bool IsInLove() const; + /** Returns whether the monster has just been fed and is ready to mate. If this is "true" and GetPartner isn't "nullptr", then the monster is mating. */ + bool IsInLove() const; - /** Returns whether the monster is tired of breeding and is in the cooldown state. */ - bool IsInLoveCooldown() const; + /** Returns whether the monster is tired of breeding and is in the cooldown state. */ + bool IsInLoveCooldown() const; private: - /** Our parent */ - cMonster * m_Parent; + /** Our parent */ + cMonster * m_Parent; - /** The monster's breeding partner. */ - cMonster * m_LovePartner; + /** The monster's breeding partner. */ + cMonster * m_LovePartner; - /** If above 0, the monster is in love mode, and will breed if a nearby monster is also in love mode. Decrements by 1 per tick till reaching zero. */ - int m_LoveTimer; + /** If above 0, the monster is in love mode, and will breed if a nearby monster is also in love mode. Decrements by 1 per tick till reaching zero. */ + int m_LoveTimer; - /** If above 0, the monster is in cooldown mode and will refuse to breed. Decrements by 1 per tick till reaching zero. */ - int m_LoveCooldown; + /** If above 0, the monster is in cooldown mode and will refuse to breed. Decrements by 1 per tick till reaching zero. */ + int m_LoveCooldown; - /** The monster is engaged in mating, once this reaches zero, a baby will be born. Decrements by 1 per tick till reaching zero, then a baby is made and ResetLoveMode() is called. */ - int m_MatingTimer; - - cItems & m_BreedingItems; + /** The monster is engaged in mating, once this reaches zero, a baby will be born. Decrements by 1 per tick till reaching zero, then a baby is made and ResetLoveMode() is called. */ + int m_MatingTimer; }; diff --git a/src/Mobs/Behaviors/BehaviorItemFollower.cpp b/src/Mobs/Behaviors/BehaviorItemFollower.cpp index 89e25ed57..275cb8c24 100644 --- a/src/Mobs/Behaviors/BehaviorItemFollower.cpp +++ b/src/Mobs/Behaviors/BehaviorItemFollower.cpp @@ -21,7 +21,7 @@ bool cBehaviorItemFollower::ActiveTick() { cWorld * World = m_Parent->GetWorld(); cItems FollowedItems; - m_ParentInterface->GetFollowedItems(FollowedItems); + m_Parent->GetFollowedItems(FollowedItems); if (FollowedItems.Size() > 0) { cPlayer * a_Closest_Player = m_Parent->GetNearestPlayer(); diff --git a/src/Mobs/Behaviors/BehaviorItemFollower.h b/src/Mobs/Behaviors/BehaviorItemFollower.h index 2abdeb381..28f00c473 100644 --- a/src/Mobs/Behaviors/BehaviorItemFollower.h +++ b/src/Mobs/Behaviors/BehaviorItemFollower.h @@ -3,20 +3,16 @@ // Makes the mob follow specific held items class cBehaviorItemFollower; -class iBehaviorItemFollower; - //fwds class cMonster; class cItems; - - - - class cBehaviorItemFollower { public: - cBehaviorItemFollower(cMonster * a_Parent); + cBehaviorItemFollower(cMonster * a_Parent, cItems & a_Items); + + void GetBreedingItems(cItems & a_Items); // Functions our host Monster should invoke: bool ActiveTick(); |