1
0
Fork 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,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;
}
} ;

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