1 // Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
2 // Copyright (C) 2010 Winch Gate Property Limited
4 // This source file has been modified by the following contributors:
5 // Copyright (C) 2013 Laszlo KIS-ADAM (dfighter) <dfighter1985@gmail.com>
6 // Copyright (C) 2019 Jan BOON (Kaetemi) <jan.boon@kaetemi.be>
8 // This program is free software: you can redistribute it and/or modify
9 // it under the terms of the GNU Affero General Public License as
10 // published by the Free Software Foundation, either version 3 of the
11 // License, or (at your option) any later version.
13 // This program is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 // GNU Affero General Public License for more details.
18 // You should have received a copy of the GNU Affero General Public License
19 // along with this program. If not, see <http://www.gnu.org/licenses/>.
27 #include "interface_manager.h"
28 #include "bot_chat_manager.h"
29 #include "nel/gui/action_handler.h"
30 #include "nel/gui/group_container.h"
31 #include "macrocmd_manager.h"
32 #include "chat_window.h"
33 #include "people_interraction.h"
34 #include "nel/gui/group_editbox.h"
35 #include "nel/gui/group_html.h"
36 #include "inventory_manager.h"
39 #include "../entities.h"
40 #include "../actions_client.h"
42 // Game share specific includes
43 #include "game_share/constants.h"
46 // ***************************************************************************
49 using namespace NLMISC
;
51 // ***************************************************************************
52 // ***************************************************************************
53 // ***************************************************************************
54 // CONTAINER ACTION HANDLERS
55 // ***************************************************************************
56 // ***************************************************************************
57 // ***************************************************************************
60 // test if a container is currently allowed to be displayed
61 static bool isContainerAuthorized(CGroupContainer
*pGC
)
64 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
65 std::string shortId
= pGC
->getShortId();
66 // special case to prevent opening the guild inventory window if there's
67 // no guild or not in guild hall.
68 if (shortId
== "inv_guild")
70 if (NLGUI::CDBManager::getInstance()->getDbProp("SERVER:GUILD:NAME") == 0
71 || !getInventory().isInventoryPresent(INVENTORIES::guild
))
73 return false; // can't open it right now
76 if (shortId
== "inv_room")
78 if (!getInventory().isInventoryPresent(INVENTORIES::player_room
))
86 // ***************************************************************************
88 // Arg : a container name
90 // ***************************************************************************
91 class CAHUIOpen
: public IActionHandler
93 virtual void execute (CCtrlBase
* /* pCaller */, const string
&Params
)
95 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
96 CGroupContainer
*pGC
= dynamic_cast<CGroupContainer
*>(CWidgetManager::getInstance()->getElementFromId("ui:interface", Params
));
99 nlwarning("%s is not a container", Params
.c_str());
102 if (!isContainerAuthorized(pGC
)) return;
106 REGISTER_ACTION_HANDLER( CAHUIOpen
, "open" );
108 // ***************************************************************************
110 // Arg : a container name
112 // ***************************************************************************
113 class CAHUIClose
: public IActionHandler
115 virtual void execute (CCtrlBase
* /* pCaller */, const string
&Params
)
117 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
118 CGroupContainer
*pGC
= dynamic_cast<CGroupContainer
*>(CWidgetManager::getInstance()->getElementFromId("ui:interface", Params
));
121 nlwarning("%s is not a container", Params
.c_str());
127 REGISTER_ACTION_HANDLER( CAHUIClose
, "close" );
129 // ***************************************************************************
131 // Arg : a container name
132 // Toggle - Close a container if opened and open it if closed
133 // ***************************************************************************
134 class CAHUIOpenClose
: public IActionHandler
136 virtual void execute (CCtrlBase
* /* pCaller */, const string
&Params
)
138 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
139 CGroupContainer
*pGC
= dynamic_cast<CGroupContainer
*>(CWidgetManager::getInstance()->getElementFromId("ui:interface", Params
));
142 nlwarning("%s is not a container", Params
.c_str());
145 if (!isContainerAuthorized(pGC
)) return;
146 pGC
->setOpen (!pGC
->isOpen());
149 REGISTER_ACTION_HANDLER( CAHUIOpenClose
, "open_close" );
151 // ***************************************************************************
153 // Arg : a container name
155 // ***************************************************************************
156 class CAHUIPopup
: public IActionHandler
158 virtual void execute (CCtrlBase
* /* pCaller */, const string
&Params
)
160 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
161 CGroupContainer
*pGC
= dynamic_cast<CGroupContainer
*>(CWidgetManager::getInstance()->getElementFromId("ui:interface", Params
));
164 nlwarning("%s is not a container", Params
.c_str());
167 if (!pGC
->isPopable())
169 nlwarning("%s cannot be popup", Params
.c_str());
172 if (!isContainerAuthorized(pGC
)) return;
176 CWidgetManager::getInstance()->setCapturePointerLeft(NULL
);
177 CWidgetManager::getInstance()->setCapturePointerRight(NULL
);
180 REGISTER_ACTION_HANDLER( CAHUIPopup
, "popup" );
182 // ***************************************************************************
184 // Arg : a container name
185 // Popin a container (restore it)
186 // ***************************************************************************
187 class CAHUIPopin
: public IActionHandler
189 virtual void execute (CCtrlBase
* /* pCaller */, const string
&Params
)
191 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
192 CGroupContainer
*pGC
= dynamic_cast<CGroupContainer
*>(CWidgetManager::getInstance()->getElementFromId("ui:interface", Params
));
195 nlwarning("%s is not a container", Params
.c_str());
198 if (!pGC
->isPopable())
200 nlwarning("%s cannot be popin", Params
.c_str());
203 if (!isContainerAuthorized(pGC
)) return;
204 // memorize popup position
205 pGC
->setPopupX(pGC
->getX());
206 pGC
->setPopupY(pGC
->getY());
207 pGC
->setPopupW(pGC
->getW());
208 pGC
->setPopupH(pGC
->getH());
211 CWidgetManager::getInstance()->setCapturePointerLeft(NULL
);
212 CWidgetManager::getInstance()->setCapturePointerRight(NULL
);
215 REGISTER_ACTION_HANDLER( CAHUIPopin
, "popin" );
217 // ***************************************************************************
219 // Arg : a container name
220 // Toggle Popup/Popin a container
221 // ***************************************************************************
222 class CAHUIPopupPopin
: public IActionHandler
224 virtual void execute (CCtrlBase
* /* pCaller */, const string
&Params
)
226 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
227 CGroupContainer
*pGC
= dynamic_cast<CGroupContainer
*>(CWidgetManager::getInstance()->getElementFromId("ui:interface", Params
));
230 nlwarning("%s is not a container", Params
.c_str());
233 if (!pGC
->isPopable())
235 nlwarning("%s cannot be popup/popin", Params
.c_str());
238 if (!isContainerAuthorized(pGC
)) return;
239 if (pGC
->isPopuped())
240 CAHManager::getInstance()->runActionHandler("popin", NULL
, Params
);
242 CAHManager::getInstance()->runActionHandler("popup", NULL
, Params
);
245 REGISTER_ACTION_HANDLER( CAHUIPopupPopin
, "popup_popin" );
247 // ***************************************************************************
249 // Arg : a container name
250 // Show a container on a key down (else hide it)
251 // ***************************************************************************
252 class CAHUIShowOnPress
: public IActionHandler
260 virtual void execute (CCtrlBase
* /* pCaller */, const string
&Params
)
262 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
263 CGroupContainer
*pGC
= dynamic_cast<CGroupContainer
*>(CWidgetManager::getInstance()->getElementFromId("ui:interface", Params
));
266 nlwarning("%s is not a container", Params
.c_str());
269 if (!isContainerAuthorized(pGC
)) return;
271 CActionsManager
*pAM
= &Actions
;
274 if (!pAM
->valide(CAction::CName("show_on_press",Params
.c_str())))
276 pGC
->setActive(false);
281 // For the first time ?
286 else // Not the first time*/
288 // Show the container
289 pGC
->setActive(true);
296 REGISTER_ACTION_HANDLER( CAHUIShowOnPress
, "show_on_press" );
299 // ***************************************************************************
301 // Arg : a container name
303 // ***************************************************************************
304 class CAHUIShow
: public IActionHandler
311 virtual void execute (CCtrlBase
* /* pCaller */, const string
&Params
)
313 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
314 CGroupContainer
*pGC
= dynamic_cast<CGroupContainer
*>(CWidgetManager::getInstance()->getElementFromId("ui:interface", Params
));
317 nlwarning("%s is not a container", Params
.c_str());
320 if (!isContainerAuthorized(pGC
)) return;
322 pGC
->setActive(true);
323 CWidgetManager::getInstance()->setTopWindow(pGC
);
326 REGISTER_ACTION_HANDLER( CAHUIShow
, "show" );
328 static string currentWebApp
;
330 // ***************************************************************************
332 // Arg : a container name
334 // ***************************************************************************
335 class CAHUIHide
: public IActionHandler
342 virtual void execute (CCtrlBase
* /* pCaller */, const string
&Params
)
344 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
345 CGroupContainer
*pGC
= dynamic_cast<CGroupContainer
*>(CWidgetManager::getInstance()->getElementFromId("ui:interface", Params
));
348 nlwarning("%s is not a container", Params
.c_str());
351 if (!isContainerAuthorized(pGC
)) return;
353 pGC
->setActive(false);
356 REGISTER_ACTION_HANDLER( CAHUIHide
, "hide" );
358 string
urlencode(const string
¶m
)
360 CSString str
= param
;
361 str
= str
.replace("+", toString("%%%2x", '+').c_str());
362 str
= str
.replace("'", toString("%%%2x", '\'').c_str());
363 str
= str
.replace("-", toString("%%%2x", '-').c_str());
364 str
= str
.replace("\"", toString("%%%2x", '"').c_str());
365 str
= str
.replace(" ", "+");
369 // ***************************************************************************
371 // Arg : a container name
372 // Toggle - Show a container if hidden and hide it if shown
373 // ***************************************************************************
374 class CAHUIShowHide
: public IActionHandler
376 virtual void execute (CCtrlBase
* /* pCaller */, const string
&Params
)
378 string webapp
, window
= Params
;
380 explode(Params
, string("|"), res
);
381 if(res
[0]=="webig" || res
[0]=="mailbox" || res
[0]=="guild_forum" || res
[0]=="profile")
384 if(res
[0]=="mailbox")
386 else if(res
[0]=="guild_forum")
388 else if(res
[0]=="profile")
389 webapp
= "profile&pname="+urlencode(getParam(Params
,"pname"))+"&ptype="+getParam(Params
,"ptype");
394 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
395 CGroupContainer
*pGC
= dynamic_cast<CGroupContainer
*>(CWidgetManager::getInstance()->getElementFromId("ui:interface", window
));
398 nlwarning("%s is not a container", window
.c_str());
401 if (!isContainerAuthorized(pGC
)) return;
403 if(window
== "webig")
405 if(pGC
->getActive() && currentWebApp
== webapp
)
407 pGC
->setActive(false);
408 currentWebApp
.clear();
412 pGC
->setActive(true);
413 currentWebApp
= webapp
;
415 if(!webapp
.empty() && pGC
->getActive())
417 CGroupHTML
*pGH
= dynamic_cast<CGroupHTML
*>(CWidgetManager::getInstance()->getElementFromId("ui:interface:webig:content:html"));
420 nlwarning("%s is not a group html", window
.c_str());
423 pGH
->setURL(ClientCfg
.WebIgMainDomain
+ "/index.php?app=" + webapp
);
428 // normal open/close swap
429 pGC
->setActive(!pGC
->getActive());
433 REGISTER_ACTION_HANDLER( CAHUIShowHide
, "show_hide" );
435 // ***************************************************************************
436 // ***************************************************************************
437 // ***************************************************************************
438 // GAME ACTION HANDLERS
439 // ***************************************************************************
440 // ***************************************************************************
441 // ***************************************************************************
443 // ***************************************************************************
446 // Set the Next sheath
447 // ***************************************************************************
449 class CAHNextSheath : public IActionHandler
451 virtual void execute (CCtrlBase *pCaller, const string &Params)
453 CInterfaceManager *pIM = CInterfaceManager::getInstance();
454 CCDBNodeLeaf *pNLCurSetWrite = NLGUI::CDBManager::getInstance()->getDbProp(CWidgetManager::getInstance()->getParser()->getDefine("ui_set_active"));
455 CCDBNodeLeaf *pNLCurSetRead = NLGUI::CDBManager::getInstance()->getDbProp(CWidgetManager::getInstance()->getParser()->getDefine("set_active"));
456 CCDBNodeLeaf *pNLNbSet = NLGUI::CDBManager::getInstance()->getDbProp(CWidgetManager::getInstance()->getParser()->getDefine("set_nb"));
457 sint64 nVal = pNLCurSetRead->getValue64() - INVENTORIES::sheath1;
458 sint64 nMax = pNLNbSet->getValue64();
460 if (nVal >= nMax) nVal = 0;
461 nVal += INVENTORIES::sheath1;
462 pNLCurSetWrite->setValue64(nVal);
465 REGISTER_ACTION_HANDLER( CAHNextSheath, "next_sheath" );
467 // ***************************************************************************
470 // Set the Previous sheath
471 // ***************************************************************************
473 class CAHPreviousSheath : public IActionHandler
475 virtual void execute (CCtrlBase *pCaller, const string &Params)
477 CInterfaceManager *pIM = CInterfaceManager::getInstance();
478 CCDBNodeLeaf *pNLCurSetWrite = NLGUI::CDBManager::getInstance()->getDbProp(CWidgetManager::getInstance()->getParser()->getDefine("ui_set_active"));
479 CCDBNodeLeaf *pNLCurSetRead = NLGUI::CDBManager::getInstance()->getDbProp(CWidgetManager::getInstance()->getParser()->getDefine("set_active"));
480 CCDBNodeLeaf *pNLNbSet = NLGUI::CDBManager::getInstance()->getDbProp(CWidgetManager::getInstance()->getParser()->getDefine("set_nb"));
481 sint64 nVal = pNLCurSetRead->getValue64() - INVENTORIES::sheath1;
482 sint64 nMax = pNLNbSet->getValue64();
483 if (nVal == 0) nVal = nMax;
485 nVal += INVENTORIES::sheath1;
486 pNLCurSetWrite->setValue64(nVal);
489 REGISTER_ACTION_HANDLER( CAHPreviousSheath, "previous_sheath" );
491 // ***************************************************************************
493 // Arg : the sheath number (int)
495 // ***************************************************************************
497 class CAHSetSheath : public IActionHandler
499 virtual void execute (CCtrlBase *pCaller, const string &Params)
501 CInterfaceManager *pIM = CInterfaceManager::getInstance();
502 CCDBNodeLeaf *pNLCurSetWrite = NLGUI::CDBManager::getInstance()->getDbProp(CWidgetManager::getInstance()->getParser()->getDefine("ui_set_active"));
503 CCDBNodeLeaf *pNLNbSet = NLGUI::CDBManager::getInstance()->getDbProp(CWidgetManager::getInstance()->getParser()->getDefine("set_nb"));
505 fromString(Params, nVal);
506 nVal -= INVENTORIES::sheath1;
507 sint64 nMax = pNLNbSet->getValue64();
508 if (nVal < 0) nVal = 0;
509 if (nVal >= nMax) nVal = nMax-1;
510 nVal += INVENTORIES::sheath1;
511 pNLCurSetWrite->setValue64(nVal);
514 REGISTER_ACTION_HANDLER( CAHSetSheath, "set_sheath" );
516 // ***************************************************************************
519 // Talk or end dialog with the current target
520 // ***************************************************************************
521 class CAHTalkUntalk
: public IActionHandler
523 virtual void execute (CCtrlBase
* /* pCaller */, const string
&/* Params */)
525 /* CInterfaceManager *pIM = CInterfaceManager::getInstance();
526 if(pIM == NULL) return;
527 CEntityCL *selection = EntitiesMngr.entity(UserEntity->selection());
529 if (selection && selection->Type == CEntityCL::Player)
531 if (!selection->getName().empty())
533 // popup the main window and set its target to be the player
534 CChatWindow *cw = PeopleInterraction.MainChat.Window;
535 if (cw && cw->getContainer())
537 cw->getContainer()->setActive(true);
538 cw->getContainer()->setOpen(true);
539 CInterfaceManager *im = CInterfaceManager::getInstance();
540 CWidgetManager::getInstance()->setTopWindow(cw->getContainer());
542 CWidgetManager::getInstance()->setCaptureKeyboard(cw->getEditBox());
543 PeopleInterraction.MainChat.Filter.setTargetPlayer(selection->getName());
549 CBotChatManager::getInstance()->setCurrPage(NULL);
551 if (UserEntity->mode()==MBEHAV::COMBAT
552 || UserEntity->mode()==MBEHAV::COMBAT_FLOAT)
556 // Not in combat mode.
560 if ((UserEntity->selection() != UserEntity->slot()) &&
561 (selection) && (selection->properties().talkableTo()))
563 CVectorD vect1 = selection->pos();
564 CVectorD vect2 = UserEntity->pos();
565 double distanceSquare = pow(vect1.x-vect2.x,2) + pow(vect1.y-vect2.y,2);
566 if(distanceSquare <= MaxTalkingDistSquare)
568 CAHManager::getInstance()->runActionHandler("context_talk",NULL);
575 REGISTER_ACTION_HANDLER( CAHTalkUntalk
, "talk_untalk" );
577 // ***************************************************************************
580 // Mount or unseat if we can the current target
581 // ***************************************************************************
582 class CAHMountUnmount
: public IActionHandler
584 virtual void execute (CCtrlBase
* /* pCaller */, const string
&/* Params */)
586 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
587 if(pIM
== NULL
) return;
588 CEntityCL
*selection
= EntitiesMngr
.entity(UserEntity
->selection());
590 // If mode Combat (no talk, no give, no mount)
591 if(UserEntity
->mode()==MBEHAV::COMBAT
592 || UserEntity
->mode()==MBEHAV::COMBAT_FLOAT
)
594 return; // Cant mount
597 else if(UserEntity
->isRiding())
599 // We are currently mounted so unmount
600 CAHManager::getInstance()->runActionHandler("context_unseat",NULL
);
602 // Not in combat mode.
605 // check if we can mount
606 if ((selection
) && (selection
->properties().mountable()))
608 CVectorD vect1
= selection
->pos();
609 CVectorD vect2
= UserEntity
->pos();
610 double distanceSquare
= pow(vect1
.x
-vect2
.x
,2) + pow(vect1
.y
-vect2
.y
,2);
611 if(distanceSquare
<= MaxTalkingDistSquare
)
614 CAHManager::getInstance()->runActionHandler("context_mount",NULL
);
620 REGISTER_ACTION_HANDLER( CAHMountUnmount
, "mount_unmount" );
622 // ***************************************************************************
625 // Exchange with the current target
626 // ***************************************************************************
627 class CAHExchange
: public IActionHandler
629 virtual void execute (CCtrlBase
* /* pCaller */, const string
&/* Params */)
631 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
632 if(pIM
== NULL
) return;
633 CEntityCL
*selection
= EntitiesMngr
.entity(UserEntity
->selection());
635 if(UserEntity
->mode()==MBEHAV::COMBAT
636 || UserEntity
->mode()==MBEHAV::COMBAT_FLOAT
)
638 return; // Cant exchange
643 if (selection
&& selection
->properties().canExchangeItem())
644 if (!UserEntity
->isBusy())
645 CAHManager::getInstance()->runActionHandler("context_exchange",NULL
);
649 REGISTER_ACTION_HANDLER( CAHExchange
, "exchange" );
651 // ***************************************************************************
653 // Arg : window full name
654 // ***************************************************************************
655 class CAHUISetTopWindow
: public IActionHandler
657 virtual void execute (CCtrlBase
* /* pCaller */, const string
&Params
)
659 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
660 string sWin
= getParam(Params
,"win");
661 CGroupContainer
*pGC
= dynamic_cast<CGroupContainer
*>(CWidgetManager::getInstance()->getElementFromId(sWin
));
662 if (pGC
!= NULL
&& isContainerAuthorized(pGC
)) CWidgetManager::getInstance()->setTopWindow(pGC
);
665 REGISTER_ACTION_HANDLER( CAHUISetTopWindow
, "set_top_window" );
668 // ***************************************************************************
670 // ***************************************************************************
672 class CAHUIDockUndocChat
: public IActionHandler
674 virtual void execute (CCtrlBase
* /* pCaller */, const string
&Params
)
676 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
677 // change the DB (if exist)
678 CCDBNodeLeaf
*node
= NLGUI::CDBManager::getInstance()->getDbProp(toString("UI:SAVE:ISDETACHED:")+Params
, false);
682 node
->setValueBool(!node
->getValueBool());
686 REGISTER_ACTION_HANDLER( CAHUIDockUndocChat
, "dock_undock_chat" );