summaryrefslogtreecommitdiffstats
path: root/src/Mobs/Villager.cpp
diff options
context:
space:
mode:
authordaniel0916 <theschokolps@gmail.com>2014-04-07 20:12:17 +0200
committerdaniel0916 <theschokolps@gmail.com>2014-04-07 20:12:17 +0200
commit2e9754ac1cf0537c12ab7974cf55c451c0724540 (patch)
tree713c5b8c8f22f77893b30b9c8cefca4a7c491483 /src/Mobs/Villager.cpp
parentFixed merge conflict (diff)
parentFixed some more minor issues with the redstone simulator. (diff)
downloadcuberite-2e9754ac1cf0537c12ab7974cf55c451c0724540.tar
cuberite-2e9754ac1cf0537c12ab7974cf55c451c0724540.tar.gz
cuberite-2e9754ac1cf0537c12ab7974cf55c451c0724540.tar.bz2
cuberite-2e9754ac1cf0537c12ab7974cf55c451c0724540.tar.lz
cuberite-2e9754ac1cf0537c12ab7974cf55c451c0724540.tar.xz
cuberite-2e9754ac1cf0537c12ab7974cf55c451c0724540.tar.zst
cuberite-2e9754ac1cf0537c12ab7974cf55c451c0724540.zip
Diffstat (limited to '')
-rw-r--r--src/Mobs/Villager.cpp161
1 files changed, 159 insertions, 2 deletions
diff --git a/src/Mobs/Villager.cpp b/src/Mobs/Villager.cpp
index 7f89fb6cc..bbd8d6aaa 100644
--- a/src/Mobs/Villager.cpp
+++ b/src/Mobs/Villager.cpp
@@ -3,6 +3,9 @@
#include "Villager.h"
#include "../World.h"
+#include "../BlockArea.h"
+#include "../Blocks/BlockHandler.h"
+#include "../BlockInServerPluginInterface.h"
@@ -10,7 +13,9 @@
cVillager::cVillager(eVillagerType VillagerType) :
super("Villager", mtVillager, "", "", 0.6, 1.8),
- m_Type(VillagerType)
+ m_ActionCountDown(-1),
+ m_Type(VillagerType),
+ m_VillagerAction(false)
{
}
@@ -21,7 +26,7 @@ cVillager::cVillager(eVillagerType VillagerType) :
void cVillager::DoTakeDamage(TakeDamageInfo & a_TDI)
{
super::DoTakeDamage(a_TDI);
- if (a_TDI.Attacker->IsPlayer())
+ if ((a_TDI.Attacker != NULL) && a_TDI.Attacker->IsPlayer())
{
if (m_World->GetTickRandomNumber(5) == 3)
{
@@ -33,3 +38,155 @@ void cVillager::DoTakeDamage(TakeDamageInfo & a_TDI)
+
+void cVillager::Tick(float a_Dt, cChunk & a_Chunk)
+{
+ super::Tick(a_Dt, a_Chunk);
+
+ if (m_ActionCountDown > -1)
+ {
+ m_ActionCountDown--;
+ if (m_ActionCountDown == 0)
+ {
+ switch (m_Type)
+ {
+ case vtFarmer:
+ {
+ HandleFarmerPlaceCrops();
+ }
+ }
+ }
+ return;
+ }
+
+ if (m_VillagerAction)
+ {
+ switch (m_Type)
+ {
+ case vtFarmer:
+ {
+ HandleFarmerTryHarvestCrops();
+ }
+ }
+ m_VillagerAction = false;
+ return;
+ }
+
+ // Don't always try to do a special action. Each tick has 1% to do a special action.
+ if (m_World->GetTickRandomNumber(99) != 0)
+ {
+ return;
+ }
+
+ switch (m_Type)
+ {
+ case vtFarmer:
+ {
+ HandleFarmerPrepareFarmCrops();
+ }
+ }
+}
+
+
+
+
+////////////////////////////////////////////////////////////////////////////////
+// Farmer functions.
+void cVillager::HandleFarmerPrepareFarmCrops()
+{
+ if (!m_World->VillagersShouldHarvestCrops())
+ {
+ return;
+ }
+
+ cBlockArea Surrounding;
+ /// Read a 11x7x11 area.
+ Surrounding.Read(
+ m_World,
+ (int) GetPosX() - 5,
+ (int) GetPosX() + 5,
+ (int) GetPosY() - 3,
+ (int) GetPosY() + 3,
+ (int) GetPosZ() - 5,
+ (int) GetPosZ() + 5
+ );
+
+ for (int I = 0; I < 5; I++)
+ {
+ for (int Y = 0; Y < 6; Y++)
+ {
+ // Pick random coordinates and check for crops.
+ int X = m_World->GetTickRandomNumber(11);
+ int Z = m_World->GetTickRandomNumber(11);
+
+ // A villager can't farm this.
+ if (!IsBlockFarmable(Surrounding.GetRelBlockType(X, Y, Z)))
+ {
+ continue;
+ }
+ if (Surrounding.GetRelBlockMeta(X, Y, Z) != 0x7)
+ {
+ continue;
+ }
+
+ m_VillagerAction = true;
+ m_CropsPos = Vector3i((int) GetPosX() + X - 5, (int) GetPosY() + Y - 3, (int) GetPosZ() + Z - 5);
+ MoveToPosition(Vector3f((float) (m_CropsPos.x + 0.5), (float) m_CropsPos.y, (float) (m_CropsPos.z + 0.5)));
+ return;
+ } // for Y loop.
+ } // Repeat the procces 5 times.
+}
+
+
+
+
+
+void cVillager::HandleFarmerTryHarvestCrops()
+{
+ // Harvest the crops if the villager isn't moving and if the crops are closer then 2 blocks.
+ if (!m_bMovingToDestination && (GetPosition() - m_CropsPos).Length() < 2)
+ {
+ // Check if the blocks didn't change while the villager was walking to the coordinates.
+ BLOCKTYPE CropBlock = m_World->GetBlock(m_CropsPos.x, m_CropsPos.y, m_CropsPos.z);
+ if (IsBlockFarmable(CropBlock) && m_World->GetBlockMeta(m_CropsPos.x, m_CropsPos.y, m_CropsPos.z) == 0x7)
+ {
+ cBlockHandler * Handler = cBlockInfo::GetHandler(CropBlock);
+ cChunkInterface ChunkInterface(m_World->GetChunkMap());
+ cBlockInServerPluginInterface PluginInterface(*m_World);
+ Handler->DropBlock(ChunkInterface, *m_World, PluginInterface, this, m_CropsPos.x, m_CropsPos.y, m_CropsPos.z);
+ m_World->SetBlock(m_CropsPos.x, m_CropsPos.y, m_CropsPos.z, E_BLOCK_AIR, 0);
+ m_ActionCountDown = 20;
+ }
+ }
+}
+
+
+
+
+void cVillager::HandleFarmerPlaceCrops()
+{
+ // Check if there is still farmland at the spot where the crops were.
+ if (m_World->GetBlock(m_CropsPos.x, m_CropsPos.y - 1, m_CropsPos.z) == E_BLOCK_FARMLAND)
+ {
+ m_World->SetBlock(m_CropsPos.x, m_CropsPos.y, m_CropsPos.z, E_BLOCK_CROPS, 0);
+ }
+}
+
+
+
+
+
+bool cVillager::IsBlockFarmable(BLOCKTYPE a_BlockType)
+{
+ switch (a_BlockType)
+ {
+ case E_BLOCK_CROPS:
+ case E_BLOCK_POTATOES:
+ case E_BLOCK_CARROTS:
+ {
+ return true;
+ }
+ }
+ return false;
+}
+