1
0

Made grass spreader prettier

This commit is contained in:
Tiger Wang 2020-04-21 23:12:55 +01:00
parent 58ab289b56
commit e205d4109b
3 changed files with 91 additions and 65 deletions

View File

@ -52,72 +52,102 @@ public:
a_Chunk.GetWorld()->QueueLightChunk(a_Chunk.GetPosX(), a_Chunk.GetPosZ());
return;
}
auto AbovePos = a_RelPos.addedY(1);
if (cChunkDef::IsValidHeight(AbovePos.y))
if (!cBlockGrassHandler::TrySurvive(a_Chunk, a_RelPos))
{
return;
}
// Grass spreads to adjacent dirt blocks:
for (unsigned i = 0; i < 2; i++) // Pick two blocks to grow to
{
auto & Random = GetRandomProvider();
int OfsX = Random.RandInt(-1, 1);
int OfsY = Random.RandInt(-3, 1);
int OfsZ = Random.RandInt(-1, 1);
cBlockGrassHandler::TryThrive(a_Chunk, a_RelPos + Vector3i(OfsX, OfsY, OfsZ));
} // for i - repeat twice
}
/** 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.
auto Above = a_Chunk.GetBlock(AbovePos);
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;
return false;
}
// 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;
}
const auto Light = std::max(a_Chunk.GetBlockLight(AbovePos), a_Chunk.GetSkyLightAltered(AbovePos));
return (Light >= 9);
}
// Grass spreads to adjacent dirt blocks:
auto & rand = GetRandomProvider();
for (int 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);
BLOCKTYPE DestBlock;
NIBBLETYPE DestMeta;
auto Pos = a_RelPos + Vector3i(OfsX, OfsY, OfsZ);
if (!cChunkDef::IsValidHeight(Pos.y))
/** 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
continue;
return;
}
auto Chunk = a_Chunk.GetRelNeighborChunkAdjustCoords(Pos);
auto Chunk = a_Chunk.GetRelNeighborChunkAdjustCoords(a_RelPos);
if (Chunk == nullptr)
{
// Unloaded chunk
continue;
return;
}
Chunk->GetBlockTypeMeta(Pos, DestBlock, DestMeta);
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
continue;
return;
}
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))
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)
)
{
auto AbsPos = Chunk->RelativeToAbsolute(Pos);
const auto AbsPos = Chunk->RelativeToAbsolute(a_RelPos);
if (!cRoot::Get()->GetPluginManager()->CallHookBlockSpread(*Chunk->GetWorld(), AbsPos.x, AbsPos.y, AbsPos.z, ssGrassSpread))
{
Chunk->FastSetBlock(Pos, E_BLOCK_GRASS, 0);
Chunk->FastSetBlock(a_RelPos, E_BLOCK_GRASS, 0);
}
}
} // for i - repeat twice
}
@ -130,7 +160,3 @@ public:
return 1;
}
} ;

View File

@ -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));

View File

@ -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));