2012-06-14 09:06:06 -04:00
// cChunkMap.h
// Interfaces to the cChunkMap class representing the chunk storage for a single world
# pragma once
2014-05-18 10:10:12 -04:00
# include "ChunkDataCallback.h"
2012-06-14 09:06:06 -04:00
class cWorld ;
2014-01-26 09:20:39 -05:00
class cWorldInterface ;
2012-06-14 09:06:06 -04:00
class cItem ;
class MTRand ;
class cChunkStay ;
class cChunk ;
class cPlayer ;
2014-07-30 16:19:51 -04:00
class cBeaconEntity ;
2012-06-17 15:58:39 -04:00
class cChestEntity ;
2012-12-19 16:19:36 -05:00
class cDispenserEntity ;
2013-05-26 10:39:04 -04:00
class cDropperEntity ;
class cDropSpenserEntity ;
2012-06-17 15:58:39 -04:00
class cFurnaceEntity ;
2013-12-14 11:52:22 -05:00
class cNoteEntity ;
2014-01-18 08:16:47 -05:00
class cCommandBlockEntity ;
2014-02-19 08:45:09 -05:00
class cMobHeadEntity ;
2014-03-06 19:30:34 -05:00
class cFlowerPotEntity ;
2012-08-19 17:14:45 -04:00
class cPawn ;
2012-08-24 05:49:00 -04:00
class cPickup ;
2012-08-26 17:01:07 -04:00
class cChunkDataSerializer ;
2012-10-06 12:58:31 -04:00
class cBlockArea ;
2013-09-07 16:19:56 -04:00
class cMobCensus ;
2013-09-07 18:11:38 -04:00
class cMobSpawner ;
2014-07-24 12:32:05 -04:00
class cSetChunkData ;
2014-09-03 11:00:26 -04:00
class cBoundingBox ;
2012-06-14 09:06:06 -04:00
2014-06-16 19:15:38 -04:00
typedef std : : list < cClientHandle * > cClientHandleList ;
typedef cChunk * cChunkPtr ;
2014-01-18 08:16:47 -05:00
typedef cItemCallback < cEntity > cEntityCallback ;
typedef cItemCallback < cBlockEntity > cBlockEntityCallback ;
2014-07-30 16:19:51 -04:00
typedef cItemCallback < cBeaconEntity > cBeaconCallback ;
2014-01-18 08:16:47 -05:00
typedef cItemCallback < cChestEntity > cChestCallback ;
typedef cItemCallback < cDispenserEntity > cDispenserCallback ;
typedef cItemCallback < cDropperEntity > cDropperCallback ;
typedef cItemCallback < cDropSpenserEntity > cDropSpenserCallback ;
2014-03-06 19:30:34 -05:00
typedef cItemCallback < cFlowerPotEntity > cFlowerPotCallback ;
2014-01-18 08:16:47 -05:00
typedef cItemCallback < cFurnaceEntity > cFurnaceCallback ;
typedef cItemCallback < cNoteEntity > cNoteBlockCallback ;
typedef cItemCallback < cCommandBlockEntity > cCommandBlockCallback ;
2014-03-07 05:44:16 -05:00
typedef cItemCallback < cMobHeadEntity > cMobHeadCallback ;
2014-01-18 08:16:47 -05:00
typedef cItemCallback < cChunk > cChunkCallback ;
2012-06-14 09:06:06 -04:00
class cChunkMap
{
public :
static const int LAYER_SIZE = 32 ;
2015-05-09 05:16:56 -04:00
cChunkMap ( cWorld * a_World ) ;
2012-06-14 09:06:06 -04:00
~ cChunkMap ( ) ;
2013-07-07 09:06:06 -04:00
// Broadcast respective packets to all clients of the chunk where the event is taking place
// (Please keep these alpha-sorted)
2013-03-03 14:05:11 -05:00
void BroadcastAttachEntity ( const cEntity & a_Entity , const cEntity * a_Vehicle ) ;
2014-10-20 16:55:07 -04:00
void BroadcastBlockAction ( int a_BlockX , int a_BlockY , int a_BlockZ , char a_Byte1 , char a_Byte2 , BLOCKTYPE a_BlockType , const cClientHandle * a_Exclude = nullptr ) ;
2015-03-21 10:18:17 -04:00
void BroadcastBlockBreakAnimation ( UInt32 a_EntityID , int a_BlockX , int a_BlockY , int a_BlockZ , char a_Stage , const cClientHandle * a_Exclude = nullptr ) ;
2013-07-07 09:06:06 -04:00
void BroadcastBlockEntity ( int a_BlockX , int a_BlockY , int a_BlockZ , const cClientHandle * a_Exclude ) ;
2014-10-20 16:55:07 -04:00
void BroadcastCollectEntity ( const cEntity & a_Entity , const cPlayer & a_Player , const cClientHandle * a_Exclude = nullptr ) ;
void BroadcastCollectPickup ( const cPickup & a_Pickup , const cPlayer & a_Player , const cClientHandle * a_Exclude = nullptr ) ;
void BroadcastDestroyEntity ( const cEntity & a_Entity , const cClientHandle * a_Exclude = nullptr ) ;
void BroadcastEntityEffect ( const cEntity & a_Entity , int a_EffectID , int a_Amplifier , short a_Duration , const cClientHandle * a_Exclude = nullptr ) ;
void BroadcastEntityEquipment ( const cEntity & a_Entity , short a_SlotNum , const cItem & a_Item , const cClientHandle * a_Exclude = nullptr ) ;
void BroadcastEntityHeadLook ( const cEntity & a_Entity , const cClientHandle * a_Exclude = nullptr ) ;
void BroadcastEntityLook ( const cEntity & a_Entity , const cClientHandle * a_Exclude = nullptr ) ;
void BroadcastEntityMetadata ( const cEntity & a_Entity , const cClientHandle * a_Exclude = nullptr ) ;
void BroadcastEntityRelMove ( const cEntity & a_Entity , char a_RelX , char a_RelY , char a_RelZ , const cClientHandle * a_Exclude = nullptr ) ;
void BroadcastEntityRelMoveLook ( const cEntity & a_Entity , char a_RelX , char a_RelY , char a_RelZ , const cClientHandle * a_Exclude = nullptr ) ;
void BroadcastEntityStatus ( const cEntity & a_Entity , char a_Status , const cClientHandle * a_Exclude = nullptr ) ;
void BroadcastEntityVelocity ( const cEntity & a_Entity , const cClientHandle * a_Exclude = nullptr ) ;
void BroadcastEntityAnimation ( const cEntity & a_Entity , char a_Animation , const cClientHandle * a_Exclude = nullptr ) ;
void BroadcastParticleEffect ( const AString & a_ParticleName , float a_SrcX , float a_SrcY , float a_SrcZ , float a_OffsetX , float a_OffsetY , float a_OffsetZ , float a_ParticleData , int a_ParticleAmount , cClientHandle * a_Exclude = nullptr ) ;
void BroadcastRemoveEntityEffect ( const cEntity & a_Entity , int a_EffectID , const cClientHandle * a_Exclude = nullptr ) ;
void BroadcastSoundEffect ( const AString & a_SoundName , double a_X , double a_Y , double a_Z , float a_Volume , float a_Pitch , const cClientHandle * a_Exclude = nullptr ) ;
void BroadcastSoundParticleEffect ( int a_EffectID , int a_SrcX , int a_SrcY , int a_SrcZ , int a_Data , const cClientHandle * a_Exclude = nullptr ) ;
void BroadcastSpawnEntity ( cEntity & a_Entity , const cClientHandle * a_Exclude = nullptr ) ;
void BroadcastThunderbolt ( int a_BlockX , int a_BlockY , int a_BlockZ , const cClientHandle * a_Exclude = nullptr ) ;
2014-07-21 09:19:48 -04:00
void BroadcastUseBed ( const cEntity & a_Entity , int a_BlockX , int a_BlockY , int a_BlockZ ) ;
2012-08-24 03:58:26 -04:00
2014-02-08 15:55:21 -05:00
/** Sends the block entity, if it is at the coords specified, to a_Client */
2012-08-24 03:58:26 -04:00
void SendBlockEntity ( int a_BlockX , int a_BlockY , int a_BlockZ , cClientHandle & a_Client ) ;
2014-02-08 15:55:21 -05:00
/** a_Player rclked block entity at the coords specified, handle it */
2012-06-14 09:06:06 -04:00
void UseBlockEntity ( cPlayer * a_Player , int a_X , int a_Y , int a_Z ) ;
2013-02-28 02:42:45 -05:00
2014-02-08 15:55:21 -05:00
/** Calls the callback for the chunk specified, with ChunkMapCS locked; returns false if the chunk doesn't exist, otherwise returns the same value as the callback */
2013-08-03 14:26:50 -04:00
bool DoWithChunk ( int a_ChunkX , int a_ChunkZ , cChunkCallback & a_Callback ) ;
2015-03-21 13:17:26 -04:00
/** Calls the callback for the chunk at the block position specified, with ChunkMapCS locked; returns false if the chunk doesn't exist, otherwise returns the same value as the callback **/
bool DoWithChunkAt ( Vector3i a_BlockPos , std : : function < bool ( cChunk & ) > a_Callback ) ;
2014-02-08 15:55:21 -05:00
/** Wakes up simulators for the specified block */
2013-02-28 02:42:45 -05:00
void WakeUpSimulators ( int a_BlockX , int a_BlockY , int a_BlockZ ) ;
2012-06-14 09:06:06 -04:00
2014-02-08 15:55:21 -05:00
/** Wakes up the simulators for the specified area of blocks */
2013-06-21 16:47:58 -04:00
void WakeUpSimulatorsInArea ( int a_MinBlockX , int a_MaxBlockX , int a_MinBlockY , int a_MaxBlockY , int a_MinBlockZ , int a_MaxBlockZ ) ;
2014-07-06 18:50:22 -04:00
void MarkRedstoneDirty ( int a_ChunkX , int a_ChunkZ ) ;
void MarkChunkDirty ( int a_ChunkX , int a_ChunkZ , bool a_MarkRedstoneDirty = false ) ;
2013-04-13 17:02:10 -04:00
void MarkChunkSaving ( int a_ChunkX , int a_ChunkZ ) ;
void MarkChunkSaved ( int a_ChunkX , int a_ChunkZ ) ;
2012-06-14 09:06:06 -04:00
/** Sets the chunk data as either loaded from the storage or generated.
2014-07-24 12:32:05 -04:00
BlockLight and BlockSkyLight are optional , if not present , chunk will be marked as unlighted .
If MarkDirty is set , the chunk is set as dirty ( used after generating )
Modifies the BlockEntity list in a_SetChunkData - moves the block entities into the chunk .
2012-06-14 09:06:06 -04:00
*/
2014-07-24 12:32:05 -04:00
void SetChunkData ( cSetChunkData & a_SetChunkData ) ;
2012-06-14 09:06:06 -04:00
void ChunkLighted (
int a_ChunkX , int a_ChunkZ ,
const cChunkDef : : BlockNibbles & a_BlockLight ,
const cChunkDef : : BlockNibbles & a_SkyLight
) ;
2013-04-13 17:02:10 -04:00
bool GetChunkData ( int a_ChunkX , int a_ChunkZ , cChunkDataCallback & a_Callback ) ;
2012-06-14 09:06:06 -04:00
2014-02-08 15:55:21 -05:00
/** Copies the chunk's blocktypes into a_Blocks; returns true if successful */
2013-04-13 17:02:10 -04:00
bool GetChunkBlockTypes ( int a_ChunkX , int a_ChunkZ , BLOCKTYPE * a_Blocks ) ;
2012-06-14 09:06:06 -04:00
2014-09-05 16:16:48 -04:00
/** Returns true iff the chunk is in the loader / generator queue. */
bool IsChunkQueued ( int a_ChunkX , int a_ChunkZ ) ;
2013-04-13 17:02:10 -04:00
bool IsChunkValid ( int a_ChunkX , int a_ChunkZ ) ;
bool HasChunkAnyClients ( int a_ChunkX , int a_ChunkZ ) ;
int GetHeight ( int a_BlockX , int a_BlockZ ) ; // Waits for the chunk to get loaded / generated
bool TryGetHeight ( int a_BlockX , int a_BlockZ , int & a_Height ) ; // Returns false if chunk not loaded / generated
2014-01-26 09:20:39 -05:00
void FastSetBlock ( int a_BlockX , int a_BlockY , int a_BlockZ , BLOCKTYPE a_BlockType , NIBBLETYPE a_BlockMeta ) ;
void FastSetQueuedBlocks ( ) ;
2014-12-24 01:20:17 -05:00
void FastSetBlocks ( sSetBlockList & a_BlockList ) ;
/** Performs the specified single-block set operations simultaneously, as if SetBlock() was called for each item.
Is more efficient than calling SetBlock ( ) multiple times .
If the chunk for any of the blocks is not loaded , the set operation is ignored silently . */
void SetBlocks ( const sSetBlockVector & a_Blocks ) ;
2014-10-15 13:01:55 -04:00
void CollectPickupsByPlayer ( cPlayer & a_Player ) ;
2012-10-20 07:40:34 -04:00
BLOCKTYPE GetBlock ( int a_BlockX , int a_BlockY , int a_BlockZ ) ;
NIBBLETYPE GetBlockMeta ( int a_BlockX , int a_BlockY , int a_BlockZ ) ;
NIBBLETYPE GetBlockSkyLight ( int a_BlockX , int a_BlockY , int a_BlockZ ) ;
NIBBLETYPE GetBlockBlockLight ( int a_BlockX , int a_BlockY , int a_BlockZ ) ;
2014-07-12 18:51:42 -04:00
void SetBlockMeta ( int a_BlockX , int a_BlockY , int a_BlockZ , NIBBLETYPE a_BlockMeta ) ;
2014-09-12 13:07:20 -04:00
void SetBlock ( int a_BlockX , int a_BlockY , int a_BlockZ , BLOCKTYPE a_BlockType , NIBBLETYPE a_BlockMeta , bool a_SendToClients = true ) ;
void QueueSetBlock ( int a_BlockX , int a_BlockY , int a_BlockZ , BLOCKTYPE a_BlockType , NIBBLETYPE a_BlockMeta , Int64 a_Tick , BLOCKTYPE a_PreviousBlockType = E_BLOCK_AIR ) ;
2012-10-26 04:47:30 -04:00
bool GetBlockTypeMeta ( int a_BlockX , int a_BlockY , int a_BlockZ , BLOCKTYPE & a_BlockType , NIBBLETYPE & a_BlockMeta ) ;
bool GetBlockInfo ( int a_BlockX , int a_BlockY , int a_BlockZ , BLOCKTYPE & a_BlockType , NIBBLETYPE & a_Meta , NIBBLETYPE & a_SkyLight , NIBBLETYPE & a_BlockLight ) ;
2012-06-14 09:06:06 -04:00
2014-02-08 15:55:21 -05:00
/** Replaces world blocks with a_Blocks, if they are of type a_FilterBlockType */
2012-06-14 09:06:06 -04:00
void ReplaceBlocks ( const sSetBlockVector & a_Blocks , BLOCKTYPE a_FilterBlockType ) ;
2014-02-08 15:55:21 -05:00
/** Special function used for growing trees, replaces only blocks that tree may overwrite */
2012-06-14 09:06:06 -04:00
void ReplaceTreeBlocks ( const sSetBlockVector & a_Blocks ) ;
2014-02-18 07:06:18 -05:00
/** Returns the biome at the specified coords. Reads the biome from the chunk, if loaded, otherwise uses the world generator to provide the biome value */
2012-06-14 09:06:06 -04:00
EMCSBiome GetBiomeAt ( int a_BlockX , int a_BlockZ ) ;
2014-02-18 07:06:18 -05:00
/** Sets the biome at the specified coords. Returns true if successful, false if not (chunk not loaded).
Doesn ' t resend the chunk to clients . */
bool SetBiomeAt ( int a_BlockX , int a_BlockZ , EMCSBiome a_Biome ) ;
/** Sets the biome at the area. Returns true if successful, false if any subarea failed (chunk not loaded).
( Re ) sends the chunks to their relevant clients if successful . */
bool SetAreaBiome ( int a_MinX , int a_MaxX , int a_MinZ , int a_MaxZ , EMCSBiome a_Biome ) ;
2014-12-24 01:20:17 -05:00
/** Retrieves block types and metas of the specified blocks.
If a chunk is not loaded , doesn ' t modify the block and consults a_ContinueOnFailure whether to process the rest of the array .
Returns true if all blocks were read , false if any one failed . */
2012-06-14 09:06:06 -04:00
bool GetBlocks ( sSetBlockVector & a_Blocks , bool a_ContinueOnFailure ) ;
2014-12-24 01:20:17 -05:00
/** Removes the block at the specified coords and wakes up simulators.
Returns false if the chunk is not loaded ( and the block is not dug ) .
Returns true if successful . */
bool DigBlock ( int a_BlockX , int a_BlockY , int a_BlockZ ) ;
/** Sends the block at the specified coords to the specified player.
Uses a blockchange packet to send the block .
If the relevant chunk isn ' t loaded , doesn ' t do anything . */
void SendBlockTo ( int a_BlockX , int a_BlockY , int a_BlockZ , cPlayer * a_Player ) ;
2012-06-14 09:06:06 -04:00
2014-02-08 15:55:21 -05:00
/** Compares clients of two chunks, calls the callback accordingly */
2013-04-13 17:02:10 -04:00
void CompareChunkClients ( int a_ChunkX1 , int a_ChunkZ1 , int a_ChunkX2 , int a_ChunkZ2 , cClientDiffCallback & a_Callback ) ;
2012-06-14 09:06:06 -04:00
2014-02-08 15:55:21 -05:00
/** Compares clients of two chunks, calls the callback accordingly */
2013-04-13 17:02:10 -04:00
void CompareChunkClients ( cChunk * a_Chunk1 , cChunk * a_Chunk2 , cClientDiffCallback & a_Callback ) ;
2014-02-08 15:55:21 -05:00
/** Adds client to a chunk, if not already present; returns true if added, false if present */
2013-04-13 17:02:10 -04:00
bool AddChunkClient ( int a_ChunkX , int a_ChunkZ , cClientHandle * a_Client ) ;
2012-06-14 09:06:06 -04:00
2014-02-08 15:55:21 -05:00
/** Removes the client from the chunk */
2013-04-13 17:02:10 -04:00
void RemoveChunkClient ( int a_ChunkX , int a_ChunkZ , cClientHandle * a_Client ) ;
2012-06-14 09:06:06 -04:00
2014-02-08 15:55:21 -05:00
/** Removes the client from all chunks it is present in */
2012-06-14 09:06:06 -04:00
void RemoveClientFromChunks ( cClientHandle * a_Client ) ;
2014-02-08 15:55:21 -05:00
/** Adds the entity to its appropriate chunk, takes ownership of the entity pointer */
2013-04-13 17:02:10 -04:00
void AddEntity ( cEntity * a_Entity ) ;
2012-06-14 09:06:06 -04:00
2014-06-10 12:25:53 -04:00
/** Adds the entity to its appropriate chunk, if the entity is not already added.
Takes ownership of the entity pointer */
void AddEntityIfNotPresent ( cEntity * a_Entity ) ;
2014-02-08 15:55:21 -05:00
/** Returns true if the entity with specified ID is present in the chunks */
2015-03-21 10:18:17 -04:00
bool HasEntity ( UInt32 a_EntityID ) ;
2013-04-13 17:02:10 -04:00
2014-02-08 15:55:21 -05:00
/** Removes the entity from its appropriate chunk */
2013-04-13 17:28:55 -04:00
void RemoveEntity ( cEntity * a_Entity ) ;
2014-02-08 15:55:21 -05:00
/** Calls the callback for each entity in the entire world; returns true if all entities processed, false if the callback aborted by returning true */
2013-04-13 17:02:10 -04:00
bool ForEachEntity ( cEntityCallback & a_Callback ) ; // Lua-accessible
2014-02-08 15:55:21 -05:00
/** Calls the callback for each entity in the specified chunk; returns true if all entities processed, false if the callback aborted by returning true */
2012-06-16 04:35:07 -04:00
bool ForEachEntityInChunk ( int a_ChunkX , int a_ChunkZ , cEntityCallback & a_Callback ) ; // Lua-accessible
2013-05-04 02:25:58 -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 .
If any chunk in the box is missing , ignores the entities in that chunk silently . */
bool ForEachEntityInBox ( const cBoundingBox & a_Box , cEntityCallback & a_Callback ) ; // Lua-accessible
2014-02-08 15:55:21 -05:00
/** Destroys and returns a list of blocks destroyed in the explosion at the specified coordinates */
2013-09-07 12:12:22 -04:00
void DoExplosionAt ( double a_ExplosionSize , double a_BlockX , double a_BlockY , double a_BlockZ , cVector3iArray & a_BlockAffected ) ;
2013-04-13 17:02:10 -04:00
2015-03-21 10:18:17 -04: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 and callback returned false . */
bool DoWithEntityByID ( UInt32 a_EntityID , cEntityCallback & a_Callback ) ; // Lua-accessible
2012-06-16 04:35:07 -04:00
2015-03-21 10:18:17 -04:00
/** Calls the callback for each block entity in the specified chunk.
Returns true if all block entities processed , false if the callback aborted by returning true . */
2013-11-20 15:53:29 -05:00
bool ForEachBlockEntityInChunk ( int a_ChunkX , int a_ChunkZ , cBlockEntityCallback & a_Callback ) ; // Lua-accessible
2015-03-21 10:18:17 -04:00
/** Calls the callback for each chest in the specified chunk.
Returns true if all chests processed , false if the callback aborted by returning true . */
2013-11-20 15:53:29 -05:00
bool ForEachChestInChunk ( int a_ChunkX , int a_ChunkZ , cChestCallback & a_Callback ) ; // Lua-accessible
2012-06-17 15:58:39 -04:00
2015-03-21 10:18:17 -04:00
/** Calls the callback for each dispenser in the specified chunk.
Returns true if all dispensers processed , false if the callback aborted by returning true . */
2012-12-27 10:07:12 -05:00
bool ForEachDispenserInChunk ( int a_ChunkX , int a_ChunkZ , cDispenserCallback & a_Callback ) ;
2012-12-26 12:16:33 -05:00
2015-03-21 10:18:17 -04:00
/** Calls the callback for each dropper in the specified chunk.
Returns true if all droppers processed , false if the callback aborted by returning true . */
2013-05-26 10:39:04 -04:00
bool ForEachDropperInChunk ( int a_ChunkX , int a_ChunkZ , cDropperCallback & a_Callback ) ;
2015-03-21 10:18:17 -04:00
/** Calls the callback for each dropspenser in the specified chunk.
Returns true if all dropspensers processed , false if the callback aborted by returning true . */
2013-05-26 10:39:04 -04:00
bool ForEachDropSpenserInChunk ( int a_ChunkX , int a_ChunkZ , cDropSpenserCallback & a_Callback ) ;
2015-03-21 10:18:17 -04:00
/** Calls the callback for each furnace in the specified chunk.
Returns true if all furnaces processed , false if the callback aborted by returning true . */
2012-06-17 15:58:39 -04:00
bool ForEachFurnaceInChunk ( int a_ChunkX , int a_ChunkZ , cFurnaceCallback & a_Callback ) ; // Lua-accessible
2015-03-21 10:18:17 -04: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 . */
2013-11-20 15:53:29 -05:00
bool DoWithBlockEntityAt ( int a_BlockX , int a_BlockY , int a_BlockZ , cBlockEntityCallback & a_Callback ) ; // Lua-acessible
2015-03-21 10:18:17 -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 . */
2014-07-30 16:19:51 -04:00
bool DoWithBeaconAt ( int a_BlockX , int a_BlockY , int a_BlockZ , cBeaconCallback & a_Callback ) ; // Lua-acessible
2015-03-21 10:18:17 -04:00
/** Calls the callback for the chest at the specified coords.
Returns false if there ' s no chest at those coords , true if found . */
2013-11-20 15:53:29 -05:00
bool DoWithChestAt ( int a_BlockX , int a_BlockY , int a_BlockZ , cChestCallback & a_Callback ) ; // Lua-acessible
2012-06-17 15:58:39 -04:00
2015-03-21 10:18:17 -04: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 . */
2013-05-26 10:39:04 -04:00
bool DoWithDispenserAt ( int a_BlockX , int a_BlockY , int a_BlockZ , cDispenserCallback & a_Callback ) ; // Lua-accessible
2015-03-21 10:18:17 -04:00
/** Calls the callback for the dropper at the specified coords.
Returns false if there ' s no dropper at those coords or callback returns true , returns true if found . */
2013-05-26 10:39:04 -04:00
bool DoWithDropperAt ( int a_BlockX , int a_BlockY , int a_BlockZ , cDropperCallback & a_Callback ) ; // Lua-accessible
2015-03-21 10:18:17 -04:00
/** Calls the callback for the dropspenser at the specified coords.
Returns false if there ' s no dropspenser at those coords or callback returns true , returns true if found . */
2013-05-26 10:39:04 -04:00
bool DoWithDropSpenserAt ( int a_BlockX , int a_BlockY , int a_BlockZ , cDropSpenserCallback & a_Callback ) ; // Lua-accessible
2012-12-26 12:16:33 -05:00
2015-03-21 10:18:17 -04: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 . */
2012-06-17 15:58:39 -04:00
bool DoWithFurnaceAt ( int a_BlockX , int a_BlockY , int a_BlockZ , cFurnaceCallback & a_Callback ) ; // Lua-accessible
2015-03-21 10:18:17 -04: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 . */
2013-12-14 11:52:22 -05:00
bool DoWithNoteBlockAt ( int a_BlockX , int a_BlockY , int a_BlockZ , cNoteBlockCallback & a_Callback ) ; // Lua-accessible
2015-03-21 10:18:17 -04: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 . */
2014-01-18 08:16:47 -05:00
bool DoWithCommandBlockAt ( int a_BlockX , int a_BlockY , int a_BlockZ , cCommandBlockCallback & a_Callback ) ; // Lua-accessible
2015-05-31 10:28:38 -04:00
/** Calls the callback for the mob head block at the specified coords.
2015-03-21 10:18:17 -04:00
Returns false if there ' s no mob head block at those coords or callback returns true , returns true if found . */
2014-03-07 05:44:16 -05:00
bool DoWithMobHeadAt ( int a_BlockX , int a_BlockY , int a_BlockZ , cMobHeadCallback & a_Callback ) ; // Lua-accessible
2014-02-18 15:40:02 -05:00
2015-03-21 10:18:17 -04: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 . */
2014-03-06 19:30:34 -05:00
bool DoWithFlowerPotAt ( int a_BlockX , int a_BlockY , int a_BlockZ , cFlowerPotCallback & a_Callback ) ; // Lua-accessible
2015-03-21 10:18:17 -04:00
/** Retrieves the test on the sign at the specified coords.
Returns false if there ' s no sign at those coords , true if found . */
2012-06-17 15:58:39 -04:00
bool GetSignLines ( int a_BlockX , int a_BlockY , int a_BlockZ , AString & a_Line1 , AString & a_Line2 , AString & a_Line3 , AString & a_Line4 ) ; // Lua-accessible
2014-02-08 15:55:21 -05:00
/** Touches the chunk, causing it to be loaded or generated */
2014-08-28 05:36:35 -04:00
void TouchChunk ( int a_ChunkX , int a_ChunkZ ) ;
2014-12-10 16:35:16 -05:00
/** Queues the chunk for preparing - making sure that it's generated and lit.
The specified chunk is queued to be loaded or generated , and lit if needed .
The specified callback is called after the chunk has been prepared . If there ' s no preparation to do , only the callback is called .
It is legal to call without the callback . */
2015-05-30 06:11:17 -04:00
void PrepareChunk ( int a_ChunkX , int a_ChunkZ , std : : unique_ptr < cChunkCoordCallback > a_CallAfter = { } ) ; // Lua-accessible
2014-12-10 16:35:16 -05:00
/** Queues the chunk for generating.
First attempts to load the chunk from the storage . If that fails , queues the chunk for generating .
The specified callback is called after the chunk has been loaded / generated .
It is legal to call without the callback .
Returns true if successful , false if not ( possibly an out - of - memory error ) .
If the return value is true , the callback was / will be called . */
bool GenerateChunk ( int a_ChunkX , int a_ChunkZ , cChunkCoordCallback * a_CallAfter = nullptr ) ; // Lua-accessible
2012-06-14 09:06:06 -04:00
2014-02-08 15:55:21 -05:00
/** Marks the chunk as failed-to-load */
2014-08-28 05:36:35 -04:00
void ChunkLoadFailed ( int a_ChunkX , int a_ChunkZ ) ;
2012-06-14 09:06:06 -04:00
2014-02-08 15:55:21 -05:00
/** Sets the sign text. Returns true if sign text changed. */
2013-06-12 03:14:06 -04:00
bool SetSignLines ( int a_BlockX , int a_BlockY , int a_BlockZ , 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
/** Marks the chunk as being regenerated - all its clients want that chunk again (used by cWorld::RegenerateChunk()) */
2012-06-14 09:06:06 -04:00
void MarkChunkRegenerating ( int a_ChunkX , int a_ChunkZ ) ;
bool IsChunkLighted ( int a_ChunkX , int a_ChunkZ ) ;
2014-02-08 15:55:21 -05:00
/** Calls the callback for each chunk in the coords specified (all cords are inclusive). Returns true if all chunks have been processed successfully */
2012-07-02 12:30:17 -04:00
bool ForEachChunkInRect ( int a_MinChunkX , int a_MaxChunkX , int a_MinChunkZ , int a_MaxChunkZ , cChunkDataCallback & a_Callback ) ;
2014-02-08 15:55:21 -05:00
/** Writes the block area into the specified coords. Returns true if all chunks have been processed. Prefer cBlockArea::Write() instead. */
2012-10-06 12:58:31 -04:00
bool 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 the number of valid chunks and the number of dirty chunks */
2012-06-14 09:06:06 -04:00
void GetChunkStats ( int & a_NumChunksValid , int & a_NumChunksDirty ) ;
2014-02-08 15:55:21 -05:00
/** Grows a melon or a pumpkin next to the block specified (assumed to be the stem) */
2012-06-14 09:06:06 -04:00
void GrowMelonPumpkin ( int a_BlockX , int a_BlockY , int a_BlockZ , BLOCKTYPE a_BlockType , MTRand & a_Rand ) ;
2014-02-08 15:55:21 -05:00
/** Grows a sugarcane present at the block specified by the amount of blocks specified, up to the max height specified in the config */
2012-06-14 09:06:06 -04:00
void GrowSugarcane ( int a_BlockX , int a_BlockY , int a_BlockZ , int a_NumBlocksToGrow ) ;
2014-02-08 15:55:21 -05:00
/** Grows a cactus present at the block specified by the amount of blocks specified, up to the max height specified in the config */
2012-06-14 09:06:06 -04:00
void GrowCactus ( int a_BlockX , int a_BlockY , int a_BlockZ , int a_NumBlocksToGrow ) ;
2014-02-08 15:55:21 -05:00
/** Sets the blockticking to start at the specified block. Only one blocktick per chunk may be set, second call overwrites the first call */
2012-06-14 09:06:06 -04:00
void SetNextBlockTick ( int a_BlockX , int a_BlockY , int a_BlockZ ) ;
2015-05-09 05:16:56 -04:00
/** Make a Mob census, of all mobs, their family, their chunk and their distance to closest player */
void CollectMobCensus ( cMobCensus & a_ToFill ) ;
2013-09-07 16:19:56 -04:00
2014-02-08 15:55:21 -05:00
/** Try to Spawn Monsters inside all Chunks */
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 ) ;
2013-11-30 09:58:27 -05:00
2014-02-08 15:55:21 -05:00
/** Ticks a single block. Used by cWorld::TickQueuedBlocks() to tick the queued blocks */
2013-11-30 09:58:27 -05:00
void TickBlock ( int a_BlockX , int a_BlockY , int a_BlockZ ) ;
2012-06-14 09:06:06 -04:00
2013-04-13 17:02:10 -04:00
void UnloadUnusedChunks ( void ) ;
void SaveAllChunks ( void ) ;
2012-06-14 09:06:06 -04:00
2013-04-13 17:02:10 -04:00
cWorld * GetWorld ( void ) { return m_World ; }
2012-06-14 09:06:06 -04:00
int GetNumChunks ( void ) ;
void ChunkValidated ( void ) ; // Called by chunks that have become valid
2012-10-14 14:30:16 -04:00
2014-02-08 15:55:21 -05:00
/** Queues the specified block for ticking (block update) */
2013-02-28 02:42:45 -05:00
void QueueTickBlock ( int a_BlockX , int a_BlockY , int a_BlockZ ) ;
2013-06-15 11:29:20 -04:00
2014-02-08 15:55:21 -05:00
/** Returns the CS for locking the chunkmap; only cWorld::cLock may use this function! */
2013-06-15 11:29:20 -04:00
cCriticalSection & GetCS ( void ) { return m_CSLayers ; }
2014-07-10 12:18:32 -04:00
/** Increments (a_AlwaysTicked == true) or decrements (false) the m_AlwaysTicked counter for the specified chunk.
If the m_AlwaysTicked counter is greater than zero , the chunk is ticked in the tick - thread regardless of
whether it has any clients or not .
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 SetChunkAlwaysTicked ( int a_ChunkX , int a_ChunkZ , bool a_AlwaysTicked ) ;
2012-06-14 09:06:06 -04:00
private :
2014-02-08 15:55:21 -05:00
// The chunks can manipulate neighbors while in their Tick() method, using LockedGetBlock() and LockedSetBlock()
friend class cChunk ;
// The chunkstay can (de-)register itself using AddChunkStay() and DelChunkStay()
friend class cChunkStay ;
2012-06-14 09:06:06 -04:00
class cChunkLayer
{
public :
2014-06-16 10:12:50 -04:00
cChunkLayer (
2014-07-17 10:33:09 -04:00
int a_LayerX , int a_LayerZ ,
2014-06-16 10:12:50 -04:00
cChunkMap * a_Parent ,
cAllocationPool < cChunkData : : sChunkSection > & a_Pool
) ;
2012-06-14 09:06:06 -04:00
~ cChunkLayer ( ) ;
2014-02-08 15:55:21 -05:00
/** Always returns an assigned chunkptr, but the chunk needn't be valid (loaded / generated) - callers must check */
2014-08-28 05:36:35 -04:00
cChunkPtr GetChunk ( int a_ChunkX , int a_ChunkZ ) ;
2012-06-14 09:06:06 -04:00
2014-10-20 16:55:07 -04:00
/** Returns the specified chunk, or nullptr if not created yet */
2012-12-14 17:38:30 -05:00
cChunk * FindChunk ( int a_ChunkX , int a_ChunkZ ) ;
2012-06-14 09:06:06 -04:00
int GetX ( void ) const { return m_LayerX ; }
int GetZ ( void ) const { return m_LayerZ ; }
int GetNumChunksLoaded ( void ) const ;
void GetChunkStats ( int & a_NumChunksValid , int & a_NumChunksDirty ) const ;
void Save ( void ) ;
void UnloadUnusedChunks ( void ) ;
2014-02-08 15:55:21 -05:00
/** Collect a mob census, of all mobs, their megatype, their chunk and their distance o closest player */
2015-05-09 05:16:56 -04:00
void CollectMobCensus ( cMobCensus & a_ToFill ) ;
2014-02-08 15:55:21 -05:00
/** Try to Spawn Monsters inside all Chunks */
2015-05-09 05:16:56 -04:00
void SpawnMobs ( cMobSpawner & a_MobSpawner ) ;
2013-09-07 16:19:56 -04:00
2015-01-11 16:12:26 -05:00
void Tick ( std : : chrono : : milliseconds a_Dt ) ;
2012-06-14 09:06:06 -04:00
void RemoveClient ( cClientHandle * a_Client ) ;
2014-02-08 15:55:21 -05:00
/** Calls the callback for each entity in the entire world; returns true if all entities processed, false if the callback aborted by returning true */
2013-04-13 17:02:10 -04:00
bool ForEachEntity ( cEntityCallback & a_Callback ) ; // Lua-accessible
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. */
2015-03-21 10:18:17 -04:00
bool DoWithEntityByID ( UInt32 a_EntityID , cEntityCallback & a_Callback , bool & a_CallbackReturn ) ; // Lua-accessible
2013-04-13 17:02:10 -04:00
2014-02-08 15:55:21 -05:00
/** Returns true if there is an entity with the specified ID within this layer's chunks */
2015-03-21 10:18:17 -04:00
bool HasEntity ( UInt32 a_EntityID ) ;
2013-04-13 17:02:10 -04:00
2012-06-14 09:06:06 -04:00
protected :
cChunkPtr m_Chunks [ LAYER_SIZE * LAYER_SIZE ] ;
int m_LayerX ;
int m_LayerZ ;
cChunkMap * m_Parent ;
int m_NumChunksLoaded ;
2014-06-16 10:12:50 -04:00
cAllocationPool < cChunkData : : sChunkSection > & m_Pool ;
} ;
class cStarvationCallbacks
: public cAllocationPool < cChunkData : : sChunkSection > : : cStarvationCallbacks
{
virtual void OnStartUsingReserve ( ) override
{
LOG ( " Using backup memory buffer " ) ;
}
virtual void OnEndUsingReserve ( ) override
{
LOG ( " Stoped using backup memory buffer " ) ;
}
virtual void OnOutOfReserve ( ) override
{
LOG ( " Out of Memory " ) ;
}
2012-06-14 09:06:06 -04:00
} ;
typedef std : : list < cChunkLayer * > cChunkLayerList ;
2014-02-08 15:55:21 -05:00
typedef std : : list < cChunkStay * > cChunkStays ;
2012-06-14 09:06:06 -04:00
2014-10-20 16:55:07 -04:00
/** Finds the cChunkLayer object responsible for the specified chunk; returns nullptr if not found. Assumes m_CSLayers is locked. */
2012-12-14 17:38:30 -05:00
cChunkLayer * FindLayerForChunk ( int a_ChunkX , int a_ChunkZ ) ;
2014-10-20 16:55:07 -04:00
/** Returns the specified cChunkLayer object; returns nullptr if not found. Assumes m_CSLayers is locked. */
2012-12-14 17:38:30 -05:00
cChunkLayer * FindLayer ( int a_LayerX , int a_LayerZ ) ;
2014-02-08 15:55:21 -05:00
/** Returns the cChunkLayer object responsible for the specified chunk; creates it if not found. */
2012-12-14 17:38:30 -05:00
cChunkLayer * GetLayerForChunk ( int a_ChunkX , int a_ChunkZ ) ;
2014-02-08 15:55:21 -05:00
/** Returns the specified cChunkLayer object; creates it if not found. */
2012-12-14 17:38:30 -05:00
cChunkLayer * GetLayer ( int a_LayerX , int a_LayerZ ) ;
void RemoveLayer ( cChunkLayer * a_Layer ) ;
2012-06-14 09:06:06 -04:00
cCriticalSection m_CSLayers ;
cChunkLayerList m_Layers ;
cEvent m_evtChunkValid ; // Set whenever any chunk becomes valid, via ChunkValidated()
cWorld * m_World ;
2014-01-26 09:20:39 -05:00
cCriticalSection m_CSFastSetBlock ;
sSetBlockList m_FastSetBlockQueue ;
2014-02-08 15:55:21 -05:00
/** The cChunkStay descendants that are currently enabled in this chunkmap */
cChunkStays m_ChunkStays ;
2012-06-14 09:06:06 -04:00
2014-06-16 10:51:30 -04:00
std : : auto_ptr < cAllocationPool < cChunkData : : sChunkSection > > m_Pool ;
2014-06-16 10:12:50 -04:00
2014-08-28 05:36:35 -04:00
cChunkPtr GetChunk ( int a_ChunkX , int a_ChunkZ ) ; // Also queues the chunk for loading / generating if not valid
cChunkPtr GetChunkNoGen ( int a_ChunkX , int a_ChunkZ ) ; // Also queues the chunk for loading if not valid; doesn't generate
cChunkPtr GetChunkNoLoad ( int a_ChunkX , int a_ChunkZ ) ; // Doesn't load, doesn't generate
2012-06-14 09:06:06 -04:00
2014-02-08 15:55:21 -05:00
/** Gets a block in any chunk while in the cChunk's Tick() method; returns true if successful, false if chunk not loaded (doesn't queue load) */
2012-06-14 09:06:06 -04:00
bool LockedGetBlock ( int a_BlockX , int a_BlockY , int a_BlockZ , BLOCKTYPE & a_BlockType , NIBBLETYPE & a_BlockMeta ) ;
2014-02-08 15:55:21 -05:00
/** Gets a block type in any chunk while in the cChunk's Tick() method; returns true if successful, false if chunk not loaded (doesn't queue load) */
2013-05-28 08:05:23 -04:00
bool LockedGetBlockType ( int a_BlockX , int a_BlockY , int a_BlockZ , BLOCKTYPE & a_BlockType ) ;
2014-02-08 15:55:21 -05:00
/** Gets a block meta in any chunk while in the cChunk's Tick() method; returns true if successful, false if chunk not loaded (doesn't queue load) */
2013-05-28 08:05:23 -04:00
bool LockedGetBlockMeta ( int a_BlockX , int a_BlockY , int a_BlockZ , NIBBLETYPE & a_BlockMeta ) ;
2014-02-08 15:55:21 -05:00
/** Sets a block in any chunk while in the cChunk's Tick() method; returns true if successful, false if chunk not loaded (doesn't queue load) */
2013-05-28 08:05:23 -04:00
bool LockedSetBlock ( int a_BlockX , int a_BlockY , int a_BlockZ , BLOCKTYPE a_BlockType , NIBBLETYPE a_BlockMeta ) ;
2012-06-14 09:06:06 -04:00
2014-02-08 15:55:21 -05:00
/** Fast-sets a block in any chunk while in the cChunk's Tick() method; returns true if successful, false if chunk not loaded (doesn't queue load) */
2013-05-28 08:05:23 -04:00
bool LockedFastSetBlock ( int a_BlockX , int a_BlockY , int a_BlockZ , BLOCKTYPE a_BlockType , NIBBLETYPE a_BlockMeta ) ;
2012-12-14 17:38:30 -05:00
2014-02-08 15:55:21 -05:00
/** Locates a chunk ptr in the chunkmap; doesn't create it when not found; assumes m_CSLayers is locked. To be called only from cChunkMap. */
2012-12-14 17:38:30 -05:00
cChunk * FindChunk ( int a_ChunkX , int a_ChunkZ ) ;
2012-06-14 09:06:06 -04:00
2014-02-08 15:55:21 -05:00
/** Adds a new cChunkStay descendant to the internal list of ChunkStays; loads its chunks.
To be used only by cChunkStay ; others should use cChunkStay : : Enable ( ) instead */
void AddChunkStay ( cChunkStay & a_ChunkStay ) ;
2012-06-14 09:06:06 -04:00
2014-02-08 15:55:21 -05:00
/** Removes the specified cChunkStay descendant from the internal list of ChunkStays.
To be used only by cChunkStay ; others should use cChunkStay : : Disable ( ) instead */
void DelChunkStay ( cChunkStay & a_ChunkStay ) ;
2012-06-14 09:06:06 -04:00
2014-02-08 15:55:21 -05:00
} ;
2012-06-14 09:06:06 -04:00