2012-07-15 16:36:34 -04:00
# pragma once
# include "../Defines.h"
class cWorld ;
class cPlayer ;
class cBlockHandler
{
public :
cBlockHandler ( BLOCKTYPE a_BlockID ) ;
2012-08-22 12:31:13 -04:00
// Called when the block gets ticked either by a random tick or by a queued tick
2012-07-15 16:36:34 -04:00
virtual void OnUpdate ( cWorld * a_World , int a_X , int a_Y , int a_Z ) ;
2012-08-22 12:31:13 -04:00
// Will be called by cBlockHandler::PlaceBlock after the player has placed a new block
2012-07-15 16:36:34 -04:00
virtual void OnPlacedByPlayer ( cWorld * a_World , cPlayer * a_Player , int a_X , int a_Y , int a_Z , int a_Dir ) ;
2012-08-22 12:31:13 -04:00
// Will be called before the player has destroyed a block
2012-07-15 16:36:34 -04:00
virtual void OnDestroyedByPlayer ( cWorld * a_World , cPlayer * a_Player , int a_X , int a_Y , int a_Z ) ;
2012-08-22 12:31:13 -04:00
// Will be called when a new block was placed. Will be called before OnPlacedByPlayer
2012-07-15 16:36:34 -04:00
virtual void OnPlaced ( cWorld * a_World , int a_X , int a_Y , int a_Z , int a_Dir ) ;
2012-08-22 12:31:13 -04:00
// Will be called before a block gets destroyed / replaced with air
2012-07-15 16:36:34 -04:00
virtual void OnDestroyed ( cWorld * a_World , int a_X , int a_Y , int a_Z ) ;
2012-08-22 12:31:13 -04:00
// Will be called when a direct neighbor of this block has been changed (The position is the own position, not the neighbor position)
2012-07-15 16:36:34 -04:00
virtual void OnNeighborChanged ( cWorld * a_World , int a_X , int a_Y , int a_Z ) ;
2012-08-22 12:31:13 -04:00
// Notifies all neighbors of the give block about a change
2012-07-15 16:36:34 -04:00
static void NeighborChanged ( cWorld * a_World , int a_X , int a_Y , int a_Z ) ;
2012-08-22 12:31:13 -04:00
// Will be called while the player diggs the block.
2012-08-19 06:44:19 -04:00
virtual void OnDigging ( cWorld * a_World , cPlayer * a_Player , int a_X , int a_Y , int a_Z ) ;
2012-08-22 12:31:13 -04:00
// Will be called if the user right clicks the block and the block is useable
2012-08-19 06:44:19 -04:00
virtual void OnUse ( cWorld * a_World , cPlayer * a_Player , int a_X , int a_Y , int a_Z ) ;
2012-08-22 12:31:13 -04:00
// This function handles the real block placement for the give block by a player and also calls the OnPlacedByPlayer function
2012-07-16 15:20:37 -04:00
virtual void PlaceBlock ( cWorld * a_World , cPlayer * a_Player , NIBBLETYPE a_BlockMeta , int a_X , int a_Y , int a_Z , char a_Dir ) ;
2012-07-15 16:36:34 -04:00
2012-08-22 12:31:13 -04:00
// Indicates how much items are dropped DEFAULT: 1
2012-07-15 16:36:34 -04:00
virtual char GetDropCount ( ) ;
2012-08-22 12:31:13 -04:00
// Indicates the id dropped by this block DEFAULT: BlockID
2012-07-15 16:36:34 -04:00
virtual int GetDropID ( ) ;
2012-08-22 12:31:13 -04:00
// Indicates the Drop Meta data based on the block meta DEFAULT: BlockMeta
2012-07-16 15:20:37 -04:00
virtual NIBBLETYPE GetDropMeta ( NIBBLETYPE a_BlockMeta ) ;
2012-08-22 12:31:13 -04:00
// This function handles the dropping of a block based on the Drop id, drop count and drop meta. This will not destroy the block
2012-07-15 16:36:34 -04:00
virtual void DropBlock ( cWorld * a_World , int a_X , int a_Y , int a_Z ) ;
2012-09-11 08:01:34 -04:00
/// Returns step sound name of block
virtual AString GetStepSound ( ) ;
2012-08-06 16:10:16 -04:00
2012-08-22 12:31:13 -04:00
// Indicates whether this block needs random ticks DEFAULT: False
virtual bool NeedsRandomTicks ( ) ;
/// Checks if the block can stay at the specified coords in the world
2012-08-06 16:10:16 -04:00
virtual bool CanBeAt ( cWorld * a_World , int a_BlockX , int a_BlockY , int a_BlockZ ) ;
/// Checks if the block can be placed at this point. Default: CanBeAt(...) NOTE: This call doesn't actually place the block
virtual bool CanBePlacedAt ( cWorld * a_World , int a_BlockX , int a_BlockY , int a_BlockZ , char a_Dir ) ;
/// 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
virtual bool AllowBlockOnTop ( void ) ;
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-08-22 12:31:13 -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-08-22 12:31:13 -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
2012-08-06 16:10:16 -04:00
virtual bool IgnoreBuildCollision ( void ) ;
/// Indicates this block can be placed on the side of other blocks. Default: true
2012-07-15 16:36:34 -04:00
virtual bool CanBePlacedOnSide ( ) ;
2012-08-06 16:10:16 -04:00
/// Does this block drop if it gets destroyed by an unsuitable situation? Default: true
2012-07-15 16:36:34 -04:00
virtual bool DropOnUnsuitable ( ) ;
2012-08-22 12:31:13 -04:00
// Static function to get the blockhandler for an specific block id
2012-08-06 16:10:16 -04:00
static cBlockHandler * GetBlockHandler ( BLOCKTYPE a_BlockID ) ;
2012-07-15 16:36:34 -04:00
2012-08-22 12:31:13 -04:00
// Deletes all initialised block handlers
2012-07-15 16:36:34 -04:00
static void Deinit ( ) ;
protected :
2012-08-06 06:36:20 -04:00
BLOCKTYPE m_BlockID ;
2012-08-22 12:31:13 -04:00
// Creates a new blockhandler for the given block id. For internal use only, use GetBlockHandler instead.
2012-07-15 16:36:34 -04:00
static cBlockHandler * CreateBlockHandler ( BLOCKTYPE a_BlockID ) ;
static cBlockHandler * m_BlockHandler [ 256 ] ;
static bool m_HandlerInitialized ; //used to detect if the blockhandlers are initialized
} ;
2012-08-22 12:31:13 -04:00
// Shortcut to get the blockhandler for a specific block
2012-07-16 15:20:37 -04:00
inline cBlockHandler * BlockHandler ( BLOCKTYPE a_BlockID ) { return cBlockHandler : : GetBlockHandler ( a_BlockID ) ; }