Fix css style order when using external css files
[ryzomcore.git] / ryzom / client / src / interface_v3 / player_trade.cpp
blob5b0084cba1be9622fdf1d4bcdc0df8af0892e382
1 // Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
2 // Copyright (C) 2010 Winch Gate Property Limited
3 //
4 // This source file has been modified by the following contributors:
5 // Copyright (C) 2013 Laszlo KIS-ADAM (dfighter) <dfighter1985@gmail.com>
6 //
7 // This program is free software: you can redistribute it and/or modify
8 // it under the terms of the GNU Affero General Public License as
9 // published by the Free Software Foundation, either version 3 of the
10 // License, or (at your option) any later version.
12 // This program is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 // GNU Affero General Public License for more details.
17 // You should have received a copy of the GNU Affero General Public License
18 // along with this program. If not, see <http://www.gnu.org/licenses/>.
22 #include "stdpch.h"
24 #include "player_trade.h"
25 #include "interface_manager.h"
26 #include "dbctrl_sheet.h"
27 #include "dbgroup_list_sheet.h"
28 #include "nel/gui/action_handler.h"
29 #include "inventory_manager.h"
31 #include "game_share/inventories.h"
33 #include "../sheet_manager.h"
34 #include "../client_sheets/item_sheet.h"
36 using namespace std;
37 using namespace NLMISC;
39 /////////////
40 // GLOBALS //
41 /////////////
44 CPlayerTrade PlayerTrade;
46 // Context help
47 extern void contextHelp (const std::string &help);
49 //////////////////////
50 // MEMBER FUNCTIONS //
51 //////////////////////
54 void CPlayerTrade::putItemInExchange(CDBCtrlSheet *src, CDBCtrlSheet *dest, uint quantityMove)
56 if (dest && src)
58 restoreItem(dest);
59 src->copyAspect(dest);
61 // Partial copy?
62 sint quantitySrc= src->getQuantity();
63 if((sint)quantityMove<quantitySrc)
65 dest->setQuantity(quantityMove);
66 src->setQuantity(quantitySrc-quantityMove);
68 // no more item in inventaire
69 else
71 src->setSheetId(0);
76 void CPlayerTrade::restoreItem(CDBCtrlSheet *exchangeSlot)
78 if (!exchangeSlot) return;
79 if (exchangeSlot->getSheetId() == 0) return; // not used
80 CInventoryManager &im = getInventory();
82 // *** If not an AMMO, try to 'auto-stack', as server does
83 bool canAutoStack= false;
84 uint32 autoStackSheetId = 0;
85 sint32 autoStackQuality = 0;
86 sint32 autoStackMaxQuantity = 0;
87 const CItemSheet *itemSheet= exchangeSlot->asItemSheet();
88 // NB: cannot auto stack ammo because their full props (dammage etc...) are not sent to client
89 if(itemSheet)
91 canAutoStack= itemSheet->Stackable>1 && itemSheet->Family!=ITEMFAMILY::AMMO;
92 autoStackSheetId= itemSheet->Id.asInt();
93 autoStackQuality= exchangeSlot->getQuality();
94 autoStackMaxQuantity= itemSheet->Stackable;
97 // *** find an empty place in the inventory, or if autoStack, distribute over existing slot
98 sint32 emptySlot= -1;
99 sint32 quantityLeft= exchangeSlot->getQuantity();
100 for(uint k = 0; k < MAX_BAGINV_ENTRIES; ++k)
102 if (im.getBagItem(k).getSheetID() == 0)
104 emptySlot= k;
105 // if cannot auto stack, don't need to go further
106 if(!canAutoStack)
107 break;
109 // can auto stack on this slot?
110 else if(canAutoStack)
112 sint32 dstQuantity= im.getBagItem(k).getQuantity();
114 // if same sheet/quality, and if can put some stack in this slot
115 if( im.getBagItem(k).getSheetID()==autoStackSheetId &&
116 im.getBagItem(k).getQuality()==autoStackQuality &&
117 dstQuantity<autoStackMaxQuantity )
119 // if can put all left stack
120 if(autoStackMaxQuantity-dstQuantity>=quantityLeft)
122 im.getBagItem(k).setQuantity((uint16)(dstQuantity+quantityLeft));
123 quantityLeft= 0;
124 break;
126 else
128 im.getBagItem(k).setQuantity((uint16)autoStackMaxQuantity);
129 quantityLeft-= autoStackMaxQuantity-dstQuantity;
135 // if some quantity not distributed, Move all the remaining exchange slot to the empty slot detected (if any)
136 if(quantityLeft && emptySlot>=0)
138 im.getBagItem(emptySlot).setSheetID(exchangeSlot->getSheetId());
139 im.getBagItem(emptySlot).setQuality((uint16) exchangeSlot->getQuality());
140 im.getBagItem(emptySlot).setQuantity((uint16) quantityLeft);
141 im.getBagItem(emptySlot).setUserColor((uint8) exchangeSlot->getItemColor());
142 im.getBagItem(emptySlot).setWeight((uint32) exchangeSlot->getItemWeight());
143 im.getBagItem(emptySlot).setNameId(exchangeSlot->getItemNameId());
144 im.getBagItem(emptySlot).setInfoVersion(exchangeSlot->getItemInfoVersion());
145 im.getBagItem(emptySlot).setResaleFlag(exchangeSlot->getItemResaleFlag());
149 // clear item from exchange
150 exchangeSlot->setSheetId(0);
151 exchangeSlot->setQuality(0);
152 exchangeSlot->setQuantity(0);
155 CDBCtrlSheet *CPlayerTrade::getExchangeItem(uint index)
157 CInterfaceManager *im = CInterfaceManager::getInstance();
158 return dynamic_cast<CDBCtrlSheet *>(CWidgetManager::getInstance()->getElementFromId(NLMISC::toString("ui:interface:player_trade:header_opened:give:given_items:slot%d", (int) index)));
162 void CPlayerTrade::restoreAllItems()
164 for(uint k = 0; k < NumTradeSlot; ++k)
166 restoreItem(getExchangeItem(k));
171 /////////////////////
172 // ACTION HANDLERS //
173 /////////////////////
175 class CPlayerTradeStartHandler : public IActionHandler
177 virtual void execute (CCtrlBase * /* pCaller */, const string &/* Params */)
179 CInterfaceManager *im = CInterfaceManager::getInstance();
180 if (NLGUI::CDBManager::getInstance()->getDbProp("LOCAL:EXCHANGE:BEGUN")->getValue8() != 0)
182 //PlayerTrade.reset();
184 // Context help
185 contextHelp ("inventory");
189 REGISTER_ACTION_HANDLER(CPlayerTradeStartHandler, "player_trade_start");
192 class CPlayerTradeLeftClickOnSlotHandler : public IActionHandler
194 virtual void execute (CCtrlBase *pCaller, const string &/* Params */)
196 CDBCtrlSheet *sheet = dynamic_cast<CDBCtrlSheet *>(pCaller);
197 if (!sheet) return;
198 if (sheet->getSheetId() == 0)
200 CInventoryManager *pInv = CInventoryManager::getInstance();
201 // is there's no item that is not worn, can't choose any item)
202 bool isThereObjectNotWorn = false;
203 for(uint k = 0; k < MAX_BAGINV_ENTRIES; ++k)
205 uint32 sheetid = pInv->getBagItem(k).getSheetID();
206 if (sheetid != 0)
208 if (!pInv->isBagItemWeared(k))
210 CEntitySheet *pES = SheetMngr.get(CSheetId(sheetid));
211 if (pES && pES->type()== CEntitySheet::ITEM)
213 CItemSheet *pIS = (CItemSheet*)pES;
214 if (pIS->canExchangeOrGive(PlayerTrade.BotChatGiftContext))
216 isThereObjectNotWorn = true;
217 break;
224 if (!isThereObjectNotWorn)
226 // every object are worn, so there's no use to display an empty list -> no-op
227 return;
230 CInterfaceManager *im = CInterfaceManager::getInstance();
231 CWidgetManager::getInstance()->pushModalWindow(pCaller, "ui:interface:exchange_choose_in_bag");
234 REGISTER_ACTION_HANDLER(CPlayerTradeLeftClickOnSlotHandler, "exchange_left_click_on_slot");