32 #include "json/json.h"
42 int a_ChunkX,
int a_ChunkZ,
45 m_Presence(cpInvalid),
46 m_IsLightValid(false),
53 m_ChunkMap(a_ChunkMap),
54 m_WaterSimulatorData(a_World->GetWaterSimulator()->CreateChunkData()),
55 m_LavaSimulatorData (a_World->GetLavaSimulator ()->CreateChunkData()),
56 m_RedstoneSimulatorData(a_World->GetRedstoneSimulator()->CreateChunkData()),
122 if (
const auto PendingBlocksCount =
m_PendingSendBlocks.size(); PendingBlocksCount >= 10240)
130 else if (PendingBlocksCount == 0)
137 BlockEntity->SendTo(*ClientHandle);
150 BlockEntity->SendTo(*ClientHandle);
196 [](
const auto & Entity)
198 return Entity->IsPlayer();
243 ASSERT(!Entity->IsPlayer());
246 Entity->OnRemoveFromWorld(*Entity->GetWorld());
252 KeyPair.second->OnRemoveFromWorld();
318 a_Callback.Entity(Entity.get());
323 a_Callback.BlockEntity(KeyPair.second.get());
333 std::copy_n(a_SetChunkData.HeightMap, std::size(a_SetChunkData.HeightMap),
m_HeightMap);
334 std::copy_n(a_SetChunkData.BiomeMap, std::size(a_SetChunkData.BiomeMap),
m_BiomeMap);
345 a_SetChunkData.Entities.insert(
346 a_SetChunkData.Entities.end(),
352 m_Entities = std::move(a_SetChunkData.Entities);
358 Entity->SetParentChunk(
this);
359 Entity->SetIsTicking(
true);
365 KeyPair.second->Destroy();
366 KeyPair.second->OnRemoveFromWorld();
379 ASSERT(WorldBlockType == EntityBlockType);
391 KeyPair.second->OnAddToWorld(*
m_World, *
this);
424 LOGWARNING(
"cChunk::WriteBlockArea(): unsupported datatype request, can write only types + metas together (0x%x), requested 0x%x. Ignoring.",
436 int SizeX = BlockEndX - BlockStartX;
437 int SizeZ = BlockEndZ - BlockStartZ;
441 int BaseX = BlockStartX - a_MinBlockX;
442 int BaseZ = BlockStartZ - a_MinBlockZ;
447 for (
int y = 0; y < SizeY; y++)
449 int ChunkY = a_MinBlockY + y;
451 for (
int z = 0; z < SizeZ; z++)
453 int ChunkZ = OffZ + z;
454 int AreaZ = BaseZ + z;
455 for (
int x = 0; x < SizeX; x++)
457 int ChunkX = OffX + x;
458 int AreaX = BaseX + x;
459 auto idx = a_Area.
MakeIndex(AreaX, AreaY, AreaZ);
471 { BlockStartX, a_MinBlockY, BlockStartZ },
472 { BlockEndX, a_MinBlockY + SizeY - 1, BlockEndZ }
480 if (affectedArea.IsInside(itr->second->GetPos()))
482 itr->second->Destroy();
483 itr->second->OnRemoveFromWorld();
503 auto & be = keyPair.second;
504 auto posX = be->GetPosX() + a_MinBlockX;
505 auto posY = be->GetPosY() + a_MinBlockY;
506 auto posZ = be->GetPosZ() + a_MinBlockZ;
549 std::vector<Vector3d> PlayerPositions;
553 const cPlayer * currentPlayer = ClientHandle->GetPlayer();
554 PlayerPositions.push_back(currentPlayer->
GetPosition());
563 auto & Monster =
static_cast<cMonster &
>(*entity);
564 currentPosition = Monster.GetPosition();
565 for (
const auto & PlayerPos : PlayerPositions)
567 toFill.
CollectMob(Monster, *
this, (currentPosition - PlayerPos).SqrLength());
580 (a_MaxX > 0) && (a_MaxY > 0) && (a_MaxZ > 0) &&
581 (a_MaxX <= std::numeric_limits<int>::max() / a_MaxY) &&
582 (a_MaxX * a_MaxY <= std::numeric_limits<int>::max() / a_MaxZ)
586 int OverallMax = (a_MaxX * a_MaxY * a_MaxZ) - 1;
589 a_X = Random % a_MaxX;
590 a_Y = (Random / a_MaxX) % a_MaxY;
591 a_Z = ((Random / a_MaxX) / a_MaxY) % a_MaxZ;
613 int CenterX, CenterY, CenterZ;
623 int NumberOfTries = 0;
624 int NumberOfSuccess = 0;
625 int MaxNbOfSuccess = 4;
626 while ((NumberOfTries < 12) && (NumberOfSuccess < MaxNbOfSuccess))
628 const int HorizontalRange = 20;
629 const int VerticalRange = 0;
630 int TryX, TryY, TryZ;
631 GetThreeRandomNumbers(TryX, TryY, TryZ, 2 * HorizontalRange + 1, 2 * VerticalRange + 1, 2 * HorizontalRange + 1);
632 TryX -= HorizontalRange;
633 TryY -= VerticalRange;
634 TryZ -= HorizontalRange;
642 int WorldX, WorldY, WorldZ;
663 if ((Chunk ==
nullptr) || !Chunk->IsValid() || !Chunk->IsLightValid())
669 if (newMob ==
nullptr)
673 double ActualX = WorldX + 0.5;
674 double ActualZ = WorldZ + 0.5;
676 FLOGD(
"Spawning {0} #{1} at {2}", newMob->GetClass(), newMob->GetUniqueID(),
Vector3i{WorldX, WorldY, WorldZ});
698 if (!(*itr)->IsTicking())
704 if (!((*itr)->IsMob()))
707 ASSERT((*itr)->GetParentChunk() ==
this);
708 (*itr)->Tick(a_Dt, *
this);
709 ASSERT((*itr)->GetParentChunk() ==
this);
714 if (!(*itr)->IsTicking())
721 ((*itr)->GetChunkX() !=
m_PosX) ||
722 ((*itr)->GetChunkZ() !=
m_PosZ)
726 if (!(*itr)->IsPlayer())
733 (*itr)->SetParentChunk(
nullptr);
771 if (Neighbor ==
nullptr)
773 LOGWARNING(
"%s: Entity at %p (%s, ID %d) moving to a non-existent chunk.",
774 __FUNCTION__,
static_cast<void *
>(a_Entity.get()), a_Entity->GetClass(), a_Entity->GetUniqueID()
781 auto & Entity = *a_Entity;
782 Neighbor->
AddEntity(std::move(a_Entity));
794 m_Entity.SpawnOn(*a_Client);
800 cMover(
cEntity & a_CallbackEntity) :
801 m_Entity(a_CallbackEntity)
852 if (Section ==
nullptr)
913 for (
int i = 0; i < 4; i++)
924 MaxSize = std::min(BlockMeta[i] + 1, MaxSize);
929 if (TopMeta < MaxSize)
933 else if (TopMeta > MaxSize)
977 if (BlockEntity !=
nullptr)
979 auto BlockEntityPickups = BlockEntity->ConvertToPickups();
980 Pickups.insert(Pickups.end(), std::make_move_iterator(BlockEntityPickups.begin()), std::make_move_iterator(BlockEntityPickups.end()));
989 a_Digger, a_Tool, Pickups
1012 LOGWARNING(
"%s: requesting a block with a_RelY out of range: %d", __FUNCTION__, a_RelPos.
y);
1016 if ((chunk ==
nullptr) || !chunk->IsValid())
1021 chunk->GetBlockTypeMeta(a_RelPos, a_BlockType, a_BlockMeta);
1033 LOGWARNING(
"%s: requesting a block with a_RelY out of range: %d", __FUNCTION__, a_RelPos.
y);
1037 if ((chunk ==
nullptr) || !chunk->IsValid())
1042 a_BlockType = chunk->GetBlock(a_RelPos);
1054 LOGWARNING(
"%s: requesting a block with a_RelY out of range: %d", __FUNCTION__, a_RelPos.
y);
1058 if ((chunk ==
nullptr) || !chunk->IsValid())
1063 a_BlockMeta = chunk->GetMeta(a_RelPos);
1075 LOGWARNING(
"%s: requesting a block with a_RelY out of range: %d", __FUNCTION__, a_RelPos.
y);
1079 if ((chunk ==
nullptr) || !chunk->IsValid())
1084 a_BlockBlockLight = chunk->GetBlockLight(a_RelPos);
1096 LOGWARNING(
"%s: requesting a block with a_RelY out of range: %d", __FUNCTION__, a_RelPos.
y);
1100 if ((chunk ==
nullptr) || !chunk->IsValid())
1105 a_BlockSkyLight = chunk->GetSkyLight(a_RelPos);
1117 LOGWARNING(
"%s: requesting a block with a_RelY out of range: %d", __FUNCTION__, a_RelPos.
y);
1121 if ((chunk ==
nullptr) || !chunk->IsValid())
1126 a_BlockLight = chunk->GetBlockLight(a_RelPos);
1127 a_SkyLight = chunk->GetSkyLight (a_RelPos);
1139 LOGWARNING(
"%s: requesting a block with a_RelY out of range: %d", __FUNCTION__, a_RelPos.
y);
1143 if ((chunk ==
nullptr) || !chunk->IsValid())
1148 chunk->SetBlock(a_RelPos, a_BlockType, a_BlockMeta);
1160 LOGWARNING(
"%s: requesting a block with a_RelY out of range: %d", __FUNCTION__, a_RelPos.
y);
1164 if ((chunk ==
nullptr) || !chunk->IsValid())
1169 chunk->FastSetBlock(a_RelPos, a_BlockType, a_BlockMeta);
1198 const auto Biome =
GetBiomeAt(a_RelX, a_RelZ);
1218 for (
int y =
GetHeight(a_Position.
x, a_Position.
z); y >= a_Position.
y; y--)
1242 if (Section ==
nullptr)
1249 const auto BlockType = (*Section)[BlockIdx];
1252 RedstoneSimulator->AddBlock(*
this, Position,
BlockType);
1253 WaterSimulator->AddBlock(*
this, Position,
BlockType);
1254 LavaSimulator->AddBlock(*
this, Position,
BlockType);
1276 auto & BlockEntity = *FindResult->second;
1278 BlockEntity.Destroy();
1279 BlockEntity.OnRemoveFromWorld();
1303 if ((OldBlockType == a_BlockType) && (OldBlockMeta == a_BlockMeta))
1308 bool ReplacingLiquids = (
1315 if (!ReplacingLiquids)
1329 (OldBlockMeta != a_BlockMeta) || (!ReplacingLiquids)
1357 for (
int y = a_RelY - 1; y > 0; --y)
1377 if (a_Client ==
nullptr)
1380 m_PendingSendBlocks.emplace_back(
m_PosX,
m_PosZ, a_RelX, a_RelY, a_RelZ,
GetBlock(a_RelX, a_RelY, a_RelZ),
GetMeta(a_RelX, a_RelY, a_RelZ));
1381 if (BlockEntity !=
nullptr)
1392 if (BlockEntity !=
nullptr)
1394 BlockEntity->SendTo(*a_Client);
1404 const auto BlockEntityPtr = a_BlockEntity.get();
1406 cChunkDef::MakeIndex(a_BlockEntity->GetRelX(), a_BlockEntity->GetPosY(), a_BlockEntity->GetRelZ()),
1407 std::move(a_BlockEntity)
1411 BlockEntityPtr->OnAddToWorld(*
m_World, *
this);
1461 Stay(a_AlwaysTicked);
1466 Stay(a_AlwaysTicked);
1479 return be->
UsedBy(a_Player);
1500 for (
int z = a_MinRelZ; z <= a_MaxRelZ; z++)
1502 for (
int x = a_MinRelX; x <= a_MaxRelX; x++)
1584 if (!a_Entity->IsPlayer())
1589 auto EntityPtr = a_Entity.get();
1592 m_Entities.emplace_back(std::move(a_Entity));
1594 ASSERT(EntityPtr->GetParentChunk() ==
nullptr);
1595 EntityPtr->SetParentChunk(
this);
1619 [&a_Entity, &Removed](decltype(
m_Entities)::value_type & a_Value)
1621 if (a_Value.get() == &a_Entity)
1624 Removed = std::move(a_Value);
1645 if (Entity->GetUniqueID() == a_EntityID)
1662 if (Entity->IsTicking() && a_Callback(*Entity))
1679 if (!Entity->IsTicking())
1683 if (!Entity->GetBoundingBox().DoesIntersect(a_Box))
1688 if (a_Callback(*Entity))
1705 if ((Entity->GetUniqueID() == a_EntityID) && (Entity->IsTicking()))
1707 a_CallbackResult = a_Callback(*Entity);
1724 if (a_Callback(*KeyPair.second))
1742 if (BlockEntity ==
nullptr)
1747 const bool Result = a_Callback(*BlockEntity);
1760 a_BlockMeta =
GetMeta(a_RelPos);
1791 if ((*a_Chunk ==
nullptr) || !(*a_Chunk)->IsValid())
1797 a_Rel.
y = a_Position.
y;
1821 if ((a_RelX < -128) || (a_RelX > 128) || (a_RelZ < -128) || (a_RelZ > 128))
1831 bool ReturnThis =
true;
1837 if (Candidate !=
nullptr)
1850 if (Candidate !=
nullptr)
1878 return (ReturnThis ?
this :
nullptr);
1899 int RelX = a_RelPos.
x;
1900 int RelZ = a_RelPos.
z;
1906 while ((RelX < 0) && (ToReturn !=
nullptr))
1916 while ((RelZ < 0) && (ToReturn !=
nullptr))
1921 if (ToReturn !=
nullptr)
1931 int DstChunkX, DstChunkZ;
1946 if (Entity ==
nullptr)
1950 Entity->
SendTo(a_Client);
1981 return (a_Skylight < 16)? a_Skylight : 0;
int GetSnowStartHeight(EMCSBiome a_Biome)
Returns the height when a biome when a biome starts snowing.
bool IsBiomeNoDownfall(EMCSBiome a_Biome)
Returns true if the biome has no downfall - deserts and savannas.
bool IsBiomeCold(EMCSBiome a_Biome)
Returns true if the biome is cold (has snow and snowfall at higher elevations but not at regular heig...
EMCSBiome
Biome IDs The first batch corresponds to the clientside biomes, used by MineCraft.
bool IsBlockWater(BLOCKTYPE a_BlockType)
@ E_BLOCK_STATIONARY_LAVA
@ E_BLOCK_STATIONARY_WATER
unsigned char NIBBLETYPE
The datatype used by nibbledata (meta, light, skylight)
unsigned char HEIGHTTYPE
The type used by the heightmap.
std::unique_ptr< cEntity > OwnedEntity
unsigned char BLOCKTYPE
The datatype used by blockdata.
MTRand & GetRandomProvider()
Returns the current thread's random number source.
std::enable_if< std::is_arithmetic< T >::value, C >::type FloorC(T a_Value)
Floors a value, then casts it to C (an int by default).
void LOGWARNING(std::string_view a_Format, const Args &... args)
bool CallHookBlockToPickups(cWorld &a_World, Vector3i a_BlockPos, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, const cBlockEntity *a_BlockEntity, const cEntity *a_Digger, const cItem *a_Tool, cItems &a_Pickups)
size_t MakeIndex(Vector3i a_RelPos) const
Returns the index into the internal arrays for the specified coords.
NIBBLETYPE * GetBlockMetas(void) const
BLOCKTYPE * GetBlockTypes(void) const
Returns the internal pointer to the block types.
const cBlockEntities & GetBlockEntities(void) const
Direct read-only access to block entities.
virtual void SendTo(cClientHandle &a_Client)=0
Sends the packet defining the block entity to the client specified.
static OwnedBlockEntity CreateByBlockType(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, Vector3i a_Pos, cWorld *a_World=nullptr)
Creates a new block entity for the specified block type at the specified absolute pos.
virtual bool UsedBy(cPlayer *a_Player)=0
Called when a player uses this entity; should open the UI window.
static bool IsBlockEntityBlockType(BLOCKTYPE a_BlockType)
Returns true if the specified blocktype is supposed to have an associated block entity.
static NIBBLETYPE GetSpreadLightFalloff(BLOCKTYPE Block)
How much light do the blocks consume?
static bool IsSnowable(BLOCKTYPE Block)
static NIBBLETYPE GetLightValue(BLOCKTYPE Block)
How much light do the blocks emit on their own?
static bool IsTransparent(BLOCKTYPE Block)
Is a block transparent? (https://minecraft.wiki/w/Opacity)
static bool IsRainBlocker(BLOCKTYPE Block)
Does this block block the passage of rain?
virtual cItems ConvertToPickups(NIBBLETYPE a_BlockMeta, const cItem *a_Tool=nullptr) const
Returns the pickups that would result if the block was mined by a_Digger using a_Tool.
void Check(cChunkInterface &ChunkInterface, cBlockPluginInterface &a_PluginInterface, Vector3i a_RelPos, cChunk &a_Chunk) const
Called when one of the neighbors gets set; equivalent to MC block update.
virtual int Grow(cChunk &a_Chunk, Vector3i a_RelPos, int a_NumStages=1) const
Grows this block, if it supports growing, by the specified amount of stages (at most).
static const cBlockHandler & For(BLOCKTYPE a_BlockType)
virtual void OnUpdate(cChunkInterface &a_ChunkInterface, cWorldInterface &a_WorldInterface, cBlockPluginInterface &a_BlockPluginInterface, cChunk &a_Chunk, const Vector3i a_RelPos) const
Called when the block gets ticked either by a random tick or by a queued tick.
Represents two sets of coords, minimum and maximum for each direction.
bool GetChunkAndRelByAbsolute(const Vector3d &a_Position, cChunk **a_Chunk, Vector3i &a_Rel)
Convert absolute coordinates into relative coordinates.
void AddBlockEntity(OwnedBlockEntity a_BlockEntity)
Takes ownership of a block entity, which MUST actually reside in this chunk.
NIBBLETYPE GetBlockLight(Vector3i a_RelPos) const
Get the level of artificial light illuminating the block (0 - 15)
void GetAllData(cChunkDataCallback &a_Callback) const
Gets all chunk data, calls the a_Callback's methods for each data type.
ePresence m_Presence
Holds the presence status of the chunk - if it is present, or in the loader / generator queue,...
void TickBlocks(void)
Ticks several random blocks in the chunk.
std::vector< OwnedEntity > m_Entities
NIBBLETYPE GetMeta(int a_RelX, int a_RelY, int a_RelZ) const
bool ShouldBeTicked(void) const
Returns true if the chunk should be ticked in the tick-thread.
std::vector< cBlockEntity * > m_PendingSendBlockEntities
Block entities that have been touched and need to be sent to all clients.
void CheckBlocks()
Checks the block scheduled for checking in m_ToTickBlocks[].
EMCSBiome GetBiomeAt(int a_RelX, int a_RelZ) const
void SpawnMobs(cMobSpawner &a_MobSpawner)
Try to Spawn Monsters inside chunk.
void SendBlockEntity(int a_BlockX, int a_BlockY, int a_BlockZ, cClientHandle &a_Client)
unsigned m_AlwaysTicked
If greater than zero, the chunk is ticked even if it has no clients.
bool IsSlimeChunk() const
Returns true if slimes should spawn in the chunk.
bool UnboundedRelGetBlockMeta(Vector3i a_RelPos, NIBBLETYPE &a_BlockMeta) const
Same as GetBlockMeta(), but relative coords needn't be in this chunk (uses m_Neighbor-s or m_ChunkMap...
int GrowPlantAt(Vector3i a_RelPos, int a_NumStages=1)
Grows the plant at the specified position by at most a_NumStages.
bool UseBlockEntity(cPlayer *a_Player, int a_X, int a_Y, int a_Z)
Use block entity on coordinate.
void SetAllData(SetChunkData &&a_SetChunkData)
Sets all chunk data as either loaded from the storage or generated.
bool DoWithBlockEntityAt(Vector3i a_Position, cBlockEntityCallback a_Callback)
Calls the callback for the block entity at the specified coords; returns false if there's no block en...
void SetLight(const cChunkDef::BlockNibbles &a_BlockLight, const cChunkDef::BlockNibbles &a_SkyLight)
bool ForEachEntity(cEntityCallback a_Callback) const
Calls the callback for each entity; returns true if all entities processed, false if the callback abo...
ChunkLightData m_LightData
void FastSetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType, BLOCKTYPE a_BlockMeta)
void MarkRegenerating(void)
Marks all clients attached to this chunk as wanting this chunk.
void WriteBlockArea(cBlockArea &a_Area, int a_MinBlockX, int a_MinBlockY, int a_MinBlockZ, int a_DataTypes)
Writes the specified cBlockArea at the coords specified.
BLOCKTYPE GetBlock(int a_RelX, int a_RelY, int a_RelZ) const
void AddEntity(OwnedEntity a_Entity)
Vector3i RelativeToAbsolute(Vector3i a_RelBlockPosition) const
Converts the coord relative to this chunk into an absolute coord.
void GetThreeRandomNumbers(int &a_X, int &a_Y, int &a_Z, int a_MaxX, int a_MaxY, int a_MaxZ)
cChunk * GetRelNeighborChunkAdjustCoords(Vector3i &a_RelPos) const
Returns the chunk into which the relatively-specified block belongs.
cChunkCoords GetPos() const
bool HasClient(cClientHandle *a_Client)
Returns true if the specified client is present in this chunk.
int GetHeight(int a_X, int a_Z) const
void WakeUpSimulators(void)
Wakes up each simulator for its specific blocks; through all the blocks in the chunk.
void GetRandomBlockCoords(int &a_X, int &a_Y, int &a_Z)
bool IsWeatherSunnyAt(int a_RelX, int a_RelZ) const
Returns true if it is sunny at the specified location.
NIBBLETYPE GetTimeAlteredLight(NIBBLETYPE a_Skylight) const
Light alterations based on time.
void SetBlock(Vector3i a_RelBlockPos, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta)
bool ForEachEntityInBox(const cBoundingBox &a_Box, cEntityCallback a_Callback) const
Calls the callback for each entity that has a nonempty intersection with the specified boundingbox.
bool CanUnload(void) const
cBlockEntity * GetBlockEntity(Vector3i a_AbsPos)
Returns the block entity at the specified (absolute) coords.
void SetPresence(ePresence a_Presence)
Sets the chunk's presence.
void SetBiomeAt(int a_RelX, int a_RelZ, EMCSBiome a_Biome)
Sets the biome at the specified relative coords.
bool UnboundedRelSetBlock(Vector3i a_RelPos, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta)
Same as SetBlock(), but relative coords needn't be in this chunk (uses m_Neighbor-s or m_ChunkMap in ...
void MarkLoadFailed(void)
Queues the chunk for generating.
bool AddClient(cClientHandle *a_Client)
Adds a client to the chunk; returns true if added, false if already there.
bool UnboundedRelGetBlockSkyLight(Vector3i a_RelPos, NIBBLETYPE &a_SkyLight) const
Same as GetBlockSkyLight(), but relative coords needn't be in this chunk (uses m_Neighbor-s or m_Chun...
cChunk * GetRelNeighborChunk(int a_RelX, int a_RelZ)
Returns the chunk into which the relatively-specified block belongs, by walking the neighbors.
void ApplyWeatherToTop(void)
Adds snow to the top of snowy biomes and hydrates farmland / fills cauldrons in rainy biomes.
bool UnboundedRelFastSetBlock(Vector3i a_RelPos, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta)
Same as FastSetBlock(), but relative coords needn't be in this chunk (uses m_Neighbor-s or m_ChunkMap...
cFluidSimulatorData * m_WaterSimulatorData
ePresence
Represents the presence state of the chunk.
@ cpQueued
The chunk is not present, but is queued for loading / generation.
@ cpPresent
The chunk is present.
void Stay(bool a_Stay=true)
Sets or resets the internal flag that prevents chunk from being unloaded.
void SendBlockTo(int a_RelX, int a_RelY, int a_RelZ, cClientHandle *a_Client)
cItems PickupsFromBlock(Vector3i a_RelPos, const cEntity *a_Digger, const cItem *a_Tool)
Returns the pickups that would be produced, if the specified block was dug up by a_Digger using a_Too...
bool CanUnloadAfterSaving(void) const
Returns true if the chunk could have been unloaded if it weren't dirty.
cChunk * GetNeighborChunk(int a_BlockX, int a_BlockZ)
Returns the chunk into which the specified block belongs, by walking the neighbors.
cChunkDef::HeightMap m_HeightMap
void TickBlock(const Vector3i a_RelPos)
Ticks a single block.
bool UnboundedRelGetBlock(Vector3i a_RelCoords, BLOCKTYPE &a_BlockType, NIBBLETYPE &a_BlockMeta) const
Same as GetBlock(), but relative coords needn't be in this chunk (uses m_Neighbor-s or m_ChunkMap in ...
ChunkBlockData m_BlockData
cFluidSimulatorData * m_LavaSimulatorData
bool IsWeatherWetAt(int a_RelX, int a_RelZ) const
Returns true if it is raining or storming at the specified location, taking into account biomes.
bool IsValid(void) const
Returns true iff the chunk block data is valid (loaded / generated)
bool UnboundedRelGetBlockBlockLight(Vector3i a_RelPos, NIBBLETYPE &a_BlockLight) const
Same as GetBlockBlockLight(), but relative coords needn't be in this chunk (uses m_Neighbor-s or m_Ch...
cWorld * GetWorld(void) const
cBlockEntity * GetBlockEntityRel(Vector3i a_RelPos)
Returns the block entity at the specified (relative) coords.
void GetBlockInfo(Vector3i a_RelPos, BLOCKTYPE &a_BlockType, NIBBLETYPE &a_Meta, NIBBLETYPE &a_SkyLight, NIBBLETYPE &a_BlockLight) const
std::vector< cClientHandle * > m_LoadedByClient
void CollectMobCensus(cMobCensus &toFill)
Recence all mobs proximities to players in order to know what to do with them.
std::queue< Vector3i > m_BlocksToCheck
A queue of relative positions to call cBlockHandler::Check on.
cBlockEntities m_BlockEntities
void MoveEntityToNewChunk(OwnedEntity a_Entity)
Called by Tick() when an entity moves out of this chunk into a neighbor; moves the entity and sends s...
cChunk(int a_ChunkX, int a_ChunkZ, cChunkMap *a_ChunkMap, cWorld *a_World)
void OnUnload()
Called when the chunkmap unloads unused chunks.
bool ForEachBlockEntity(cBlockEntityCallback a_Callback)
Calls the callback for each block entity; returns true if all block entities processed,...
bool UnboundedRelGetBlockLights(Vector3i a_RelPos, NIBBLETYPE &a_BlockLight, NIBBLETYPE &a_SkyLight) const
Queries both BlockLight and SkyLight, relative coords needn't be in this chunk (uses m_Neighbor-s or ...
unsigned m_StayCount
Number of times the chunk has been requested to stay (by various cChunkStay objects); if zero,...
Vector3i m_BlockToTick
Relative coords of the block to tick first in the next Tick() call.
void BroadcastPendingChanges(void)
Flushes the pending block (entity) queue, and clients' outgoing data buffers.
void Tick(std::chrono::milliseconds a_Dt)
cChunkDef::BiomeMap m_BiomeMap
sSetBlockVector m_PendingSendBlocks
Blocks that have changed and need to be sent to all clients.
cRedstoneSimulatorChunkData * m_RedstoneSimulatorData
OwnedEntity RemoveEntity(cEntity &a_Entity)
Releases ownership of the given entity if it was found in this chunk.
void SetAlwaysTicked(bool a_AlwaysTicked)
Increments (a_AlwaysTicked == true) or decrements (false) the m_AlwaysTicked counter.
bool UnboundedRelGetBlockType(Vector3i a_RelCoords, BLOCKTYPE &a_BlockType) const
Same as GetBlockType(), but relative coords needn't be in this chunk (uses m_Neighbor-s or m_ChunkMap...
void SetAreaBiome(int a_MinRelX, int a_MaxRelX, int a_MinRelZ, int a_MaxRelZ, EMCSBiome a_Biome)
Sets the biome in the specified relative coords area.
bool HasAnyClients(void) const
Returns true if theres any client in the chunk; false otherwise.
bool HasEntity(UInt32 a_EntityID) const
Vector3i PositionToWorldPosition(Vector3i a_RelPos)
bool HasPlayerEntities() const
Check m_Entities for cPlayer objects.
void GetBlockTypeMeta(Vector3i a_RelPos, BLOCKTYPE &a_BlockType, NIBBLETYPE &a_BlockMeta) const
bool DoWithEntityByID(UInt32 a_EntityID, cEntityCallback a_Callback, bool &a_CallbackResult) const
Calls the callback if the entity with the specified ID is found, with the entity object as the callba...
void RemoveClient(cClientHandle *a_Client)
Removes the specified client from the chunk; ignored if client not in chunk.
static constexpr size_t SectionBlockCount
NIBBLETYPE GetMeta(Vector3i a_Position) const
BlockArray * GetSection(size_t a_Y) const
void SetMeta(Vector3i a_Position, NIBBLETYPE a_Meta)
void SetBlock(Vector3i a_Position, BLOCKTYPE a_Block)
void SetAll(const cChunkDef::BlockNibbles &a_BlockLightSource, const cChunkDef::BlockNibbles &a_SkyLightSource)
NIBBLETYPE GetSkyLight(Vector3i a_Position) const
NIBBLETYPE GetBlockLight(Vector3i a_Position) const
static bool IsValidHeight(Vector3i a_BlockPosition)
Validates a height-coordinate.
static Vector3i RelativeToAbsolute(Vector3i a_RelBlockPosition, cChunkCoords a_ChunkCoords)
Converts relative block coordinates into absolute coordinates with a known chunk location.
static void BlockToChunk(int a_X, int a_Z, int &a_ChunkX, int &a_ChunkZ)
Converts absolute block coords to chunk coords:
static void AbsoluteToRelative(int &a_X, int &a_Y, int &a_Z, int &a_ChunkX, int &a_ChunkZ)
Converts absolute block coords into relative (chunk + block) coords:
static bool IsValidRelPos(Vector3i a_RelPos)
Validates a chunk relative coordinate.
static size_t MakeIndex(int x, int y, int z)
NIBBLETYPE BlockNibbles[NumBlocks/2]
The type used for block data in nibble format, AXIS_ORDER ordering.
static const size_t NumSections
static Vector3i IndexToCoordinate(size_t index)
static const int NumBlocks
static void SetBiome(BiomeMap &a_BiomeMap, int a_X, int a_Z, EMCSBiome a_Biome)
Interface class used for comparing clients of two chunks.
void QueueGenerateChunk(cChunkCoords a_Coords, bool a_ForceRegeneration, cChunkCoordCallback *a_Callback=nullptr)
Queues the chunk for generation If a-ForceGenerate is set, the chunk is regenerated even if the data ...
void ChunkValidated(void)
cChunk * FindChunk(int a_ChunkX, int a_ChunkZ)
Locates a chunk ptr in the chunkmap; doesn't create it when not found; assumes m_CSChunks is locked.
cChunk & ConstructChunk(int a_ChunkX, int a_ChunkZ)
Returns or creates and returns a chunk pointer corresponding to the given chunk coordinates.
void CompareChunkClients(int a_ChunkX1, int a_ChunkZ1, int a_ChunkX2, int a_ChunkZ2, cClientDiffCallback &a_Callback)
Compares clients of two chunks, calls the callback accordingly.
void SendDestroyEntity(const cEntity &a_Entity)
void SendBlockChange(Vector3i a_BlockPos, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta)
bool IsDestroyed(void) const
bool IsPlayer(void) const
cChunk * GetParentChunk()
Returns the chunk responsible for ticking this entity.
bool IsTicking(void) const
Returns true if the entity is valid and ticking.
void SetPosition(double a_PosX, double a_PosY, double a_PosZ)
void SetParentChunk(cChunk *a_Chunk)
Sets the parent chunk, which is the chunk responsible for ticking this entity.
const Vector3d & GetPosition(void) const
Exported in ManualBindings.
const cItemHandler & GetHandler(void) const
Returns the cItemHandler responsible for this item type.
This class bridges a vector of cItem for safe access via Lua.
virtual bool CanHarvestBlock(BLOCKTYPE a_BlockType) const
Returns whether this tool / item can harvest a specific block (e.g.
This class is used to collect information, for each Mob, what is the distance of the closest player i...
void CollectSpawnableChunk(cChunk &a_Chunk)
void CollectMob(cMonster &a_Monster, cChunk &a_Chunk, double a_Distance)
Collect a mob - its distance to player, its family ...
This class is used to determine which monster can be spawned in which place it is essentially static ...
bool CheckPackCenter(BLOCKTYPE a_BlockType)
Check if specified block can be a Pack center for this spawner.
void NewPack(void)
Mark the beginning of a new Pack.
cMonster * TryToSpawnHere(cChunk *a_Chunk, Vector3i a_RelPos, EMCSBiome a_Biome, int &a_MaxPackSize)
Try to create a monster here If this is the first of a Pack, determine the type of monster a_Biome,...
cPluginManager * GetPluginManager(void)
Contains the data for a loaded / generated chunk, ready to be set into a cWorld.
void SimulateChunk(std::chrono::milliseconds a_DT, int a_ChunkX, int a_ChunkZ, cChunk *a_Chunk)
Called in each tick for each chunk, a_Dt is the time passed since the last tick, in msec; direct acce...
void WakeUp(cChunk &a_Chunk, Vector3i a_Position)
bool IsSlimeChunk(int a_ChunkX, int a_ChunkZ) const
Returns true if slimes should spawn in the chunk.
bool IsWeatherSunny(void) const
Returns true if the current weather is sunny.
cChunkGeneratorThread & GetGenerator(void)
cFluidSimulator * GetWaterSimulator(void)
int GetTickRandomNumber(int a_Range)
Returns a random number in range [0 .
bool IsDeepSnowEnabled(void) const
void ForceSendChunkTo(int a_ChunkX, int a_ChunkZ, cChunkSender::Priority a_Priority, cClientHandle *a_Client)
Sends the chunk to the client specified, even if the client already has the chunk.
eWeather GetWeather(void) const
Returns the current weather.
NIBBLETYPE GetSkyDarkness()
Get the current darkness level based on the time.
cRedstoneSimulator * GetRedstoneSimulator(void)
cFluidSimulator * GetLavaSimulator(void)
cChunkMap * GetChunkMap(void)
bool IsWeatherWet(void) const
Returns true if the world currently has any precipitation - rain, storm or snow.
cSimulatorManager * GetSimulatorManager(void)
std::unique_ptr< cBlockEntity > OwnedBlockEntity