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
# include "ChunkDef.h"
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 ;
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 ;
2012-06-14 09:06:06 -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 ;
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 ;
cChunkMap ( cWorld * a_World ) ;
~ 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 ) ;
2012-08-31 17:59:57 -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 = NULL ) ;
2013-07-07 09:06:06 -04:00
void BroadcastBlockBreakAnimation ( int a_entityID , int a_blockX , int a_blockY , int a_blockZ , char a_stage , const cClientHandle * a_Exclude = NULL ) ;
void BroadcastBlockEntity ( int a_BlockX , int a_BlockY , int a_BlockZ , const cClientHandle * a_Exclude ) ;
void BroadcastChunkData ( int a_ChunkX , int a_ChunkZ , cChunkDataSerializer & a_Serializer , const cClientHandle * a_Exclude = NULL ) ;
void BroadcastCollectPickup ( const cPickup & a_Pickup , const cPlayer & a_Player , const cClientHandle * a_Exclude = NULL ) ;
2012-08-19 15:42:32 -04:00
void BroadcastDestroyEntity ( const cEntity & a_Entity , const cClientHandle * a_Exclude = NULL ) ;
2013-12-15 04:51:46 -05:00
void BroadcastEntityEffect ( const cEntity & a_Entity , int a_EffectID , int a_Amplifier , short a_Duration , const cClientHandle * a_Exclude = NULL ) ;
2013-07-07 09:06:06 -04:00
void BroadcastEntityEquipment ( const cEntity & a_Entity , short a_SlotNum , const cItem & a_Item , const cClientHandle * a_Exclude = NULL ) ;
void BroadcastEntityHeadLook ( const cEntity & a_Entity , const cClientHandle * a_Exclude = NULL ) ;
void BroadcastEntityLook ( const cEntity & a_Entity , const cClientHandle * a_Exclude = NULL ) ;
void BroadcastEntityMetadata ( const cEntity & a_Entity , const cClientHandle * a_Exclude = NULL ) ;
void BroadcastEntityRelMove ( const cEntity & a_Entity , char a_RelX , char a_RelY , char a_RelZ , const cClientHandle * a_Exclude = NULL ) ;
void BroadcastEntityRelMoveLook ( const cEntity & a_Entity , char a_RelX , char a_RelY , char a_RelZ , const cClientHandle * a_Exclude = NULL ) ;
2012-08-19 17:14:45 -04:00
void BroadcastEntityStatus ( const cEntity & a_Entity , char a_Status , const cClientHandle * a_Exclude = NULL ) ;
2013-07-07 09:06:06 -04:00
void BroadcastEntityVelocity ( const cEntity & a_Entity , const cClientHandle * a_Exclude = NULL ) ;
2013-12-06 18:47:07 -05:00
void BroadcastEntityAnimation ( const cEntity & a_Entity , char a_Animation , const cClientHandle * a_Exclude = NULL ) ;
2013-12-22 08:45:25 -05:00
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_ParticleAmmount , cClientHandle * a_Exclude = NULL ) ;
2013-12-15 04:51:46 -05:00
void BroadcastRemoveEntityEffect ( const cEntity & a_Entity , int a_EffectID , const cClientHandle * a_Exclude = NULL ) ;
2012-09-11 08:01:34 -04:00
void BroadcastSoundEffect ( const AString & a_SoundName , int a_SrcX , int a_SrcY , int a_SrcZ , float a_Volume , float a_Pitch , const cClientHandle * a_Exclude = NULL ) ; // a_Src coords are Block * 8
2012-10-21 03:46:28 -04:00
void BroadcastSoundParticleEffect ( int a_EffectID , int a_SrcX , int a_SrcY , int a_SrcZ , int a_Data , const cClientHandle * a_Exclude = NULL ) ;
2013-07-07 09:06:06 -04:00
void BroadcastSpawnEntity ( cEntity & a_Entity , const cClientHandle * a_Exclude = NULL ) ;
void BroadcastThunderbolt ( int a_BlockX , int a_BlockY , int a_BlockZ , const cClientHandle * a_Exclude = NULL ) ;
2012-09-29 16:43:42 -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 ) ;
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 ) ;
2013-04-13 17:02:10 -04:00
void MarkChunkDirty ( int a_ChunkX , int a_ChunkZ ) ;
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.
a_BlockLight and a_BlockSkyLight are optional , if not present , chunk will be marked as unlighted .
a_BiomeMap is optional , if not present , biomes will be calculated by the generator
a_HeightMap is optional , if not present , will be calculated .
If a_MarkDirty is set , the chunk is set as dirty ( used after generating )
*/
void SetChunkData (
2013-04-13 17:02:10 -04:00
int a_ChunkX , int a_ChunkZ ,
2012-06-14 09:06:06 -04:00
const BLOCKTYPE * a_BlockTypes ,
const NIBBLETYPE * a_BlockMeta ,
const NIBBLETYPE * a_BlockLight ,
const NIBBLETYPE * a_BlockSkyLight ,
const cChunkDef : : HeightMap * a_HeightMap ,
const cChunkDef : : BiomeMap & a_BiomeMap ,
cBlockEntityList & a_BlockEntities ,
bool a_MarkDirty
) ;
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
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 ( ) ;
2012-06-14 09:06:06 -04:00
void FastSetBlocks ( sSetBlockList & a_BlockList ) ;
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 ) ;
void SetBlockMeta ( int a_BlockX , int a_BlockY , int a_BlockZ , BLOCKTYPE a_BlockMeta ) ;
2014-05-25 08:46:34 -04:00
void SetBlock ( cWorldInterface & a_WorldInterface , int a_BlockX , int a_BlockY , int a_BlockZ , BLOCKTYPE a_BlockType , BLOCKTYPE a_BlockMeta , bool a_SendToClients = true ) ;
2013-12-06 17:29:15 -05:00
void QueueSetBlock ( int a_BlockX , int a_BlockY , int a_BlockZ , BLOCKTYPE a_BlockType , BLOCKTYPE 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-02-08 15:55:21 -05:00
/** Retrieves block types of the specified blocks. If a chunk is not loaded, doesn't modify the block. Returns true if all blocks were read. */
2012-06-14 09:06:06 -04:00
bool GetBlocks ( sSetBlockVector & a_Blocks , bool a_ContinueOnFailure ) ;
bool DigBlock ( int a_X , int a_Y , int a_Z ) ;
void SendBlockTo ( int a_X , int a_Y , int a_Z , cPlayer * a_Player ) ;
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-02-08 15:55:21 -05:00
/** Returns true if the entity with specified ID is present in the chunks */
2013-04-13 17:02:10 -04:00
bool HasEntity ( int a_EntityID ) ;
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-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
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 and callback returned false. */
2013-04-13 17:02:10 -04:00
bool DoWithEntityByID ( int a_UniqueID , cEntityCallback & a_Callback ) ; // Lua-accessible
2012-06-16 04:35:07 -04:00
2014-02-08 15:55:21 -05: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
2014-02-08 15:55:21 -05: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
2014-02-08 15:55:21 -05: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
2014-02-08 15:55:21 -05: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 ) ;
2014-02-08 15:55:21 -05: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 ) ;
2014-02-08 15:55:21 -05: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
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 */
2013-11-20 15:53:29 -05:00
bool DoWithBlockEntityAt ( int a_BlockX , int a_BlockY , int a_BlockZ , cBlockEntityCallback & a_Callback ) ; // Lua-acessible
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 */
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
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 */
2013-05-26 10:39:04 -04:00
bool DoWithDispenserAt ( int a_BlockX , int a_BlockY , int a_BlockZ , cDispenserCallback & a_Callback ) ; // Lua-accessible
2014-02-08 15:55:21 -05: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
2014-02-08 15:55:21 -05: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
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 */
2012-06-17 15:58:39 -04:00
bool DoWithFurnaceAt ( int a_BlockX , int a_BlockY , int a_BlockZ , cFurnaceCallback & a_Callback ) ; // Lua-accessible
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 */
2013-12-14 11:52:22 -05:00
bool DoWithNoteBlockAt ( int a_BlockX , int a_BlockY , int a_BlockZ , cNoteBlockCallback & a_Callback ) ; // Lua-accessible
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 */
2014-01-18 08:16:47 -05:00
bool DoWithCommandBlockAt ( int a_BlockX , int a_BlockY , int a_BlockZ , cCommandBlockCallback & a_Callback ) ; // Lua-accessible
2014-02-19 08:45:09 -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 */
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
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 */
bool DoWithFlowerPotAt ( int a_BlockX , int a_BlockY , int a_BlockZ , cFlowerPotCallback & a_Callback ) ; // Lua-accessible
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 */
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 */
2012-06-14 09:06:06 -04:00
void TouchChunk ( int a_ChunkX , int a_ChunkY , int a_ChunkZ ) ;
2014-02-08 15:55:21 -05:00
/** Loads the chunk, if not already loaded. Doesn't generate. Returns true if chunk valid (even if already loaded before) */
2012-06-14 09:06:06 -04:00
bool LoadChunk ( int a_ChunkX , int a_ChunkY , int a_ChunkZ ) ;
2014-02-08 15:55:21 -05:00
/** Loads the chunks specified. Doesn't report failure, other than chunks being !IsValid() */
2012-06-14 09:06:06 -04:00
void LoadChunks ( const cChunkCoordsList & a_Chunks ) ;
2014-02-08 15:55:21 -05:00
/** Marks the chunk as failed-to-load */
2012-06-14 09:06:06 -04:00
void ChunkLoadFailed ( int a_ChunkX , int a_ChunkY , int a_ChunkZ ) ;
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-02-08 15:55:21 -05: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 ) ;
2014-02-08 15:55:21 -05:00
/** Make a Mob census, of all mobs, their family, their chunk and theyr distance to closest player */
2013-09-07 16:19:56 -04:00
void CollectMobCensus ( cMobCensus & a_ToFill ) ;
2014-02-08 15:55:21 -05:00
/** Try to Spawn Monsters inside all Chunks */
2013-09-07 18:11:38 -04:00
void SpawnMobs ( cMobSpawner & a_MobSpawner ) ;
2013-04-13 17:02:10 -04:00
void Tick ( float 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 ; }
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 :
cChunkLayer ( int a_LayerX , int a_LayerZ , cChunkMap * a_Parent ) ;
~ 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 */
2012-06-14 09:06:06 -04:00
cChunkPtr GetChunk ( int a_ChunkX , int a_ChunkY , int a_ChunkZ ) ;
2014-02-08 15:55:21 -05:00
/** Returns the specified chunk, or NULL 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 */
2013-09-07 18:11:38 -04:00
void CollectMobCensus ( cMobCensus & a_ToFill ) ;
2014-02-08 15:55:21 -05:00
/** Try to Spawn Monsters inside all Chunks */
2013-09-07 18:11:38 -04:00
void SpawnMobs ( cMobSpawner & a_MobSpawner ) ;
2013-09-07 16:19:56 -04:00
2013-04-13 17:02:10 -04:00
void Tick ( float 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. */
2013-04-13 17:02:10 -04:00
bool DoWithEntityByID ( int a_EntityID , cEntityCallback & a_Callback , bool & a_CallbackReturn ) ; // Lua-accessible
2014-02-08 15:55:21 -05:00
/** Returns true if there is an entity with the specified ID within this layer's chunks */
2013-04-13 17:02:10 -04:00
bool HasEntity ( int a_EntityID ) ;
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 ;
} ;
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-02-08 15:55:21 -05:00
/** Finds the cChunkLayer object responsible for the specified chunk; returns NULL 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-02-08 15:55:21 -05:00
/** Returns the specified cChunkLayer object; returns NULL 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
cChunkPtr GetChunk ( int a_ChunkX , int a_ChunkY , int a_ChunkZ ) ; // Also queues the chunk for loading / generating if not valid
cChunkPtr GetChunkNoGen ( int a_ChunkX , int a_ChunkY , int a_ChunkZ ) ; // Also queues the chunk for loading if not valid; doesn't generate
cChunkPtr GetChunkNoLoad ( int a_ChunkX , int a_ChunkY , int a_ChunkZ ) ; // Doesn't load, doesn't generate
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