2013-07-29 07:13:03 -04:00
|
|
|
|
|
|
|
// BlockFarmland.h
|
|
|
|
|
|
|
|
// Declares the cBlcokFarmlandHandler representing the block handler for farmland
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include "BlockHandler.h"
|
|
|
|
#include "../BlockArea.h"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class cBlockFarmlandHandler :
|
|
|
|
public cBlockHandler
|
|
|
|
{
|
|
|
|
|
|
|
|
public:
|
2014-07-14 16:57:44 -04:00
|
|
|
cBlockFarmlandHandler(BLOCKTYPE a_BlockType) :
|
|
|
|
cBlockHandler(a_BlockType)
|
2013-07-29 07:13:03 -04:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2014-02-02 09:49:37 -05:00
|
|
|
virtual void OnUpdate(cChunkInterface & cChunkInterface, cWorldInterface & a_WorldInterface, cBlockPluginInterface & a_PluginInterface, cChunk & a_Chunk, int a_RelX, int a_RelY, int a_RelZ) override
|
2013-07-29 07:13:03 -04:00
|
|
|
{
|
2013-11-30 09:58:27 -05:00
|
|
|
NIBBLETYPE BlockMeta = a_Chunk.GetMeta(a_RelX, a_RelY, a_RelZ);
|
2014-09-12 13:07:20 -04:00
|
|
|
|
|
|
|
if (IsWaterInNear(a_Chunk, a_RelX, a_RelY, a_RelZ))
|
2013-07-29 07:13:03 -04:00
|
|
|
{
|
2014-09-12 13:07:20 -04:00
|
|
|
// Water was found, set block meta to 7
|
|
|
|
a_Chunk.FastSetBlock(a_RelX, a_RelY, a_RelZ, m_BlockType, 7);
|
2013-07-29 07:13:03 -04:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Water wasn't found, de-hydrate block:
|
|
|
|
if (BlockMeta > 0)
|
|
|
|
{
|
2013-11-30 09:58:27 -05:00
|
|
|
a_Chunk.FastSetBlock(a_RelX, a_RelY, a_RelZ, E_BLOCK_FARMLAND, --BlockMeta);
|
2013-07-29 07:13:03 -04:00
|
|
|
return;
|
|
|
|
}
|
2014-09-12 13:07:20 -04:00
|
|
|
|
2013-07-29 07:13:03 -04:00
|
|
|
// Farmland too dry. If nothing is growing on top, turn back to dirt:
|
2014-09-12 13:07:20 -04:00
|
|
|
BLOCKTYPE UpperBlock = (a_RelY >= cChunkDef::Height) ? E_BLOCK_AIR : a_Chunk.GetBlock(a_RelX, a_RelY + 1, a_RelZ);
|
|
|
|
switch (UpperBlock)
|
2013-07-29 07:13:03 -04:00
|
|
|
{
|
|
|
|
case E_BLOCK_CROPS:
|
2014-02-03 16:14:52 -05:00
|
|
|
case E_BLOCK_POTATOES:
|
|
|
|
case E_BLOCK_CARROTS:
|
2013-07-29 07:13:03 -04:00
|
|
|
case E_BLOCK_MELON_STEM:
|
|
|
|
case E_BLOCK_PUMPKIN_STEM:
|
|
|
|
{
|
|
|
|
// Produce on top, don't revert
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
{
|
2014-09-12 13:07:20 -04:00
|
|
|
a_Chunk.SetBlock(a_RelX, a_RelY, a_RelZ, E_BLOCK_DIRT, 0);
|
2013-07-29 07:13:03 -04:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2014-07-14 16:57:44 -04:00
|
|
|
|
2014-09-12 13:07:20 -04:00
|
|
|
virtual void OnNeighborChanged(cChunkInterface & a_ChunkInterface, int a_BlockX, int a_BlockY, int a_BlockZ) override
|
|
|
|
{
|
|
|
|
if (a_BlockY >= cChunkDef::Height)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
BLOCKTYPE UpperBlock = a_ChunkInterface.GetBlock(a_BlockX, a_BlockY + 1, a_BlockZ);
|
|
|
|
if (cBlockInfo::FullyOccupiesVoxel(UpperBlock))
|
|
|
|
{
|
|
|
|
a_ChunkInterface.SetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_DIRT, 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-07-14 16:57:44 -04:00
|
|
|
virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override
|
|
|
|
{
|
2014-07-17 16:15:34 -04:00
|
|
|
a_Pickups.Add(E_BLOCK_DIRT, 1, 0); // Reset meta
|
2014-07-14 16:57:44 -04:00
|
|
|
}
|
2014-09-12 13:07:20 -04:00
|
|
|
|
|
|
|
bool IsWaterInNear(cChunk & a_Chunk, int a_RelX, int a_RelY, int a_RelZ)
|
|
|
|
{
|
|
|
|
if (a_Chunk.GetWorld()->IsWeatherWetAt(a_RelX, a_RelZ))
|
|
|
|
{
|
|
|
|
// Rain hydrates farmland, too, except in Desert biomes.
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Search for water in a close proximity:
|
|
|
|
// Ref.: http://www.minecraftwiki.net/wiki/Farmland#Hydrated_Farmland_Tiles
|
|
|
|
// TODO: Rewrite this to use the chunk and its neighbors directly
|
|
|
|
cBlockArea Area;
|
|
|
|
int BlockX = a_RelX + a_Chunk.GetPosX() * cChunkDef::Width;
|
|
|
|
int BlockZ = a_RelZ + a_Chunk.GetPosZ() * cChunkDef::Width;
|
|
|
|
if (!Area.Read(a_Chunk.GetWorld(), BlockX - 4, BlockX + 4, a_RelY, a_RelY + 1, BlockZ - 4, BlockZ + 4))
|
|
|
|
{
|
|
|
|
// Too close to the world edge, cannot check surroundings
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
size_t NumBlocks = Area.GetBlockCount();
|
|
|
|
BLOCKTYPE * BlockTypes = Area.GetBlockTypes();
|
|
|
|
for (size_t i = 0; i < NumBlocks; i++)
|
|
|
|
{
|
|
|
|
if (IsBlockWater(BlockTypes[i]))
|
|
|
|
{
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
} // for i - BlockTypes[]
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
2013-07-29 07:13:03 -04:00
|
|
|
} ;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|