summaryrefslogtreecommitdiffstats
path: root/src/UI/SlotArea.cpp
diff options
context:
space:
mode:
authorKingCol13 <48412633+KingCol13@users.noreply.github.com>2020-10-01 23:33:32 +0200
committerGitHub <noreply@github.com>2020-10-01 23:33:32 +0200
commit8947147c25e2640519897bfdc8807e97ee291d70 (patch)
tree63eca1e5bd8ad29ac9beba5a780d466c9bb13849 /src/UI/SlotArea.cpp
parentAdd SetBlockMeta warning in documentation (#4943) (diff)
downloadcuberite-8947147c25e2640519897bfdc8807e97ee291d70.tar
cuberite-8947147c25e2640519897bfdc8807e97ee291d70.tar.gz
cuberite-8947147c25e2640519897bfdc8807e97ee291d70.tar.bz2
cuberite-8947147c25e2640519897bfdc8807e97ee291d70.tar.lz
cuberite-8947147c25e2640519897bfdc8807e97ee291d70.tar.xz
cuberite-8947147c25e2640519897bfdc8807e97ee291d70.tar.zst
cuberite-8947147c25e2640519897bfdc8807e97ee291d70.zip
Diffstat (limited to 'src/UI/SlotArea.cpp')
-rw-r--r--src/UI/SlotArea.cpp79
1 files changed, 62 insertions, 17 deletions
diff --git a/src/UI/SlotArea.cpp b/src/UI/SlotArea.cpp
index 1450294a4..bb597b2c9 100644
--- a/src/UI/SlotArea.cpp
+++ b/src/UI/SlotArea.cpp
@@ -1678,25 +1678,59 @@ void cSlotAreaEnchanting::UpdateResult(cPlayer & a_Player)
{
cItem Item = *GetSlot(0, a_Player);
- if (cItem::IsEnchantable(Item.m_ItemType) && Item.m_Enchantments.IsEmpty())
+ if (!cItem::IsEnchantable(Item.m_ItemType) || !Item.m_Enchantments.IsEmpty())
{
- int Bookshelves = std::min(GetBookshelvesCount(*a_Player.GetWorld()), 15);
+ return;
+ }
- auto & Random = GetRandomProvider();
- int Base = (Random.RandInt(1, 8) + (Bookshelves / 2) + Random.RandInt(0, Bookshelves));
- int TopSlot = std::max(Base / 3, 1);
- int MiddleSlot = (Base * 2) / 3 + 1;
- int BottomSlot = std::max(Base, Bookshelves * 2);
+ // Pseudocode found at: https://minecraft.gamepedia.com/Enchanting_mechanics
+ const auto Bookshelves = std::min(GetBookshelvesCount(*a_Player.GetWorld()), 15U);
- m_ParentWindow.SetProperty(0, static_cast<short>(TopSlot), a_Player);
- m_ParentWindow.SetProperty(1, static_cast<short>(MiddleSlot), a_Player);
- m_ParentWindow.SetProperty(2, static_cast<short>(BottomSlot), a_Player);
- }
- else
+ // A PRNG initialised using the player's enchantment seed.
+ auto Random = a_Player.GetEnchantmentRandomProvider();
+
+ // Calculate the levels for the offered enchantment options:
+ const auto Base = (Random.RandInt(1U, 8U) + (Bookshelves / 2) + Random.RandInt(0U, Bookshelves));
+ const std::array<unsigned int, 3> OptionLevels
{
- m_ParentWindow.SetProperty(0, 0, a_Player);
- m_ParentWindow.SetProperty(1, 0, a_Player);
- m_ParentWindow.SetProperty(2, 0, a_Player);
+ std::max(Base / 3, 1U),
+ (Base * 2) / 3 + 1,
+ std::max(Base, Bookshelves * 2)
+ };
+
+ // Properties set according to: https://wiki.vg/Protocol#Window_Property
+ // Fake a "seed" for the client to draw Standard Galactic Alphabet glyphs:
+ m_ParentWindow.SetProperty(3, Random.RandInt<short>(), a_Player);
+
+ // Calculate an enchanting possibility for each option (top, middle and bottom) and send details to window:
+ for (short i = 0; i != OptionLevels.size(); i++)
+ {
+ // A copy of the item.
+ cItem EnchantedItem = Item.CopyOne();
+
+ // Enchant based on the number of levels:
+ EnchantedItem.EnchantByXPLevels(OptionLevels[i], Random);
+
+ LOGD("Generated enchanted item %d with enchantments: %s", i, EnchantedItem.m_Enchantments.ToString());
+
+ // Send the level requirement for the enchantment option:
+ m_ParentWindow.SetProperty(i, static_cast<short>(OptionLevels[i]), a_Player);
+
+ // Get the first enchantment ID, which must exist:
+ ASSERT(EnchantedItem.m_Enchantments.begin() != EnchantedItem.m_Enchantments.end());
+ const short EnchantmentID = static_cast<short>(EnchantedItem.m_Enchantments.begin()->first);
+
+ // Send the enchantment ID of the first enchantment on our item:
+ m_ParentWindow.SetProperty(4 + i, EnchantmentID, a_Player);
+
+ const short EnchantmentLevel = static_cast<short>(EnchantedItem.m_Enchantments.GetLevel(EnchantmentID));
+ ASSERT(EnchantmentLevel > 0);
+
+ // Send the level for the first enchantment on our item:
+ m_ParentWindow.SetProperty(7 + i, EnchantmentLevel, a_Player);
+
+ // Store the item we've enchanted as an option to be retrieved later:
+ m_EnchantedItemOptions[i] = std::move(EnchantedItem);
}
}
@@ -1704,9 +1738,8 @@ void cSlotAreaEnchanting::UpdateResult(cPlayer & a_Player)
-int cSlotAreaEnchanting::GetBookshelvesCount(cWorld & a_World)
+unsigned cSlotAreaEnchanting::GetBookshelvesCount(cWorld & a_World)
{
- int Bookshelves = 0;
cBlockArea Area;
Area.Read(a_World, m_BlockPos - Vector3i(2, 0, 2), m_BlockPos + Vector3i(2, 1, 2));
@@ -1751,6 +1784,8 @@ int cSlotAreaEnchanting::GetBookshelvesCount(cWorld & a_World)
{ 1, 1, 0, 1, 1, 1 }, // Bookcase at {1, 1, 0}, air at {1, 1, 1}
};
+ unsigned Bookshelves = 0;
+
for (size_t i = 0; i < ARRAYCOUNT(CheckCoords); i++)
{
if (
@@ -1769,6 +1804,16 @@ int cSlotAreaEnchanting::GetBookshelvesCount(cWorld & a_World)
+cItem cSlotAreaEnchanting::SelectEnchantedOption(size_t a_EnchantOption)
+{
+ ASSERT(a_EnchantOption < m_EnchantedItemOptions.size());
+ return std::move(m_EnchantedItemOptions[a_EnchantOption]);
+}
+
+
+
+
+
////////////////////////////////////////////////////////////////////////////////
// cSlotAreaEnderChest: