Fix explosion knockback issues and tweak knockback strength (#4590)
This commit is contained in:
parent
25d5e1bfe1
commit
59e38d1a46
@ -1313,18 +1313,19 @@ void cChunkMap::DoExplosionAt(double a_ExplosionSize, double a_BlockX, double a_
|
|||||||
a_Entity.TakeDamage(dtExplosion, nullptr, static_cast<int>((1 / std::max(1.0, DistanceFromExplosion.Length())) * 8 * ExplosionSizeInt), 0);
|
a_Entity.TakeDamage(dtExplosion, nullptr, static_cast<int>((1 / std::max(1.0, DistanceFromExplosion.Length())) * 8 * ExplosionSizeInt), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
double Length = DistanceFromExplosion.Length();
|
float EntityExposure = a_Entity.GetExplosionExposureRate(ExplosionPos, static_cast<float>(a_ExplosionSize));
|
||||||
if (Length <= ExplosionSizeInt) // Entity is impacted by explosion
|
|
||||||
|
// Exposure reduced by armor
|
||||||
|
EntityExposure = EntityExposure * (1.0f - a_Entity.GetEnchantmentBlastKnockbackReduction());
|
||||||
|
|
||||||
|
auto Impact = std::pow(std::max(0.2, DistanceFromExplosion.Length()), -1);
|
||||||
|
Impact *= EntityExposure * ExplosionSizeInt * 6.0;
|
||||||
|
|
||||||
|
if (Impact > 0.0)
|
||||||
{
|
{
|
||||||
float EntityExposure = a_Entity.GetExplosionExposureRate(ExplosionPos, static_cast<float>(a_ExplosionSize));
|
|
||||||
|
|
||||||
// Exposure reduced by armor
|
|
||||||
EntityExposure = EntityExposure * (1.0f - a_Entity.GetEnchantmentBlastKnockbackReduction());
|
|
||||||
|
|
||||||
double Impact = (1 - ((Length / ExplosionSizeInt) / 2)) * EntityExposure;
|
|
||||||
|
|
||||||
DistanceFromExplosion.Normalize();
|
DistanceFromExplosion.Normalize();
|
||||||
DistanceFromExplosion *= Impact;
|
DistanceFromExplosion *= Vector3d{Impact, 0.0, Impact};
|
||||||
|
DistanceFromExplosion.y += 0.3 * Impact;
|
||||||
|
|
||||||
a_Entity.SetSpeed(DistanceFromExplosion);
|
a_Entity.SetSpeed(DistanceFromExplosion);
|
||||||
}
|
}
|
||||||
@ -2315,8 +2316,3 @@ void cChunkMap::DelChunkStay(cChunkStay & a_ChunkStay)
|
|||||||
} // for itr - Chunks[]
|
} // for itr - Chunks[]
|
||||||
a_ChunkStay.OnDisabled();
|
a_ChunkStay.OnDisabled();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -3080,7 +3080,7 @@ float cPlayer::GetExplosionExposureRate(Vector3d a_ExplosionPosition, float a_Ex
|
|||||||
return 0; // No impact from explosion
|
return 0; // No impact from explosion
|
||||||
}
|
}
|
||||||
|
|
||||||
return super::GetExplosionExposureRate(a_ExplosionPosition, a_ExlosionPower);
|
return super::GetExplosionExposureRate(a_ExplosionPosition, a_ExlosionPower) / 30.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -581,6 +581,9 @@ public:
|
|||||||
Otherwise it returns the dig speed (float GetDigSpeed(BLOCKTYPE a_Block)) divided by the block hardness (cBlockInfo::GetHardness(BLOCKTYPE a_Block)) divided by 30 if the player can harvest the block and divided by 100 if he can't. */
|
Otherwise it returns the dig speed (float GetDigSpeed(BLOCKTYPE a_Block)) divided by the block hardness (cBlockInfo::GetHardness(BLOCKTYPE a_Block)) divided by 30 if the player can harvest the block and divided by 100 if he can't. */
|
||||||
float GetPlayerRelativeBlockHardness(BLOCKTYPE a_Block);
|
float GetPlayerRelativeBlockHardness(BLOCKTYPE a_Block);
|
||||||
|
|
||||||
|
/** get player explosion exposure rate */
|
||||||
|
virtual float GetExplosionExposureRate(Vector3d a_ExplosionPosition, float a_ExlosionPower) override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
typedef std::vector<std::vector<AString> > AStringVectorVector;
|
typedef std::vector<std::vector<AString> > AStringVectorVector;
|
||||||
@ -759,9 +762,6 @@ protected:
|
|||||||
/** Returns the filename for the player data based on the UUID given.
|
/** Returns the filename for the player data based on the UUID given.
|
||||||
This can be used both for online and offline UUIDs. */
|
This can be used both for online and offline UUIDs. */
|
||||||
AString GetUUIDFileName(const cUUID & a_UUID);
|
AString GetUUIDFileName(const cUUID & a_UUID);
|
||||||
|
|
||||||
/** get player explosion exposure rate */
|
|
||||||
virtual float GetExplosionExposureRate(Vector3d a_ExplosionPosition, float a_ExlosionPower) override;
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
/** Pins the player to a_Location until Unfreeze() is called.
|
/** Pins the player to a_Location until Unfreeze() is called.
|
||||||
|
@ -1417,17 +1417,20 @@ void cWorld::DoExplosionAt(double a_ExplosionSize, double a_BlockX, double a_Blo
|
|||||||
|
|
||||||
BroadcastSoundEffect("entity.generic.explode", Vector3d(a_BlockX, a_BlockY, a_BlockZ), 4.0f, SoundPitchMultiplier * 0.7f);
|
BroadcastSoundEffect("entity.generic.explode", Vector3d(a_BlockX, a_BlockY, a_BlockZ), 4.0f, SoundPitchMultiplier * 0.7f);
|
||||||
|
|
||||||
|
Vector3d ExplosionPos(a_BlockX, a_BlockY, a_BlockZ);
|
||||||
{
|
{
|
||||||
cCSLock Lock(m_CSPlayers);
|
cCSLock Lock(m_CSPlayers);
|
||||||
for (cPlayerList::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr)
|
for (auto Player : m_Players)
|
||||||
{
|
{
|
||||||
cClientHandle * ch = (*itr)->GetClientHandle();
|
cClientHandle * ch = Player->GetClientHandle();
|
||||||
if (ch == nullptr)
|
if (ch == nullptr)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
ch->SendExplosion(a_BlockX, a_BlockY, a_BlockZ, static_cast<float>(a_ExplosionSize), BlocksAffected, (*itr)->GetSpeed());
|
bool InRange = (Player->GetExplosionExposureRate(ExplosionPos, static_cast<float>(a_ExplosionSize)) > 0);
|
||||||
|
auto Speed = InRange ? Player->GetSpeed() : Vector3d{};
|
||||||
|
ch->SendExplosion(a_BlockX, a_BlockY, a_BlockZ, static_cast<float>(a_ExplosionSize), BlocksAffected, Speed);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user