// Enchantments.cpp // Implements the cEnchantments class representing a storage for item enchantments and stored-enchantments #include "Globals.h" #include "Enchantments.h" #include "WorldStorage/FastNBT.h" #include "FastRandom.h" #include "Noise/Noise.h" #include "BlockType.h" cEnchantments::cEnchantments(void) { // Nothing needed yet, but the constructor needs to be declared and impemented in order to be usable } cEnchantments::cEnchantments(const AString & a_StringSpec) { AddFromString(a_StringSpec); } void cEnchantments::Add(const cEnchantments & a_Other) { for (cEnchantments::cMap::const_iterator itr = a_Other.m_Enchantments.begin(), end = a_Other.m_Enchantments.end(); itr != end; ++itr) { SetLevel(itr->first, itr->second); } // for itr - a_Other.m_Enchantments[] } void cEnchantments::AddFromString(const AString & a_StringSpec) { // Add enchantments in the stringspec; if a specified enchantment already exists, overwrites it // Split the StringSpec into separate declarations, each in the form "id=lvl": AStringVector Decls = StringSplit(a_StringSpec, ";"); for (AStringVector::const_iterator itr = Decls.begin(), end = Decls.end(); itr != end; ++itr) { // Split each declaration into the id and lvl part: if (itr->empty()) { // The decl is empty (may happen if there's an extra semicolon at the end), ignore silently continue; } AStringVector Split = StringSplitAndTrim(*itr, "="); if (Split.size() != 2) { // Malformed decl LOG("%s: Malformed enchantment decl: \"%s\", skipping.", __FUNCTION__, itr->c_str()); continue; } int id = StringToEnchantmentID(Split[0]); if (id < 0) { LOG("%s: Failed to parse enchantment \"%s\", skipping.", __FUNCTION__, Split[0].c_str()); continue; } unsigned int lvl; if (!StringToInteger(Split[1], lvl)) { // Level failed to parse LOG("%s: Failed to parse enchantment level \"%s\", skipping.", __FUNCTION__, Split[1].c_str()); continue; } SetLevel(id, lvl); } // for itr - Decls[] } size_t cEnchantments::Count(void) { return m_Enchantments.size(); } AString cEnchantments::ToString(void) const { // Serialize all the enchantments into a string AString res; for (cEnchantments::cMap::const_iterator itr = m_Enchantments.begin(), end = m_Enchantments.end(); itr != end; ++itr) { AppendPrintf(res, "%d=%d;", itr->first, itr->second); } // for itr - m_Enchantments[] return res; } unsigned int cEnchantments::GetLevel(int a_EnchantmentID) const { // Return the level for the specified enchantment; 0 if not stored cMap::const_iterator itr = m_Enchantments.find(a_EnchantmentID); if (itr != m_Enchantments.end()) { return itr->second; } // Not stored, return zero return 0; } void cEnchantments::SetLevel(int a_EnchantmentID, unsigned int a_Level) { // Sets the level for the specified enchantment, adding it if not stored before or removing it if level <= 0 if (a_Level == 0) { // Delete enchantment, if present: cMap::iterator itr = m_Enchantments.find(a_EnchantmentID); if (itr != m_Enchantments.end()) { m_Enchantments.erase(itr); } } else { // Add / overwrite enchantment m_Enchantments[a_EnchantmentID] = a_Level; } } void cEnchantments::Clear(void) { m_Enchantments.clear(); } bool cEnchantments::IsEmpty(void) const { return m_Enchantments.empty(); } unsigned int cEnchantments::GetLevelCap(int a_EnchantmentID) { switch (a_EnchantmentID) { case enchProtection: return 4; case enchFireProtection: return 4; case enchFeatherFalling: return 4; case enchBlastProtection: return 4; case enchProjectileProtection: return 4; case enchRespiration: return 3; case enchAquaAffinity: return 1; case enchThorns: return 3; case enchDepthStrider: return 3; case enchSharpness: return 5; case enchSmite: return 5; case enchBaneOfArthropods: return 5; case enchKnockback: return 2; case enchFireAspect: return 2; case enchLooting: return 3; case enchEfficiency: return 5; case enchSilkTouch: return 1; case enchUnbreaking: return 3; case enchFortune: return 3; case enchPower: return 5; case enchPunch: return 2; case enchFlame: return 1; case enchInfinity: return 1; case enchLuckOfTheSea: return 3; case enchLure: return 3; } LOGWARNING("Unknown enchantment ID %d", a_EnchantmentID); return 0; } int cEnchantments::GetXPCostMultiplier(int a_EnchantmentID, bool FromBook) { if (FromBook) { switch (a_EnchantmentID) { case enchProtection: return 1; case enchFireProtection: return 1; case enchFeatherFalling: return 1; case enchBlastProtection: return 2; case enchProjectileProtection: return 1; case enchRespiration: return 2; case enchAquaAffinity: return 2; case enchThorns: return 4; case enchDepthStrider: return 2; case enchSharpness: return 1; case enchSmite: return 1; case enchBaneOfArthropods: return 1; case enchKnockback: return 1; case enchFireAspect: return 2; case enchLooting: return 2; case enchEfficiency: return 1; case enchSilkTouch: return 4; case enchUnbreaking: return 1; case enchFortune: return 1; case enchPower: return 1; case enchPunch: return 2; case enchFlame: return 2; case enchInfinity: return 4; case enchLuckOfTheSea: return 2; case enchLure: return 2; } } else // Without book { switch (a_EnchantmentID) { case enchProtection: return 1; case enchFireProtection: return 2; case enchFeatherFalling: return 2; case enchBlastProtection: return 4; case enchProjectileProtection: return 2; case enchRespiration: return 4; case enchAquaAffinity: return 4; case enchThorns: return 8; case enchDepthStrider: return 4; case enchSharpness: return 1; case enchSmite: return 2; case enchBaneOfArthropods: return 2; case enchKnockback: return 2; case enchFireAspect: return 4; case enchLooting: return 4; case enchEfficiency: return 1; case enchSilkTouch: return 8; case enchUnbreaking: return 2; case enchFortune: return 4; case enchPower: return 1; case enchPunch: return 4; case enchFlame: return 4; case enchInfinity: return 8; case enchLuckOfTheSea: return 4; case enchLure: return 4; } } LOGWARNING("Unknown enchantment ID %d", a_EnchantmentID); return 0; } bool cEnchantments::CanAddEnchantment(int a_EnchantmentID) const { if (GetLevel(a_EnchantmentID) > 0) { return true; } static const std::vector > IncompatibleEnchantments = { // Armor { enchProtection, enchFireProtection, enchBlastProtection, enchProjectileProtection }, // Tool { enchFortune, enchSilkTouch }, // Sword { enchSharpness, enchSmite, enchBaneOfArthropods }, // Boots // {enchDepthStrider, enchFrostWalker}, // Bow // {enchInfinity, enchMending} }; for (const auto & excl: IncompatibleEnchantments) { if (excl.count(a_EnchantmentID) != 0) { // See if we also have any of the enchantments for (auto ench: excl) { if (GetLevel(ench) > 0) { return false; } } } } return true; } int cEnchantments::StringToEnchantmentID(const AString & a_EnchantmentName) { static const struct { int m_Value; const char * m_Name; } EnchantmentNames[] = { { enchProtection, "Protection" }, { enchFireProtection, "FireProtection" }, { enchFeatherFalling, "FeatherFalling" }, { enchBlastProtection, "BlastProtection" }, { enchProjectileProtection, "ProjectileProtection" }, { enchRespiration, "Respiration" }, { enchAquaAffinity, "AquaAffinity" }, { enchThorns, "Thorns" }, { enchDepthStrider, "DepthStrider" }, { enchSharpness, "Sharpness" }, { enchSmite, "Smite" }, { enchBaneOfArthropods, "BaneOfArthropods" }, { enchKnockback, "Knockback" }, { enchFireAspect, "FireAspect" }, { enchLooting, "Looting" }, { enchEfficiency, "Efficiency" }, { enchSilkTouch, "SilkTouch" }, { enchUnbreaking, "Unbreaking" }, { enchFortune, "Fortune" }, { enchPower, "Power" }, { enchPunch, "Punch" }, { enchFlame, "Flame" }, { enchInfinity, "Infinity" }, { enchLuckOfTheSea, "LuckOfTheSea" }, { enchLure, "Lure" }, } ; // First try to parse as a number: int id = atoi(a_EnchantmentName.c_str()); if ((id != 0) || (a_EnchantmentName == "0")) { return id; } // It wasn't a number, do a lookup: for (size_t i = 0; i < ARRAYCOUNT(EnchantmentNames); i++) { if (NoCaseCompare(EnchantmentNames[i].m_Name, a_EnchantmentName) == 0) { return EnchantmentNames[i].m_Value; } } // for i - EnchantmentNames[] return -1; } bool cEnchantments::operator ==(const cEnchantments & a_Other) const { return m_Enchantments == a_Other.m_Enchantments; } bool cEnchantments::operator !=(const cEnchantments & a_Other) const { return m_Enchantments != a_Other.m_Enchantments; } void cEnchantments::AddItemEnchantmentWeights(cWeightedEnchantments & a_Enchantments, short a_ItemType, int a_EnchantmentLevel) { if (ItemCategory::IsSword(a_ItemType)) { // Sharpness if ((a_EnchantmentLevel >= 34) && (a_EnchantmentLevel <= 54)) { AddEnchantmentWeightToVector(a_Enchantments, 10, enchSharpness, 4); } else if ((a_EnchantmentLevel >= 23) && (a_EnchantmentLevel <= 43)) { AddEnchantmentWeightToVector(a_Enchantments, 10, enchSharpness, 3); } else if ((a_EnchantmentLevel >= 12) && (a_EnchantmentLevel <= 32)) { AddEnchantmentWeightToVector(a_Enchantments, 10, enchSharpness, 2); } else if ((a_EnchantmentLevel >= 1) && (a_EnchantmentLevel <= 21)) { AddEnchantmentWeightToVector(a_Enchantments, 10, enchSharpness, 1); } // Smite if ((a_EnchantmentLevel >= 29) && (a_EnchantmentLevel <= 49)) { AddEnchantmentWeightToVector(a_Enchantments, 5, enchSmite, 4); } else if ((a_EnchantmentLevel >= 21) && (a_EnchantmentLevel <= 41)) { AddEnchantmentWeightToVector(a_Enchantments, 5, enchSmite, 3); } else if ((a_EnchantmentLevel >= 13) && (a_EnchantmentLevel <= 33)) { AddEnchantmentWeightToVector(a_Enchantments, 5, enchSmite, 2); } else if ((a_EnchantmentLevel >= 5) && (a_EnchantmentLevel <= 25)) { AddEnchantmentWeightToVector(a_Enchantments, 5, enchSmite, 1); } // Bane of Arthropods if ((a_EnchantmentLevel >= 29) && (a_EnchantmentLevel <= 49)) { AddEnchantmentWeightToVector(a_Enchantments, 5, enchBaneOfArthropods, 4); } else if ((a_EnchantmentLevel >= 21) && (a_EnchantmentLevel <= 41)) { AddEnchantmentWeightToVector(a_Enchantments, 5, enchBaneOfArthropods, 3); } else if ((a_EnchantmentLevel >= 13) && (a_EnchantmentLevel <= 33)) { AddEnchantmentWeightToVector(a_Enchantments, 5, enchBaneOfArthropods, 2); } else if ((a_EnchantmentLevel >= 5) && (a_EnchantmentLevel <= 25)) { AddEnchantmentWeightToVector(a_Enchantments, 5, enchBaneOfArthropods, 1); } // Knockback if ((a_EnchantmentLevel >= 25) && (a_EnchantmentLevel <= 75)) { AddEnchantmentWeightToVector(a_Enchantments, 5, enchKnockback, 2); } else if ((a_EnchantmentLevel >= 5) && (a_EnchantmentLevel <= 55)) { AddEnchantmentWeightToVector(a_Enchantments, 5, enchKnockback, 1); } // Fire Aspect if ((a_EnchantmentLevel >= 30) && (a_EnchantmentLevel <= 80)) { AddEnchantmentWeightToVector(a_Enchantments, 2, enchFireAspect, 2); } else if ((a_EnchantmentLevel >= 10) && (a_EnchantmentLevel <= 60)) { AddEnchantmentWeightToVector(a_Enchantments, 2, enchFireAspect, 1); } // Looting if ((a_EnchantmentLevel >= 33) && (a_EnchantmentLevel <= 83)) { AddEnchantmentWeightToVector(a_Enchantments, 2, enchLooting, 3); } else if ((a_EnchantmentLevel >= 24) && (a_EnchantmentLevel <= 74)) { AddEnchantmentWeightToVector(a_Enchantments, 2, enchLooting, 2); } else if ((a_EnchantmentLevel >= 15) && (a_EnchantmentLevel <= 65)) { AddEnchantmentWeightToVector(a_Enchantments, 2, enchLooting, 1); } } else if (ItemCategory::IsTool(a_ItemType)) { // Efficiency if ((a_EnchantmentLevel >= 31) && (a_EnchantmentLevel <= 81)) { AddEnchantmentWeightToVector(a_Enchantments, 10, enchEfficiency, 4); } else if ((a_EnchantmentLevel >= 21) && (a_EnchantmentLevel <= 71)) { AddEnchantmentWeightToVector(a_Enchantments, 10, enchEfficiency, 3); } else if ((a_EnchantmentLevel >= 11) && (a_EnchantmentLevel <= 61)) { AddEnchantmentWeightToVector(a_Enchantments, 10, enchEfficiency, 2); } else if ((a_EnchantmentLevel >= 1) && (a_EnchantmentLevel <= 51)) { AddEnchantmentWeightToVector(a_Enchantments, 10, enchEfficiency, 1); } // Silk Touch if ((a_EnchantmentLevel >= 15) && (a_EnchantmentLevel <= 65)) { AddEnchantmentWeightToVector(a_Enchantments, 1, enchSilkTouch, 1); } // Fortune if ((a_EnchantmentLevel >= 33) && (a_EnchantmentLevel <= 83)) { AddEnchantmentWeightToVector(a_Enchantments, 2, enchFortune, 3); } else if ((a_EnchantmentLevel >= 24) && (a_EnchantmentLevel <= 74)) { AddEnchantmentWeightToVector(a_Enchantments, 2, enchFortune, 2); } else if ((a_EnchantmentLevel >= 15) && (a_EnchantmentLevel <= 65)) { AddEnchantmentWeightToVector(a_Enchantments, 2, enchFortune, 1); } } else if (ItemCategory::IsArmor(a_ItemType)) { // Protection if ((a_EnchantmentLevel >= 34) && (a_EnchantmentLevel <= 54)) { AddEnchantmentWeightToVector(a_Enchantments, 10, enchProtection, 4); } else if ((a_EnchantmentLevel >= 23) && (a_EnchantmentLevel <= 43)) { AddEnchantmentWeightToVector(a_Enchantments, 10, enchProtection, 3); } else if ((a_EnchantmentLevel >= 12) && (a_EnchantmentLevel <= 32)) { AddEnchantmentWeightToVector(a_Enchantments, 10, enchProtection, 2); } else if ((a_EnchantmentLevel >= 1) && (a_EnchantmentLevel <= 21)) { AddEnchantmentWeightToVector(a_Enchantments, 10, enchProtection, 1); } // Fire Protection if ((a_EnchantmentLevel >= 34) && (a_EnchantmentLevel <= 46)) { AddEnchantmentWeightToVector(a_Enchantments, 5, enchFireProtection, 4); } else if ((a_EnchantmentLevel >= 26) && (a_EnchantmentLevel <= 38)) { AddEnchantmentWeightToVector(a_Enchantments, 5, enchFireProtection, 3); } else if ((a_EnchantmentLevel >= 18) && (a_EnchantmentLevel <= 30)) { AddEnchantmentWeightToVector(a_Enchantments, 5, enchFireProtection, 2); } else if ((a_EnchantmentLevel >= 10) && (a_EnchantmentLevel <= 22)) { AddEnchantmentWeightToVector(a_Enchantments, 5, enchFireProtection, 1); } // Blast Protection if ((a_EnchantmentLevel >= 29) && (a_EnchantmentLevel <= 41)) { AddEnchantmentWeightToVector(a_Enchantments, 2, enchBlastProtection, 4); } else if ((a_EnchantmentLevel >= 21) && (a_EnchantmentLevel <= 33)) { AddEnchantmentWeightToVector(a_Enchantments, 2, enchBlastProtection, 3); } else if ((a_EnchantmentLevel >= 13) && (a_EnchantmentLevel <= 25)) { AddEnchantmentWeightToVector(a_Enchantments, 2, enchBlastProtection, 2); } else if ((a_EnchantmentLevel >= 5) && (a_EnchantmentLevel <= 17)) { AddEnchantmentWeightToVector(a_Enchantments, 2, enchBlastProtection, 1); } // Projectile Protection if ((a_EnchantmentLevel >= 21) && (a_EnchantmentLevel <= 36)) { AddEnchantmentWeightToVector(a_Enchantments, 5, enchProjectileProtection, 4); } else if ((a_EnchantmentLevel >= 15) && (a_EnchantmentLevel <= 30)) { AddEnchantmentWeightToVector(a_Enchantments, 5, enchProjectileProtection, 3); } else if ((a_EnchantmentLevel >= 9) && (a_EnchantmentLevel <= 24)) { AddEnchantmentWeightToVector(a_Enchantments, 5, enchProjectileProtection, 2); } else if ((a_EnchantmentLevel >= 3) && (a_EnchantmentLevel <= 18)) { AddEnchantmentWeightToVector(a_Enchantments, 5, enchProjectileProtection, 1); } // Thorns if ((a_EnchantmentLevel >= 50) && (a_EnchantmentLevel <= 100)) { AddEnchantmentWeightToVector(a_Enchantments, 1, enchThorns, 3); } else if ((a_EnchantmentLevel >= 30) && (a_EnchantmentLevel <= 80)) { AddEnchantmentWeightToVector(a_Enchantments, 1, enchThorns, 2); } else if ((a_EnchantmentLevel >= 10) && (a_EnchantmentLevel <= 60)) { AddEnchantmentWeightToVector(a_Enchantments, 1, enchThorns, 1); } if (ItemCategory::IsHelmet(a_ItemType)) { // Respiration if ((a_EnchantmentLevel >= 30) && (a_EnchantmentLevel <= 60)) { AddEnchantmentWeightToVector(a_Enchantments, 2, enchRespiration, 3); } else if ((a_EnchantmentLevel >= 20) && (a_EnchantmentLevel <= 50)) { AddEnchantmentWeightToVector(a_Enchantments, 2, enchRespiration, 2); } else if ((a_EnchantmentLevel >= 10) && (a_EnchantmentLevel <= 40)) { AddEnchantmentWeightToVector(a_Enchantments, 2, enchRespiration, 1); } // Aqua Affinity if ((a_EnchantmentLevel >= 1) && (a_EnchantmentLevel <= 41)) { AddEnchantmentWeightToVector(a_Enchantments, 2, enchAquaAffinity, 1); } } else if (ItemCategory::IsBoots(a_ItemType)) { // Feather Fall if ((a_EnchantmentLevel >= 23) && (a_EnchantmentLevel <= 33)) { AddEnchantmentWeightToVector(a_Enchantments, 5, enchFeatherFalling, 4); } else if ((a_EnchantmentLevel >= 17) && (a_EnchantmentLevel <= 27)) { AddEnchantmentWeightToVector(a_Enchantments, 5, enchFeatherFalling, 3); } else if ((a_EnchantmentLevel >= 11) && (a_EnchantmentLevel <= 21)) { AddEnchantmentWeightToVector(a_Enchantments, 5, enchFeatherFalling, 2); } else if ((a_EnchantmentLevel >= 5) && (a_EnchantmentLevel <= 15)) { AddEnchantmentWeightToVector(a_Enchantments, 5, enchFeatherFalling, 1); } // Depth Strider if ((a_EnchantmentLevel >= 30) && (a_EnchantmentLevel <= 45)) { AddEnchantmentWeightToVector(a_Enchantments, 2, enchDepthStrider, 3); } else if ((a_EnchantmentLevel >= 20) && (a_EnchantmentLevel <= 35)) { AddEnchantmentWeightToVector(a_Enchantments, 2, enchDepthStrider, 2); } else if ((a_EnchantmentLevel >= 10) && (a_EnchantmentLevel <= 25)) { AddEnchantmentWeightToVector(a_Enchantments, 2, enchDepthStrider, 1); } } } else if (a_ItemType == E_ITEM_BOW) { // Power if ((a_EnchantmentLevel >= 31) && (a_EnchantmentLevel <= 46)) { AddEnchantmentWeightToVector(a_Enchantments, 10, enchPower, 4); } else if ((a_EnchantmentLevel >= 21) && (a_EnchantmentLevel <= 36)) { AddEnchantmentWeightToVector(a_Enchantments, 10, enchPower, 3); } else if ((a_EnchantmentLevel >= 11) && (a_EnchantmentLevel <= 26)) { AddEnchantmentWeightToVector(a_Enchantments, 10, enchPower, 2); } else if ((a_EnchantmentLevel >= 1) && (a_EnchantmentLevel <= 16)) { AddEnchantmentWeightToVector(a_Enchantments, 10, enchPower, 1); } // Punch if ((a_EnchantmentLevel >= 32) && (a_EnchantmentLevel <= 57)) { AddEnchantmentWeightToVector(a_Enchantments, 2, enchPunch, 2); } else if ((a_EnchantmentLevel >= 12) && (a_EnchantmentLevel <= 37)) { AddEnchantmentWeightToVector(a_Enchantments, 2, enchPunch, 1); } // Flame and Infinity if ((a_EnchantmentLevel >= 20) && (a_EnchantmentLevel <= 50)) { AddEnchantmentWeightToVector(a_Enchantments, 2, enchFlame, 1); AddEnchantmentWeightToVector(a_Enchantments, 1, enchInfinity, 1); } } else if (a_ItemType == E_ITEM_FISHING_ROD) { // Luck of the Sea and Lure if ((a_EnchantmentLevel >= 33) && (a_EnchantmentLevel <= 83)) { AddEnchantmentWeightToVector(a_Enchantments, 1, enchLuckOfTheSea, 3); AddEnchantmentWeightToVector(a_Enchantments, 1, enchLure, 3); } else if ((a_EnchantmentLevel >= 24) && (a_EnchantmentLevel <= 74)) { AddEnchantmentWeightToVector(a_Enchantments, 1, enchLuckOfTheSea, 2); AddEnchantmentWeightToVector(a_Enchantments, 1, enchLure, 2); } else if ((a_EnchantmentLevel >= 15) && (a_EnchantmentLevel <= 65)) { AddEnchantmentWeightToVector(a_Enchantments, 1, enchLuckOfTheSea, 1); AddEnchantmentWeightToVector(a_Enchantments, 1, enchLure, 1); } } else if (a_ItemType == E_ITEM_BOOK) { // All Enchantments // Sharpness if ((a_EnchantmentLevel >= 34) && (a_EnchantmentLevel <= 54)) { AddEnchantmentWeightToVector(a_Enchantments, 10, enchSharpness, 4); } else if ((a_EnchantmentLevel >= 23) && (a_EnchantmentLevel <= 43)) { AddEnchantmentWeightToVector(a_Enchantments, 10, enchSharpness, 3); } else if ((a_EnchantmentLevel >= 12) && (a_EnchantmentLevel <= 32)) { AddEnchantmentWeightToVector(a_Enchantments, 10, enchSharpness, 2); } else if ((a_EnchantmentLevel >= 1) && (a_EnchantmentLevel <= 21)) { AddEnchantmentWeightToVector(a_Enchantments, 10, enchSharpness, 1); } // Smite if ((a_EnchantmentLevel >= 29) && (a_EnchantmentLevel <= 49)) { AddEnchantmentWeightToVector(a_Enchantments, 5, enchSmite, 4); } else if ((a_EnchantmentLevel >= 21) && (a_EnchantmentLevel <= 41)) { AddEnchantmentWeightToVector(a_Enchantments, 5, enchSmite, 3); } else if ((a_EnchantmentLevel >= 13) && (a_EnchantmentLevel <= 33)) { AddEnchantmentWeightToVector(a_Enchantments, 5, enchSmite, 2); } else if ((a_EnchantmentLevel >= 5) && (a_EnchantmentLevel <= 25)) { AddEnchantmentWeightToVector(a_Enchantments, 5, enchSmite, 1); } // Bane of Arthropods if ((a_EnchantmentLevel >= 29) && (a_EnchantmentLevel <= 49)) { AddEnchantmentWeightToVector(a_Enchantments, 5, enchBaneOfArthropods, 4); } else if ((a_EnchantmentLevel >= 21) && (a_EnchantmentLevel <= 41)) { AddEnchantmentWeightToVector(a_Enchantments, 5, enchBaneOfArthropods, 3); } else if ((a_EnchantmentLevel >= 13) && (a_EnchantmentLevel <= 33)) { AddEnchantmentWeightToVector(a_Enchantments, 5, enchBaneOfArthropods, 2); } else if ((a_EnchantmentLevel >= 5) && (a_EnchantmentLevel <= 25)) { AddEnchantmentWeightToVector(a_Enchantments, 5, enchBaneOfArthropods, 1); } // Knockback if ((a_EnchantmentLevel >= 25) && (a_EnchantmentLevel <= 75)) { AddEnchantmentWeightToVector(a_Enchantments, 5, enchKnockback, 2); } else if ((a_EnchantmentLevel >= 5) && (a_EnchantmentLevel <= 55)) { AddEnchantmentWeightToVector(a_Enchantments, 5, enchKnockback, 1); } // Fire Aspect if ((a_EnchantmentLevel >= 30) && (a_EnchantmentLevel <= 80)) { AddEnchantmentWeightToVector(a_Enchantments, 2, enchFireAspect, 2); } else if ((a_EnchantmentLevel >= 10) && (a_EnchantmentLevel <= 60)) { AddEnchantmentWeightToVector(a_Enchantments, 2, enchFireAspect, 1); } // Looting if ((a_EnchantmentLevel >= 33) && (a_EnchantmentLevel <= 83)) { AddEnchantmentWeightToVector(a_Enchantments, 2, enchLooting, 3); } else if ((a_EnchantmentLevel >= 24) && (a_EnchantmentLevel <= 74)) { AddEnchantmentWeightToVector(a_Enchantments, 2, enchLooting, 2); } else if ((a_EnchantmentLevel >= 15) && (a_EnchantmentLevel <= 65)) { AddEnchantmentWeightToVector(a_Enchantments, 2, enchLooting, 1); } // Efficiency if ((a_EnchantmentLevel >= 31) && (a_EnchantmentLevel <= 81)) { AddEnchantmentWeightToVector(a_Enchantments, 10, enchEfficiency, 4); } else if ((a_EnchantmentLevel >= 21) && (a_EnchantmentLevel <= 71)) { AddEnchantmentWeightToVector(a_Enchantments, 10, enchEfficiency, 3); } else if ((a_EnchantmentLevel >= 11) && (a_EnchantmentLevel <= 61)) { AddEnchantmentWeightToVector(a_Enchantments, 10, enchEfficiency, 2); } else if ((a_EnchantmentLevel >= 1) && (a_EnchantmentLevel <= 51)) { AddEnchantmentWeightToVector(a_Enchantments, 10, enchEfficiency, 1); } // Silk Touch if ((a_EnchantmentLevel >= 15) && (a_EnchantmentLevel <= 65)) { AddEnchantmentWeightToVector(a_Enchantments, 1, enchSilkTouch, 1); } // Fortune if ((a_EnchantmentLevel >= 33) && (a_EnchantmentLevel <= 83)) { AddEnchantmentWeightToVector(a_Enchantments, 2, enchFortune, 3); } else if ((a_EnchantmentLevel >= 24) && (a_EnchantmentLevel <= 74)) { AddEnchantmentWeightToVector(a_Enchantments, 2, enchFortune, 2); } else if ((a_EnchantmentLevel >= 15) && (a_EnchantmentLevel <= 65)) { AddEnchantmentWeightToVector(a_Enchantments, 2, enchFortune, 1); } // Protection if ((a_EnchantmentLevel >= 34) && (a_EnchantmentLevel <= 54)) { AddEnchantmentWeightToVector(a_Enchantments, 10, enchProtection, 4); } else if ((a_EnchantmentLevel >= 23) && (a_EnchantmentLevel <= 43)) { AddEnchantmentWeightToVector(a_Enchantments, 10, enchProtection, 3); } else if ((a_EnchantmentLevel >= 12) && (a_EnchantmentLevel <= 32)) { AddEnchantmentWeightToVector(a_Enchantments, 10, enchProtection, 2); } else if ((a_EnchantmentLevel >= 1) && (a_EnchantmentLevel <= 21)) { AddEnchantmentWeightToVector(a_Enchantments, 10, enchProtection, 1); } // Fire Protection if ((a_EnchantmentLevel >= 34) && (a_EnchantmentLevel <= 46)) { AddEnchantmentWeightToVector(a_Enchantments, 5, enchFireProtection, 4); } else if ((a_EnchantmentLevel >= 26) && (a_EnchantmentLevel <= 38)) { AddEnchantmentWeightToVector(a_Enchantments, 5, enchFireProtection, 3); } else if ((a_EnchantmentLevel >= 18) && (a_EnchantmentLevel <= 30)) { AddEnchantmentWeightToVector(a_Enchantments, 5, enchFireProtection, 2); } else if ((a_EnchantmentLevel >= 10) && (a_EnchantmentLevel <= 22)) { AddEnchantmentWeightToVector(a_Enchantments, 5, enchFireProtection, 1); } // Blast Protection if ((a_EnchantmentLevel >= 29) && (a_EnchantmentLevel <= 41)) { AddEnchantmentWeightToVector(a_Enchantments, 2, enchBlastProtection, 4); } else if ((a_EnchantmentLevel >= 21) && (a_EnchantmentLevel <= 33)) { AddEnchantmentWeightToVector(a_Enchantments, 2, enchBlastProtection, 3); } else if ((a_EnchantmentLevel >= 13) && (a_EnchantmentLevel <= 25)) { AddEnchantmentWeightToVector(a_Enchantments, 2, enchBlastProtection, 2); } else if ((a_EnchantmentLevel >= 5) && (a_EnchantmentLevel <= 17)) { AddEnchantmentWeightToVector(a_Enchantments, 2, enchBlastProtection, 1); } // Projectile Protection if ((a_EnchantmentLevel >= 21) && (a_EnchantmentLevel <= 36)) { AddEnchantmentWeightToVector(a_Enchantments, 5, enchProjectileProtection, 4); } else if ((a_EnchantmentLevel >= 15) && (a_EnchantmentLevel <= 30)) { AddEnchantmentWeightToVector(a_Enchantments, 5, enchProjectileProtection, 3); } else if ((a_EnchantmentLevel >= 9) && (a_EnchantmentLevel <= 24)) { AddEnchantmentWeightToVector(a_Enchantments, 5, enchProjectileProtection, 2); } else if ((a_EnchantmentLevel >= 3) && (a_EnchantmentLevel <= 18)) { AddEnchantmentWeightToVector(a_Enchantments, 5, enchProjectileProtection, 1); } // Thorns if ((a_EnchantmentLevel >= 50) && (a_EnchantmentLevel <= 100)) { AddEnchantmentWeightToVector(a_Enchantments, 1, enchThorns, 3); } else if ((a_EnchantmentLevel >= 30) && (a_EnchantmentLevel <= 80)) { AddEnchantmentWeightToVector(a_Enchantments, 1, enchThorns, 2); } else if ((a_EnchantmentLevel >= 10) && (a_EnchantmentLevel <= 60)) { AddEnchantmentWeightToVector(a_Enchantments, 1, enchThorns, 1); } // Respiration if ((a_EnchantmentLevel >= 30) && (a_EnchantmentLevel <= 60)) { AddEnchantmentWeightToVector(a_Enchantments, 2, enchRespiration, 3); } else if ((a_EnchantmentLevel >= 20) && (a_EnchantmentLevel <= 50)) { AddEnchantmentWeightToVector(a_Enchantments, 2, enchRespiration, 2); } else if ((a_EnchantmentLevel >= 10) && (a_EnchantmentLevel <= 40)) { AddEnchantmentWeightToVector(a_Enchantments, 2, enchRespiration, 1); } // Aqua Affinity if ((a_EnchantmentLevel >= 1) && (a_EnchantmentLevel <= 41)) { AddEnchantmentWeightToVector(a_Enchantments, 2, enchAquaAffinity, 1); } // Feather Fall if ((a_EnchantmentLevel >= 23) && (a_EnchantmentLevel <= 33)) { AddEnchantmentWeightToVector(a_Enchantments, 5, enchFeatherFalling, 4); } else if ((a_EnchantmentLevel >= 17) && (a_EnchantmentLevel <= 27)) { AddEnchantmentWeightToVector(a_Enchantments, 5, enchFeatherFalling, 3); } else if ((a_EnchantmentLevel >= 11) && (a_EnchantmentLevel <= 21)) { AddEnchantmentWeightToVector(a_Enchantments, 5, enchFeatherFalling, 2); } else if ((a_EnchantmentLevel >= 5) && (a_EnchantmentLevel <= 15)) { AddEnchantmentWeightToVector(a_Enchantments, 5, enchFeatherFalling, 1); } // Power if ((a_EnchantmentLevel >= 31) && (a_EnchantmentLevel <= 46)) { AddEnchantmentWeightToVector(a_Enchantments, 10, enchPower, 4); } else if ((a_EnchantmentLevel >= 21) && (a_EnchantmentLevel <= 36)) { AddEnchantmentWeightToVector(a_Enchantments, 10, enchPower, 3); } else if ((a_EnchantmentLevel >= 11) && (a_EnchantmentLevel <= 26)) { AddEnchantmentWeightToVector(a_Enchantments, 10, enchPower, 2); } else if ((a_EnchantmentLevel >= 1) && (a_EnchantmentLevel <= 16)) { AddEnchantmentWeightToVector(a_Enchantments, 10, enchPower, 1); } // Punch if ((a_EnchantmentLevel >= 32) && (a_EnchantmentLevel <= 57)) { AddEnchantmentWeightToVector(a_Enchantments, 2, enchPunch, 2); } else if ((a_EnchantmentLevel >= 12) && (a_EnchantmentLevel <= 37)) { AddEnchantmentWeightToVector(a_Enchantments, 2, enchPunch, 1); } // Flame and Infinity if ((a_EnchantmentLevel >= 20) && (a_EnchantmentLevel <= 50)) { AddEnchantmentWeightToVector(a_Enchantments, 2, enchFlame, 1); AddEnchantmentWeightToVector(a_Enchantments, 1, enchInfinity, 1); } // Luck of the Sea and Lure if ((a_EnchantmentLevel >= 33) && (a_EnchantmentLevel <= 83)) { AddEnchantmentWeightToVector(a_Enchantments, 1, enchLuckOfTheSea, 3); AddEnchantmentWeightToVector(a_Enchantments, 1, enchLure, 3); } else if ((a_EnchantmentLevel >= 24) && (a_EnchantmentLevel <= 74)) { AddEnchantmentWeightToVector(a_Enchantments, 1, enchLuckOfTheSea, 2); AddEnchantmentWeightToVector(a_Enchantments, 1, enchLure, 2); } else if ((a_EnchantmentLevel >= 15) && (a_EnchantmentLevel <= 65)) { AddEnchantmentWeightToVector(a_Enchantments, 1, enchLuckOfTheSea, 1); AddEnchantmentWeightToVector(a_Enchantments, 1, enchLure, 1); } } // Unbreaking if ((a_EnchantmentLevel >= 21) && (a_EnchantmentLevel <= 71)) { AddEnchantmentWeightToVector(a_Enchantments, 5, enchUnbreaking, 3); } else if ((a_EnchantmentLevel >= 13) && (a_EnchantmentLevel <= 63)) { AddEnchantmentWeightToVector(a_Enchantments, 5, enchUnbreaking, 2); } else if ((a_EnchantmentLevel >= 5) && (a_EnchantmentLevel <= 55)) { AddEnchantmentWeightToVector(a_Enchantments, 5, enchUnbreaking, 1); } } void cEnchantments::AddEnchantmentWeightToVector(cWeightedEnchantments & a_Enchantments, int a_Weight, int a_EnchantmentID, unsigned int a_EnchantmentLevel) { cWeightedEnchantment weightedenchantment; weightedenchantment.m_Weight = a_Weight; cEnchantments enchantment; enchantment.SetLevel(a_EnchantmentID, a_EnchantmentLevel); weightedenchantment.m_Enchantments = enchantment; a_Enchantments.push_back(weightedenchantment); } void cEnchantments::RemoveEnchantmentWeightFromVector(cWeightedEnchantments & a_Enchantments, int a_EnchantmentID) { for (cWeightedEnchantments::iterator it = a_Enchantments.begin(); it != a_Enchantments.end(); ++it) { if ((*it).m_Enchantments.GetLevel(a_EnchantmentID) > 0) { a_Enchantments.erase(it); break; } } } void cEnchantments::RemoveEnchantmentWeightFromVector(cWeightedEnchantments & a_Enchantments, const cEnchantments & a_Enchantment) { for (cWeightedEnchantments::iterator it = a_Enchantments.begin(); it != a_Enchantments.end(); ++it) { if ((*it).m_Enchantments == a_Enchantment) { a_Enchantments.erase(it); break; } } } void cEnchantments::CheckEnchantmentConflictsFromVector( cWeightedEnchantments & a_Enchantments, const cEnchantments & a_FirstEnchantment ) { if (a_FirstEnchantment.GetLevel(cEnchantments::enchProtection) > 0) { RemoveEnchantmentWeightFromVector(a_Enchantments, cEnchantments::enchFireProtection); RemoveEnchantmentWeightFromVector(a_Enchantments, cEnchantments::enchBlastProtection); RemoveEnchantmentWeightFromVector(a_Enchantments, cEnchantments::enchProjectileProtection); } else if (a_FirstEnchantment.GetLevel(cEnchantments::enchFireProtection) > 0) { RemoveEnchantmentWeightFromVector(a_Enchantments, cEnchantments::enchProtection); RemoveEnchantmentWeightFromVector(a_Enchantments, cEnchantments::enchBlastProtection); RemoveEnchantmentWeightFromVector(a_Enchantments, cEnchantments::enchProjectileProtection); } else if (a_FirstEnchantment.GetLevel(cEnchantments::enchBlastProtection) > 0) { RemoveEnchantmentWeightFromVector(a_Enchantments, cEnchantments::enchProtection); RemoveEnchantmentWeightFromVector(a_Enchantments, cEnchantments::enchFireProtection); RemoveEnchantmentWeightFromVector(a_Enchantments, cEnchantments::enchProjectileProtection); } else if (a_FirstEnchantment.GetLevel(cEnchantments::enchProjectileProtection) > 0) { RemoveEnchantmentWeightFromVector(a_Enchantments, cEnchantments::enchProtection); RemoveEnchantmentWeightFromVector(a_Enchantments, cEnchantments::enchFireProtection); RemoveEnchantmentWeightFromVector(a_Enchantments, cEnchantments::enchBlastProtection); } else if (a_FirstEnchantment.GetLevel(cEnchantments::enchSharpness) > 0) { RemoveEnchantmentWeightFromVector(a_Enchantments, cEnchantments::enchSmite); RemoveEnchantmentWeightFromVector(a_Enchantments, cEnchantments::enchBaneOfArthropods); } else if (a_FirstEnchantment.GetLevel(cEnchantments::enchSmite) > 0) { RemoveEnchantmentWeightFromVector(a_Enchantments, cEnchantments::enchSharpness); RemoveEnchantmentWeightFromVector(a_Enchantments, cEnchantments::enchBaneOfArthropods); } else if (a_FirstEnchantment.GetLevel(cEnchantments::enchBaneOfArthropods) > 0) { RemoveEnchantmentWeightFromVector(a_Enchantments, cEnchantments::enchSharpness); RemoveEnchantmentWeightFromVector(a_Enchantments, cEnchantments::enchSmite); } else if (a_FirstEnchantment.GetLevel(cEnchantments::enchSilkTouch) > 0) { RemoveEnchantmentWeightFromVector(a_Enchantments, cEnchantments::enchFortune); } else if (a_FirstEnchantment.GetLevel(cEnchantments::enchFortune) > 0) { RemoveEnchantmentWeightFromVector(a_Enchantments, cEnchantments::enchSilkTouch); } } cEnchantments cEnchantments::GetRandomEnchantmentFromVector(cWeightedEnchantments & a_Enchantments) { int AllWeights = 0; for (cWeightedEnchantments::iterator it = a_Enchantments.begin(); it != a_Enchantments.end(); ++it) { AllWeights += (*it).m_Weight; } int RandomNumber = GetRandomProvider().RandInt(AllWeights - 1); for (cWeightedEnchantments::iterator it = a_Enchantments.begin(); it != a_Enchantments.end(); ++it) { RandomNumber -= (*it).m_Weight; if (RandomNumber < 0) { return (*it).m_Enchantments; } } return cEnchantments(); } cEnchantments cEnchantments::SelectEnchantmentFromVector(const cWeightedEnchantments & a_Enchantments, int a_Seed) { // Sum up all the enchantments' weights: int AllWeights = 0; for (const auto & Enchantment : a_Enchantments) { AllWeights += Enchantment.m_Weight; } // If there's no weight for any of the enchantments, return an empty enchantment if (AllWeights <= 0) { return cEnchantments(); } // Pick a random enchantment: cNoise Noise(a_Seed); int RandomNumber = Noise.IntNoise1DInt(AllWeights) / 7 % AllWeights; for (const auto & Enchantment : a_Enchantments) { RandomNumber -= Enchantment.m_Weight; if (RandomNumber <= 0) { return Enchantment.m_Enchantments; } } // No enchantment picked, return an empty one (we probably shouldn't ever get here): return cEnchantments(); }