4 #include "../BlockInfo.h"
7 #include "../Entities/Player.h"
8 #include "../BlockInServerPluginInterface.h"
15 #define PISTON_MAX_PUSH_DISTANCE 12
23 switch (a_PistonMeta & 0x07)
33 LOGWARNING(
"%s: invalid direction %d, ignoring", __FUNCTION__, a_PistonMeta & 0x07);
34 ASSERT(!
"Invalid direction");
63 World.GetBlockTypeMeta(a_BlockPos, pistonBlock, pistonMeta);
88 Vector3i extensionPos = a_BlockPos + pushDir;
89 World.SetBlock(a_BlockPos, pistonBlock, pistonMeta | 0x8);
93 World.BroadcastSoundEffect(
"block.piston.extend", a_BlockPos, 0.5f, 0.7f);
115 World.GetBlockTypeMeta(a_BlockPos, pistonBlock, pistonMeta);
133 Vector3i extensionPos = a_BlockPos + pushDir;
136 LOGD(
"%s: Piston without an extension - still extending, or just in an invalid state?", __FUNCTION__);
142 World.SetBlock(a_BlockPos, pistonBlock, pistonMeta & ~(8));
145 World.BroadcastSoundEffect(
"block.piston.contract", a_BlockPos, 0.5f, 0.7f);
154 Vector3i AdjustedPosition = a_BlockPos + pushDir * 2;
181 std::vector<Vector3i> sortedBlocks(a_BlocksToPush.begin(), a_BlocksToPush.end());
182 std::sort(sortedBlocks.begin(), sortedBlocks.end(), [a_PushDir](
const Vector3i & a,
const Vector3i & b)
184 return (a.Dot(a_PushDir) > b.Dot(a_PushDir));
190 for (
auto & moveBlockPos : sortedBlocks)
203 moveBlockPos += a_PushDir;
204 a_World.
SetBlock(moveBlockPos, moveBlock, moveMeta);
214 const Vector3i & a_BlockPos,
cWorld & a_World,
bool a_RequirePushable,
224 const static std::array<Vector3i, 6> pushingDirs =
249 if (!
CanPush(currBlock, currMeta))
252 return !a_RequirePushable;
269 for (
const auto & testDir : pushingDirs)
271 if (!
CanPushBlock(a_BlockPos + testDir, a_World,
false, a_BlocksPushed, a_PushDir))
280 return CanPushBlock(a_BlockPos + a_PushDir, a_World,
true, a_BlocksPushed, a_PushDir);
#define PISTON_MAX_PUSH_DISTANCE
@ E_BLOCK_PISTON_EXTENSION
unsigned char NIBBLETYPE
The datatype used by nibbledata (meta, light, skylight)
unsigned char BLOCKTYPE
The datatype used by blockdata.
void LOGWARNING(std::string_view a_Format, const Args &... args)
Utilities to allow casting a cWorld to one of its interfaces without including World....
static bool IsPistonBreakable(BLOCKTYPE Block)
Can a piston break this block?
virtual void OnBroken(cChunkInterface &a_ChunkInterface, cWorldInterface &a_WorldInterface, Vector3i a_BlockPos, BLOCKTYPE a_OldBlockType, NIBBLETYPE a_OldBlockMeta, const cEntity *a_Digger) const override
static const Byte PistonExtendAction
Piston extension block action.
static Vector3i MetadataToOffset(NIBBLETYPE a_PistonMeta)
Converts piston block's metadata into a unit vector representing the direction in which the piston wi...
static bool IsSticky(BLOCKTYPE a_BlockType)
Returns true if the piston (specified by blocktype) is a sticky piston.
static void RetractPiston(Vector3i a_BlockPos, cWorld &a_World)
std::unordered_set< Vector3i, VectorHasher< int > > Vector3iSet
static void ExtendPiston(Vector3i a_BlockPos, cWorld &a_World)
static void PushBlocks(const Vector3iSet &a_BlocksToPush, cWorld &a_World, const Vector3i &a_PushDir)
Moves a list of blocks in a specific direction.
static bool CanPushBlock(const Vector3i &a_BlockPos, cWorld &a_World, bool a_RequirePushable, Vector3iSet &a_BlocksPushed, const Vector3i &a_PushDir)
Tries to push a block and increases the pushed blocks variable.
static const Byte PistonRetractAction
Piston retraction block action.
static bool CanPush(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta)
Returns true if the specified block can be pushed by a piston (and left intact)
static bool IsExtended(NIBBLETYPE a_PistonMeta)
Returns true if the piston (with the specified meta) is extended.
virtual void OnBroken(cChunkInterface &a_ChunkInterface, cWorldInterface &a_WorldInterface, Vector3i a_BlockPos, BLOCKTYPE a_OldBlockType, NIBBLETYPE a_OldBlockMeta, const cEntity *a_Digger) const override
Called after a block gets broken (replaced with air), by natural means.
virtual cItems ConvertToPickups(NIBBLETYPE a_BlockMeta, const cItem *a_Tool) const override
Returns the pickups that would result if the block was mined by a_Digger using a_Tool.
void SetBlock(Vector3i a_BlockPos, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta)
Sets the block at the specified coords to the specified value.
BLOCKTYPE GetBlock(Vector3i a_Pos)
static bool IsValidHeight(Vector3i a_BlockPosition)
Validates a height-coordinate.
This class bridges a vector of cItem for safe access via Lua.
void ScheduleTask(cTickTime a_DelayTicks, std::function< void(cWorld &)> a_Task)
Queues a lambda task onto the tick thread, with the specified delay.
bool DropBlockAsPickups(Vector3i a_BlockPos, const cEntity *a_Digger=nullptr, const cItem *a_Tool=nullptr)
Digs the specified block, and spawns the appropriate pickups for it.
bool GetBlockTypeMeta(Vector3i a_BlockPos, BLOCKTYPE &a_BlockType, NIBBLETYPE &a_BlockMeta) const
Retrieves the block type and meta at the specified coords.
virtual void BroadcastBlockAction(Vector3i a_BlockPos, Byte a_Byte1, Byte a_Byte2, BLOCKTYPE a_BlockType, const cClientHandle *a_Exclude=nullptr) override
void SetBlock(Vector3i a_BlockPos, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta)
Sets the block at the specified coords to the specified value.