1
0

Add unbreaking for armor (#4220)

Ref: minecraft.gamepedia.com/Enchanting#Unbreaking

#915
This commit is contained in:
Bond-009 2018-07-13 00:10:15 +02:00 committed by peterbell10
parent 06eb5cc70d
commit 2431b077cd
2 changed files with 37 additions and 22 deletions

View File

@ -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

View File

@ -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);