From 359e772dee0ef4595c8ad982f17e13725f255219 Mon Sep 17 00:00:00 2001 From: LogicParrot Date: Mon, 11 Jan 2016 21:34:41 +0200 Subject: Tamed wolf assists owner (attack / defence) --- src/Mobs/Monster.h | 2 +- src/Mobs/Wolf.cpp | 118 +++++++++++++++++++++++++++++++++++++++-------------- src/Mobs/Wolf.h | 12 +++++- 3 files changed, 100 insertions(+), 32 deletions(-) (limited to 'src/Mobs') diff --git a/src/Mobs/Monster.h b/src/Mobs/Monster.h index cc830a058..43ea91471 100644 --- a/src/Mobs/Monster.h +++ b/src/Mobs/Monster.h @@ -188,7 +188,7 @@ protected: bool ReachedFinalDestination(void) { return ((m_FinalDestination - GetPosition()).SqrLength() < WAYPOINT_RADIUS * WAYPOINT_RADIUS); } /** Returns whether or not the target is close enough for attack. */ - bool TargetIsInRange(void) { return ((m_FinalDestination - GetPosition()).SqrLength() < (m_AttackRange * m_AttackRange)); } + bool TargetIsInRange(void) { ASSERT(m_Target != nullptr); return ((m_Target->GetPosition() - GetPosition()).SqrLength() < (m_AttackRange * m_AttackRange)); } /** Returns if a monster can reach a given height by jumping. */ inline bool DoesPosYRequireJump(int a_PosY) diff --git a/src/Mobs/Wolf.cpp b/src/Mobs/Wolf.cpp index 2d5cfb13f..c755e9058 100644 --- a/src/Mobs/Wolf.cpp +++ b/src/Mobs/Wolf.cpp @@ -29,7 +29,7 @@ cWolf::cWolf(void) : bool cWolf::DoTakeDamage(TakeDamageInfo & a_TDI) { - if (super::DoTakeDamage(a_TDI)) + if (!super::DoTakeDamage(a_TDI)) { return false; } @@ -55,12 +55,16 @@ bool cWolf::Attack(std::chrono::milliseconds a_Dt) { return super::Attack(a_Dt); } + else + { + m_Target = nullptr; + } } else { return super::Attack(a_Dt); } - + return false; } @@ -68,6 +72,19 @@ bool cWolf::Attack(std::chrono::milliseconds a_Dt) +void cWolf::NearbyPlayerIsFighting(cPlayer * a_Player, cEntity * a_Opponent) +{ + if ((m_Target == nullptr) && (a_Player->GetName() == m_OwnerName) && !IsSitting()) + { + m_Target = a_Opponent; + } + +} + + + + + void cWolf::OnRightClicked(cPlayer & a_Player) { if (!IsTame() && !IsAngry()) @@ -160,43 +177,65 @@ void cWolf::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) super::Tick(a_Dt, a_Chunk); } - cPlayer * a_Closest_Player = m_World->FindClosestPlayer(GetPosition(), static_cast(m_SightDistance)); - if (a_Closest_Player != nullptr) + if (m_Target == nullptr) { - switch (a_Closest_Player->GetEquippedItem().m_ItemType) + cPlayer * a_Closest_Player = m_World->FindClosestPlayer(GetPosition(), static_cast(m_SightDistance)); + if (a_Closest_Player != nullptr) { - case E_ITEM_BONE: - case E_ITEM_RAW_BEEF: - case E_ITEM_STEAK: - case E_ITEM_RAW_CHICKEN: - case E_ITEM_COOKED_CHICKEN: - case E_ITEM_ROTTEN_FLESH: - case E_ITEM_RAW_PORKCHOP: - case E_ITEM_COOKED_PORKCHOP: + switch (a_Closest_Player->GetEquippedItem().m_ItemType) { - if (!IsBegging()) + case E_ITEM_BONE: + case E_ITEM_RAW_BEEF: + case E_ITEM_STEAK: + case E_ITEM_RAW_CHICKEN: + case E_ITEM_COOKED_CHICKEN: + case E_ITEM_ROTTEN_FLESH: + case E_ITEM_RAW_PORKCHOP: + case E_ITEM_COOKED_PORKCHOP: { - SetIsBegging(true); - m_World->BroadcastEntityMetadata(*this); - } + if (!IsBegging()) + { + SetIsBegging(true); + m_World->BroadcastEntityMetadata(*this); + } - m_FinalDestination = a_Closest_Player->GetPosition(); // So that we will look at a player holding food + m_FinalDestination = a_Closest_Player->GetPosition(); // So that we will look at a player holding food - // Don't move to the player if the wolf is sitting. - if (!IsSitting()) + // Don't move to the player if the wolf is sitting. + if (!IsSitting()) + { + MoveToPosition(a_Closest_Player->GetPosition()); + } + + break; + } + default: { - MoveToPosition(a_Closest_Player->GetPosition()); + if (IsBegging()) + { + SetIsBegging(false); + m_World->BroadcastEntityMetadata(*this); + } } - - break; } - default: + } + } + else + { + if (IsSitting()) + { + m_Target = nullptr; + } + else + { + if (TargetIsInRange()) { - if (IsBegging()) - { - SetIsBegging(false); - m_World->BroadcastEntityMetadata(*this); - } + StopMovingToPosition(); + Attack(a_Dt); + } + else + { + MoveToPosition(m_Target->GetPosition()); } } } @@ -237,14 +276,33 @@ void cWolf::TickFollowPlayer() { Callback.OwnerPos.y = FindFirstNonAirBlockPosition(Callback.OwnerPos.x, Callback.OwnerPos.z); TeleportToCoords(Callback.OwnerPos.x, Callback.OwnerPos.y, Callback.OwnerPos.z); + m_Target = nullptr; + } + if (Distance < 2) + { + if (m_Target == nullptr) + { + StopMovingToPosition(); + } } else { - MoveToPosition(Callback.OwnerPos); + if (m_Target == nullptr) + { + MoveToPosition(Callback.OwnerPos); + } } } } +void cWolf::InStateIdle(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) +{ + if (!IsTame()) + { + cMonster::InStateIdle(a_Dt, a_Chunk); + } +} + diff --git a/src/Mobs/Wolf.h b/src/Mobs/Wolf.h index ed37367b9..57178a3f4 100644 --- a/src/Mobs/Wolf.h +++ b/src/Mobs/Wolf.h @@ -12,7 +12,7 @@ class cWolf : public cPassiveAggressiveMonster { typedef cPassiveAggressiveMonster super; - + public: cWolf(void); @@ -45,6 +45,16 @@ public: m_OwnerUUID = a_NewOwnerUUID; } + /** Notfies the wolf that the player a_Player is being attacked by a_Attacker. + The wolf will then defend the player by attacking a_Attacker if all these conditions are met: + - a_Player is the wolf's owner. + - The wolf is not already attacking a mob. + - The wolf is not sitting. + This is called by cPlayer::NotifyFriendlyWolves whenever a player takes or deals damage and a wolf is nearby. */ + void NearbyPlayerIsFighting(cPlayer * a_Player, cEntity * a_Opponent); + + virtual void InStateIdle(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override; + protected: bool m_IsSitting; -- cgit v1.2.3