From 01e72ddb6567531b16f92af2564b853878b6ef65 Mon Sep 17 00:00:00 2001 From: changyong guo Date: Mon, 23 Jul 2018 17:24:00 +0800 Subject: Rewrite explosion knock back (#4251) 1. Base knockback on an entity's bounding box intersection with the explosion 2. Armor blast protection reduces knockback 3. Don't apply knockback to players flying in creative mode Fixes #4139 --- src/Entities/Entity.cpp | 64 ++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 63 insertions(+), 1 deletion(-) (limited to 'src/Entities/Entity.cpp') diff --git a/src/Entities/Entity.cpp b/src/Entities/Entity.cpp index d1fdcfd39..4ecc5c4da 100644 --- a/src/Entities/Entity.cpp +++ b/src/Entities/Entity.cpp @@ -14,7 +14,7 @@ #include "Items/ItemHandler.h" #include "../FastRandom.h" #include "../NetherPortalScanner.h" - +#include "../BoundingBox.h" @@ -690,6 +690,33 @@ int cEntity::GetEnchantmentCoverAgainst(const cEntity * a_Attacker, eDamageType + +float cEntity::GetEnchantmentBlastKnockbackReduction() +{ + UInt32 MaxLevel = 0; + + const cItem ArmorItems[] = { GetEquippedHelmet(), GetEquippedChestplate(), GetEquippedLeggings(), GetEquippedBoots() }; + + for (auto & Item : ArmorItems) + { + UInt32 Level = Item.m_Enchantments.GetLevel(cEnchantments::enchBlastProtection); + if (Level > MaxLevel) + { + // Get max blast protection + MaxLevel = Level; + } + } + + // Max blast protect level is 4, each level provide 15% knock back reduction + MaxLevel = std::min(MaxLevel, 4); + return MaxLevel * 0.15f; +} + + + + + + int cEntity::GetArmorCoverAgainst(const cEntity * a_Attacker, eDamageType a_DamageType, int a_Damage) { // Returns the hitpoints out of a_RawDamage that the currently equipped armor would cover @@ -2241,3 +2268,38 @@ void cEntity::RemoveLeashedMob(cMonster * a_Monster) m_LeashedMobs.remove(a_Monster); } + + + + + + +float cEntity::GetExplosionExposureRate(Vector3d a_ExplosionPosition, float a_ExlosionPower) +{ + double EntitySize = m_Width * m_Width * m_Height; + if (EntitySize <= 0) + { + // Handle entity with invalid size + return 0; + } + + cBoundingBox EntityBox(GetPosition(), m_Width / 2, m_Height); + cBoundingBox ExplosionBox(a_ExplosionPosition, a_ExlosionPower * 2.0); + cBoundingBox IntersectionBox(EntityBox); + + bool Overlap = EntityBox.Intersect(ExplosionBox, IntersectionBox); + if (Overlap) + { + Vector3d Diff = IntersectionBox.GetMax() - IntersectionBox.GetMin(); + double OverlapSize = Diff.x * Diff.y * Diff.z; + + return static_cast(OverlapSize / EntitySize); + } + else + { + return 0; + } +} + + + -- cgit v1.2.3