Enchanting
#31
The IsEnchantable() function is used only in the older protocol versions that didn't support enchantments on all items; with current protocols any item could be enchanted, so you should use the normal approach:
When a player places an item in the enchantment slot, ask plugins using a hook to give you the list of enchantments available for this item. The plugins should modify a list of enchantments that the server can choose from for the item.
When the player chooses the enchantment cost, find the (default) enchantments that the server would give the item, then fire a plugin hook saying user is about to enchant something at a specified cost, letting the plugins to modify the final enchantments.

HOOK_GET_APPLICABLE_ENCHANTMENTS: Called when the player places an item in the enchantment table's slot
Receives arguments:
- the player
- the item
- array-table of cEnchantments, each containing a single allowed enchantment (represented as std::vector<cEnchantments> in the C++ code); the server initializes this to the default list of enchantments applicable for that item
Return values:
- continue hook execution (bool) - when true, no more hooks in the chain are called (if not given, false if assumed)
- array-table of cEnchantments, each containing a single allowed enchantment (if not given, the default list given in the parameter is assumed)
After the hook returns, the server stores the list of applicable enchantments in the cPlayer object, so that it can retrieve it later, and displays the XP costs, if applicable.

HOOK_ENCHANTING_ITEM: Called when the player chooses the XP cost in the enchantment table's UI
Receive arguments:
- the player
- the item
- the XP cost that the player has chosen
- single cEnchantments class containing all the enchantments that the item will receive, initialized by the server from the list of applicable enchantments; plugins may directly modify this object
Return values:
- continue hook execution (bool) - when true, no more hooks in the chain are called (if not given, false if assumed)
Reply
Thanks given by: daniel0916
#32
Thanks. You mean i should only add hooks and not the whole enchantment system?

And have you an answer to me question before?
"How can i make something for all players?"

Edit: Than i can use IsEnchantable() or? because when it is for older protocols where only enchantable items can be enchanted it should return me if it's normally enchantable or not?

My idea was that i add the whole enchanting system to MCServer. Then i will add hooks like your examples.
And when someone won't use enchanting, he can disable enchanting with the hooks.
I don't think the enchanting system need really many performance when the enchantment window is disabled with a hook.
Reply
Thanks given by:
#33
I meant, add the enchanting system, but have it think about how the hooks will be implemented later on, so that it's easy to add them (if you can't do it already - these will be a bit more difficult hooks than regular ones).

Why would you need to do something for all players? Enchanting is a single-player action, it shouldn't need any interaction with other players.

You won't need IsEnchantable() function at all. Read my description of the solution again. The server will provide default applicable enchantments (which means none if the server doesn't think the item should be enchanted), then it will choose enchantments based on that list. The point is, the server will, for each item type, have the list of applicable enchantments. This will in fact "work around" the IsEnchantable() function - items that don't have any applicable enchantments aren't enchantable. And vice-versa: items that are enchantable need a list of applicable enchantments.
Reply
Thanks given by:
#34
Okay, now i understand it.

The enchanting packet returns me the window id. Now i need the window from them.
My idea was to get from all players the window and then the id. Then i will check if the ids are the same.
Have you a idea how can i make it or maybe a better idea?
Reply
Thanks given by:
#35
The enchanting packet is sent by a client (cClientHandle); that client has an associated cPlayer object (m_Player, GetPlayer()), that is the player you are searching for.

You should drop a note in the GitHub issue tracker that you're working on this: https://github.com/mc-server/MCServer/issues/32
Reply
Thanks given by: daniel0916
#36
Code:
cItem enchantitem = *this->m_Client->GetPlayer()->GetWindow()->GetSlot(*this->m_Client->GetPlayer() , 0);

    //Enchant item with Sharpness 5
    enchantitem.m_Enchantments.SetLevel(cEnchantments::enchSharpness, 5);

    this->m_Client->GetPlayer()->GetWindow()->SetSlot(*this->m_Client->GetPlayer(), 0, enchantitem);

    this->m_Client->GetPlayer()->SendMessage(this->m_Client->GetPlayer()->GetWindow()->GetSlot(*this->m_Client->GetPlayer(), 0)->m_Enchantments.ToString());

My current code. But the item isn't enchanted. Have you a idea why?
And it returns "16=5:"

(01-22-2014, 08:05 AM)xoft Wrote: You should drop a note in the GitHub issue tracker that you're working on this: https://github.com/mc-server/MCServer/issues/32

I will make this. (made. It's only a little message)
Reply
Thanks given by:
#37
There's a question on how to implement the enchantment checking - specific items may only be enchanted by specific enchantments. I think we should add these functions:
class cEnchantment
{
  enum eEnchantmentType { enchProtection ... };  // <-- NAME the enchantment enum
  ...
  /** Returns true if the item type supports the specified enchantment type and level */
  static bool CanEnchantItemType(short a_ItemType, eEnchantmentType a_EnchantmentType, int a_Level);

  /** Returns true if the specified item can be enchanted with the specified enchantment 
  This includes checks for mutually exclusive enchantments, such as Sharpness and Smite */
  static bool CanEnchantItem(const cItem & a_Item, eEnchantmentType a_EnchantmentType, int a_Level);
} ;

I think the server should build a list of applicable enchantments based on the enchanting rules in the MC wiki, but if a plugin modifies this list and adds an incompatible enchantment, the server should NOT discard that enchantment, rather, it should handle it as if there was a version of minecraft that supports the enchantments together (just like there were versions that didn't support some combinations, such as Unbreaking on Shears).
Reply
Thanks given by: daniel0916
#38
Little question: How can i make a function which returns a enum with the enchantments?
I haven't so much knowing in c++.
Code:
enum cItem::GetEnchantments(short item)
{
    enum EnchantmentType { enchProtection };
    return EnchantmentType;
}
Don't work.
Reply
Thanks given by:
#39
Your code has two major problems:
1, you need to declare EnchantmentType before declaring the function - the function return value has to be known before the function is parsed.
2, your function would be able to return only one enchantment. What you really want is an array of enchantments.
Reply
Thanks given by:
#40
Thanks. How can i make a array of enchantments?
Reply
Thanks given by:




Users browsing this thread: 3 Guest(s)