summaryrefslogtreecommitdiffstats
path: root/src/Mobs
diff options
context:
space:
mode:
Diffstat (limited to 'src/Mobs')
-rw-r--r--src/Mobs/Horse.cpp134
-rw-r--r--src/Mobs/Horse.h28
2 files changed, 137 insertions, 25 deletions
diff --git a/src/Mobs/Horse.cpp b/src/Mobs/Horse.cpp
index 07d3f7481..77edc0d27 100644
--- a/src/Mobs/Horse.cpp
+++ b/src/Mobs/Horse.cpp
@@ -5,6 +5,7 @@
#include "../EffectID.h"
#include "../Entities/Player.h"
#include "Broadcaster.h"
+#include "UI/HorseWindow.h"
@@ -12,16 +13,15 @@
cHorse::cHorse(int Type, int Color, int Style, int TameTimes) :
super("Horse", mtHorse, "entity.horse.hurt", "entity.horse.death", 1.4, 1.6),
+ cEntityWindowOwner(this),
m_bHasChest(false),
m_bIsEating(false),
m_bIsRearing(false),
m_bIsMouthOpen(false),
m_bIsTame(false),
- m_bIsSaddled(false),
m_Type(Type),
m_Color(Color),
m_Style(Style),
- m_Armour(0),
m_TimesToTame(TameTimes),
m_TameAttemptTimes(0),
m_RearTickCount(0),
@@ -33,6 +33,19 @@ cHorse::cHorse(int Type, int Color, int Style, int TameTimes) :
+cHorse::~cHorse()
+{
+ auto Window = GetWindow();
+ if (Window != nullptr)
+ {
+ Window->OwnerDestroyed();
+ }
+}
+
+
+
+
+
void cHorse::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
{
super::Tick(a_Dt, a_Chunk);
@@ -108,22 +121,24 @@ void cHorse::OnRightClicked(cPlayer & a_Player)
if (m_bIsTame)
{
- if (!m_bIsSaddled)
+ if (a_Player.IsCrouched())
{
- if (a_Player.GetEquippedItem().m_ItemType == E_ITEM_SADDLE)
- {
- // Saddle the horse:
- if (!a_Player.IsGameModeCreative())
- {
- a_Player.GetInventory().RemoveOneEquippedItem();
- }
- m_bIsSaddled = true;
- m_World->BroadcastEntityMetadata(*this);
- }
- else
- {
- a_Player.AttachTo(this);
- }
+ PlayerOpenWindow(a_Player);
+ return;
+ }
+
+ auto EquipedItemType = a_Player.GetEquippedItem().m_ItemType;
+
+ if (
+ !IsSaddled() &&
+ (
+ (EquipedItemType == E_ITEM_SADDLE) ||
+ ItemCategory::IsHorseArmor(EquipedItemType)
+ )
+ )
+ {
+ // Player is holding a horse inventory item, open the window:
+ PlayerOpenWindow(a_Player);
}
else
{
@@ -167,6 +182,65 @@ void cHorse::OnRightClicked(cPlayer & a_Player)
+void cHorse::SetHorseSaddle(cItem a_Saddle)
+{
+ if (a_Saddle.m_ItemType == E_ITEM_SADDLE)
+ {
+ m_World->BroadcastSoundEffect("entity.horse.saddle", GetPosition(), 1.0f, 0.8f);
+ }
+ else if (!a_Saddle.IsEmpty())
+ {
+ return; // Invalid item
+ }
+
+ m_Saddle = std::move(a_Saddle);
+ m_World->BroadcastEntityMetadata(*this);
+}
+
+
+
+
+
+void cHorse::SetHorseArmor(cItem a_Armor)
+{
+ if (ItemCategory::IsHorseArmor(a_Armor.m_ItemType))
+ {
+ m_World->BroadcastSoundEffect("entity.horse.armor", GetPosition(), 1.0f, 0.8f);
+ }
+ else if (!a_Armor.IsEmpty())
+ {
+ return; // Invalid item
+ }
+
+ m_Armor = std::move(a_Armor);
+ m_World->BroadcastEntityMetadata(*this);
+}
+
+
+
+
+
+int cHorse::GetHorseArmour(void) const
+{
+ switch (m_Armor.m_ItemType)
+ {
+ case E_ITEM_EMPTY: return 0;
+ case E_ITEM_IRON_HORSE_ARMOR: return 1;
+ case E_ITEM_GOLD_HORSE_ARMOR: return 2;
+ case E_ITEM_DIAMOND_HORSE_ARMOR: return 3;
+
+ default:
+ {
+ LOGWARN("cHorse::GetHorseArmour: Invalid armour item (%d)", m_Armor.m_ItemType);
+ return 0;
+ }
+ }
+}
+
+
+
+
+
void cHorse::GetDrops(cItems & a_Drops, cEntity * a_Killer)
{
if (IsBaby())
@@ -180,9 +254,13 @@ void cHorse::GetDrops(cItems & a_Drops, cEntity * a_Killer)
LootingLevel = a_Killer->GetEquippedWeapon().m_Enchantments.GetLevel(cEnchantments::enchLooting);
}
AddRandomDropItem(a_Drops, 0, 2 + LootingLevel, E_ITEM_LEATHER);
- if (m_bIsSaddled)
+ if (IsSaddled())
{
- a_Drops.push_back(cItem(E_ITEM_SADDLE, 1));
+ a_Drops.push_back(m_Saddle);
+ }
+ if (!m_Armor.IsEmpty())
+ {
+ a_Drops.push_back(m_Armor);
}
}
@@ -205,8 +283,24 @@ void cHorse::InStateIdle(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
void cHorse::HandleSpeedFromAttachee(float a_Forward, float a_Sideways)
{
- if ((m_bIsTame) && (m_bIsSaddled))
+ if ((m_bIsTame) && IsSaddled())
{
super::HandleSpeedFromAttachee(a_Forward * m_MaxSpeed, a_Sideways * m_MaxSpeed);
}
}
+
+
+
+
+
+void cHorse::PlayerOpenWindow(cPlayer & a_Player)
+{
+ auto Window = GetWindow();
+ if (Window == nullptr)
+ {
+ Window = new cHorseWindow(*this);
+ OpenWindow(Window);
+ }
+
+ a_Player.OpenWindow(*Window);
+}
diff --git a/src/Mobs/Horse.h b/src/Mobs/Horse.h
index 82026a0ee..38625001e 100644
--- a/src/Mobs/Horse.h
+++ b/src/Mobs/Horse.h
@@ -2,18 +2,21 @@
#pragma once
#include "PassiveMonster.h"
+#include "UI/WindowOwner.h"
class cHorse :
- public cPassiveMonster
+ public cPassiveMonster,
+ public cEntityWindowOwner
{
typedef cPassiveMonster super;
public:
cHorse(int Type, int Color, int Style, int TameTimes);
+ virtual ~cHorse() override;
CLASS_PROTODEF(cHorse)
@@ -23,7 +26,7 @@ public:
virtual void Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override;
virtual void OnRightClicked(cPlayer & a_Player) override;
- bool IsSaddled (void) const {return m_bIsSaddled; }
+ bool IsSaddled (void) const {return !m_Saddle.IsEmpty(); }
bool IsChested (void) const {return m_bHasChest; }
bool IsEating (void) const {return m_bIsEating; }
bool IsRearing (void) const {return m_bIsRearing; }
@@ -32,7 +35,18 @@ public:
int GetHorseType (void) const {return m_Type; }
int GetHorseColor (void) const {return m_Color; }
int GetHorseStyle (void) const {return m_Style; }
- int GetHorseArmour (void) const {return m_Armour;}
+ int GetHorseArmour (void) const;
+
+ /** Set the horse's saddle to the given item.
+ @param a_SaddleItem should be either a saddle or empty. */
+ void SetHorseSaddle(cItem a_SaddleItem);
+
+ /** Set the horse's armor slot to the given item.
+ @param a_SaddleItem should be either a type of horse armor or empty. */
+ void SetHorseArmor(cItem a_ArmorItem);
+
+ const cItem & GetHorseSaddle() const { return m_Saddle; }
+ const cItem & GetHorseArmorItem() const { return m_Armor; }
virtual void GetBreedingItems(cItems & a_Items) override
{
@@ -40,11 +54,15 @@ public:
a_Items.Add(E_ITEM_GOLDEN_APPLE);
}
+ void PlayerOpenWindow(cPlayer & a_Player);
+
private:
- bool m_bHasChest, m_bIsEating, m_bIsRearing, m_bIsMouthOpen, m_bIsTame, m_bIsSaddled;
- int m_Type, m_Color, m_Style, m_Armour, m_TimesToTame, m_TameAttemptTimes, m_RearTickCount;
+ bool m_bHasChest, m_bIsEating, m_bIsRearing, m_bIsMouthOpen, m_bIsTame;
+ int m_Type, m_Color, m_Style, m_TimesToTame, m_TameAttemptTimes, m_RearTickCount;
float m_MaxSpeed;
+ cItem m_Saddle;
+ cItem m_Armor;
} ;