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
# 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 ;
2020-03-27 08:03:28 -04:00
class cHopperEntity ;
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-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
2021-03-05 08:03:55 -05:00
struct SetChunkData ;
2017-09-11 17:20:49 -04:00
typedef std : : list < cClientHandle * > cClientHandleList ;
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 & ) > ;
2020-03-27 08:03:28 -04:00
using cHopperCallback = cFunctionRef < bool ( cHopperEntity & ) > ;
2017-09-11 17:20:49 -04:00
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 ) ;
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
*/
2021-03-05 08:03:55 -05:00
void SetChunkData ( SetChunkData & & 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 ) . */
2020-12-21 09:31:44 -05:00
bool GetChunkData ( cChunkCoords a_Coords , cChunkDataCallback & a_Callback ) const ;
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. */
2020-12-21 09:31:44 -05:00
bool IsChunkQueued ( int a_ChunkX , int a_ChunkZ ) const ;
2014-09-05 16:16:48 -04:00
2021-01-04 21:13:02 -05:00
bool IsWeatherSunnyAt ( int a_BlockX , int a_BlockZ ) const ;
bool IsWeatherWetAt ( int a_BlockX , int a_BlockZ ) const ;
bool IsWeatherWetAt ( Vector3i a_Position ) const ;
2020-12-21 09:31:44 -05:00
bool IsChunkValid ( int a_ChunkX , int a_ChunkZ ) const ;
bool HasChunkAnyClients ( int a_ChunkX , int a_ChunkZ ) const ;
2013-04-13 17:02:10 -04:00
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
2019-10-11 05:02:53 -04:00
/** Makes the specified player collect all the pickups around them. */
void CollectPickupsByPlayer ( cPlayer & a_Player ) ;
2020-12-21 09:31:44 -05:00
BLOCKTYPE GetBlock ( Vector3i a_BlockPos ) const ;
NIBBLETYPE GetBlockMeta ( Vector3i a_BlockPos ) const ;
NIBBLETYPE GetBlockSkyLight ( Vector3i a_BlockPos ) const ;
NIBBLETYPE GetBlockBlockLight ( Vector3i a_BlockPos ) const ;
2019-10-11 05:02:53 -04:00
/** Sets the meta for the specified block, while keeping the blocktype.
Ignored if the chunk is invalid . */
2020-08-26 16:45:13 -04:00
void SetBlockMeta ( Vector3i a_BlockPos , NIBBLETYPE a_BlockMeta ) ;
2016-02-05 16:45:45 -05:00
2021-01-04 21:13:02 -05:00
void SetBlock ( Vector3i a_BlockPos , BLOCKTYPE a_BlockType , NIBBLETYPE a_BlockMeta ) ;
bool GetBlockTypeMeta ( Vector3i a_BlockPos , BLOCKTYPE & a_BlockType , NIBBLETYPE & a_BlockMeta ) const ;
bool GetBlockInfo ( Vector3i , BLOCKTYPE & a_BlockType , NIBBLETYPE & a_Meta , NIBBLETYPE & a_SkyLight , NIBBLETYPE & a_BlockLight ) const ;
2012-06-14 09:06:06 -04:00
2014-02-08 15:55:21 -05:00
/** Special function used for growing trees, replaces only blocks that tree may overwrite */
2021-01-04 21:13:02 -05:00
void ReplaceTreeBlocks ( const sSetBlockVector & a_Blocks ) ;
2016-02-05 16:45:45 -05:00
2021-01-04 21:13:02 -05:00
/** Returns the biome at the specified coords. Reads the biome from the chunk, if loaded, invalid otherwise. */
EMCSBiome GetBiomeAt ( int a_BlockX , int a_BlockZ ) const ;
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
2020-09-03 17:25:35 -04:00
/** Adds the player to its appropriate chunk, takes ownership of the player pointer */
void AddPlayer ( std : : unique_ptr < cPlayer > a_Player ) ;
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 */
2020-08-20 07:50:22 -04:00
bool HasEntity ( UInt32 a_EntityID ) const ;
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 */
2020-08-20 07:50:22 -04:00
bool ForEachEntity ( cEntityCallback a_Callback ) const ; // 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
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 . */
2020-08-20 07:50:22 -04:00
bool DoWithEntityByID ( UInt32 a_EntityID , cEntityCallback a_Callback ) const ; // 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
2020-03-27 08:03:28 -04:00
/** Calls the callback for the hopper at the specified coords.
Returns false if there ' s no hopper at those coords or callback returns true , returns true if found . */
bool DoWithHopperAt ( int a_BlockX , int a_BlockY , int a_BlockZ , cHopperCallback 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 . */
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-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.
2020-08-28 16:26:04 -04:00
First attempts to load the chunk from the storage . If that fails , queues the chunk for generating . */
void GenerateChunk ( int a_ChunkX , int a_ChunkZ ) ; // 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 */
2020-08-20 07:50:22 -04:00
bool ForEachLoadedChunk ( cFunctionRef < bool ( int , int ) > a_Callback ) const ;
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 */
2020-08-20 07:50:22 -04:00
void GetChunkStats ( int & a_NumChunksValid , int & a_NumChunksDirty ) const ;
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
2020-04-17 05:36:37 -04:00
/** Causes the specified block to be ticked on the next Tick() call.
Plugins can use this via the cWorld : SetNextBlockToTick ( ) API .
Only one block coord per chunk may be set , a second call overwrites the first call */
void SetNextBlockToTick ( const Vector3i a_BlockPos ) ;
2012-06-14 09:06:06 -04:00
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 */
2020-04-17 05:36:37 -04:00
void TickBlock ( const Vector3i a_BlockPos ) ;
2012-06-14 09:06:06 -04:00
2013-04-13 17:02:10 -04:00
void UnloadUnusedChunks ( void ) ;
2020-08-20 07:50:22 -04:00
void SaveAllChunks ( void ) const ;
2012-06-14 09:06:06 -04:00
2020-08-20 07:50:22 -04:00
cWorld * GetWorld ( void ) const { return m_World ; }
2012-06-14 09:06:06 -04:00
2020-08-20 07:50:22 -04:00
size_t GetNumChunks ( void ) const ;
2016-09-03 11:38:29 -04:00
/** Returns the number of unused dirty chunks. Those are chunks that we can save and then unload */
2020-08-20 07:50:22 -04:00
size_t GetNumUnusedDirtyChunks ( void ) const ;
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
/** Returns the CS for locking the chunkmap; only cWorld::cLock may use this function! */
2021-03-17 19:18:02 -04:00
cCriticalSection & GetCS ( void ) const { 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 :
2020-08-28 16:32:46 -04:00
// Chunks query their neighbors using FindChunk(), 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
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
2020-08-20 07:50:22 -04:00
/** A map of chunk coordinates to chunks.
Uses a map ( as opposed to unordered_map ) because sorted maps are apparently faster . */
2020-12-21 10:51:43 -05:00
std : : map < cChunkCoords , cChunk > 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
2016-08-02 18:56:53 -04:00
/** Returns or creates and returns a chunk pointer corresponding to the given chunk coordinates.
2020-08-28 16:22:44 -04:00
Emplaces this chunk in the chunk map . */
cChunk & ConstructChunk ( int a_ChunkX , int a_ChunkZ ) ;
2016-08-02 18:56:53 -04:00
/** Constructs a chunk and queues it for loading / generating if not valid, returning it */
2020-08-28 16:22:44 -04:00
cChunk & GetChunk ( int a_ChunkX , int 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
2020-12-21 09:31:44 -05: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. */
const cChunk * FindChunk ( int a_ChunkX , int a_ChunkZ ) const ;
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
} ;