Cuberite
A lightweight, fast and extensible game server for Minecraft
BlockPlant.h
Go to the documentation of this file.
1 #pragma once
2 
3 
4 #include "BlockHandler.h"
5 
6 
7 
8 
11 template <bool NeedsLightToGrow>
12 class cBlockPlant :
13  public cBlockHandler
14 {
16 
17 public:
18 
19  using Super::Super;
20 
21 protected:
22 
23  ~cBlockPlant() = default;
24 
27  {
30  paStay
31  };
32 
38  static PlantAction HasEnoughLight(cChunk & a_Chunk, Vector3i a_RelPos)
39  {
40  // If the plant requires light to grow, check to see if there is enough light
41  // Otherwise, return true
42  if (!NeedsLightToGrow)
43  {
44  return paGrowth;
45  }
46  NIBBLETYPE Blocklight = a_Chunk.GetBlockLight(a_RelPos);
47  NIBBLETYPE SkyLight = a_Chunk.GetSkyLight (a_RelPos);
48  NIBBLETYPE Light = a_Chunk.GetTimeAlteredLight(SkyLight);
49 
50  // If the amount of light provided by blocks is greater than the sky light, use it instead
51  if (Blocklight > Light)
52  {
53  Light = Blocklight;
54  }
55 
56  // Based on light levels, decide between growth, stay and death:
57  if (Light > 8)
58  {
59  return paGrowth;
60  }
61  else if ((Blocklight < 9) && (SkyLight < 9))
62  {
63  return paDeath;
64  }
65 
66  return paStay;
67  }
68 
69 
70 
71 
72 
81  virtual PlantAction CanGrow(cChunk & a_Chunk, Vector3i a_RelPos) const
82  {
83  // Plant can grow if it has the required amount of light, and it passes a random chance based on surrounding blocks
84  auto action = HasEnoughLight(a_Chunk, a_RelPos);
85  if ((action == paGrowth) && !GetRandomProvider().RandBool(1.0 / GetGrowthChance(a_Chunk, a_RelPos)))
86  {
87  action = paStay;
88  }
89  return action;
90  }
91 
92 
93 
94 
95 
98  virtual int GetGrowthChance(cChunk & a_Chunk, Vector3i a_RelPos) const
99  {
100  float Chance = 1.0f;
101  a_RelPos.y -= 1;
102  for (int x = -1; x < 2; ++x)
103  {
104  for (int z = -1; z < 2; ++z)
105  {
106  float Adjustment = 0.0f;
108  NIBBLETYPE Meta;
109 
110  // If the chunk we are trying to get the block information from is loaded
111  if (a_Chunk.UnboundedRelGetBlock(a_RelPos + Vector3i(x, 0, z), Block, Meta))
112  {
113  // If the block affects growth, add to the adjustment
115  {
116  Adjustment = 1.0f;
117 
118  // Farmland alters the chance further if it is watered
119  if ((Block == E_BLOCK_FARMLAND) && (Meta != 0))
120  {
121  Adjustment = 3.0f;
122  }
123  }
124  }
125 
126  // If this is not the block right underneath the plant, it has little effect on the growth
127  if ((x != 0) || (z != 0))
128  {
129  Adjustment /= 4.0f;
130  }
131 
132  Chance += Adjustment;
133  }
134  }
135  return FloorC(24.0f / Chance) + 1;
136  }
137 
138 private:
139 
140  virtual void OnUpdate(
141  cChunkInterface & a_ChunkInterface,
142  cWorldInterface & a_WorldInterface,
143  cBlockPluginInterface & a_PluginInterface,
144  cChunk & a_Chunk,
145  const Vector3i a_RelPos
146  ) const override
147  {
148  auto Action = CanGrow(a_Chunk, a_RelPos);
149  switch (Action)
150  {
151  case paGrowth:
152  {
153  if (Grow(a_Chunk, a_RelPos) == 0)
154  {
155  BearFruit(a_Chunk, a_RelPos);
156  }
157  break;
158  }
159  case paDeath:
160  {
161  a_ChunkInterface.SetBlock(a_Chunk.RelativeToAbsolute(a_RelPos), E_BLOCK_AIR, 0);
162  break;
163  }
164  case paStay: break; // do nothing
165  }
166  }
167 
169  virtual void BearFruit(cChunk & a_Chunk, const Vector3i a_StemRelPos) const
170  {
171  // Nothing to do by default
172  }
173 };
@ E_BLOCK_FARMLAND
Definition: BlockType.h:72
@ E_BLOCK_AIR
Definition: BlockType.h:10
unsigned char NIBBLETYPE
The datatype used by nibbledata (meta, light, skylight)
Definition: ChunkDef.h:44
unsigned char BLOCKTYPE
The datatype used by blockdata.
Definition: ChunkDef.h:41
MTRand & GetRandomProvider()
Returns the current thread's random number source.
Definition: FastRandom.cpp:12
std::enable_if< std::is_arithmetic< T >::value, C >::type FloorC(T a_Value)
Floors a value, then casts it to C (an int by default).
Definition: Globals.h:347
virtual bool CanSustainPlant(BLOCKTYPE a_Plant) const
Checks whether the block has an effect on growing the plant.
Definition: BlockHandler.h:128
virtual int Grow(cChunk &a_Chunk, Vector3i a_RelPos, int a_NumStages=1) const
Grows this block, if it supports growing, by the specified amount of stages (at most).
Definition: BlockHandler.h:179
static const cBlockHandler & For(BLOCKTYPE a_BlockType)
constexpr cBlockHandler(BLOCKTYPE a_BlockType)
Definition: BlockHandler.h:29
const BLOCKTYPE m_BlockType
Definition: BlockHandler.h:205
Base class for plants that use light values to decide whether to grow or not.
Definition: BlockPlant.h:14
virtual int GetGrowthChance(cChunk &a_Chunk, Vector3i a_RelPos) const
Generates an int value between 4 and 25 based on surrounding blocks that affect how quickly the plant...
Definition: BlockPlant.h:98
~cBlockPlant()=default
static PlantAction HasEnoughLight(cChunk &a_Chunk, Vector3i a_RelPos)
Checks whether there is enough light for the plant to grow.
Definition: BlockPlant.h:38
virtual PlantAction CanGrow(cChunk &a_Chunk, Vector3i a_RelPos) const
Checks whether a plant can grow grow, based on what is returned from cBlockPlant::HasEnoughLight and ...
Definition: BlockPlant.h:81
PlantAction
The action the plant can take on an update.
Definition: BlockPlant.h:27
virtual void OnUpdate(cChunkInterface &a_ChunkInterface, cWorldInterface &a_WorldInterface, cBlockPluginInterface &a_PluginInterface, cChunk &a_Chunk, const Vector3i a_RelPos) const override
Called when the block gets ticked either by a random tick or by a queued tick.
Definition: BlockPlant.h:140
virtual void BearFruit(cChunk &a_Chunk, const Vector3i a_StemRelPos) const
Grows the final produce next to the stem at the specified position.
Definition: BlockPlant.h:169
This interface is used to decouple block handlers from the cPluginManager dependency through cWorld.
void SetBlock(Vector3i a_BlockPos, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta)
Sets the block at the specified coords to the specified value.
Definition: Chunk.h:36
NIBBLETYPE GetBlockLight(Vector3i a_RelPos) const
Get the level of artificial light illuminating the block (0 - 15)
Definition: Chunk.h:302
Vector3i RelativeToAbsolute(Vector3i a_RelBlockPosition) const
Converts the coord relative to this chunk into an absolute coord.
Definition: Chunk.h:450
NIBBLETYPE GetSkyLight(Vector3i a_RelPos) const
Get the level of sky light illuminating the block (0 - 15) independent of daytime.
Definition: Chunk.h:306
NIBBLETYPE GetTimeAlteredLight(NIBBLETYPE a_Skylight) const
Light alterations based on time.
Definition: Chunk.cpp:1977
bool UnboundedRelGetBlock(Vector3i a_RelCoords, BLOCKTYPE &a_BlockType, NIBBLETYPE &a_BlockMeta) const
Same as GetBlock(), but relative coords needn't be in this chunk (uses m_Neighbor-s or m_ChunkMap in ...
Definition: Chunk.cpp:1008
T y
Definition: Vector3.h:17