summaryrefslogtreecommitdiffstats
path: root/src/Mobs
diff options
context:
space:
mode:
Diffstat (limited to 'src/Mobs')
-rw-r--r--src/Mobs/Monster.h2
-rw-r--r--src/Mobs/Wolf.cpp118
-rw-r--r--src/Mobs/Wolf.h12
3 files changed, 100 insertions, 32 deletions
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<float>(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<float>(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;