From 439b3304f4c82448b0e1585f8641503691212cac Mon Sep 17 00:00:00 2001 From: LogicParrot Date: Fri, 22 Jan 2016 20:55:46 +0200 Subject: Improved tamed wolf pack cooperation and projectile reactions --- src/Entities/ArrowEntity.cpp | 2 +- src/Entities/Entity.cpp | 41 +++++++++++++++++++++++++++++++++++ src/Entities/Entity.h | 3 +++ src/Entities/Player.cpp | 16 ++++++++------ src/Entities/Player.h | 7 ++++-- src/Entities/ProjectileEntity.cpp | 18 +++++++-------- src/Entities/ThrownSnowballEntity.cpp | 2 +- 7 files changed, 68 insertions(+), 21 deletions(-) (limited to 'src/Entities') diff --git a/src/Entities/ArrowEntity.cpp b/src/Entities/ArrowEntity.cpp index 47789992c..380af101c 100644 --- a/src/Entities/ArrowEntity.cpp +++ b/src/Entities/ArrowEntity.cpp @@ -133,7 +133,7 @@ void cArrowEntity::OnHitEntity(cEntity & a_EntityHit, const Vector3d & a_HitPos) } // a_EntityHit.TakeDamage(dtRangedAttack, this, Damage, KnockbackAmount); // TODO fix knockback. - a_EntityHit.TakeDamage(dtRangedAttack, this, Damage, 0); // Until knockback is fixed. + a_EntityHit.TakeDamage(dtRangedAttack, GetCreatorUniqueID(), Damage, 0); // Until knockback is fixed. if (IsOnFire() && !a_EntityHit.IsSubmerged() && !a_EntityHit.IsSwimming()) { diff --git a/src/Entities/Entity.cpp b/src/Entities/Entity.cpp index 69f64eb40..aeb70b552 100644 --- a/src/Entities/Entity.cpp +++ b/src/Entities/Entity.cpp @@ -238,6 +238,47 @@ void cEntity::TakeDamage(eDamageType a_DamageType, cEntity * a_Attacker, int a_R +void cEntity::TakeDamage(eDamageType a_DamageType, UInt32 a_AttackerID, int a_RawDamage, double a_KnockbackAmount) +{ + class cNotifyWolves : public cEntityCallback + { + public: + + cEntity * m_Entity; + eDamageType m_DamageType; + int m_RawDamage; + double m_KnockbackAmount; + + virtual bool Item(cEntity * a_Attacker) override + { + cPawn * Attacker; + if (a_Attacker->IsPawn()) + { + Attacker = static_cast(a_Attacker); + } + else + { + Attacker = nullptr; + } + + + int FinalDamage = m_RawDamage - m_Entity->GetArmorCoverAgainst(Attacker, m_DamageType, m_RawDamage); + m_Entity->TakeDamage(m_DamageType, Attacker, m_RawDamage, FinalDamage, m_KnockbackAmount); + return true; + } + } Callback; + + Callback.m_Entity = this; + Callback.m_DamageType = a_DamageType; + Callback.m_RawDamage = a_RawDamage; + Callback.m_KnockbackAmount = a_KnockbackAmount; + m_World->DoWithEntityByID(a_AttackerID, Callback); +} + + + + + void cEntity::TakeDamage(eDamageType a_DamageType, cEntity * a_Attacker, int a_RawDamage, int a_FinalDamage, double a_KnockbackAmount) { TakeDamageInfo TDI; diff --git a/src/Entities/Entity.h b/src/Entities/Entity.h index fdc5437b3..3715fb5c4 100644 --- a/src/Entities/Entity.h +++ b/src/Entities/Entity.h @@ -263,6 +263,9 @@ public: /** Makes this entity take the specified damage. The final damage is calculated using current armor, then DoTakeDamage() called */ void TakeDamage(eDamageType a_DamageType, cEntity * a_Attacker, int a_RawDamage, double a_KnockbackAmount); + /** Makes this entity take the specified damage. The final damage is calculated using current armor, then DoTakeDamage() called */ + void TakeDamage(eDamageType a_DamageType, UInt32 a_Attacker, int a_RawDamage, double a_KnockbackAmount); + /** Makes this entity take the specified damage. The values are packed into a TDI, knockback calculated, then sent through DoTakeDamage() */ void TakeDamage(eDamageType a_DamageType, cEntity * a_Attacker, int a_RawDamage, int a_FinalDamage, double a_KnockbackAmount); diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp index dd26f1491..767ee2061 100644 --- a/src/Entities/Player.cpp +++ b/src/Entities/Player.cpp @@ -862,7 +862,7 @@ bool cPlayer::DoTakeDamage(TakeDamageInfo & a_TDI) { if (a_TDI.Attacker->IsPawn()) { - NotifyFriendlyWolves(static_cast(a_TDI.Attacker)); + NotifyNearbyWolves(static_cast(a_TDI.Attacker), true); } } m_Stats.AddValue(statDamageTaken, FloorC(a_TDI.FinalDamage * 10 + 0.5)); @@ -875,7 +875,7 @@ bool cPlayer::DoTakeDamage(TakeDamageInfo & a_TDI) -void cPlayer::NotifyFriendlyWolves(cPawn * a_Opponent) +void cPlayer::NotifyNearbyWolves(cPawn * a_Opponent, bool a_IsPlayerInvolved) { ASSERT(a_Opponent != nullptr); class LookForWolves : public cEntityCallback @@ -883,10 +883,12 @@ void cPlayer::NotifyFriendlyWolves(cPawn * a_Opponent) public: cPlayer * m_Player; cPawn * m_Attacker; + bool m_IsPlayerInvolved; - LookForWolves(cPlayer * a_Me, cPawn * a_MyAttacker) : + LookForWolves(cPlayer * a_Me, cPawn * a_MyAttacker, bool a_PlayerInvolved) : m_Player(a_Me), - m_Attacker(a_MyAttacker) + m_Attacker(a_MyAttacker), + m_IsPlayerInvolved(a_PlayerInvolved) { } @@ -898,14 +900,14 @@ void cPlayer::NotifyFriendlyWolves(cPawn * a_Opponent) if (Mob->GetMobType() == mtWolf) { cWolf * Wolf = static_cast(Mob); - Wolf->NearbyPlayerIsFighting(m_Player, m_Attacker); + Wolf->ReceiveNearbyFightInfo(m_Player->GetUUID(), m_Attacker, m_IsPlayerInvolved); } } return false; } - } Callback(this, a_Opponent); + } Callback(this, a_Opponent, a_IsPlayerInvolved); - m_World->ForEachEntityInBox(cBoundingBox(GetPosition(), 16, 16), Callback); + m_World->ForEachEntityInBox(cBoundingBox(GetPosition(), 16), Callback); } diff --git a/src/Entities/Player.h b/src/Entities/Player.h index fbb09b815..efd515b23 100644 --- a/src/Entities/Player.h +++ b/src/Entities/Player.h @@ -499,8 +499,11 @@ public: Assumes that all the blocks are in currently loaded chunks. */ 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. */ - void NotifyFriendlyWolves(cPawn * a_Opponent); + /** Notify nearby wolves that the player or one of the player's wolves took damage or did damage to an entity + @param a_Opponent the opponent we're fighting. + @param a_IsPlayerInvolved Should be true if the player took or did damage, and false if one of the player's wolves took or did damage. + */ + void NotifyNearbyWolves(cPawn * a_Opponent, bool a_IsPlayerInvolved); // cEntity overrides: virtual bool IsCrouched (void) const override { return m_IsCrouched; } diff --git a/src/Entities/ProjectileEntity.cpp b/src/Entities/ProjectileEntity.cpp index bb08f38d9..72dccbfb4 100644 --- a/src/Entities/ProjectileEntity.cpp +++ b/src/Entities/ProjectileEntity.cpp @@ -314,26 +314,24 @@ void cProjectileEntity::OnHitSolidBlock(const Vector3d & a_HitPos, eBlockFace a_ void cProjectileEntity::OnHitEntity(cEntity & a_EntityHit, const Vector3d & a_HitPos) { - if (a_EntityHit.IsPawn() && (GetCreatorName() != "")) // If we're hitting a mob or a player and we were created by a player - { + UNUSED(a_HitPos); + // If we were created by a player and we hit a pawn, notify attacking player's wolves + if (a_EntityHit.IsPawn() && (GetCreatorName() != "")) + { class cNotifyWolves : public cEntityCallback { public: cPawn * m_EntityHit; - cNotifyWolves(cPawn * a_Entity) : - m_EntityHit(a_Entity) - { - } - - virtual bool Item(cEntity * a_Player) override + virtual bool Item(cEntity * a_Hitter) override { - static_cast(a_Player)->NotifyFriendlyWolves(m_EntityHit); + static_cast(a_Hitter)->NotifyNearbyWolves(m_EntityHit, true); return true; } - } Callback(static_cast(&a_EntityHit)); + } Callback; + Callback.m_EntityHit = static_cast(&a_EntityHit); m_World->DoWithEntityByID(GetCreatorUniqueID(), Callback); } } diff --git a/src/Entities/ThrownSnowballEntity.cpp b/src/Entities/ThrownSnowballEntity.cpp index ab5429011..ef88bfd18 100644 --- a/src/Entities/ThrownSnowballEntity.cpp +++ b/src/Entities/ThrownSnowballEntity.cpp @@ -41,7 +41,7 @@ void cThrownSnowballEntity::OnHitEntity(cEntity & a_EntityHit, const Vector3d & } } // TODO: If entity is Ender Crystal, destroy it - a_EntityHit.TakeDamage(dtRangedAttack, this, TotalDamage, 1); + a_EntityHit.TakeDamage(dtRangedAttack, GetCreatorUniqueID(), TotalDamage, 1); m_DestroyTimer = 5; } -- cgit v1.2.3