2012-10-01 17:08:15 -04:00
2012-07-15 16:36:34 -04:00
# pragma once
2012-10-01 17:08:15 -04:00
2012-07-15 16:36:34 -04:00
# include "../Defines.h"
2012-10-01 17:08:15 -04:00
# include "../Item.h"
2013-03-15 16:18:11 -04:00
# include "../Chunk.h"
2012-10-01 17:08:15 -04:00
2012-07-15 16:36:34 -04:00
2012-10-01 17:08:15 -04:00
// fwd:
2012-07-15 16:36:34 -04:00
class cWorld ;
class cPlayer ;
2012-10-01 17:08:15 -04:00
2012-07-15 16:36:34 -04:00
class cBlockHandler
{
public :
2012-10-03 04:52:11 -04:00
cBlockHandler ( BLOCKTYPE a_BlockType ) ;
2012-08-22 12:31:13 -04:00
2013-01-11 23:46:01 -05:00
/// Called when the block gets ticked either by a random tick or by a queued tick
2012-10-03 04:52:11 -04:00
virtual void OnUpdate ( cWorld * a_World , int a_BlockX , int a_BlockY , int a_BlockZ ) ;
2012-08-22 12:31:13 -04:00
2013-01-11 23:46:01 -05:00
/** Called before a block is placed into a world.
The handler should return true to allow placement , false to refuse .
Also , the handler should set a_BlockType and a_BlockMeta to correct values for the newly placed block .
Called by cItemHandler : : GetPlacementBlockTypeMeta ( ) if the item is a block
*/
virtual bool GetPlacementBlockTypeMeta (
cWorld * a_World , cPlayer * a_Player ,
int a_BlockX , int a_BlockY , int a_BlockZ , char a_BlockFace ,
int a_CursorX , int a_CursorY , int a_CursorZ ,
BLOCKTYPE & a_BlockType , NIBBLETYPE & a_BlockMeta
) ;
/// Called by cWorld::SetBlock() after the block has been set
virtual void OnPlaced ( cWorld * a_World , int a_BlockX , int a_BlockY , int a_BlockZ , BLOCKTYPE a_BlockType , NIBBLETYPE a_BlockMeta ) ;
/// Called by cClientHandle::HandlePlaceBlock() after the player has placed a new block. Called after OnPlaced().
virtual void OnPlacedByPlayer (
cWorld * a_World , cPlayer * a_Player ,
int a_BlockX , int a_BlockY , int a_BlockZ , char a_BlockFace ,
int a_CursorX , int a_CursorY , int a_CursorZ ,
BLOCKTYPE a_BlockType , NIBBLETYPE a_BlockMeta
) ;
2012-10-01 17:08:15 -04:00
/// Called before the player has destroyed a block
2012-10-03 04:52:11 -04:00
virtual void OnDestroyedByPlayer ( cWorld * a_World , cPlayer * a_Player , int a_BlockX , int a_BlockY , int a_BlockZ ) ;
2012-10-01 17:08:15 -04:00
/// Called before a block gets destroyed / replaced with air
2012-10-03 04:52:11 -04:00
virtual void OnDestroyed ( cWorld * a_World , int a_BlockX , int a_BlockY , int a_BlockZ ) ;
2012-10-01 17:08:15 -04:00
/// Called when a direct neighbor of this block has been changed (The position is the own position, not the neighbor position)
2012-10-03 04:52:11 -04:00
virtual void OnNeighborChanged ( cWorld * a_World , int a_BlockX , int a_BlockY , int a_BlockZ ) ;
2012-10-01 17:08:15 -04:00
/// Notifies all neighbors of the given block about a change
2012-10-03 04:52:11 -04:00
static void NeighborChanged ( cWorld * a_World , int a_BlockX , int a_BlockY , int a_BlockZ ) ;
2012-10-01 17:08:15 -04:00
/// Called while the player diggs the block.
2012-10-03 04:52:11 -04:00
virtual void OnDigging ( cWorld * a_World , cPlayer * a_Player , int a_BlockX , int a_BlockY , int a_BlockZ ) ;
2012-08-06 16:10:16 -04:00
2012-10-01 17:08:15 -04:00
/// Called if the user right clicks the block and the block is useable
2013-01-11 23:46:01 -05:00
virtual void OnUse ( cWorld * a_World , cPlayer * a_Player , int a_BlockX , int a_BlockY , int a_BlockZ , char a_BlockFace , int a_CursorX , int a_CursorY , int a_CursorZ ) ;
2012-10-01 17:08:15 -04:00
/// Called when the item is mined to convert it into pickups. Pickups may specify multiple items.
virtual void ConvertToPickups ( cItems & a_Pickups , NIBBLETYPE a_BlockMeta ) ;
2013-01-26 21:00:33 -05:00
/// Handles the dropping of a block based on what ConvertToDrops() returns. This will not destroy the block. a_Digger is the entity causing the drop; it may be NULL
virtual void DropBlock ( cWorld * a_World , cEntity * a_Digger , int a_BlockX , int a_BlockY , int a_BlockZ ) ;
2012-10-01 17:08:15 -04:00
/// Returns step sound name of block
virtual const char * GetStepSound ( void ) ;
2012-08-22 12:31:13 -04:00
2013-03-15 16:18:11 -04:00
/// Checks if the block can stay at the specified relative coords in the chunk
virtual bool CanBeAt ( int a_RelX , int a_RelY , int a_RelZ , const cChunk & a_Chunk ) ;
2012-08-06 16:10:16 -04:00
2012-10-01 17:08:15 -04:00
/** Checks if the block can be placed at this point.
Default : CanBeAt ( . . . )
NOTE : This call doesn ' t actually place the block
*/
2013-03-15 16:18:11 -04:00
// virtual bool CanBePlacedAt(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Dir);
2012-08-06 16:10:16 -04:00
/// Called when the player tries to place a block on top of this block (Only if he aims directly on this block); return false to disallow
2012-10-01 17:08:15 -04:00
virtual bool DoesAllowBlockOnTop ( void ) ;
2012-08-06 16:10:16 -04:00
2012-08-22 12:31:13 -04:00
/// Called to check whether this block supports a rclk action. If it returns true, OnUse() is called
2012-08-06 16:10:16 -04:00
virtual bool IsUseable ( void ) ;
2012-10-01 17:08:15 -04:00
/** Indicates whether the client will click through this block.
For example digging a fire will hit the block below the fire so fire is clicked through
*/
2012-08-06 16:10:16 -04:00
virtual bool IsClickedThrough ( void ) ;
2012-10-01 17:08:15 -04:00
/** Checks if the player can build "inside" this block.
For example blocks placed " on " snow will be placed at the same position . So : Snow ignores Build collision
*/
virtual bool DoesIgnoreBuildCollision ( void ) ;
2012-08-06 16:10:16 -04:00
/// Indicates this block can be placed on the side of other blocks. Default: true
2012-10-01 17:08:15 -04:00
virtual bool CanBePlacedOnSide ( void ) ;
2012-10-23 14:13:37 -04:00
2012-08-06 16:10:16 -04:00
/// Does this block drop if it gets destroyed by an unsuitable situation? Default: true
2012-10-01 17:08:15 -04:00
virtual bool DoesDropOnUnsuitable ( void ) ;
2012-07-15 16:36:34 -04:00
2012-10-14 14:30:16 -04:00
/** Called when one of the neighbors gets set; equivalent to MC block update.
By default drops if position no more suitable ( CanBeAt ( ) , DoesDropOnUnsuitable ( ) , Drop ( ) ) ,
and wakes up all simulators on the block .
*/
2013-03-15 16:18:11 -04:00
virtual void Check ( int a_RelX , int a_RelY , int a_RelZ , cChunk & a_Chunk ) ;
2012-10-14 14:30:16 -04:00
2013-03-26 17:06:12 -04:00
/// Returns the meta for a block after rotating it counter-clockwise from the specified meta. Default: no change
virtual NIBBLETYPE MetaRotateCCW ( NIBBLETYPE a_Meta ) { return a_Meta ; }
/// Returns the meta for a block after rotating it clockwise from the specified meta. Default: no change
virtual NIBBLETYPE MetaRotateCW ( NIBBLETYPE a_Meta ) { return a_Meta ; }
/// Returns the meta for a block after mirroring it around the XY plane. Default: no change
virtual NIBBLETYPE MetaMirrorXY ( NIBBLETYPE a_Meta ) { return a_Meta ; }
/// Returns the meta for a block after mirroring it around the XZ plane. Default: no change
virtual NIBBLETYPE MetaMirrorXZ ( NIBBLETYPE a_Meta ) { return a_Meta ; }
/// Returns the meta for a block after mirroring it around the YZ plane. Default: no change
virtual NIBBLETYPE MetaMirrorYZ ( NIBBLETYPE a_Meta ) { return a_Meta ; }
2012-08-22 12:31:13 -04:00
2012-10-01 17:08:15 -04:00
/// Get the blockhandler for a specific block id
2012-10-03 04:52:11 -04:00
static cBlockHandler * GetBlockHandler ( BLOCKTYPE a_BlockType ) ;
2012-07-15 16:36:34 -04:00
2012-10-01 17:08:15 -04:00
/// Deletes all initialised block handlers
2012-07-15 16:36:34 -04:00
static void Deinit ( ) ;
protected :
2012-10-03 04:52:11 -04:00
BLOCKTYPE m_BlockType ;
// Creates a new blockhandler for the given block type. For internal use only, use ::GetBlockHandler() instead.
static cBlockHandler * CreateBlockHandler ( BLOCKTYPE a_BlockType ) ;
2012-07-15 16:36:34 -04:00
static cBlockHandler * m_BlockHandler [ 256 ] ;
static bool m_HandlerInitialized ; //used to detect if the blockhandlers are initialized
} ;
2012-10-01 17:08:15 -04:00
2012-08-22 12:31:13 -04:00
// Shortcut to get the blockhandler for a specific block
2012-10-03 04:52:11 -04:00
inline cBlockHandler * BlockHandler ( BLOCKTYPE a_BlockType )
2012-10-01 17:08:15 -04:00
{
2012-10-03 04:52:11 -04:00
return cBlockHandler : : GetBlockHandler ( a_BlockType ) ;
2012-10-01 17:08:15 -04:00
}