2017-09-02 03:45:06 -04:00
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
2017-08-03 18:01:22 -04:00
# include <functional>
2014-05-18 10:10:12 -04:00
# include "ChunkDataCallback.h"
2015-11-23 18:39:19 -05:00
# include "EffectID.h"
2017-09-11 17:20:49 -04:00
# include "FunctionRef.h"
2012-06-14 09:06:06 -04:00
class cWorld ;
class cItem ;
2019-10-16 04:06:34 -04:00
class cItems ;
2012-06-14 09:06:06 -04:00
class cChunkStay ;
class cChunk ;
class cPlayer ;
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 ;
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-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 ;
2017-01-17 16:38:04 -05:00
class cDeadlockDetect ;
2012-06-14 09:06:06 -04:00
2017-09-11 17:20:49 -04:00
typedef std : : list < cClientHandle * > cClientHandleList ;
typedef cChunk * cChunkPtr ;
using cEntityCallback = cFunctionRef < bool ( cEntity & ) > ;
using cBeaconCallback = cFunctionRef < bool ( cBeaconEntity & ) > ;
using cBedCallback = cFunctionRef < bool ( cBedEntity & ) > ;
using cBlockEntityCallback = cFunctionRef < bool ( cBlockEntity & ) > ;
using cBrewingstandCallback = cFunctionRef < bool ( cBrewingstandEntity & ) > ;
using cChestCallback = cFunctionRef < bool ( cChestEntity & ) > ;
using cChunkCallback = cFunctionRef < bool ( cChunk & ) > ;
using cDispenserCallback = cFunctionRef < bool ( cDispenserEntity & ) > ;
using cDropperCallback = cFunctionRef < bool ( cDropperEntity & ) > ;
using cDropSpenserCallback = cFunctionRef < bool ( cDropSpenserEntity & ) > ;
using cFurnaceCallback = cFunctionRef < bool ( cFurnaceEntity & ) > ;
using cNoteBlockCallback = cFunctionRef < bool ( cNoteEntity & ) > ;
using cCommandBlockCallback = cFunctionRef < bool ( cCommandBlockEntity & ) > ;
using cMobHeadCallback = cFunctionRef < bool ( cMobHeadEntity & ) > ;
using cFlowerPotCallback = cFunctionRef < bool ( cFlowerPotEntity & ) > ;
2016-10-12 08:38:45 -04:00
2012-06-14 09:06:06 -04:00
class cChunkMap
{
public :
2015-05-09 05:16:56 -04:00
cChunkMap ( cWorld * a_World ) ;
2016-05-01 17:18:21 -04:00
~ cChunkMap ( ) ;
2012-06-14 09:06:06 -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 ) ;
2016-02-05 16:45:45 -05:00
2015-12-01 17:12:44 -05:00
/** a_Player rclked block entity at the coords specified, handle it
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 ) ;
2016-02-05 16:45: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 */
2017-09-11 17:20:49 -04:00
bool DoWithChunk ( int a_ChunkX , int a_ChunkZ , cChunkCallback a_Callback ) ;
2013-08-03 14:26:50 -04:00
2015-07-31 10:49:10 -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 */
2017-09-11 17:20:49 -04:00
bool DoWithChunkAt ( Vector3i a_BlockPos , cChunkCallback a_Callback ) ;
2015-03-21 13:17:26 -04:00
2014-02-08 15:55:21 -05:00
/** Wakes up simulators for the specified block */
2017-08-17 09:48:38 -04:00
void WakeUpSimulators ( Vector3i a_Block ) ;
// DEPRECATED, use the vector-parametered version instead.
void WakeUpSimulators ( int a_BlockX , int a_BlockY , int a_BlockZ )
{
LOGWARNING ( " cChunkMap::WakeUpSimulators(int, int, int) is deprecated, use cChunkMap::WakeUpSimulators(Vector3i) instead. " ) ;
WakeUpSimulators ( Vector3i ( a_BlockX , a_BlockY , a_BlockZ ) ) ;
}
2012-06-14 09:06:06 -04:00
2016-04-18 06:30:23 -04:00
void MarkChunkDirty ( int a_ChunkX , int a_ChunkZ ) ;
2013-04-13 17:02:10 -04:00
void MarkChunkSaving ( int a_ChunkX , int a_ChunkZ ) ;
void MarkChunkSaved ( int a_ChunkX , int a_ChunkZ ) ;
2016-02-05 16:45:45 -05:00
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 ) ;
2016-02-05 16:45:45 -05:00
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
) ;
2016-02-05 16:45:45 -05:00
2019-09-24 08:20:50 -04:00
/** Calls the callback with the chunk's data, if available (with ChunkCS locked).
Returns true if the chunk was reported successfully , false if not ( chunk not present or callback failed ) . */
bool GetChunkData ( cChunkCoords a_Coords , cChunkDataCallback & a_Callback ) ;
2016-02-05 16:45:45 -05: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 ) ;
2016-02-05 16:45:45 -05: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
2019-10-11 05:02:53 -04:00
/** Sets the block at the specified coords to the specified value.
The replacement doesn ' t trigger block updates , nor wake up simulators .
The replaced blocks aren ' t checked for block entities ( block entity is leaked if it exists at this block ) .
If the chunk is invalid , the operation is ignored silently . */
void FastSetBlock ( Vector3i a_BlockPos , BLOCKTYPE a_BlockType , NIBBLETYPE a_BlockMeta ) ;
2014-12-24 01:20:17 -05:00
/** 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 ) ;
2019-10-11 05:02:53 -04:00
/** Makes the specified player collect all the pickups around them. */
void CollectPickupsByPlayer ( cPlayer & a_Player ) ;
BLOCKTYPE GetBlock ( Vector3i a_BlockPos ) ;
NIBBLETYPE GetBlockMeta ( Vector3i a_BlockPos ) ;
NIBBLETYPE GetBlockSkyLight ( Vector3i a_BlockPos ) ;
NIBBLETYPE GetBlockBlockLight ( Vector3i a_BlockPos ) ;
/** Sets the meta for the specified block, while keeping the blocktype.
If a_ShouldMarkDirty is true , the chunk is marked dirty by this change ( false is used eg . by water turning still ) .
If a_ShouldInformClients is true , the change is broadcast to all clients of the chunk .
Ignored if the chunk is invalid . */
void SetBlockMeta ( Vector3i a_BlockPos , NIBBLETYPE a_BlockMeta , bool a_ShouldMarkDirty , bool a_ShouldInformClients ) ;
2016-02-05 16:45:45 -05:00
2019-10-16 04:06:34 -04:00
void SetBlock ( Vector3i a_BlockPos , BLOCKTYPE a_BlockType , NIBBLETYPE a_BlockMeta ) ;
bool GetBlockTypeMeta ( Vector3i a_BlockPos , BLOCKTYPE & a_BlockType , NIBBLETYPE & a_BlockMeta ) ;
2019-10-11 05:02:53 -04:00
bool GetBlockInfo ( Vector3i , 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 ) ;
2016-02-05 16:45:45 -05:00
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 ) ;
2016-02-05 16:45:45 -05:00
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 ) ;
2016-02-05 16:45:45 -05:00
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 ) ;
2016-02-05 16:45:45 -05:00
2014-02-18 07:06:18 -05:00
/** 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 ) ;
2016-02-05 16:45:45 -05:00
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 . */
2019-10-16 04:06:34 -04:00
bool DigBlock ( Vector3i a_BlockPos ) ;
/** Returns all the pickups that would result if the a_Digger dug up the block at a_BlockPos using a_Tool.
a_Digger is usually a player , but can be nullptr for natural causes .
a_Tool is an optional item used to dig up the block , used by the handlers ( empty hand vs shears produce different pickups from leaves ) .
An empty hand is assumed if a_Tool is nullptr .
Returns an empty cItems object if the chunk is not present . */
cItems PickupsFromBlock ( Vector3i a_BlockPos , const cEntity * a_Digger , const cItem * a_Tool ) ;
2014-12-24 01:20:17 -05:00
/** 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 . */
2017-07-31 15:50:40 -04:00
void SendBlockTo ( int a_BlockX , int a_BlockY , int a_BlockZ , cPlayer & a_Player ) ;
2016-02-05 16:45:45 -05: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 ) ;
2016-02-05 16:45:45 -05: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 ) ;
2016-02-05 16:45:45 -05: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 */
2016-12-19 15:12:23 -05:00
void AddEntity ( OwnedEntity a_Entity ) ;
2016-02-05 16:45:45 -05: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 */
2016-12-19 15:12:23 -05:00
void AddEntityIfNotPresent ( OwnedEntity a_Entity ) ;
2016-02-05 16:45:45 -05:00
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 ) ;
2016-02-05 16:45:45 -05:00
2016-12-19 15:12:23 -05:00
/** Removes the entity from its appropriate chunk
Returns an owning reference to the found entity . */
OwnedEntity RemoveEntity ( cEntity & a_Entity ) ;
2016-02-05 16:45:45 -05:00
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 */
2017-09-11 17:20:49 -04:00
bool ForEachEntity ( cEntityCallback a_Callback ) ; // Lua-accessible
2013-04-13 17:02:10 -04:00
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 */
2017-09-11 17:20:49 -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 . */
2017-09-11 17:20:49 -04:00
bool ForEachEntityInBox ( const cBoundingBox & a_Box , cEntityCallback a_Callback ) ; // Lua-accessible
2014-09-03 11:00:26 -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 ) ;
2016-02-05 16:45:45 -05: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 . */
2017-09-11 17:20:49 -04:00
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 . */
2017-09-11 17:20:49 -04:00
bool ForEachBlockEntityInChunk ( int a_ChunkX , int a_ChunkZ , 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 brewingstand in the specified chunk.
Returns true if all brewingstands processed , false if the callback aborted by returning true . */
2017-09-11 17:20:49 -04:00
bool ForEachBrewingstandInChunk ( int a_ChunkX , int a_ChunkZ , cBrewingstandCallback a_Callback ) ; // Lua-accessible
2015-09-24 04:48:33 -04:00
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 . */
2017-09-11 17:20:49 -04: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 . */
2017-09-11 17:20:49 -04: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 . */
2017-09-11 17:20:49 -04:00
bool ForEachDropperInChunk ( int a_ChunkX , int a_ChunkZ , cDropperCallback a_Callback ) ;
2013-05-26 10:39:04 -04:00
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 . */
2017-09-11 17:20:49 -04:00
bool ForEachDropSpenserInChunk ( int a_ChunkX , int a_ChunkZ , cDropSpenserCallback a_Callback ) ;
2013-05-26 10:39:04 -04:00
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 . */
2017-09-11 17:20:49 -04:00
bool ForEachFurnaceInChunk ( int a_ChunkX , int a_ChunkZ , cFurnaceCallback a_Callback ) ; // Lua-accessible
2016-02-05 16:45:45 -05:00
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 . */
2017-09-11 17:20:49 -04:00
bool DoWithBlockEntityAt ( int a_BlockX , int a_BlockY , int a_BlockZ , cBlockEntityCallback a_Callback ) ; // Lua-acessible
2013-11-20 15:53:29 -05:00
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 . */
2017-09-11 17:20:49 -04:00
bool DoWithBeaconAt ( int a_BlockX , int a_BlockY , int a_BlockZ , cBeaconCallback a_Callback ) ; // Lua-acessible
2014-07-30 16:19:51 -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 . */
2017-09-11 17:20:49 -04:00
bool DoWithBedAt ( int a_BlockX , int a_BlockY , int a_BlockZ , cBedCallback a_Callback ) ; // Lua-acessible
2017-07-07 03:31:45 -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 */
2017-09-11 17:20:49 -04:00
bool DoWithBrewingstandAt ( int a_BlockX , int a_BlockY , int a_BlockZ , cBrewingstandCallback a_Callback ) ; // Lua-acessible
2015-09-24 04:48:33 -04:00
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 . */
2017-09-11 17:20:49 -04: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 . */
2017-09-11 17:20:49 -04:00
bool DoWithDispenserAt ( int a_BlockX , int a_BlockY , int a_BlockZ , cDispenserCallback a_Callback ) ; // Lua-accessible
2013-05-26 10:39:04 -04:00
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 . */
2017-09-11 17:20:49 -04:00
bool DoWithDropperAt ( int a_BlockX , int a_BlockY , int a_BlockZ , cDropperCallback a_Callback ) ; // Lua-accessible
2013-05-26 10:39:04 -04:00
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 . */
2017-09-11 17:20:49 -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 . */
2017-09-11 17:20:49 -04:00
bool DoWithFurnaceAt ( int a_BlockX , int a_BlockY , int a_BlockZ , cFurnaceCallback a_Callback ) ; // Lua-accessible
2012-06-17 15:58:39 -04:00
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 . */
2017-09-11 17:20:49 -04:00
bool DoWithNoteBlockAt ( int a_BlockX , int a_BlockY , int a_BlockZ , cNoteBlockCallback a_Callback ) ; // Lua-accessible
2013-12-14 11:52:22 -05:00
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 . */
2017-09-11 17:20:49 -04:00
bool DoWithCommandBlockAt ( int a_BlockX , int a_BlockY , int a_BlockZ , cCommandBlockCallback a_Callback ) ; // Lua-accessible
2014-01-18 08:16:47 -05:00
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 . */
2017-09-11 17:20:49 -04: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 . */
2017-09-11 17:20:49 -04:00
bool DoWithFlowerPotAt ( int a_BlockX , int a_BlockY , int a_BlockZ , cFlowerPotCallback a_Callback ) ; // Lua-accessible
2014-03-06 19:30:34 -05:00
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
2016-02-05 16:45:45 -05: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 ) ;
2016-02-05 16:45:45 -05: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 ) ;
2016-02-05 16:45:45 -05: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 ) ;
2016-02-05 16:45:45 -05:00
2012-06-14 09:06:06 -04:00
bool IsChunkLighted ( int a_ChunkX , int a_ChunkZ ) ;
2016-02-05 16:45:45 -05:00
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 ) ;
2015-09-24 10:43:31 -04:00
/** Calls the callback for each loaded chunk. Returns true if all chunks have been processed successfully */
2017-09-11 17:20:49 -04:00
bool ForEachLoadedChunk ( cFunctionRef < bool ( int , int ) > a_Callback ) ;
2016-02-05 16:45:45 -05:00
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 ) ;
2016-02-05 16:45:45 -05:00
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_BlockPos , int a_NumStages = 1 ) ;
2016-05-29 16:10:35 -04:00
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 ) ;
2016-02-05 16:45:45 -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
2016-09-03 11:38:29 -04:00
size_t GetNumChunks ( void ) ;
/** Returns the number of unused dirty chunks. Those are chunks that we can save and then unload */
size_t GetNumUnusedDirtyChunks ( void ) ;
2016-02-05 16:45:45 -05:00
2012-06-14 09:06:06 -04:00
void ChunkValidated ( void ) ; // Called by chunks that have become valid
2016-02-05 16:45:45 -05:00
2014-02-08 15:55:21 -05:00
/** Queues the specified block for ticking (block update) */
2019-10-11 05:02:53 -04:00
void QueueTickBlock ( Vector3i a_AbsPos ) ;
2016-02-05 16:45:45 -05:00
2014-02-08 15:55:21 -05:00
/** Returns the CS for locking the chunkmap; only cWorld::cLock may use this function! */
2016-08-02 18:56:53 -04:00
cCriticalSection & GetCS ( void ) { return m_CSChunks ; }
2016-02-05 16:45:45 -05:00
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
2017-01-17 16:38:04 -05:00
/** Adds this chunkmap's CS to the DeadlockDetect's tracked CSs. */
void TrackInDeadlockDetect ( cDeadlockDetect & a_DeadlockDetect , const AString & a_WorldName ) ;
/** Removes this chunkmap's CS from the DeadlockDetect's tracked CSs. */
void UntrackInDeadlockDetect ( cDeadlockDetect & a_DeadlockDetect ) ;
2012-06-14 09:06:06 -04:00
private :
2019-10-16 04:06:34 -04:00
// Chunks query their neighbors using GetChunk(), while being ticked
2014-02-08 15:55:21 -05:00
friend class cChunk ;
2016-02-05 16:45:45 -05:00
2014-02-08 15:55:21 -05:00
// The chunkstay can (de-)register itself using AddChunkStay() and DelChunkStay()
friend class cChunkStay ;
2016-02-05 16:45:45 -05:00
2012-06-14 09:06:06 -04:00
2014-06-16 10:12:50 -04:00
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
} ;
2016-02-05 16:45:45 -05:00
2016-08-02 18:56:53 -04:00
struct ChunkCoordinate
{
struct Comparer
{
bool operator ( ) ( const ChunkCoordinate & a_Lhs , const ChunkCoordinate & a_Rhs ) const
{
return ( ( a_Lhs . ChunkX = = a_Rhs . ChunkX ) ? ( a_Lhs . ChunkZ < a_Rhs . ChunkZ ) : ( a_Lhs . ChunkX < a_Rhs . ChunkX ) ) ;
}
} ;
int ChunkX ;
int ChunkZ ;
} ;
2016-02-05 16:45:45 -05:00
2014-02-08 15:55:21 -05:00
typedef std : : list < cChunkStay * > cChunkStays ;
2012-06-14 09:06:06 -04:00
2019-09-24 08:20:50 -04:00
mutable cCriticalSection m_CSChunks ;
2016-02-05 16:45:45 -05:00
2016-08-02 18:56:53 -04:00
/** A map of chunk coordinates to chunk pointers
Uses a map ( as opposed to unordered_map ) because sorted maps are apparently faster */
std : : map < ChunkCoordinate , std : : unique_ptr < cChunk > , ChunkCoordinate : : Comparer > m_Chunks ;
2012-06-14 09:06:06 -04:00
2016-08-02 18:56:53 -04:00
cEvent m_evtChunkValid ; // Set whenever any chunk becomes valid, via ChunkValidated()
2012-06-14 09:06:06 -04:00
cWorld * m_World ;
2016-02-05 16:45:45 -05:00
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
2015-08-14 16:19:15 -04:00
std : : unique_ptr < cAllocationPool < cChunkData : : sChunkSection > > m_Pool ;
2014-06-16 10:12:50 -04:00
2016-08-02 18:56:53 -04:00
/** Returns or creates and returns a chunk pointer corresponding to the given chunk coordinates.
Emplaces this chunk in the chunk map .
Developers SHOULD use the GetChunk variants instead of this function . */
cChunkPtr ConstructChunk ( int a_ChunkX , int a_ChunkZ ) ;
/** Constructs a chunk and queues it for loading / generating if not valid, returning it */
cChunkPtr GetChunk ( int a_ChunkX , int a_ChunkZ ) ;
/** Constructs a chunk and queues the chunk for loading if not valid, returning it; doesn't generate */
2017-08-17 09:48:38 -04:00
cChunkPtr GetChunkNoGen ( cChunkCoords a_Chunk ) ;
// Deprecated in favor of the vector version
cChunkPtr GetChunkNoGen ( int a_ChunkX , int a_ChunkZ )
{
2019-09-24 08:20:50 -04:00
return GetChunkNoGen ( { a_ChunkX , a_ChunkZ } ) ;
2017-08-17 09:48:38 -04:00
}
2016-08-02 18:56:53 -04:00
/** Constructs a chunk, returning it. Doesn't load, doesn't generate */
2019-10-11 05:02:53 -04:00
cChunkPtr GetChunkNoLoad ( cChunkCoords a_Coords ) ;
/** OBSOLETE, use the cChunkCoords-based overload instead.
Constructs a chunk , returning it . Doesn ' t load , doesn ' t generate */
cChunkPtr GetChunkNoLoad ( int a_ChunkX , int a_ChunkZ )
{
return GetChunkNoLoad ( { a_ChunkX , a_ChunkZ } ) ;
}
2016-02-05 16:45:45 -05:00
2016-08-02 18:56:53 -04:00
/** Locates a chunk ptr in the chunkmap; doesn't create it when not found; assumes m_CSChunks 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 ) ;
2016-02-05 16:45:45 -05: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 ) ;
2016-02-05 16:45:45 -05:00
2014-02-08 15:55:21 -05:00
} ;
2012-06-14 09:06:06 -04:00