Made grass spreader prettier
This commit is contained in:
parent
58ab289b56
commit
e205d4109b
@ -52,71 +52,21 @@ public:
|
||||
a_Chunk.GetWorld()->QueueLightChunk(a_Chunk.GetPosX(), a_Chunk.GetPosZ());
|
||||
return;
|
||||
}
|
||||
auto AbovePos = a_RelPos.addedY(1);
|
||||
if (cChunkDef::IsValidHeight(AbovePos.y))
|
||||
{
|
||||
// Grass turns back to dirt when the block Above it is not transparent or water.
|
||||
// It does not turn to dirt when a snow layer is Above.
|
||||
auto Above = a_Chunk.GetBlock(AbovePos);
|
||||
if (
|
||||
(Above != E_BLOCK_SNOW) &&
|
||||
(!cBlockInfo::IsTransparent(Above) || IsBlockWater(Above)))
|
||||
{
|
||||
a_Chunk.FastSetBlock(a_RelPos, E_BLOCK_DIRT, E_META_DIRT_NORMAL);
|
||||
return;
|
||||
}
|
||||
|
||||
// Make sure that there is enough light at the source block to spread
|
||||
auto light = std::max(a_Chunk.GetBlockLight(AbovePos), a_Chunk.GetTimeAlteredLight(a_Chunk.GetSkyLight(AbovePos)));
|
||||
if (light < 9)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (!cBlockGrassHandler::TrySurvive(a_Chunk, a_RelPos))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Grass spreads to adjacent dirt blocks:
|
||||
auto & rand = GetRandomProvider();
|
||||
for (int i = 0; i < 2; i++) // Pick two blocks to grow to
|
||||
for (unsigned i = 0; i < 2; i++) // Pick two blocks to grow to
|
||||
{
|
||||
int OfsX = rand.RandInt(-1, 1);
|
||||
int OfsY = rand.RandInt(-3, 1);
|
||||
int OfsZ = rand.RandInt(-1, 1);
|
||||
auto & Random = GetRandomProvider();
|
||||
int OfsX = Random.RandInt(-1, 1);
|
||||
int OfsY = Random.RandInt(-3, 1);
|
||||
int OfsZ = Random.RandInt(-1, 1);
|
||||
|
||||
BLOCKTYPE DestBlock;
|
||||
NIBBLETYPE DestMeta;
|
||||
auto Pos = a_RelPos + Vector3i(OfsX, OfsY, OfsZ);
|
||||
if (!cChunkDef::IsValidHeight(Pos.y))
|
||||
{
|
||||
// Y Coord out of range
|
||||
continue;
|
||||
}
|
||||
auto Chunk = a_Chunk.GetRelNeighborChunkAdjustCoords(Pos);
|
||||
if (Chunk == nullptr)
|
||||
{
|
||||
// Unloaded chunk
|
||||
continue;
|
||||
}
|
||||
Chunk->GetBlockTypeMeta(Pos, DestBlock, DestMeta);
|
||||
if ((DestBlock != E_BLOCK_DIRT) || (DestMeta != E_META_DIRT_NORMAL))
|
||||
{
|
||||
// Not a regular dirt block
|
||||
continue;
|
||||
}
|
||||
auto AboveDestPos = Pos.addedY(1);
|
||||
auto AboveBlockType = Chunk->GetBlock(AboveDestPos);
|
||||
auto Light = std::max(Chunk->GetBlockLight(AboveDestPos), Chunk->GetTimeAlteredLight(Chunk->GetSkyLight(AboveDestPos)));
|
||||
if ((Light > 4) &&
|
||||
cBlockInfo::IsTransparent(AboveBlockType) &&
|
||||
(!IsBlockLava(AboveBlockType)) &&
|
||||
(!IsBlockWaterOrIce(AboveBlockType))
|
||||
)
|
||||
{
|
||||
auto AbsPos = Chunk->RelativeToAbsolute(Pos);
|
||||
if (!cRoot::Get()->GetPluginManager()->CallHookBlockSpread(*Chunk->GetWorld(), AbsPos.x, AbsPos.y, AbsPos.z, ssGrassSpread))
|
||||
{
|
||||
Chunk->FastSetBlock(Pos, E_BLOCK_GRASS, 0);
|
||||
}
|
||||
}
|
||||
cBlockGrassHandler::TryThrive(a_Chunk, a_RelPos + Vector3i(OfsX, OfsY, OfsZ));
|
||||
} // for i - repeat twice
|
||||
}
|
||||
|
||||
@ -124,13 +74,89 @@ public:
|
||||
|
||||
|
||||
|
||||
/** Check if conditions are favourable to a grass block at the given position.
|
||||
If they are not, the grass dies and is turned to dirt.
|
||||
Returns whether conditions are so good that the grass can try to spread to neighbours. */
|
||||
static bool TrySurvive(cChunk & a_Chunk, const Vector3i a_RelPos)
|
||||
{
|
||||
const auto AbovePos = a_RelPos.addedY(1);
|
||||
if (!cChunkDef::IsValidHeight(AbovePos.y))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// Grass turns back to dirt when the block Above it is not transparent or water.
|
||||
// It does not turn to dirt when a snow layer is Above.
|
||||
const auto Above = a_Chunk.GetBlock(AbovePos);
|
||||
if (
|
||||
(Above != E_BLOCK_SNOW) &&
|
||||
(!cBlockInfo::IsTransparent(Above) || IsBlockWater(Above)))
|
||||
{
|
||||
a_Chunk.FastSetBlock(a_RelPos, E_BLOCK_DIRT, E_META_DIRT_NORMAL);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Make sure that there is enough light at the source block to spread
|
||||
const auto Light = std::max(a_Chunk.GetBlockLight(AbovePos), a_Chunk.GetSkyLightAltered(AbovePos));
|
||||
return (Light >= 9);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/** Attempt to spread grass to a block at the given position. */
|
||||
static void TryThrive(cChunk & a_Chunk, Vector3i a_RelPos)
|
||||
{
|
||||
if (!cChunkDef::IsValidHeight(a_RelPos.y))
|
||||
{
|
||||
// Y Coord out of range
|
||||
return;
|
||||
}
|
||||
|
||||
auto Chunk = a_Chunk.GetRelNeighborChunkAdjustCoords(a_RelPos);
|
||||
if (Chunk == nullptr)
|
||||
{
|
||||
// Unloaded chunk
|
||||
return;
|
||||
}
|
||||
|
||||
BLOCKTYPE DestBlock;
|
||||
NIBBLETYPE DestMeta;
|
||||
Chunk->GetBlockTypeMeta(a_RelPos, DestBlock, DestMeta);
|
||||
|
||||
if ((DestBlock != E_BLOCK_DIRT) || (DestMeta != E_META_DIRT_NORMAL))
|
||||
{
|
||||
// Not a regular dirt block
|
||||
return;
|
||||
}
|
||||
|
||||
const auto AbovePos = a_RelPos.addedY(1);
|
||||
const auto Above = Chunk->GetBlock(AbovePos);
|
||||
const auto Light = std::max(Chunk->GetBlockLight(AbovePos), Chunk->GetSkyLightAltered(AbovePos));
|
||||
|
||||
if (
|
||||
(Light > 4) &&
|
||||
cBlockInfo::IsTransparent(Above) &&
|
||||
!IsBlockLava(Above) &&
|
||||
!IsBlockWaterOrIce(Above)
|
||||
)
|
||||
{
|
||||
const auto AbsPos = Chunk->RelativeToAbsolute(a_RelPos);
|
||||
if (!cRoot::Get()->GetPluginManager()->CallHookBlockSpread(*Chunk->GetWorld(), AbsPos.x, AbsPos.y, AbsPos.z, ssGrassSpread))
|
||||
{
|
||||
Chunk->FastSetBlock(a_RelPos, E_BLOCK_GRASS, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) override
|
||||
{
|
||||
UNUSED(a_Meta);
|
||||
return 1;
|
||||
}
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -394,8 +394,8 @@ void cProtocol_1_11_0::SendSpawnMob(const cMonster & a_Mob)
|
||||
Pkt.WriteBEDouble(LastSentPos.x);
|
||||
Pkt.WriteBEDouble(LastSentPos.y);
|
||||
Pkt.WriteBEDouble(LastSentPos.z);
|
||||
Pkt.WriteByteAngle(a_Mob.GetHeadYaw()); // Doesn't seem to be used
|
||||
Pkt.WriteByteAngle(a_Mob.GetPitch());
|
||||
Pkt.WriteByteAngle(a_Mob.GetHeadYaw());
|
||||
Pkt.WriteByteAngle(a_Mob.GetYaw());
|
||||
Pkt.WriteBEInt16(static_cast<Int16>(a_Mob.GetSpeedX() * 400));
|
||||
Pkt.WriteBEInt16(static_cast<Int16>(a_Mob.GetSpeedY() * 400));
|
||||
|
@ -1409,8 +1409,8 @@ void cProtocol_1_8_0::SendSpawnMob(const cMonster & a_Mob)
|
||||
Pkt.WriteFPInt(LastSentPos.x);
|
||||
Pkt.WriteFPInt(LastSentPos.y);
|
||||
Pkt.WriteFPInt(LastSentPos.z);
|
||||
Pkt.WriteByteAngle(a_Mob.GetHeadYaw()); // Doesn't seem to be used
|
||||
Pkt.WriteByteAngle(a_Mob.GetPitch());
|
||||
Pkt.WriteByteAngle(a_Mob.GetHeadYaw());
|
||||
Pkt.WriteByteAngle(a_Mob.GetYaw());
|
||||
Pkt.WriteBEInt16(static_cast<Int16>(a_Mob.GetSpeedX() * 400));
|
||||
Pkt.WriteBEInt16(static_cast<Int16>(a_Mob.GetSpeedY() * 400));
|
||||
|
Loading…
Reference in New Issue
Block a user