1
0

Enchanting table shows detail on hover. Enchanting is deterministic. (#4937)

* Use lapis for enchanting, subtract correct number of levels, ClientHandle now selects from pregenerated list.

Co-authored-by: Tiger Wang <ziwei.tiger@outlook.com>
This commit is contained in:
KingCol13
2020-10-02 00:33:32 +03:00
committed by GitHub
parent be841b4769
commit 8947147c25
13 changed files with 219 additions and 115 deletions

View File

@@ -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);
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);
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);
return;
}
else
// Pseudocode found at: https://minecraft.gamepedia.com/Enchanting_mechanics
const auto Bookshelves = std::min(GetBookshelvesCount(*a_Player.GetWorld()), 15U);
// 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: