summaryrefslogtreecommitdiffstats
path: root/src/Mobs
diff options
context:
space:
mode:
Diffstat (limited to 'src/Mobs')
-rw-r--r--src/Mobs/Chicken.cpp1
-rw-r--r--src/Mobs/Chicken.h3
-rw-r--r--src/Mobs/Cow.cpp2
-rw-r--r--src/Mobs/Cow.h3
-rw-r--r--src/Mobs/Mooshroom.cpp2
-rw-r--r--src/Mobs/Mooshroom.h2
-rw-r--r--src/Mobs/PassiveMonster.cpp16
-rw-r--r--src/Mobs/PassiveMonster.h3
-rw-r--r--src/Mobs/Pig.cpp2
-rw-r--r--src/Mobs/Pig.h3
-rw-r--r--src/Mobs/Sheep.cpp1
-rw-r--r--src/Mobs/Sheep.h2
-rw-r--r--src/Mobs/Villager.cpp156
-rw-r--r--src/Mobs/Villager.h26
14 files changed, 211 insertions, 11 deletions
diff --git a/src/Mobs/Chicken.cpp b/src/Mobs/Chicken.cpp
index 087fd088a..fab92ce49 100644
--- a/src/Mobs/Chicken.cpp
+++ b/src/Mobs/Chicken.cpp
@@ -9,7 +9,6 @@
-
cChicken::cChicken(void) :
super("Chicken", mtChicken, "mob.chicken.hurt", "mob.chicken.hurt", 0.3, 0.4),
m_EggDropTimer(0)
diff --git a/src/Mobs/Chicken.h b/src/Mobs/Chicken.h
index 979c4d8a0..a4c1d6b9e 100644
--- a/src/Mobs/Chicken.h
+++ b/src/Mobs/Chicken.h
@@ -19,8 +19,9 @@ public:
virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = NULL) override;
virtual void Tick(float a_Dt, cChunk & a_Chunk) override;
-private:
+ virtual const cItem GetFollowedItem(void) const override { return cItem(E_ITEM_SEEDS); }
+private:
int m_EggDropTimer;
} ;
diff --git a/src/Mobs/Cow.cpp b/src/Mobs/Cow.cpp
index 9eb74dac2..d8e905217 100644
--- a/src/Mobs/Cow.cpp
+++ b/src/Mobs/Cow.cpp
@@ -41,5 +41,3 @@ void cCow::OnRightClicked(cPlayer & a_Player)
}
}
-
-
diff --git a/src/Mobs/Cow.h b/src/Mobs/Cow.h
index 0391d4a31..973171ab5 100644
--- a/src/Mobs/Cow.h
+++ b/src/Mobs/Cow.h
@@ -19,6 +19,9 @@ public:
virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = NULL) override;
virtual void OnRightClicked(cPlayer & a_Player) override;
+
+ virtual const cItem GetFollowedItem(void) const override { return cItem(E_ITEM_WHEAT); }
+
} ;
diff --git a/src/Mobs/Mooshroom.cpp b/src/Mobs/Mooshroom.cpp
index 940e2db44..88101cd83 100644
--- a/src/Mobs/Mooshroom.cpp
+++ b/src/Mobs/Mooshroom.cpp
@@ -6,7 +6,6 @@
-
// TODO: Milk Cow
@@ -30,4 +29,3 @@ void cMooshroom::GetDrops(cItems & a_Drops, cEntity * a_Killer)
-
diff --git a/src/Mobs/Mooshroom.h b/src/Mobs/Mooshroom.h
index 73f6348b6..c94301098 100644
--- a/src/Mobs/Mooshroom.h
+++ b/src/Mobs/Mooshroom.h
@@ -18,6 +18,8 @@ public:
CLASS_PROTODEF(cMooshroom);
virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = NULL) override;
+
+ virtual const cItem GetFollowedItem(void) const override { return cItem(E_ITEM_WHEAT); }
} ;
diff --git a/src/Mobs/PassiveMonster.cpp b/src/Mobs/PassiveMonster.cpp
index d774d3170..904cd63cc 100644
--- a/src/Mobs/PassiveMonster.cpp
+++ b/src/Mobs/PassiveMonster.cpp
@@ -3,7 +3,7 @@
#include "PassiveMonster.h"
#include "../World.h"
-
+#include "../Entities/Player.h"
@@ -39,6 +39,20 @@ void cPassiveMonster::Tick(float a_Dt, cChunk & a_Chunk)
{
CheckEventLostPlayer();
}
+ cItem FollowedItem = GetFollowedItem();
+ if (FollowedItem.IsEmpty())
+ {
+ return;
+ }
+ cPlayer * a_Closest_Player = m_World->FindClosestPlayer(GetPosition(), (float)m_SightDistance);
+ if (a_Closest_Player != NULL)
+ {
+ if (a_Closest_Player->GetEquippedItem().IsEqual(FollowedItem))
+ {
+ Vector3d PlayerPos = a_Closest_Player->GetPosition();
+ MoveToPosition(PlayerPos);
+ }
+ }
}
diff --git a/src/Mobs/PassiveMonster.h b/src/Mobs/PassiveMonster.h
index 14a6be6b1..0b3c155da 100644
--- a/src/Mobs/PassiveMonster.h
+++ b/src/Mobs/PassiveMonster.h
@@ -19,6 +19,9 @@ public:
/// When hit by someone, run away
virtual void DoTakeDamage(TakeDamageInfo & a_TDI) override;
+ /** Returns the item that the animal of this class follows when a player holds it in hand
+ Return an empty item not to follow (default). */
+ virtual const cItem GetFollowedItem(void) const { return cItem(); }
} ;
diff --git a/src/Mobs/Pig.cpp b/src/Mobs/Pig.cpp
index 0871a38a9..d8f3dda37 100644
--- a/src/Mobs/Pig.cpp
+++ b/src/Mobs/Pig.cpp
@@ -73,5 +73,3 @@ void cPig::OnRightClicked(cPlayer & a_Player)
-
-
diff --git a/src/Mobs/Pig.h b/src/Mobs/Pig.h
index 4fd0d8db8..d434324c1 100644
--- a/src/Mobs/Pig.h
+++ b/src/Mobs/Pig.h
@@ -19,6 +19,9 @@ public:
virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = NULL) override;
virtual void OnRightClicked(cPlayer & a_Player) override;
+
+ virtual const cItem GetFollowedItem(void) const override { return cItem(E_ITEM_CARROT); }
+
bool IsSaddled(void) const { return m_bIsSaddled; }
private:
diff --git a/src/Mobs/Sheep.cpp b/src/Mobs/Sheep.cpp
index 702108ae4..4761103e5 100644
--- a/src/Mobs/Sheep.cpp
+++ b/src/Mobs/Sheep.cpp
@@ -97,3 +97,4 @@ void cSheep::Tick(float a_Dt, cChunk & a_Chunk)
}
}
}
+
diff --git a/src/Mobs/Sheep.h b/src/Mobs/Sheep.h
index 4eee3db1c..402e8e61c 100644
--- a/src/Mobs/Sheep.h
+++ b/src/Mobs/Sheep.h
@@ -21,6 +21,8 @@ public:
virtual void OnRightClicked(cPlayer & a_Player) override;
virtual void Tick(float a_Dt, cChunk & a_Chunk) override;
+ virtual const cItem GetFollowedItem(void) const override { return cItem(E_ITEM_WHEAT); }
+
bool IsSheared(void) const { return m_IsSheared; }
int GetFurColor(void) const { return m_WoolColor; }
diff --git a/src/Mobs/Villager.cpp b/src/Mobs/Villager.cpp
index c8ff4f101..44ec14295 100644
--- a/src/Mobs/Villager.cpp
+++ b/src/Mobs/Villager.cpp
@@ -3,6 +3,8 @@
#include "Villager.h"
#include "../World.h"
+#include "../BlockArea.h"
+#include "../Blocks/BlockHandler.h"
@@ -10,7 +12,9 @@
cVillager::cVillager(eVillagerType VillagerType) :
super("Villager", mtVillager, "", "", 0.6, 1.8),
- m_Type(VillagerType)
+ m_Type(VillagerType),
+ m_VillagerAction(false),
+ m_ActionCountDown(-1)
{
}
@@ -33,3 +37,153 @@ 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 = cBlockHandler::GetBlockHandler(CropBlock);
+ Handler->DropBlock(m_World, 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;
+}
+
diff --git a/src/Mobs/Villager.h b/src/Mobs/Villager.h
index 4cd9aaa8e..b99ae876f 100644
--- a/src/Mobs/Villager.h
+++ b/src/Mobs/Villager.h
@@ -29,12 +29,36 @@ public:
CLASS_PROTODEF(cVillager);
+ // Override functions
virtual void DoTakeDamage(TakeDamageInfo & a_TDI) override;
- int GetVilType(void) const { return m_Type; }
+ virtual void Tick (float a_Dt, cChunk & a_Chunk) override;
+
+ // cVillager functions
+ /** return true if the given blocktype are: crops, potatoes or carrots.*/
+ bool IsBlockFarmable(BLOCKTYPE a_BlockType);
+
+ //////////////////////////////////////////////////////////////////
+ // Farmer functions
+ /** It searches in a 11x7x11 area for crops. If it found some it will navigate to them.*/
+ void HandleFarmerPrepareFarmCrops();
+
+ /** Looks if the farmer has reached it's destination, and if it's still crops and the destination is closer then 2 blocks it will harvest them.*/
+ void HandleFarmerTryHarvestCrops();
+
+ /** Replaces the crops he harvested.*/
+ void HandleFarmerPlaceCrops();
+
+ // Get and set functions.
+ int GetVilType(void) const { return m_Type; }
+ Vector3i GetCropsPos(void) const { return m_CropsPos; }
+ bool DoesHaveActionActivated(void) const { return m_VillagerAction; }
private:
+ int m_ActionCountDown;
int m_Type;
+ bool m_VillagerAction;
+ Vector3i m_CropsPos;
} ;