summaryrefslogtreecommitdiffstats
path: root/src/Item.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/Item.cpp')
-rw-r--r--src/Item.cpp199
1 files changed, 196 insertions, 3 deletions
diff --git a/src/Item.cpp b/src/Item.cpp
index d421a95ad..3d9efb3b3 100644
--- a/src/Item.cpp
+++ b/src/Item.cpp
@@ -228,14 +228,14 @@ void cItem::FromJson(const Json::Value & a_Value)
-bool cItem::IsEnchantable(short a_ItemType, bool a_WithBook)
+bool cItem::IsEnchantable(short a_ItemType, bool a_FromBook)
{
if (
ItemCategory::IsAxe(a_ItemType) ||
ItemCategory::IsSword(a_ItemType) ||
ItemCategory::IsShovel(a_ItemType) ||
ItemCategory::IsPickaxe(a_ItemType) ||
- (a_WithBook && ItemCategory::IsHoe(a_ItemType)) ||
+ (a_FromBook && ItemCategory::IsHoe(a_ItemType)) ||
ItemCategory::IsArmor(a_ItemType)
)
{
@@ -255,7 +255,7 @@ bool cItem::IsEnchantable(short a_ItemType, bool a_WithBook)
case E_ITEM_SHEARS:
case E_ITEM_FLINT_AND_STEEL:
{
- return a_WithBook;
+ return a_FromBook;
}
}
@@ -419,6 +419,199 @@ bool cItem::EnchantByXPLevels(int a_NumXPLevels)
+int cItem::AddEnchantment(int a_EnchantmentID, unsigned int a_Level, bool a_FromBook)
+{
+ unsigned int OurLevel = m_Enchantments.GetLevel(a_EnchantmentID);
+ int Multiplier = cEnchantments::GetXPCostMultiplier(a_EnchantmentID, a_FromBook);
+ unsigned int NewLevel = 0;
+ if (OurLevel > a_Level)
+ {
+ // They don't add anything to us
+ NewLevel = OurLevel;
+ }
+ else if (OurLevel == a_Level)
+ {
+ // Bump it by 1
+ NewLevel = OurLevel + 1;
+ }
+ else
+ {
+ // Take the sacrifice's level
+ NewLevel = a_Level;
+ }
+ unsigned int LevelCap = cEnchantments::GetLevelCap(a_EnchantmentID);
+ if (NewLevel > LevelCap)
+ {
+ NewLevel = LevelCap;
+ }
+
+ m_Enchantments.SetLevel(a_EnchantmentID, NewLevel);
+ return static_cast<int>(NewLevel) * Multiplier;
+}
+
+
+
+
+
+bool cItem::CanHaveEnchantment(int a_EnchantmentID)
+{
+ if (m_ItemType == E_ITEM_ENCHANTED_BOOK)
+ {
+ // Enchanted books can take anything
+ return true;
+ }
+
+ // The organization here is based on the summary at:
+ // http://minecraft.gamepedia.com/Enchanting
+ // as of July 2017 (Minecraft 1.12).
+
+ // Hand tool enchantments
+ static const std::set<int> SwordEnchantments =
+ {
+ cEnchantments::enchBaneOfArthropods,
+ cEnchantments::enchFireAspect,
+ cEnchantments::enchKnockback,
+ cEnchantments::enchLooting,
+ cEnchantments::enchSharpness,
+ cEnchantments::enchSmite,
+ cEnchantments::enchUnbreaking
+ };
+ static const std::set<int> AxeEnchantments =
+ {
+ cEnchantments::enchBaneOfArthropods,
+ cEnchantments::enchEfficiency,
+ cEnchantments::enchFortune,
+ cEnchantments::enchSharpness,
+ cEnchantments::enchSilkTouch,
+ cEnchantments::enchSmite,
+ cEnchantments::enchUnbreaking
+ };
+ static const std::set<int> ToolEnchantments =
+ {
+ cEnchantments::enchEfficiency,
+ cEnchantments::enchFortune,
+ cEnchantments::enchSilkTouch,
+ cEnchantments::enchUnbreaking
+ };
+ static const std::set<int> ShearEnchantments =
+ {
+ cEnchantments::enchEfficiency,
+ cEnchantments::enchUnbreaking
+ };
+ static const std::set<int> BowEnchantments =
+ {
+ cEnchantments::enchFlame,
+ cEnchantments::enchInfinity,
+ cEnchantments::enchPower,
+ cEnchantments::enchPunch
+ };
+ static const std::set<int> FishingEnchantments =
+ {
+ cEnchantments::enchLuckOfTheSea,
+ cEnchantments::enchLure
+ };
+ static const std::set<int> MiscEnchantments =
+ {
+ cEnchantments::enchUnbreaking
+ };
+
+ if (ItemCategory::IsSword(m_ItemType))
+ {
+ return SwordEnchantments.count(a_EnchantmentID) > 0;
+ }
+ if (ItemCategory::IsAxe(m_ItemType))
+ {
+ return AxeEnchantments.count(a_EnchantmentID) > 0;
+ }
+ if (ItemCategory::IsPickaxe(m_ItemType) || ItemCategory::IsShovel(m_ItemType))
+ {
+ return ToolEnchantments.count(a_EnchantmentID) > 0;
+ }
+ if (m_ItemType == E_ITEM_SHEARS)
+ {
+ return ShearEnchantments.count(a_EnchantmentID) > 0;
+ }
+ if (m_ItemType == E_ITEM_BOW)
+ {
+ return BowEnchantments.count(a_EnchantmentID) > 0;
+ }
+ if (m_ItemType == E_ITEM_FISHING_ROD)
+ {
+ return FishingEnchantments.count(a_EnchantmentID) > 0;
+ }
+ if (ItemCategory::IsHoe(m_ItemType) || (m_ItemType == E_ITEM_FLINT_AND_STEEL) || (m_ItemType == E_ITEM_CARROT_ON_STICK) || (m_ItemType == E_ITEM_SHIELD))
+ {
+ return MiscEnchantments.count(a_EnchantmentID) > 0;
+ }
+
+ // Armor enchantments
+ static const std::set<int> ArmorEnchantments =
+ {
+ cEnchantments::enchBlastProtection,
+ cEnchantments::enchFireProtection,
+ cEnchantments::enchProjectileProtection,
+ cEnchantments::enchProtection,
+ cEnchantments::enchThorns,
+ cEnchantments::enchUnbreaking
+ };
+ static const std::set<int> HatOnlyEnchantments =
+ {
+ cEnchantments::enchAquaAffinity,
+ cEnchantments::enchRespiration
+ };
+ static const std::set<int> BootOnlyEnchantments =
+ {
+ cEnchantments::enchDepthStrider,
+ cEnchantments::enchFeatherFalling
+ };
+
+ if (ItemCategory::IsBoots(m_ItemType))
+ {
+ return (BootOnlyEnchantments.count(a_EnchantmentID) > 0) || (ArmorEnchantments.count(a_EnchantmentID) > 0);
+ }
+ if (ItemCategory::IsHelmet(m_ItemType))
+ {
+ return (HatOnlyEnchantments.count(a_EnchantmentID) > 0) || (ArmorEnchantments.count(a_EnchantmentID) > 0);
+ }
+ if (ItemCategory::IsArmor(m_ItemType))
+ {
+ return ArmorEnchantments.count(a_EnchantmentID) > 0;
+ }
+ return false;
+}
+
+
+
+
+
+int cItem::AddEnchantmentsFromItem(const cItem & a_Other)
+{
+ bool FromBook = (a_Other.m_ItemType == E_ITEM_ENCHANTED_BOOK);
+
+ // Consider each enchantment seperately
+ int EnchantingCost = 0;
+ for (auto & Enchantment : a_Other.m_Enchantments)
+ {
+ if (CanHaveEnchantment(Enchantment.first))
+ {
+ if (!m_Enchantments.CanAddEnchantment(Enchantment.first))
+ {
+ // Cost of incompatible enchantments
+ EnchantingCost += 1;
+ }
+ else
+ {
+ EnchantingCost += AddEnchantment(Enchantment.first, Enchantment.second, FromBook);
+ }
+ }
+ }
+ return EnchantingCost;
+}
+
+
+
+
+
////////////////////////////////////////////////////////////////////////////////
// cItems: