158 default:
return 0.09f;
165 class LineOfSightCallbacks final :
public cLineBlockTracer::cCallbacks
173 const Vector3d Position = a_Position;
174 unsigned Unobstructed = 0, Total = 0;
184 const Vector3d Destination{X, Y, Z};
185 if ((Destination - Position).SqrLength() > a_SquareRadius)
192 if (Tracer.
Trace(a_Position, Destination))
201 return (Total == 0) ? 0 : (
static_cast<float>(Unobstructed) / Total);
207 const auto Radius = a_Power * 2;
208 const auto SquareRadius = Radius * Radius;
214 const auto Direction = Entity.GetPosition() - a_Position;
215 const auto Impact = (1 - (
static_cast<float>(
Direction.Length()) / Radius)) * Exposure;
218 if (!Entity.IsTNT() && !Entity.IsFallingBlock())
220 const auto Damage = (Impact * Impact + Impact) * 7 * a_Power + 1;
227 const auto ReducedImpact = Impact - Impact * Entity.GetEnchantmentBlastKnockbackReduction();
262 const auto DestroyedMeta = a_Chunk.
GetMeta(a_RelativePosition);
268 a_Chunk.
SetBlock(a_RelativePosition, a_NewBlock, 0);
271 cBlockHandler::For(a_DestroyedBlock).
OnBroken(Interface, a_World, a_AbsolutePosition, a_DestroyedBlock, DestroyedMeta, a_ExplodingEntity);
279 const auto DestroyedBlock = a_Chunk.
GetBlock(a_Position);
294 const int FuseTime = Random.RandInt(10, 30);
297 World.SpawnPrimedTNT(
Vector3d(0.5, 0, 0.5) + Absolute, FuseTime, 1,
false);
299 else if ((a_ExplodingEntity !=
nullptr) && (a_ExplodingEntity->
IsTNT() ||
BlockAlwaysDrops(DestroyedBlock) || Random.RandBool(1.f / a_Power)))
301 const auto DestroyedMeta = a_Chunk.
GetMeta(a_Position);
304 else if (a_Fiery && Random.RandBool(1 / 3.0))
306 const auto Below = a_Position.
addedY(-1);
314 else if (
const auto Shrapnel =
World.GetTNTShrapnelLevel(); (Shrapnel >
slNone) && Random.RandBool(0))
322 const auto DestroyedMeta = a_Chunk.
GetMeta(a_Position);
323 auto FallingBlock = std::make_unique<cFallingBlock>(
Vector3d(0.5, 0, 0.5) + Absolute, DestroyedBlock, DestroyedMeta);
325 FallingBlock->Initialize(std::move(FallingBlock),
World);
336 auto Checkpoint = a_Origin;
342 while (a_Intensity > 0)
344 auto Position = Checkpoint.Floor();
351 if ((Neighbour ==
nullptr) || !Neighbour->IsValid())
357 if (a_Intensity <= 0)
363 DestroyBlock(*Neighbour, Position, a_Power, a_Fiery, a_ExplodingEntity);
379 return a_Power * (0.7f + a_Random.
RandReal(0.6f));
393 for (
float OffsetX = -HalfSide; OffsetX < HalfSide; OffsetX++)
395 for (
float OffsetZ = -HalfSide; OffsetZ < HalfSide; OffsetZ++)
403 for (
float OffsetX = -HalfSide; OffsetX < HalfSide; OffsetX++)
405 for (
float OffsetY = -HalfSide + 1; OffsetY < HalfSide - 1; OffsetY++)
413 for (
float OffsetZ = -HalfSide + 1; OffsetZ < HalfSide - 1; OffsetZ++)
415 for (
float OffsetY = -HalfSide + 1; OffsetY < HalfSide - 1; OffsetY++)
428 Client->SendExplosion(a_Position,
static_cast<float>(a_Power));
436 LagTheClient(a_Chunk, a_Position, a_Power);
437 DamageEntities(a_Chunk, a_Position, a_Power);
438 DamageBlocks(a_Chunk, AbsoluteToRelative(a_Position, a_Chunk.GetPos()), a_Power, a_Fiery, a_ExplodingEntity);
bool IsBlockShulkerBox(BLOCKTYPE a_BlockType)
@ E_BLOCK_NETHER_BRICK_STAIRS
@ E_BLOCK_STANDING_BANNER
@ E_BLOCK_COBBLESTONE_STAIRS
@ E_BLOCK_STATIONARY_LAVA
@ E_BLOCK_STONE_BRICK_STAIRS
@ E_BLOCK_ENCHANTMENT_TABLE
@ E_BLOCK_END_PORTAL_FRAME
@ E_BLOCK_PRISMARINE_BLOCK
@ E_BLOCK_BLOCK_OF_REDSTONE
@ E_BLOCK_MOSSY_COBBLESTONE
@ E_BLOCK_NETHER_WART_BLOCK
@ E_BLOCK_RED_SANDSTONE_STAIRS
@ E_BLOCK_CONCRETE_POWDER
@ E_BLOCK_NETHER_QUARTZ_ORE
@ E_BLOCK_SANDSTONE_STAIRS
@ E_BLOCK_STATIONARY_WATER
@ E_BLOCK_COBBLESTONE_WALL
@ E_BLOCK_NETHER_BRICK_FENCE
unsigned char NIBBLETYPE
The datatype used by nibbledata (meta, light, skylight)
unsigned char BLOCKTYPE
The datatype used by blockdata.
eBlockFace
Block face constants, used in PlayerDigging and PlayerBlockPlacement packets and bbox collision calc.
MTRand & GetRandomProvider()
Returns the current thread's random number source.
std::enable_if< std::is_arithmetic< T >::value, C >::type FloorC(T a_Value)
Floors a value, then casts it to C (an int by default).
Vector3< double > Vector3d
Vector3< float > Vector3f
Utilities to allow casting a cWorld to one of its interfaces without including World....
static const auto StepAttenuation
static void DestructionTrace(cChunk *a_Chunk, Vector3f a_Origin, const Vector3f a_Direction, const int a_Power, const bool a_Fiery, float a_Intensity, const cEntity *const a_ExplodingEntity)
Traces the path taken by one Explosion Lazor (tm) with given direction and intensity,...
static void DamageEntities(const cChunk &a_Chunk, const Vector3f a_Position, const int a_Power)
Applies distance-based damage and knockback to all entities within the explosion's effect range.
static void SetBlock(cWorld &a_World, cChunk &a_Chunk, const Vector3i a_AbsolutePosition, const Vector3i a_RelativePosition, const BLOCKTYPE a_DestroyedBlock, const BLOCKTYPE a_NewBlock, const cEntity *const a_ExplodingEntity)
Sets the block at the given position, updating surroundings.
static void LagTheClient(cChunk &a_Chunk, const Vector3f a_Position, const int a_Power)
Sends an explosion packet to all clients in the given chunk.
static const auto StepUnit
static const auto KnockbackFactor
static const auto TraceCubeSideLength
static const auto BoundingBoxStepUnit
static Vector3f RebaseRelativePosition(const cChunkCoords a_From, const cChunkCoords a_To, const Vector3f a_Position)
Make a From Chunk-relative Position into a To Chunk-relative position.
static void DamageBlocks(cChunk &a_Chunk, const Vector3f a_Position, const int a_Power, const bool a_Fiery, const cEntity *const a_ExplodingEntity)
Sends out Explosion Lazors (tm) originating from the given position that destroy blocks.
void Kaboom(cWorld &a_World, const Vector3f a_Position, const int a_Power, const bool a_Fiery, const cEntity *const a_ExplodingEntity)
Creates an explosion of Power, centred at Position, with ability to set fires as provided.
static float GetExplosionAbsorption(const BLOCKTYPE Block)
Returns how much of an explosion Destruction Lazor's (tm) intensity the given block attenuates.
static bool BlockAlwaysDrops(const BLOCKTYPE a_Block)
Returns true if block should always drop when exploded.
static void DestroyBlock(cChunk &a_Chunk, const Vector3i a_Position, const int a_Power, const bool a_Fiery, const cEntity *const a_ExplodingEntity)
Work out what should happen when an explosion destroys the given block.
static Vector3f AbsoluteToRelative(const Vector3f a_Position, const cChunkCoords a_ChunkPosition)
Converts an absolute floating-point Position into a Chunk-relative one.
static float RandomIntensity(MTRand &a_Random, const int a_Power)
Returns a random intensity for an Explosion Lazor (tm) as a function of the explosion's power.
static float CalculateEntityExposure(const cChunk &a_Chunk, const cEntity &a_Entity, const Vector3f a_Position, const int a_SquareRadius)
Calculates the approximate percentage of an Entity's bounding box that is exposed to an explosion cen...
static bool FullyOccupiesVoxel(BLOCKTYPE Block)
Does this block fully occupy its voxel - is it a 'full' block?
static const cBlockHandler & For(BLOCKTYPE a_BlockType)
virtual void OnBroken(cChunkInterface &a_ChunkInterface, cWorldInterface &a_WorldInterface, Vector3i a_BlockPos, BLOCKTYPE a_OldBlockType, NIBBLETYPE a_OldBlockMeta, const cEntity *a_Digger) const
Called after a block gets broken (replaced with air), by natural means.
NIBBLETYPE GetMeta(int a_RelX, int a_RelY, int a_RelZ) const
BLOCKTYPE GetBlock(int a_RelX, int a_RelY, int a_RelZ) const
cChunk * GetRelNeighborChunkAdjustCoords(Vector3i &a_RelPos) const
Returns the chunk into which the relatively-specified block belongs.
cChunkCoords GetPos() const
void SetBlock(Vector3i a_RelBlockPos, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta)
const auto & GetAllClients(void) const
cWorld * GetWorld(void) const
Wraps the chunk coords into a single structure.
static bool IsValidHeight(Vector3i a_BlockPosition)
Validates a height-coordinate.
static Vector3i RelativeToAbsolute(Vector3i a_RelBlockPosition, cChunkCoords a_ChunkCoords)
Converts relative block coordinates into absolute coordinates with a known chunk location.
cBoundingBox GetBoundingBox() const
Class to wrap any random engine to provide a more convenient interface.
RealType RandReal(RealType a_Min, RealType a_Max)
Return a random RealType in the range [a_Min, a_Max).
bool Trace(Vector3d a_Start, Vector3d a_End)
Traces one line between Start and End; returns true if the entire line was traced (until OnNoMoreHits...
static bool IsAllowedBlock(BLOCKTYPE a_BlockType)
Vector3< T > addedY(T a_AddY) const
Returns a copy of this vector moved by the specified amount on the y axis.
Vector3< int > Floor(void) const
Returns a new Vector3i with coords set to std::floor() of this vector's coords.
Vector3< T > NormalizeCopy(void) const
bool DoWithChunkAt(Vector3i a_BlockPos, cChunkCallback a_Callback)
Calls the callback for the chunk at the block position specified, with ChunkMapCS locked.
virtual bool ForEachEntityInBox(const cBoundingBox &a_Box, cEntityCallback a_Callback) override
Calls the callback for each entity that has a nonempty intersection with the specified boundingbox.
void SpawnItemPickups(const cItems &a_Pickups, Vector3i a_BlockPos, double a_FlyAwaySpeed=1.0, bool a_IsPlayerCreated=false)
Spawns item pickups for each item in the list.
cChunkMap * GetChunkMap(void)