Use tracing for explosions (#4845)
* TNT: Implement tracing algorithm + Add intensity tracing * Fix iterating over all players to SendExplosion, even those not in range * Implemented TNT entity interaction * Fixed misaligned destruction tracing * Finalise TNT algorithm - Remove BlockArea and just use chunks Using SetBlock makes it so that we can update everything properly, and does appear to be faster. * BlockInfo learns about explosion attentuation * Rename Explodinator parameters * TNT: pull block destruction into common function Co-authored-by: Alexander Harkness <me@bearbin.net>
This commit is contained in:
@@ -4,6 +4,7 @@
|
||||
#include "World.h"
|
||||
#include "BlockInfo.h"
|
||||
#include "ClientHandle.h"
|
||||
#include "Physics/Explodinator.h"
|
||||
#include "Server.h"
|
||||
#include "Root.h"
|
||||
#include "IniFile.h"
|
||||
@@ -1393,47 +1394,13 @@ bool cWorld::ForEachFurnaceInChunk(int a_ChunkX, int a_ChunkZ, cFurnaceCallback
|
||||
void cWorld::DoExplosionAt(double a_ExplosionSize, double a_BlockX, double a_BlockY, double a_BlockZ, bool a_CanCauseFire, eExplosionSource a_Source, void * a_SourceData)
|
||||
{
|
||||
cLock Lock(*this);
|
||||
if (cPluginManager::Get()->CallHookExploding(*this, a_ExplosionSize, a_CanCauseFire, a_BlockX, a_BlockY, a_BlockZ, a_Source, a_SourceData) || (a_ExplosionSize <= 0))
|
||||
|
||||
if (!cPluginManager::Get()->CallHookExploding(*this, a_ExplosionSize, a_CanCauseFire, a_BlockX, a_BlockY, a_BlockZ, a_Source, a_SourceData) && (a_ExplosionSize > 0))
|
||||
{
|
||||
return;
|
||||
// TODO: CanCauseFire gets reset to false for some reason
|
||||
Explodinator::Kaboom(*this, Vector3f(a_BlockX, a_BlockY, a_BlockZ), a_ExplosionSize, a_CanCauseFire);
|
||||
cPluginManager::Get()->CallHookExploded(*this, a_ExplosionSize, a_CanCauseFire, a_BlockX, a_BlockY, a_BlockZ, a_Source, a_SourceData);
|
||||
}
|
||||
|
||||
// TODO: Implement block hardiness
|
||||
cVector3iArray BlocksAffected;
|
||||
m_ChunkMap->DoExplosionAt(a_ExplosionSize, a_BlockX, a_BlockY, a_BlockZ, BlocksAffected);
|
||||
|
||||
auto & Random = GetRandomProvider();
|
||||
auto SoundPitchMultiplier = 1.0f + (Random.RandReal(1.0f) - Random.RandReal(1.0f)) * 0.2f;
|
||||
|
||||
BroadcastSoundEffect("entity.generic.explode", Vector3d(a_BlockX, a_BlockY, a_BlockZ), 4.0f, SoundPitchMultiplier * 0.7f);
|
||||
|
||||
Vector3d ExplosionPos(a_BlockX, a_BlockY, a_BlockZ);
|
||||
for (auto Player : m_Players)
|
||||
{
|
||||
cClientHandle * ch = Player->GetClientHandle();
|
||||
if (ch == nullptr)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
auto Position = Vector3d(a_BlockX, a_BlockY - 0.5f, a_BlockZ);
|
||||
auto ParticleFormula = a_ExplosionSize * 0.33f;
|
||||
auto Spread = ParticleFormula * 0.5f;
|
||||
auto ParticleCount = std::min((ParticleFormula * 125), 600.0);
|
||||
|
||||
BroadcastParticleEffect("largesmoke", Position, Vector3f{}, static_cast<float>(Spread), static_cast<int>(ParticleCount));
|
||||
|
||||
Spread = ParticleFormula * 0.35f;
|
||||
ParticleCount = std::min((ParticleFormula * 550), 1800.0);
|
||||
|
||||
BroadcastParticleEffect("explode", Position, Vector3f{}, static_cast<float>(Spread), static_cast<int>(ParticleCount));
|
||||
|
||||
cPluginManager::Get()->CallHookExploded(*this, a_ExplosionSize, a_CanCauseFire, a_BlockX, a_BlockY, a_BlockZ, a_Source, a_SourceData);
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user