summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/Entities/Player.cpp55
-rw-r--r--src/Entities/Player.h4
2 files changed, 37 insertions, 22 deletions
diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp
index c674f4620..e984534a5 100644
--- a/src/Entities/Player.cpp
+++ b/src/Entities/Player.cpp
@@ -934,17 +934,14 @@ void cPlayer::SetFlying(bool a_IsFlying)
-void cPlayer::ApplyArmorDamage(int DamageBlocked)
+void cPlayer::ApplyArmorDamage(int a_DamageBlocked)
{
- short ArmorDamage = static_cast<short>(DamageBlocked / 4);
- if (ArmorDamage == 0)
+ short ArmorDamage = static_cast<short>(std::max(a_DamageBlocked / 4, 1));
+
+ for (int i = 0; i < 4; i++)
{
- ArmorDamage = 1;
+ UseItem(cInventory::invArmorOffset + i, ArmorDamage);
}
- m_Inventory.DamageItem(cInventory::invArmorOffset + 0, ArmorDamage);
- m_Inventory.DamageItem(cInventory::invArmorOffset + 1, ArmorDamage);
- m_Inventory.DamageItem(cInventory::invArmorOffset + 2, ArmorDamage);
- m_Inventory.DamageItem(cInventory::invArmorOffset + 3, ArmorDamage);
}
@@ -2334,20 +2331,7 @@ void cPlayer::UseEquippedItem(short a_Damage)
return;
}
- // If the item has an unbreaking enchantment, give it a chance of escaping damage:
- // Ref: https://minecraft.gamepedia.com/Enchanting#Unbreaking
- cItem Item = GetEquippedItem();
- int UnbreakingLevel = static_cast<int>(Item.m_Enchantments.GetLevel(cEnchantments::enchUnbreaking));
- double chance = 1 - (1.0 / (UnbreakingLevel + 1));
- if (GetRandomProvider().RandBool(chance))
- {
- return;
- }
-
- if (GetInventory().DamageEquippedItem(a_Damage))
- {
- m_World->BroadcastSoundEffect("entity.item.break", GetPosition(), 0.5f, static_cast<float>(0.75 + (static_cast<float>((GetUniqueID() * 23) % 32)) / 64));
- }
+ UseItem(cInventory::invHotbarOffset + m_Inventory.GetEquippedSlotNum(), a_Damage);
}
@@ -2369,6 +2353,33 @@ void cPlayer::UseEquippedItem(cItemHandler::eDurabilityLostAction a_Action)
+void cPlayer::UseItem(int a_SlotNumber, short a_Damage)
+{
+ const cItem & Item = m_Inventory.GetSlot(a_SlotNumber);
+ if (Item.IsEmpty())
+ {
+ return;
+ }
+
+ // Ref: https://minecraft.gamepedia.com/Enchanting#Unbreaking
+ unsigned int UnbreakingLevel = Item.m_Enchantments.GetLevel(cEnchantments::enchUnbreaking);
+ double chance = ItemCategory::IsArmor(Item.m_ItemType)
+ ? (0.6 + (0.4 / (UnbreakingLevel + 1))) : (1.0 / (UnbreakingLevel + 1));
+
+ // When durability is reduced by multiple points
+ // Unbreaking is applied for each point of reduction.
+ std::binomial_distribution<short> Dist(a_Damage, chance);
+ short ReducedDamage = Dist(GetRandomProvider().Engine());
+ if (m_Inventory.DamageItem(a_SlotNumber, ReducedDamage))
+ {
+ m_World->BroadcastSoundEffect("entity.item.break", GetPosition(), 0.5f, static_cast<float>(0.75 + (static_cast<float>((GetUniqueID() * 23) % 32)) / 64));
+ }
+}
+
+
+
+
+
void cPlayer::HandleFood(void)
{
// Ref.: https://minecraft.gamepedia.com/Hunger
diff --git a/src/Entities/Player.h b/src/Entities/Player.h
index f04f90a2b..8fa463c5a 100644
--- a/src/Entities/Player.h
+++ b/src/Entities/Player.h
@@ -425,6 +425,10 @@ public:
is damaged by when used for a_Action */
void UseEquippedItem(cItemHandler::eDurabilityLostAction a_Action);
+ /** Damage the item in a_SlotNumber by a_Damage, possibly less if the
+ equipped item is enchanted. */
+ void UseItem(int a_SlotNumber, short a_Damage = 1);
+
void SendHealth(void);
void SendExperience(void);