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);
|
short ArmorDamage = static_cast<short>(std::max(a_DamageBlocked / 4, 1));
|
||||||
if (ArmorDamage == 0)
|
|
||||||
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the item has an unbreaking enchantment, give it a chance of escaping damage:
|
UseItem(cInventory::invHotbarOffset + m_Inventory.GetEquippedSlotNum(), a_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));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -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)
|
void cPlayer::HandleFood(void)
|
||||||
{
|
{
|
||||||
// Ref.: https://minecraft.gamepedia.com/Hunger
|
// Ref.: https://minecraft.gamepedia.com/Hunger
|
||||||
|
@ -425,6 +425,10 @@ public:
|
|||||||
is damaged by when used for a_Action */
|
is damaged by when used for a_Action */
|
||||||
void UseEquippedItem(cItemHandler::eDurabilityLostAction 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 SendHealth(void);
|
||||||
|
|
||||||
void SendExperience(void);
|
void SendExperience(void);
|
||||||
|
Loading…
Reference in New Issue
Block a user