1
0

Merge pull request #2878 from LogicParrot/wolf2

Fix crash when tamed wolf is hit by arrows
This commit is contained in:
LogicParrot 2016-01-16 16:58:49 +02:00
commit dc33276dda
7 changed files with 79 additions and 61 deletions

View File

@ -1640,7 +1640,10 @@ void cClientHandle::HandleUseEntity(UInt32 a_TargetEntityID, bool a_IsLeftClick)
} }
a_Entity->TakeDamage(*m_Me); a_Entity->TakeDamage(*m_Me);
m_Me->AddFoodExhaustion(0.3); m_Me->AddFoodExhaustion(0.3);
m_Me->NotifyFriendlyWolves(a_Entity); if (a_Entity->IsPawn())
{
m_Me->NotifyFriendlyWolves(static_cast<cPawn*>(a_Entity));
}
return true; return true;
} }
} Callback(m_Player); } Callback(m_Player);

View File

@ -242,7 +242,14 @@ void cEntity::TakeDamage(eDamageType a_DamageType, cEntity * a_Attacker, int a_R
{ {
TakeDamageInfo TDI; TakeDamageInfo TDI;
TDI.DamageType = a_DamageType; TDI.DamageType = a_DamageType;
if ((a_Attacker != nullptr) && a_Attacker->IsPawn())
{
TDI.Attacker = a_Attacker; TDI.Attacker = a_Attacker;
}
else
{
TDI.Attacker = nullptr;
}
TDI.RawDamage = a_RawDamage; TDI.RawDamage = a_RawDamage;
TDI.FinalDamage = a_FinalDamage; TDI.FinalDamage = a_FinalDamage;

View File

@ -856,7 +856,10 @@ bool cPlayer::DoTakeDamage(TakeDamageInfo & a_TDI)
if (a_TDI.Attacker != nullptr) if (a_TDI.Attacker != nullptr)
{ {
NotifyFriendlyWolves(a_TDI.Attacker); if (a_TDI.Attacker->IsPawn())
{
NotifyFriendlyWolves(static_cast<cPawn*>(a_TDI.Attacker));
}
} }
m_Stats.AddValue(statDamageTaken, FloorC<StatValue>(a_TDI.FinalDamage * 10 + 0.5)); m_Stats.AddValue(statDamageTaken, FloorC<StatValue>(a_TDI.FinalDamage * 10 + 0.5));
return true; return true;
@ -868,16 +871,16 @@ bool cPlayer::DoTakeDamage(TakeDamageInfo & a_TDI)
void cPlayer::NotifyFriendlyWolves(cEntity * a_Opponent) void cPlayer::NotifyFriendlyWolves(cPawn * a_Opponent)
{ {
ASSERT(a_Opponent != nullptr); ASSERT(a_Opponent != nullptr);
class LookForWolves : public cEntityCallback class LookForWolves : public cEntityCallback
{ {
public: public:
cPlayer * m_Player; cPlayer * m_Player;
cEntity * m_Attacker; cPawn * m_Attacker;
LookForWolves(cPlayer * a_Me, cEntity * a_MyAttacker) : LookForWolves(cPlayer * a_Me, cPawn * a_MyAttacker) :
m_Player(a_Me), m_Player(a_Me),
m_Attacker(a_MyAttacker) m_Attacker(a_MyAttacker)
{ {

View File

@ -500,7 +500,7 @@ public:
bool PlaceBlocks(const sSetBlockVector & a_Blocks); bool PlaceBlocks(const sSetBlockVector & a_Blocks);
/** Notify friendly wolves that we took damage or did damage to an entity so that they might assist us. */ /** Notify friendly wolves that we took damage or did damage to an entity so that they might assist us. */
void NotifyFriendlyWolves(cEntity * a_Opponent); void NotifyFriendlyWolves(cPawn * a_Opponent);
// cEntity overrides: // cEntity overrides:
virtual bool IsCrouched (void) const override { return m_IsCrouched; } virtual bool IsCrouched (void) const override { return m_IsCrouched; }

View File

@ -316,12 +316,13 @@ void cProjectileEntity::OnHitEntity(cEntity & a_EntityHit, const Vector3d & a_Hi
{ {
if (a_EntityHit.IsPawn() && (GetCreatorName() != "")) // If we're hitting a mob or a player and we were created by a player if (a_EntityHit.IsPawn() && (GetCreatorName() != "")) // If we're hitting a mob or a player and we were created by a player
{ {
class cNotifyWolves : public cEntityCallback class cNotifyWolves : public cEntityCallback
{ {
public: public:
cEntity * m_EntityHit; cPawn * m_EntityHit;
cNotifyWolves(cEntity * a_Entity) : cNotifyWolves(cPawn * a_Entity) :
m_EntityHit(a_Entity) m_EntityHit(a_Entity)
{ {
} }
@ -331,7 +332,7 @@ void cProjectileEntity::OnHitEntity(cEntity & a_EntityHit, const Vector3d & a_Hi
static_cast<cPlayer*>(a_Player)->NotifyFriendlyWolves(m_EntityHit); static_cast<cPlayer*>(a_Player)->NotifyFriendlyWolves(m_EntityHit);
return true; return true;
} }
} Callback(&a_EntityHit); } Callback(static_cast<cPawn*>(&a_EntityHit));
m_World->DoWithEntityByID(GetCreatorUniqueID(), Callback); m_World->DoWithEntityByID(GetCreatorUniqueID(), Callback);
} }

View File

@ -73,8 +73,12 @@ bool cWolf::Attack(std::chrono::milliseconds a_Dt)
void cWolf::NearbyPlayerIsFighting(cPlayer * a_Player, cEntity * a_Opponent) void cWolf::NearbyPlayerIsFighting(cPlayer * a_Player, cPawn * a_Opponent)
{ {
if (a_Opponent == nullptr)
{
return;
}
if ((m_Target == nullptr) && (a_Player->GetName() == m_OwnerName) && !IsSitting() && (a_Opponent->IsPawn())) if ((m_Target == nullptr) && (a_Player->GetName() == m_OwnerName) && !IsSitting() && (a_Opponent->IsPawn()))
{ {
m_Target = a_Opponent; m_Target = a_Opponent;

View File

@ -51,7 +51,7 @@ public:
- The wolf is not already attacking a mob. - The wolf is not already attacking a mob.
- The wolf is not sitting. - The wolf is not sitting.
This is called by cPlayer::NotifyFriendlyWolves whenever a player takes or deals damage and a wolf is nearby. */ 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); void NearbyPlayerIsFighting(cPlayer * a_Player, cPawn * a_Opponent);
virtual void InStateIdle(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override; virtual void InStateIdle(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override;