Added anvil enchantment handling. (#3857)

+ Added anvil enchantment handling.
This commit is contained in:
Lane Kolbly
2017-07-28 18:00:20 +01:00
committed by Tiger Wang
parent 5402b214b3
commit 790e15f2e6
6 changed files with 480 additions and 37 deletions
+196 -3
View File
@@ -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: