summaryrefslogtreecommitdiffstats
path: root/src/Mobs
diff options
context:
space:
mode:
authorLogicParrot <LogicParrot@users.noreply.github.com>2017-08-22 14:15:36 +0200
committerLogicParrot <LogicParrot@users.noreply.github.com>2017-08-22 19:55:30 +0200
commit18c3dd3b4fc6c40c103296e7b5a53a99fa5e758e (patch)
tree221db2c2a9f4c3388f50edf79d38448ca1a0e4a2 /src/Mobs
parentd (diff)
downloadcuberite-18c3dd3b4fc6c40c103296e7b5a53a99fa5e758e.tar
cuberite-18c3dd3b4fc6c40c103296e7b5a53a99fa5e758e.tar.gz
cuberite-18c3dd3b4fc6c40c103296e7b5a53a99fa5e758e.tar.bz2
cuberite-18c3dd3b4fc6c40c103296e7b5a53a99fa5e758e.tar.lz
cuberite-18c3dd3b4fc6c40c103296e7b5a53a99fa5e758e.tar.xz
cuberite-18c3dd3b4fc6c40c103296e7b5a53a99fa5e758e.tar.zst
cuberite-18c3dd3b4fc6c40c103296e7b5a53a99fa5e758e.zip
Diffstat (limited to 'src/Mobs')
-rw-r--r--src/Mobs/Bat.cpp9
-rw-r--r--src/Mobs/Behaviors/BehaviorBreeder.cpp304
-rw-r--r--src/Mobs/Behaviors/BehaviorBreeder.h54
-rw-r--r--src/Mobs/Behaviors/BehaviorItemFollower.cpp2
-rw-r--r--src/Mobs/Behaviors/BehaviorItemFollower.h10
-rw-r--r--src/Mobs/Blaze.cpp2
-rw-r--r--src/Mobs/CaveSpider.cpp2
-rw-r--r--src/Mobs/Chicken.cpp88
-rw-r--r--src/Mobs/Chicken.h24
-rw-r--r--src/Mobs/Cow.cpp42
-rw-r--r--src/Mobs/Cow.h20
-rw-r--r--src/Mobs/Creeper.cpp1
-rw-r--r--src/Mobs/Creeper.h27
-rw-r--r--src/Mobs/Ghast.cpp56
-rw-r--r--src/Mobs/Ghast.h13
-rw-r--r--src/Mobs/Monster.cpp11
-rw-r--r--src/Mobs/Monster.h6
-rw-r--r--src/Mobs/PassiveMonster.cpp4
-rw-r--r--src/Mobs/PassiveMonster.h4
-rw-r--r--src/Mobs/Silverfish.h14
-rw-r--r--src/Mobs/Skeleton.cpp94
-rw-r--r--src/Mobs/Skeleton.h20
-rw-r--r--src/Mobs/Slime.cpp114
-rw-r--r--src/Mobs/Slime.h32
-rw-r--r--src/Mobs/Spider.cpp92
-rw-r--r--src/Mobs/Wolf.cpp656
-rw-r--r--src/Mobs/Wolf.h104
27 files changed, 897 insertions, 908 deletions
diff --git a/src/Mobs/Bat.cpp b/src/Mobs/Bat.cpp
index e419ceb2d..906b99320 100644
--- a/src/Mobs/Bat.cpp
+++ b/src/Mobs/Bat.cpp
@@ -4,12 +4,13 @@
#include "Bat.h"
#include "../Chunk.h"
-
cBat::cBat(void) :
- super("Bat", mtBat, "entity.bat.hurt", "entity.bat.death", 0.5, 0.9)
+ super("Bat", mtBat, "entity.bat.hurt", "entity.bat.death", 0.5, 0.9)
{
- SetGravity(-2.0f);
- SetAirDrag(0.05f);
+ SetGravity(-2.0f);
+ SetAirDrag(0.05f);
+
+
}
diff --git a/src/Mobs/Behaviors/BehaviorBreeder.cpp b/src/Mobs/Behaviors/BehaviorBreeder.cpp
index ea3e10026..ddca1715a 100644
--- a/src/Mobs/Behaviors/BehaviorBreeder.cpp
+++ b/src/Mobs/Behaviors/BehaviorBreeder.cpp
@@ -9,25 +9,15 @@
#include "../../Item.h"
#include "../../BoundingBox.h"
-iBehaviorBreeder::~iBehaviorBreeder()
+cBehaviorBreeder::cBehaviorBreeder(cMonster * a_Parent) :
+ m_Parent(a_Parent),
+ m_LovePartner(nullptr),
+ m_LoveTimer(0),
+ m_LoveCooldown(0),
+ m_MatingTimer(0),
{
-
-}
-
-
-
-
-
-cBehaviorBreeder::cBehaviorBreeder(cMonster * a_Parent, cItems & a_BreedingItems) :
- m_Parent(a_Parent),
- m_LovePartner(nullptr),
- m_LoveTimer(0),
- m_LoveCooldown(0),
- m_MatingTimer(0),
- m_BreedingItems(a_BreedingItems)
-{
- m_Parent = dynamic_cast<cMonster *>(m_ParentInterface);
- ASSERT(m_Parent != nullptr);
+ m_Parent = a_Parent;
+ ASSERT(m_Parent != nullptr);
}
@@ -36,105 +26,105 @@ cBehaviorBreeder::cBehaviorBreeder(cMonster * a_Parent, cItems & a_BreedingItems
bool cBehaviorBreeder::ActiveTick()
{
- cWorld * World = m_Parent->GetWorld();
- // if we have a partner, mate
- if (m_LovePartner != nullptr)
- {
- if (m_MatingTimer > 0)
- {
- // If we should still mate, keep bumping into them until baby is made
- Vector3d Pos = m_LovePartner->GetPosition();
- m_Parent->MoveToPosition(Pos);
- }
- else
- {
- // Mating finished. Spawn baby
- Vector3f Pos = (m_Parent->GetPosition() + m_LovePartner->GetPosition()) * 0.5;
- UInt32 BabyID = World->SpawnMob(Pos.x, Pos.y, Pos.z, m_Parent->GetMobType(), true);
-
- class cBabyInheritCallback :
- public cEntityCallback
- {
- public:
- cMonster * Baby;
- cBabyInheritCallback() : Baby(nullptr) { }
- virtual bool Item(cEntity * a_Entity) override
- {
- Baby = static_cast<cMonster *>(a_Entity);
- return true;
- }
- } Callback;
-
- m_Parent->GetWorld()->DoWithEntityByID(BabyID, Callback);
- if (Callback.Baby != nullptr)
- {
- Callback.Baby->InheritFromParents(m_Parent, m_LovePartner);
- }
-
- cFastRandom Random;
- World->SpawnExperienceOrb(Pos.x, Pos.y, Pos.z, 1 + Random.NextInt(6));
-
- m_LovePartner->GetBehaviorBreeder()->ResetLoveMode();
- ResetLoveMode();
- }
- return true;
- }
-
- // If we are in love mode and we have no partner
- if (m_LoveTimer > 0)
- {
- class LookForLover : public cEntityCallback
- {
- public:
- cMonster * m_Me;
- LookForLover(cMonster * a_Me) :
- m_Me(a_Me)
- {
- }
-
- virtual bool Item(cEntity * a_Entity) override
- {
- // If the entity is not a monster, don't breed with it
- // Also, do not self-breed
- if ((a_Entity->GetEntityType() != cEntity::eEntityType::etMonster) || (a_Entity == m_Me))
- {
- return false;
- }
-
- auto PotentialPartner = static_cast<cMonster*>(a_Entity);
-
- // If the potential partner is not of the same species, don't breed with it
- if (PotentialPartner->GetMobType() != m_Me->GetMobType())
- {
- return false;
- }
-
- auto PartnerBreedingBehavior = PotentialPartner->GetBehaviorBreeder();
- auto MyBreedingBehavior = m_Me->GetBehaviorBreeder();
-
- // If the potential partner is not in love
- // Or they already have a mate, do not breed with them
-
- if ((!PartnerBreedingBehavior->IsInLove()) || (PartnerBreedingBehavior->GetPartner() != nullptr))
- {
- return false;
- }
-
- // All conditions met, let's breed!
- PartnerBreedingBehavior->EngageLoveMode(m_Me);
- MyBreedingBehavior->EngageLoveMode(PotentialPartner);
- return true;
- }
- } Callback(m_Parent);
-
- World->ForEachEntityInBox(cBoundingBox(m_Parent->GetPosition(), 8, 8), Callback);
- if (m_LovePartner != nullptr)
- {
- return true; // We found love and took control of the monster, prevent other Behaviors from doing so
- }
- }
-
- return false;
+ cWorld * World = m_Parent->GetWorld();
+ // if we have a partner, mate
+ if (m_LovePartner != nullptr)
+ {
+ if (m_MatingTimer > 0)
+ {
+ // If we should still mate, keep bumping into them until baby is made
+ Vector3d Pos = m_LovePartner->GetPosition();
+ m_Parent->MoveToPosition(Pos);
+ }
+ else
+ {
+ // Mating finished. Spawn baby
+ Vector3f Pos = (m_Parent->GetPosition() + m_LovePartner->GetPosition()) * 0.5;
+ UInt32 BabyID = World->SpawnMob(Pos.x, Pos.y, Pos.z, m_Parent->GetMobType(), true);
+
+ class cBabyInheritCallback :
+ public cEntityCallback
+ {
+ public:
+ cMonster * Baby;
+ cBabyInheritCallback() : Baby(nullptr) { }
+ virtual bool Item(cEntity * a_Entity) override
+ {
+ Baby = static_cast<cMonster *>(a_Entity);
+ return true;
+ }
+ } Callback;
+
+ m_Parent->GetWorld()->DoWithEntityByID(BabyID, Callback);
+ if (Callback.Baby != nullptr)
+ {
+ Callback.Baby->InheritFromParents(m_Parent, m_LovePartner);
+ }
+
+ cFastRandom Random;
+ World->SpawnExperienceOrb(Pos.x, Pos.y, Pos.z, 1 + Random.NextInt(6));
+
+ m_LovePartner->GetBehaviorBreeder()->ResetLoveMode();
+ ResetLoveMode();
+ }
+ return true;
+ }
+
+ // If we are in love mode and we have no partner
+ if (m_LoveTimer > 0)
+ {
+ class LookForLover : public cEntityCallback
+ {
+ public:
+ cMonster * m_Me;
+ LookForLover(cMonster * a_Me) :
+ m_Me(a_Me)
+ {
+ }
+
+ virtual bool Item(cEntity * a_Entity) override
+ {
+ // If the entity is not a monster, don't breed with it
+ // Also, do not self-breed
+ if ((a_Entity->GetEntityType() != cEntity::eEntityType::etMonster) || (a_Entity == m_Me))
+ {
+ return false;
+ }
+
+ auto PotentialPartner = static_cast<cMonster*>(a_Entity);
+
+ // If the potential partner is not of the same species, don't breed with it
+ if (PotentialPartner->GetMobType() != m_Me->GetMobType())
+ {
+ return false;
+ }
+
+ auto PartnerBreedingBehavior = PotentialPartner->GetBehaviorBreeder();
+ auto MyBreedingBehavior = m_Me->GetBehaviorBreeder();
+
+ // If the potential partner is not in love
+ // Or they already have a mate, do not breed with them
+
+ if ((!PartnerBreedingBehavior->IsInLove()) || (PartnerBreedingBehavior->GetPartner() != nullptr))
+ {
+ return false;
+ }
+
+ // All conditions met, let's breed!
+ PartnerBreedingBehavior->EngageLoveMode(m_Me);
+ MyBreedingBehavior->EngageLoveMode(PotentialPartner);
+ return true;
+ }
+ } Callback(m_Parent);
+
+ World->ForEachEntityInBox(cBoundingBox(m_Parent->GetPosition(), 8, 8), Callback);
+ if (m_LovePartner != nullptr)
+ {
+ return true; // We found love and took control of the monster, prevent other Behaviors from doing so
+ }
+ }
+
+ return false;
}
@@ -143,18 +133,18 @@ bool cBehaviorBreeder::ActiveTick()
void cBehaviorBreeder::Tick()
{
- if (m_MatingTimer > 0)
- {
- m_MatingTimer--;
- }
- if (m_LoveCooldown > 0)
- {
- m_LoveCooldown--;
- }
- if (m_LoveTimer > 0)
- {
- m_LoveTimer--;
- }
+ if (m_MatingTimer > 0)
+ {
+ m_MatingTimer--;
+ }
+ if (m_LoveCooldown > 0)
+ {
+ m_LoveCooldown--;
+ }
+ if (m_LoveTimer > 0)
+ {
+ m_LoveTimer--;
+ }
}
@@ -163,10 +153,10 @@ void cBehaviorBreeder::Tick()
void cBehaviorBreeder::Destroyed()
{
- if (m_LovePartner != nullptr)
- {
- m_LovePartner->GetBehaviorBreeder()->ResetLoveMode();
- }
+ if (m_LovePartner != nullptr)
+ {
+ m_LovePartner->GetBehaviorBreeder()->ResetLoveMode();
+ }
}
@@ -175,28 +165,28 @@ void cBehaviorBreeder::Destroyed()
void cBehaviorBreeder::OnRightClicked(cPlayer & a_Player)
{
- // If a player holding breeding items right-clicked me, go into love mode
- if ((m_LoveCooldown == 0) && !IsInLove() && !m_Parent->IsBaby())
- {
- short HeldItem = a_Player.GetEquippedItem().m_ItemType;
- if (m_BreedingItems.ContainsType(HeldItem))
- {
- if (!a_Player.IsGameModeCreative())
- {
- a_Player.GetInventory().RemoveOneEquippedItem();
- }
- m_LoveTimer = 20 * 30; // half a minute
- m_Parent->GetWorld()->BroadcastEntityStatus(*m_Parent, cEntity::eEntityStatus::esMobInLove);
- }
- }
+ // If a player holding breeding items right-clicked me, go into love mode
+ if ((m_LoveCooldown == 0) && !IsInLove() && !m_Parent->IsBaby())
+ {
+ short HeldItem = a_Player.GetEquippedItem().m_ItemType;
+ if (m_BreedingItems.ContainsType(HeldItem))
+ {
+ if (!a_Player.IsGameModeCreative())
+ {
+ a_Player.GetInventory().RemoveOneEquippedItem();
+ }
+ m_LoveTimer = 20 * 30; // half a minute
+ m_Parent->GetWorld()->BroadcastEntityStatus(*m_Parent, cEntity::eEntityStatus::esMobInLove);
+ }
+ }
}
void cBehaviorBreeder::EngageLoveMode(cMonster * a_Partner)
{
- m_LovePartner = a_Partner;
- m_MatingTimer = 50; // about 3 seconds of mating
+ m_LovePartner = a_Partner;
+ m_MatingTimer = 50; // about 3 seconds of mating
}
@@ -205,13 +195,13 @@ void cBehaviorBreeder::EngageLoveMode(cMonster * a_Partner)
void cBehaviorBreeder::ResetLoveMode()
{
- m_LovePartner = nullptr;
- m_LoveTimer = 0;
- m_MatingTimer = 0;
- m_LoveCooldown = 20 * 60 * 5; // 5 minutes
+ m_LovePartner = nullptr;
+ m_LoveTimer = 0;
+ m_MatingTimer = 0;
+ m_LoveCooldown = 20 * 60 * 5; // 5 minutes
- // when an animal is in love mode, the client only stops sending the hearts if we let them know it's in cooldown, which is done with the "age" metadata
- m_Parent->GetWorld()->BroadcastEntityMetadata(*m_Parent);
+ // when an animal is in love mode, the client only stops sending the hearts if we let them know it's in cooldown, which is done with the "age" metadata
+ m_Parent->GetWorld()->BroadcastEntityMetadata(*m_Parent);
}
@@ -220,7 +210,7 @@ void cBehaviorBreeder::ResetLoveMode()
bool cBehaviorBreeder::IsInLove() const
{
- return m_LoveTimer > 0;
+ return m_LoveTimer > 0;
}
@@ -229,5 +219,5 @@ bool cBehaviorBreeder::IsInLove() const
bool cBehaviorBreeder::IsInLoveCooldown() const
{
- return (m_LoveCooldown > 0);
+ return (m_LoveCooldown > 0);
}
diff --git a/src/Mobs/Behaviors/BehaviorBreeder.h b/src/Mobs/Behaviors/BehaviorBreeder.h
index 4d7dc1aa4..fa52a40d4 100644
--- a/src/Mobs/Behaviors/BehaviorBreeder.h
+++ b/src/Mobs/Behaviors/BehaviorBreeder.h
@@ -17,44 +17,42 @@ class cBehaviorBreeder
{
public:
- cBehaviorBreeder(cMonster * a_Parent, cItems & a_BreedingItems);
+ cBehaviorBreeder(cMonster * a_Parent, cItems & a_BreedingItems);
- // Functions our host Monster should invoke:
- void Tick();
- bool ActiveTick();
- void OnRightClicked(cPlayer & a_Player);
- void Destroyed();
+ // Functions our host Monster should invoke:
+ void Tick();
+ bool ActiveTick();
+ void OnRightClicked(cPlayer & a_Player);
+ void Destroyed();
- /** Returns the partner which the monster is currently mating with. */
- cMonster * GetPartner(void) const { return m_LovePartner; }
+ /** Returns the partner which the monster is currently mating with. */
+ cMonster * GetPartner(void) const { return m_LovePartner; }
- /** Start the mating process. Causes the monster to keep bumping into the partner until m_MatingTimer reaches zero. */
- void EngageLoveMode(cMonster * a_Partner);
+ /** Start the mating process. Causes the monster to keep bumping into the partner until m_MatingTimer reaches zero. */
+ void EngageLoveMode(cMonster * a_Partner);
- /** Finish the mating process. Called after a baby is born. Resets all breeding related timers and sets m_LoveCooldown to 20 minutes. */
- void ResetLoveMode();
+ /** Finish the mating process. Called after a baby is born. Resets all breeding related timers and sets m_LoveCooldown to 20 minutes. */
+ void ResetLoveMode();
- /** Returns whether the monster has just been fed and is ready to mate. If this is "true" and GetPartner isn't "nullptr", then the monster is mating. */
- bool IsInLove() const;
+ /** Returns whether the monster has just been fed and is ready to mate. If this is "true" and GetPartner isn't "nullptr", then the monster is mating. */
+ bool IsInLove() const;
- /** Returns whether the monster is tired of breeding and is in the cooldown state. */
- bool IsInLoveCooldown() const;
+ /** Returns whether the monster is tired of breeding and is in the cooldown state. */
+ bool IsInLoveCooldown() const;
private:
- /** Our parent */
- cMonster * m_Parent;
+ /** Our parent */
+ cMonster * m_Parent;
- /** The monster's breeding partner. */
- cMonster * m_LovePartner;
+ /** The monster's breeding partner. */
+ cMonster * m_LovePartner;
- /** If above 0, the monster is in love mode, and will breed if a nearby monster is also in love mode. Decrements by 1 per tick till reaching zero. */
- int m_LoveTimer;
+ /** If above 0, the monster is in love mode, and will breed if a nearby monster is also in love mode. Decrements by 1 per tick till reaching zero. */
+ int m_LoveTimer;
- /** If above 0, the monster is in cooldown mode and will refuse to breed. Decrements by 1 per tick till reaching zero. */
- int m_LoveCooldown;
+ /** If above 0, the monster is in cooldown mode and will refuse to breed. Decrements by 1 per tick till reaching zero. */
+ int m_LoveCooldown;
- /** The monster is engaged in mating, once this reaches zero, a baby will be born. Decrements by 1 per tick till reaching zero, then a baby is made and ResetLoveMode() is called. */
- int m_MatingTimer;
-
- cItems & m_BreedingItems;
+ /** The monster is engaged in mating, once this reaches zero, a baby will be born. Decrements by 1 per tick till reaching zero, then a baby is made and ResetLoveMode() is called. */
+ int m_MatingTimer;
};
diff --git a/src/Mobs/Behaviors/BehaviorItemFollower.cpp b/src/Mobs/Behaviors/BehaviorItemFollower.cpp
index 89e25ed57..275cb8c24 100644
--- a/src/Mobs/Behaviors/BehaviorItemFollower.cpp
+++ b/src/Mobs/Behaviors/BehaviorItemFollower.cpp
@@ -21,7 +21,7 @@ bool cBehaviorItemFollower::ActiveTick()
{
cWorld * World = m_Parent->GetWorld();
cItems FollowedItems;
- m_ParentInterface->GetFollowedItems(FollowedItems);
+ m_Parent->GetFollowedItems(FollowedItems);
if (FollowedItems.Size() > 0)
{
cPlayer * a_Closest_Player = m_Parent->GetNearestPlayer();
diff --git a/src/Mobs/Behaviors/BehaviorItemFollower.h b/src/Mobs/Behaviors/BehaviorItemFollower.h
index 2abdeb381..28f00c473 100644
--- a/src/Mobs/Behaviors/BehaviorItemFollower.h
+++ b/src/Mobs/Behaviors/BehaviorItemFollower.h
@@ -3,20 +3,16 @@
// Makes the mob follow specific held items
class cBehaviorItemFollower;
-class iBehaviorItemFollower;
-
//fwds
class cMonster;
class cItems;
-
-
-
-
class cBehaviorItemFollower
{
public:
- cBehaviorItemFollower(cMonster * a_Parent);
+ cBehaviorItemFollower(cMonster * a_Parent, cItems & a_Items);
+
+ void GetBreedingItems(cItems & a_Items);
// Functions our host Monster should invoke:
bool ActiveTick();
diff --git a/src/Mobs/Blaze.cpp b/src/Mobs/Blaze.cpp
index 7ada21369..e9126ff2d 100644
--- a/src/Mobs/Blaze.cpp
+++ b/src/Mobs/Blaze.cpp
@@ -9,7 +9,7 @@
cBlaze::cBlaze(void) :
- super("Blaze", mtBlaze, "entity.blaze.hurt", "entity.blaze.death", 0.6, 1.8)
+ super("Blaze", mtBlaze, "entity.blaze.hurt", "entity.blaze.death", 0.6, 1.8, 15)
{
SetGravity(-8.0f);
SetAirDrag(0.05f);
diff --git a/src/Mobs/CaveSpider.cpp b/src/Mobs/CaveSpider.cpp
index 8d8e15d85..78e04f7e0 100644
--- a/src/Mobs/CaveSpider.cpp
+++ b/src/Mobs/CaveSpider.cpp
@@ -8,7 +8,7 @@
cCaveSpider::cCaveSpider(void) :
- super("CaveSpider", mtCaveSpider, "entity.spider.hurt", "entity.spider.death", 0.7, 0.5)
+ super("CaveSpider", mtCaveSpider, "entity.spider.hurt", "entity.spider.death", 0.7, 0.5, 15)
{
}
diff --git a/src/Mobs/Chicken.cpp b/src/Mobs/Chicken.cpp
index 1068295e6..80cff7fb8 100644
--- a/src/Mobs/Chicken.cpp
+++ b/src/Mobs/Chicken.cpp
@@ -5,16 +5,12 @@
-
-
-
-
cChicken::cChicken(void) :
- super("Chicken", mtChicken, "entity.chicken.hurt", "entity.chicken.death", 0.3, 0.4),
- m_EggDropTimer(0)
+ super("Chicken", mtChicken, "entity.chicken.hurt", "entity.chicken.death", 0.3, 0.4),
+ m_EggDropTimer(0)
{
- SetGravity(-2.0f);
- SetAirDrag(0.0f);
+ SetGravity(-2.0f);
+ SetAirDrag(0.0f);
}
@@ -22,36 +18,36 @@ cChicken::cChicken(void) :
void cChicken::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
{
- super::Tick(a_Dt, a_Chunk);
- if (!IsTicking())
- {
- // The base class tick destroyed us
- return;
- }
-
- if (IsBaby())
- {
- return; // Babies don't lay eggs
- }
-
- if ((m_EggDropTimer == 6000) && GetRandomProvider().RandBool())
- {
- cItems Drops;
- m_EggDropTimer = 0;
- Drops.push_back(cItem(E_ITEM_EGG, 1));
- m_World->SpawnItemPickups(Drops, GetPosX(), GetPosY(), GetPosZ(), 10);
- }
- else if (m_EggDropTimer == 12000)
- {
- cItems Drops;
- m_EggDropTimer = 0;
- Drops.push_back(cItem(E_ITEM_EGG, 1));
- m_World->SpawnItemPickups(Drops, GetPosX(), GetPosY(), GetPosZ(), 10);
- }
- else
- {
- m_EggDropTimer++;
- }
+ super::Tick(a_Dt, a_Chunk);
+ if (!IsTicking())
+ {
+ // The base class tick destroyed us
+ return;
+ }
+
+ if (IsBaby())
+ {
+ return; // Babies don't lay eggs
+ }
+
+ if ((m_EggDropTimer == 6000) && GetRandomProvider().RandBool())
+ {
+ cItems Drops;
+ m_EggDropTimer = 0;
+ Drops.push_back(cItem(E_ITEM_EGG, 1));
+ m_World->SpawnItemPickups(Drops, GetPosX(), GetPosY(), GetPosZ(), 10);
+ }
+ else if (m_EggDropTimer == 12000)
+ {
+ cItems Drops;
+ m_EggDropTimer = 0;
+ Drops.push_back(cItem(E_ITEM_EGG, 1));
+ m_World->SpawnItemPickups(Drops, GetPosX(), GetPosY(), GetPosZ(), 10);
+ }
+ else
+ {
+ m_EggDropTimer++;
+ }
}
@@ -60,13 +56,13 @@ void cChicken::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
void cChicken::GetDrops(cItems & a_Drops, cEntity * a_Killer)
{
- unsigned int LootingLevel = 0;
- if (a_Killer != nullptr)
- {
- LootingLevel = a_Killer->GetEquippedWeapon().m_Enchantments.GetLevel(cEnchantments::enchLooting);
- }
- AddRandomDropItem(a_Drops, 0, 2 + LootingLevel, E_ITEM_FEATHER);
- AddRandomDropItem(a_Drops, 1, 1, IsOnFire() ? E_ITEM_COOKED_CHICKEN : E_ITEM_RAW_CHICKEN);
+ unsigned int LootingLevel = 0;
+ if (a_Killer != nullptr)
+ {
+ LootingLevel = a_Killer->GetEquippedWeapon().m_Enchantments.GetLevel(cEnchantments::enchLooting);
+ }
+ AddRandomDropItem(a_Drops, 0, 2 + LootingLevel, E_ITEM_FEATHER);
+ AddRandomDropItem(a_Drops, 1, 1, IsOnFire() ? E_ITEM_COOKED_CHICKEN : E_ITEM_RAW_CHICKEN);
}
@@ -75,7 +71,7 @@ void cChicken::GetDrops(cItems & a_Drops, cEntity * a_Killer)
void cChicken::HandleFalling(void)
{
- // empty - chickens don't take fall damage
+ // empty - chickens don't take fall damage
}
diff --git a/src/Mobs/Chicken.h b/src/Mobs/Chicken.h
index 3be338b15..b954c19ec 100644
--- a/src/Mobs/Chicken.h
+++ b/src/Mobs/Chicken.h
@@ -7,28 +7,28 @@
class cChicken :
- public cPassiveMonster
+ public cPassiveMonster
{
- typedef cPassiveMonster super;
+ typedef cPassiveMonster super;
public:
- cChicken(void);
+ cChicken(void);
- CLASS_PROTODEF(cChicken)
+ CLASS_PROTODEF(cChicken)
- virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = nullptr) override;
- virtual void Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override;
+ virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = nullptr) override;
+ virtual void Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override;
- virtual void GetFollowedItems(cItems & a_Items) override
- {
- a_Items.Add(E_ITEM_SEEDS);
- }
+ virtual void GetFollowedItems(cItems & a_Items) override
+ {
+ a_Items.Add(E_ITEM_SEEDS);
+ }
- virtual void HandleFalling(void) override;
+ virtual void HandleFalling(void) override;
private:
- int m_EggDropTimer;
+ int m_EggDropTimer;
} ;
diff --git a/src/Mobs/Cow.cpp b/src/Mobs/Cow.cpp
index 9736fe440..c92f2369f 100644
--- a/src/Mobs/Cow.cpp
+++ b/src/Mobs/Cow.cpp
@@ -6,12 +6,8 @@
-
-
-
-
cCow::cCow(void) :
- super("Cow", mtCow, "entity.cow.hurt", "entity.cow.death", 0.9, 1.3)
+ super("Cow", mtCow, "entity.cow.hurt", "entity.cow.death", 0.9, 1.3)
{
}
@@ -21,13 +17,13 @@ cCow::cCow(void) :
void cCow::GetDrops(cItems & a_Drops, cEntity * a_Killer)
{
- unsigned int LootingLevel = 0;
- if (a_Killer != nullptr)
- {
- LootingLevel = a_Killer->GetEquippedWeapon().m_Enchantments.GetLevel(cEnchantments::enchLooting);
- }
- AddRandomDropItem(a_Drops, 0, 2 + LootingLevel, E_ITEM_LEATHER);
- AddRandomDropItem(a_Drops, 1, 3 + LootingLevel, IsOnFire() ? E_ITEM_STEAK : E_ITEM_RAW_BEEF);
+ unsigned int LootingLevel = 0;
+ if (a_Killer != nullptr)
+ {
+ LootingLevel = a_Killer->GetEquippedWeapon().m_Enchantments.GetLevel(cEnchantments::enchLooting);
+ }
+ AddRandomDropItem(a_Drops, 0, 2 + LootingLevel, E_ITEM_LEATHER);
+ AddRandomDropItem(a_Drops, 1, 3 + LootingLevel, IsOnFire() ? E_ITEM_STEAK : E_ITEM_RAW_BEEF);
}
@@ -36,15 +32,15 @@ void cCow::GetDrops(cItems & a_Drops, cEntity * a_Killer)
void cCow::OnRightClicked(cPlayer & a_Player)
{
- super::OnRightClicked(a_Player);
-
- short HeldItem = a_Player.GetEquippedItem().m_ItemType;
- if (HeldItem == E_ITEM_BUCKET)
- {
- if (!a_Player.IsGameModeCreative())
- {
- a_Player.GetInventory().RemoveOneEquippedItem();
- a_Player.GetInventory().AddItem(E_ITEM_MILK);
- }
- }
+ super::OnRightClicked(a_Player);
+
+ short HeldItem = a_Player.GetEquippedItem().m_ItemType;
+ if (HeldItem == E_ITEM_BUCKET)
+ {
+ if (!a_Player.IsGameModeCreative())
+ {
+ a_Player.GetInventory().RemoveOneEquippedItem();
+ a_Player.GetInventory().AddItem(E_ITEM_MILK);
+ }
+ }
}
diff --git a/src/Mobs/Cow.h b/src/Mobs/Cow.h
index 569c6e619..7b3cdb56e 100644
--- a/src/Mobs/Cow.h
+++ b/src/Mobs/Cow.h
@@ -8,22 +8,22 @@
class cCow :
- public cPassiveMonster
+ public cPassiveMonster
{
- typedef cPassiveMonster super;
+ typedef cPassiveMonster super;
public:
- cCow();
+ cCow();
- CLASS_PROTODEF(cCow)
+ CLASS_PROTODEF(cCow)
- virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = nullptr) override;
- virtual void OnRightClicked(cPlayer & a_Player) override;
+ virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = nullptr) override;
+ virtual void OnRightClicked(cPlayer & a_Player) override;
- virtual void GetFollowedItems(cItems & a_Items) override
- {
- a_Items.Add(E_ITEM_WHEAT);
- }
+ virtual void GetFollowedItems(cItems & a_Items) override
+ {
+ a_Items.Add(E_ITEM_WHEAT);
+ }
} ;
diff --git a/src/Mobs/Creeper.cpp b/src/Mobs/Creeper.cpp
index 505e637b0..f84a8acd7 100644
--- a/src/Mobs/Creeper.cpp
+++ b/src/Mobs/Creeper.cpp
@@ -125,6 +125,7 @@ bool cCreeper::DoTakeDamage(TakeDamageInfo & a_TDI)
+// mobTODO
/*
bool cCreeper::Attack(std::chrono::milliseconds a_Dt)
{
diff --git a/src/Mobs/Creeper.h b/src/Mobs/Creeper.h
index aea36def3..2ef72650b 100644
--- a/src/Mobs/Creeper.h
+++ b/src/Mobs/Creeper.h
@@ -8,29 +8,28 @@
class cCreeper :
- public cAggressiveMonster
+ public cAggressiveMonster
{
- typedef cAggressiveMonster super;
+ typedef cAggressiveMonster super;
public:
- cCreeper(void);
+ cCreeper(void);
- CLASS_PROTODEF(cCreeper)
+ CLASS_PROTODEF(cCreeper)
- virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = nullptr) override;
- virtual bool DoTakeDamage(TakeDamageInfo & a_TDI) override;
- virtual bool Attack(std::chrono::milliseconds a_Dt) override;
- virtual void Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override;
- virtual void OnRightClicked(cPlayer & a_Player) override;
+ virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = nullptr) override;
+ virtual bool DoTakeDamage(TakeDamageInfo & a_TDI) override;
+ virtual void Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override;
+ virtual void OnRightClicked(cPlayer & a_Player) override;
- bool IsBlowing(void) const {return m_bIsBlowing; }
- bool IsCharged(void) const {return m_bIsCharged; }
- bool IsBurnedWithFlintAndSteel(void) const {return m_BurnedWithFlintAndSteel; }
+ bool IsBlowing(void) const {return m_bIsBlowing; }
+ bool IsCharged(void) const {return m_bIsCharged; }
+ bool IsBurnedWithFlintAndSteel(void) const {return m_BurnedWithFlintAndSteel; }
private:
- bool m_bIsBlowing, m_bIsCharged, m_BurnedWithFlintAndSteel;
- int m_ExplodingTimer;
+ bool m_bIsBlowing, m_bIsCharged, m_BurnedWithFlintAndSteel;
+ int m_ExplodingTimer;
} ;
diff --git a/src/Mobs/Ghast.cpp b/src/Mobs/Ghast.cpp
index 2488e63b1..97a27be5a 100644
--- a/src/Mobs/Ghast.cpp
+++ b/src/Mobs/Ghast.cpp
@@ -9,7 +9,7 @@
cGhast::cGhast(void) :
- super("Ghast", mtGhast, "entity.ghast.hurt", "entity.ghast.death", 4, 4)
+ super("Ghast", mtGhast, "entity.ghast.hurt", "entity.ghast.death", 4, 4)
{
}
@@ -19,39 +19,39 @@ cGhast::cGhast(void) :
void cGhast::GetDrops(cItems & a_Drops, cEntity * a_Killer)
{
- unsigned int LootingLevel = 0;
- if (a_Killer != nullptr)
- {
- LootingLevel = a_Killer->GetEquippedWeapon().m_Enchantments.GetLevel(cEnchantments::enchLooting);
- }
- AddRandomDropItem(a_Drops, 0, 2 + LootingLevel, E_ITEM_GUNPOWDER);
- AddRandomDropItem(a_Drops, 0, 1 + LootingLevel, E_ITEM_GHAST_TEAR);
+ unsigned int LootingLevel = 0;
+ if (a_Killer != nullptr)
+ {
+ LootingLevel = a_Killer->GetEquippedWeapon().m_Enchantments.GetLevel(cEnchantments::enchLooting);
+ }
+ AddRandomDropItem(a_Drops, 0, 2 + LootingLevel, E_ITEM_GUNPOWDER);
+ AddRandomDropItem(a_Drops, 0, 1 + LootingLevel, E_ITEM_GHAST_TEAR);
}
-
-bool cGhast::Attack(std::chrono::milliseconds a_Dt)
+// mobTODO
+/*bool cGhast::Attack(std::chrono::milliseconds a_Dt)
{
- if ((GetTarget() != nullptr) && (m_AttackCoolDownTicksLeft == 0))
- {
- // Setting this higher gives us more wiggle room for attackrate
- Vector3d Speed = GetLookVector() * 20;
- Speed.y = Speed.y + 1;
-
- auto GhastBall = cpp14::make_unique<cGhastFireballEntity>(this, GetPosX(), GetPosY() + 1, GetPosZ(), Speed);
- auto GhastBallPtr = GhastBall.get();
- if (!GhastBallPtr->Initialize(std::move(GhastBall), *m_World))
- {
- return false;
- }
-
- ResetAttackCooldown();
- return true;
- }
- return false;
-}
+ if ((GetTarget() != nullptr) && (m_AttackCoolDownTicksLeft == 0))
+ {
+ // Setting this higher gives us more wiggle room for attackrate
+ Vector3d Speed = GetLookVector() * 20;
+ Speed.y = Speed.y + 1;
+
+ auto GhastBall = cpp14::make_unique<cGhastFireballEntity>(this, GetPosX(), GetPosY() + 1, GetPosZ(), Speed);
+ auto GhastBallPtr = GhastBall.get();
+ if (!GhastBallPtr->Initialize(std::move(GhastBall), *m_World))
+ {
+ return false;
+ }
+
+ ResetAttackCooldown();
+ return true;
+ }
+ return false;
+}*/
diff --git a/src/Mobs/Ghast.h b/src/Mobs/Ghast.h
index a41a72ddc..c3423590a 100644
--- a/src/Mobs/Ghast.h
+++ b/src/Mobs/Ghast.h
@@ -8,19 +8,18 @@
class cGhast :
- public cAggressiveMonster
+ public cAggressiveMonster
{
- typedef cAggressiveMonster super;
+ typedef cAggressiveMonster super;
public:
- cGhast(void);
+ cGhast(void);
- CLASS_PROTODEF(cGhast)
+ CLASS_PROTODEF(cGhast)
- virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = nullptr) override;
- virtual bool Attack(std::chrono::milliseconds a_Dt) override;
+ virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = nullptr) override;
- bool IsCharging(void) const {return false; }
+ bool IsCharging(void) const {return false; }
} ;
diff --git a/src/Mobs/Monster.cpp b/src/Mobs/Monster.cpp
index 059edbcbc..4513ea3f8 100644
--- a/src/Mobs/Monster.cpp
+++ b/src/Mobs/Monster.cpp
@@ -1167,13 +1167,17 @@ cBehaviorWanderer * cMonster::GetBehaviorWanderer()
-void cMonster::InheritFromParents(cMonster * a_Parent1, cMonster * a_Parent2)
+void cMonster::InheritFromParents(cPassiveMonster * a_Parent1, cPassiveMonster * a_Parent2)
{
UNUSED(a_Parent1);
UNUSED(a_Parent2);
return;
}
+
+
+
+
void cMonster::GetFollowedItems(cItems & a_Items)
{
return;
@@ -1183,6 +1187,11 @@ void cMonster::GetFollowedItems(cItems & a_Items)
+void cMonster::GetBreedingItems(cItems & a_Items)
+{
+ return GetFollowedItems();
+}
+
std::unique_ptr<cMonster> cMonster::NewMonsterFromType(eMonsterType a_MobType)
{
auto & Random = GetRandomProvider();
diff --git a/src/Mobs/Monster.h b/src/Mobs/Monster.h
index 6308b2945..144228fe7 100644
--- a/src/Mobs/Monster.h
+++ b/src/Mobs/Monster.h
@@ -11,6 +11,7 @@ class cClientHandle;
//Behavior fwds
+class cPassiveMonster;
class cBehaviorAggressive;
class cBehaviorBreeder;
class cBehaviorChaser;
@@ -226,9 +227,10 @@ public:
virtual cBehaviorStriker * GetBehaviorStriker();
virtual cBehaviorWanderer * GetBehaviorWanderer();
- // Polymorphic behavior functions
- virtual void InheritFromParents(cMonster * a_Parent1, cMonster * a_Parent2);
+ // Polymorphic behavior functions ("Skin-specific")
+ virtual void InheritFromParents(cPassiveMonster * a_Parent1, cPassiveMonster * a_Parent2);
virtual void GetFollowedItems(cItems & a_Items);
+ virtual void GetBreedingItems(cItems & a_Items);
protected:
diff --git a/src/Mobs/PassiveMonster.cpp b/src/Mobs/PassiveMonster.cpp
index 1c020232a..f8bc62c09 100644
--- a/src/Mobs/PassiveMonster.cpp
+++ b/src/Mobs/PassiveMonster.cpp
@@ -9,9 +9,9 @@
-cPassiveMonster::cPassiveMonster(const AString & a_ConfigName, eMonsterType a_MobType, const AString & a_SoundHurt, const AString & a_SoundDeath, double a_Width, double a_Height, cItems & a_BreedingItems, cItems & a_FollowedItems) :
+cPassiveMonster::cPassiveMonster(const AString & a_ConfigName, eMonsterType a_MobType, const AString & a_SoundHurt, const AString & a_SoundDeath, double a_Width, double a_Height, cItem & a_BreedingItems, cItem & a_FollowedItems) :
super(a_ConfigName, a_MobType, a_SoundHurt, a_SoundDeath, a_Width, a_Height),
- m_BehaviorBreeder(this), m_BehaviorItemFollower(this, a_FollowedItems), m_BehaviorCoward(this)
+ m_BehaviorBreeder(this), m_BehaviorItemFollower(this), m_BehaviorCoward(this)
{
m_EMPersonality = PASSIVE;
}
diff --git a/src/Mobs/PassiveMonster.h b/src/Mobs/PassiveMonster.h
index 012357024..1ab6d27e3 100644
--- a/src/Mobs/PassiveMonster.h
+++ b/src/Mobs/PassiveMonster.h
@@ -13,7 +13,9 @@ class cPassiveMonster : public cMonster
typedef cMonster super;
public:
- cPassiveMonster(const AString & a_ConfigName, eMonsterType a_MobType, const AString & a_SoundHurt, const AString & a_SoundDeath, double a_Width, double a_Height, cItems & a_BreedingItems, cItems & a_FollowedItems);
+ cPassiveMonster(const AString & a_ConfigName, eMonsterType a_MobType,
+ const AString & a_SoundHurt, const AString & a_SoundDeath,
+ double a_Width, double a_Height);
virtual ~cPassiveMonster();
virtual void Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override;
virtual void OnRightClicked(cPlayer & a_Player) override;
diff --git a/src/Mobs/Silverfish.h b/src/Mobs/Silverfish.h
index 90ef5ea5d..c5d39a7a4 100644
--- a/src/Mobs/Silverfish.h
+++ b/src/Mobs/Silverfish.h
@@ -8,17 +8,17 @@
class cSilverfish :
- public cAggressiveMonster
+ public cAggressiveMonster
{
- typedef cAggressiveMonster super;
+ typedef cAggressiveMonster super;
public:
- cSilverfish(void) :
- super("Silverfish", mtSilverfish, "entity.silverfish.hurt", "entity.silverfish.death", 0.3, 0.7)
- {
- }
+ cSilverfish(void) :
+ super("Silverfish", mtSilverfish, "entity.silverfish.hurt", "entity.silverfish.death", 0.3, 0.7, 15)
+ {
+ }
- CLASS_PROTODEF(cSilverfish)
+ CLASS_PROTODEF(cSilverfish)
} ;
diff --git a/src/Mobs/Skeleton.cpp b/src/Mobs/Skeleton.cpp
index e48991a06..22ea3e1bc 100644
--- a/src/Mobs/Skeleton.cpp
+++ b/src/Mobs/Skeleton.cpp
@@ -10,10 +10,10 @@
cSkeleton::cSkeleton(bool IsWither) :
- super("Skeleton", mtSkeleton, "entity.skeleton.hurt", "entity.skeleton.death", 0.6, 1.8),
- m_bIsWither(IsWither)
+ super("Skeleton", mtSkeleton, "entity.skeleton.hurt", "entity.skeleton.death", 0.6, 1.8),
+ m_bIsWither(IsWither)
{
- SetBurnsInDaylight(true);
+ SetBurnsInDaylight(true);
}
@@ -22,54 +22,54 @@ cSkeleton::cSkeleton(bool IsWither) :
void cSkeleton::GetDrops(cItems & a_Drops, cEntity * a_Killer)
{
- unsigned int LootingLevel = 0;
- if (a_Killer != nullptr)
- {
- LootingLevel = a_Killer->GetEquippedWeapon().m_Enchantments.GetLevel(cEnchantments::enchLooting);
- }
- if (IsWither())
- {
- AddRandomUncommonDropItem(a_Drops, 33.0f, E_ITEM_COAL);
- cItems RareDrops;
- RareDrops.Add(cItem(E_ITEM_HEAD, 1, 1));
- AddRandomRareDropItem(a_Drops, RareDrops, LootingLevel);
- }
- else
- {
- AddRandomDropItem(a_Drops, 0, 2 + LootingLevel, E_ITEM_ARROW);
-
- }
- AddRandomDropItem(a_Drops, 0, 2 + LootingLevel, E_ITEM_BONE);
- AddRandomArmorDropItem(a_Drops, LootingLevel);
- AddRandomWeaponDropItem(a_Drops, LootingLevel);
+ unsigned int LootingLevel = 0;
+ if (a_Killer != nullptr)
+ {
+ LootingLevel = a_Killer->GetEquippedWeapon().m_Enchantments.GetLevel(cEnchantments::enchLooting);
+ }
+ if (IsWither())
+ {
+ AddRandomUncommonDropItem(a_Drops, 33.0f, E_ITEM_COAL);
+ cItems RareDrops;
+ RareDrops.Add(cItem(E_ITEM_HEAD, 1, 1));
+ AddRandomRareDropItem(a_Drops, RareDrops, LootingLevel);
+ }
+ else
+ {
+ AddRandomDropItem(a_Drops, 0, 2 + LootingLevel, E_ITEM_ARROW);
+
+ }
+ AddRandomDropItem(a_Drops, 0, 2 + LootingLevel, E_ITEM_BONE);
+ AddRandomArmorDropItem(a_Drops, LootingLevel);
+ AddRandomWeaponDropItem(a_Drops, LootingLevel);
}
-
-bool cSkeleton::Attack(std::chrono::milliseconds a_Dt)
+//mobTodo
+/*bool cSkeleton::Attack(std::chrono::milliseconds a_Dt)
{
- StopMovingToPosition(); // Todo handle this in a better way, the skeleton does some uneeded recalcs due to inStateChasing
- auto & Random = GetRandomProvider();
- if ((GetTarget() != nullptr) && (m_AttackCoolDownTicksLeft == 0))
- {
- Vector3d Inaccuracy = Vector3d(Random.RandReal<double>(-0.25, 0.25), Random.RandReal<double>(-0.25, 0.25), Random.RandReal<double>(-0.25, 0.25));
- Vector3d Speed = (GetTarget()->GetPosition() + Inaccuracy - GetPosition()) * 5;
- Speed.y += Random.RandInt(-1, 1);
-
- auto Arrow = cpp14::make_unique<cArrowEntity>(this, GetPosX(), GetPosY() + 1, GetPosZ(), Speed);
- auto ArrowPtr = Arrow.get();
- if (!ArrowPtr->Initialize(std::move(Arrow), *m_World))
- {
- return false;
- }
-
- ResetAttackCooldown();
- return true;
- }
- return false;
-}
+ StopMovingToPosition(); // Todo handle this in a better way, the skeleton does some uneeded recalcs due to inStateChasing
+ auto & Random = GetRandomProvider();
+ if ((GetTarget() != nullptr) && (m_AttackCoolDownTicksLeft == 0))
+ {
+ Vector3d Inaccuracy = Vector3d(Random.RandReal<double>(-0.25, 0.25), Random.RandReal<double>(-0.25, 0.25), Random.RandReal<double>(-0.25, 0.25));
+ Vector3d Speed = (GetTarget()->GetPosition() + Inaccuracy - GetPosition()) * 5;
+ Speed.y += Random.RandInt(-1, 1);
+
+ auto Arrow = cpp14::make_unique<cArrowEntity>(this, GetPosX(), GetPosY() + 1, GetPosZ(), Speed);
+ auto ArrowPtr = Arrow.get();
+ if (!ArrowPtr->Initialize(std::move(Arrow), *m_World))
+ {
+ return false;
+ }
+
+ ResetAttackCooldown();
+ return true;
+ }
+ return false;
+}*/
@@ -77,8 +77,8 @@ bool cSkeleton::Attack(std::chrono::milliseconds a_Dt)
void cSkeleton::SpawnOn(cClientHandle & a_ClientHandle)
{
- super::SpawnOn(a_ClientHandle);
- a_ClientHandle.SendEntityEquipment(*this, 0, cItem(E_ITEM_BOW));
+ super::SpawnOn(a_ClientHandle);
+ a_ClientHandle.SendEntityEquipment(*this, 0, cItem(E_ITEM_BOW));
}
diff --git a/src/Mobs/Skeleton.h b/src/Mobs/Skeleton.h
index 0316fb9b5..91e094c4c 100644
--- a/src/Mobs/Skeleton.h
+++ b/src/Mobs/Skeleton.h
@@ -8,26 +8,26 @@
class cSkeleton :
- public cAggressiveMonster
+ public cAggressiveMonster
{
- typedef cAggressiveMonster super;
+ typedef cAggressiveMonster super;
public:
- cSkeleton(bool IsWither);
+ cSkeleton(bool IsWither);
- CLASS_PROTODEF(cSkeleton)
+ CLASS_PROTODEF(cSkeleton)
- virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = nullptr) override;
- virtual bool Attack(std::chrono::milliseconds a_Dt) override;
- virtual void SpawnOn(cClientHandle & a_ClientHandle) override;
+ virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = nullptr) override;
+ /*virtual bool Attack(std::chrono::milliseconds a_Dt) override;*/
+ virtual void SpawnOn(cClientHandle & a_ClientHandle) override;
- virtual bool IsUndead(void) override { return true; }
+ virtual bool IsUndead(void) override { return true; }
- bool IsWither(void) const { return m_bIsWither; }
+ bool IsWither(void) const { return m_bIsWither; }
private:
- bool m_bIsWither;
+ bool m_bIsWither;
} ;
diff --git a/src/Mobs/Slime.cpp b/src/Mobs/Slime.cpp
index 291a3a57f..df4c2f6ee 100644
--- a/src/Mobs/Slime.cpp
+++ b/src/Mobs/Slime.cpp
@@ -10,17 +10,17 @@
cSlime::cSlime(int a_Size) :
- super("Slime",
- mtSlime,
- Printf("entity.%sslime.hurt", GetSizeName(a_Size).c_str()),
- Printf("entity.%sslime.death", GetSizeName(a_Size).c_str()),
- 0.6 * a_Size,
- 0.6 * a_Size
- ),
- m_Size(a_Size)
+ super("Slime",
+ mtSlime,
+ Printf("entity.%sslime.hurt", GetSizeName(a_Size).c_str()),
+ Printf("entity.%sslime.death", GetSizeName(a_Size).c_str()),
+ 0.6 * a_Size,
+ 0.6 * a_Size
+ ),
+ m_Size(a_Size)
{
- SetMaxHealth(a_Size * a_Size);
- SetAttackDamage(a_Size);
+ SetMaxHealth(a_Size * a_Size);
+ SetAttackDamage(a_Size);
}
@@ -29,33 +29,33 @@ cSlime::cSlime(int a_Size) :
void cSlime::GetDrops(cItems & a_Drops, cEntity * a_Killer)
{
- unsigned int LootingLevel = 0;
- if (a_Killer != nullptr)
- {
- LootingLevel = a_Killer->GetEquippedWeapon().m_Enchantments.GetLevel(cEnchantments::enchLooting);
- }
-
- // Only slimes with the size 1 can drop slimeballs.
- if (m_Size == 1)
- {
- AddRandomDropItem(a_Drops, 0, 2 + LootingLevel, E_ITEM_SLIMEBALL);
- }
+ unsigned int LootingLevel = 0;
+ if (a_Killer != nullptr)
+ {
+ LootingLevel = a_Killer->GetEquippedWeapon().m_Enchantments.GetLevel(cEnchantments::enchLooting);
+ }
+
+ // Only slimes with the size 1 can drop slimeballs.
+ if (m_Size == 1)
+ {
+ AddRandomDropItem(a_Drops, 0, 2 + LootingLevel, E_ITEM_SLIMEBALL);
+ }
}
-
-bool cSlime::Attack(std::chrono::milliseconds a_Dt)
+//mobTodo
+/*bool cSlime::Attack(std::chrono::milliseconds a_Dt)
{
- if (m_Size > 1)
- {
- // Only slimes larger than size 1 attack a player.
- return super::Attack(a_Dt);
- }
+ if (m_Size > 1)
+ {
+ // Only slimes larger than size 1 attack a player.
+ return super::Attack(a_Dt);
+ }
- return false;
-}
+ return false;
+}*/
@@ -63,28 +63,28 @@ bool cSlime::Attack(std::chrono::milliseconds a_Dt)
void cSlime::KilledBy(TakeDamageInfo & a_TDI)
{
- if (GetHealth() > 0)
- {
- return;
- }
-
- if (m_Size != 1)
- {
- auto & Random = GetRandomProvider();
- int SpawnAmount = Random.RandInt(2, 4);
-
- for (int i = 0; i < SpawnAmount; ++i)
- {
- double AddX = (i % 2 - 0.5) * m_Size / 4.0;
- double AddZ = (i / 2 - 0.5) * m_Size / 4.0;
-
- auto NewSlime = cpp14::make_unique<cSlime>(m_Size / 2);
- NewSlime->SetPosition(GetPosX() + AddX, GetPosY() + 0.5, GetPosZ() + AddZ);
- NewSlime->SetYaw(Random.RandReal(360.0f));
- m_World->SpawnMobFinalize(std::move(NewSlime));
- }
- }
- super::KilledBy(a_TDI);
+ if (GetHealth() > 0)
+ {
+ return;
+ }
+
+ if (m_Size != 1)
+ {
+ auto & Random = GetRandomProvider();
+ int SpawnAmount = Random.RandInt(2, 4);
+
+ for (int i = 0; i < SpawnAmount; ++i)
+ {
+ double AddX = (i % 2 - 0.5) * m_Size / 4.0;
+ double AddZ = (i / 2 - 0.5) * m_Size / 4.0;
+
+ auto NewSlime = cpp14::make_unique<cSlime>(m_Size / 2);
+ NewSlime->SetPosition(GetPosX() + AddX, GetPosY() + 0.5, GetPosZ() + AddZ);
+ NewSlime->SetYaw(Random.RandReal(360.0f));
+ m_World->SpawnMobFinalize(std::move(NewSlime));
+ }
+ }
+ super::KilledBy(a_TDI);
}
@@ -93,11 +93,11 @@ void cSlime::KilledBy(TakeDamageInfo & a_TDI)
AString cSlime::GetSizeName(int a_Size)
{
- if (a_Size == 1)
- {
- return "small_";
- }
- return "";
+ if (a_Size == 1)
+ {
+ return "small_";
+ }
+ return "";
}
diff --git a/src/Mobs/Slime.h b/src/Mobs/Slime.h
index c78461a02..26bc6716d 100644
--- a/src/Mobs/Slime.h
+++ b/src/Mobs/Slime.h
@@ -8,32 +8,32 @@
class cSlime :
- public cAggressiveMonster
+ public cAggressiveMonster
{
- typedef cAggressiveMonster super;
+ typedef cAggressiveMonster super;
public:
- /** Creates a slime of the specified size; size can be 1, 2 or 4, with 1 is the smallest and 4 is the tallest. */
- cSlime(int a_Size);
+ /** Creates a slime of the specified size; size can be 1, 2 or 4, with 1 is the smallest and 4 is the tallest. */
+ cSlime(int a_Size);
- CLASS_PROTODEF(cSlime)
+ CLASS_PROTODEF(cSlime)
- // cAggressiveMonster overrides:
- virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = nullptr) override;
- virtual bool Attack(std::chrono::milliseconds a_Dt) override;
- virtual void KilledBy(TakeDamageInfo & a_TDI) override;
+ // cAggressiveMonster overrides:
+ virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = nullptr) override;
+ // virtual bool Attack(std::chrono::milliseconds a_Dt) override;
+ virtual void KilledBy(TakeDamageInfo & a_TDI) override;
- int GetSize(void) const { return m_Size; }
+ int GetSize(void) const { return m_Size; }
- /** Returns the text describing the slime's size, as used by the client's resource subsystem for sounds.
- Returns either "big" or "small". */
- static AString GetSizeName(int a_Size);
+ /** Returns the text describing the slime's size, as used by the client's resource subsystem for sounds.
+ Returns either "big" or "small". */
+ static AString GetSizeName(int a_Size);
protected:
- /** Size of the slime, with 1 being the smallest.
- Vanilla uses sizes 1, 2 and 4 only. */
- int m_Size;
+ /** Size of the slime, with 1 being the smallest.
+ Vanilla uses sizes 1, 2 and 4 only. */
+ int m_Size;
} ;
diff --git a/src/Mobs/Spider.cpp b/src/Mobs/Spider.cpp
index 971ff22f6..89bd04ff5 100644
--- a/src/Mobs/Spider.cpp
+++ b/src/Mobs/Spider.cpp
@@ -9,7 +9,7 @@
cSpider::cSpider(void) :
- super("Spider", mtSpider, "entity.spider.hurt", "entity.spider.death", 1.4, 0.9)
+ super("Spider", mtSpider, "entity.spider.hurt", "entity.spider.death", 1.4, 0.9, 11)
{
}
@@ -19,16 +19,16 @@ cSpider::cSpider(void) :
void cSpider::GetDrops(cItems & a_Drops, cEntity * a_Killer)
{
- unsigned int LootingLevel = 0;
- if (a_Killer != nullptr)
- {
- LootingLevel = a_Killer->GetEquippedWeapon().m_Enchantments.GetLevel(cEnchantments::enchLooting);
- }
- AddRandomDropItem(a_Drops, 0, 2 + LootingLevel, E_ITEM_STRING);
- if ((a_Killer != nullptr) && (a_Killer->IsPlayer() || a_Killer->IsA("cWolf")))
- {
- AddRandomUncommonDropItem(a_Drops, 33.0f, E_ITEM_SPIDER_EYE);
- }
+ unsigned int LootingLevel = 0;
+ if (a_Killer != nullptr)
+ {
+ LootingLevel = a_Killer->GetEquippedWeapon().m_Enchantments.GetLevel(cEnchantments::enchLooting);
+ }
+ AddRandomDropItem(a_Drops, 0, 2 + LootingLevel, E_ITEM_STRING);
+ if ((a_Killer != nullptr) && (a_Killer->IsPlayer() || a_Killer->IsA("cWolf")))
+ {
+ AddRandomUncommonDropItem(a_Drops, 33.0f, E_ITEM_SPIDER_EYE);
+ }
}
@@ -37,24 +37,24 @@ void cSpider::GetDrops(cItems & a_Drops, cEntity * a_Killer)
void cSpider::EventSeePlayer(cPlayer * a_Player, cChunk & a_Chunk)
{
- if (!GetWorld()->IsChunkLighted(GetChunkX(), GetChunkZ()))
- {
- return;
- }
-
- PREPARE_REL_AND_CHUNK(GetPosition(), a_Chunk);
- if (!RelSuccess)
- {
- return;
- }
-
- if (
- a_Player->CanMobsTarget() &&
- !((Chunk->GetSkyLightAltered(Rel.x, Rel.y, Rel.z) > 11) || (Chunk->GetBlockLight(Rel.x, Rel.y, Rel.z) > 11))
- )
- {
- super::EventSeePlayer(a_Player, a_Chunk);
- }
+ if (!GetWorld()->IsChunkLighted(GetChunkX(), GetChunkZ()))
+ {
+ return;
+ }
+
+ PREPARE_REL_AND_CHUNK(GetPosition(), a_Chunk);
+ if (!RelSuccess)
+ {
+ return;
+ }
+
+ if (
+ a_Player->CanMobsTarget() &&
+ !((Chunk->GetSkyLightAltered(Rel.x, Rel.y, Rel.z) > 11) || (Chunk->GetBlockLight(Rel.x, Rel.y, Rel.z) > 11))
+ )
+ {
+ super::EventSeePlayer(a_Player, a_Chunk);
+ }
}
@@ -63,21 +63,21 @@ void cSpider::EventSeePlayer(cPlayer * a_Player, cChunk & a_Chunk)
bool cSpider::DoTakeDamage(TakeDamageInfo & a_TDI)
{
- if (!super::DoTakeDamage(a_TDI))
- {
- return false;
- }
-
- // If the source of the damage is not from an pawn entity, switch to idle
- if ((a_TDI.Attacker == nullptr) || !a_TDI.Attacker->IsPawn())
- {
- m_EMState = IDLE;
- }
- else
- {
- // If the source of the damage is from a pawn entity, chase that entity
- m_EMState = CHASING;
- }
-
- return true;
+ if (!super::DoTakeDamage(a_TDI))
+ {
+ return false;
+ }
+
+ // If the source of the damage is not from an pawn entity, switch to idle
+ if ((a_TDI.Attacker == nullptr) || !a_TDI.Attacker->IsPawn())
+ {
+ m_EMState = IDLE;
+ }
+ else
+ {
+ // If the source of the damage is from a pawn entity, chase that entity
+ m_EMState = CHASING;
+ }
+
+ return true;
}
diff --git a/src/Mobs/Wolf.cpp b/src/Mobs/Wolf.cpp
index 33a9b31ee..520de483d 100644
--- a/src/Mobs/Wolf.cpp
+++ b/src/Mobs/Wolf.cpp
@@ -12,16 +12,16 @@
cWolf::cWolf(void) :
- super("Wolf", mtWolf, "entity.wolf.hurt", "entity.wolf.death", 0.6, 0.8),
- m_IsSitting(false),
- m_IsTame(false),
- m_IsBegging(false),
- m_IsAngry(false),
- m_OwnerName(""),
- m_CollarColor(E_META_DYE_ORANGE),
- m_NotificationCooldown(0)
+ super("Wolf", mtWolf, "entity.wolf.hurt", "entity.wolf.death", 0.6, 0.8),
+ m_IsSitting(false),
+ m_IsTame(false),
+ m_IsBegging(false),
+ m_IsAngry(false),
+ m_OwnerName(""),
+ m_CollarColor(E_META_DYE_ORANGE),
+ m_NotificationCooldown(0)
{
- m_RelativeWalkSpeed = 2;
+ m_RelativeWalkSpeed = 2;
}
@@ -30,43 +30,43 @@ cWolf::cWolf(void) :
bool cWolf::DoTakeDamage(TakeDamageInfo & a_TDI)
{
- cPawn * PreviousTarget = GetTarget();
- if (!super::DoTakeDamage(a_TDI))
- {
- return false;
- }
-
- if ((a_TDI.Attacker != nullptr) && a_TDI.Attacker->IsPawn())
- {
- auto currTarget = GetTarget();
- if ((currTarget != nullptr) && currTarget->IsPlayer())
- {
- if (m_IsTame)
- {
- if ((static_cast<cPlayer*>(currTarget)->GetUUID() == m_OwnerUUID))
- {
- SetTarget(PreviousTarget); // Do not attack owner
- }
- else
- {
- SetIsSitting(false);
- NotifyAlliesOfFight(static_cast<cPawn*>(a_TDI.Attacker));
- }
- }
- else
- {
- m_IsAngry = true;
- }
- }
- else if (m_IsTame)
- {
- SetIsSitting(false);
- NotifyAlliesOfFight(static_cast<cPawn*>(a_TDI.Attacker));
- }
- }
-
- m_World->BroadcastEntityMetadata(*this); // Broadcast health and possibly angry face
- return true;
+ cPawn * PreviousTarget = GetTarget();
+ if (!super::DoTakeDamage(a_TDI))
+ {
+ return false;
+ }
+
+ if ((a_TDI.Attacker != nullptr) && a_TDI.Attacker->IsPawn())
+ {
+ auto currTarget = GetTarget();
+ if ((currTarget != nullptr) && currTarget->IsPlayer())
+ {
+ if (m_IsTame)
+ {
+ if ((static_cast<cPlayer*>(currTarget)->GetUUID() == m_OwnerUUID))
+ {
+ SetTarget(PreviousTarget); // Do not attack owner
+ }
+ else
+ {
+ SetIsSitting(false);
+ NotifyAlliesOfFight(static_cast<cPawn*>(a_TDI.Attacker));
+ }
+ }
+ else
+ {
+ m_IsAngry = true;
+ }
+ }
+ else if (m_IsTame)
+ {
+ SetIsSitting(false);
+ NotifyAlliesOfFight(static_cast<cPawn*>(a_TDI.Attacker));
+ }
+ }
+
+ m_World->BroadcastEntityMetadata(*this); // Broadcast health and possibly angry face
+ return true;
}
@@ -75,43 +75,43 @@ bool cWolf::DoTakeDamage(TakeDamageInfo & a_TDI)
void cWolf::NotifyAlliesOfFight(cPawn * a_Opponent)
{
- if (GetOwnerName() == "")
- {
- return;
- }
- m_NotificationCooldown = 15;
- class cCallback : public cPlayerListCallback
- {
- virtual bool Item(cPlayer * a_Player) override
- {
- a_Player->NotifyNearbyWolves(m_Opponent, false);
- return false;
- }
- public:
- cPawn * m_Opponent;
- } Callback;
-
- Callback.m_Opponent = a_Opponent;
- m_World->DoWithPlayerByUUID(m_OwnerUUID, Callback);
+ if (GetOwnerName() == "")
+ {
+ return;
+ }
+ m_NotificationCooldown = 15;
+ class cCallback : public cPlayerListCallback
+ {
+ virtual bool Item(cPlayer * a_Player) override
+ {
+ a_Player->NotifyNearbyWolves(m_Opponent, false);
+ return false;
+ }
+ public:
+ cPawn * m_Opponent;
+ } Callback;
+
+ Callback.m_Opponent = a_Opponent;
+ m_World->DoWithPlayerByUUID(m_OwnerUUID, Callback);
}
-bool cWolf::Attack(std::chrono::milliseconds a_Dt)
+/*bool cWolf::Attack(std::chrono::milliseconds a_Dt)
{
- UNUSED(a_Dt);
+ UNUSED(a_Dt);
- if ((GetTarget() != nullptr) && (GetTarget()->IsPlayer()))
- {
- if (static_cast<cPlayer *>(GetTarget())->GetUUID() == m_OwnerUUID)
- {
- SetTarget(nullptr);
- return false;
- }
- }
+ if ((GetTarget() != nullptr) && (GetTarget()->IsPlayer()))
+ {
+ if (static_cast<cPlayer *>(GetTarget())->GetUUID() == m_OwnerUUID)
+ {
+ SetTarget(nullptr);
+ return false;
+ }
+ }
- NotifyAlliesOfFight(static_cast<cPawn*>(GetTarget()));
- return super::Attack(a_Dt);
+ NotifyAlliesOfFight(static_cast<cPawn*>(GetTarget()));
+ return super::Attack(a_Dt);
-}
+}*/
@@ -119,46 +119,46 @@ bool cWolf::Attack(std::chrono::milliseconds a_Dt)
void cWolf::ReceiveNearbyFightInfo(AString a_PlayerID, cPawn * a_Opponent, bool a_IsPlayerInvolved)
{
- if (
- (a_Opponent == nullptr) || IsSitting() || (!IsTame()) ||
- (!a_Opponent->IsPawn()) || (a_PlayerID != m_OwnerUUID)
- )
- {
- return;
- }
-
- // If we already have a target
- if (GetTarget() != nullptr)
- {
- // If a wolf is asking for help and we already have a target, do nothing
- if (!a_IsPlayerInvolved)
- {
- return;
- }
- // If a player is asking for help and we already have a target,
- // there's a 50% chance of helping and a 50% chance of doing nothing
- // This helps spread a wolf pack's targets over several mobs
- else if (GetRandomProvider().RandBool())
- {
- return;
- }
- }
-
- if (a_Opponent->IsPlayer() && static_cast<cPlayer *>(a_Opponent)->GetUUID() == m_OwnerUUID)
- {
- return; // Our owner has hurt himself, avoid attacking them.
- }
-
- if (a_Opponent->IsMob() && static_cast<cMonster *>(a_Opponent)->GetMobType() == mtWolf)
- {
- cWolf * Wolf = static_cast<cWolf *>(a_Opponent);
- if (Wolf->GetOwnerUUID() == GetOwnerUUID())
- {
- return; // Our owner attacked one of their wolves. Abort attacking wolf.
- }
- }
-
- SetTarget(a_Opponent);
+ if (
+ (a_Opponent == nullptr) || IsSitting() || (!IsTame()) ||
+ (!a_Opponent->IsPawn()) || (a_PlayerID != m_OwnerUUID)
+ )
+ {
+ return;
+ }
+
+ // If we already have a target
+ if (GetTarget() != nullptr)
+ {
+ // If a wolf is asking for help and we already have a target, do nothing
+ if (!a_IsPlayerInvolved)
+ {
+ return;
+ }
+ // If a player is asking for help and we already have a target,
+ // there's a 50% chance of helping and a 50% chance of doing nothing
+ // This helps spread a wolf pack's targets over several mobs
+ else if (GetRandomProvider().RandBool())
+ {
+ return;
+ }
+ }
+
+ if (a_Opponent->IsPlayer() && static_cast<cPlayer *>(a_Opponent)->GetUUID() == m_OwnerUUID)
+ {
+ return; // Our owner has hurt himself, avoid attacking them.
+ }
+
+ if (a_Opponent->IsMob() && static_cast<cMonster *>(a_Opponent)->GetMobType() == mtWolf)
+ {
+ cWolf * Wolf = static_cast<cWolf *>(a_Opponent);
+ if (Wolf->GetOwnerUUID() == GetOwnerUUID())
+ {
+ return; // Our owner attacked one of their wolves. Abort attacking wolf.
+ }
+ }
+
+ SetTarget(a_Opponent);
}
@@ -169,82 +169,82 @@ void cWolf::ReceiveNearbyFightInfo(AString a_PlayerID, cPawn * a_Opponent, bool
void cWolf::OnRightClicked(cPlayer & a_Player)
{
- const cItem & EquippedItem = a_Player.GetEquippedItem();
- const int EquippedItemType = EquippedItem.m_ItemType;
-
- if (!IsTame() && !IsAngry())
- {
- // If the player is holding a bone, try to tame the wolf:
- if (EquippedItemType == E_ITEM_BONE)
- {
- if (!a_Player.IsGameModeCreative())
- {
- a_Player.GetInventory().RemoveOneEquippedItem();
- }
-
- if (GetRandomProvider().RandBool(0.125))
- {
- // Taming succeeded
- SetMaxHealth(20);
- SetIsTame(true);
- SetOwner(a_Player.GetName(), a_Player.GetUUID());
- m_World->BroadcastEntityStatus(*this, esWolfTamed);
- m_World->GetBroadcaster().BroadcastParticleEffect("heart", static_cast<Vector3f>(GetPosition()), Vector3f{}, 0, 5);
- }
- else
- {
- // Taming failed
- m_World->BroadcastEntityStatus(*this, esWolfTaming);
- m_World->GetBroadcaster().BroadcastParticleEffect("smoke", static_cast<Vector3f>(GetPosition()), Vector3f{}, 0, 5);
- }
- }
- }
- else if (IsTame())
- {
- // Feed the wolf, restoring its health, or dye its collar:
- switch (EquippedItemType)
- {
- case E_ITEM_RAW_BEEF:
- case E_ITEM_STEAK:
- case E_ITEM_RAW_PORKCHOP:
- case E_ITEM_COOKED_PORKCHOP:
- case E_ITEM_RAW_CHICKEN:
- case E_ITEM_COOKED_CHICKEN:
- case E_ITEM_ROTTEN_FLESH:
- {
- if (m_Health < m_MaxHealth)
- {
- Heal(ItemHandler(EquippedItemType)->GetFoodInfo(&EquippedItem).FoodLevel);
- if (!a_Player.IsGameModeCreative())
- {
- a_Player.GetInventory().RemoveOneEquippedItem();
- }
- }
- break;
- }
- case E_ITEM_DYE:
- {
- if (a_Player.GetUUID() == m_OwnerUUID) // Is the player the owner of the dog?
- {
- SetCollarColor(EquippedItem.m_ItemDamage);
- if (!a_Player.IsGameModeCreative())
- {
- a_Player.GetInventory().RemoveOneEquippedItem();
- }
- }
- break;
- }
- default:
- {
- if (a_Player.GetUUID() == m_OwnerUUID) // Is the player the owner of the dog?
- {
- SetIsSitting(!IsSitting());
- }
- }
- }
- }
-
- m_World->BroadcastEntityMetadata(*this);
+ const cItem & EquippedItem = a_Player.GetEquippedItem();
+ const int EquippedItemType = EquippedItem.m_ItemType;
+
+ if (!IsTame() && !IsAngry())
+ {
+ // If the player is holding a bone, try to tame the wolf:
+ if (EquippedItemType == E_ITEM_BONE)
+ {
+ if (!a_Player.IsGameModeCreative())
+ {
+ a_Player.GetInventory().RemoveOneEquippedItem();
+ }
+
+ if (GetRandomProvider().RandBool(0.125))
+ {
+ // Taming succeeded
+ SetMaxHealth(20);
+ SetIsTame(true);
+ SetOwner(a_Player.GetName(), a_Player.GetUUID());
+ m_World->BroadcastEntityStatus(*this, esWolfTamed);
+ m_World->GetBroadcaster().BroadcastParticleEffect("heart", static_cast<Vector3f>(GetPosition()), Vector3f{}, 0, 5);
+ }
+ else
+ {
+ // Taming failed
+ m_World->BroadcastEntityStatus(*this, esWolfTaming);
+ m_World->GetBroadcaster().BroadcastParticleEffect("smoke", static_cast<Vector3f>(GetPosition()), Vector3f{}, 0, 5);
+ }
+ }
+ }
+ else if (IsTame())
+ {
+ // Feed the wolf, restoring its health, or dye its collar:
+ switch (EquippedItemType)
+ {
+ case E_ITEM_RAW_BEEF:
+ case E_ITEM_STEAK:
+ case E_ITEM_RAW_PORKCHOP:
+ case E_ITEM_COOKED_PORKCHOP:
+ case E_ITEM_RAW_CHICKEN:
+ case E_ITEM_COOKED_CHICKEN:
+ case E_ITEM_ROTTEN_FLESH:
+ {
+ if (m_Health < m_MaxHealth)
+ {
+ Heal(ItemHandler(EquippedItemType)->GetFoodInfo(&EquippedItem).FoodLevel);
+ if (!a_Player.IsGameModeCreative())
+ {
+ a_Player.GetInventory().RemoveOneEquippedItem();
+ }
+ }
+ break;
+ }
+ case E_ITEM_DYE:
+ {
+ if (a_Player.GetUUID() == m_OwnerUUID) // Is the player the owner of the dog?
+ {
+ SetCollarColor(EquippedItem.m_ItemDamage);
+ if (!a_Player.IsGameModeCreative())
+ {
+ a_Player.GetInventory().RemoveOneEquippedItem();
+ }
+ }
+ break;
+ }
+ default:
+ {
+ if (a_Player.GetUUID() == m_OwnerUUID) // Is the player the owner of the dog?
+ {
+ SetIsSitting(!IsSitting());
+ }
+ }
+ }
+ }
+
+ m_World->BroadcastEntityMetadata(*this);
}
@@ -253,92 +253,92 @@ void cWolf::OnRightClicked(cPlayer & a_Player)
void cWolf::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
{
- if (!IsAngry())
- {
- cMonster::Tick(a_Dt, a_Chunk);
- if (m_NotificationCooldown > 0)
- {
- m_NotificationCooldown -= 1;
- }
- }
- else
- {
- super::Tick(a_Dt, a_Chunk);
- }
-
- if (!IsTicking())
- {
- // The base class tick destroyed us
- return;
- }
-
- if (GetTarget() == nullptr)
- {
- cPlayer * a_Closest_Player = m_World->FindClosestPlayer(GetPosition(), static_cast<float>(m_SightDistance));
- if (a_Closest_Player != nullptr)
- {
- switch (a_Closest_Player->GetEquippedItem().m_ItemType)
- {
- case E_ITEM_BONE:
- case E_ITEM_RAW_BEEF:
- case E_ITEM_STEAK:
- case E_ITEM_RAW_CHICKEN:
- case E_ITEM_COOKED_CHICKEN:
- case E_ITEM_ROTTEN_FLESH:
- case E_ITEM_RAW_PORKCHOP:
- case E_ITEM_COOKED_PORKCHOP:
- {
- if (!IsBegging())
- {
- SetIsBegging(true);
- m_World->BroadcastEntityMetadata(*this);
- }
-
- m_FinalDestination = a_Closest_Player->GetPosition(); // So that we will look at a player holding food
-
- // Don't move to the player if the wolf is sitting.
- if (!IsSitting())
- {
- MoveToPosition(a_Closest_Player->GetPosition());
- }
-
- break;
- }
- default:
- {
- if (IsBegging())
- {
- SetIsBegging(false);
- m_World->BroadcastEntityMetadata(*this);
- }
- }
- }
- }
- }
- else
- {
- if (IsSitting())
- {
- SetTarget(nullptr);
- }
- else
- {
- MoveToPosition(GetTarget()->GetPosition());
- if (TargetIsInRange())
- {
- Attack(a_Dt);
- }
- }
- }
-
- if (IsTame() && !IsSitting())
- {
- TickFollowPlayer();
- }
- else if (IsSitting())
- {
- StopMovingToPosition();
- }
+ if (!IsAngry())
+ {
+ cMonster::Tick(a_Dt, a_Chunk);
+ if (m_NotificationCooldown > 0)
+ {
+ m_NotificationCooldown -= 1;
+ }
+ }
+ else
+ {
+ super::Tick(a_Dt, a_Chunk);
+ }
+
+ if (!IsTicking())
+ {
+ // The base class tick destroyed us
+ return;
+ }
+
+ if (GetTarget() == nullptr)
+ {
+ cPlayer * a_Closest_Player = m_World->FindClosestPlayer(GetPosition(), static_cast<float>(m_SightDistance));
+ if (a_Closest_Player != nullptr)
+ {
+ switch (a_Closest_Player->GetEquippedItem().m_ItemType)
+ {
+ case E_ITEM_BONE:
+ case E_ITEM_RAW_BEEF:
+ case E_ITEM_STEAK:
+ case E_ITEM_RAW_CHICKEN:
+ case E_ITEM_COOKED_CHICKEN:
+ case E_ITEM_ROTTEN_FLESH:
+ case E_ITEM_RAW_PORKCHOP:
+ case E_ITEM_COOKED_PORKCHOP:
+ {
+ if (!IsBegging())
+ {
+ SetIsBegging(true);
+ m_World->BroadcastEntityMetadata(*this);
+ }
+
+ m_FinalDestination = a_Closest_Player->GetPosition(); // So that we will look at a player holding food
+
+ // Don't move to the player if the wolf is sitting.
+ if (!IsSitting())
+ {
+ MoveToPosition(a_Closest_Player->GetPosition());
+ }
+
+ break;
+ }
+ default:
+ {
+ if (IsBegging())
+ {
+ SetIsBegging(false);
+ m_World->BroadcastEntityMetadata(*this);
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ if (IsSitting())
+ {
+ SetTarget(nullptr);
+ }
+ else
+ {
+ MoveToPosition(GetTarget()->GetPosition());
+ if (TargetIsInRange())
+ {
+ Attack(a_Dt);
+ }
+ }
+ }
+
+ if (IsTame() && !IsSitting())
+ {
+ TickFollowPlayer();
+ }
+ else if (IsSitting())
+ {
+ StopMovingToPosition();
+ }
}
@@ -347,61 +347,61 @@ void cWolf::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
void cWolf::TickFollowPlayer()
{
- class cCallback :
- public cPlayerListCallback
- {
- virtual bool Item(cPlayer * a_Player) override
- {
- OwnerPos = a_Player->GetPosition();
- OwnerFlying = a_Player->IsFlying();
- return true;
- }
- public:
- Vector3d OwnerPos;
- bool OwnerFlying;
- } Callback;
-
- if (m_World->DoWithPlayerByUUID(m_OwnerUUID, Callback))
- {
- // The player is present in the world, follow him:
- double Distance = (Callback.OwnerPos - GetPosition()).Length();
- if (Distance > 20)
- {
- if (!Callback.OwnerFlying)
- {
- Callback.OwnerPos.y = FindFirstNonAirBlockPosition(Callback.OwnerPos.x, Callback.OwnerPos.z);
- TeleportToCoords(Callback.OwnerPos.x, Callback.OwnerPos.y, Callback.OwnerPos.z);
- SetTarget(nullptr);
- }
- }
- if (Distance < 2)
- {
- if (GetTarget() == nullptr)
- {
- StopMovingToPosition();
- }
- }
- else
- {
- if (GetTarget() == nullptr)
- {
- if (!Callback.OwnerFlying)
- {
- MoveToPosition(Callback.OwnerPos);
- }
- }
- }
- }
+ class cCallback :
+ public cPlayerListCallback
+ {
+ virtual bool Item(cPlayer * a_Player) override
+ {
+ OwnerPos = a_Player->GetPosition();
+ OwnerFlying = a_Player->IsFlying();
+ return true;
+ }
+ public:
+ Vector3d OwnerPos;
+ bool OwnerFlying;
+ } Callback;
+
+ if (m_World->DoWithPlayerByUUID(m_OwnerUUID, Callback))
+ {
+ // The player is present in the world, follow him:
+ double Distance = (Callback.OwnerPos - GetPosition()).Length();
+ if (Distance > 20)
+ {
+ if (!Callback.OwnerFlying)
+ {
+ Callback.OwnerPos.y = FindFirstNonAirBlockPosition(Callback.OwnerPos.x, Callback.OwnerPos.z);
+ TeleportToCoords(Callback.OwnerPos.x, Callback.OwnerPos.y, Callback.OwnerPos.z);
+ SetTarget(nullptr);
+ }
+ }
+ if (Distance < 2)
+ {
+ if (GetTarget() == nullptr)
+ {
+ StopMovingToPosition();
+ }
+ }
+ else
+ {
+ if (GetTarget() == nullptr)
+ {
+ if (!Callback.OwnerFlying)
+ {
+ MoveToPosition(Callback.OwnerPos);
+ }
+ }
+ }
+ }
}
void cWolf::InStateIdle(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
{
- if (!IsTame())
- {
- cMonster::InStateIdle(a_Dt, a_Chunk);
- }
+ if (!IsTame())
+ {
+ cMonster::InStateIdle(a_Dt, a_Chunk);
+ }
}
diff --git a/src/Mobs/Wolf.h b/src/Mobs/Wolf.h
index e05fedbf8..f001fb559 100644
--- a/src/Mobs/Wolf.h
+++ b/src/Mobs/Wolf.h
@@ -9,64 +9,64 @@ class cEntity;
class cWolf :
- public cPassiveAggressiveMonster
+ public cPassiveAggressiveMonster
{
- typedef cPassiveAggressiveMonster super;
+ typedef cPassiveAggressiveMonster super;
public:
- cWolf(void);
-
- CLASS_PROTODEF(cWolf)
-
- void NotifyAlliesOfFight(cPawn * a_Opponent);
- virtual bool DoTakeDamage(TakeDamageInfo & a_TDI) override;
- virtual void OnRightClicked(cPlayer & a_Player) override;
- virtual void Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override;
- virtual void TickFollowPlayer();
- virtual bool Attack(std::chrono::milliseconds a_Dt) override;
-
- // Get functions
- bool IsSitting (void) const override { return m_IsSitting; }
- bool IsTame (void) const override { return m_IsTame; }
- bool IsBegging (void) const { return m_IsBegging; }
- bool IsAngry (void) const { return m_IsAngry; }
- AString GetOwnerName (void) const { return m_OwnerName; }
- AString GetOwnerUUID (void) const { return m_OwnerUUID; }
- int GetCollarColor(void) const { return m_CollarColor; }
-
- // Set functions
- void SetIsSitting (bool a_IsSitting) { m_IsSitting = a_IsSitting; }
- void SetIsTame (bool a_IsTame) { m_IsTame = a_IsTame; }
- void SetIsBegging (bool a_IsBegging) { m_IsBegging = a_IsBegging; }
- void SetIsAngry (bool a_IsAngry) { m_IsAngry = a_IsAngry; }
- void SetCollarColor(int a_CollarColor) { m_CollarColor = a_CollarColor; }
- void SetOwner (const AString & a_NewOwnerName, const AString & a_NewOwnerUUID)
- {
- m_OwnerName = a_NewOwnerName;
- m_OwnerUUID = a_NewOwnerUUID;
- }
-
- /** Notfies the wolf of a nearby fight.
- The wolf may then decide to attack a_Opponent.
- If a_IsPlayer is true, then the player whose ID is a_PlayerID is fighting a_Opponent
- If false, then a wolf owned by the player whose ID is a_PlayerID is fighting a_Opponent
- @param a_PlayerID The ID of the fighting player, or the ID of the owner whose wolf is fighting.
- @param a_Opponent The opponent who is being faught.
- @param a_IsPlayerInvolved Whether the fighter a player or a wolf. */
- void ReceiveNearbyFightInfo(AString a_PlayerID, cPawn * a_Opponent, bool a_IsPlayerInvolved);
-
- virtual void InStateIdle(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override;
+ cWolf(void);
+
+ CLASS_PROTODEF(cWolf)
+
+ void NotifyAlliesOfFight(cPawn * a_Opponent);
+ virtual bool DoTakeDamage(TakeDamageInfo & a_TDI) override;
+ virtual void OnRightClicked(cPlayer & a_Player) override;
+ virtual void Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override;
+ virtual void TickFollowPlayer();
+ //virtual bool Attack(std::chrono::milliseconds a_Dt) override;
+
+ // Get functions
+ bool IsSitting (void) const override { return m_IsSitting; }
+ bool IsTame (void) const override { return m_IsTame; }
+ bool IsBegging (void) const { return m_IsBegging; }
+ bool IsAngry (void) const { return m_IsAngry; }
+ AString GetOwnerName (void) const { return m_OwnerName; }
+ AString GetOwnerUUID (void) const { return m_OwnerUUID; }
+ int GetCollarColor(void) const { return m_CollarColor; }
+
+ // Set functions
+ void SetIsSitting (bool a_IsSitting) { m_IsSitting = a_IsSitting; }
+ void SetIsTame (bool a_IsTame) { m_IsTame = a_IsTame; }
+ void SetIsBegging (bool a_IsBegging) { m_IsBegging = a_IsBegging; }
+ void SetIsAngry (bool a_IsAngry) { m_IsAngry = a_IsAngry; }
+ void SetCollarColor(int a_CollarColor) { m_CollarColor = a_CollarColor; }
+ void SetOwner (const AString & a_NewOwnerName, const AString & a_NewOwnerUUID)
+ {
+ m_OwnerName = a_NewOwnerName;
+ m_OwnerUUID = a_NewOwnerUUID;
+ }
+
+ /** Notfies the wolf of a nearby fight.
+ The wolf may then decide to attack a_Opponent.
+ If a_IsPlayer is true, then the player whose ID is a_PlayerID is fighting a_Opponent
+ If false, then a wolf owned by the player whose ID is a_PlayerID is fighting a_Opponent
+ @param a_PlayerID The ID of the fighting player, or the ID of the owner whose wolf is fighting.
+ @param a_Opponent The opponent who is being faught.
+ @param a_IsPlayerInvolved Whether the fighter a player or a wolf. */
+ void ReceiveNearbyFightInfo(AString a_PlayerID, cPawn * a_Opponent, bool a_IsPlayerInvolved);
+
+ virtual void InStateIdle(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override;
protected:
- bool m_IsSitting;
- bool m_IsTame;
- bool m_IsBegging;
- bool m_IsAngry;
- AString m_OwnerName;
- AString m_OwnerUUID;
- int m_CollarColor;
- int m_NotificationCooldown;
+ bool m_IsSitting;
+ bool m_IsTame;
+ bool m_IsBegging;
+ bool m_IsAngry;
+ AString m_OwnerName;
+ AString m_OwnerUUID;
+ int m_CollarColor;
+ int m_NotificationCooldown;
} ;