Add unbreaking for armor (#4220)
Ref: minecraft.gamepedia.com/Enchanting#Unbreaking #915
This commit is contained in:
parent
06eb5cc70d
commit
2431b077cd
@ -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
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user