6 #include "../Entities/Player.h" 7 #include "../BlockInServerPluginInterface.h" 14 #define PISTON_MAX_PUSH_DISTANCE 12 51 int a_BlockX,
int a_BlockY,
int a_BlockZ,
eBlockFace a_BlockFace,
52 int a_CursorX,
int a_CursorY,
int a_CursorZ,
67 switch (a_PistonMeta & 0x07)
77 LOGWARNING(
"%s: invalid direction %d, ignoring", __FUNCTION__, a_PistonMeta & 0x07);
78 ASSERT(!
"Invalid direction");
95 std::vector<Vector3i> sortedBlocks(a_BlocksToPush.begin(), a_BlocksToPush.end());
96 std::sort(sortedBlocks.begin(), sortedBlocks.end(), [a_PushDir](
const Vector3i & a,
const Vector3i & b)
98 return (a.
Dot(a_PushDir) > b.Dot(a_PushDir));
104 for (
auto & moveBlockPos : sortedBlocks)
106 a_World.
GetBlockTypeMeta(moveBlockPos.x, moveBlockPos.y, moveBlockPos.z, moveBlock, moveMeta);
117 moveBlockPos += a_PushDir;
118 a_World.
SetBlock(moveBlockPos.x, moveBlockPos.y, moveBlockPos.z, moveBlock, moveMeta);
128 const Vector3i & a_BlockPos,
cWorld & a_World,
bool a_RequirePushable,
132 const static std::array<Vector3i, 6> pushingDirs =
157 if (!
CanPush(currBlock, currMeta))
160 return !a_RequirePushable;
177 for (
const auto & testDir : pushingDirs)
179 if (!
CanPushBlock(a_BlockPos + testDir, a_World,
false, a_BlocksPushed, a_PushDir))
188 return CanPushBlock(a_BlockPos + a_PushDir, a_World,
true, a_BlocksPushed, a_PushDir);
202 a_World.
GetBlockTypeMeta(a_BlockPos.
x, a_BlockPos.
y, a_BlockPos.
z, pistonBlock, pistonMeta);
231 if (!
CanPushBlock(a_BlockPos + pushDir, World,
true, blocksPushed, pushDir))
239 Vector3i extensionPos = a_BlockPos + pushDir;
240 World.
SetBlock(a_BlockPos.
x, a_BlockPos.
y, a_BlockPos.
z, pistonBlock, pistonMeta | 0x8);
242 extensionPos.
x, extensionPos.
y, extensionPos.
z,
261 a_World.
GetBlockTypeMeta(a_BlockPos.
x, a_BlockPos.
y, a_BlockPos.
z, pistonBlock, pistonMeta);
287 Vector3i extensionPos = a_BlockPos + pushDir;
290 LOGD(
"%s: Piston without an extension - still extending, or just in an invalid state?", __FUNCTION__);
296 World.
SetBlock(a_BlockPos.
x, a_BlockPos.
y, a_BlockPos.
z, pistonBlock, pistonMeta & ~(8));
308 Vector3i AdjustedPosition = a_BlockPos + pushDir * 2;
313 if (!
CanPushBlock(AdjustedPosition, World,
false, pushedBlocks, pushDir))
static void ExtendPiston(Vector3i a_BlockPos, cWorld &a_World)
static NIBBLETYPE RotationPitchToMetaData(double a_Rotation, double a_Pitch)
double GetPitch(void) const
BLOCKTYPE GetBlock(Vector3i a_BlockPos)
Returns the block type at the specified position.
cBlockPistonHandler(BLOCKTYPE a_BlockType)
T Dot(const Vector3< T > &a_Rhs) const
static bool IsExtended(NIBBLETYPE a_PistonMeta)
Returns true if the piston (with the specified meta) is extended.
unsigned char BLOCKTYPE
The datatype used by blockdata.
static bool CanPush(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta)
Returns true if the specified block can be pushed by a piston (and left intact)
virtual void OnBroken(cChunkInterface &a_ChunkInterface, cWorldInterface &a_WorldInterface, Vector3i a_BlockPos, BLOCKTYPE a_OldBlockType, NIBBLETYPE a_OldBlockMeta) override
Called after a block gets broken (replaced with air), either by player or by natural means...
static bool IsValidHeight(int a_Height)
Validates a height-coordinate.
unsigned char NIBBLETYPE
The datatype used by nibbledata (meta, light, skylight)
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.
#define PISTON_MAX_PUSH_DISTANCE
virtual void BroadcastSoundEffect(const AString &a_SoundName, Vector3d a_Position, float a_Volume, float a_Pitch, const cClientHandle *a_Exclude=nullptr) override
virtual bool GetPlacementBlockTypeMeta(cChunkInterface &a_ChunkInterface, cPlayer &a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ, BLOCKTYPE &a_BlockType, NIBBLETYPE &a_BlockMeta) override
Called before a block is placed into a world.
cBlockPistonHeadHandler(void)
Utilities to allow casting a cWorld to one of its interfaces without including World.h.
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 bool IsSticky(BLOCKTYPE a_BlockType)
Returns true if the piston (specified by blocktype) is a sticky piston.
bool GetBlockTypeMeta(Vector3i a_BlockPos, BLOCKTYPE &a_BlockType, NIBBLETYPE &a_BlockMeta)
Retrieves the block type and meta at the specified coords.
static const Byte PistonExtendAction
Piston extension block action.
virtual void BroadcastBlockAction(Vector3i a_BlockPos, Byte a_Byte1, Byte a_Byte2, BLOCKTYPE a_BlockType, const cClientHandle *a_Exclude=nullptr) override
static const Byte PistonRetractAction
Piston retraction block action.
void LOGWARNING(const char *a_Format, fmt::ArgList a_ArgList)
void ScheduleTask(int a_DelayTicks, std::function< void(cWorld &)> a_Task)
Queues a lambda task onto the tick thread, with the specified delay.
void DropBlockAsPickups(Vector3i a_BlockPos, const cEntity *a_Digger=nullptr, const cItem *a_Tool=nullptr)
Digs the block and spawns the relevant pickups, as if a_Digger used a_Tool to dig the block...
double GetYaw(void) const
eBlockFace
Block face constants, used in PlayerDigging and PlayerBlockPlacement packets and bbox collision calc...
static void PushBlocks(const Vector3iSet &a_BlocksToPush, cWorld &a_World, const Vector3i &a_PushDir)
Moves a list of blocks in a specific direction.
BLOCKTYPE GetBlock(Vector3i a_Pos)
static bool IsPistonBreakable(BLOCKTYPE a_Type)
static void RetractPiston(Vector3i a_BlockPos, cWorld &a_World)
virtual void OnBroken(cChunkInterface &a_ChunkInterface, cWorldInterface &a_WorldInterface, Vector3i a_BlockPos, BLOCKTYPE a_OldBlockType, NIBBLETYPE a_OldBlockMeta) override
Called after a block gets broken (replaced with air), either by player or by natural means...
std::unordered_set< Vector3i, VectorHasher< int > > Vector3iSet
static Vector3i MetadataToOffset(NIBBLETYPE a_PistonMeta)
Converts piston block's metadata into a unit vector representing the direction in which the piston wi...
void SetBlock(Vector3i a_BlockPos, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta)
Sets the block at the specified coords to the specified value.