Merged OnBreak with OnPlayerBreak (#4967)
Co-authored-by: 12xx12 <12xx12100@gmail.com> Co-authored-by: Tiger Wang <ziwei.tiger@outlook.com>
This commit is contained in:
parent
a9031b6bae
commit
3381c0f6d6
@ -18,9 +18,11 @@
|
||||
void cBlockBedHandler::OnBroken(
|
||||
cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface,
|
||||
const Vector3i a_BlockPos,
|
||||
BLOCKTYPE a_OldBlockType, NIBBLETYPE a_OldBlockMeta
|
||||
BLOCKTYPE a_OldBlockType, NIBBLETYPE a_OldBlockMeta,
|
||||
const cEntity * a_Digger
|
||||
) const
|
||||
{
|
||||
UNUSED(a_Digger);
|
||||
auto Direction = MetaDataToDirection(a_OldBlockMeta & 0x03);
|
||||
if ((a_OldBlockMeta & 0x08) != 0)
|
||||
{
|
||||
|
@ -57,7 +57,8 @@ private:
|
||||
virtual void OnBroken(
|
||||
cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface,
|
||||
const Vector3i a_BlockPos,
|
||||
BLOCKTYPE a_OldBlockType, NIBBLETYPE a_OldBlockMeta
|
||||
BLOCKTYPE a_OldBlockType, NIBBLETYPE a_OldBlockMeta,
|
||||
const cEntity * a_Digger
|
||||
) const override;
|
||||
|
||||
virtual bool OnUse(
|
||||
|
@ -115,8 +115,14 @@ private:
|
||||
|
||||
|
||||
|
||||
virtual void OnBroken(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, const Vector3i a_BlockPos, BLOCKTYPE a_OldBlockType, NIBBLETYPE a_OldBlockMeta) const override
|
||||
virtual void OnBroken(
|
||||
cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface,
|
||||
const Vector3i a_BlockPos,
|
||||
BLOCKTYPE a_OldBlockType, NIBBLETYPE a_OldBlockMeta,
|
||||
const cEntity * a_Digger
|
||||
) const override
|
||||
{
|
||||
UNUSED(a_Digger);
|
||||
if ((a_OldBlockMeta & 0x8) != 0)
|
||||
{
|
||||
// Was upper part of flower
|
||||
|
@ -36,7 +36,7 @@ private:
|
||||
a_Player.GetStatManager().AddValue(Statistic::EatCakeSlice);
|
||||
if (Meta >= 5)
|
||||
{
|
||||
a_ChunkInterface.DigBlock(a_WorldInterface, a_BlockPos);
|
||||
a_ChunkInterface.DigBlock(a_WorldInterface, a_BlockPos, &a_Player);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -7,8 +7,14 @@
|
||||
|
||||
|
||||
|
||||
void cBlockDoorHandler::OnBroken(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, Vector3i a_BlockPos, BLOCKTYPE a_OldBlockType, NIBBLETYPE a_OldBlockMeta) const
|
||||
void cBlockDoorHandler::OnBroken(
|
||||
cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface,
|
||||
Vector3i a_BlockPos, BLOCKTYPE a_OldBlockType,
|
||||
NIBBLETYPE a_OldBlockMeta,
|
||||
const cEntity * a_Digger
|
||||
) const
|
||||
{
|
||||
UNUSED(a_Digger);
|
||||
// A part of the multiblock door was broken; the relevant half will drop any pickups as required.
|
||||
// All that is left to do is to delete the other half of the multiblock.
|
||||
|
||||
|
@ -142,7 +142,8 @@ private:
|
||||
virtual void OnBroken(
|
||||
cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface,
|
||||
Vector3i a_BlockPos,
|
||||
BLOCKTYPE a_OldBlockType, NIBBLETYPE a_OldBlockMeta
|
||||
BLOCKTYPE a_OldBlockType, NIBBLETYPE a_OldBlockMeta,
|
||||
const cEntity * a_Digger
|
||||
) const override;
|
||||
|
||||
virtual bool OnUse(
|
||||
|
@ -156,9 +156,11 @@ private:
|
||||
virtual void OnBroken(
|
||||
cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface,
|
||||
Vector3i a_BlockPos,
|
||||
BLOCKTYPE a_OldBlockType, NIBBLETYPE a_OldBlockMeta
|
||||
BLOCKTYPE a_OldBlockType, NIBBLETYPE a_OldBlockMeta,
|
||||
const cEntity * a_Digger
|
||||
) const override
|
||||
{
|
||||
UNUSED(a_Digger);
|
||||
// Destroy any leash knot tied to the fence:
|
||||
auto leashKnot = cLeashKnot::FindKnotAtPos(a_WorldInterface, a_BlockPos);
|
||||
if (leashKnot != nullptr)
|
||||
@ -166,7 +168,6 @@ private:
|
||||
leashKnot->SetShouldSelfDestroy();
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
@ -73,24 +73,15 @@ public:
|
||||
cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer & a_Player, const sSetBlock & a_BlockChange
|
||||
) const {}
|
||||
|
||||
/** Called just after the player breaks the block.
|
||||
/** Called after a block gets broken (replaced with air), by natural means.
|
||||
The block is already dug up in the world, the original block type and meta is passed in a_OldBlockType and a_OldBlockMeta.
|
||||
By default does nothing special, descendants may provide further behavior. */
|
||||
virtual void OnPlayerBrokeBlock(
|
||||
cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface,
|
||||
cPlayer & a_Player,
|
||||
Vector3i a_BlockPos,
|
||||
BLOCKTYPE a_OldBlockType, NIBBLETYPE a_OldBlockMeta
|
||||
) const {}
|
||||
|
||||
/** Called after a block gets broken (replaced with air), either by player or by natural means.
|
||||
If by player, it is called before the OnPlayerBrokeBlock() callback.
|
||||
The block is already dug up in the world, the original block type and meta is passed in a_OldBlockType and a_OldBlockMeta.
|
||||
By default notifies all direct neighbors via their OnNeighborChanged() callbacks. */
|
||||
By default notifies all direct neighbors via their OnNeighborChanged() callbacks.
|
||||
You can determine what kind of entity broke the block (e.g. player) by checking a_Digger! */
|
||||
virtual void OnBroken(
|
||||
cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface,
|
||||
Vector3i a_BlockPos,
|
||||
BLOCKTYPE a_OldBlockType, NIBBLETYPE a_OldBlockMeta
|
||||
BLOCKTYPE a_OldBlockType, NIBBLETYPE a_OldBlockMeta,
|
||||
const cEntity * a_Digger
|
||||
) const {}
|
||||
|
||||
/** Called when a direct neighbor of this block has been changed.
|
||||
|
@ -81,7 +81,8 @@ private:
|
||||
virtual void OnBroken(
|
||||
cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface,
|
||||
Vector3i a_BlockPos,
|
||||
BLOCKTYPE a_OldBlockType, NIBBLETYPE a_OldBlockMeta
|
||||
BLOCKTYPE a_OldBlockType, NIBBLETYPE a_OldBlockMeta,
|
||||
const cEntity * a_Digger
|
||||
) const override
|
||||
{
|
||||
// If there's a solid block or a liquid underneath, convert to water, rather than air
|
||||
@ -97,6 +98,10 @@ private:
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) const override
|
||||
{
|
||||
UNUSED(a_Meta);
|
||||
|
@ -54,21 +54,27 @@ private:
|
||||
|
||||
|
||||
|
||||
virtual void OnPlayerBrokeBlock(
|
||||
virtual void OnBroken(
|
||||
cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface,
|
||||
cPlayer & a_Player,
|
||||
Vector3i a_BlockPos,
|
||||
BLOCKTYPE a_OldBlockType, NIBBLETYPE a_OldBlockMeta
|
||||
BLOCKTYPE a_OldBlockType, NIBBLETYPE a_OldBlockMeta,
|
||||
const cEntity * a_Digger
|
||||
) const override
|
||||
{
|
||||
auto handler = a_Player.GetEquippedItem().GetHandler();
|
||||
if (!a_Player.IsGameModeSurvival() || !handler->CanHarvestBlock(E_BLOCK_MOB_SPAWNER))
|
||||
if (!a_Digger->IsPlayer())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
auto & random = GetRandomProvider();
|
||||
int reward = 15 + random.RandInt(14) + random.RandInt(14);
|
||||
a_WorldInterface.SpawnSplitExperienceOrbs(Vector3d(0.5, 0.5, 0.5) + a_BlockPos, reward);
|
||||
const auto Player = static_cast<const cPlayer *>(a_Digger);
|
||||
auto Handler = Player->GetEquippedItem().GetHandler();
|
||||
if (!Player->IsGameModeSurvival() || !Handler->CanHarvestBlock(E_BLOCK_MOB_SPAWNER))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
auto & Random = GetRandomProvider();
|
||||
int Reward = 15 + Random.RandInt(14) + Random.RandInt(14);
|
||||
a_WorldInterface.SpawnSplitExperienceOrbs(Vector3d(0.5, 0.5, 0.5) + a_BlockPos, Reward);
|
||||
}
|
||||
} ;
|
||||
|
@ -64,26 +64,33 @@ private:
|
||||
|
||||
|
||||
|
||||
virtual void OnPlayerBrokeBlock(
|
||||
virtual void OnBroken(
|
||||
cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface,
|
||||
cPlayer & a_Player, Vector3i a_BlockPos,
|
||||
BLOCKTYPE a_OldBlockType, NIBBLETYPE a_OldBlockMeta
|
||||
Vector3i a_BlockPos,
|
||||
BLOCKTYPE a_OldBlockType, NIBBLETYPE a_OldBlockMeta,
|
||||
const cEntity * a_Digger
|
||||
) const override
|
||||
{
|
||||
if (!a_Player.IsGameModeSurvival())
|
||||
if (!a_Digger->IsPlayer())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const auto Player = static_cast<const cPlayer *>(a_Digger);
|
||||
if (!Player->IsGameModeSurvival())
|
||||
{
|
||||
// Don't drop XP unless the player is in survival mode.
|
||||
return;
|
||||
}
|
||||
|
||||
if (a_Player.GetEquippedItem().m_Enchantments.GetLevel(cEnchantments::enchSilkTouch) != 0)
|
||||
if (Player->GetEquippedItem().m_Enchantments.GetLevel(cEnchantments::enchSilkTouch) != 0)
|
||||
{
|
||||
// Don't drop XP when the ore is mined with the Silk Touch enchantment
|
||||
return;
|
||||
}
|
||||
|
||||
auto & random = GetRandomProvider();
|
||||
int reward = 0;
|
||||
auto & Random = GetRandomProvider();
|
||||
int Reward = 0;
|
||||
|
||||
switch (a_OldBlockType)
|
||||
{
|
||||
@ -91,36 +98,36 @@ private:
|
||||
case E_BLOCK_LAPIS_ORE:
|
||||
{
|
||||
// Lapis and nether quartz get 2 - 5 experience
|
||||
reward = random.RandInt(2, 5);
|
||||
Reward = Random.RandInt(2, 5);
|
||||
break;
|
||||
}
|
||||
case E_BLOCK_REDSTONE_ORE:
|
||||
case E_BLOCK_REDSTONE_ORE_GLOWING:
|
||||
{
|
||||
// Redstone gets 1 - 5 experience
|
||||
reward = random.RandInt(1, 5);
|
||||
Reward = Random.RandInt(1, 5);
|
||||
break;
|
||||
}
|
||||
case E_BLOCK_DIAMOND_ORE:
|
||||
case E_BLOCK_EMERALD_ORE:
|
||||
{
|
||||
// Diamond and emerald get 3 - 7 experience
|
||||
reward = random.RandInt(3, 7);
|
||||
Reward = Random.RandInt(3, 7);
|
||||
break;
|
||||
}
|
||||
case E_BLOCK_COAL_ORE:
|
||||
{
|
||||
// Coal gets 0 - 2 experience
|
||||
reward = random.RandInt(2);
|
||||
Reward = Random.RandInt(2);
|
||||
break;
|
||||
}
|
||||
|
||||
default: break;
|
||||
}
|
||||
|
||||
if (reward > 0)
|
||||
if (Reward > 0)
|
||||
{
|
||||
a_WorldInterface.SpawnSplitExperienceOrbs(Vector3d(0.5, 0.5, 0.5) + a_BlockPos, reward);
|
||||
a_WorldInterface.SpawnSplitExperienceOrbs(Vector3d(0.5, 0.5, 0.5) + a_BlockPos, Reward);
|
||||
}
|
||||
}
|
||||
} ;
|
||||
|
@ -289,9 +289,11 @@ bool cBlockPistonHandler::CanPushBlock(
|
||||
void cBlockPistonHandler::OnBroken(
|
||||
cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface,
|
||||
Vector3i a_BlockPos,
|
||||
BLOCKTYPE a_OldBlockType, NIBBLETYPE a_OldBlockMeta
|
||||
BLOCKTYPE a_OldBlockType, NIBBLETYPE a_OldBlockMeta,
|
||||
const cEntity * a_Digger
|
||||
) const
|
||||
{
|
||||
UNUSED(a_Digger);
|
||||
if (!IsExtended(a_OldBlockMeta))
|
||||
{
|
||||
return;
|
||||
@ -318,9 +320,11 @@ void cBlockPistonHandler::OnBroken(
|
||||
void cBlockPistonHeadHandler::OnBroken(
|
||||
cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface,
|
||||
Vector3i a_BlockPos,
|
||||
BLOCKTYPE a_OldBlockType, NIBBLETYPE a_OldBlockMeta
|
||||
BLOCKTYPE a_OldBlockType, NIBBLETYPE a_OldBlockMeta,
|
||||
const cEntity * a_Digger
|
||||
) const
|
||||
{
|
||||
UNUSED(a_Digger);
|
||||
const auto Base = a_BlockPos - cBlockPistonHandler::MetadataToOffset(a_OldBlockMeta);
|
||||
if (!cChunkDef::IsValidHeight(Base.y))
|
||||
{
|
||||
|
@ -128,7 +128,8 @@ private:
|
||||
virtual void OnBroken(
|
||||
cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface,
|
||||
Vector3i a_BlockPos,
|
||||
BLOCKTYPE a_OldBlockType, NIBBLETYPE a_OldBlockMeta
|
||||
BLOCKTYPE a_OldBlockType, NIBBLETYPE a_OldBlockMeta,
|
||||
const cEntity * a_Digger
|
||||
) const override;
|
||||
|
||||
/** Moves a list of blocks in a specific direction */
|
||||
@ -156,7 +157,8 @@ public:
|
||||
virtual void OnBroken(
|
||||
cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface,
|
||||
Vector3i a_BlockPos,
|
||||
BLOCKTYPE a_OldBlockType, NIBBLETYPE a_OldBlockMeta
|
||||
BLOCKTYPE a_OldBlockType, NIBBLETYPE a_OldBlockMeta,
|
||||
const cEntity * a_Digger
|
||||
) const override;
|
||||
|
||||
virtual cItems ConvertToPickups(NIBBLETYPE a_BlockMeta, const cEntity * a_Digger, const cItem * a_Tool) const override;
|
||||
|
@ -77,10 +77,11 @@ private:
|
||||
virtual void OnBroken(
|
||||
cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface,
|
||||
Vector3i a_BlockPos,
|
||||
BLOCKTYPE a_OldBlockType, NIBBLETYPE a_OldBlockMeta
|
||||
BLOCKTYPE a_OldBlockType, NIBBLETYPE a_OldBlockMeta,
|
||||
const cEntity * a_Digger
|
||||
) const override
|
||||
{
|
||||
Super::OnBroken(a_ChunkInterface, a_WorldInterface, a_BlockPos, a_OldBlockType, a_OldBlockMeta);
|
||||
Super::OnBroken(a_ChunkInterface, a_WorldInterface, a_BlockPos, a_OldBlockType, a_OldBlockMeta, a_Digger);
|
||||
|
||||
// Alert diagonal rails:
|
||||
NeighborChanged(a_ChunkInterface, a_BlockPos + Vector3i( 1, 1, 0), BLOCK_FACE_NONE);
|
||||
|
@ -101,7 +101,7 @@ bool cChunkInterface::WriteBlockArea(cBlockArea & a_Area, int a_MinBlockX, int a
|
||||
|
||||
|
||||
|
||||
bool cChunkInterface::DigBlock(cWorldInterface & a_WorldInterface, Vector3i a_BlockPos)
|
||||
bool cChunkInterface::DigBlock(cWorldInterface & a_WorldInterface, Vector3i a_BlockPos, cEntity * a_Digger)
|
||||
{
|
||||
BLOCKTYPE BlockType;
|
||||
NIBBLETYPE BlockMeta;
|
||||
@ -112,7 +112,7 @@ bool cChunkInterface::DigBlock(cWorldInterface & a_WorldInterface, Vector3i a_Bl
|
||||
return false;
|
||||
}
|
||||
|
||||
cBlockHandler::For(BlockType).OnBroken(*this, a_WorldInterface, a_BlockPos, BlockType, BlockMeta);
|
||||
cBlockHandler::For(BlockType).OnBroken(*this, a_WorldInterface, a_BlockPos, BlockType, BlockMeta, a_Digger);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -69,7 +69,7 @@ public:
|
||||
|
||||
virtual bool WriteBlockArea(cBlockArea & a_Area, int a_MinBlockX, int a_MinBlockY, int a_MinBlockZ, int a_DataTypes) override;
|
||||
|
||||
bool DigBlock(cWorldInterface & a_WorldInterface, Vector3i a_BlockPos);
|
||||
bool DigBlock(cWorldInterface & a_WorldInterface, Vector3i a_BlockPos, cEntity * a_Digger);
|
||||
|
||||
/** Digs the block and spawns the relevant pickups, as if a_Digger used a_Tool to dig the block. */
|
||||
void DropBlockAsPickups(Vector3i a_BlockPos, const cEntity * a_Digger = nullptr, const cItem * a_Tool = nullptr);
|
||||
|
@ -1398,7 +1398,12 @@ void cClientHandle::HandleBlockDigFinished(int a_BlockX, int a_BlockY, int a_Blo
|
||||
return;
|
||||
}
|
||||
|
||||
// Apply hunger:
|
||||
m_Player->AddFoodExhaustion(0.025);
|
||||
|
||||
// Damage the tool, but not for 0 hardness blocks:
|
||||
m_Player->UseEquippedItem(cBlockInfo::IsOneHitDig(a_OldBlock) ? cItemHandler::dlaBreakBlockInstant : cItemHandler::dlaBreakBlock);
|
||||
|
||||
cChunkInterface ChunkInterface(World->GetChunkMap());
|
||||
Vector3i absPos(a_BlockX, a_BlockY, a_BlockZ);
|
||||
if (m_Player->IsGameModeSurvival())
|
||||
@ -1407,15 +1412,10 @@ void cClientHandle::HandleBlockDigFinished(int a_BlockX, int a_BlockY, int a_Blo
|
||||
}
|
||||
else
|
||||
{
|
||||
World->DigBlock(absPos);
|
||||
World->DigBlock(absPos, m_Player);
|
||||
}
|
||||
|
||||
// Damage the tool, but not for 0 hardness blocks:
|
||||
auto dlAction = cBlockInfo::IsOneHitDig(a_OldBlock) ? cItemHandler::dlaBreakBlockInstant : cItemHandler::dlaBreakBlock;
|
||||
m_Player->UseEquippedItem(dlAction);
|
||||
|
||||
World->BroadcastSoundParticleEffect(EffectID::PARTICLE_SMOKE, absPos, a_OldBlock, this);
|
||||
cBlockHandler::For(a_OldBlock).OnPlayerBrokeBlock(ChunkInterface, *World, *m_Player, absPos, a_OldBlock, a_OldMeta);
|
||||
cRoot::Get()->GetPluginManager()->CallHookPlayerBrokenBlock(*m_Player, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_OldBlock, a_OldMeta);
|
||||
}
|
||||
|
||||
|
@ -65,7 +65,7 @@ public:
|
||||
case E_BLOCK_TNT:
|
||||
{
|
||||
// Activate the TNT:
|
||||
a_World->DigBlock(a_ClickedBlockPos);
|
||||
a_World->DigBlock(a_ClickedBlockPos, a_Player);
|
||||
a_World->SpawnPrimedTNT(Vector3d(a_ClickedBlockPos) + Vector3d(0.5, 0.5, 0.5)); // 80 ticks to boom
|
||||
break;
|
||||
}
|
||||
|
@ -102,7 +102,7 @@ namespace Explodinator
|
||||
}
|
||||
|
||||
/** Sets the block at the given position, updating surroundings. */
|
||||
static void DestroyBlock(cWorld & a_World, cChunk & a_Chunk, const Vector3i a_AbsolutePosition, const Vector3i a_RelativePosition, const BLOCKTYPE a_DestroyedBlock, const BLOCKTYPE a_NewBlock)
|
||||
static void DestroyBlock(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)
|
||||
{
|
||||
const auto DestroyedMeta = a_Chunk.GetMeta(a_RelativePosition);
|
||||
|
||||
@ -113,12 +113,12 @@ namespace Explodinator
|
||||
a_Chunk.SetBlock(a_RelativePosition, a_NewBlock, 0);
|
||||
|
||||
cChunkInterface Interface(a_World.GetChunkMap());
|
||||
cBlockHandler::For(a_DestroyedBlock).OnBroken(Interface, a_World, a_AbsolutePosition, a_DestroyedBlock, DestroyedMeta);
|
||||
cBlockHandler::For(a_DestroyedBlock).OnBroken(Interface, a_World, a_AbsolutePosition, a_DestroyedBlock, DestroyedMeta, a_ExplodingEntity);
|
||||
}
|
||||
|
||||
/** Sets the block at the given Position to air, updates surroundings, and spawns pickups, fire, shrapnel according to Minecraft rules.
|
||||
OK, _mostly_ Minecraft rules. */
|
||||
static void DestroyBlock(cChunk & a_Chunk, const Vector3i a_Position, const unsigned a_Power, const bool a_Fiery)
|
||||
static void DestroyBlock(cChunk & a_Chunk, const Vector3i a_Position, const unsigned a_Power, const bool a_Fiery, const cEntity * const a_ExplodingEntity)
|
||||
{
|
||||
const auto DestroyedBlock = a_Chunk.GetBlock(a_Position);
|
||||
if (DestroyedBlock == E_BLOCK_AIR)
|
||||
@ -150,7 +150,7 @@ namespace Explodinator
|
||||
if ((Below.y >= 0) && cBlockInfo::FullyOccupiesVoxel(a_Chunk.GetBlock(Below)))
|
||||
{
|
||||
// Start a fire:
|
||||
DestroyBlock(World, a_Chunk, Absolute, a_Position, DestroyedBlock, E_BLOCK_FIRE);
|
||||
DestroyBlock(World, a_Chunk, Absolute, a_Position, DestroyedBlock, E_BLOCK_FIRE, a_ExplodingEntity);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -169,11 +169,11 @@ namespace Explodinator
|
||||
}
|
||||
}
|
||||
|
||||
DestroyBlock(World, a_Chunk, Absolute, a_Position, DestroyedBlock, E_BLOCK_AIR);
|
||||
DestroyBlock(World, a_Chunk, Absolute, a_Position, DestroyedBlock, E_BLOCK_AIR, a_ExplodingEntity);
|
||||
}
|
||||
|
||||
/** Traces the path taken by one Explosion Lazor (tm) with given direction and intensity, that will destroy blocks until it is exhausted. */
|
||||
static void DestructionTrace(cChunk * a_Chunk, Vector3f a_Origin, const Vector3f a_Destination, const unsigned a_Power, const bool a_Fiery, float a_Intensity)
|
||||
static void DestructionTrace(cChunk * a_Chunk, Vector3f a_Origin, const Vector3f a_Destination, const unsigned a_Power, const bool a_Fiery, float a_Intensity, const cEntity * const a_ExplodingEntity)
|
||||
{
|
||||
// The current position the ray is at.
|
||||
auto Checkpoint = a_Origin;
|
||||
@ -206,7 +206,7 @@ namespace Explodinator
|
||||
break;
|
||||
}
|
||||
|
||||
DestroyBlock(*Neighbour, Position, a_Power, a_Fiery);
|
||||
DestroyBlock(*Neighbour, Position, a_Power, a_Fiery, a_ExplodingEntity);
|
||||
|
||||
// Adjust coordinates to be relative to the neighbour chunk:
|
||||
Checkpoint = RebaseRelativePosition(a_Chunk->GetPos(), Neighbour->GetPos(), Checkpoint);
|
||||
@ -220,7 +220,7 @@ namespace Explodinator
|
||||
}
|
||||
|
||||
/** Sends out Explosion Lazors (tm) originating from the given position that destroy blocks. */
|
||||
static void DamageBlocks(cChunk & a_Chunk, const Vector3f a_Position, const unsigned a_Power, const bool a_Fiery)
|
||||
static void DamageBlocks(cChunk & a_Chunk, const Vector3f a_Position, const unsigned a_Power, const bool a_Fiery, const cEntity * const a_ExplodingEntity)
|
||||
{
|
||||
const auto Intensity = a_Power * (0.7f + GetRandomProvider().RandReal(0.6f));
|
||||
const auto ExplosionRadius = CeilC((Intensity / StepAttenuation) * StepUnit);
|
||||
@ -236,8 +236,8 @@ namespace Explodinator
|
||||
{
|
||||
for (int OffsetZ = -HalfSide; OffsetZ < HalfSide; OffsetZ++)
|
||||
{
|
||||
DestructionTrace(&a_Chunk, a_Position, a_Position + Vector3f(OffsetX, +ExplosionRadius, OffsetZ), a_Power, a_Fiery, Intensity);
|
||||
DestructionTrace(&a_Chunk, a_Position, a_Position + Vector3f(OffsetX, -ExplosionRadius, OffsetZ), a_Power, a_Fiery, Intensity);
|
||||
DestructionTrace(&a_Chunk, a_Position, a_Position + Vector3f(OffsetX, +ExplosionRadius, OffsetZ), a_Power, a_Fiery, Intensity, a_ExplodingEntity);
|
||||
DestructionTrace(&a_Chunk, a_Position, a_Position + Vector3f(OffsetX, -ExplosionRadius, OffsetZ), a_Power, a_Fiery, Intensity, a_ExplodingEntity);
|
||||
}
|
||||
}
|
||||
|
||||
@ -263,10 +263,10 @@ namespace Explodinator
|
||||
{
|
||||
for (int OffsetY = -HalfSide + 1; OffsetY < HalfSide - 1; OffsetY++)
|
||||
{
|
||||
DestructionTrace(&a_Chunk, a_Position, a_Position + Vector3f(ExplosionRadius, OffsetY, Offset + 1), a_Power, a_Fiery, Intensity);
|
||||
DestructionTrace(&a_Chunk, a_Position, a_Position + Vector3f(-ExplosionRadius, OffsetY, Offset), a_Power, a_Fiery, Intensity);
|
||||
DestructionTrace(&a_Chunk, a_Position, a_Position + Vector3f(Offset, OffsetY, ExplosionRadius), a_Power, a_Fiery, Intensity);
|
||||
DestructionTrace(&a_Chunk, a_Position, a_Position + Vector3f(Offset + 1, OffsetY, -ExplosionRadius), a_Power, a_Fiery, Intensity);
|
||||
DestructionTrace(&a_Chunk, a_Position, a_Position + Vector3f(ExplosionRadius, OffsetY, Offset + 1), a_Power, a_Fiery, Intensity, a_ExplodingEntity);
|
||||
DestructionTrace(&a_Chunk, a_Position, a_Position + Vector3f(-ExplosionRadius, OffsetY, Offset), a_Power, a_Fiery, Intensity, a_ExplodingEntity);
|
||||
DestructionTrace(&a_Chunk, a_Position, a_Position + Vector3f(Offset, OffsetY, ExplosionRadius), a_Power, a_Fiery, Intensity, a_ExplodingEntity);
|
||||
DestructionTrace(&a_Chunk, a_Position, a_Position + Vector3f(Offset + 1, OffsetY, -ExplosionRadius), a_Power, a_Fiery, Intensity, a_ExplodingEntity);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -280,13 +280,13 @@ namespace Explodinator
|
||||
}
|
||||
}
|
||||
|
||||
void Kaboom(cWorld & a_World, const Vector3f a_Position, const unsigned a_Power, const bool a_Fiery)
|
||||
void Kaboom(cWorld & a_World, const Vector3f a_Position, const unsigned a_Power, const bool a_Fiery, const cEntity * const a_ExplodingEntity)
|
||||
{
|
||||
a_World.DoWithChunkAt(a_Position.Floor(), [a_Position, a_Power, a_Fiery](cChunk & a_Chunk)
|
||||
a_World.DoWithChunkAt(a_Position.Floor(), [a_Position, a_Power, a_Fiery, a_ExplodingEntity](cChunk & a_Chunk)
|
||||
{
|
||||
LagTheClient(a_Chunk, a_Position, a_Power);
|
||||
DamageEntities(a_Chunk, a_Position, a_Power);
|
||||
DamageBlocks(a_Chunk, AbsoluteToRelative(a_Position, a_Chunk.GetPos()), a_Power, a_Fiery);
|
||||
DamageBlocks(a_Chunk, AbsoluteToRelative(a_Position, a_Chunk.GetPos()), a_Power, a_Fiery, a_ExplodingEntity);
|
||||
|
||||
return false;
|
||||
});
|
||||
|
@ -5,16 +5,17 @@
|
||||
|
||||
|
||||
|
||||
class cEntity;
|
||||
class cWorld;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
namespace Explodinator
|
||||
{
|
||||
/** Creates an explosion of Power, centred at Position, with ability to set fires as provided.
|
||||
For maximum efficiency, Position should be in the centre of the entity or block that exploded.
|
||||
The entity pointer is used to trigger OnBreak for the destroyed blocks.
|
||||
Kaboom indeed, you drunken wretch. */
|
||||
void Kaboom(cWorld & World, Vector3f Position, unsigned Power, bool Fiery);
|
||||
void Kaboom(cWorld & World, Vector3f Position, unsigned Power, bool Fiery, const cEntity * a_ExplodingEntity);
|
||||
}
|
||||
|
@ -1394,7 +1394,27 @@ void cWorld::DoExplosionAt(double a_ExplosionSize, double a_BlockX, double a_Blo
|
||||
if (!cPluginManager::Get()->CallHookExploding(*this, a_ExplosionSize, a_CanCauseFire, a_BlockX, a_BlockY, a_BlockZ, a_Source, a_SourceData) && (a_ExplosionSize > 0))
|
||||
{
|
||||
// TODO: CanCauseFire gets reset to false for some reason
|
||||
Explodinator::Kaboom(*this, Vector3d(a_BlockX, a_BlockY, a_BlockZ), FloorC<unsigned>(a_ExplosionSize), a_CanCauseFire);
|
||||
|
||||
const cEntity * Entity;
|
||||
switch (a_Source)
|
||||
{
|
||||
case eExplosionSource::esEnderCrystal:
|
||||
case eExplosionSource::esGhastFireball:
|
||||
case eExplosionSource::esMonster:
|
||||
case eExplosionSource::esPrimedTNT:
|
||||
case eExplosionSource::esWitherBirth:
|
||||
case eExplosionSource::esWitherSkull:
|
||||
{
|
||||
Entity = static_cast<const cEntity *>(a_SourceData);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
Entity = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
Explodinator::Kaboom(*this, Vector3d(a_BlockX, a_BlockY, a_BlockZ), FloorC<unsigned>(a_ExplosionSize), a_CanCauseFire, Entity);
|
||||
cPluginManager::Get()->CallHookExploded(*this, a_ExplosionSize, a_CanCauseFire, a_BlockX, a_BlockY, a_BlockZ, a_Source, a_SourceData);
|
||||
}
|
||||
}
|
||||
@ -2166,7 +2186,7 @@ bool cWorld::GetBlocks(sSetBlockVector & a_Blocks, bool a_ContinueOnFailure)
|
||||
|
||||
|
||||
|
||||
bool cWorld::DigBlock(Vector3i a_BlockPos)
|
||||
bool cWorld::DigBlock(Vector3i a_BlockPos, const cEntity * a_Digger)
|
||||
{
|
||||
BLOCKTYPE BlockType;
|
||||
NIBBLETYPE BlockMeta;
|
||||
@ -2178,7 +2198,7 @@ bool cWorld::DigBlock(Vector3i a_BlockPos)
|
||||
}
|
||||
|
||||
cChunkInterface ChunkInterface(GetChunkMap());
|
||||
cBlockHandler::For(BlockType).OnBroken(ChunkInterface, *this, a_BlockPos, BlockType, BlockMeta);
|
||||
cBlockHandler::For(BlockType).OnBroken(ChunkInterface, *this, a_BlockPos, BlockType, BlockMeta, a_Digger);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -2190,7 +2210,7 @@ bool cWorld::DigBlock(Vector3i a_BlockPos)
|
||||
bool cWorld::DropBlockAsPickups(Vector3i a_BlockPos, const cEntity * a_Digger, const cItem * a_Tool)
|
||||
{
|
||||
auto pickups = PickupsFromBlock(a_BlockPos, a_Digger, a_Tool);
|
||||
if (!DigBlock(a_BlockPos))
|
||||
if (!DigBlock(a_BlockPos, a_Digger))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
@ -667,16 +667,16 @@ public:
|
||||
/** Replaces the specified block with air, and calls the OnBroken block handler.
|
||||
Wakes up the simulators. Doesn't produce pickups, use DropBlockAsPickups() for that instead.
|
||||
Returns true on success, false if the chunk is not loaded. */
|
||||
bool DigBlock(Vector3i a_BlockPos);
|
||||
bool DigBlock(Vector3i a_BlockPos, const cEntity * a_Digger);
|
||||
|
||||
/** OBSOLETE, use the Vector3-based overload instead.
|
||||
Replaces the specified block with air, and calls the apropriate block handlers (OnBreaking(), OnBroken()).
|
||||
Wakes up the simulators.
|
||||
Doesn't produce pickups, use DropBlockAsPickups() for that instead.
|
||||
Returns true on success, false if the chunk is not loaded. */
|
||||
bool DigBlock(int a_X, int a_Y, int a_Z)
|
||||
bool DigBlock(int a_X, int a_Y, int a_Z, cEntity * a_Digger)
|
||||
{
|
||||
return DigBlock({a_X, a_Y, a_Z});
|
||||
return DigBlock({a_X, a_Y, a_Z}, a_Digger);
|
||||
}
|
||||
|
||||
/** Digs the specified block, and spawns the appropriate pickups for it.
|
||||
|
Loading…
Reference in New Issue
Block a user