This describes how trading between players is implemented.
Please note, that all other (item dropping, equipping, adding to inventory) is taken as working and explained, and is NOT being explained here again!
This solution uses principles explained in previous parts of documentation
We want two players to be able to exchange items (trade). The requirements are following:
|Revert the trade||Give items back to both players|
|Close the trade||Revert trade for both players|
As another step of analysis, let's have a look at messages, that will have to be sent between server and client to accomplish this task:
|TradeRequest||Informs server that player A want to initiate trade with player B|
|TradeAccept||Informs server that player X accepted trade|
|TradeDecline||Informs server that player X declined trade|
|TradeAddItem / TradeRemoveItem||Informs server that player X wants to add / remove item to the offer window|
Server to client messages:
|TradeRequest||Informs player A that player B wants to trade him|
|TradeOpen||Opens trade window on client side|
|TradeClose (sucessfull or unsuccessfull)||Closes trade window on client side and displays console message|
|TradeAccept||Informs player A that player B has accepted trade|
|TradeAddItem / TradeRemoveItem||Client side removes / adds item to the html offer window|
Using the messages above (mostly like 3 or more messages can fit into one packet class),
it is possible to implement entire trading system between players.
Understanding, that once trade is successfully finished, items are removed / added to player inventories accordingly, if at all possible.
In order to manage all trades, there must be a class that takes a care about it.
However, one can say, that trade instance can be inside relevant player instance, which would be possible solution, however, not so versatile as it is needed, because if we would like to cancel all ongoing trades (for example when the server shuts down), the task and iteration would be quite ugly.
The trade orchestrator (trade manager) can do following things:
This is actually very simple.
There is HTML window, representing the trade, and it is hidden, or shown, or it's elements are changed according to the packet received.
Also, appropriate console messages are shown about trade progress
On client side, an instance of InventoryHTML is created, allowing to parse pormal inventory event packet.
This allows sending such a packet, but inside trading packet, with additional info.
Like that, quite simply, items can be displayed inside the trade windows.
This is done on the server side, and once it it done, updater takes all created packets and send them to clients.
When item is added to trade window, it is physically removed from the inventory, and added to the trade instance.
This is processs of cancelling existing trade, where the items must be returned back to their owners
In this case, we can run to problems:
|The player is no longer in game||We MUST make sure it never happens *|
|The player has no inventory space||Item is dropped under him|
|The player is in different map||We MUST make sure it never happens|
As stated above, we must make sure that player will never be able to switch maps, while trading.
Reverting such a trade, would still be possible, however, we set it as rule, because then it would all be so chaotic in game...
While player is trading, we forbid him to do following (and if he does it, it reverts ongoing trade):
We can not forbid this from happening, as we would break the game rules.
When player dies, and he is still trading, then the trade is closed automatically