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>
13  public cBlockHandler
14 {
16 
17 
18 public:
19 
20  cBlockPlant(BLOCKTYPE a_BlockType):
21  super(a_BlockType)
22  {
23  }
24 
25 
26 
27 
28 
29  virtual void OnUpdate(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cBlockPluginInterface & a_PluginInterface, cChunk & a_Chunk, int a_RelX, int a_RelY, int a_RelZ) override
30  {
31  Vector3i relPos(a_RelX, a_RelY, a_RelZ);
32  auto action = CanGrow(a_Chunk, relPos);
33  switch (action)
34  {
35  case paGrowth:
36  {
37  Grow(a_Chunk, relPos);
38  break;
39  }
40  case paDeath:
41  {
42  a_ChunkInterface.DigBlock(a_WorldInterface, a_Chunk.RelativeToAbsolute(relPos));
43  break;
44  }
45  case paStay: break; // do nothing
46  }
47  }
48 
49 
50 
51 
52 
53 protected:
54 
57  {
61  };
62 
63 
64 
65 
66 
73  {
74  // If the plant requires light to grow, check to see if there is enough light
75  // Otherwise, return true
76  if (!NeedsLightToGrow)
77  {
78  return paGrowth;
79  }
80  NIBBLETYPE Blocklight = a_Chunk.GetBlockLight(a_RelPos);
81  NIBBLETYPE SkyLight = a_Chunk.GetSkyLight (a_RelPos);
82  NIBBLETYPE Light = a_Chunk.GetTimeAlteredLight(SkyLight);
83 
84  // If the amount of light provided by blocks is greater than the sky light, use it instead
85  if (Blocklight > Light)
86  {
87  Light = Blocklight;
88  }
89 
90  // Based on light levels, decide between growth, stay and death:
91  if (Light > 8)
92  {
93  return paGrowth;
94  }
95  else if ((Blocklight < 9) && (SkyLight < 9))
96  {
97  return paDeath;
98  }
99 
100  return paStay;
101  }
102 
103 
104 
105 
106 
115  virtual PlantAction CanGrow(cChunk & a_Chunk, Vector3i a_RelPos)
116  {
117  // Plant can grow if it has the required amount of light, and it passes a random chance based on surrounding blocks
118  auto action = HasEnoughLight(a_Chunk, a_RelPos);
119  if ((action == paGrowth) && !GetRandomProvider().RandBool(1.0 / GetGrowthChance(a_Chunk, a_RelPos)))
120  {
121  action = paStay;
122  }
123  return action;
124  }
125 
126 
127 
128 
129 
132  virtual int GetGrowthChance(cChunk & a_Chunk, Vector3i a_RelPos)
133  {
134  float Chance = 1.0f;
135  a_RelPos.y -= 1;
136  for (int x = -1; x < 2; ++x)
137  {
138  for (int z = -1; z < 2; ++z)
139  {
140  float Adjustment = 0.0f;
141  BLOCKTYPE Block;
142  NIBBLETYPE Meta;
143 
144  // If the chunk we are trying to get the block information from is loaded
145  if (a_Chunk.UnboundedRelGetBlock(a_RelPos + Vector3i(x, 0, z), Block, Meta))
146  {
147  cBlockHandler * Handler = BlockHandler(Block);
148 
149  // If the block affects growth, add to the adjustment
150  if (Handler->CanSustainPlant(m_BlockType))
151  {
152  Adjustment = 1.0f;
153 
154  // Farmland alters the chance further if it is watered
155  if ((Block == E_BLOCK_FARMLAND) && (Meta != 0))
156  {
157  Adjustment = 3.0f;
158  }
159  }
160  }
161 
162  // If this is not the block right underneath the plant, it has little effect on the growth
163  if ((x != 0) || (z != 0))
164  {
165  Adjustment /= 4.0f;
166  }
167 
168  Chance += Adjustment;
169  }
170  }
171  return FloorC(24.0f / Chance) + 1;
172  }
173 };
NIBBLETYPE GetSkyLight(Vector3i a_RelPos) const
Get the level of sky light illuminating the block (0 - 15) independent of daytime.
Definition: Chunk.h:419
NIBBLETYPE GetTimeAlteredLight(NIBBLETYPE a_Skylight) const
Light alterations based on time.
Definition: Chunk.cpp:2450
virtual void OnUpdate(cChunkInterface &a_ChunkInterface, cWorldInterface &a_WorldInterface, cBlockPluginInterface &a_PluginInterface, cChunk &a_Chunk, int a_RelX, int a_RelY, int a_RelZ) override
Called when the block gets ticked either by a random tick or by a queued tick.
Definition: BlockPlant.h:29
NIBBLETYPE GetBlockLight(Vector3i a_RelPos) const
Get the level of artificial light illuminating the block (0 - 15)
Definition: Chunk.h:415
unsigned char BLOCKTYPE
The datatype used by blockdata.
Definition: ChunkDef.h:42
MTRand & GetRandomProvider()
Returns the current thread&#39;s random number source.
Definition: FastRandom.cpp:20
Vector3i RelativeToAbsolute(Vector3i a_RelBlockPosition)
Converts the coord relative to this chunk into an absolute coord.
Definition: Chunk.h:569
cBlockHandler(BLOCKTYPE a_BlockType)
BLOCKTYPE m_BlockType
Definition: BlockHandler.h:213
cBlockPlant(BLOCKTYPE a_BlockType)
Definition: BlockPlant.h:20
unsigned char NIBBLETYPE
The datatype used by nibbledata (meta, light, skylight)
Definition: ChunkDef.h:45
virtual int GetGrowthChance(cChunk &a_Chunk, Vector3i a_RelPos)
Generates an int value between 4 and 25 based on surrounding blocks that affect how quickly the plant...
Definition: BlockPlant.h:132
Definition: Chunk.h:49
T y
Definition: Vector3.h:17
This interface is used to decouple block handlers from the cPluginManager dependency through cWorld...
virtual int Grow(cChunk &a_Chunk, Vector3i a_RelPos, int a_NumStages=1)
Grows this block, if it supports growing, by the specified amount of stages (at most).
Definition: BlockHandler.h:205
virtual PlantAction CanGrow(cChunk &a_Chunk, Vector3i a_RelPos)
Checks whether a plant can grow grow, based on what is returned from cBlockPlant::HasEnoughLight and ...
Definition: BlockPlant.h:115
PlantAction HasEnoughLight(cChunk &a_Chunk, Vector3i a_RelPos)
Checks whether there is enough light for the plant to grow.
Definition: BlockPlant.h:72
cBlockHandler * BlockHandler(BLOCKTYPE a_BlockType)
Definition: BlockInfo.h:159
bool UnboundedRelGetBlock(Vector3i a_RelCoords, BLOCKTYPE &a_BlockType, NIBBLETYPE &a_BlockMeta) const
Same as GetBlock(), but relative coords needn&#39;t be in this chunk (uses m_Neighbor-s or m_ChunkMap in ...
Definition: Chunk.cpp:997
Base class for plants that use light values to decide whether to grow or not.
Definition: BlockPlant.h:12
bool DigBlock(cWorldInterface &a_WorldInterface, Vector3i a_BlockPos)
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:362
virtual bool CanSustainPlant(BLOCKTYPE a_Plant)
Checks whether the block has an effect on growing the plant.
Definition: BlockHandler.h:138
PlantAction
The action the plant can take on an update.
Definition: BlockPlant.h:56