2013-07-29 07:13:03 -04:00
# pragma once
# include "../Defines.h"
2017-07-28 12:59:21 -04:00
# include "../BoundingBox.h"
2013-07-29 07:13:03 -04:00
// fwd:
class cPlayer ;
2014-02-01 09:01:13 -05:00
class cChunk ;
2014-09-26 13:13:19 -04:00
class cBlockPluginInterface ;
class cChunkInterface ;
class cWorldInterface ;
class cItems ;
2013-07-29 07:13:03 -04:00
class cBlockHandler
{
public :
cBlockHandler ( BLOCKTYPE a_BlockType ) ;
2016-02-05 16:45:45 -05:00
2014-03-08 11:33:38 -05:00
virtual ~ cBlockHandler ( ) { }
2013-07-29 07:13:03 -04:00
2015-07-31 10:49:10 -04:00
/** Called when the block gets ticked either by a random tick or by a queued tick.
Note that the coords are chunk - relative ! */
2014-02-02 09:49:37 -05:00
virtual void OnUpdate ( cChunkInterface & cChunkInterface , cWorldInterface & a_WorldInterface , cBlockPluginInterface & a_BlockPluginInterface , cChunk & a_Chunk , int a_RelX , int a_RelY , int a_RelZ ) ;
2013-07-29 07:13:03 -04:00
2017-07-28 12:59:21 -04:00
/** Returns the relative bounding box that must be entity-free in
order for the block to be placed . a_XM , a_XP , etc . stand for the
blocktype of the minus - X neighbor , the positive - X neighbor , etc . */
virtual cBoundingBox GetPlacementCollisionBox ( BLOCKTYPE a_XM , BLOCKTYPE a_XP , BLOCKTYPE a_YM , BLOCKTYPE a_YP , BLOCKTYPE a_ZM , BLOCKTYPE a_ZP ) ;
2014-07-17 16:50:58 -04:00
/** Called before a block is placed into a world.
2013-07-29 07:13:03 -04:00
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 .
2015-07-31 10:49:10 -04:00
Called by cItemHandler : : GetPlacementBlockTypeMeta ( ) if the item is a block */
2013-07-29 07:13:03 -04:00
virtual bool GetPlacementBlockTypeMeta (
2017-07-31 16:17:52 -04:00
cChunkInterface & a_ChunkInterface , cPlayer & a_Player ,
2014-07-17 16:50:58 -04:00
int a_BlockX , int a_BlockY , int a_BlockZ , eBlockFace a_BlockFace ,
2013-07-29 07:13:03 -04:00
int a_CursorX , int a_CursorY , int a_CursorZ ,
BLOCKTYPE & a_BlockType , NIBBLETYPE & a_BlockMeta
) ;
2014-12-24 01:20:17 -05:00
/** Called by cWorld::SetBlock() after the block has been set */
2014-02-01 08:06:32 -05:00
virtual void OnPlaced ( cChunkInterface & a_ChunkInterface , cWorldInterface & a_WorldInterface , int a_BlockX , int a_BlockY , int a_BlockZ , BLOCKTYPE a_BlockType , NIBBLETYPE a_BlockMeta ) ;
2016-02-05 16:45:45 -05:00
2014-12-24 01:20:17 -05:00
/** Called by cPlayer::PlaceBlocks() for each block after it has been set to the world. Called after OnPlaced(). */
2013-07-29 07:13:03 -04:00
virtual void OnPlacedByPlayer (
2017-07-31 16:17:52 -04:00
cChunkInterface & a_ChunkInterface , cWorldInterface & a_WorldInterface , cPlayer & a_Player , const sSetBlock & a_BlockChange
2013-07-29 07:13:03 -04:00
) ;
2016-02-05 16:45:45 -05:00
2015-07-31 10:49:10 -04:00
/** Called before the player has destroyed a block */
2017-07-31 16:17:52 -04:00
virtual void OnDestroyedByPlayer ( cChunkInterface & a_ChunkInterface , cWorldInterface & a_WorldInterface , cPlayer & a_Player , int a_BlockX , int a_BlockY , int a_BlockZ ) ;
2016-02-05 16:45:45 -05:00
2015-07-31 10:49:10 -04:00
/** Called before a block gets destroyed / replaced with air */
2014-02-01 08:06:32 -05:00
virtual void OnDestroyed ( cChunkInterface & a_ChunkInterface , cWorldInterface & a_WorldInterface , int a_BlockX , int a_BlockY , int a_BlockZ ) ;
2016-02-05 16:45:45 -05:00
2015-07-01 04:40:16 -04:00
/** Called when a direct neighbor of this block has been changed (The position is the block's own position, not the changing neighbor's position)
a_WhichNeighbor indicates which neighbor has changed . For example , BLOCK_FACE_YP meant the neighbor above has changed .
BLOCK_FACE_NONE means that it is a neighbor not directly adjacent ( diagonal , etc . ) */
virtual void OnNeighborChanged ( cChunkInterface & a_ChunkInterface , int a_BlockX , int a_BlockY , int a_BlockZ , eBlockFace a_WhichNeighbor ) { }
2016-02-05 16:45:45 -05:00
2015-07-01 04:40:16 -04:00
/** Notifies the specified neighbor that the current block has changed.
a_NeighborXYZ coords are the coords of the neighbor
a_WhichNeighbor specifies which neighbor ( relative to a_NeighborXYZ ) has changed .
For example BLOCK_FACE_YP means that the block at { a_NeighborX , a_NeighborY + 1 , a_NeighborZ } has changed .
BLOCK_FACE_NONE means that it is a neighbor not directly adjacent ( diagonal , etc . ) */
static void NeighborChanged ( cChunkInterface & a_ChunkInterface , int a_NeighborX , int a_NeighborY , int a_NeighborZ , eBlockFace a_WhichNeighbor ) ;
2016-02-05 16:45:45 -05:00
2015-07-01 04:40:16 -04:00
/** Called when the player starts digging the block. */
2017-07-31 16:17:52 -04:00
virtual void OnDigging ( cChunkInterface & cChunkInterface , cWorldInterface & a_WorldInterface , cPlayer & a_Player , int a_BlockX , int a_BlockY , int a_BlockZ ) { }
2016-02-05 16:45:45 -05:00
2015-12-01 17:12:44 -05:00
/** Called if the user right clicks the block and the block is useable
returns true if the use was successful , return false to use the block as a " normal " block */
2017-07-31 16:17:52 -04:00
virtual bool OnUse ( cChunkInterface & a_ChunkInterface , cWorldInterface & a_WorldInterface , cPlayer & a_Player , int a_BlockX , int a_BlockY , int a_BlockZ , eBlockFace a_BlockFace , int a_CursorX , int a_CursorY , int a_CursorZ ) { return false ; }
2016-02-05 16:45:45 -05:00
2014-07-20 07:00:20 -04:00
/** Called when a right click to this block is cancelled */
2017-07-31 16:17:52 -04:00
virtual void OnCancelRightClick ( cChunkInterface & a_ChunkInterface , cWorldInterface & a_WorldInterface , cPlayer & a_Player , int a_BlockX , int a_BlockY , int a_BlockZ , eBlockFace a_BlockFace ) { }
2016-02-05 16:45:45 -05:00
2015-07-31 10:49:10 -04:00
/** Called when the item is mined to convert it into pickups. Pickups may specify multiple items. Appends items to a_Pickups, preserves its original contents */
2013-07-29 07:13:03 -04:00
virtual void ConvertToPickups ( cItems & a_Pickups , NIBBLETYPE a_BlockMeta ) ;
2016-02-05 16:45:45 -05:00
2017-07-07 03:31:45 -04:00
/** Called when the item is mined to convert it into pickups. Pickups may specify multiple items. Appends items to a_Pickups, preserves its original contents.
2017-08-25 05:56:01 -04:00
Overloaded method with coords and world interface for blocks that needs to access the block entity , e . g . a bed . */
virtual void ConvertToPickups ( cWorldInterface & a_WorldInterface , cItems & a_Pickups , NIBBLETYPE a_BlockMeta , int a_BlockX , int a_BlockY , int a_BlockZ ) { }
2017-07-07 03:31:45 -04:00
2014-07-20 07:00:20 -04:00
/** Handles the dropping, but not destruction, of a block based on what ConvertTo(Verbatim)Pickups() returns, including the spawning of pickups and alertion of plugins
2014-10-20 16:55:07 -04:00
@ param a_Digger The entity causing the drop ; it may be nullptr
2014-07-24 16:38:25 -04:00
@ param a_CanDrop Informs the handler whether the block should be dropped at all . One example when this is false is when stone is destroyed by hand
2014-07-20 07:00:20 -04:00
@ param a_DropVerbatim Calls ConvertToVerbatimPickups ( ) instead of its counterpart , meaning the block itself is dropped by default ( due to a speical tool or enchantment )
*/
2014-09-13 17:49:27 -04:00
virtual void DropBlock ( cChunkInterface & a_ChunkInterface , cWorldInterface & a_WorldInterface , cBlockPluginInterface & a_BlockPluginInterface , cEntity * a_Digger , int a_BlockX , int a_BlockY , int a_BlockZ , bool a_CanDrop = true ) ;
2016-02-05 16:45:45 -05:00
2015-07-31 10:49:10 -04:00
/** Checks if the block can stay at the specified relative coords in the chunk */
2014-02-01 08:06:32 -05:00
virtual bool CanBeAt ( cChunkInterface & a_ChunkInterface , int a_RelX , int a_RelY , int a_RelZ , const cChunk & a_Chunk ) ;
2015-08-19 12:45:53 -04:00
/** Checks whether the block has an effect on growing the plant */
virtual bool CanSustainPlant ( BLOCKTYPE a_Plant ) { return false ; }
2016-02-05 16:45:45 -05:00
2013-07-29 07:13:03 -04:00
/** Checks if the block can be placed at this point.
2014-07-17 16:50:58 -04:00
Default : CanBeAt ( . . . )
2013-07-29 07:13:03 -04:00
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);
2016-02-05 16:45:45 -05:00
2014-12-24 01:20:17 -05:00
/** Called to check whether this block supports a rclk action.
If it returns true , OnUse ( ) is called */
2013-07-29 07:13:03 -04:00
virtual bool IsUseable ( void ) ;
2016-02-05 16:45:45 -05:00
2014-07-17 16:50:58 -04:00
/** Indicates whether the client will click through this block.
2013-07-29 07:13:03 -04:00
For example digging a fire will hit the block below the fire so fire is clicked through
*/
virtual bool IsClickedThrough ( void ) ;
2016-02-05 16:45:45 -05:00
2014-07-17 16:50:58 -04:00
/** Checks if the player can build "inside" this block.
2013-07-29 07:13:03 -04:00
For example blocks placed " on " snow will be placed at the same position . So : Snow ignores Build collision
2017-07-07 10:37:53 -04:00
@ param a_Pos Position of the block
@ param a_Player Player trying to build on the block
@ param a_Meta Meta value of the block currently at a_Pos
2013-07-29 07:13:03 -04:00
*/
2017-07-07 10:37:53 -04:00
virtual bool DoesIgnoreBuildCollision ( cChunkInterface & ChunkInterface , Vector3i a_Pos , cPlayer & a_Player , NIBBLETYPE a_Meta ) ;
2013-11-29 19:31:21 -05:00
2014-12-24 01:20:17 -05:00
/** Returns if this block drops if it gets destroyed by an unsuitable situation.
Default : true */
2013-07-29 07:13:03 -04:00
virtual bool DoesDropOnUnsuitable ( void ) ;
2015-11-10 08:02:07 -05:00
/** Tests if a_Position is inside the block where a_Position is relative to the origin of the block
Note that this is considered from a " top-down " perspective i . e . empty spaces on the bottom of a block don ' t matter */
virtual bool IsInsideBlock ( const Vector3d & a_Position , const BLOCKTYPE a_BlockType , const NIBBLETYPE a_BlockMeta ) ;
2014-07-17 16:50:58 -04:00
/** Called when one of the neighbors gets set; equivalent to MC block update.
2013-07-29 07:13:03 -04:00
By default drops if position no more suitable ( CanBeAt ( ) , DoesDropOnUnsuitable ( ) , Drop ( ) ) ,
2014-12-24 01:20:17 -05:00
and wakes up all simulators on the block . */
2014-02-02 09:49:37 -05:00
virtual void Check ( cChunkInterface & ChunkInterface , cBlockPluginInterface & a_PluginInterface , int a_RelX , int a_RelY , int a_RelZ , cChunk & a_Chunk ) ;
2015-06-30 10:50:15 -04:00
2017-08-24 05:19:40 -04:00
/** Returns the base colour ID of the block, as will be represented on a map, as per documentation: https://minecraft.gamepedia.com/Map_item_format */
2015-06-30 10:50:15 -04:00
virtual ColourID GetMapBaseColourID ( NIBBLETYPE a_Meta ) ;
2016-02-05 16:45:45 -05:00
2015-07-31 10:49:10 -04:00
/** Rotates a given block meta counter-clockwise. Default: no change
Returns block meta following rotation */
2013-07-29 07:13:03 -04:00
virtual NIBBLETYPE MetaRotateCCW ( NIBBLETYPE a_Meta ) { return a_Meta ; }
2016-02-05 16:45:45 -05:00
2015-07-31 10:49:10 -04:00
/** Rotates a given block meta clockwise. Default: no change
Returns block meta following rotation */
2013-07-29 07:13:03 -04:00
virtual NIBBLETYPE MetaRotateCW ( NIBBLETYPE a_Meta ) { return a_Meta ; }
2016-02-05 16:45:45 -05:00
2015-07-31 10:49:10 -04:00
/** Mirrors a given block meta around the XY plane. Default: no change
Returns block meta following rotation */
2013-07-29 07:13:03 -04:00
virtual NIBBLETYPE MetaMirrorXY ( NIBBLETYPE a_Meta ) { return a_Meta ; }
2015-07-31 10:49:10 -04:00
/** Mirros a given block meta around the XZ plane. Default: no change
Returns block meta following rotation */
2013-07-29 07:13:03 -04:00
virtual NIBBLETYPE MetaMirrorXZ ( NIBBLETYPE a_Meta ) { return a_Meta ; }
2015-07-31 10:49:10 -04:00
/** Mirros a given block meta around the YZ plane. Default: no change
Returns block meta following rotation */
2013-07-29 07:13:03 -04:00
virtual NIBBLETYPE MetaMirrorYZ ( NIBBLETYPE a_Meta ) { return a_Meta ; }
2016-02-05 16:45:45 -05:00
2013-07-29 07:13:03 -04:00
protected :
BLOCKTYPE m_BlockType ;
2016-02-05 16:45:45 -05:00
2013-07-29 07:13:03 -04:00
// Creates a new blockhandler for the given block type. For internal use only, use ::GetBlockHandler() instead.
2014-03-02 14:25:05 -05:00
static cBlockHandler * CreateBlockHandler ( BLOCKTYPE a_BlockType ) ;
2013-07-29 07:13:03 -04:00
2014-03-02 14:25:05 -05:00
friend class cBlockInfo ;
} ;
2013-07-29 07:13:03 -04:00