* Logic for handling plant growth has been centralized into cBlockPlant, and all growable plants now inherit from it.
* Blocks now have an effect upon plant growth, just like in vanilla.
This commit is contained in:
parent
dffa8a7b56
commit
cc83c4641d
@ -1,18 +1,19 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "BlockHandler.h"
|
||||
#include "BlockPlant.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class cBlockCactusHandler :
|
||||
public cBlockHandler
|
||||
public cBlockPlant
|
||||
{
|
||||
typedef cBlockPlant Super;
|
||||
public:
|
||||
cBlockCactusHandler(BLOCKTYPE a_BlockType)
|
||||
: cBlockHandler(a_BlockType)
|
||||
: Super(a_BlockType, false)
|
||||
{
|
||||
}
|
||||
|
||||
@ -64,7 +65,10 @@ public:
|
||||
|
||||
virtual void OnUpdate(cChunkInterface & cChunkInterface, cWorldInterface & a_WorldInterface, cBlockPluginInterface & a_PluginInterface, cChunk & a_Chunk, int a_RelX, int a_RelY, int a_RelZ) override
|
||||
{
|
||||
a_Chunk.GetWorld()->GrowCactus(a_RelX + a_Chunk.GetPosX() * cChunkDef::Width, a_RelY, a_RelZ + a_Chunk.GetPosZ() * cChunkDef::Width, 1);
|
||||
if (CanGrow(a_Chunk, a_RelX, a_RelY, a_RelZ) == paGrowth)
|
||||
{
|
||||
a_Chunk.GetWorld()->GrowCactus(a_RelX + a_Chunk.GetPosX() * cChunkDef::Width, a_RelY, a_RelZ + a_Chunk.GetPosZ() * cChunkDef::Width, 1);
|
||||
}
|
||||
}
|
||||
|
||||
virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) override
|
||||
@ -72,6 +76,19 @@ public:
|
||||
UNUSED(a_Meta);
|
||||
return 7;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
virtual PlantAction CanGrow(cChunk & a_Chunk, int a_RelX, int a_RelY, int a_RelZ) override
|
||||
{
|
||||
auto Action = paStay;
|
||||
if (((a_RelY + 1) < cChunkDef::Height) && (a_Chunk.GetBlock(a_RelX, a_RelY + 1, a_RelZ) == E_BLOCK_AIR))
|
||||
{
|
||||
Action = Super::CanGrow(a_Chunk, a_RelX, a_RelY, a_RelZ);
|
||||
}
|
||||
|
||||
return Action;
|
||||
}
|
||||
} ;
|
||||
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "BlockHandler.h"
|
||||
#include "BlockPlant.h"
|
||||
#include "../FastRandom.h"
|
||||
|
||||
|
||||
@ -10,11 +10,12 @@
|
||||
|
||||
/** Common class that takes care of carrots, potatoes and wheat */
|
||||
class cBlockCropsHandler :
|
||||
public cBlockHandler
|
||||
public cBlockPlant
|
||||
{
|
||||
typedef cBlockPlant Super;
|
||||
public:
|
||||
cBlockCropsHandler(BLOCKTYPE a_BlockType)
|
||||
: cBlockHandler(a_BlockType)
|
||||
: Super(a_BlockType, true)
|
||||
{
|
||||
}
|
||||
|
||||
@ -82,12 +83,17 @@ public:
|
||||
{
|
||||
Light = SkyLight;
|
||||
}
|
||||
|
||||
if ((Meta < 7) && (Light > 8))
|
||||
|
||||
// Check to see if the plant can grow
|
||||
auto Action = CanGrow(a_Chunk, a_RelX, a_RelY, a_RelZ);
|
||||
|
||||
// If there is still room to grow and the plant can grow, then grow.
|
||||
// Otherwise if the plant needs to die, then dig it up
|
||||
if ((Meta < 7) && (Action == paGrowth))
|
||||
{
|
||||
a_Chunk.FastSetBlock(a_RelX, a_RelY, a_RelZ, m_BlockType, ++Meta);
|
||||
}
|
||||
else if (Light < 9)
|
||||
else if (Action == paDeath)
|
||||
{
|
||||
a_Chunk.GetWorld()->DigBlock(a_RelX + a_Chunk.GetPosX() * cChunkDef::Width, a_RelY, a_RelZ + a_Chunk.GetPosZ() * cChunkDef::Width);
|
||||
}
|
||||
|
@ -127,6 +127,17 @@ public:
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual bool CanSustainPlant(BLOCKTYPE a_Plant) override
|
||||
{
|
||||
return (
|
||||
(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)
|
||||
);
|
||||
}
|
||||
} ;
|
||||
|
||||
|
||||
|
@ -57,6 +57,17 @@ public:
|
||||
ASSERT(!"Unhandled blocktype in fluid/water handler!");
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual bool CanSustainPlant(BLOCKTYPE a_Plant) override
|
||||
{
|
||||
return (
|
||||
(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)
|
||||
);
|
||||
}
|
||||
} ;
|
||||
|
||||
|
||||
@ -144,6 +155,11 @@ public:
|
||||
UNUSED(a_Meta);
|
||||
return 4;
|
||||
}
|
||||
|
||||
virtual bool CanSustainPlant(BLOCKTYPE a_Plant) override
|
||||
{
|
||||
return false;
|
||||
}
|
||||
} ;
|
||||
|
||||
|
||||
|
@ -49,6 +49,7 @@
|
||||
#include "BlockMobSpawner.h"
|
||||
#include "BlockMushroom.h"
|
||||
#include "BlockMycelium.h"
|
||||
#include "BlockNetherrack.h"
|
||||
#include "BlockNetherWart.h"
|
||||
#include "BlockOre.h"
|
||||
#include "BlockPiston.h"
|
||||
@ -263,6 +264,7 @@ cBlockHandler * cBlockHandler::CreateBlockHandler(BLOCKTYPE a_BlockType)
|
||||
case E_BLOCK_NETHER_BRICK_STAIRS: return new cBlockStairsHandler (a_BlockType);
|
||||
case E_BLOCK_NETHER_PORTAL: return new cBlockPortalHandler (a_BlockType);
|
||||
case E_BLOCK_NETHER_WART: return new cBlockNetherWartHandler (a_BlockType);
|
||||
case E_BLOCK_NETHERRACK: return new cBlockNetherrack (a_BlockType);
|
||||
case E_BLOCK_NETHER_QUARTZ_ORE: return new cBlockOreHandler (a_BlockType);
|
||||
case E_BLOCK_NEW_LEAVES: return new cBlockLeavesHandler (a_BlockType);
|
||||
case E_BLOCK_NEW_LOG: return new cBlockSidewaysHandler (a_BlockType);
|
||||
|
@ -88,6 +88,9 @@ public:
|
||||
|
||||
/** Checks if the block can stay at the specified relative coords in the chunk */
|
||||
virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk);
|
||||
|
||||
/** Checks whether the block has an effect on growing the plant */
|
||||
virtual bool CanSustainPlant(BLOCKTYPE a_Plant) { return false; }
|
||||
|
||||
/** Checks if the block can be placed at this point.
|
||||
Default: CanBeAt(...)
|
||||
|
@ -1,7 +1,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "BlockHandler.h"
|
||||
#include "BlockPlant.h"
|
||||
#include "../FastRandom.h"
|
||||
#include "../World.h"
|
||||
|
||||
@ -10,11 +10,12 @@
|
||||
|
||||
|
||||
class cBlockNetherWartHandler :
|
||||
public cBlockHandler
|
||||
public cBlockPlant
|
||||
{
|
||||
typedef cBlockPlant Super;
|
||||
public:
|
||||
cBlockNetherWartHandler(BLOCKTYPE a_BlockType)
|
||||
: cBlockHandler(a_BlockType)
|
||||
: Super(a_BlockType, false)
|
||||
{
|
||||
}
|
||||
|
||||
@ -36,7 +37,7 @@ public:
|
||||
virtual void OnUpdate(cChunkInterface & cChunkInterface, cWorldInterface & a_WorldInterface, cBlockPluginInterface & a_PluginInterface, cChunk & a_Chunk, int a_RelX, int a_RelY, int a_RelZ) override
|
||||
{
|
||||
NIBBLETYPE Meta = a_Chunk.GetMeta(a_RelX, a_RelY, a_RelZ);
|
||||
if (Meta < 7)
|
||||
if ((Meta < 7) && (CanGrow(a_Chunk, a_RelX, a_RelY, a_RelZ) == paGrowth))
|
||||
{
|
||||
a_Chunk.FastSetBlock(a_RelX, a_RelY, a_RelZ, E_BLOCK_NETHER_WART, ++Meta);
|
||||
}
|
||||
|
12
src/Blocks/BlockNetherrack.h
Normal file
12
src/Blocks/BlockNetherrack.h
Normal file
@ -0,0 +1,12 @@
|
||||
#pragma once
|
||||
|
||||
|
||||
#include "BlockHandler.h"
|
||||
|
||||
class cBlockNetherrack : public cBlockHandler
|
||||
{
|
||||
public:
|
||||
cBlockNetherrack(BLOCKTYPE a_Type) : cBlockHandler(a_Type){}
|
||||
|
||||
virtual bool CanSustainPlant(BLOCKTYPE a_Plant) override { return (a_Plant == E_BLOCK_NETHER_WART); }
|
||||
};
|
132
src/Blocks/BlockPlant.h
Normal file
132
src/Blocks/BlockPlant.h
Normal file
@ -0,0 +1,132 @@
|
||||
|
||||
// BlockPlant.h
|
||||
|
||||
// Base class for any growing block
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "BlockHandler.h"
|
||||
|
||||
class cBlockPlant : public cBlockHandler
|
||||
{
|
||||
typedef cBlockHandler Super;
|
||||
bool m_NeedLightToGrow;
|
||||
public:
|
||||
cBlockPlant(BLOCKTYPE a_BlockType, bool a_LightToGrow)
|
||||
: Super(a_BlockType), m_NeedLightToGrow(a_LightToGrow){}
|
||||
|
||||
protected:
|
||||
enum PlantAction
|
||||
{
|
||||
paDeath,
|
||||
paGrowth,
|
||||
paStay
|
||||
};
|
||||
|
||||
/** Checks whether there is enough light for the plant to grow.
|
||||
If the plant doesn't require light to grow, then it returns paGrowth.
|
||||
If the plant requires light to grow and there is enough light, it returns paGrowth.
|
||||
If the plant requires light to grow and there isn't enough light, it returns paStay.
|
||||
If the plant requires light to grow and there is too little light, it returns paDeath.
|
||||
*/
|
||||
PlantAction HasEnoughLight(cChunk & a_Chunk, int a_RelX, int a_RelY, int a_RelZ)
|
||||
{
|
||||
// If the plant requires light to grow, check to see if there is enough light
|
||||
// Otherwise, return true
|
||||
if (m_NeedLightToGrow)
|
||||
{
|
||||
NIBBLETYPE Blocklight = a_Chunk.GetBlockLight(a_RelX, a_RelY, a_RelZ);
|
||||
NIBBLETYPE SkyLight = a_Chunk.GetSkyLight (a_RelX, a_RelY, a_RelZ);
|
||||
NIBBLETYPE Light = a_Chunk.GetTimeAlteredLight(SkyLight);
|
||||
|
||||
// If the amount of light provided by blocks is greater than the sky light, use it instead
|
||||
if (Blocklight > Light)
|
||||
{
|
||||
Light = Blocklight;
|
||||
}
|
||||
|
||||
// Return true if there is enough light
|
||||
// Set m_ShouldDie if the base light amounts are not enough to sustain a plant
|
||||
if (Light > 8)
|
||||
{
|
||||
return paGrowth;
|
||||
}
|
||||
else if (Blocklight < 9 && SkyLight < 9)
|
||||
{
|
||||
return paDeath;
|
||||
}
|
||||
|
||||
return paStay;
|
||||
}
|
||||
|
||||
return paGrowth;
|
||||
}
|
||||
|
||||
/** Checks whether a plant can grow grow, based on what is returned from cBlockPlant::HasEnoughLight
|
||||
and a random check based on what is returned from cBlockPlant::GetGrowthChance.
|
||||
Can return three values.
|
||||
paGrowth when the conditions are right for the plant to grow.
|
||||
paStay when the conditions are not quite right.
|
||||
paDeath is returned when there isn't enough light for the plant to survive.
|
||||
Plants that don't require light will never have a paDeath returned
|
||||
*/
|
||||
virtual PlantAction CanGrow(cChunk & a_Chunk, int a_RelX, int a_RelY, int a_RelZ)
|
||||
{
|
||||
cFastRandom rand;
|
||||
// Plant can grow if it has the required amount of light, and it passes a random chance based on surrounding blocks
|
||||
PlantAction Action = HasEnoughLight(a_Chunk, a_RelX, a_RelY, a_RelZ);
|
||||
if ((Action == paGrowth) && (rand.NextInt(GetGrowthChance(a_Chunk, a_RelX, a_RelY, a_RelZ)) != 0))
|
||||
{
|
||||
Action = paStay;
|
||||
}
|
||||
return Action;
|
||||
}
|
||||
|
||||
/** Generates a int value between 4 and 25 based on surrounding blocks that affect how quickly the plant grows.
|
||||
The higher the value, the less likely the plant is to grow */
|
||||
virtual int GetGrowthChance(cChunk & a_Chunk, int a_RelX, int a_RelY, int a_RelZ)
|
||||
{
|
||||
float Chance = 1.0f;
|
||||
a_RelY -= 1;
|
||||
for (int x = -1; x < 2; ++x)
|
||||
{
|
||||
for (int z = -1; z < 2; ++z)
|
||||
{
|
||||
float Adjustment = 0.0f;
|
||||
BLOCKTYPE Block;
|
||||
NIBBLETYPE Meta;
|
||||
|
||||
// If the chunk we are trying to get the block information from is loaded
|
||||
if (a_Chunk.UnboundedRelGetBlock(a_RelX + x, a_RelY, a_RelZ + z, Block, Meta))
|
||||
{
|
||||
cBlockHandler * Handler = cBlockInfo::Get(Block).m_Handler;
|
||||
|
||||
// If the block affects growth, add to the adjustment
|
||||
if (Handler->CanSustainPlant(m_BlockType))
|
||||
{
|
||||
Adjustment = 1.0f;
|
||||
|
||||
// Farmland alters the chance further if it is watered
|
||||
if ((Block == E_BLOCK_FARMLAND) && (Meta != 0))
|
||||
{
|
||||
Adjustment = 3.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If this is not the block right underneath the plant, it has little effect on the growth
|
||||
if ((x != 0) || (z != 0))
|
||||
{
|
||||
Adjustment /= 4.0f;
|
||||
}
|
||||
|
||||
Chance += Adjustment;
|
||||
}
|
||||
}
|
||||
return FloorC(24.0f / Chance) + 1;
|
||||
}
|
||||
};
|
@ -1,7 +1,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "BlockHandler.h"
|
||||
#include "BlockPlant.h"
|
||||
#include "../World.h"
|
||||
|
||||
|
||||
@ -9,11 +9,12 @@
|
||||
|
||||
|
||||
class cBlockStemsHandler :
|
||||
public cBlockHandler
|
||||
public cBlockPlant
|
||||
{
|
||||
typedef cBlockPlant Super;
|
||||
public:
|
||||
cBlockStemsHandler(BLOCKTYPE a_BlockType)
|
||||
: cBlockHandler(a_BlockType)
|
||||
: Super(a_BlockType, true)
|
||||
{
|
||||
}
|
||||
|
||||
@ -25,18 +26,26 @@ public:
|
||||
|
||||
virtual void OnUpdate(cChunkInterface & cChunkInterface, cWorldInterface & a_WorldInterface, cBlockPluginInterface & a_PluginInterface, cChunk & a_Chunk, int a_RelX, int a_RelY, int a_RelZ) override
|
||||
{
|
||||
NIBBLETYPE Meta = a_Chunk.GetMeta(a_RelX, a_RelY, a_RelZ);
|
||||
if (Meta >= 7)
|
||||
auto Action = CanGrow(a_Chunk, a_RelX, a_RelY, a_RelZ);
|
||||
if (Action == paGrowth)
|
||||
{
|
||||
// Grow the produce:
|
||||
int BlockX = a_RelX + a_Chunk.GetPosX() * cChunkDef::Width;
|
||||
int BlockZ = a_RelZ + a_Chunk.GetPosZ() * cChunkDef::Width;
|
||||
a_Chunk.GetWorld()->GrowMelonPumpkin(BlockX, a_RelY, BlockZ, m_BlockType);
|
||||
NIBBLETYPE Meta = a_Chunk.GetMeta(a_RelX, a_RelY, a_RelZ);
|
||||
if (Meta >= 7)
|
||||
{
|
||||
// Grow the produce:
|
||||
int BlockX = a_RelX + a_Chunk.GetPosX() * cChunkDef::Width;
|
||||
int BlockZ = a_RelZ + a_Chunk.GetPosZ() * cChunkDef::Width;
|
||||
a_Chunk.GetWorld()->GrowMelonPumpkin(BlockX, a_RelY, BlockZ, m_BlockType);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Grow the stem:
|
||||
a_Chunk.FastSetBlock(a_RelX, a_RelY, a_RelZ, m_BlockType, Meta + 1);
|
||||
}
|
||||
}
|
||||
else
|
||||
else if (Action == paDeath)
|
||||
{
|
||||
// Grow the stem:
|
||||
a_Chunk.FastSetBlock(a_RelX, a_RelY, a_RelZ, m_BlockType, Meta + 1);
|
||||
a_Chunk.GetWorld()->DigBlock(a_RelX + a_Chunk.GetPosX() * cChunkDef::Width, a_RelY, a_RelZ + a_Chunk.GetPosZ() * cChunkDef::Width);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,18 +1,19 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "BlockHandler.h"
|
||||
#include "BlockPlant.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class cBlockSugarcaneHandler :
|
||||
public cBlockHandler
|
||||
public cBlockPlant
|
||||
{
|
||||
typedef cBlockPlant Super;
|
||||
public:
|
||||
cBlockSugarcaneHandler(BLOCKTYPE a_BlockType)
|
||||
: cBlockHandler(a_BlockType)
|
||||
: Super(a_BlockType, false)
|
||||
{
|
||||
}
|
||||
|
||||
@ -73,7 +74,10 @@ public:
|
||||
|
||||
virtual void OnUpdate(cChunkInterface & cChunkInterface, cWorldInterface & a_WorldInterface, cBlockPluginInterface & a_PluginInterface, cChunk & a_Chunk, int a_RelX, int a_RelY, int a_RelZ) override
|
||||
{
|
||||
a_Chunk.GetWorld()->GrowSugarcane(a_RelX + a_Chunk.GetPosX() * cChunkDef::Width, a_RelY, a_RelZ + a_Chunk.GetPosZ() * cChunkDef::Width, 1);
|
||||
if (CanGrow(a_Chunk, a_RelX, a_RelY, a_RelZ) == paGrowth)
|
||||
{
|
||||
a_Chunk.GetWorld()->GrowSugarcane(a_RelX + a_Chunk.GetPosX() * cChunkDef::Width, a_RelY, a_RelZ + a_Chunk.GetPosZ() * cChunkDef::Width, 1);
|
||||
}
|
||||
}
|
||||
|
||||
virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) override
|
||||
@ -81,6 +85,19 @@ public:
|
||||
UNUSED(a_Meta);
|
||||
return 7;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
virtual PlantAction CanGrow(cChunk & a_Chunk, int a_RelX, int a_RelY, int a_RelZ) override
|
||||
{
|
||||
auto Action = paStay;
|
||||
if (((a_RelY + 1) < cChunkDef::Height) && (a_Chunk.GetBlock(a_RelX, a_RelY + 1, a_RelZ) == E_BLOCK_AIR))
|
||||
{
|
||||
Action = Super::CanGrow(a_Chunk, a_RelX, a_RelY, a_RelZ);
|
||||
}
|
||||
|
||||
return Action;
|
||||
}
|
||||
} ;
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user