1
0

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:
Tiger Wang
2020-09-12 19:57:44 +01:00
committed by GitHub
parent 834d61dacc
commit 93adbdce9a
22 changed files with 531 additions and 300 deletions

View File

@@ -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);
}