Merge pull request #2894 from LogicParrot/spider
Spiders now friendly at daylight, new cChunk functions
This commit is contained in:
commit
30b95fcc4e
163
src/Chunk.cpp
163
src/Chunk.cpp
@ -123,9 +123,9 @@ cChunk::cChunk(
|
|||||||
cChunk::~cChunk()
|
cChunk::~cChunk()
|
||||||
{
|
{
|
||||||
cPluginManager::Get()->CallHookChunkUnloaded(*m_World, m_PosX, m_PosZ);
|
cPluginManager::Get()->CallHookChunkUnloaded(*m_World, m_PosX, m_PosZ);
|
||||||
|
|
||||||
// LOGINFO("### delete cChunk() (%i, %i) from %p, thread 0x%x ###", m_PosX, m_PosZ, this, GetCurrentThreadId());
|
// LOGINFO("### delete cChunk() (%i, %i) from %p, thread 0x%x ###", m_PosX, m_PosZ, this, GetCurrentThreadId());
|
||||||
|
|
||||||
for (cBlockEntityList::iterator itr = m_BlockEntities.begin(); itr != m_BlockEntities.end(); ++itr)
|
for (cBlockEntityList::iterator itr = m_BlockEntities.begin(); itr != m_BlockEntities.end(); ++itr)
|
||||||
{
|
{
|
||||||
delete *itr;
|
delete *itr;
|
||||||
@ -143,7 +143,7 @@ cChunk::~cChunk()
|
|||||||
delete *itr;
|
delete *itr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_NeighborXM != nullptr)
|
if (m_NeighborXM != nullptr)
|
||||||
{
|
{
|
||||||
m_NeighborXM->m_NeighborXP = nullptr;
|
m_NeighborXM->m_NeighborXP = nullptr;
|
||||||
@ -284,12 +284,12 @@ void cChunk::GetAllData(cChunkDataCallback & a_Callback)
|
|||||||
a_Callback.LightIsValid(m_IsLightValid);
|
a_Callback.LightIsValid(m_IsLightValid);
|
||||||
|
|
||||||
a_Callback.ChunkData(m_ChunkData);
|
a_Callback.ChunkData(m_ChunkData);
|
||||||
|
|
||||||
for (cEntityList::iterator itr = m_Entities.begin(); itr != m_Entities.end(); ++itr)
|
for (cEntityList::iterator itr = m_Entities.begin(); itr != m_Entities.end(); ++itr)
|
||||||
{
|
{
|
||||||
a_Callback.Entity(*itr);
|
a_Callback.Entity(*itr);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (cBlockEntityList::iterator itr = m_BlockEntities.begin(); itr != m_BlockEntities.end(); ++itr)
|
for (cBlockEntityList::iterator itr = m_BlockEntities.begin(); itr != m_BlockEntities.end(); ++itr)
|
||||||
{
|
{
|
||||||
a_Callback.BlockEntity(*itr);
|
a_Callback.BlockEntity(*itr);
|
||||||
@ -305,7 +305,7 @@ void cChunk::SetAllData(cSetChunkData & a_SetChunkData)
|
|||||||
ASSERT(a_SetChunkData.IsHeightMapValid());
|
ASSERT(a_SetChunkData.IsHeightMapValid());
|
||||||
ASSERT(a_SetChunkData.AreBiomesValid());
|
ASSERT(a_SetChunkData.AreBiomesValid());
|
||||||
ASSERT(IsQueued());
|
ASSERT(IsQueued());
|
||||||
|
|
||||||
memcpy(m_BiomeMap, a_SetChunkData.GetBiomes(), sizeof(m_BiomeMap));
|
memcpy(m_BiomeMap, a_SetChunkData.GetBiomes(), sizeof(m_BiomeMap));
|
||||||
memcpy(m_HeightMap, a_SetChunkData.GetHeightMap(), sizeof(m_HeightMap));
|
memcpy(m_HeightMap, a_SetChunkData.GetHeightMap(), sizeof(m_HeightMap));
|
||||||
|
|
||||||
@ -339,19 +339,19 @@ void cChunk::SetAllData(cSetChunkData & a_SetChunkData)
|
|||||||
ASSERT(WorldBlockType == EntityBlockType);
|
ASSERT(WorldBlockType == EntityBlockType);
|
||||||
} // for itr - m_BlockEntities
|
} // for itr - m_BlockEntities
|
||||||
#endif // _DEBUG
|
#endif // _DEBUG
|
||||||
|
|
||||||
// Set all block entities' World variable:
|
// Set all block entities' World variable:
|
||||||
for (cBlockEntityList::iterator itr = m_BlockEntities.begin(); itr != m_BlockEntities.end(); ++itr)
|
for (cBlockEntityList::iterator itr = m_BlockEntities.begin(); itr != m_BlockEntities.end(); ++itr)
|
||||||
{
|
{
|
||||||
(*itr)->SetWorld(m_World);
|
(*itr)->SetWorld(m_World);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create block entities that the loader didn't load; fill them with defaults
|
// Create block entities that the loader didn't load; fill them with defaults
|
||||||
CreateBlockEntities();
|
CreateBlockEntities();
|
||||||
|
|
||||||
// Set the chunk data as valid. This may be needed for some simulators that perform actions upon block adding (Vaporize)
|
// Set the chunk data as valid. This may be needed for some simulators that perform actions upon block adding (Vaporize)
|
||||||
SetPresence(cpPresent);
|
SetPresence(cpPresent);
|
||||||
|
|
||||||
// Wake up all simulators for their respective blocks:
|
// Wake up all simulators for their respective blocks:
|
||||||
WakeUpSimulators();
|
WakeUpSimulators();
|
||||||
|
|
||||||
@ -399,7 +399,7 @@ void cChunk::WriteBlockArea(cBlockArea & a_Area, int a_MinBlockX, int a_MinBlock
|
|||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// SizeX, SizeZ are the dimensions of the block data to copy to the chunk (size of the geometric union)
|
// SizeX, SizeZ are the dimensions of the block data to copy to the chunk (size of the geometric union)
|
||||||
|
|
||||||
int BlockStartX = std::max(a_MinBlockX, m_PosX * cChunkDef::Width);
|
int BlockStartX = std::max(a_MinBlockX, m_PosX * cChunkDef::Width);
|
||||||
@ -541,7 +541,7 @@ void cChunk::SpawnMobs(cMobSpawner & a_MobSpawner)
|
|||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
a_MobSpawner.NewPack();
|
a_MobSpawner.NewPack();
|
||||||
int NumberOfTries = 0;
|
int NumberOfTries = 0;
|
||||||
int NumberOfSuccess = 0;
|
int NumberOfSuccess = 0;
|
||||||
@ -561,7 +561,7 @@ void cChunk::SpawnMobs(cMobSpawner & a_MobSpawner)
|
|||||||
|
|
||||||
ASSERT(TryY > 0);
|
ASSERT(TryY > 0);
|
||||||
ASSERT(TryY < cChunkDef::Height - 1);
|
ASSERT(TryY < cChunkDef::Height - 1);
|
||||||
|
|
||||||
EMCSBiome Biome = m_ChunkMap->GetBiomeAt(TryX, TryZ);
|
EMCSBiome Biome = m_ChunkMap->GetBiomeAt(TryX, TryZ);
|
||||||
// MG TODO :
|
// MG TODO :
|
||||||
// Moon cycle (for slime)
|
// Moon cycle (for slime)
|
||||||
@ -569,7 +569,7 @@ void cChunk::SpawnMobs(cMobSpawner & a_MobSpawner)
|
|||||||
// check mobs presence on the block
|
// check mobs presence on the block
|
||||||
|
|
||||||
// MG TODO : check that "Level" really means Y
|
// MG TODO : check that "Level" really means Y
|
||||||
|
|
||||||
/*
|
/*
|
||||||
NIBBLETYPE SkyLight = 0;
|
NIBBLETYPE SkyLight = 0;
|
||||||
|
|
||||||
@ -581,7 +581,7 @@ void cChunk::SpawnMobs(cMobSpawner & a_MobSpawner)
|
|||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
cEntity * newMob = a_MobSpawner.TryToSpawnHere(this, TryX, TryY, TryZ, Biome, MaxNbOfSuccess);
|
cEntity * newMob = a_MobSpawner.TryToSpawnHere(this, TryX, TryY, TryZ, Biome, MaxNbOfSuccess);
|
||||||
if (newMob == nullptr)
|
if (newMob == nullptr)
|
||||||
{
|
{
|
||||||
@ -606,10 +606,10 @@ void cChunk::Tick(std::chrono::milliseconds a_Dt)
|
|||||||
BroadcastPendingBlockChanges();
|
BroadcastPendingBlockChanges();
|
||||||
|
|
||||||
CheckBlocks();
|
CheckBlocks();
|
||||||
|
|
||||||
// Tick simulators:
|
// Tick simulators:
|
||||||
m_World->GetSimulatorManager()->SimulateChunk(a_Dt, m_PosX, m_PosZ, this);
|
m_World->GetSimulatorManager()->SimulateChunk(a_Dt, m_PosX, m_PosZ, this);
|
||||||
|
|
||||||
TickBlocks();
|
TickBlocks();
|
||||||
|
|
||||||
// Tick all block entities in this chunk:
|
// Tick all block entities in this chunk:
|
||||||
@ -617,7 +617,7 @@ void cChunk::Tick(std::chrono::milliseconds a_Dt)
|
|||||||
{
|
{
|
||||||
m_IsDirty = (*itr)->Tick(a_Dt, *this) | m_IsDirty;
|
m_IsDirty = (*itr)->Tick(a_Dt, *this) | m_IsDirty;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (cEntityList::iterator itr = m_Entities.begin(); itr != m_Entities.end();)
|
for (cEntityList::iterator itr = m_Entities.begin(); itr != m_Entities.end();)
|
||||||
{
|
{
|
||||||
if (!((*itr)->IsMob())) // Mobs are ticked inside cWorld::TickMobs() (as we don't have to tick them if they are far away from players)
|
if (!((*itr)->IsMob())) // Mobs are ticked inside cWorld::TickMobs() (as we don't have to tick them if they are far away from players)
|
||||||
@ -657,7 +657,7 @@ void cChunk::Tick(std::chrono::milliseconds a_Dt)
|
|||||||
++itr;
|
++itr;
|
||||||
}
|
}
|
||||||
} // for itr - m_Entitites[]
|
} // for itr - m_Entitites[]
|
||||||
|
|
||||||
ApplyWeatherToTop();
|
ApplyWeatherToTop();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -715,7 +715,7 @@ void cChunk::MoveEntityToNewChunk(cEntity * a_Entity)
|
|||||||
m_Entity(a_CallbackEntity)
|
m_Entity(a_CallbackEntity)
|
||||||
{}
|
{}
|
||||||
} Mover(a_Entity);
|
} Mover(a_Entity);
|
||||||
|
|
||||||
m_ChunkMap->CompareChunkClients(this, Neighbor, Mover);
|
m_ChunkMap->CompareChunkClients(this, Neighbor, Mover);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -761,10 +761,10 @@ void cChunk::CheckBlocks()
|
|||||||
}
|
}
|
||||||
std::vector<Vector3i> ToTickBlocks;
|
std::vector<Vector3i> ToTickBlocks;
|
||||||
std::swap(m_ToTickBlocks, ToTickBlocks);
|
std::swap(m_ToTickBlocks, ToTickBlocks);
|
||||||
|
|
||||||
cChunkInterface ChunkInterface(m_World->GetChunkMap());
|
cChunkInterface ChunkInterface(m_World->GetChunkMap());
|
||||||
cBlockInServerPluginInterface PluginInterface(*m_World);
|
cBlockInServerPluginInterface PluginInterface(*m_World);
|
||||||
|
|
||||||
for (std::vector<Vector3i>::const_iterator itr = ToTickBlocks.begin(), end = ToTickBlocks.end(); itr != end; ++itr)
|
for (std::vector<Vector3i>::const_iterator itr = ToTickBlocks.begin(), end = ToTickBlocks.end(); itr != end; ++itr)
|
||||||
{
|
{
|
||||||
Vector3i Pos = (*itr);
|
Vector3i Pos = (*itr);
|
||||||
@ -788,17 +788,17 @@ void cChunk::TickBlocks(void)
|
|||||||
int TickX = m_BlockTickX;
|
int TickX = m_BlockTickX;
|
||||||
int TickY = m_BlockTickY;
|
int TickY = m_BlockTickY;
|
||||||
int TickZ = m_BlockTickZ;
|
int TickZ = m_BlockTickZ;
|
||||||
|
|
||||||
cChunkInterface ChunkInterface(this->GetWorld()->GetChunkMap());
|
cChunkInterface ChunkInterface(this->GetWorld()->GetChunkMap());
|
||||||
cBlockInServerPluginInterface PluginInterface(*this->GetWorld());
|
cBlockInServerPluginInterface PluginInterface(*this->GetWorld());
|
||||||
|
|
||||||
// This for loop looks disgusting, but it actually does a simple thing - first processes m_BlockTick, then adds random to it
|
// This for loop looks disgusting, but it actually does a simple thing - first processes m_BlockTick, then adds random to it
|
||||||
// This is so that SetNextBlockTick() works
|
// This is so that SetNextBlockTick() works
|
||||||
for (int i = 0; i < 50; i++,
|
for (int i = 0; i < 50; i++,
|
||||||
|
|
||||||
// This weird construct (*2, then /2) is needed,
|
// This weird construct (*2, then /2) is needed,
|
||||||
// otherwise the blocktick distribution is too biased towards even coords!
|
// otherwise the blocktick distribution is too biased towards even coords!
|
||||||
|
|
||||||
TickX = (TickX + RandomX) % (Width * 2),
|
TickX = (TickX + RandomX) % (Width * 2),
|
||||||
TickY = (TickY + RandomY) % (Height * 2),
|
TickY = (TickY + RandomY) % (Height * 2),
|
||||||
TickZ = (TickZ + RandomZ) % (Width * 2),
|
TickZ = (TickZ + RandomZ) % (Width * 2),
|
||||||
@ -836,7 +836,7 @@ void cChunk::ApplyWeatherToTop()
|
|||||||
// Not the right weather, or not at this tick; bail out
|
// Not the right weather, or not at this tick; bail out
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int X = m_World->GetTickRandomNumber(15);
|
int X = m_World->GetTickRandomNumber(15);
|
||||||
int Z = m_World->GetTickRandomNumber(15);
|
int Z = m_World->GetTickRandomNumber(15);
|
||||||
|
|
||||||
@ -944,7 +944,7 @@ void cChunk::GrowMelonPumpkin(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_Bl
|
|||||||
// Neighbors not valid or already taken by the same produce
|
// Neighbors not valid or already taken by the same produce
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pick a direction in which to place the produce:
|
// Pick a direction in which to place the produce:
|
||||||
int x = 0, z = 0;
|
int x = 0, z = 0;
|
||||||
int CheckType = a_TickRandom.randInt(3); // The index to the neighbors array which should be checked for emptiness
|
int CheckType = a_TickRandom.randInt(3); // The index to the neighbors array which should be checked for emptiness
|
||||||
@ -955,7 +955,7 @@ void cChunk::GrowMelonPumpkin(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_Bl
|
|||||||
case 2: z = 1; break;
|
case 2: z = 1; break;
|
||||||
case 3: z = -1; break;
|
case 3: z = -1; break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check that the block in that direction is empty:
|
// Check that the block in that direction is empty:
|
||||||
switch (BlockType[CheckType])
|
switch (BlockType[CheckType])
|
||||||
{
|
{
|
||||||
@ -968,7 +968,7 @@ void cChunk::GrowMelonPumpkin(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_Bl
|
|||||||
}
|
}
|
||||||
default: return;
|
default: return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if there's soil under the neighbor. We already know the neighbors are valid. Place produce if ok
|
// Check if there's soil under the neighbor. We already know the neighbors are valid. Place produce if ok
|
||||||
BLOCKTYPE Soil;
|
BLOCKTYPE Soil;
|
||||||
VERIFY(UnboundedRelGetBlock(a_RelX + x, a_RelY - 1, a_RelZ + z, Soil, BlockMeta));
|
VERIFY(UnboundedRelGetBlock(a_RelX + x, a_RelY - 1, a_RelZ + z, Soil, BlockMeta));
|
||||||
@ -1019,7 +1019,7 @@ void cChunk::GrowSugarcane(int a_RelX, int a_RelY, int a_RelZ, int a_NumBlocks)
|
|||||||
{
|
{
|
||||||
--Bottom;
|
--Bottom;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Grow by at most a_NumBlocks, but no more than max height:
|
// Grow by at most a_NumBlocks, but no more than max height:
|
||||||
int ToGrow = std::min(a_NumBlocks, m_World->GetMaxSugarcaneHeight() + 1 - (Top - Bottom));
|
int ToGrow = std::min(a_NumBlocks, m_World->GetMaxSugarcaneHeight() + 1 - (Top - Bottom));
|
||||||
for (int i = 0; i < ToGrow; i++)
|
for (int i = 0; i < ToGrow; i++)
|
||||||
@ -1060,7 +1060,7 @@ void cChunk::GrowCactus(int a_RelX, int a_RelY, int a_RelZ, int a_NumBlocks)
|
|||||||
{
|
{
|
||||||
--Bottom;
|
--Bottom;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Grow by at most a_NumBlocks, but no more than max height:
|
// Grow by at most a_NumBlocks, but no more than max height:
|
||||||
int ToGrow = std::min(a_NumBlocks, m_World->GetMaxCactusHeight() + 1 - (Top - Bottom));
|
int ToGrow = std::min(a_NumBlocks, m_World->GetMaxCactusHeight() + 1 - (Top - Bottom));
|
||||||
for (int i = 0; i < ToGrow; i++)
|
for (int i = 0; i < ToGrow; i++)
|
||||||
@ -1273,7 +1273,7 @@ void cChunk::UnboundedQueueTickBlock(int a_RelX, int a_RelY, int a_RelZ)
|
|||||||
int cChunk::GetHeight(int a_X, int a_Z)
|
int cChunk::GetHeight(int a_X, int a_Z)
|
||||||
{
|
{
|
||||||
ASSERT((a_X >= 0) && (a_X < Width) && (a_Z >= 0) && (a_Z < Width));
|
ASSERT((a_X >= 0) && (a_X < Width) && (a_Z >= 0) && (a_Z < Width));
|
||||||
|
|
||||||
if ((a_X >= 0) && (a_X < Width) && (a_Z >= 0) && (a_Z < Width))
|
if ((a_X >= 0) && (a_X < Width) && (a_Z >= 0) && (a_Z < Width))
|
||||||
{
|
{
|
||||||
return m_HeightMap[a_X + a_Z * Width];
|
return m_HeightMap[a_X + a_Z * Width];
|
||||||
@ -1410,7 +1410,7 @@ void cChunk::CalculateHeightmap(const BLOCKTYPE * a_BlockTypes)
|
|||||||
void cChunk::SetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, bool a_SendToClients)
|
void cChunk::SetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, bool a_SendToClients)
|
||||||
{
|
{
|
||||||
FastSetBlock(a_RelX, a_RelY, a_RelZ, a_BlockType, a_BlockMeta, a_SendToClients);
|
FastSetBlock(a_RelX, a_RelY, a_RelZ, a_BlockType, a_BlockMeta, a_SendToClients);
|
||||||
|
|
||||||
// Tick this block and its neighbors:
|
// Tick this block and its neighbors:
|
||||||
m_ToTickBlocks.push_back(Vector3i(a_RelX, a_RelY, a_RelZ));
|
m_ToTickBlocks.push_back(Vector3i(a_RelX, a_RelY, a_RelZ));
|
||||||
QueueTickBlockNeighbors(a_RelX, a_RelY, a_RelZ);
|
QueueTickBlockNeighbors(a_RelX, a_RelY, a_RelZ);
|
||||||
@ -1425,7 +1425,7 @@ void cChunk::SetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType,
|
|||||||
delete BlockEntity;
|
delete BlockEntity;
|
||||||
BlockEntity = nullptr;
|
BlockEntity = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the new block is a block entity, create the entity object:
|
// If the new block is a block entity, create the entity object:
|
||||||
switch (a_BlockType)
|
switch (a_BlockType)
|
||||||
{
|
{
|
||||||
@ -1470,7 +1470,7 @@ void cChunk::QueueTickBlock(int a_RelX, int a_RelY, int a_RelZ)
|
|||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_ToTickBlocks.push_back(Vector3i(a_RelX, a_RelY, a_RelZ));
|
m_ToTickBlocks.push_back(Vector3i(a_RelX, a_RelY, a_RelZ));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1508,7 +1508,7 @@ void cChunk::FastSetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockT
|
|||||||
ASSERT(!((a_RelX < 0) || (a_RelX >= Width) || (a_RelY < 0) || (a_RelY >= Height) || (a_RelZ < 0) || (a_RelZ >= Width)));
|
ASSERT(!((a_RelX < 0) || (a_RelX >= Width) || (a_RelY < 0) || (a_RelY >= Height) || (a_RelZ < 0) || (a_RelZ >= Width)));
|
||||||
|
|
||||||
ASSERT(IsValid());
|
ASSERT(IsValid());
|
||||||
|
|
||||||
const BLOCKTYPE OldBlockType = GetBlock(a_RelX, a_RelY, a_RelZ);
|
const BLOCKTYPE OldBlockType = GetBlock(a_RelX, a_RelY, a_RelZ);
|
||||||
const BLOCKTYPE OldBlockMeta = m_ChunkData.GetMeta(a_RelX, a_RelY, a_RelZ);
|
const BLOCKTYPE OldBlockMeta = m_ChunkData.GetMeta(a_RelX, a_RelY, a_RelZ);
|
||||||
if ((OldBlockType == a_BlockType) && (OldBlockMeta == a_BlockMeta))
|
if ((OldBlockType == a_BlockType) && (OldBlockMeta == a_BlockMeta))
|
||||||
@ -1543,7 +1543,7 @@ void cChunk::FastSetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockT
|
|||||||
{
|
{
|
||||||
m_PendingSendBlocks.push_back(sSetBlock(m_PosX, m_PosZ, a_RelX, a_RelY, a_RelZ, a_BlockType, a_BlockMeta));
|
m_PendingSendBlocks.push_back(sSetBlock(m_PosX, m_PosZ, a_RelX, a_RelY, a_RelZ, a_BlockType, a_BlockMeta));
|
||||||
}
|
}
|
||||||
|
|
||||||
m_ChunkData.SetMeta(a_RelX, a_RelY, a_RelZ, a_BlockMeta);
|
m_ChunkData.SetMeta(a_RelX, a_RelY, a_RelZ, a_BlockMeta);
|
||||||
|
|
||||||
// ONLY recalculate lighting if it's necessary!
|
// ONLY recalculate lighting if it's necessary!
|
||||||
@ -1593,7 +1593,7 @@ void cChunk::SendBlockTo(int a_RelX, int a_RelY, int a_RelZ, cClientHandle * a_C
|
|||||||
|
|
||||||
Vector3i wp = PositionToWorldPosition(a_RelX, a_RelY, a_RelZ);
|
Vector3i wp = PositionToWorldPosition(a_RelX, a_RelY, a_RelZ);
|
||||||
a_Client->SendBlockChange(wp.x, wp.y, wp.z, GetBlock(a_RelX, a_RelY, a_RelZ), GetMeta(a_RelX, a_RelY, a_RelZ));
|
a_Client->SendBlockChange(wp.x, wp.y, wp.z, GetBlock(a_RelX, a_RelY, a_RelZ), GetMeta(a_RelX, a_RelY, a_RelZ));
|
||||||
|
|
||||||
// FS #268 - if a BlockEntity digging is cancelled by a plugin, the entire block entity must be re-sent to the client:
|
// FS #268 - if a BlockEntity digging is cancelled by a plugin, the entire block entity must be re-sent to the client:
|
||||||
for (cBlockEntityList::iterator itr = m_BlockEntities.begin(), end = m_BlockEntities.end(); itr != end; ++itr)
|
for (cBlockEntityList::iterator itr = m_BlockEntities.begin(), end = m_BlockEntities.end(); itr != end; ++itr)
|
||||||
{
|
{
|
||||||
@ -1637,7 +1637,7 @@ cBlockEntity * cChunk::GetBlockEntity(int a_BlockX, int a_BlockY, int a_BlockZ)
|
|||||||
return *itr;
|
return *itr;
|
||||||
}
|
}
|
||||||
} // for itr - m_BlockEntities[]
|
} // for itr - m_BlockEntities[]
|
||||||
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1704,7 +1704,7 @@ void cChunk::SetAreaBiome(int a_MinRelX, int a_MaxRelX, int a_MinRelZ, int a_Max
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
MarkDirty();
|
MarkDirty();
|
||||||
|
|
||||||
// Re-send the chunk to all clients:
|
// Re-send the chunk to all clients:
|
||||||
for (auto ClientHandle : m_LoadedByClient)
|
for (auto ClientHandle : m_LoadedByClient)
|
||||||
{
|
{
|
||||||
@ -1721,7 +1721,7 @@ void cChunk::CollectPickupsByPlayer(cPlayer & a_Player)
|
|||||||
double PosX = a_Player.GetPosX();
|
double PosX = a_Player.GetPosX();
|
||||||
double PosY = a_Player.GetPosY();
|
double PosY = a_Player.GetPosY();
|
||||||
double PosZ = a_Player.GetPosZ();
|
double PosZ = a_Player.GetPosZ();
|
||||||
|
|
||||||
for (cEntityList::iterator itr = m_Entities.begin(); itr != m_Entities.end(); ++itr)
|
for (cEntityList::iterator itr = m_Entities.begin(); itr != m_Entities.end(); ++itr)
|
||||||
{
|
{
|
||||||
if ((!(*itr)->IsPickup()) && (!(*itr)->IsProjectile()))
|
if ((!(*itr)->IsPickup()) && (!(*itr)->IsProjectile()))
|
||||||
@ -2150,14 +2150,14 @@ bool cChunk::DoWithBlockEntityAt(int a_BlockX, int a_BlockY, int a_BlockZ, cBloc
|
|||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (a_Callback.Item(*itr))
|
if (a_Callback.Item(*itr))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
} // for itr - m_BlockEntitites[]
|
} // for itr - m_BlockEntitites[]
|
||||||
|
|
||||||
// Not found:
|
// Not found:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -2180,7 +2180,7 @@ bool cChunk::DoWithBeaconAt(int a_BlockX, int a_BlockY, int a_BlockZ, cBeaconCal
|
|||||||
// There is a block entity here, but of different type. No other block entity can be here, so we can safely bail out
|
// There is a block entity here, but of different type. No other block entity can be here, so we can safely bail out
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// The correct block entity is here
|
// The correct block entity is here
|
||||||
if (a_Callback.Item(reinterpret_cast<cBeaconEntity *>(*itr)))
|
if (a_Callback.Item(reinterpret_cast<cBeaconEntity *>(*itr)))
|
||||||
{
|
{
|
||||||
@ -2188,7 +2188,7 @@ bool cChunk::DoWithBeaconAt(int a_BlockX, int a_BlockY, int a_BlockZ, cBeaconCal
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
} // for itr - m_BlockEntitites[]
|
} // for itr - m_BlockEntitites[]
|
||||||
|
|
||||||
// Not found:
|
// Not found:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -2244,7 +2244,7 @@ bool cChunk::DoWithChestAt(int a_BlockX, int a_BlockY, int a_BlockZ, cChestCallb
|
|||||||
// There is a block entity here, but of different type. No other block entity can be here, so we can safely bail out
|
// There is a block entity here, but of different type. No other block entity can be here, so we can safely bail out
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// The correct block entity is here
|
// The correct block entity is here
|
||||||
if (a_Callback.Item(reinterpret_cast<cChestEntity *>(*itr)))
|
if (a_Callback.Item(reinterpret_cast<cChestEntity *>(*itr)))
|
||||||
{
|
{
|
||||||
@ -2252,7 +2252,7 @@ bool cChunk::DoWithChestAt(int a_BlockX, int a_BlockY, int a_BlockZ, cChestCallb
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
} // for itr - m_BlockEntitites[]
|
} // for itr - m_BlockEntitites[]
|
||||||
|
|
||||||
// Not found:
|
// Not found:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -2276,7 +2276,7 @@ bool cChunk::DoWithDispenserAt(int a_BlockX, int a_BlockY, int a_BlockZ, cDispen
|
|||||||
// There is a block entity here, but of different type. No other block entity can be here, so we can safely bail out
|
// There is a block entity here, but of different type. No other block entity can be here, so we can safely bail out
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// The correct block entity is here
|
// The correct block entity is here
|
||||||
if (a_Callback.Item(reinterpret_cast<cDispenserEntity *>(*itr)))
|
if (a_Callback.Item(reinterpret_cast<cDispenserEntity *>(*itr)))
|
||||||
{
|
{
|
||||||
@ -2284,7 +2284,7 @@ bool cChunk::DoWithDispenserAt(int a_BlockX, int a_BlockY, int a_BlockZ, cDispen
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
} // for itr - m_BlockEntitites[]
|
} // for itr - m_BlockEntitites[]
|
||||||
|
|
||||||
// Not found:
|
// Not found:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -2308,7 +2308,7 @@ bool cChunk::DoWithDropperAt(int a_BlockX, int a_BlockY, int a_BlockZ, cDropperC
|
|||||||
// There is a block entity here, but of different type. No other block entity can be here, so we can safely bail out
|
// There is a block entity here, but of different type. No other block entity can be here, so we can safely bail out
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// The correct block entity is here
|
// The correct block entity is here
|
||||||
if (a_Callback.Item(reinterpret_cast<cDropperEntity *>(*itr)))
|
if (a_Callback.Item(reinterpret_cast<cDropperEntity *>(*itr)))
|
||||||
{
|
{
|
||||||
@ -2316,7 +2316,7 @@ bool cChunk::DoWithDropperAt(int a_BlockX, int a_BlockY, int a_BlockZ, cDropperC
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
} // for itr - m_BlockEntitites[]
|
} // for itr - m_BlockEntitites[]
|
||||||
|
|
||||||
// Not found:
|
// Not found:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -2340,7 +2340,7 @@ bool cChunk::DoWithDropSpenserAt(int a_BlockX, int a_BlockY, int a_BlockZ, cDrop
|
|||||||
// There is a block entity here, but of different type. No other block entity can be here, so we can safely bail out
|
// There is a block entity here, but of different type. No other block entity can be here, so we can safely bail out
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// The correct block entity is here
|
// The correct block entity is here
|
||||||
if (a_Callback.Item(reinterpret_cast<cDropSpenserEntity *>(*itr)))
|
if (a_Callback.Item(reinterpret_cast<cDropSpenserEntity *>(*itr)))
|
||||||
{
|
{
|
||||||
@ -2348,7 +2348,7 @@ bool cChunk::DoWithDropSpenserAt(int a_BlockX, int a_BlockY, int a_BlockZ, cDrop
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
} // for itr - m_BlockEntitites[]
|
} // for itr - m_BlockEntitites[]
|
||||||
|
|
||||||
// Not found:
|
// Not found:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -2380,7 +2380,7 @@ bool cChunk::DoWithFurnaceAt(int a_BlockX, int a_BlockY, int a_BlockZ, cFurnaceC
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} // switch (BlockType)
|
} // switch (BlockType)
|
||||||
|
|
||||||
// The correct block entity is here,
|
// The correct block entity is here,
|
||||||
if (a_Callback.Item(reinterpret_cast<cFurnaceEntity *>(*itr)))
|
if (a_Callback.Item(reinterpret_cast<cFurnaceEntity *>(*itr)))
|
||||||
{
|
{
|
||||||
@ -2388,7 +2388,7 @@ bool cChunk::DoWithFurnaceAt(int a_BlockX, int a_BlockY, int a_BlockZ, cFurnaceC
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
} // for itr - m_BlockEntitites[]
|
} // for itr - m_BlockEntitites[]
|
||||||
|
|
||||||
// Not found:
|
// Not found:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -2412,7 +2412,7 @@ bool cChunk::DoWithNoteBlockAt(int a_BlockX, int a_BlockY, int a_BlockZ, cNoteBl
|
|||||||
// There is a block entity here, but of different type. No other block entity can be here, so we can safely bail out
|
// There is a block entity here, but of different type. No other block entity can be here, so we can safely bail out
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// The correct block entity is here
|
// The correct block entity is here
|
||||||
if (a_Callback.Item(reinterpret_cast<cNoteEntity *>(*itr)))
|
if (a_Callback.Item(reinterpret_cast<cNoteEntity *>(*itr)))
|
||||||
{
|
{
|
||||||
@ -2420,7 +2420,7 @@ bool cChunk::DoWithNoteBlockAt(int a_BlockX, int a_BlockY, int a_BlockZ, cNoteBl
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
} // for itr - m_BlockEntitites[]
|
} // for itr - m_BlockEntitites[]
|
||||||
|
|
||||||
// Not found:
|
// Not found:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -2444,7 +2444,7 @@ bool cChunk::DoWithCommandBlockAt(int a_BlockX, int a_BlockY, int a_BlockZ, cCom
|
|||||||
// There is a block entity here, but of different type. No other block entity can be here, so we can safely bail out
|
// There is a block entity here, but of different type. No other block entity can be here, so we can safely bail out
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// The correct block entity is here,
|
// The correct block entity is here,
|
||||||
if (a_Callback.Item(reinterpret_cast<cCommandBlockEntity *>(*itr)))
|
if (a_Callback.Item(reinterpret_cast<cCommandBlockEntity *>(*itr)))
|
||||||
{
|
{
|
||||||
@ -2452,7 +2452,7 @@ bool cChunk::DoWithCommandBlockAt(int a_BlockX, int a_BlockY, int a_BlockZ, cCom
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
} // for itr - m_BlockEntitites[]
|
} // for itr - m_BlockEntitites[]
|
||||||
|
|
||||||
// Not found:
|
// Not found:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -2476,7 +2476,7 @@ bool cChunk::DoWithMobHeadAt(int a_BlockX, int a_BlockY, int a_BlockZ, cMobHeadC
|
|||||||
// There is a block entity here, but of different type. No other block entity can be here, so we can safely bail out
|
// There is a block entity here, but of different type. No other block entity can be here, so we can safely bail out
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// The correct block entity is here,
|
// The correct block entity is here,
|
||||||
if (a_Callback.Item(reinterpret_cast<cMobHeadEntity *>(*itr)))
|
if (a_Callback.Item(reinterpret_cast<cMobHeadEntity *>(*itr)))
|
||||||
{
|
{
|
||||||
@ -2484,7 +2484,7 @@ bool cChunk::DoWithMobHeadAt(int a_BlockX, int a_BlockY, int a_BlockZ, cMobHeadC
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
} // for itr - m_BlockEntitites[]
|
} // for itr - m_BlockEntitites[]
|
||||||
|
|
||||||
// Not found:
|
// Not found:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -2508,7 +2508,7 @@ bool cChunk::DoWithFlowerPotAt(int a_BlockX, int a_BlockY, int a_BlockZ, cFlower
|
|||||||
// There is a block entity here, but of different type. No other block entity can be here, so we can safely bail out
|
// There is a block entity here, but of different type. No other block entity can be here, so we can safely bail out
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// The correct block entity is here
|
// The correct block entity is here
|
||||||
if (a_Callback.Item(reinterpret_cast<cFlowerPotEntity *>(*itr)))
|
if (a_Callback.Item(reinterpret_cast<cFlowerPotEntity *>(*itr)))
|
||||||
{
|
{
|
||||||
@ -2516,7 +2516,7 @@ bool cChunk::DoWithFlowerPotAt(int a_BlockX, int a_BlockY, int a_BlockZ, cFlower
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
} // for itr - m_BlockEntitites[]
|
} // for itr - m_BlockEntitites[]
|
||||||
|
|
||||||
// Not found:
|
// Not found:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -2546,11 +2546,11 @@ bool cChunk::GetSignLines(int a_BlockX, int a_BlockY, int a_BlockZ, AString & a_
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
} // switch (BlockType)
|
} // switch (BlockType)
|
||||||
|
|
||||||
// There is a block entity here, but of different type. No other block entity can be here, so we can safely bail out
|
// There is a block entity here, but of different type. No other block entity can be here, so we can safely bail out
|
||||||
return false;
|
return false;
|
||||||
} // for itr - m_BlockEntitites[]
|
} // for itr - m_BlockEntitites[]
|
||||||
|
|
||||||
// Not found:
|
// Not found:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -2600,6 +2600,31 @@ void cChunk::GetBlockInfo(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE & a_Bloc
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool cChunk::GetChunkAndRelByAbsolute(const Vector3d & a_Position, cChunk ** a_Chunk, Vector3i & a_Rel)
|
||||||
|
{
|
||||||
|
return GetChunkAndRelByAbsolute(Vector3i(FloorC(a_Position.x), FloorC(a_Position.y), FloorC(a_Position.z)), a_Chunk, a_Rel);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool cChunk::GetChunkAndRelByAbsolute(const Vector3i & a_Position, cChunk ** a_Chunk, Vector3i & a_Rel)
|
||||||
|
{
|
||||||
|
*a_Chunk = this->GetNeighborChunk(a_Position.x, a_Position.z);
|
||||||
|
if ((*a_Chunk == nullptr) || !(*a_Chunk)->IsValid())
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
a_Rel.x = a_Position.x - (*a_Chunk)->GetPosX() * cChunkDef::Width;
|
||||||
|
a_Rel.y = a_Position.y;
|
||||||
|
a_Rel.z = a_Position.z - (*a_Chunk)->GetPosZ() * cChunkDef::Width;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
cChunk * cChunk::GetNeighborChunk(int a_BlockX, int a_BlockZ)
|
cChunk * cChunk::GetNeighborChunk(int a_BlockX, int a_BlockZ)
|
||||||
{
|
{
|
||||||
// Convert coords to relative, then call the relative version:
|
// Convert coords to relative, then call the relative version:
|
||||||
@ -2652,7 +2677,7 @@ cChunk * cChunk::GetRelNeighborChunk(int a_RelX, int a_RelZ)
|
|||||||
// Going X first failed, but if the request is crossing Z as well, let's try the Z first later on.
|
// Going X first failed, but if the request is crossing Z as well, let's try the Z first later on.
|
||||||
ReturnThis = false;
|
ReturnThis = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (a_RelZ < 0)
|
if (a_RelZ < 0)
|
||||||
{
|
{
|
||||||
if (m_NeighborZM != nullptr)
|
if (m_NeighborZM != nullptr)
|
||||||
@ -2671,7 +2696,7 @@ cChunk * cChunk::GetRelNeighborChunk(int a_RelX, int a_RelZ)
|
|||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (ReturnThis ? this : nullptr);
|
return (ReturnThis ? this : nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2691,7 +2716,7 @@ cChunk * cChunk::GetRelNeighborChunkAdjustCoords(int & a_RelX, int & a_RelZ) con
|
|||||||
{
|
{
|
||||||
return ToReturn;
|
return ToReturn;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Request for a different chunk, calculate chunk offset:
|
// Request for a different chunk, calculate chunk offset:
|
||||||
int RelX = a_RelX; // Make a local copy of the coords (faster access)
|
int RelX = a_RelX; // Make a local copy of the coords (faster access)
|
||||||
int RelZ = a_RelZ;
|
int RelZ = a_RelZ;
|
||||||
@ -2721,7 +2746,7 @@ cChunk * cChunk::GetRelNeighborChunkAdjustCoords(int & a_RelX, int & a_RelZ) con
|
|||||||
a_RelZ = RelZ;
|
a_RelZ = RelZ;
|
||||||
return ToReturn;
|
return ToReturn;
|
||||||
}
|
}
|
||||||
|
|
||||||
// The chunk cannot be walked through neighbors, find it through the chunkmap:
|
// The chunk cannot be walked through neighbors, find it through the chunkmap:
|
||||||
int AbsX = a_RelX + m_PosX * Width;
|
int AbsX = a_RelX + m_PosX * Width;
|
||||||
int AbsZ = a_RelZ + m_PosZ * Width;
|
int AbsZ = a_RelZ + m_PosZ * Width;
|
||||||
|
149
src/Chunk.h
149
src/Chunk.h
@ -63,7 +63,9 @@ typedef cItemCallback<cCommandBlockEntity> cCommandBlockCallback;
|
|||||||
typedef cItemCallback<cMobHeadEntity> cMobHeadCallback;
|
typedef cItemCallback<cMobHeadEntity> cMobHeadCallback;
|
||||||
typedef cItemCallback<cFlowerPotEntity> cFlowerPotCallback;
|
typedef cItemCallback<cFlowerPotEntity> cFlowerPotCallback;
|
||||||
|
|
||||||
|
// A convenience macro for calling GetChunkAndRelByAbsolute.
|
||||||
|
#define PREPARE_REL_AND_CHUNK(Position, OriginalChunk) cChunk * Chunk; Vector3i Rel; bool RelSuccess = (OriginalChunk).GetChunkAndRelByAbsolute(Position, &Chunk, Rel);
|
||||||
|
#define PREPARE_BLOCKDATA BLOCKTYPE BlockType; NIBBLETYPE BlockMeta;
|
||||||
|
|
||||||
|
|
||||||
// This class is not to be used directly
|
// This class is not to be used directly
|
||||||
@ -109,9 +111,9 @@ public:
|
|||||||
bool IsDirty(void) const {return m_IsDirty; }
|
bool IsDirty(void) const {return m_IsDirty; }
|
||||||
|
|
||||||
bool CanUnload(void);
|
bool CanUnload(void);
|
||||||
|
|
||||||
bool IsLightValid(void) const {return m_IsLightValid; }
|
bool IsLightValid(void) const {return m_IsLightValid; }
|
||||||
|
|
||||||
/*
|
/*
|
||||||
To save a chunk, the WSSchema must:
|
To save a chunk, the WSSchema must:
|
||||||
1. Mark the chunk as being saved (MarkSaving())
|
1. Mark the chunk as being saved (MarkSaving())
|
||||||
@ -126,34 +128,34 @@ public:
|
|||||||
/** Marks the chunk as failed to load.
|
/** Marks the chunk as failed to load.
|
||||||
If m_ShouldGenerateIfLoadFailed is set, queues the chunk for generating. */
|
If m_ShouldGenerateIfLoadFailed is set, queues the chunk for generating. */
|
||||||
void MarkLoadFailed(void);
|
void MarkLoadFailed(void);
|
||||||
|
|
||||||
/** Gets all chunk data, calls the a_Callback's methods for each data type */
|
/** Gets all chunk data, calls the a_Callback's methods for each data type */
|
||||||
void GetAllData(cChunkDataCallback & a_Callback);
|
void GetAllData(cChunkDataCallback & a_Callback);
|
||||||
|
|
||||||
/** Sets all chunk data as either loaded from the storage or generated.
|
/** Sets all chunk data as either loaded from the storage or generated.
|
||||||
BlockLight and BlockSkyLight are optional, if not present, chunk will be marked as unlighted.
|
BlockLight and BlockSkyLight are optional, if not present, chunk will be marked as unlighted.
|
||||||
Modifies the BlockEntity list in a_SetChunkData - moves the block entities into the chunk. */
|
Modifies the BlockEntity list in a_SetChunkData - moves the block entities into the chunk. */
|
||||||
void SetAllData(cSetChunkData & a_SetChunkData);
|
void SetAllData(cSetChunkData & a_SetChunkData);
|
||||||
|
|
||||||
void SetLight(
|
void SetLight(
|
||||||
const cChunkDef::BlockNibbles & a_BlockLight,
|
const cChunkDef::BlockNibbles & a_BlockLight,
|
||||||
const cChunkDef::BlockNibbles & a_SkyLight
|
const cChunkDef::BlockNibbles & a_SkyLight
|
||||||
);
|
);
|
||||||
|
|
||||||
/** Copies m_BlockData into a_BlockTypes, only the block types */
|
/** Copies m_BlockData into a_BlockTypes, only the block types */
|
||||||
void GetBlockTypes(BLOCKTYPE * a_BlockTypes);
|
void GetBlockTypes(BLOCKTYPE * a_BlockTypes);
|
||||||
|
|
||||||
/** Writes the specified cBlockArea at the coords specified. Note that the coords may extend beyond the chunk! */
|
/** Writes the specified cBlockArea at the coords specified. Note that the coords may extend beyond the chunk! */
|
||||||
void WriteBlockArea(cBlockArea & a_Area, int a_MinBlockX, int a_MinBlockY, int a_MinBlockZ, int a_DataTypes);
|
void WriteBlockArea(cBlockArea & a_Area, int a_MinBlockX, int a_MinBlockY, int a_MinBlockZ, int a_DataTypes);
|
||||||
|
|
||||||
/** Returns true if there is a block entity at the coords specified */
|
/** Returns true if there is a block entity at the coords specified */
|
||||||
bool HasBlockEntityAt(int a_BlockX, int a_BlockY, int a_BlockZ);
|
bool HasBlockEntityAt(int a_BlockX, int a_BlockY, int a_BlockZ);
|
||||||
|
|
||||||
/** Sets or resets the internal flag that prevents chunk from being unloaded.
|
/** Sets or resets the internal flag that prevents chunk from being unloaded.
|
||||||
The flag is cumulative - it can be set multiple times and then needs to be un-set that many times
|
The flag is cumulative - it can be set multiple times and then needs to be un-set that many times
|
||||||
before the chunk is unloadable again. */
|
before the chunk is unloadable again. */
|
||||||
void Stay(bool a_Stay = true);
|
void Stay(bool a_Stay = true);
|
||||||
|
|
||||||
/** Recence all mobs proximities to players in order to know what to do with them */
|
/** Recence all mobs proximities to players in order to know what to do with them */
|
||||||
void CollectMobCensus(cMobCensus & toFill);
|
void CollectMobCensus(cMobCensus & toFill);
|
||||||
|
|
||||||
@ -161,22 +163,22 @@ public:
|
|||||||
void SpawnMobs(cMobSpawner & a_MobSpawner);
|
void SpawnMobs(cMobSpawner & a_MobSpawner);
|
||||||
|
|
||||||
void Tick(std::chrono::milliseconds a_Dt);
|
void Tick(std::chrono::milliseconds a_Dt);
|
||||||
|
|
||||||
/** Ticks a single block. Used by cWorld::TickQueuedBlocks() to tick the queued blocks */
|
/** Ticks a single block. Used by cWorld::TickQueuedBlocks() to tick the queued blocks */
|
||||||
void TickBlock(int a_RelX, int a_RelY, int a_RelZ);
|
void TickBlock(int a_RelX, int a_RelY, int a_RelZ);
|
||||||
|
|
||||||
int GetPosX(void) const { return m_PosX; }
|
int GetPosX(void) const { return m_PosX; }
|
||||||
int GetPosZ(void) const { return m_PosZ; }
|
int GetPosZ(void) const { return m_PosZ; }
|
||||||
|
|
||||||
cWorld * GetWorld(void) const { return m_World; }
|
cWorld * GetWorld(void) const { return m_World; }
|
||||||
|
|
||||||
void SetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, bool a_SendToClients = true);
|
void SetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, bool a_SendToClients = true);
|
||||||
// SetBlock() does a lot of work (heightmap, tickblocks, blockentities) so a BlockIdx version doesn't make sense
|
// SetBlock() does a lot of work (heightmap, tickblocks, blockentities) so a BlockIdx version doesn't make sense
|
||||||
void SetBlock( const Vector3i & a_RelBlockPos, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) { SetBlock( a_RelBlockPos.x, a_RelBlockPos.y, a_RelBlockPos.z, a_BlockType, a_BlockMeta); }
|
void SetBlock( const Vector3i & a_RelBlockPos, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) { SetBlock( a_RelBlockPos.x, a_RelBlockPos.y, a_RelBlockPos.z, a_BlockType, a_BlockMeta); }
|
||||||
|
|
||||||
/** Queues block for ticking (m_ToTickQueue) */
|
/** Queues block for ticking (m_ToTickQueue) */
|
||||||
void QueueTickBlock(int a_RelX, int a_RelY, int a_RelZ);
|
void QueueTickBlock(int a_RelX, int a_RelY, int a_RelZ);
|
||||||
|
|
||||||
/** Queues all 6 neighbors of the specified block for ticking (m_ToTickQueue). If any are outside the chunk, relays the checking to the proper neighboring chunk */
|
/** Queues all 6 neighbors of the specified block for ticking (m_ToTickQueue). If any are outside the chunk, relays the checking to the proper neighboring chunk */
|
||||||
void QueueTickBlockNeighbors(int a_RelX, int a_RelY, int a_RelZ);
|
void QueueTickBlockNeighbors(int a_RelX, int a_RelY, int a_RelZ);
|
||||||
|
|
||||||
@ -185,18 +187,38 @@ public:
|
|||||||
BLOCKTYPE GetBlock(const Vector3i & a_RelCoords) const { return GetBlock(a_RelCoords.x, a_RelCoords.y, a_RelCoords.z); }
|
BLOCKTYPE GetBlock(const Vector3i & a_RelCoords) const { return GetBlock(a_RelCoords.x, a_RelCoords.y, a_RelCoords.z); }
|
||||||
void GetBlockTypeMeta(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta) const;
|
void GetBlockTypeMeta(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta) const;
|
||||||
void GetBlockInfo (int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_Meta, NIBBLETYPE & a_SkyLight, NIBBLETYPE & a_BlockLight);
|
void GetBlockInfo (int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_Meta, NIBBLETYPE & a_SkyLight, NIBBLETYPE & a_BlockLight);
|
||||||
|
|
||||||
|
/** Convert absolute coordinates into relative coordinates.
|
||||||
|
Returns false on failure to obtain a valid chunk. Returns true otherwise.
|
||||||
|
@param a_Position The position you'd like to convert, a_Position need not be in the calling chunk and can safely be out
|
||||||
|
of its bounds, but for best performance, it should not be too far from the calling chunk.
|
||||||
|
@param a_Chunk Returns the chunk in which a_Position is in. If a_Position is within the calling chunk's bounds,
|
||||||
|
returns the calling chunk. For best performance, a_Position shouldn't be too far from the calling chunk.
|
||||||
|
@param a_Rel Returns the converted relative position. Note that it is relative to the returned a_Chunk.
|
||||||
|
The vector will not be modified if the function returns false. */
|
||||||
|
bool GetChunkAndRelByAbsolute(const Vector3d & a_Position, cChunk ** a_Chunk, Vector3i & a_Rel);
|
||||||
|
|
||||||
|
/** Convert absolute coordinates into relative coordinates.
|
||||||
|
Returns false on failure to obtain a valid chunk. Returns true otherwise.
|
||||||
|
@param a_Position The position you'd like to convert, a_Position need not be in the calling chunk and can safely be out
|
||||||
|
of its bounds, but for best performance, it should not be too far from the calling chunk.
|
||||||
|
@param a_Chunk Returns the chunk in which a_Position is in. If a_Position is within the calling chunk's bounds,
|
||||||
|
returns the calling chunk. For best performance, a_Position shouldn't be too far from the calling chunk.
|
||||||
|
@param a_Rel Returns the converted relative position. Note that it is relative to the returned a_Chunk.
|
||||||
|
The vector will not be modified if the function returns false. */
|
||||||
|
bool GetChunkAndRelByAbsolute(const Vector3i & a_Position, cChunk ** a_Chunk, Vector3i & a_Rel);
|
||||||
|
|
||||||
/** Returns the chunk into which the specified block belongs, by walking the neighbors.
|
/** Returns the chunk into which the specified block belongs, by walking the neighbors.
|
||||||
Will return self if appropriate. Returns nullptr if not reachable through neighbors.
|
Will return self if appropriate. Returns nullptr if not reachable through neighbors.
|
||||||
*/
|
*/
|
||||||
cChunk * GetNeighborChunk(int a_BlockX, int a_BlockZ);
|
cChunk * GetNeighborChunk(int a_BlockX, int a_BlockZ);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Returns the chunk into which the relatively-specified block belongs, by walking the neighbors.
|
Returns the chunk into which the relatively-specified block belongs, by walking the neighbors.
|
||||||
Will return self if appropriate. Returns nullptr if not reachable through neighbors.
|
Will return self if appropriate. Returns nullptr if not reachable through neighbors.
|
||||||
*/
|
*/
|
||||||
cChunk * GetRelNeighborChunk(int a_RelX, int a_RelZ);
|
cChunk * GetRelNeighborChunk(int a_RelX, int a_RelZ);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Returns the chunk into which the relatively-specified block belongs.
|
Returns the chunk into which the relatively-specified block belongs.
|
||||||
Also modifies the relative coords from this-relative to return-relative.
|
Also modifies the relative coords from this-relative to return-relative.
|
||||||
@ -204,19 +226,19 @@ public:
|
|||||||
Will try walking the neighbors first; if that fails, will query the chunkmap
|
Will try walking the neighbors first; if that fails, will query the chunkmap
|
||||||
*/
|
*/
|
||||||
cChunk * GetRelNeighborChunkAdjustCoords(int & a_RelX, int & a_RelZ) const;
|
cChunk * GetRelNeighborChunkAdjustCoords(int & a_RelX, int & a_RelZ) const;
|
||||||
|
|
||||||
EMCSBiome GetBiomeAt(int a_RelX, int a_RelZ) const {return cChunkDef::GetBiome(m_BiomeMap, a_RelX, a_RelZ); }
|
EMCSBiome GetBiomeAt(int a_RelX, int a_RelZ) const {return cChunkDef::GetBiome(m_BiomeMap, a_RelX, a_RelZ); }
|
||||||
|
|
||||||
/** Sets the biome at the specified relative coords.
|
/** Sets the biome at the specified relative coords.
|
||||||
Doesn't resend the chunk to clients. */
|
Doesn't resend the chunk to clients. */
|
||||||
void SetBiomeAt(int a_RelX, int a_RelZ, EMCSBiome a_Biome);
|
void SetBiomeAt(int a_RelX, int a_RelZ, EMCSBiome a_Biome);
|
||||||
|
|
||||||
/** Sets the biome in the specified relative coords area. All the coords are inclusive.
|
/** Sets the biome in the specified relative coords area. All the coords are inclusive.
|
||||||
Sends the chunk to all relevant clients. */
|
Sends the chunk to all relevant clients. */
|
||||||
void SetAreaBiome(int a_MinRelX, int a_MaxRelX, int a_MinRelZ, int a_MaxRelZ, EMCSBiome a_Biome);
|
void SetAreaBiome(int a_MinRelX, int a_MaxRelX, int a_MinRelZ, int a_MaxRelZ, EMCSBiome a_Biome);
|
||||||
|
|
||||||
void CollectPickupsByPlayer(cPlayer & a_Player);
|
void CollectPickupsByPlayer(cPlayer & a_Player);
|
||||||
|
|
||||||
/** Sets the sign text. Returns true if successful. Also sends update packets to all clients in the chunk */
|
/** Sets the sign text. Returns true if successful. Also sends update packets to all clients in the chunk */
|
||||||
bool SetSignLines(int a_RelX, int a_RelY, int a_RelZ, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4);
|
bool SetSignLines(int a_RelX, int a_RelY, int a_RelZ, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4);
|
||||||
|
|
||||||
@ -226,20 +248,20 @@ public:
|
|||||||
|
|
||||||
/** Adds a client to the chunk; returns true if added, false if already there */
|
/** Adds a client to the chunk; returns true if added, false if already there */
|
||||||
bool AddClient(cClientHandle * a_Client);
|
bool AddClient(cClientHandle * a_Client);
|
||||||
|
|
||||||
/** Removes the specified client from the chunk; ignored if client not in chunk. */
|
/** Removes the specified client from the chunk; ignored if client not in chunk. */
|
||||||
void RemoveClient(cClientHandle * a_Client);
|
void RemoveClient(cClientHandle * a_Client);
|
||||||
|
|
||||||
/** Returns true if the specified client is present in this chunk. */
|
/** Returns true if the specified client is present in this chunk. */
|
||||||
bool HasClient(cClientHandle * a_Client);
|
bool HasClient(cClientHandle * a_Client);
|
||||||
|
|
||||||
/** Returns true if theres any client in the chunk; false otherwise */
|
/** Returns true if theres any client in the chunk; false otherwise */
|
||||||
bool HasAnyClients(void) const;
|
bool HasAnyClients(void) const;
|
||||||
|
|
||||||
void AddEntity(cEntity * a_Entity);
|
void AddEntity(cEntity * a_Entity);
|
||||||
void RemoveEntity(cEntity * a_Entity);
|
void RemoveEntity(cEntity * a_Entity);
|
||||||
bool HasEntity(UInt32 a_EntityID);
|
bool HasEntity(UInt32 a_EntityID);
|
||||||
|
|
||||||
/** Calls the callback for each entity; returns true if all entities processed, false if the callback aborted by returning true */
|
/** Calls the callback for each entity; returns true if all entities processed, false if the callback aborted by returning true */
|
||||||
bool ForEachEntity(cEntityCallback & a_Callback); // Lua-accessible
|
bool ForEachEntity(cEntityCallback & a_Callback); // Lua-accessible
|
||||||
|
|
||||||
@ -270,10 +292,10 @@ public:
|
|||||||
|
|
||||||
/** Calls the callback for each furnace; returns true if all furnaces processed, false if the callback aborted by returning true */
|
/** Calls the callback for each furnace; returns true if all furnaces processed, false if the callback aborted by returning true */
|
||||||
bool ForEachFurnace(cFurnaceCallback & a_Callback); // Lua-accessible
|
bool ForEachFurnace(cFurnaceCallback & a_Callback); // Lua-accessible
|
||||||
|
|
||||||
/** 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 */
|
/** 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 */
|
||||||
bool DoWithBlockEntityAt(int a_BlockX, int a_BlockY, int a_BlockZ, cBlockEntityCallback & a_Callback); // Lua-acessible
|
bool DoWithBlockEntityAt(int a_BlockX, int a_BlockY, int a_BlockZ, cBlockEntityCallback & a_Callback); // Lua-acessible
|
||||||
|
|
||||||
/** Calls the callback for the beacon at the specified coords; returns false if there's no beacon at those coords, true if found */
|
/** Calls the callback for the beacon at the specified coords; returns false if there's no beacon at those coords, true if found */
|
||||||
bool DoWithBeaconAt(int a_BlockX, int a_BlockY, int a_BlockZ, cBeaconCallback & a_Callback); // Lua-acessible
|
bool DoWithBeaconAt(int a_BlockX, int a_BlockY, int a_BlockZ, cBeaconCallback & a_Callback); // Lua-acessible
|
||||||
|
|
||||||
@ -300,7 +322,7 @@ public:
|
|||||||
|
|
||||||
/** 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 */
|
/** 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 */
|
||||||
bool DoWithCommandBlockAt(int a_BlockX, int a_BlockY, int a_BlockZ, cCommandBlockCallback & a_Callback);
|
bool DoWithCommandBlockAt(int a_BlockX, int a_BlockY, int a_BlockZ, cCommandBlockCallback & a_Callback);
|
||||||
|
|
||||||
/** Calls the callback for the mob head block at the specified coords; returns false if there's no mob head block at those coords or callback returns true, returns true if found */
|
/** Calls the callback for the mob head block at the specified coords; returns false if there's no mob head block at those coords or callback returns true, returns true if found */
|
||||||
bool DoWithMobHeadAt(int a_BlockX, int a_BlockY, int a_BlockZ, cMobHeadCallback & a_Callback);
|
bool DoWithMobHeadAt(int a_BlockX, int a_BlockY, int a_BlockZ, cMobHeadCallback & a_Callback);
|
||||||
|
|
||||||
@ -341,14 +363,14 @@ public:
|
|||||||
void BroadcastSpawnEntity (cEntity & a_Entity, const cClientHandle * a_Exclude = nullptr);
|
void BroadcastSpawnEntity (cEntity & a_Entity, const cClientHandle * a_Exclude = nullptr);
|
||||||
void BroadcastThunderbolt (int a_BlockX, int a_BlockY, int a_BlockZ, const cClientHandle * a_Exclude = nullptr);
|
void BroadcastThunderbolt (int a_BlockX, int a_BlockY, int a_BlockZ, const cClientHandle * a_Exclude = nullptr);
|
||||||
void BroadcastUseBed (const cEntity & a_Entity, int a_BlockX, int a_BlockY, int a_BlockZ);
|
void BroadcastUseBed (const cEntity & a_Entity, int a_BlockX, int a_BlockY, int a_BlockZ);
|
||||||
|
|
||||||
void SendBlockEntity (int a_BlockX, int a_BlockY, int a_BlockZ, cClientHandle & a_Client);
|
void SendBlockEntity (int a_BlockX, int a_BlockY, int a_BlockZ, cClientHandle & a_Client);
|
||||||
|
|
||||||
Vector3i PositionToWorldPosition(const Vector3i & a_RelPos)
|
Vector3i PositionToWorldPosition(const Vector3i & a_RelPos)
|
||||||
{
|
{
|
||||||
return PositionToWorldPosition(a_RelPos.x, a_RelPos.y, a_RelPos.z);
|
return PositionToWorldPosition(a_RelPos.x, a_RelPos.y, a_RelPos.z);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PositionToWorldPosition(int a_RelX, int a_RelY, int a_RelZ, int & a_BlockX, int & a_BlockY, int & a_BlockZ);
|
void PositionToWorldPosition(int a_RelX, int a_RelY, int a_RelZ, int & a_BlockX, int & a_BlockY, int & a_BlockZ);
|
||||||
Vector3i PositionToWorldPosition(int a_RelX, int a_RelY, int a_RelZ);
|
Vector3i PositionToWorldPosition(int a_RelX, int a_RelY, int a_RelZ);
|
||||||
|
|
||||||
@ -357,7 +379,7 @@ public:
|
|||||||
m_IsDirty = true;
|
m_IsDirty = true;
|
||||||
m_IsSaving = false;
|
m_IsSaving = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Sets the blockticking to start at the specified block. Only one blocktick may be set, second call overwrites the first call */
|
/** Sets the blockticking to start at the specified block. Only one blocktick may be set, second call overwrites the first call */
|
||||||
inline void SetNextBlockTick(int a_RelX, int a_RelY, int a_RelZ)
|
inline void SetNextBlockTick(int a_RelX, int a_RelY, int a_RelZ)
|
||||||
{
|
{
|
||||||
@ -365,7 +387,7 @@ public:
|
|||||||
m_BlockTickY = a_RelY;
|
m_BlockTickY = a_RelY;
|
||||||
m_BlockTickZ = a_RelZ;
|
m_BlockTickZ = a_RelZ;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline NIBBLETYPE GetMeta(int a_RelX, int a_RelY, int a_RelZ) const
|
inline NIBBLETYPE GetMeta(int a_RelX, int a_RelY, int a_RelZ) const
|
||||||
{
|
{
|
||||||
return m_ChunkData.GetMeta(a_RelX, a_RelY, a_RelZ);
|
return m_ChunkData.GetMeta(a_RelX, a_RelY, a_RelZ);
|
||||||
@ -377,23 +399,32 @@ public:
|
|||||||
{
|
{
|
||||||
MarkDirty();
|
MarkDirty();
|
||||||
m_IsRedstoneDirty = true;
|
m_IsRedstoneDirty = true;
|
||||||
|
|
||||||
m_PendingSendBlocks.push_back(sSetBlock(m_PosX, m_PosZ, a_RelX, a_RelY, a_RelZ, GetBlock(a_RelX, a_RelY, a_RelZ), a_Meta));
|
m_PendingSendBlocks.push_back(sSetBlock(m_PosX, m_PosZ, a_RelX, a_RelY, a_RelZ, GetBlock(a_RelX, a_RelY, a_RelZ), a_Meta));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Light alterations based on time */
|
||||||
|
NIBBLETYPE GetTimeAlteredLight(NIBBLETYPE a_Skylight) const;
|
||||||
|
|
||||||
|
/** Get the level of artificial light illuminating the block (0 - 15) */
|
||||||
inline NIBBLETYPE GetBlockLight(int a_RelX, int a_RelY, int a_RelZ) const {return m_ChunkData.GetBlockLight(a_RelX, a_RelY, a_RelZ); }
|
inline NIBBLETYPE GetBlockLight(int a_RelX, int a_RelY, int a_RelZ) const {return m_ChunkData.GetBlockLight(a_RelX, a_RelY, a_RelZ); }
|
||||||
|
|
||||||
|
/** Get the level of sky light illuminating the block (0 - 15) independent of daytime. */
|
||||||
inline NIBBLETYPE GetSkyLight (int a_RelX, int a_RelY, int a_RelZ) const {return m_ChunkData.GetSkyLight(a_RelX, a_RelY, a_RelZ); }
|
inline NIBBLETYPE GetSkyLight (int a_RelX, int a_RelY, int a_RelZ) const {return m_ChunkData.GetSkyLight(a_RelX, a_RelY, a_RelZ); }
|
||||||
|
|
||||||
|
/** Get the level of sky light illuminating the block (0 - 15), taking daytime into a account. */
|
||||||
|
inline NIBBLETYPE GetSkyLightAltered (int a_RelX, int a_RelY, int a_RelZ) const {return GetTimeAlteredLight(m_ChunkData.GetSkyLight(a_RelX, a_RelY, a_RelZ)); }
|
||||||
|
|
||||||
/** Same as GetBlock(), but relative coords needn't be in this chunk (uses m_Neighbor-s or m_ChunkMap in such a case); returns true on success */
|
/** Same as GetBlock(), but relative coords needn't be in this chunk (uses m_Neighbor-s or m_ChunkMap in such a case); returns true on success */
|
||||||
bool UnboundedRelGetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta) const;
|
bool UnboundedRelGetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta) const;
|
||||||
|
|
||||||
/** Same as GetBlockType(), but relative coords needn't be in this chunk (uses m_Neighbor-s or m_ChunkMap in such a case); returns true on success */
|
/** Same as GetBlockType(), but relative coords needn't be in this chunk (uses m_Neighbor-s or m_ChunkMap in such a case); returns true on success */
|
||||||
bool UnboundedRelGetBlockType(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE & a_BlockType) const;
|
bool UnboundedRelGetBlockType(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE & a_BlockType) const;
|
||||||
|
|
||||||
/** Same as GetBlockMeta(), but relative coords needn't be in this chunk (uses m_Neighbor-s or m_ChunkMap in such a case); returns true on success */
|
/** Same as GetBlockMeta(), but relative coords needn't be in this chunk (uses m_Neighbor-s or m_ChunkMap in such a case); returns true on success */
|
||||||
bool UnboundedRelGetBlockMeta(int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE & a_BlockMeta) const;
|
bool UnboundedRelGetBlockMeta(int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE & a_BlockMeta) const;
|
||||||
|
|
||||||
/** Same as GetBlockBlockLight(), but relative coords needn't be in this chunk (uses m_Neighbor-s or m_ChunkMap in such a case); returns true on success */
|
/** Same as GetBlockBlockLight(), but relative coords needn't be in this chunk (uses m_Neighbor-s or m_ChunkMap in such a case); returns true on success */
|
||||||
bool UnboundedRelGetBlockBlockLight(int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE & a_BlockLight) const;
|
bool UnboundedRelGetBlockBlockLight(int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE & a_BlockLight) const;
|
||||||
|
|
||||||
@ -408,12 +439,10 @@ public:
|
|||||||
|
|
||||||
/** Same as FastSetBlock(), but relative coords needn't be in this chunk (uses m_Neighbor-s or m_ChunkMap in such a case); returns true on success */
|
/** Same as FastSetBlock(), but relative coords needn't be in this chunk (uses m_Neighbor-s or m_ChunkMap in such a case); returns true on success */
|
||||||
bool UnboundedRelFastSetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta);
|
bool UnboundedRelFastSetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta);
|
||||||
|
|
||||||
/** Same as QueueTickBlock(), but relative coords needn't be in this chunk (uses m_Neighbor-s in such a case), ignores unsuccessful attempts */
|
/** Same as QueueTickBlock(), but relative coords needn't be in this chunk (uses m_Neighbor-s in such a case), ignores unsuccessful attempts */
|
||||||
void UnboundedQueueTickBlock(int a_RelX, int a_RelY, int a_RelZ);
|
void UnboundedQueueTickBlock(int a_RelX, int a_RelY, int a_RelZ);
|
||||||
|
|
||||||
/** Light alterations based on time */
|
|
||||||
NIBBLETYPE GetTimeAlteredLight(NIBBLETYPE a_Skylight) const;
|
|
||||||
|
|
||||||
|
|
||||||
// Per-chunk simulator data:
|
// Per-chunk simulator data:
|
||||||
@ -429,11 +458,11 @@ public:
|
|||||||
|
|
||||||
cBlockEntity * GetBlockEntity(int a_BlockX, int a_BlockY, int a_BlockZ);
|
cBlockEntity * GetBlockEntity(int a_BlockX, int a_BlockY, int a_BlockZ);
|
||||||
cBlockEntity * GetBlockEntity(const Vector3i & a_BlockPos) { return GetBlockEntity(a_BlockPos.x, a_BlockPos.y, a_BlockPos.z); }
|
cBlockEntity * GetBlockEntity(const Vector3i & a_BlockPos) { return GetBlockEntity(a_BlockPos.x, a_BlockPos.y, a_BlockPos.z); }
|
||||||
|
|
||||||
/** Returns true if the chunk should be ticked in the tick-thread.
|
/** Returns true if the chunk should be ticked in the tick-thread.
|
||||||
Checks if there are any clients and if the always-tick flag is set */
|
Checks if there are any clients and if the always-tick flag is set */
|
||||||
bool ShouldBeTicked(void) const;
|
bool ShouldBeTicked(void) const;
|
||||||
|
|
||||||
/** Increments (a_AlwaysTicked == true) or decrements (false) the m_AlwaysTicked counter.
|
/** Increments (a_AlwaysTicked == true) or decrements (false) the m_AlwaysTicked counter.
|
||||||
If the m_AlwaysTicked counter is greater than zero, the chunk is ticked in the tick-thread regardless of
|
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.
|
whether it has any clients or not.
|
||||||
@ -450,7 +479,7 @@ public:
|
|||||||
private:
|
private:
|
||||||
|
|
||||||
friend class cChunkMap;
|
friend class cChunkMap;
|
||||||
|
|
||||||
struct sSetBlockQueueItem
|
struct sSetBlockQueueItem
|
||||||
{
|
{
|
||||||
Int64 m_Tick;
|
Int64 m_Tick;
|
||||||
@ -458,7 +487,7 @@ private:
|
|||||||
BLOCKTYPE m_BlockType;
|
BLOCKTYPE m_BlockType;
|
||||||
NIBBLETYPE m_BlockMeta;
|
NIBBLETYPE m_BlockMeta;
|
||||||
BLOCKTYPE m_PreviousType;
|
BLOCKTYPE m_PreviousType;
|
||||||
|
|
||||||
sSetBlockQueueItem(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, Int64 a_Tick, BLOCKTYPE a_PreviousBlockType) :
|
sSetBlockQueueItem(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, Int64 a_Tick, BLOCKTYPE a_PreviousBlockType) :
|
||||||
m_Tick(a_Tick), m_RelX(a_RelX), m_RelY(a_RelY), m_RelZ(a_RelZ), m_BlockType(a_BlockType), m_BlockMeta(a_BlockMeta), m_PreviousType(a_PreviousBlockType)
|
m_Tick(a_Tick), m_RelX(a_RelX), m_RelY(a_RelY), m_RelZ(a_RelZ), m_BlockType(a_BlockType), m_BlockMeta(a_BlockMeta), m_PreviousType(a_PreviousBlockType)
|
||||||
{
|
{
|
||||||
@ -466,7 +495,7 @@ private:
|
|||||||
} ;
|
} ;
|
||||||
|
|
||||||
typedef std::vector<sSetBlockQueueItem> sSetBlockQueueVector;
|
typedef std::vector<sSetBlockQueueItem> sSetBlockQueueVector;
|
||||||
|
|
||||||
|
|
||||||
/** Holds the presence status of the chunk - if it is present, or in the loader / generator queue, or unloaded */
|
/** Holds the presence status of the chunk - if it is present, or in the loader / generator queue, or unloaded */
|
||||||
ePresence m_Presence;
|
ePresence m_Presence;
|
||||||
@ -478,15 +507,15 @@ private:
|
|||||||
bool m_IsDirty; // True if the chunk has changed since it was last saved
|
bool m_IsDirty; // True if the chunk has changed since it was last saved
|
||||||
bool m_IsSaving; // True if the chunk is being saved
|
bool m_IsSaving; // True if the chunk is being saved
|
||||||
bool m_HasLoadFailed; // True if chunk failed to load and hasn't been generated yet since then
|
bool m_HasLoadFailed; // True if chunk failed to load and hasn't been generated yet since then
|
||||||
|
|
||||||
std::vector<Vector3i> m_ToTickBlocks;
|
std::vector<Vector3i> m_ToTickBlocks;
|
||||||
sSetBlockVector m_PendingSendBlocks; ///< Blocks that have changed and need to be sent to all clients
|
sSetBlockVector m_PendingSendBlocks; ///< Blocks that have changed and need to be sent to all clients
|
||||||
|
|
||||||
// A critical section is not needed, because all chunk access is protected by its parent ChunkMap's csLayers
|
// A critical section is not needed, because all chunk access is protected by its parent ChunkMap's csLayers
|
||||||
std::vector<cClientHandle *> m_LoadedByClient;
|
std::vector<cClientHandle *> m_LoadedByClient;
|
||||||
cEntityList m_Entities;
|
cEntityList m_Entities;
|
||||||
cBlockEntityList m_BlockEntities;
|
cBlockEntityList m_BlockEntities;
|
||||||
|
|
||||||
/** Number of times the chunk has been requested to stay (by various cChunkStay objects); if zero, the chunk can be unloaded */
|
/** Number of times the chunk has been requested to stay (by various cChunkStay objects); if zero, the chunk can be unloaded */
|
||||||
int m_StayCount;
|
int m_StayCount;
|
||||||
|
|
||||||
@ -500,12 +529,12 @@ private:
|
|||||||
cChunkDef::BiomeMap m_BiomeMap;
|
cChunkDef::BiomeMap m_BiomeMap;
|
||||||
|
|
||||||
int m_BlockTickX, m_BlockTickY, m_BlockTickZ;
|
int m_BlockTickX, m_BlockTickY, m_BlockTickZ;
|
||||||
|
|
||||||
cChunk * m_NeighborXM; // Neighbor at [X - 1, Z]
|
cChunk * m_NeighborXM; // Neighbor at [X - 1, Z]
|
||||||
cChunk * m_NeighborXP; // Neighbor at [X + 1, Z]
|
cChunk * m_NeighborXP; // Neighbor at [X + 1, Z]
|
||||||
cChunk * m_NeighborZM; // Neighbor at [X, Z - 1]
|
cChunk * m_NeighborZM; // Neighbor at [X, Z - 1]
|
||||||
cChunk * m_NeighborZP; // Neighbor at [X, Z + 1]
|
cChunk * m_NeighborZP; // Neighbor at [X, Z + 1]
|
||||||
|
|
||||||
// Per-chunk simulator data:
|
// Per-chunk simulator data:
|
||||||
cFireSimulatorChunkData m_FireSimulatorData;
|
cFireSimulatorChunkData m_FireSimulatorData;
|
||||||
cFluidSimulatorData * m_WaterSimulatorData;
|
cFluidSimulatorData * m_WaterSimulatorData;
|
||||||
@ -517,12 +546,12 @@ private:
|
|||||||
|
|
||||||
/** Indicates if simulate-once blocks should be updated by the redstone simulator */
|
/** Indicates if simulate-once blocks should be updated by the redstone simulator */
|
||||||
bool m_IsRedstoneDirty;
|
bool m_IsRedstoneDirty;
|
||||||
|
|
||||||
/** If greater than zero, the chunk is ticked even if it has no clients.
|
/** If greater than zero, the chunk is ticked even if it has no clients.
|
||||||
Manipulated by the SetAlwaysTicked() function, allows for nested calls of the function.
|
Manipulated by the SetAlwaysTicked() function, allows for nested calls of the function.
|
||||||
This is the support for plugin-accessible chunk tick forcing. */
|
This is the support for plugin-accessible chunk tick forcing. */
|
||||||
int m_AlwaysTicked;
|
int m_AlwaysTicked;
|
||||||
|
|
||||||
|
|
||||||
// Pick up a random block of this chunk
|
// Pick up a random block of this chunk
|
||||||
void GetRandomBlockCoords(int & a_X, int & a_Y, int & a_Z);
|
void GetRandomBlockCoords(int & a_X, int & a_Y, int & a_Z);
|
||||||
@ -533,31 +562,31 @@ private:
|
|||||||
|
|
||||||
/** Creates a block entity for each block that needs a block entity and doesn't have one in the list */
|
/** Creates a block entity for each block that needs a block entity and doesn't have one in the list */
|
||||||
void CreateBlockEntities(void);
|
void CreateBlockEntities(void);
|
||||||
|
|
||||||
/** Wakes up each simulator for its specific blocks; through all the blocks in the chunk */
|
/** Wakes up each simulator for its specific blocks; through all the blocks in the chunk */
|
||||||
void WakeUpSimulators(void);
|
void WakeUpSimulators(void);
|
||||||
|
|
||||||
/** Sends m_PendingSendBlocks to all clients */
|
/** Sends m_PendingSendBlocks to all clients */
|
||||||
void BroadcastPendingBlockChanges(void);
|
void BroadcastPendingBlockChanges(void);
|
||||||
|
|
||||||
/** Checks the block scheduled for checking in m_ToTickBlocks[] */
|
/** Checks the block scheduled for checking in m_ToTickBlocks[] */
|
||||||
void CheckBlocks();
|
void CheckBlocks();
|
||||||
|
|
||||||
/** Ticks several random blocks in the chunk */
|
/** Ticks several random blocks in the chunk */
|
||||||
void TickBlocks(void);
|
void TickBlocks(void);
|
||||||
|
|
||||||
/** Adds snow to the top of snowy biomes and hydrates farmland / fills cauldrons in rainy biomes */
|
/** Adds snow to the top of snowy biomes and hydrates farmland / fills cauldrons in rainy biomes */
|
||||||
void ApplyWeatherToTop(void);
|
void ApplyWeatherToTop(void);
|
||||||
|
|
||||||
/** Grows sugarcane by the specified number of blocks, but no more than 3 blocks high (used by both bonemeal and ticking) */
|
/** Grows sugarcane by the specified number of blocks, but no more than 3 blocks high (used by both bonemeal and ticking) */
|
||||||
void GrowSugarcane (int a_RelX, int a_RelY, int a_RelZ, int a_NumBlocks);
|
void GrowSugarcane (int a_RelX, int a_RelY, int a_RelZ, int a_NumBlocks);
|
||||||
|
|
||||||
/** Grows cactus by the specified number of blocks, but no more than 3 blocks high (used by both bonemeal and ticking) */
|
/** Grows cactus by the specified number of blocks, but no more than 3 blocks high (used by both bonemeal and ticking) */
|
||||||
void GrowCactus (int a_RelX, int a_RelY, int a_RelZ, int a_NumBlocks);
|
void GrowCactus (int a_RelX, int a_RelY, int a_RelZ, int a_NumBlocks);
|
||||||
|
|
||||||
/** Grows a melon or a pumpkin next to the block specified (assumed to be the stem) */
|
/** Grows a melon or a pumpkin next to the block specified (assumed to be the stem) */
|
||||||
void GrowMelonPumpkin(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType, MTRand & a_Random);
|
void GrowMelonPumpkin(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType, MTRand & a_Random);
|
||||||
|
|
||||||
/** Called by Tick() when an entity moves out of this chunk into a neighbor; moves the entity and sends spawn / despawn packet to clients */
|
/** Called by Tick() when an entity moves out of this chunk into a neighbor; moves the entity and sends spawn / despawn packet to clients */
|
||||||
void MoveEntityToNewChunk(cEntity * a_Entity);
|
void MoveEntityToNewChunk(cEntity * a_Entity);
|
||||||
};
|
};
|
||||||
|
@ -37,7 +37,6 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class cWorld;
|
class cWorld;
|
||||||
class cClientHandle;
|
class cClientHandle;
|
||||||
class cPlayer;
|
class cPlayer;
|
||||||
|
@ -36,11 +36,11 @@ void cAggressiveMonster::InStateChasing(std::chrono::milliseconds a_Dt, cChunk &
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cAggressiveMonster::EventSeePlayer(cEntity * a_Entity)
|
void cAggressiveMonster::EventSeePlayer(cEntity * a_Entity, cChunk & a_Chunk)
|
||||||
{
|
{
|
||||||
if (!static_cast<cPlayer *>(a_Entity)->IsGameModeCreative())
|
if (!static_cast<cPlayer *>(a_Entity)->IsGameModeCreative())
|
||||||
{
|
{
|
||||||
super::EventSeePlayer(a_Entity);
|
super::EventSeePlayer(a_Entity, a_Chunk);
|
||||||
m_EMState = CHASING;
|
m_EMState = CHASING;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -59,7 +59,7 @@ void cAggressiveMonster::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
CheckEventSeePlayer();
|
CheckEventSeePlayer(a_Chunk);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_Target == nullptr)
|
if (m_Target == nullptr)
|
||||||
|
@ -19,7 +19,7 @@ public:
|
|||||||
virtual void Tick (std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override;
|
virtual void Tick (std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override;
|
||||||
virtual void InStateChasing(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override;
|
virtual void InStateChasing(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override;
|
||||||
|
|
||||||
virtual void EventSeePlayer(cEntity *) override;
|
virtual void EventSeePlayer(cEntity * a_Player, cChunk & a_Chunk) override;
|
||||||
|
|
||||||
/** Try to perform attack
|
/** Try to perform attack
|
||||||
returns true if attack was deemed successful (hit player, fired projectile, creeper exploded, etc.) even if it didn't actually do damage
|
returns true if attack was deemed successful (hit player, fired projectile, creeper exploded, etc.) even if it didn't actually do damage
|
||||||
|
@ -28,32 +28,32 @@ public:
|
|||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector3d Direction = m_EndermanPos - a_Player->GetPosition();
|
Vector3d Direction = m_EndermanPos - a_Player->GetPosition();
|
||||||
|
|
||||||
// Don't check players who are more then SightDistance (64) blocks away
|
// Don't check players who are more then SightDistance (64) blocks away
|
||||||
if (Direction.Length() > m_SightDistance)
|
if (Direction.Length() > m_SightDistance)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Don't check if the player has a pumpkin on his head
|
// Don't check if the player has a pumpkin on his head
|
||||||
if (a_Player->GetEquippedHelmet().m_ItemType == E_BLOCK_PUMPKIN)
|
if (a_Player->GetEquippedHelmet().m_ItemType == E_BLOCK_PUMPKIN)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Vector3d LookVector = a_Player->GetLookVector();
|
Vector3d LookVector = a_Player->GetLookVector();
|
||||||
double dot = Direction.Dot(LookVector);
|
double dot = Direction.Dot(LookVector);
|
||||||
|
|
||||||
// 0.09 rad ~ 5 degrees
|
// 0.09 rad ~ 5 degrees
|
||||||
// If the player's crosshair is within 5 degrees of the enderman, it counts as looking
|
// If the player's crosshair is within 5 degrees of the enderman, it counts as looking
|
||||||
if (dot <= cos(0.09))
|
if (dot <= cos(0.09))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
cTracer LineOfSight(a_Player->GetWorld());
|
cTracer LineOfSight(a_Player->GetWorld());
|
||||||
if (LineOfSight.Trace(m_EndermanPos, Direction, static_cast<int>(Direction.Length())))
|
if (LineOfSight.Trace(m_EndermanPos, Direction, static_cast<int>(Direction.Length())))
|
||||||
{
|
{
|
||||||
@ -64,7 +64,7 @@ public:
|
|||||||
m_Player = a_Player;
|
m_Player = a_Player;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
cPlayer * GetPlayer(void) const { return m_Player; }
|
cPlayer * GetPlayer(void) const { return m_Player; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@ -102,7 +102,7 @@ void cEnderman::GetDrops(cItems & a_Drops, cEntity * a_Killer)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cEnderman::CheckEventSeePlayer()
|
void cEnderman::CheckEventSeePlayer(cChunk & a_Chunk)
|
||||||
{
|
{
|
||||||
if (m_Target != nullptr)
|
if (m_Target != nullptr)
|
||||||
{
|
{
|
||||||
@ -114,7 +114,7 @@ void cEnderman::CheckEventSeePlayer()
|
|||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ASSERT(Callback.GetPlayer() != nullptr);
|
ASSERT(Callback.GetPlayer() != nullptr);
|
||||||
|
|
||||||
if (!CheckLight())
|
if (!CheckLight())
|
||||||
@ -126,7 +126,7 @@ void cEnderman::CheckEventSeePlayer()
|
|||||||
|
|
||||||
if (!Callback.GetPlayer()->IsGameModeCreative())
|
if (!Callback.GetPlayer()->IsGameModeCreative())
|
||||||
{
|
{
|
||||||
cMonster::EventSeePlayer(Callback.GetPlayer());
|
cMonster::EventSeePlayer(Callback.GetPlayer(), a_Chunk);
|
||||||
m_EMState = CHASING;
|
m_EMState = CHASING;
|
||||||
m_bIsScreaming = true;
|
m_bIsScreaming = true;
|
||||||
GetWorld()->BroadcastEntityMetadata(*this);
|
GetWorld()->BroadcastEntityMetadata(*this);
|
||||||
@ -145,7 +145,7 @@ void cEnderman::CheckEventLostPlayer(void)
|
|||||||
EventLosePlayer();
|
EventLosePlayer();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -11,14 +11,14 @@ class cEnderman :
|
|||||||
public cPassiveAggressiveMonster
|
public cPassiveAggressiveMonster
|
||||||
{
|
{
|
||||||
typedef cPassiveAggressiveMonster super;
|
typedef cPassiveAggressiveMonster super;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
cEnderman(void);
|
cEnderman(void);
|
||||||
|
|
||||||
CLASS_PROTODEF(cEnderman)
|
CLASS_PROTODEF(cEnderman)
|
||||||
|
|
||||||
virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = nullptr) override;
|
virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = nullptr) override;
|
||||||
virtual void CheckEventSeePlayer(void) override;
|
virtual void CheckEventSeePlayer(cChunk & a_Chunk) override;
|
||||||
virtual void CheckEventLostPlayer(void) override;
|
virtual void CheckEventLostPlayer(void) override;
|
||||||
virtual void EventLosePlayer(void) override;
|
virtual void EventLosePlayer(void) override;
|
||||||
virtual void Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override;
|
virtual void Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override;
|
||||||
|
@ -560,14 +560,14 @@ void cMonster::OnRightClicked(cPlayer & a_Player)
|
|||||||
|
|
||||||
// Checks to see if EventSeePlayer should be fired
|
// Checks to see if EventSeePlayer should be fired
|
||||||
// monster sez: Do I see the player
|
// monster sez: Do I see the player
|
||||||
void cMonster::CheckEventSeePlayer(void)
|
void cMonster::CheckEventSeePlayer(cChunk & a_Chunk)
|
||||||
{
|
{
|
||||||
// TODO: Rewrite this to use cWorld's DoWithPlayers()
|
// TODO: Rewrite this to use cWorld's DoWithPlayers()
|
||||||
cPlayer * Closest = m_World->FindClosestPlayer(GetPosition(), static_cast<float>(m_SightDistance), false);
|
cPlayer * Closest = m_World->FindClosestPlayer(GetPosition(), static_cast<float>(m_SightDistance), false);
|
||||||
|
|
||||||
if (Closest != nullptr)
|
if (Closest != nullptr)
|
||||||
{
|
{
|
||||||
EventSeePlayer(Closest);
|
EventSeePlayer(Closest, a_Chunk);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -596,7 +596,7 @@ void cMonster::CheckEventLostPlayer(void)
|
|||||||
|
|
||||||
// What to do if player is seen
|
// What to do if player is seen
|
||||||
// default to change state to chasing
|
// default to change state to chasing
|
||||||
void cMonster::EventSeePlayer(cEntity * a_SeenPlayer)
|
void cMonster::EventSeePlayer(cEntity * a_SeenPlayer, cChunk & a_Chunk)
|
||||||
{
|
{
|
||||||
m_Target = a_SeenPlayer;
|
m_Target = a_SeenPlayer;
|
||||||
}
|
}
|
||||||
|
@ -67,8 +67,8 @@ public:
|
|||||||
eFamily GetMobFamily(void) const;
|
eFamily GetMobFamily(void) const;
|
||||||
// tolua_end
|
// tolua_end
|
||||||
|
|
||||||
virtual void CheckEventSeePlayer(void);
|
virtual void CheckEventSeePlayer(cChunk & a_Chunk);
|
||||||
virtual void EventSeePlayer(cEntity * a_Player);
|
virtual void EventSeePlayer(cEntity * a_Entity, cChunk & a_Chunk);
|
||||||
|
|
||||||
/** Reads the monster configuration for the specified monster name and assigns it to this object. */
|
/** Reads the monster configuration for the specified monster name and assigns it to this object. */
|
||||||
void GetMonsterConfig(const AString & a_Name);
|
void GetMonsterConfig(const AString & a_Name);
|
||||||
|
@ -25,7 +25,7 @@ bool cPassiveAggressiveMonster::DoTakeDamage(TakeDamageInfo & a_TDI)
|
|||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((m_Target != nullptr) && (m_Target->IsPlayer()))
|
if ((m_Target != nullptr) && (m_Target->IsPlayer()))
|
||||||
{
|
{
|
||||||
if (!static_cast<cPlayer *>(m_Target)->IsGameModeCreative())
|
if (!static_cast<cPlayer *>(m_Target)->IsGameModeCreative())
|
||||||
@ -39,7 +39,7 @@ bool cPassiveAggressiveMonster::DoTakeDamage(TakeDamageInfo & a_TDI)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cPassiveAggressiveMonster::EventSeePlayer(cEntity *)
|
void cPassiveAggressiveMonster::EventSeePlayer(cEntity *, cChunk & a_Chunk)
|
||||||
{
|
{
|
||||||
// don't do anything, neutral mobs don't react to just seeing the player
|
// don't do anything, neutral mobs don't react to just seeing the player
|
||||||
}
|
}
|
||||||
|
@ -11,12 +11,12 @@ class cPassiveAggressiveMonster :
|
|||||||
public cAggressiveMonster
|
public cAggressiveMonster
|
||||||
{
|
{
|
||||||
typedef cAggressiveMonster super;
|
typedef cAggressiveMonster super;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
cPassiveAggressiveMonster(const AString & a_ConfigName, eMonsterType a_MobType, const AString & a_SoundHurt, const AString & a_SoundDeath, double a_Width, double a_Height);
|
cPassiveAggressiveMonster(const AString & a_ConfigName, eMonsterType a_MobType, const AString & a_SoundHurt, const AString & a_SoundDeath, double a_Width, double a_Height);
|
||||||
|
|
||||||
virtual bool DoTakeDamage(TakeDamageInfo & a_TDI) override;
|
virtual bool DoTakeDamage(TakeDamageInfo & a_TDI) override;
|
||||||
virtual void EventSeePlayer(cEntity *) override;
|
virtual void EventSeePlayer(cEntity *, cChunk & a_Chunk) override;
|
||||||
} ;
|
} ;
|
||||||
|
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
#include "../World.h"
|
#include "../World.h"
|
||||||
#include "../Entities/Player.h"
|
#include "../Entities/Player.h"
|
||||||
|
#include "../Chunk.h"
|
||||||
|
|
||||||
|
|
||||||
cSpider::cSpider(void) :
|
cSpider::cSpider(void) :
|
||||||
@ -35,17 +35,22 @@ void cSpider::GetDrops(cItems & a_Drops, cEntity * a_Killer)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cSpider::EventSeePlayer(cEntity * a_Entity)
|
void cSpider::EventSeePlayer(cEntity * a_Entity, cChunk & a_Chunk)
|
||||||
{
|
{
|
||||||
if (!GetWorld()->IsChunkLighted(GetChunkX(), GetChunkZ()))
|
if (!GetWorld()->IsChunkLighted(GetChunkX(), GetChunkZ()))
|
||||||
{
|
{
|
||||||
GetWorld()->QueueLightChunk(GetChunkX(), GetChunkZ());
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!static_cast<cPlayer *>(a_Entity)->IsGameModeCreative() && (GetWorld()->GetBlockBlockLight(this->GetPosition()) <= 9))
|
PREPARE_REL_AND_CHUNK(GetPosition(), a_Chunk);
|
||||||
|
if (!RelSuccess)
|
||||||
{
|
{
|
||||||
super::EventSeePlayer(a_Entity);
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!static_cast<cPlayer *>(a_Entity)->IsGameModeCreative() && (Chunk->GetSkyLightAltered(Rel.x, Rel.y, Rel.z) <= 9))
|
||||||
|
{
|
||||||
|
super::EventSeePlayer(a_Entity, a_Chunk);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,14 +11,14 @@ class cSpider :
|
|||||||
public cAggressiveMonster
|
public cAggressiveMonster
|
||||||
{
|
{
|
||||||
typedef cAggressiveMonster super;
|
typedef cAggressiveMonster super;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
cSpider(void);
|
cSpider(void);
|
||||||
|
|
||||||
CLASS_PROTODEF(cSpider)
|
CLASS_PROTODEF(cSpider)
|
||||||
|
|
||||||
virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = nullptr) override;
|
virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = nullptr) override;
|
||||||
virtual void EventSeePlayer(cEntity *) override;
|
virtual void EventSeePlayer(cEntity *, cChunk & a_Chunk) override;
|
||||||
virtual bool DoTakeDamage(TakeDamageInfo & a_TDI) override;
|
virtual bool DoTakeDamage(TakeDamageInfo & a_TDI) override;
|
||||||
} ;
|
} ;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user