00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "net/ea/tradehandler.h"
00023
00024 #include "net/ea/protocol.h"
00025
00026 #include "net/messagein.h"
00027 #include "net/messageout.h"
00028
00029 #include "inventory.h"
00030 #include "item.h"
00031 #include "localplayer.h"
00032 #include "player_relations.h"
00033
00034 #include "gui/confirm_dialog.h"
00035 #include "gui/trade.h"
00036
00037 #include "gui/widgets/chattab.h"
00038
00039 #include "utils/gettext.h"
00040
00041 std::string tradePartnerName;
00042
00046 namespace {
00047 struct RequestTradeListener : public gcn::ActionListener
00048 {
00049 void action(const gcn::ActionEvent &event)
00050 {
00051 player_node->tradeReply(event.getId() == "yes");
00052 }
00053 } listener;
00054 }
00055
00056 Net::TradeHandler *tradeHandler;
00057
00058 namespace EAthena {
00059
00060 TradeHandler::TradeHandler()
00061 {
00062 static const Uint16 _messages[] = {
00063 SMSG_TRADE_REQUEST,
00064 SMSG_TRADE_RESPONSE,
00065 SMSG_TRADE_ITEM_ADD,
00066 SMSG_TRADE_ITEM_ADD_RESPONSE,
00067 SMSG_TRADE_OK,
00068 SMSG_TRADE_CANCEL,
00069 SMSG_TRADE_COMPLETE,
00070 0
00071 };
00072 handledMessages = _messages;
00073 tradeHandler = this;
00074 }
00075
00076
00077 void TradeHandler::handleMessage(MessageIn &msg)
00078 {
00079 switch (msg.getId())
00080 {
00081 case SMSG_TRADE_REQUEST:
00082
00083
00084
00085
00086
00087
00088 tradePartnerName = msg.readString(24);
00089
00090 if (player_relations.hasPermission(tradePartnerName, PlayerRelation::TRADE))
00091 {
00092 if (!player_node->tradeRequestOk())
00093 {
00094 player_node->tradeReply(false);
00095 break;
00096 }
00097
00098 player_node->setTrading(true);
00099 ConfirmDialog *dlg;
00100 dlg = new ConfirmDialog(_("Request for trade"),
00101 tradePartnerName +
00102 _(" wants to trade with you, do you accept?"));
00103 dlg->addActionListener(&listener);
00104 }
00105 else
00106 {
00107 player_node->tradeReply(false);
00108 break;
00109 }
00110 break;
00111
00112 case SMSG_TRADE_RESPONSE:
00113 switch (msg.readInt8())
00114 {
00115 case 0:
00116 localChatTab->chatLog(_("Trading isn't possible. Trade partner is too far away."),
00117 BY_SERVER);
00118 break;
00119 case 1:
00120 localChatTab->chatLog(_("Trading isn't possible. Character doesn't exist."),
00121 BY_SERVER);
00122 break;
00123 case 2:
00124 localChatTab->chatLog(_("Trade cancelled due to an unknown reason."),
00125 BY_SERVER);
00126 break;
00127 case 3:
00128 tradeWindow->reset();
00129 tradeWindow->setCaption(
00130 _("Trade: You and ") + tradePartnerName);
00131 tradeWindow->setVisible(true);
00132 break;
00133 case 4:
00134 if (player_relations.hasPermission(tradePartnerName,
00135 PlayerRelation::SPEECH_LOG))
00136 localChatTab->chatLog(_("Trade with ") + tradePartnerName +
00137 _(" cancelled"), BY_SERVER);
00138
00139
00140 tradeWindow->setVisible(false);
00141 player_node->setTrading(false);
00142 break;
00143 default:
00144 localChatTab->chatLog(_("Unhandled trade cancel packet"),
00145 BY_SERVER);
00146 break;
00147 }
00148 break;
00149
00150 case SMSG_TRADE_ITEM_ADD:
00151 {
00152 int amount = msg.readInt32();
00153 int type = msg.readInt16();
00154 msg.readInt8();
00155 msg.readInt8();
00156 msg.readInt8();
00157 msg.skip(8);
00158
00159
00160 if (type == 0) {
00161 tradeWindow->setMoney(amount);
00162 } else {
00163 tradeWindow->addItem(type, false, amount, false);
00164 }
00165 }
00166 break;
00167
00168 case SMSG_TRADE_ITEM_ADD_RESPONSE:
00169
00170 {
00171 const int index = msg.readInt16() - INVENTORY_OFFSET;
00172 Item *item = player_node->getInventory()->getItem(index);
00173 if (!item)
00174 {
00175 tradeWindow->receivedOk(true);
00176 return;
00177 }
00178 int quantity = msg.readInt16();
00179
00180 switch (msg.readInt8())
00181 {
00182 case 0:
00183
00184 if (item->isEquipment() && item->isEquipped())
00185 {
00186 player_node->unequipItem(item);
00187 }
00188 tradeWindow->addItem(item->getId(), true, quantity,
00189 item->isEquipment());
00190 item->increaseQuantity(-quantity);
00191 break;
00192 case 1:
00193
00194 localChatTab->chatLog(_("Failed adding item. Trade partner is over weighted."),
00195 BY_SERVER);
00196 break;
00197 case 2:
00198
00199 localChatTab->chatLog(_("Failed adding item. Trade partner has no free slot."),
00200 BY_SERVER);
00201 break;
00202 default:
00203 localChatTab->chatLog(_("Failed adding item for unknown reason."),
00204 BY_SERVER);
00205 break;
00206 }
00207 }
00208 break;
00209
00210 case SMSG_TRADE_OK:
00211
00212 tradeWindow->receivedOk(msg.readInt8() == 0);
00213 break;
00214
00215 case SMSG_TRADE_CANCEL:
00216 localChatTab->chatLog(_("Trade canceled."), BY_SERVER);
00217 tradeWindow->setVisible(false);
00218 tradeWindow->reset();
00219 player_node->setTrading(false);
00220 break;
00221
00222 case SMSG_TRADE_COMPLETE:
00223 localChatTab->chatLog(_("Trade completed."), BY_SERVER);
00224 tradeWindow->setVisible(false);
00225 tradeWindow->reset();
00226 player_node->setTrading(false);
00227 break;
00228 }
00229 }
00230
00231 void TradeHandler::request(Being *being)
00232 {
00233 MessageOut outMsg(CMSG_TRADE_REQUEST);
00234 outMsg.writeInt32(being->getId());
00235 }
00236
00237 void TradeHandler::respond(bool accept)
00238 {
00239 MessageOut outMsg(CMSG_TRADE_RESPONSE);
00240 outMsg.writeInt8(accept ? 3 : 4);
00241 }
00242
00243 void TradeHandler::addItem(Item *item, int amount)
00244 {
00245 MessageOut outMsg(CMSG_TRADE_ITEM_ADD_REQUEST);
00246 outMsg.writeInt16(item->getInvIndex() + INVENTORY_OFFSET);
00247 outMsg.writeInt32(amount);
00248 }
00249
00250 void TradeHandler::removeItem(int slotNum, int amount)
00251 {
00252
00253 }
00254
00255 void TradeHandler::setMoney(int amount)
00256 {
00257 MessageOut outMsg(CMSG_TRADE_ITEM_ADD_REQUEST);
00258 outMsg.writeInt16(0);
00259 outMsg.writeInt32(amount);
00260 }
00261
00262 void TradeHandler::confirm()
00263 {
00264 MessageOut outMsg(CMSG_TRADE_ADD_COMPLETE);
00265 }
00266
00267 void TradeHandler::finish()
00268 {
00269 MessageOut outMsg(CMSG_TRADE_OK);
00270 }
00271
00272 void TradeHandler::cancel()
00273 {
00274 MessageOut outMsg(CMSG_TRADE_CANCEL_REQUEST);
00275 }
00276
00277 }