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 :
|
2020-03-23 16:07:08 -04:00
|
|
|
public cBlockHandler
|
2013-07-29 07:13:03 -04:00
|
|
|
{
|
2020-04-13 12:38:06 -04:00
|
|
|
using Super = cBlockHandler;
|
2015-12-19 09:30:32 -05:00
|
|
|
|
2013-07-29 07:13:03 -04:00
|
|
|
public:
|
2019-10-16 04:06:34 -04:00
|
|
|
|
|
|
|
cBlockFarmlandHandler(BLOCKTYPE a_BlockType):
|
2020-04-13 12:38:06 -04:00
|
|
|
Super(a_BlockType)
|
2013-07-29 07:13:03 -04:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2019-10-16 04:06:34 -04:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2020-03-23 16:07:08 -04:00
|
|
|
virtual cItems ConvertToPickups(NIBBLETYPE a_BlockMeta, cBlockEntity * a_BlockEntity, const cEntity * a_Digger, const cItem * a_Tool) override
|
|
|
|
{
|
|
|
|
return cItem(E_BLOCK_DIRT, 1, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2020-04-17 05:36:37 -04:00
|
|
|
virtual void OnUpdate(
|
|
|
|
cChunkInterface & a_ChunkInterface,
|
|
|
|
cWorldInterface & a_WorldInterface,
|
|
|
|
cBlockPluginInterface & a_PluginInterface,
|
|
|
|
cChunk & a_Chunk,
|
|
|
|
const Vector3i a_RelPos
|
|
|
|
) override
|
2013-07-29 07:13:03 -04:00
|
|
|
{
|
2020-04-17 05:36:37 -04:00
|
|
|
auto BlockMeta = a_Chunk.GetMeta(a_RelPos);
|
2014-09-12 13:07:20 -04:00
|
|
|
|
2020-04-17 05:36:37 -04:00
|
|
|
if (IsWaterInNear(a_Chunk, a_RelPos))
|
2013-07-29 07:13:03 -04:00
|
|
|
{
|
2014-09-12 13:07:20 -04:00
|
|
|
// Water was found, set block meta to 7
|
2020-04-17 05:36:37 -04:00
|
|
|
a_Chunk.FastSetBlock(a_RelPos, m_BlockType, 7);
|
2013-07-29 07:13:03 -04:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Water wasn't found, de-hydrate block:
|
|
|
|
if (BlockMeta > 0)
|
|
|
|
{
|
2020-04-17 05:36:37 -04:00
|
|
|
a_Chunk.FastSetBlock(a_RelPos, 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:
|
2020-04-17 05:36:37 -04:00
|
|
|
auto UpperBlock = cChunkDef::IsValidHeight(a_RelPos.y + 1) ? a_Chunk.GetBlock(a_RelPos.addedY(1)) : E_BLOCK_AIR;
|
2014-09-12 13:07:20 -04:00
|
|
|
switch (UpperBlock)
|
2013-07-29 07:13:03 -04:00
|
|
|
{
|
2017-02-14 05:13:55 -05:00
|
|
|
case E_BLOCK_BEETROOTS:
|
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:
|
|
|
|
{
|
2020-04-17 05:36:37 -04:00
|
|
|
a_Chunk.SetBlock(a_RelPos, E_BLOCK_DIRT, 0);
|
2013-07-29 07:13:03 -04:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2014-07-14 16:57:44 -04:00
|
|
|
|
2015-07-01 04:40:16 -04:00
|
|
|
|
2019-10-16 04:06:34 -04:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
virtual void OnNeighborChanged(cChunkInterface & a_ChunkInterface, Vector3i a_BlockPos, eBlockFace a_WhichNeighbor) override
|
2014-09-12 13:07:20 -04:00
|
|
|
{
|
2015-07-01 04:40:16 -04:00
|
|
|
// Don't care about any neighbor but the one above us (fix recursion loop in #2213):
|
|
|
|
if (a_WhichNeighbor != BLOCK_FACE_YP)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Don't care about anything if we're at the top of the world:
|
2019-10-16 04:06:34 -04:00
|
|
|
if (a_BlockPos.y >= cChunkDef::Height)
|
2014-09-12 13:07:20 -04:00
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2015-07-01 04:40:16 -04:00
|
|
|
// Check whether we should revert to dirt:
|
2019-10-16 04:06:34 -04:00
|
|
|
auto upperBlock = a_ChunkInterface.GetBlock(a_BlockPos.addedY(1));
|
|
|
|
if (cBlockInfo::FullyOccupiesVoxel(upperBlock))
|
2014-09-12 13:07:20 -04:00
|
|
|
{
|
2019-10-16 04:06:34 -04:00
|
|
|
a_ChunkInterface.SetBlock(a_BlockPos, E_BLOCK_DIRT, 0);
|
2014-09-12 13:07:20 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-07-01 04:40:16 -04:00
|
|
|
|
2019-10-16 04:06:34 -04:00
|
|
|
|
2014-09-12 13:07:20 -04:00
|
|
|
|
2015-07-01 04:40:16 -04:00
|
|
|
|
2020-04-17 05:36:37 -04:00
|
|
|
/** Returns true if there's either a water source block close enough to hydrate the specified position, or it's raining there. */
|
|
|
|
bool IsWaterInNear(cChunk & a_Chunk, const Vector3i a_RelPos)
|
2014-09-12 13:07:20 -04:00
|
|
|
{
|
2020-04-24 13:29:12 -04:00
|
|
|
const auto WorldPos = a_Chunk.RelativeToAbsolute(a_RelPos);
|
|
|
|
if (a_Chunk.GetWorld()->IsWeatherWetAtXYZ(WorldPos))
|
2014-09-12 13:07:20 -04:00
|
|
|
{
|
2020-04-17 05:36:37 -04:00
|
|
|
// Rain hydrates farmland, too
|
2014-09-12 13:07:20 -04:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Search for water in a close proximity:
|
2017-08-24 05:19:40 -04:00
|
|
|
// Ref.: https://minecraft.gamepedia.com/Farmland#Hydration
|
2014-09-12 13:07:20 -04:00
|
|
|
// TODO: Rewrite this to use the chunk and its neighbors directly
|
|
|
|
cBlockArea Area;
|
2020-04-17 05:36:37 -04:00
|
|
|
if (!Area.Read(*a_Chunk.GetWorld(), WorldPos - Vector3i(4, 0, 4), WorldPos + Vector3i(4, 1, 4)))
|
2014-09-12 13:07:20 -04:00
|
|
|
{
|
|
|
|
// 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;
|
|
|
|
}
|
2015-08-19 12:45:53 -04:00
|
|
|
|
2020-04-17 05:36:37 -04:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2015-08-19 12:45:53 -04:00
|
|
|
virtual bool CanSustainPlant(BLOCKTYPE a_Plant) override
|
|
|
|
{
|
|
|
|
return (
|
2017-02-14 05:13:55 -05:00
|
|
|
(a_Plant == E_BLOCK_BEETROOTS) ||
|
2015-08-19 12:45:53 -04:00
|
|
|
(a_Plant == E_BLOCK_CROPS) ||
|
|
|
|
(a_Plant == E_BLOCK_CARROTS) ||
|
|
|
|
(a_Plant == E_BLOCK_POTATOES) ||
|
|
|
|
(a_Plant == E_BLOCK_MELON_STEM) ||
|
|
|
|
(a_Plant == E_BLOCK_PUMPKIN_STEM)
|
|
|
|
);
|
|
|
|
}
|
2013-07-29 07:13:03 -04:00
|
|
|
} ;
|