2017-09-02 03:45:06 -04:00
2012-06-14 09:06:06 -04:00
# pragma once
2020-04-03 17:23:38 -04:00
# include "BlockEntities/BlockEntity.h"
2013-08-19 05:39:13 -04:00
# include "Entities/Entity.h"
2014-05-21 14:58:48 -04:00
# include "ChunkData.h"
2012-06-14 09:06:06 -04:00
2013-03-01 14:35:29 -05:00
# include "Simulator/FireSimulator.h"
2013-03-02 14:57:09 -05:00
# include "Simulator/SandSimulator.h"
2015-06-26 18:24:51 -04:00
# include "Simulator/RedstoneSimulator.h"
2013-03-01 14:35:29 -05:00
2014-09-26 13:13:19 -04:00
# include "ChunkMap.h"
2012-06-14 09:06:06 -04:00
class cWorld ;
class cClientHandle ;
class cPlayer ;
class cChunkMap ;
2014-07-30 16:19:51 -04:00
class cBeaconEntity ;
2017-07-07 03:31:45 -04:00
class cBedEntity ;
2015-09-24 04:48:33 -04:00
class cBrewingstandEntity ;
2014-09-26 13:13:19 -04:00
class cBoundingBox ;
2012-06-17 15:58:39 -04:00
class cChestEntity ;
2014-10-03 16:32:41 -04:00
class cChunkDataCallback ;
2014-09-26 13:13:19 -04:00
class cCommandBlockEntity ;
2012-12-19 16:19:36 -05:00
class cDispenserEntity ;
2012-06-17 15:58:39 -04:00
class cFurnaceEntity ;
2020-03-27 08:03:28 -04:00
class cHopperEntity ;
2013-12-14 11:52:22 -05:00
class cNoteEntity ;
2014-02-19 08:45:09 -05:00
class cMobHeadEntity ;
2014-03-06 19:30:34 -05:00
class cFlowerPotEntity ;
2012-07-02 15:22:05 -04:00
class cBlockArea ;
2012-10-06 12:58:31 -04:00
class cBlockArea ;
2013-03-02 10:44:31 -05:00
class cFluidSimulatorData ;
2013-09-07 16:19:56 -04:00
class cMobCensus ;
2013-09-07 18:11:38 -04:00
class cMobSpawner ;
2014-09-26 13:13:19 -04:00
class cSetChunkData ;
2012-06-14 09:06:06 -04:00
2017-09-11 17:20:49 -04:00
typedef std : : list < cClientHandle * > cClientHandleList ;
2012-06-14 09:06:06 -04:00
2016-01-17 09:09:25 -05:00
// A convenience macro for calling GetChunkAndRelByAbsolute.
2019-08-11 05:39:43 -04:00
# define PREPARE_REL_AND_CHUNK(Position, OriginalChunk) cChunk * Chunk; Vector3i Rel; bool RelSuccess = (OriginalChunk).GetChunkAndRelByAbsolute(Position, &Chunk, Rel)
2016-01-17 09:09:25 -05:00
# define PREPARE_BLOCKDATA BLOCKTYPE BlockType; NIBBLETYPE BlockMeta;
2012-06-14 09:06:06 -04:00
// This class is not to be used directly
// Instead, call actions on cChunkMap (such as cChunkMap::SetBlock() etc.)
class cChunk :
public cChunkDef // The inheritance is "misused" here only to inherit the functions and constants defined in cChunkDef
{
public :
2016-12-19 15:12:23 -05:00
2014-09-05 16:16:48 -04:00
/** Represents the presence state of the chunk */
enum ePresence
{
cpInvalid , /**< The chunk is not present at all and is not queued in the loader / generator */
cpQueued , /**< The chunk is not present, but is queued for loading / generation */
cpPresent , /**< The chunk is present */
} ;
2012-12-14 17:38:30 -05:00
cChunk (
2014-08-28 05:36:35 -04:00
int a_ChunkX , int a_ChunkZ , // Chunk coords
2012-12-14 17:38:30 -05:00
cChunkMap * a_ChunkMap , cWorld * a_World , // Parent objects
2014-06-16 10:12:50 -04:00
cAllocationPool < cChunkData : : sChunkSection > & a_Pool
2012-12-14 17:38:30 -05:00
) ;
2020-08-20 13:29:20 -04:00
cChunk ( const cChunk & Other ) = delete ;
2012-06-14 09:06:06 -04:00
~ cChunk ( ) ;
2014-09-05 16:16:48 -04:00
/** Returns true iff the chunk block data is valid (loaded / generated) */
bool IsValid ( void ) const { return ( m_Presence = = cpPresent ) ; }
/** Returns true iff the chunk is in the queue for loading / generating */
bool IsQueued ( void ) const { return ( m_Presence = = cpQueued ) ; }
/** Sets the chunk's presence.
Wakes up any calls to cChunkMap : : GetHeight ( ) when setting to cpPresent . */
void SetPresence ( ePresence a_Presence ) ;
/** Marks all clients attached to this chunk as wanting this chunk. Also sets presence to cpQueued. */
void MarkRegenerating ( void ) ;
/** Returns true iff the chunk has changed since it was last saved. */
bool IsDirty ( void ) const { return m_IsDirty ; }
2020-08-20 07:50:22 -04:00
bool CanUnload ( void ) const ;
2016-01-17 09:09:25 -05:00
2016-09-03 11:38:29 -04:00
/** Returns true if the chunk could have been unloaded if it weren't dirty */
2020-08-20 07:50:22 -04:00
bool CanUnloadAfterSaving ( void ) const ;
2016-09-03 11:38:29 -04:00
2012-06-14 09:06:06 -04:00
bool IsLightValid ( void ) const { return m_IsLightValid ; }
2016-01-17 09:09:25 -05:00
2012-06-14 09:06:06 -04:00
/*
To save a chunk , the WSSchema must :
2014-07-21 09:19:48 -04:00
1. Mark the chunk as being saved ( MarkSaving ( ) )
2012-06-14 09:06:06 -04:00
2. Get the chunk ' s data using GetAllData ( )
2014-07-21 09:19:48 -04:00
3. Mark the chunk as saved ( MarkSaved ( ) )
2012-06-14 09:06:06 -04:00
If anywhere inside this sequence another thread mmodifies the chunk , the chunk will not get marked as saved in MarkSaved ( )
*/
2014-07-17 10:33:09 -04:00
void MarkSaving ( void ) ; // Marks the chunk as being saved.
2012-06-14 09:06:06 -04:00
void MarkSaved ( void ) ; // Marks the chunk as saved, if it didn't change from the last call to MarkSaving()
void MarkLoaded ( void ) ; // Marks the chunk as freshly loaded. Fails if the chunk is already valid
2014-09-05 16:16:48 -04:00
2020-08-28 16:26:04 -04:00
/** Queues the chunk for generating. */
2014-09-05 16:16:48 -04:00
void MarkLoadFailed ( void ) ;
2016-01-17 09:09:25 -05:00
2014-02-08 15:55:21 -05:00
/** Gets all chunk data, calls the a_Callback's methods for each data type */
2012-06-14 09:06:06 -04:00
void GetAllData ( cChunkDataCallback & a_Callback ) ;
2016-01-17 09:09:25 -05:00
2014-07-24 12:32:05 -04:00
/** Sets all chunk data as either loaded from the storage or generated.
BlockLight and BlockSkyLight are optional , if not present , chunk will be marked as unlighted .
Modifies the BlockEntity list in a_SetChunkData - moves the block entities into the chunk . */
void SetAllData ( cSetChunkData & a_SetChunkData ) ;
2016-01-17 09:09:25 -05:00
2012-06-14 09:06:06 -04:00
void SetLight (
const cChunkDef : : BlockNibbles & a_BlockLight ,
const cChunkDef : : BlockNibbles & a_SkyLight
) ;
2016-01-17 09:09:25 -05:00
2014-02-08 15:55:21 -05:00
/** Copies m_BlockData into a_BlockTypes, only the block types */
2012-06-14 09:06:06 -04:00
void GetBlockTypes ( BLOCKTYPE * a_BlockTypes ) ;
2016-01-17 09:09:25 -05:00
2014-02-08 15:55:21 -05:00
/** Writes the specified cBlockArea at the coords specified. Note that the coords may extend beyond the chunk! */
2012-10-06 12:58:31 -04:00
void WriteBlockArea ( cBlockArea & a_Area , int a_MinBlockX , int a_MinBlockY , int a_MinBlockZ , int a_DataTypes ) ;
2014-02-08 15:55:21 -05:00
/** Returns true if there is a block entity at the coords specified */
2018-07-23 14:12:51 -04:00
bool HasBlockEntityAt ( Vector3i a_BlockPos ) ;
2016-01-17 09:09:25 -05:00
2014-02-08 15:55:21 -05:00
/** Sets or resets the internal flag that prevents chunk from being unloaded.
The flag is cumulative - it can be set multiple times and then needs to be un - set that many times
before the chunk is unloadable again . */
2012-06-14 09:06:06 -04:00
void Stay ( bool a_Stay = true ) ;
2016-01-17 09:09:25 -05:00
2014-02-08 15:55:21 -05:00
/** Recence all mobs proximities to players in order to know what to do with them */
2015-05-09 05:16:56 -04:00
void CollectMobCensus ( cMobCensus & toFill ) ;
2013-09-07 16:19:56 -04:00
2014-02-08 15:55:21 -05:00
/** Try to Spawn Monsters inside chunk */
2015-05-09 05:16:56 -04:00
void SpawnMobs ( cMobSpawner & a_MobSpawner ) ;
2013-09-07 18:11:38 -04:00
2015-01-11 16:12:26 -05:00
void Tick ( std : : chrono : : milliseconds a_Dt ) ;
2016-01-17 09:09:25 -05:00
2014-02-08 15:55:21 -05:00
/** Ticks a single block. Used by cWorld::TickQueuedBlocks() to tick the queued blocks */
2020-04-17 05:36:37 -04:00
void TickBlock ( const Vector3i a_RelPos ) ;
2012-06-14 09:06:06 -04:00
2013-03-15 16:18:11 -04:00
int GetPosX ( void ) const { return m_PosX ; }
int GetPosZ ( void ) const { return m_PosZ ; }
2020-04-05 15:20:52 -04:00
cChunkCoords GetPos ( ) const { return { m_PosX , m_PosZ } ; }
2016-01-17 09:09:25 -05:00
2013-03-15 16:18:11 -04:00
cWorld * GetWorld ( void ) const { return m_World ; }
2012-06-14 09:06:06 -04:00
2019-10-16 04:06:34 -04:00
void SetBlock ( Vector3i a_RelBlockPos , BLOCKTYPE a_BlockType , NIBBLETYPE a_BlockMeta ) ;
2012-06-14 09:06:06 -04:00
// SetBlock() does a lot of work (heightmap, tickblocks, blockentities) so a BlockIdx version doesn't make sense
2016-01-17 09:09:25 -05:00
2020-08-26 16:45:13 -04:00
void FastSetBlock ( int a_RelX , int a_RelY , int a_RelZ , BLOCKTYPE a_BlockType , BLOCKTYPE a_BlockMeta ) ; // Doesn't force block updates on neighbors, use for simple changes such as grass growing etc.
void FastSetBlock ( Vector3i a_RelPos , BLOCKTYPE a_BlockType , BLOCKTYPE a_BlockMeta )
2018-02-04 17:15:31 -05:00
{
2020-08-26 16:45:13 -04:00
FastSetBlock ( a_RelPos . x , a_RelPos . y , a_RelPos . z , a_BlockType , a_BlockMeta ) ;
2018-02-04 17:15:31 -05:00
}
BLOCKTYPE GetBlock ( int a_RelX , int a_RelY , int a_RelZ ) const { return m_ChunkData . GetBlock ( { a_RelX , a_RelY , a_RelZ } ) ; }
BLOCKTYPE GetBlock ( Vector3i a_RelCoords ) const { return m_ChunkData . GetBlock ( a_RelCoords ) ; }
void GetBlockTypeMeta ( Vector3i a_RelPos , BLOCKTYPE & a_BlockType , NIBBLETYPE & a_BlockMeta ) const ;
void GetBlockTypeMeta ( int a_RelX , int a_RelY , int a_RelZ , BLOCKTYPE & a_BlockType , NIBBLETYPE & a_BlockMeta ) const
{
GetBlockTypeMeta ( { a_RelX , a_RelY , a_RelZ } , a_BlockType , a_BlockMeta ) ;
}
void GetBlockInfo ( Vector3i a_RelPos , BLOCKTYPE & a_BlockType , NIBBLETYPE & a_Meta , NIBBLETYPE & a_SkyLight , NIBBLETYPE & a_BlockLight ) ;
void GetBlockInfo ( int a_RelX , int a_RelY , int a_RelZ , BLOCKTYPE & a_BlockType , NIBBLETYPE & a_Meta , NIBBLETYPE & a_SkyLight , NIBBLETYPE & a_BlockLight )
{
GetBlockInfo ( { a_RelX , a_RelY , a_RelZ } , a_BlockType , a_Meta , a_SkyLight , a_BlockLight ) ;
}
2016-01-17 09:09:25 -05:00
/** Convert absolute coordinates into relative coordinates.
Returns false on failure to obtain a valid chunk . Returns true otherwise .
@ param a_Position The position you ' d like to convert , a_Position need not be in the calling chunk and can safely be out
of its bounds , but for best performance , it should not be too far from the calling chunk .
@ param a_Chunk Returns the chunk in which a_Position is in . If a_Position is within the calling chunk ' s bounds ,
returns the calling chunk . For best performance , a_Position shouldn ' t be too far from the calling chunk .
@ param a_Rel Returns the converted relative position . Note that it is relative to the returned a_Chunk .
The vector will not be modified if the function returns false . */
bool GetChunkAndRelByAbsolute ( const Vector3d & a_Position , cChunk * * a_Chunk , Vector3i & a_Rel ) ;
/** Convert absolute coordinates into relative coordinates.
Returns false on failure to obtain a valid chunk . Returns true otherwise .
@ param a_Position The position you ' d like to convert , a_Position need not be in the calling chunk and can safely be out
of its bounds , but for best performance , it should not be too far from the calling chunk .
@ param a_Chunk Returns the chunk in which a_Position is in . If a_Position is within the calling chunk ' s bounds ,
returns the calling chunk . For best performance , a_Position shouldn ' t be too far from the calling chunk .
@ param a_Rel Returns the converted relative position . Note that it is relative to the returned a_Chunk .
The vector will not be modified if the function returns false . */
bool GetChunkAndRelByAbsolute ( const Vector3i & a_Position , cChunk * * a_Chunk , Vector3i & a_Rel ) ;
2013-02-28 02:42:45 -05:00
/** Returns the chunk into which the specified block belongs, by walking the neighbors.
2019-10-11 05:02:53 -04:00
Will return self if appropriate . Returns nullptr if not reachable through neighbors . */
2013-03-01 14:35:29 -05:00
cChunk * GetNeighborChunk ( int a_BlockX , int a_BlockZ ) ;
2016-01-17 09:09:25 -05:00
2019-10-11 05:02:53 -04:00
/** Returns the chunk into which the relatively-specified block belongs, by walking the neighbors.
Will return self if appropriate . Returns nullptr if not reachable through neighbors . */
2013-03-01 14:35:29 -05:00
cChunk * GetRelNeighborChunk ( int a_RelX , int a_RelZ ) ;
2016-01-17 09:09:25 -05:00
2019-10-11 05:02:53 -04:00
/** Returns the chunk into which the relatively-specified block belongs.
2013-05-28 08:18:03 -04:00
Also modifies the relative coords from this - relative to return - relative .
2013-10-22 11:54:09 -04:00
Will return self if appropriate .
2019-10-11 05:02:53 -04:00
Will try walking the neighbors first ; if that fails , will query the chunkmap . */
cChunk * GetRelNeighborChunkAdjustCoords ( Vector3i & a_RelPos ) const ;
2016-01-17 09:09:25 -05:00
2012-06-14 09:06:06 -04:00
EMCSBiome GetBiomeAt ( int a_RelX , int a_RelZ ) const { return cChunkDef : : GetBiome ( m_BiomeMap , a_RelX , a_RelZ ) ; }
2016-01-17 09:09:25 -05:00
2014-02-18 07:06:18 -05:00
/** Sets the biome at the specified relative coords.
Doesn ' t resend the chunk to clients . */
void SetBiomeAt ( int a_RelX , int a_RelZ , EMCSBiome a_Biome ) ;
2016-01-17 09:09:25 -05:00
2014-02-18 07:06:18 -05:00
/** Sets the biome in the specified relative coords area. All the coords are inclusive.
Sends the chunk to all relevant clients . */
void SetAreaBiome ( int a_MinRelX , int a_MaxRelX , int a_MinRelZ , int a_MaxRelZ , EMCSBiome a_Biome ) ;
2016-01-17 09:09:25 -05:00
2014-02-08 15:55:21 -05:00
/** Sets the sign text. Returns true if successful. Also sends update packets to all clients in the chunk */
2013-06-12 03:14:06 -04:00
bool SetSignLines ( int a_RelX , int a_RelY , int a_RelZ , const AString & a_Line1 , const AString & a_Line2 , const AString & a_Line3 , const AString & a_Line4 ) ;
2012-06-14 09:06:06 -04:00
2014-07-21 09:19:48 -04:00
int GetHeight ( int a_X , int a_Z ) ;
2012-06-14 09:06:06 -04:00
2012-08-25 13:52:08 -04:00
void SendBlockTo ( int a_RelX , int a_RelY , int a_RelZ , cClientHandle * a_Client ) ;
2012-06-14 09:06:06 -04:00
2014-02-08 15:55:21 -05:00
/** Adds a client to the chunk; returns true if added, false if already there */
2014-07-10 12:18:32 -04:00
bool AddClient ( cClientHandle * a_Client ) ;
2016-01-17 09:09:25 -05:00
2014-07-10 12:18:32 -04:00
/** Removes the specified client from the chunk; ignored if client not in chunk. */
void RemoveClient ( cClientHandle * a_Client ) ;
2016-01-17 09:09:25 -05:00
2014-07-10 12:18:32 -04:00
/** Returns true if the specified client is present in this chunk. */
bool HasClient ( cClientHandle * a_Client ) ;
2016-01-17 09:09:25 -05:00
2014-07-10 12:18:32 -04:00
/** Returns true if theres any client in the chunk; false otherwise */
bool HasAnyClients ( void ) const ;
2012-06-14 09:06:06 -04:00
2016-12-19 15:12:23 -05:00
void AddEntity ( OwnedEntity a_Entity ) ;
/** Releases ownership of the given entity if it was found in this chunk.
Returns an owning reference to the found entity . */
OwnedEntity RemoveEntity ( cEntity & a_Entity ) ;
2020-08-08 07:09:40 -04:00
bool HasEntity ( UInt32 a_EntityID ) const ;
2016-01-17 09:09:25 -05:00
2014-02-08 15:55:21 -05:00
/** Calls the callback for each entity; returns true if all entities processed, false if the callback aborted by returning true */
2020-08-08 07:09:40 -04:00
bool ForEachEntity ( cEntityCallback a_Callback ) const ; // Lua-accessible
2012-06-16 04:35:07 -04:00
2014-09-03 11:00:26 -04:00
/** Calls the callback for each entity that has a nonempty intersection with the specified boundingbox.
Returns true if all entities processed , false if the callback aborted by returning true . */
2020-08-08 07:09:40 -04:00
bool ForEachEntityInBox ( const cBoundingBox & a_Box , cEntityCallback a_Callback ) const ; // Lua-accessible
2014-09-03 11:00:26 -04:00
2014-02-08 15:55:21 -05:00
/** Calls the callback if the entity with the specified ID is found, with the entity object as the callback param. Returns true if entity found. */
2020-08-08 07:09:40 -04:00
bool DoWithEntityByID ( UInt32 a_EntityID , cEntityCallback a_Callback , bool & a_CallbackResult ) const ; // Lua-accessible
2013-04-13 17:02:10 -04:00
2017-05-22 16:27:55 -04:00
/** Calls the callback for each tyEntity; returns true if all block entities processed, false if the callback aborted by returning true
tBlocktypes are all blocktypes convertible to tyEntity which are to be called . If no block type is given the callback is called for every block entity
Accessible only from within Chunk . cpp */
template < class tyEntity , BLOCKTYPE . . . tBlocktype >
2017-09-11 17:20:49 -04:00
bool GenericForEachBlockEntity ( cFunctionRef < bool ( tyEntity & ) > a_Callback ) ;
2017-05-22 16:27:55 -04:00
2014-02-08 15:55:21 -05:00
/** Calls the callback for each block entity; returns true if all block entities processed, false if the callback aborted by returning true */
2017-09-11 17:20:49 -04:00
bool ForEachBlockEntity ( cBlockEntityCallback a_Callback ) ; // Lua-accessible
2013-11-20 15:53:29 -05:00
2015-09-24 04:48:33 -04:00
/** Calls the callback for each brewingstand; returns true if all brewingstands processed, false if the callback aborted by returning true */
2017-09-11 17:20:49 -04:00
bool ForEachBrewingstand ( cBrewingstandCallback a_Callback ) ; // Lua-accessible
2015-09-24 04:48:33 -04:00
2014-02-08 15:55:21 -05:00
/** Calls the callback for each chest; returns true if all chests processed, false if the callback aborted by returning true */
2017-09-11 17:20:49 -04:00
bool ForEachChest ( cChestCallback a_Callback ) ; // Lua-accessible
2012-06-17 15:58:39 -04:00
2014-02-08 15:55:21 -05:00
/** Calls the callback for each dispenser; returns true if all dispensers processed, false if the callback aborted by returning true */
2017-09-11 17:20:49 -04:00
bool ForEachDispenser ( cDispenserCallback a_Callback ) ;
2012-12-26 12:16:33 -05:00
2014-02-08 15:55:21 -05:00
/** Calls the callback for each dropper; returns true if all droppers processed, false if the callback aborted by returning true */
2017-09-11 17:20:49 -04:00
bool ForEachDropper ( cDropperCallback a_Callback ) ;
2013-05-26 10:39:04 -04:00
2014-02-08 15:55:21 -05:00
/** Calls the callback for each dropspenser; returns true if all dropspensers processed, false if the callback aborted by returning true */
2017-09-11 17:20:49 -04:00
bool ForEachDropSpenser ( cDropSpenserCallback a_Callback ) ;
2013-05-26 10:39:04 -04:00
2014-02-08 15:55:21 -05:00
/** Calls the callback for each furnace; returns true if all furnaces processed, false if the callback aborted by returning true */
2017-09-11 17:20:49 -04:00
bool ForEachFurnace ( cFurnaceCallback a_Callback ) ; // Lua-accessible
2016-01-17 09:09:25 -05:00
2017-05-22 16:27:55 -04:00
/** Calls the callback for the tyEntity at the specified coords; returns false if there's no such block entity at those coords, true if found
tBlocktype is a list of the blocktypes to be called . If no BLOCKTYPE template arguments are given the callback is called for any block entity
Accessible only from within Chunk . cpp */
template < class tyEntity , BLOCKTYPE . . . tBlocktype >
2020-07-25 15:31:48 -04:00
bool GenericDoWithBlockEntityAt ( Vector3i a_Position , cFunctionRef < bool ( tyEntity & ) > a_Callback ) ;
2017-05-22 16:27:55 -04:00
2014-02-08 15:55:21 -05:00
/** Calls the callback for the block entity at the specified coords; returns false if there's no block entity at those coords, true if found */
2020-07-25 15:31:48 -04:00
bool DoWithBlockEntityAt ( Vector3i a_Position , cBlockEntityCallback a_Callback ) ; // Lua-acessible
2016-01-17 09:09:25 -05:00
2014-07-30 16:19:51 -04:00
/** Calls the callback for the beacon at the specified coords; returns false if there's no beacon at those coords, true if found */
2020-07-25 15:31:48 -04:00
bool DoWithBeaconAt ( Vector3i a_Position , cBeaconCallback a_Callback ) ; // Lua-acessible
2014-07-30 16:19:51 -04:00
2015-09-24 04:48:33 -04:00
/** Calls the callback for the brewingstand at the specified coords; returns false if there's no brewingstand at those coords, true if found */
2020-07-25 15:31:48 -04:00
bool DoWithBrewingstandAt ( Vector3i a_Position , cBrewingstandCallback a_Callback ) ; // Lua-acessible
2015-09-24 04:48:33 -04:00
2017-07-07 03:31:45 -04:00
/** Calls the callback for the bed at the specified coords; returns false if there's no bed at those coords, true if found */
2020-07-25 15:31:48 -04:00
bool DoWithBedAt ( Vector3i a_Position , cBedCallback a_Callback ) ; // Lua-acessible
2017-07-07 03:31:45 -04:00
2014-02-08 15:55:21 -05:00
/** Calls the callback for the chest at the specified coords; returns false if there's no chest at those coords, true if found */
2020-07-25 15:31:48 -04:00
bool DoWithChestAt ( Vector3i a_Position , cChestCallback a_Callback ) ; // Lua-acessible
2012-06-17 15:58:39 -04:00
2014-02-08 15:55:21 -05:00
/** Calls the callback for the dispenser at the specified coords; returns false if there's no dispenser at those coords or callback returns true, returns true if found */
2020-07-25 15:31:48 -04:00
bool DoWithDispenserAt ( Vector3i a_Position , cDispenserCallback a_Callback ) ;
2012-12-26 12:16:33 -05:00
2014-02-08 15:55:21 -05:00
/** Calls the callback for the dispenser at the specified coords; returns false if there's no dropper at those coords or callback returns true, returns true if found */
2020-07-25 15:31:48 -04:00
bool DoWithDropperAt ( Vector3i a_Position , cDropperCallback a_Callback ) ;
2013-05-26 10:39:04 -04:00
2014-02-08 15:55:21 -05:00
/** Calls the callback for the dispenser at the specified coords; returns false if there's no dropspenser at those coords or callback returns true, returns true if found */
2020-07-25 15:31:48 -04:00
bool DoWithDropSpenserAt ( Vector3i a_Position , cDropSpenserCallback a_Callback ) ;
2013-05-26 10:39:04 -04:00
2014-02-08 15:55:21 -05:00
/** Calls the callback for the furnace at the specified coords; returns false if there's no furnace at those coords or callback returns true, returns true if found */
2020-07-25 15:31:48 -04:00
bool DoWithFurnaceAt ( Vector3i a_Position , cFurnaceCallback a_Callback ) ; // Lua-accessible
2012-06-17 15:58:39 -04:00
2020-03-27 08:03:28 -04:00
/** Calls the callback for the hopper at the specified coords; returns false if there's no hopper at those coords or callback returns true, returns true if found */
2020-07-25 15:31:48 -04:00
bool DoWithHopperAt ( Vector3i a_Position , cHopperCallback a_Callback ) ; // Lua-accessible
2020-03-27 08:03:28 -04:00
2014-02-08 15:55:21 -05:00
/** Calls the callback for the noteblock at the specified coords; returns false if there's no noteblock at those coords or callback returns true, returns true if found */
2020-07-25 15:31:48 -04:00
bool DoWithNoteBlockAt ( Vector3i a_Position , cNoteBlockCallback a_Callback ) ;
2013-12-14 11:52:22 -05:00
2014-02-08 15:55:21 -05:00
/** Calls the callback for the command block at the specified coords; returns false if there's no command block at those coords or callback returns true, returns true if found */
2020-07-25 15:31:48 -04:00
bool DoWithCommandBlockAt ( Vector3i a_Position , cCommandBlockCallback a_Callback ) ;
2016-01-17 09:09:25 -05:00
2014-03-06 19:30:34 -05:00
/** Calls the callback for the mob head block at the specified coords; returns false if there's no mob head block at those coords or callback returns true, returns true if found */
2020-07-25 15:31:48 -04:00
bool DoWithMobHeadAt ( Vector3i a_Position , cMobHeadCallback a_Callback ) ;
2014-03-06 19:30:34 -05:00
/** Calls the callback for the flower pot at the specified coords; returns false if there's no flower pot at those coords or callback returns true, returns true if found */
2020-07-25 15:31:48 -04:00
bool DoWithFlowerPotAt ( Vector3i a_Position , cFlowerPotCallback a_Callback ) ;
2014-01-18 08:16:47 -05:00
2014-02-08 15:55:21 -05:00
/** Retrieves the test on the sign at the specified coords; returns false if there's no sign at those coords, true if found */
2020-07-25 15:31:48 -04:00
bool GetSignLines ( Vector3i a_Position , AString & a_Line1 , AString & a_Line2 , AString & a_Line3 , AString & a_Line4 ) ; // Lua-accessible
2012-06-17 15:58:39 -04:00
2015-12-01 17:12:44 -05:00
/** Use block entity on coordinate.
returns true if the use was successful , return false to use the block as a " normal " block */
bool UseBlockEntity ( cPlayer * a_Player , int a_X , int a_Y , int a_Z ) ; // [x, y, z] in world block coords
2012-06-14 09:06:06 -04:00
2014-04-07 15:57:14 -04:00
void CalculateHeightmap ( const BLOCKTYPE * a_BlockTypes ) ;
2012-06-14 09:06:06 -04:00
2012-10-21 03:46:28 -04:00
void SendBlockEntity ( int a_BlockX , int a_BlockY , int a_BlockZ , cClientHandle & a_Client ) ;
2012-06-14 09:06:06 -04:00
2017-09-25 12:17:45 -04:00
Vector3i PositionToWorldPosition ( Vector3i a_RelPos )
2012-08-25 13:52:08 -04:00
{
return PositionToWorldPosition ( a_RelPos . x , a_RelPos . y , a_RelPos . z ) ;
}
2016-01-17 09:09:25 -05:00
2012-08-25 13:52:08 -04:00
void PositionToWorldPosition ( int a_RelX , int a_RelY , int a_RelZ , int & a_BlockX , int & a_BlockY , int & a_BlockZ ) ;
2014-07-21 09:19:48 -04:00
Vector3i PositionToWorldPosition ( int a_RelX , int a_RelY , int a_RelZ ) ;
2012-06-14 09:06:06 -04:00
inline void MarkDirty ( void )
{
m_IsDirty = true ;
m_IsSaving = false ;
}
2016-01-17 09:09:25 -05:00
2020-04-17 05:36:37 -04:00
/** Causes the specified block to be ticked on the next Tick() call.
Plugins can use this via the cWorld : SetNextBlockToTick ( ) API .
Only one block coord per chunk may be set , a second call overwrites the first call */
inline void SetNextBlockToTick ( const Vector3i a_RelPos )
2012-06-14 09:06:06 -04:00
{
2020-04-17 05:36:37 -04:00
m_BlockToTick = a_RelPos ;
2012-06-14 09:06:06 -04:00
}
2016-01-17 09:09:25 -05:00
2014-04-26 13:50:23 -04:00
inline NIBBLETYPE GetMeta ( int a_RelX , int a_RelY , int a_RelZ ) const
{
2018-02-04 17:15:31 -05:00
return m_ChunkData . GetMeta ( { a_RelX , a_RelY , a_RelZ } ) ;
}
NIBBLETYPE GetMeta ( Vector3i a_RelPos ) const { return m_ChunkData . GetMeta ( a_RelPos ) ; }
2020-08-26 16:45:13 -04:00
void SetMeta ( int a_RelX , int a_RelY , int a_RelZ , NIBBLETYPE a_Meta )
2018-02-04 17:15:31 -05:00
{
2020-08-26 16:45:13 -04:00
SetMeta ( { a_RelX , a_RelY , a_RelZ } , a_Meta ) ;
2014-04-26 13:50:23 -04:00
}
2016-04-06 09:16:16 -04:00
/** Set a meta value, with the option of not informing the client and / or not marking dirty.
Used for setting metas that are of little value for saving to disk and / or for sending to the client ,
such as leaf decay flags . */
2020-08-26 16:45:13 -04:00
inline void SetMeta ( Vector3i a_RelPos , NIBBLETYPE a_Meta )
2014-04-26 13:50:23 -04:00
{
2018-02-04 17:15:31 -05:00
bool hasChanged = m_ChunkData . SetMeta ( a_RelPos , a_Meta ) ;
if ( hasChanged )
{
2020-08-26 16:45:13 -04:00
MarkDirty ( ) ;
m_PendingSendBlocks . push_back ( sSetBlock ( m_PosX , m_PosZ , a_RelPos . x , a_RelPos . y , a_RelPos . z , GetBlock ( a_RelPos ) , a_Meta ) ) ;
2018-02-04 17:15:31 -05:00
}
2014-04-26 13:50:23 -04:00
}
2012-06-14 09:06:06 -04:00
2016-01-17 09:09:25 -05:00
/** Light alterations based on time */
NIBBLETYPE GetTimeAlteredLight ( NIBBLETYPE a_Skylight ) const ;
/** Get the level of artificial light illuminating the block (0 - 15) */
2018-02-04 17:15:31 -05:00
inline NIBBLETYPE GetBlockLight ( Vector3i a_RelPos ) const { return m_ChunkData . GetBlockLight ( a_RelPos ) ; }
inline NIBBLETYPE GetBlockLight ( int a_RelX , int a_RelY , int a_RelZ ) const { return m_ChunkData . GetBlockLight ( { a_RelX , a_RelY , a_RelZ } ) ; }
2016-01-17 09:09:25 -05:00
/** Get the level of sky light illuminating the block (0 - 15) independent of daytime. */
2018-02-04 17:15:31 -05:00
inline NIBBLETYPE GetSkyLight ( Vector3i a_RelPos ) const { return m_ChunkData . GetSkyLight ( a_RelPos ) ; }
inline NIBBLETYPE GetSkyLight ( int a_RelX , int a_RelY , int a_RelZ ) const { return m_ChunkData . GetSkyLight ( { a_RelX , a_RelY , a_RelZ } ) ; }
2016-01-17 09:09:25 -05:00
/** Get the level of sky light illuminating the block (0 - 15), taking daytime into a account. */
2018-02-04 17:15:31 -05:00
inline NIBBLETYPE GetSkyLightAltered ( Vector3i a_RelPos ) const { return GetTimeAlteredLight ( m_ChunkData . GetSkyLight ( a_RelPos ) ) ; }
inline NIBBLETYPE GetSkyLightAltered ( int a_RelX , int a_RelY , int a_RelZ ) const { return GetSkyLightAltered ( { a_RelX , a_RelY , a_RelZ } ) ; }
2016-01-17 09:09:25 -05:00
2019-10-11 05:02:53 -04:00
/** Same as GetBlock(), but relative coords needn't be in this chunk (uses m_Neighbor-s or m_ChunkMap in such a case)
Returns true on success , false if queried chunk not loaded . */
bool UnboundedRelGetBlock ( Vector3i a_RelCoords , BLOCKTYPE & a_BlockType , NIBBLETYPE & a_BlockMeta ) const ;
/** OBSOLETE, use the Vector3i-based overload.
Same as GetBlock ( ) , but relative coords needn ' t be in this chunk ( uses m_Neighbor - s or m_ChunkMap in such a case )
Returns true on success , false if queried chunk not loaded . */
bool UnboundedRelGetBlock ( int a_RelX , int a_RelY , int a_RelZ , BLOCKTYPE & a_BlockType , NIBBLETYPE & a_BlockMeta ) const
{
return UnboundedRelGetBlock ( { a_RelX , a_RelY , a_RelZ } , a_BlockType , a_BlockMeta ) ;
}
/** Same as GetBlockType(), but relative coords needn't be in this chunk (uses m_Neighbor-s or m_ChunkMap in such a case)
Returns true on success , false if queried chunk not loaded . */
bool UnboundedRelGetBlockType ( Vector3i a_RelCoords , BLOCKTYPE & a_BlockType ) const ;
/** OBSOLETE, use the Vector3i-based overload.
Same as GetBlockType ( ) , but relative coords needn ' t be in this chunk ( uses m_Neighbor - s or m_ChunkMap in such a case )
Returns true on success , false if queried chunk not loaded . */
bool UnboundedRelGetBlockType ( int a_RelX , int a_RelY , int a_RelZ , BLOCKTYPE & a_BlockType ) const
{
return UnboundedRelGetBlockType ( { a_RelX , a_RelY , a_RelZ } , a_BlockType ) ;
}
/** Same as GetBlockMeta(), but relative coords needn't be in this chunk (uses m_Neighbor-s or m_ChunkMap in such a case)
Returns true on success , false if queried chunk not loaded . */
bool UnboundedRelGetBlockMeta ( Vector3i a_RelPos , NIBBLETYPE & a_BlockMeta ) const ;
2016-01-17 09:09:25 -05:00
2019-10-11 05:02:53 -04:00
/** OBSOLETE, use the Vector3i-based overload.
Same as GetBlockMeta ( ) , but relative coords needn ' t be in this chunk ( uses m_Neighbor - s or m_ChunkMap in such a case )
Returns true on success , false if queried chunk not loaded . */
bool UnboundedRelGetBlockMeta ( int a_RelX , int a_RelY , int a_RelZ , NIBBLETYPE & a_BlockMeta ) const
{
return UnboundedRelGetBlockMeta ( { a_RelX , a_RelY , a_RelZ } , a_BlockMeta ) ;
}
2016-01-17 09:09:25 -05:00
2019-10-11 05:02:53 -04:00
/** Same as GetBlockBlockLight(), but relative coords needn't be in this chunk (uses m_Neighbor-s or m_ChunkMap in such a case)
Returns true on success , false if queried chunk not loaded . */
bool UnboundedRelGetBlockBlockLight ( Vector3i a_RelPos , NIBBLETYPE & a_BlockLight ) const ;
/** OBSOLETE, use the Vector3i-based overload.
Same as GetBlockBlockLight ( ) , but relative coords needn ' t be in this chunk ( uses m_Neighbor - s or m_ChunkMap in such a case )
Returns true on success , false if queried chunk not loaded . */
bool UnboundedRelGetBlockBlockLight ( int a_RelX , int a_RelY , int a_RelZ , NIBBLETYPE & a_BlockLight ) const
{
return UnboundedRelGetBlockBlockLight ( { a_RelX , a_RelY , a_RelZ } , a_BlockLight ) ;
}
2016-01-17 09:09:25 -05:00
2019-10-11 05:02:53 -04:00
/** Same as GetBlockSkyLight(), but relative coords needn't be in this chunk (uses m_Neighbor-s or m_ChunkMap in such a case)
Returns true on success , false if queried chunk not loaded . */
bool UnboundedRelGetBlockSkyLight ( Vector3i a_RelPos , NIBBLETYPE & a_SkyLight ) const ;
2013-10-22 11:54:09 -04:00
2019-10-11 05:02:53 -04:00
/** OBSOLETE, use the Vector3i-based overload.
Same as GetBlockSkyLight ( ) , but relative coords needn ' t be in this chunk ( uses m_Neighbor - s or m_ChunkMap in such a case )
Returns true on success , false if queried chunk not loaded . */
bool UnboundedRelGetBlockSkyLight ( int a_RelX , int a_RelY , int a_RelZ , NIBBLETYPE & a_SkyLight ) const
{
return UnboundedRelGetBlockSkyLight ( { a_RelX , a_RelY , a_RelZ } , a_SkyLight ) ;
}
2013-10-22 11:54:09 -04:00
2019-10-11 05:02:53 -04:00
/** Queries both BlockLight and SkyLight, relative coords needn't be in this chunk (uses m_Neighbor-s or m_ChunkMap in such a case)
Returns true on success , false if queried chunk not loaded . */
bool UnboundedRelGetBlockLights ( Vector3i a_RelPos , NIBBLETYPE & a_BlockLight , NIBBLETYPE & a_SkyLight ) const ;
2013-10-27 04:19:13 -04:00
2019-10-11 05:02:53 -04:00
/** OBSOLETE, use the Vector3i-based overload.
Queries both BlockLight and SkyLight , relative coords needn ' t be in this chunk ( uses m_Neighbor - s or m_ChunkMap in such a case )
Returns true on success , false if queried chunk not loaded . */
bool UnboundedRelGetBlockLights ( int a_RelX , int a_RelY , int a_RelZ , NIBBLETYPE & a_BlockLight , NIBBLETYPE & a_SkyLight ) const
{
return UnboundedRelGetBlockLights ( { a_RelX , a_RelY , a_RelZ } , a_BlockLight , a_SkyLight ) ;
}
2013-03-01 14:35:29 -05:00
2019-10-11 05:02:53 -04:00
/** Same as SetBlock(), but relative coords needn't be in this chunk (uses m_Neighbor-s or m_ChunkMap in such a case)
Returns true on success , false if queried chunk not loaded . */
bool UnboundedRelSetBlock ( Vector3i a_RelPos , BLOCKTYPE a_BlockType , NIBBLETYPE a_BlockMeta ) ;
2016-01-17 09:09:25 -05:00
2019-10-11 05:02:53 -04:00
/** OBSOLETE, use the Vector3i-based overload.
Same as SetBlock ( ) , but relative coords needn ' t be in this chunk ( uses m_Neighbor - s or m_ChunkMap in such a case )
Returns true on success , false if queried chunk not loaded . */
bool UnboundedRelSetBlock ( int a_RelX , int a_RelY , int a_RelZ , BLOCKTYPE a_BlockType , NIBBLETYPE a_BlockMeta )
{
return UnboundedRelSetBlock ( { a_RelX , a_RelY , a_RelZ } , a_BlockType , a_BlockMeta ) ;
}
/** Same as FastSetBlock(), but relative coords needn't be in this chunk (uses m_Neighbor-s or m_ChunkMap in such a case)
Returns true on success , false if queried chunk not loaded . */
bool UnboundedRelFastSetBlock ( Vector3i a_RelPos , BLOCKTYPE a_BlockType , NIBBLETYPE a_BlockMeta ) ;
/** OBSOLETE, use the Vector3i-based overload.
Same as FastSetBlock ( ) , but relative coords needn ' t be in this chunk ( uses m_Neighbor - s or m_ChunkMap in such a case )
Returns true on success , false if queried chunk not loaded . */
bool UnboundedRelFastSetBlock ( int a_RelX , int a_RelY , int a_RelZ , BLOCKTYPE a_BlockType , NIBBLETYPE a_BlockMeta )
{
return UnboundedRelFastSetBlock ( { a_RelX , a_RelY , a_RelZ } , a_BlockType , a_BlockMeta ) ;
}
2013-10-29 12:44:51 -04:00
2013-10-21 16:38:38 -04:00
2014-02-15 10:51:49 -05:00
// Per-chunk simulator data:
2013-03-02 10:44:31 -05:00
cFireSimulatorChunkData & GetFireSimulatorData ( void ) { return m_FireSimulatorData ; }
2020-08-08 07:09:40 -04:00
cFluidSimulatorData * GetWaterSimulatorData ( void ) const { return m_WaterSimulatorData ; }
cFluidSimulatorData * GetLavaSimulatorData ( void ) const { return m_LavaSimulatorData ; }
2013-03-02 14:57:09 -05:00
cSandSimulatorChunkData & GetSandSimulatorData ( void ) { return m_SandSimulatorData ; }
2020-08-08 07:09:40 -04:00
cRedstoneSimulatorChunkData * GetRedstoneSimulatorData ( void ) const { return m_RedstoneSimulatorData ; }
2012-06-14 09:06:06 -04:00
2019-10-16 04:06:34 -04:00
/** Returns the block entity at the specified (absolute) coords.
Returns nullptr if no such BE or outside this chunk . */
cBlockEntity * GetBlockEntity ( Vector3i a_AbsPos ) ;
2019-10-11 05:02:53 -04:00
/** OBSOLETE, use the Vector3i-based overload instead.
Returns the block entity at the specified ( absolute ) coords .
Returns nullptr if no such BE or outside this chunk . */
cBlockEntity * GetBlockEntity ( int a_BlockX , int a_BlockY , int a_BlockZ ) { return GetBlockEntity ( { a_BlockX , a_BlockY , a_BlockZ } ) ; }
2019-10-16 04:06:34 -04:00
/** Returns the block entity at the specified (relative) coords.
Returns nullptr if no such BE .
Asserts that the position is a valid relative position . */
cBlockEntity * GetBlockEntityRel ( Vector3i a_RelPos ) ;
2016-01-17 09:09:25 -05:00
2014-07-10 12:18:32 -04:00
/** Returns true if the chunk should be ticked in the tick-thread.
Checks if there are any clients and if the always - tick flag is set */
bool ShouldBeTicked ( void ) const ;
2016-01-17 09:09:25 -05:00
2014-07-10 12:18:32 -04:00
/** Increments (a_AlwaysTicked == true) or decrements (false) the m_AlwaysTicked counter.
If the m_AlwaysTicked counter is greater than zero , the chunk is ticked in the tick - thread regardless of
2016-10-09 08:46:09 -04:00
whether it has any clients or not . When this is set , the chunk never unloads .
2014-07-10 12:18:32 -04:00
This function allows nesting and task - concurrency ( multiple separate tasks can request ticking and as long
as at least one requests is active the chunk will be ticked ) . */
void SetAlwaysTicked ( bool a_AlwaysTicked ) ;
2013-06-13 03:36:43 -04:00
2018-07-24 17:30:49 -04:00
cChunkClientHandles GetAllClients ( void ) const
2015-09-16 12:04:05 -04:00
{
2018-07-24 17:30:49 -04:00
return cChunkClientHandles ( m_LoadedByClient ) ;
2015-09-16 12:04:05 -04:00
}
2015-03-21 13:17:26 -04:00
2019-09-29 08:59:24 -04:00
/** Converts the coord relative to this chunk into an absolute coord.
Doesn ' t check relative coord validity . */
2020-04-21 16:19:22 -04:00
Vector3i RelativeToAbsolute ( Vector3i a_RelBlockPosition ) const
2019-09-29 08:59:24 -04:00
{
2019-10-11 05:02:53 -04:00
return cChunkDef : : RelativeToAbsolute ( a_RelBlockPosition , { m_PosX , m_PosZ } ) ;
2019-09-29 08:59:24 -04:00
}
2012-06-14 09:06:06 -04:00
private :
friend class cChunkMap ;
2016-01-17 09:09:25 -05:00
2013-08-18 16:44:22 -04:00
struct sSetBlockQueueItem
{
2014-04-18 15:09:44 -04:00
Int64 m_Tick ;
2013-08-18 16:44:22 -04:00
int m_RelX , m_RelY , m_RelZ ;
BLOCKTYPE m_BlockType ;
NIBBLETYPE m_BlockMeta ;
2013-12-06 17:29:15 -05:00
BLOCKTYPE m_PreviousType ;
2016-01-17 09:09:25 -05:00
2013-12-06 17:29:15 -05:00
sSetBlockQueueItem ( int a_RelX , int a_RelY , int a_RelZ , BLOCKTYPE a_BlockType , NIBBLETYPE a_BlockMeta , Int64 a_Tick , BLOCKTYPE a_PreviousBlockType ) :
2014-04-18 16:47:59 -04:00
m_Tick ( a_Tick ) , m_RelX ( a_RelX ) , m_RelY ( a_RelY ) , m_RelZ ( a_RelZ ) , m_BlockType ( a_BlockType ) , m_BlockMeta ( a_BlockMeta ) , m_PreviousType ( a_PreviousBlockType )
2013-08-18 16:44:22 -04:00
{
}
} ;
typedef std : : vector < sSetBlockQueueItem > sSetBlockQueueVector ;
2016-01-17 09:09:25 -05:00
2013-08-18 16:44:22 -04:00
2014-09-05 16:16:48 -04:00
/** Holds the presence status of the chunk - if it is present, or in the loader / generator queue, or unloaded */
ePresence m_Presence ;
2012-06-14 09:06:06 -04:00
bool m_IsLightValid ; // True if the blocklight and skylight are calculated
bool m_IsDirty ; // True if the chunk has changed since it was last saved
bool m_IsSaving ; // True if the chunk is being saved
bool m_HasLoadFailed ; // True if chunk failed to load and hasn't been generated yet since then
2016-01-17 09:09:25 -05:00
2020-07-29 13:51:39 -04:00
std : : queue < Vector3i > m_ToTickBlocks ;
2014-04-26 13:50:23 -04:00
sSetBlockVector m_PendingSendBlocks ; ///< Blocks that have changed and need to be sent to all clients
2016-01-17 09:09:25 -05:00
2012-06-14 09:06:06 -04:00
// A critical section is not needed, because all chunk access is protected by its parent ChunkMap's csLayers
2015-09-16 12:04:05 -04:00
std : : vector < cClientHandle * > m_LoadedByClient ;
2016-12-19 15:12:23 -05:00
std : : vector < OwnedEntity > m_Entities ;
2020-08-28 16:40:40 -04:00
cBlockEntities m_BlockEntities ;
2016-01-17 09:09:25 -05:00
2014-02-08 15:55:21 -05:00
/** Number of times the chunk has been requested to stay (by various cChunkStay objects); if zero, the chunk can be unloaded */
2020-08-28 16:34:23 -04:00
unsigned m_StayCount ;
2012-06-14 09:06:06 -04:00
2014-09-06 13:01:30 -04:00
int m_PosX , m_PosZ ;
2012-06-14 09:06:06 -04:00
cWorld * m_World ;
cChunkMap * m_ChunkMap ;
2014-05-21 14:58:48 -04:00
cChunkData m_ChunkData ;
2012-06-14 09:06:06 -04:00
cChunkDef : : HeightMap m_HeightMap ;
cChunkDef : : BiomeMap m_BiomeMap ;
2020-04-17 05:36:37 -04:00
/** Relative coords of the block to tick first in the next Tick() call.
Plugins can use this to force a tick in a specific block , using cWorld : SetNextBlockToTick ( ) API . */
Vector3i m_BlockToTick ;
2016-01-17 09:09:25 -05:00
2012-12-14 17:38:30 -05:00
cChunk * m_NeighborXM ; // Neighbor at [X - 1, Z]
cChunk * m_NeighborXP ; // Neighbor at [X + 1, Z]
cChunk * m_NeighborZM ; // Neighbor at [X, Z - 1]
cChunk * m_NeighborZP ; // Neighbor at [X, Z + 1]
2016-01-17 09:09:25 -05:00
2013-03-02 10:44:31 -05:00
// Per-chunk simulator data:
2013-03-01 14:35:29 -05:00
cFireSimulatorChunkData m_FireSimulatorData ;
2013-03-02 10:44:31 -05:00
cFluidSimulatorData * m_WaterSimulatorData ;
cFluidSimulatorData * m_LavaSimulatorData ;
2013-03-02 14:57:09 -05:00
cSandSimulatorChunkData m_SandSimulatorData ;
2014-09-26 12:00:34 -04:00
cRedstoneSimulatorChunkData * m_RedstoneSimulatorData ;
2014-09-16 15:29:31 -04:00
2014-07-10 12:18:32 -04:00
/** If greater than zero, the chunk is ticked even if it has no clients.
Manipulated by the SetAlwaysTicked ( ) function , allows for nested calls of the function .
This is the support for plugin - accessible chunk tick forcing . */
2020-08-28 16:34:23 -04:00
unsigned m_AlwaysTicked ;
2012-06-14 09:06:06 -04:00
2014-06-04 18:23:09 -04:00
// Pick up a random block of this chunk
2014-07-10 17:04:33 -04:00
void GetRandomBlockCoords ( int & a_X , int & a_Y , int & a_Z ) ;
void GetThreeRandomNumbers ( int & a_X , int & a_Y , int & a_Z , int a_MaxX , int a_MaxY , int a_MaxZ ) ;
2013-09-07 18:11:38 -04:00
2013-03-01 14:35:29 -05:00
void RemoveBlockEntity ( cBlockEntity * a_BlockEntity ) ;
2020-04-03 17:23:38 -04:00
void AddBlockEntity ( OwnedBlockEntity a_BlockEntity ) ;
2012-06-14 09:06:06 -04:00
2014-02-08 15:55:21 -05:00
/** Wakes up each simulator for its specific blocks; through all the blocks in the chunk */
2013-03-03 10:33:55 -05:00
void WakeUpSimulators ( void ) ;
2012-06-14 09:06:06 -04:00
2014-02-08 15:55:21 -05:00
/** Sends m_PendingSendBlocks to all clients */
2012-08-25 13:52:08 -04:00
void BroadcastPendingBlockChanges ( void ) ;
2016-01-17 09:09:25 -05:00
2014-02-08 15:55:21 -05:00
/** Checks the block scheduled for checking in m_ToTickBlocks[] */
2014-01-31 18:17:41 -05:00
void CheckBlocks ( ) ;
2016-01-17 09:09:25 -05:00
2014-02-08 15:55:21 -05:00
/** Ticks several random blocks in the chunk */
2013-04-13 17:02:10 -04:00
void TickBlocks ( void ) ;
2016-01-17 09:09:25 -05:00
2014-02-08 15:55:21 -05:00
/** Adds snow to the top of snowy biomes and hydrates farmland / fills cauldrons in rainy biomes */
2013-04-01 16:56:25 -04:00
void ApplyWeatherToTop ( void ) ;
2016-01-17 09:09:25 -05:00
2019-10-16 04:06:34 -04:00
/** Returns the pickups that would be produced, if the specified block was dug up by a_Digger using a_Tool.
Doesn ' t dig the block , only queries the block handlers and then plugins for the pickups . */
cItems PickupsFromBlock ( Vector3i a_RelPos , const cEntity * a_Digger , const cItem * a_Tool ) ;
2019-10-11 05:02:53 -04:00
/** Grows the plant at the specified position by at most a_NumStages.
The block ' s Grow handler is invoked .
Returns the number of stages the plant has grown , 0 if not a plant . */
int GrowPlantAt ( Vector3i a_RelPos , int a_NumStages = 1 ) ;
2016-01-17 09:09:25 -05:00
2014-02-08 15:55:21 -05:00
/** Called by Tick() when an entity moves out of this chunk into a neighbor; moves the entity and sends spawn / despawn packet to clients */
2016-12-19 15:12:23 -05:00
void MoveEntityToNewChunk ( OwnedEntity a_Entity ) ;
2020-03-18 13:17:59 -04:00
/** Check m_Entities for cPlayer objects. */
2020-08-20 07:50:22 -04:00
bool HasPlayerEntities ( ) const ;
2012-06-14 09:06:06 -04:00
} ;