1
0

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
This commit is contained in:
changyong guo
2018-07-23 17:24:00 +08:00
committed by peterbell10
parent 7b0db672d1
commit 01e72ddb65
7 changed files with 129 additions and 20 deletions

View File

@@ -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<UInt32>(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<float>(OverlapSize / EntitySize);
}
else
{
return 0;
}
}