ManaPlus
popupmenu.cpp
Go to the documentation of this file.
1 /*
2  * The ManaPlus Client
3  * Copyright (C) 2004-2009 The Mana World Development Team
4  * Copyright (C) 2009-2010 The Mana Developers
5  * Copyright (C) 2011-2019 The ManaPlus Developers
6  * Copyright (C) 2019-2021 Andrei Karas
7  *
8  * This file is part of The ManaPlus Client.
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program. If not, see <http://www.gnu.org/licenses/>.
22  */
23 
24 #include "gui/popups/popupmenu.h"
25 
26 #include "actormanager.h"
27 #include "configuration.h"
28 #include "party.h"
29 #include "settings.h"
30 
31 #include "being/flooritem.h"
32 #include "being/localplayer.h"
33 #include "being/playerinfo.h"
34 #include "being/playerrelation.h"
35 #include "being/playerrelations.h"
36 
37 #include "const/spells.h"
38 
40 
41 #include "input/inputmanager.h"
42 
43 #include "gui/buttontext.h"
44 #include "gui/gui.h"
45 #include "gui/popupmanager.h"
46 #include "gui/viewport.h"
47 #include "gui/windowmenu.h"
48 
49 #include "gui/windows/chatwindow.h"
51 #include "gui/windows/minimap.h"
53 #include "gui/windows/npcdialog.h"
57 #include "gui/windows/textdialog.h"
59 
60 #include "gui/widgets/button.h"
63 #include "gui/widgets/scrollarea.h"
65 #include "gui/widgets/textfield.h"
66 
68 
69 #include "net/adminhandler.h"
70 #include "net/chathandler.h"
71 #include "net/guildhandler.h"
72 #include "net/npchandler.h"
73 #include "net/net.h"
74 
75 #ifdef TMWA_SUPPORT
76 #include "net/tmwa/guildmanager.h"
77 #endif // TMWA_SUPPORT
78 
79 #include "resources/chatobject.h"
80 #include "resources/groupinfo.h"
81 #include "resources/iteminfo.h"
82 #include "resources/itemmenuitem.h"
83 
84 #include "resources/db/groupdb.h"
85 #include "resources/db/npcdb.h"
86 
87 #include "resources/item/item.h"
88 
89 #include "resources/map/map.h"
90 #include "resources/map/mapitem.h"
92 
94 
95 #include "utils/checkutils.h"
96 #include "utils/foreach.h"
97 #include "utils/gettext.h"
98 
99 #include "debug.h"
100 
101 std::string tradePartnerName;
102 
103 PopupMenu *popupMenu = nullptr;
104 
106  Popup("PopupMenu", "popupmenu.xml"),
107  mBrowserBox(new StaticBrowserBox(this, Opaque_true,
108  "popupbrowserbox.xml")),
109  mScrollArea(nullptr),
110  mBeingId(BeingId_zero),
111  mFloorItemId(BeingId_zero),
112  mItemId(0),
113  mItemIndex(-1),
114  mItemColor(ItemColor_one),
115  mMapItem(nullptr),
116  mTab(nullptr),
117  mSpell(nullptr),
118  mCallerWindow(nullptr),
119  mRenameListener(),
120  mPlayerListener(),
121  mDialog(nullptr),
122  mButton(nullptr),
123  mGroup(nullptr),
124  mName(),
125  mExtName(),
126  mTextField(nullptr),
127  mType(ActorType::Unknown),
128  mSubType(BeingTypeId_zero),
129  mX(0),
130  mY(0),
131  mAllowCleanMenu(true)
132 {
135  mRenameListener.setMapItem(nullptr);
136  mRenameListener.setDialog(nullptr);
138  mPlayerListener.setDialog(nullptr);
140  mScrollArea = new ScrollArea(this,
141  mBrowserBox, Opaque_false, std::string());
143  addMouseListener(this);
144 }
145 
147 {
148  Popup::postInit();
149  add(mScrollArea);
150 }
151 
153 {
154  if (localPlayer == nullptr)
155  return;
156  const int groupId = localPlayer->getGroupId();
157  mGroup = GroupDb::getGroup(groupId);
158 }
159 
161 {
162  if (mGroup == nullptr)
163  return false;
164 #ifdef TMWA_SUPPORT
165  // allow any commands for legacy if group > 0
167  localPlayer != nullptr &&
168  localPlayer->isGM())
169  {
170  return true;
171  }
172 #endif
173  if (mGroup->mPermissions[CAST_SIZE(ServerPermissionType::all_commands)] ==
174  Enable_true)
175  {
176  return true;
177  }
178  const ServerCommandEnable::Type enabled =
179  mGroup->mCommands[CAST_SIZE(command)];
180  return (enabled & ServerCommandEnable::Self) != 0;
181 }
182 
184 {
185  if (mGroup == nullptr ||
186  localPlayer == nullptr)
187  return false;
188 #ifdef TMWA_SUPPORT
189  // allow any commands for legacy if group > 0
191  localPlayer->isGM())
192  {
193  return true;
194  }
195 #endif
196  const ServerCommandEnable::Type enabled =
197  mGroup->mCommands[CAST_SIZE(command)];
198  if (mName == localPlayer->getName())
199  return (enabled & ServerCommandEnable::Self) != 0;
200  return (enabled & ServerCommandEnable::Other) != 0;
201 }
202 
203 void PopupMenu::showPopup(const int x, const int y, const Being *const being)
204 {
205  if (being == nullptr ||
206  localPlayer == nullptr ||
207  actorManager == nullptr)
208  {
209  return;
210  }
211 
212  initPopup();
213  mBeingId = being->getId();
214  mName = being->getName();
215  mExtName = being->getExtName();
216  mType = being->getType();
217  mSubType = being->getSubType();
219  mX = x;
220  mY = y;
221 
222  const std::string &name = mName;
223  if (being->getType() != ActorType::SkillUnit)
224  {
225  mBrowserBox->addRow(name + being->getGenderSignWithSpace(),
226  false);
227  }
228 
229  switch (being->getType())
230  {
231  case ActorType::Player:
232  {
233  // TRANSLATORS: popup menu item
234  // TRANSLATORS: trade with player
235  mBrowserBox->addRow("/trade 'NAME'", _("Trade"));
236  // TRANSLATORS: popup menu item
237  // TRANSLATORS: trade attack player
238  mBrowserBox->addRow("/attack 'NAME'", _("Attack"));
239  // TRANSLATORS: popup menu item
240  // TRANSLATORS: send whisper to player
241  mBrowserBox->addRow("/whispertext 'NAME'", _("Whisper"));
242  addMailCommands();
243  addGmCommands();
244  mBrowserBox->addSeparator("##3---");
245 
246 #ifdef TMWA_SUPPORT
248  {
249  // TRANSLATORS: popup menu item
250  // TRANSLATORS: heal player
251  mBrowserBox->addRow("/heal :'BEINGID'", _("Heal"));
252  mBrowserBox->addSeparator("##3---");
253  }
254 #endif // TMWA_SUPPORT
255 
256  addPlayerRelation(name);
257  mBrowserBox->addSeparator("##3---");
258 
259  addFollow();
260  addPartyName(being->getPartyName());
261 
262  const Guild *const guild1 = being->getGuild();
263  const Guild *const guild2 = localPlayer->getGuild();
264  if (guild2 != nullptr)
265  {
266  if (guild1 != nullptr)
267  {
268  if (guild1->getId() == guild2->getId())
269  {
270  mBrowserBox->addRow("/kickguild 'NAME'",
271  // TRANSLATORS: popup menu item
272  // TRANSLATORS: kick player from guild
273  _("Kick from guild"));
274  if (guild2->getServerGuild())
275  {
277  "@@guild-pos|%s >@@",
278  // TRANSLATORS: popup menu item
279  // TRANSLATORS: change player position in guild
280  _("Change pos in guild")),
281  false);
282  }
283  }
284  }
285  else if (guild2->getMember(mName) != nullptr)
286  {
287  mBrowserBox->addRow("/kickguild 'NAME'",
288  // TRANSLATORS: popup menu item
289  // TRANSLATORS: kick player from guild
290  _("Kick from guild"));
291  if (guild2->getServerGuild())
292  {
294  "@@guild-pos|%s >@@",
295  // TRANSLATORS: popup menu item
296  // TRANSLATORS: change player position in guild
297  _("Change pos in guild")),
298  false);
299  }
300  }
301  else
302  {
303 #ifdef TMWA_SUPPORT
304  if (guild2->getServerGuild() ||
305  (guildManager != nullptr && guildManager->havePower()))
306 #endif // TMWA_SUPPORT
307  {
308  mBrowserBox->addRow("/guild 'NAME'",
309  // TRANSLATORS: popup menu item
310  // TRANSLATORS: invite player to guild
311  _("Invite to guild"));
312  }
313  }
314  }
315 
316  // TRANSLATORS: popup menu item
317  // TRANSLATORS: set player invisible for self by id
318  mBrowserBox->addRow("/nuke 'NAME'", _("Nuke"));
319  // TRANSLATORS: popup menu item
320  // TRANSLATORS: move to player location
321  mBrowserBox->addRow("/navigateto 'NAME'", _("Move"));
322  addPlayerMisc();
323  addBuySell(being);
324  addChat(being);
325  break;
326  }
327 
328  case ActorType::Npc:
329  if (!addBeingMenu())
330  {
331  // TRANSLATORS: popup menu item
332  // TRANSLATORS: talk with npc
333  mBrowserBox->addRow("/talk :'BEINGID'", _("Talk"));
334 #ifdef TMWA_SUPPORT
336 #endif
337  {
338  mBrowserBox->addRow("/whispertext NPC:'NAME'",
339  // TRANSLATORS: popup menu item
340  // TRANSLATORS: whisper to npc
341  _("Whisper"));
342  }
343  // TRANSLATORS: popup menu item
344  // TRANSLATORS: buy from npc
345  mBrowserBox->addRow("/buy 'NAME'", _("Buy"));
346  // TRANSLATORS: popup menu item
347  // TRANSLATORS: sell to npc
348  mBrowserBox->addRow("/sell 'NAME'", _("Sell"));
349  }
350 
351  addGmCommands();
352  mBrowserBox->addSeparator("##3---");
353  // TRANSLATORS: popup menu item
354  // TRANSLATORS: move to npc location
355  mBrowserBox->addRow("/navigateto 'NAME'", _("Move"));
356  // TRANSLATORS: popup menu item
357  // TRANSLATORS: add comment to npc
358  mBrowserBox->addRow("addcomment", _("Add comment"));
359  addChat(being);
360  break;
361 
362  case ActorType::Monster:
363  {
364  // Monsters can be attacked
365  // TRANSLATORS: popup menu item
366  // TRANSLATORS: attack monster
367  mBrowserBox->addRow("/attack :'BEINGID'", _("Attack"));
369  addGmCommands();
370  mBrowserBox->addSeparator("##3---");
371 
372  if (config.getBoolValue("enableAttackFilter"))
373  {
374  mBrowserBox->addSeparator("##3---");
375  if (actorManager->isInAttackList(name)
378  {
379  mBrowserBox->addRow("/removeattack 'NAME'",
380  // TRANSLATORS: remove monster from attack list
381  // TRANSLATORS: popup menu item
382  _("Remove from attack list"));
383  }
384  else
385  {
386  mBrowserBox->addRow("/addpriorityattack 'NAME'",
387  // TRANSLATORS: popup menu item
388  // TRANSLATORS: add monster to priotiry attack list
389  _("Add to priority attack list"));
390  mBrowserBox->addRow("/addattack 'NAME'",
391  // TRANSLATORS: popup menu item
392  // TRANSLATORS: add monster to attack list
393  _("Add to attack list"));
394  mBrowserBox->addRow("/addignoreattack 'NAME'",
395  // TRANSLATORS: popup menu item
396  // TRANSLATORS: add monster to ignore list
397  _("Add to ignore list"));
398  }
399  }
400  break;
401  }
402 
404  // TRANSLATORS: popup menu item
405  // TRANSLATORS: Mercenary move to master
406  mBrowserBox->addRow("/mercenarytomaster", _("Move to master"));
407  addGmCommands();
408  mBrowserBox->addSeparator("##3---");
409  // TRANSLATORS: popup menu item
410  // TRANSLATORS: fire mercenary
411  mBrowserBox->addRow("/firemercenary", _("Fire"));
412  mBrowserBox->addSeparator("##3---");
413  break;
414 
416  {
418  if (info != nullptr)
419  {
420  mBrowserBox->addRow("/homunculustomaster",
421  // TRANSLATORS: popup menu item
422  // TRANSLATORS: homunculus move to master
423  _("Move to master"));
424  // TRANSLATORS: popup menu item
425  // TRANSLATORS: feed homunculus
426  mBrowserBox->addRow("/homunculusfeed", _("Feed"));
427  mBrowserBox->addSeparator("##3---");
428  // TRANSLATORS: popup menu item
429  // TRANSLATORS: pet rename item
430  mBrowserBox->addRow("/sethomunname", _("Rename"));
431  mBrowserBox->addSeparator("##3---");
432  // TRANSLATORS: popup menu item
433  // TRANSLATORS: delete homunculus
434  mBrowserBox->addRow("/homunculusfire", _("Kill"));
435  mBrowserBox->addSeparator("##3---");
436  }
437  addGmCommands();
438  break;
439  }
440  case ActorType::Pet:
441  if (being->getOwner() == localPlayer)
442  {
443  // TRANSLATORS: popup menu item
444  // TRANSLATORS: feed pet
445  mBrowserBox->addRow("/petfeed", _("Feed"));
446  // TRANSLATORS: popup menu item
447  // TRANSLATORS: pet drop loot
448  mBrowserBox->addRow("/petdroploot", _("Drop loot"));
449  // TRANSLATORS: popup menu item
450  // TRANSLATORS: pet unequip item
451  mBrowserBox->addRow("/petunequip", _("Unequip"));
452  addGmCommands();
453  mBrowserBox->addSeparator("##3---");
454  // TRANSLATORS: popup menu item
455  // TRANSLATORS: pet rename item
456  mBrowserBox->addRow("/setpetname", _("Rename"));
457  mBrowserBox->addSeparator("##3---");
458  const BeingInfo *const info = being->getInfo();
459  std::string msg;
460  if (info != nullptr)
461  msg = info->getString(0);
462  if (!msg.empty())
463  {
464  mBrowserBox->addRow("/petreturnegg", msg.c_str());
465  }
466  else
467  {
468  mBrowserBox->addRow("/petreturnegg",
469  // TRANSLATORS: popup menu item
470  // TRANSLATORS: pet return to egg
471  _("Return to egg"));
472  }
473  mBrowserBox->addSeparator("##3---");
474  }
475  else
476  {
478  }
479  break;
481  {
482  const BeingId id = being->getCreatorId();
483  std::string creatorName;
484  Being *const creator = actorManager->findBeing(id);
485  if (creator != nullptr)
486  creatorName = creator->getName();
487  else
488  creatorName = actorManager->getSeenPlayerById(id);
489 
490  if (creatorName.empty())
491  creatorName = strprintf("?%d", CAST_S32(id));
492 
493  mBrowserBox->addRow(strprintf("%s, %d (%s)",
494  name.c_str(),
495  CAST_S32(being->getSubType()),
496  creatorName.c_str()),
497  false);
498  break;
499  }
500  case ActorType::Avatar:
501  case ActorType::Unknown:
503  case ActorType::Portal:
505  default:
506  break;
507  }
508  // TRANSLATORS: popup menu item
509  // TRANSLATORS: add being name to chat
510  mBrowserBox->addRow("/addtext 'NAME'", _("Add name to chat"));
511  mBrowserBox->addSeparator("##3---");
512 
513  // TRANSLATORS: popup menu item
514  // TRANSLATORS: close menu
515  mBrowserBox->addRow("cancel", _("Cancel"));
516 
517  showPopup(x, y);
518 }
519 
521 {
523  if (being == nullptr)
524  return false;
525 
526  BeingInfo *const info = NPCDB::get(fromInt(
527  being->getSubType(), BeingTypeId));
528  if (info == nullptr)
529  return false;
530 
531  const STD_VECTOR<BeingMenuItem> &menu = info->getMenu();
532  FOR_EACH (STD_VECTOR<BeingMenuItem>::const_iterator, it, menu)
533  {
534  const BeingMenuItem &item = *it;
535  mBrowserBox->addRow("/" + item.command, item.name.c_str());
536  }
537  return true;
538 }
539 
541 {
542  if (viewport != nullptr)
543  {
544  mX = viewport->mMouseX;
545  mY = viewport->mMouseY;
546  }
547  else
548  {
550  }
551 }
552 
554 {
555  if (mX == 0 && mY == 0)
556  {
557  if (viewport != nullptr)
558  {
559  mX = viewport->mMouseX;
560  mY = viewport->mMouseY;
561  }
562  else
563  {
565  }
566  }
567 }
568 
569 void PopupMenu::showPopup(const int x, const int y,
570  const STD_VECTOR<ActorSprite*> &beings)
571 {
572  initPopup();
573  mX = x;
574  mY = y;
576  // TRANSLATORS: popup menu header
577  mBrowserBox->addRow(_("Players"), false);
578  FOR_EACH (STD_VECTOR<ActorSprite*>::const_iterator, it, beings)
579  {
580  const Being *const being = dynamic_cast<const Being*>(*it);
581  const ActorSprite *const actor = *it;
582  if ((being != nullptr) && !being->getName().empty())
583  {
584  mBrowserBox->addRow(strprintf("@@player_%u|%s >@@",
585  CAST_U32(being->getId()), (being->getName()
586  + being->getGenderSignWithSpace()).c_str()),
587  false);
588  }
589  else if (actor->getType() == ActorType::FloorItem)
590  {
591  const FloorItem *const floorItem
592  = static_cast<const FloorItem*>(actor);
593  mBrowserBox->addRow(strprintf("@@flooritem_%u|%s >@@",
594  CAST_U32(actor->getId()),
595  floorItem->getName().c_str()),
596  false);
597  }
598  }
599  mBrowserBox->addSeparator("##3---");
600  // TRANSLATORS: popup menu item
601  // TRANSLATORS: close menu
602  mBrowserBox->addRow("cancel", _("Cancel"));
603  showPopup(x, y);
604 }
605 
606 void PopupMenu::showPlayerPopup(const std::string &nick)
607 {
608  if (nick.empty() || (localPlayer == nullptr))
609  return;
610 
611  initPopup();
612  setMousePos();
613  mName = nick;
614  mExtName = nick;
619 
620  const std::string &name = mName;
621 
622  mBrowserBox->addRow(name, false);
623 
624  // TRANSLATORS: popup menu item
625  // TRANSLATORS: send whisper to player
626  mBrowserBox->addRow("/whispertext 'NAME'", _("Whisper"));
627  addMailCommands();
628  addGmCommands();
629  mBrowserBox->addSeparator("##3---");
630 
631  addPlayerRelation(name);
632  mBrowserBox->addSeparator("##3---");
633 
634  addFollow();
635  // TRANSLATORS: popup menu item
636  // TRANSLATORS: add comment to player
637  mBrowserBox->addRow("addcomment", _("Add comment"));
638 
639  if (localPlayer->isInParty())
640  {
641  const Party *const party = localPlayer->getParty();
642  if (party != nullptr)
643  {
644  const PartyMember *const member = party->getMember(mName);
645  if (member != nullptr)
646  {
647  // TRANSLATORS: popup menu item
648  // TRANSLATORS: kick player from party
649  mBrowserBox->addRow("/kickparty 'NAME'", _("Kick from party"));
650  mBrowserBox->addSeparator("##3---");
651  const PartyMember *const o = party->getMember(
652  localPlayer->getName());
654  if ((o != nullptr) && member->getMap() == o->getMap())
655  {
656  // TRANSLATORS: popup menu item
657  // TRANSLATORS: move to player position
658  mBrowserBox->addRow("/navigate 'X' 'Y'", _("Move"));
659  }
660  }
661  }
662  }
663 
664  const Guild *const guild2 = localPlayer->getGuild();
665  if (guild2 != nullptr)
666  {
667  if (guild2->getMember(mName) != nullptr)
668  {
669 #ifdef TMWA_SUPPORT
670  if (guild2->getServerGuild() || (guildManager != nullptr
671  && guildManager->havePower()))
672 #endif // TMWA_SUPPORT
673  {
674  mBrowserBox->addRow("/kickguild 'NAME'",
675  // TRANSLATORS: popup menu item
676  // TRANSLATORS: kick player from guild
677  _("Kick from guild"));
678  }
679  if (guild2->getServerGuild())
680  {
682  // TRANSLATORS: popup menu item
683  // TRANSLATORS: change player position in guild
684  "@@guild-pos|%s >@@", _("Change pos in guild")),
685  false);
686  }
687  }
688  else
689  {
690 #ifdef TMWA_SUPPORT
691  if (guild2->getServerGuild() || (guildManager != nullptr
692  && guildManager->havePower()))
693 #endif // TMWA_SUPPORT
694  {
695  // TRANSLATORS: popup menu item
696  // TRANSLATORS: invite player to guild
697  mBrowserBox->addRow("/guild 'NAME'", _("Invite to guild"));
698  }
699  }
700  }
701 
703  // TRANSLATORS: popup menu item
704  // TRANSLATORS: add player name to chat
705  mBrowserBox->addRow("/addtext 'NAME'", _("Add name to chat"));
706  mBrowserBox->addSeparator("##3---");
707  // TRANSLATORS: popup menu item
708  // TRANSLATORS: close menu
709  mBrowserBox->addRow("cancel", _("Cancel"));
710 
711  showPopup(mX, mY);
712 }
713 
714 void PopupMenu::showPopup(const int x, const int y,
715  const FloorItem *const floorItem)
716 {
717  if (floorItem == nullptr)
718  return;
719 
720  initPopup();
721  mX = x;
722  mY = y;
723  mFloorItemId = floorItem->getId();
724  mItemId = floorItem->getItemId();
727  for (int f = 0; f < maxCards; f ++)
728  mItemCards[f] = floorItem->getCard(f);
730  const std::string name = floorItem->getName();
731  mName = name;
732  mExtName = name;
733 
734  mBrowserBox->addRow(name, false);
735 
736  if (config.getBoolValue("enablePickupFilter"))
737  {
738  if (actorManager->isInPickupList(name)
741  {
742  // TRANSLATORS: popup menu item
743  // TRANSLATORS: pickup item from ground
744  mBrowserBox->addRow("/pickup 'FLOORID'", _("Pick up"));
745  mBrowserBox->addSeparator("##3---");
746  }
747  addPickupFilter(name);
748  }
749  else
750  {
751  // TRANSLATORS: popup menu item
752  // TRANSLATORS: pickup item from ground
753  mBrowserBox->addRow("/pickup 'FLOORID'", _("Pick up"));
754  }
755  addProtection();
756  // TRANSLATORS: popup menu item
757  // TRANSLATORS: add item name to chat
758  mBrowserBox->addRow("/addchat 'FLOORID''CARDS'", _("Add to chat"));
759  mBrowserBox->addSeparator("##3---");
760  addGmCommands();
761 
762  // TRANSLATORS: popup menu item
763  // TRANSLATORS: close menu
764  mBrowserBox->addRow("cancel", _("Cancel"));
765 
766  showPopup(mX, mY);
767 }
768 
769 void PopupMenu::showPopup(const int x, const int y, MapItem *const mapItem)
770 {
771  if (mapItem == nullptr)
772  return;
773 
774  initPopup();
775  mMapItem = mapItem;
776  mX = x;
777  mY = y;
778 
780 
781  // TRANSLATORS: popup menu header
782  mBrowserBox->addRow(_("Map Item"), false);
783  // TRANSLATORS: popup menu item
784  // TRANSLATORS: rename map item
785  mBrowserBox->addRow("rename map", _("Rename"));
786  // TRANSLATORS: popup menu item
787  // TRANSLATORS: remove map item
788  mBrowserBox->addRow("remove map", _("Remove"));
789 
791  {
792  mBrowserBox->addSeparator("##3---");
793  // TRANSLATORS: popup menu item
794  // TRANSLATORS: warp to map item
795  mBrowserBox->addRow("/slide 'MAPX' 'MAPY'", _("Warp"));
796  }
797  mBrowserBox->addSeparator("##3---");
798  // TRANSLATORS: popup menu item
799  // TRANSLATORS: close menu
800  mBrowserBox->addRow("cancel", _("Cancel"));
801 
802  showPopup(x, y);
803 }
804 
805 void PopupMenu::showMapPopup(const int x, const int y,
806  const int x2, const int y2,
807  const bool isMinimap)
808 {
809  initPopup();
810  mX = x2;
811  mY = y2;
812 
813  if (isMinimap)
815 
817 
818  // TRANSLATORS: popup menu header
819  mBrowserBox->addRow(_("Map Item"), false);
820 
822  {
823  // TRANSLATORS: popup menu item
824  // TRANSLATORS: warp to map item
825  mBrowserBox->addRow("/slide 'MAPX' 'MAPY'", _("Warp"));
826  }
827  // TRANSLATORS: popup menu item
828  // TRANSLATORS: move to map item
829  mBrowserBox->addRow("/navigate 'X' 'Y'", _("Move"));
830  // TRANSLATORS: popup menu item
831  // TRANSLATORS: move camera to map item
832  mBrowserBox->addRow("/movecamera 'X' 'Y'", _("Move camera"));
833  if (settings.cameraMode != 0)
834  {
835  // TRANSLATORS: popup menu item
836  // TRANSLATORS: restore camera to default view
837  mBrowserBox->addRow("/restorecamera", _("Restore camera"));
838  }
839  mBrowserBox->addSeparator("##3---");
840  if (isMinimap)
841  {
842  // TRANSLATORS: popup menu item
843  mBrowserBox->addRow("window close", _("Close"));
844  }
845  mBrowserBox->addSeparator("##3---");
846  // TRANSLATORS: popup menu item
847  // TRANSLATORS: close menu
848  mBrowserBox->addRow("cancel", _("Cancel"));
849 
850  showPopup(x, y);
851 }
852 
853 void PopupMenu::showOutfitsWindowPopup(const int x, const int y)
854 {
855  initPopup();
856  mX = x;
857  mY = y;
859 
861 
862  // TRANSLATORS: popup menu header
863  mBrowserBox->addRow(_("Outfits"), false);
864  // TRANSLATORS: popup menu item
865  // TRANSLATORS: copy selected outfit to chat input
866  mBrowserBox->addRow("/outfittochat", _("Add to chat"));
867  mBrowserBox->addSeparator("##3---");
868  // TRANSLATORS: popup menu item
869  // TRANSLATORS: copy equipment from player to outfit
870  mBrowserBox->addRow("/itemstooutfit", _("Copy from player"));
871  mBrowserBox->addSeparator("##3---");
872  // TRANSLATORS: popup menu item
873  // TRANSLATORS: clear selected outfit
874  mBrowserBox->addRow("/clearoutfit", _("Clear outfit"));
875  mBrowserBox->addSeparator("##3---");
876 
878  mBrowserBox->addSeparator("##3---");
879 
880  // TRANSLATORS: popup menu item
881  // TRANSLATORS: close menu
882  mBrowserBox->addRow("cancel", _("Cancel"));
883 
884  showPopup(x, y);
885 }
886 
887 void PopupMenu::showSpellPopup(const int x, const int y,
888  TextCommand *const cmd)
889 {
890  if (cmd == nullptr)
891  return;
892 
893  initPopup();
895 
896  mSpell = cmd;
897  mX = x;
898  mY = y;
899 
900  // TRANSLATORS: popup menu header
901  mBrowserBox->addRow(_("Spells"), false);
902  // TRANSLATORS: popup menu item
903  // TRANSLATORS: edit selected spell
904  mBrowserBox->addRow("edit spell", _("Edit spell"));
905  mBrowserBox->addSeparator("##3---");
906  // TRANSLATORS: popup menu item
907  // TRANSLATORS: close menu
908  mBrowserBox->addRow("cancel", _("Cancel"));
909 
910  showPopup(x, y);
911 }
912 
913 void PopupMenu::showChatPopup(const int x, const int y, ChatTab *const tab)
914 {
915  if (tab == nullptr ||
916  actorManager == nullptr ||
917  localPlayer == nullptr)
918  {
919  return;
920  }
921 
922  initPopup();
923  mTab = tab;
924  mX = x;
925  mY = y;
927 
929 
930  const ChatTabTypeT &type = tab->getType();
931  if (type == ChatTabType::WHISPER || type == ChatTabType::CHANNEL)
932  {
933  // TRANSLATORS: popup menu item
934  // TRANSLATORS: close chat tab
935  mBrowserBox->addRow("/close", _("Close"));
936  }
937 
938  // TRANSLATORS: popup menu item
939  // TRANSLATORS: remove all text from chat tab
940  mBrowserBox->addRow("/chatclear", _("Clear"));
941  mBrowserBox->addSeparator("##3---");
942 
943  if (tab->getAllowHighlight())
944  {
945  // TRANSLATORS: popup menu item
946  // TRANSLATORS: disable chat tab highlight
947  mBrowserBox->addRow("/disablehighlight", _("Disable highlight"));
948  }
949  else
950  {
951  // TRANSLATORS: popup menu item
952  // TRANSLATORS: enable chat tab highlight
953  mBrowserBox->addRow("/enablehighlight", _("Enable highlight"));
954  }
955  if (tab->getRemoveNames())
956  {
957  // TRANSLATORS: popup menu item
958  // TRANSLATORS: do not remove player names from chat tab
959  mBrowserBox->addRow("/dontremovename", _("Don't remove name"));
960  }
961  else
962  {
963  // TRANSLATORS: popup menu item
964  // TRANSLATORS: remove player names from chat tab
965  mBrowserBox->addRow("/removename", _("Remove name"));
966  }
967  if (tab->getNoAway())
968  {
969  // TRANSLATORS: popup menu item
970  // TRANSLATORS: enable away messages in chat tab
971  mBrowserBox->addRow("/enableaway", _("Enable away"));
972  }
973  else
974  {
975  // TRANSLATORS: popup menu item
976  // TRANSLATORS: disable away messages in chat tab
977  mBrowserBox->addRow("/disableaway", _("Disable away"));
978  }
979  mBrowserBox->addSeparator("##3---");
980  if (type == ChatTabType::PARTY)
981  {
982  // TRANSLATORS: popup menu item
983  // TRANSLATORS: enable away messages in chat tab
984  mBrowserBox->addRow("/leaveparty", _("Leave"));
985  mBrowserBox->addSeparator("##3---");
986  }
987  // TRANSLATORS: popup menu item
988  // TRANSLATORS: copy selected text to clipboard
989  mBrowserBox->addRow("/chatclipboard 'X' 'Y'", _("Copy to clipboard"));
990  mBrowserBox->addSeparator("##3---");
991 
992  if (type == ChatTabType::WHISPER)
993  {
994  const WhisperTab *const wTab = static_cast<WhisperTab*>(tab);
995  const std::string &name = wTab->getNick();
996 
997  const Being* const being = actorManager->findBeingByName(
998  name, ActorType::Player);
999 
1000  addGmCommands();
1001  if (being != nullptr)
1002  {
1003  mBeingId = being->getId();
1004  mName = being->getName();
1005  mExtName = being->getExtName();
1006  mType = being->getType();
1007  mSubType = being->getSubType();
1008 
1009  // TRANSLATORS: popup menu item
1010  // TRANSLATORS: trade with player
1011  mBrowserBox->addRow("/trade 'NAME'", _("Trade"));
1012  // TRANSLATORS: popup menu item
1013  // TRANSLATORS: attack player
1014  mBrowserBox->addRow("/attack 'NAME'", _("Attack"));
1015  addMailCommands();
1016  mBrowserBox->addSeparator("##3---");
1017  // TRANSLATORS: popup menu item
1018  // TRANSLATORS: heal player
1019  mBrowserBox->addRow("/heal :'BEINGID'", _("Heal"));
1020  mBrowserBox->addSeparator("##3---");
1021  addPlayerRelation(name);
1022  mBrowserBox->addSeparator("##3---");
1023  addFollow();
1024  // TRANSLATORS: popup menu item
1025  // TRANSLATORS: move to player position
1026  mBrowserBox->addRow("/navigateto 'NAME'", _("Move"));
1027  addPlayerMisc();
1028  addBuySell(being);
1029  mBrowserBox->addSeparator("##3---");
1030  addParty(wTab->getNick());
1031  const Guild *const guild1 = being->getGuild();
1032  const Guild *const guild2 = localPlayer->getGuild();
1033  if (guild2 != nullptr)
1034  {
1035  if (guild1 != nullptr)
1036  {
1037  if (guild1->getId() == guild2->getId())
1038  {
1039 #ifdef TMWA_SUPPORT
1040  if (guild2->getServerGuild() ||
1041  (guildManager != nullptr &&
1042  guildManager->havePower()))
1043 #endif // TMWA_SUPPORT
1044  {
1045  mBrowserBox->addRow("/kickguild 'NAME'",
1046  // TRANSLATORS: popup menu item
1047  // TRANSLATORS: kick player from guild
1048  _("Kick from guild"));
1049  }
1050  if (guild2->getServerGuild())
1051  {
1052  mBrowserBox->addRow(strprintf("@@guild-pos|%s >@@",
1053  // TRANSLATORS: popup menu item
1054  // TRANSLATORS: change player position in guild
1055  _("Change pos in guild")),
1056  false);
1057  }
1058  }
1059  }
1060  else
1061  {
1062 #ifdef TMWA_SUPPORT
1063  if (guild2->getServerGuild() || (guildManager != nullptr
1064  && guildManager->havePower()))
1065 #endif // TMWA_SUPPORT
1066  {
1067  mBrowserBox->addRow("/guild 'NAME'",
1068  // TRANSLATORS: popup menu item
1069  // TRANSLATORS: invite player to guild
1070  _("Invite to guild"));
1071  }
1072  }
1073  }
1074  }
1075  else
1076  {
1078  mName = name;
1079  mExtName = name;
1082  addPlayerRelation(name);
1083  mBrowserBox->addSeparator("##3---");
1084  addMailCommands();
1085  addFollow();
1086 
1087  if (localPlayer->isInParty())
1088  {
1089  const Party *const party = localPlayer->getParty();
1090  if (party != nullptr)
1091  {
1092  const PartyMember *const m = party->getMember(mName);
1093  if (m != nullptr)
1094  {
1095  // TRANSLATORS: popup menu item
1096  // TRANSLATORS: move to player location
1097  mBrowserBox->addRow("/navigateto 'NAME'", _("Move"));
1098  }
1099  }
1100  }
1101  addPlayerMisc();
1104  addParty(wTab->getNick());
1105  mBrowserBox->addSeparator("##3---");
1106  }
1107  }
1108 
1110  // TRANSLATORS: popup menu item
1111  // TRANSLATORS: close menu
1112  mBrowserBox->addRow("cancel", _("Cancel"));
1113 
1114  showPopup(x, y);
1115 }
1116 
1117 void PopupMenu::showChangePos(const int x, const int y)
1118 {
1119  initPopup();
1121  // TRANSLATORS: popup menu header
1122  mBrowserBox->addRow(_("Change guild position"), false);
1123 
1124  if (localPlayer == nullptr)
1125  return;
1126 
1127  mX = x;
1128  mY = y;
1129  const Guild *const guild = localPlayer->getGuild();
1130  if (guild != nullptr)
1131  {
1132  const PositionsMap &map = guild->getPositions();
1133  FOR_EACH (PositionsMap::const_iterator, itr, map)
1134  {
1135  mBrowserBox->addRow(strprintf("@@guild-pos-%u|%s@@",
1136  itr->first, itr->second.c_str()),
1137  false);
1138  }
1139  // TRANSLATORS: popup menu item
1140  // TRANSLATORS: close menu
1141  mBrowserBox->addRow("cancel", _("Cancel"));
1142 
1143  showPopup(x, y);
1144  }
1145  else
1146  {
1149  mItemIndex = -1;
1150  mItemId = 0;
1151  for (int f = 0; f < maxCards; f ++)
1152  mItemCards[f] = 0;
1153  mMapItem = nullptr;
1154  mName.clear();
1155  mExtName.clear();
1158  mX = 0;
1159  mY = 0;
1161  }
1162 }
1163 
1165 {
1166  if (window == nullptr)
1167  return;
1168 
1169  initPopup();
1170  setMousePos();
1171  mCallerWindow = window;
1173  // TRANSLATORS: popup menu header
1174  mBrowserBox->addRow(_("window"), false);
1175 
1176  addWindowMenu(window);
1177 
1178  // TRANSLATORS: popup menu item
1179  // TRANSLATORS: close menu
1180  mBrowserBox->addRow("cancel", _("Cancel"));
1181 
1182  showPopup(mX, mY);
1183 }
1184 
1185 void PopupMenu::addWindowMenu(const Window *const window)
1186 {
1187  if (window == nullptr)
1188  return;
1189 
1190  initPopup();
1191  if (window->getAlowClose())
1192  {
1193  // TRANSLATORS: popup menu item
1194  // TRANSLATORS: close window
1195  mBrowserBox->addRow("window close", _("Close"));
1196  }
1197 
1198  if (window->isStickyButtonLock())
1199  {
1200  if (window->isSticky())
1201  {
1202  // TRANSLATORS: popup menu item
1203  // TRANSLATORS: unlock window
1204  mBrowserBox->addRow("window unlock", _("Unlock"));
1205  }
1206  else
1207  {
1208  // TRANSLATORS: popup menu item
1209  // TRANSLATORS: lock window
1210  mBrowserBox->addRow("window lock", _("Lock"));
1211  }
1212  }
1213 }
1214 
1216 {
1217  initPopup();
1218  setMousePos();
1219 
1221  // TRANSLATORS: popup menu header
1222  mBrowserBox->addRow(_("Show emotes for:"), false);
1223 
1224  // TRANSLATORS: popup menu item
1225  // TRANSLATORS: show emotes for player
1226  mBrowserBox->addRow("/setemotetype player", _("Player"));
1227 
1228  // TRANSLATORS: popup menu item
1229  // TRANSLATORS: show emotes for pet
1230  mBrowserBox->addRow("/setemotetype pet", _("Pet"));
1231 
1233  {
1234  // TRANSLATORS: popup menu item
1235  // TRANSLATORS: show emotes for homuncules
1236  mBrowserBox->addRow("/setemotetype homun", _("Homunculus"));
1237 
1238  // TRANSLATORS: popup menu item
1239  // TRANSLATORS: show emotes for mercenary
1240  mBrowserBox->addRow("/setemotetype merc", _("Mercenary"));
1241  }
1242  mBrowserBox->addSeparator("##3---");
1243 
1244  // TRANSLATORS: popup menu item
1245  // TRANSLATORS: close menu
1246  mBrowserBox->addRow("cancel", _("Cancel"));
1247 
1248  showPopup(mX, mY);
1249 }
1250 
1251 void PopupMenu::handleLink(const std::string &link,
1252  MouseEvent *event A_UNUSED)
1253 {
1254  Being *being = nullptr;
1255  if (actorManager != nullptr)
1256  being = actorManager->findBeing(mBeingId);
1257 
1258  mAllowCleanMenu = true;
1259 
1260  if (link == "remove map" && (mMapItem != nullptr))
1261  {
1262  if (viewport != nullptr)
1263  {
1264  const Map *const map = viewport->getMap();
1265  if (map != nullptr)
1266  {
1267  SpecialLayer *const specialLayer = map->getSpecialLayer();
1268  if (specialLayer != nullptr)
1269  {
1270  const bool isHome = (mMapItem->getType()
1272  const int x = static_cast<int>(mMapItem->getX());
1273  const int y = static_cast<int>(mMapItem->getY());
1274  specialLayer->setTile(x, y,
1276  specialLayer->updateCache();
1277  if (socialWindow != nullptr)
1279  if (isHome && (localPlayer != nullptr))
1280  {
1283  }
1284  }
1285  }
1286  }
1287  }
1288  else if (link == "rename map" && (mMapItem != nullptr))
1289  {
1292  // TRANSLATORS: dialog caption
1293  // TRANSLATORS: number of chars in string should be near original
1294  _("Rename map sign "),
1295  // TRANSLATORS: label
1296  // TRANSLATORS: number of chars in string should be near original
1297  _("Name: "),
1298  nullptr,
1299  false);
1302  mDialog->setActionEventId("ok");
1304  }
1305  else if (link == "edit spell" && (mSpell != nullptr))
1306  {
1308  }
1309  else if (link == "addcomment" && !mName.empty())
1310  {
1311  TextDialog *const dialog = CREATEWIDGETR(TextDialog,
1312  // TRANSLATORS: dialog caption
1313  // TRANSLATORS: number of chars in string should be near original
1314  _("Player comment "),
1315  // TRANSLATORS: label
1316  // TRANSLATORS: number of chars in string should be near original
1317  _("Comment: "),
1318  nullptr,
1319  false);
1320  mPlayerListener.setDialog(dialog);
1323 
1324  if (being != nullptr)
1325  {
1326  being->updateComment();
1327  dialog->setText(being->getComment());
1328  }
1329  else
1330  {
1332  static_cast<ActorTypeT>(mType)));
1333  }
1334  dialog->setActionEventId("ok");
1336  }
1337  else if (link == "guild-pos" && !mName.empty())
1338  {
1339  showChangePos(getX(), getY());
1340  return;
1341  }
1342  else if (link == "clipboard copy")
1343  {
1344  if (mTextField != nullptr)
1346  }
1347  else if (link == "clipboard paste")
1348  {
1349  if (mTextField != nullptr)
1351  }
1352  else if (link == "gm" && !mName.empty())
1353  {
1354  showGMPopup(mName);
1355  return;
1356  }
1357  else if (link == "mute" && !mName.empty())
1358  {
1359  showMuteCommands();
1360  return;
1361  }
1362  else if (link == "show" && !mName.empty())
1363  {
1364  showPlayerMenu();
1365  return;
1366  }
1367  else if (link == "window close" && (mCallerWindow != nullptr))
1368  {
1370  mCallerWindow->close();
1371  }
1372  else if (link == "window unlock" && (mCallerWindow != nullptr))
1373  {
1375  mCallerWindow->setSticky(false);
1376  }
1377  else if (link == "window lock" && (mCallerWindow != nullptr))
1378  {
1380  mCallerWindow->setSticky(true);
1381  }
1382  else if (link == "join chat" && (being != nullptr))
1383  {
1384  const ChatObject *const chat = being->getChat();
1385  if (chat != nullptr)
1386  chatHandler->joinChat(chat, "");
1387  }
1388  else if (link == "craftmenu")
1389  {
1390  showCraftPopup();
1391  return;
1392  }
1393  else if (link.compare(0, 10, "guild-pos-") == 0)
1394  {
1395  if (localPlayer != nullptr)
1396  {
1397  const Guild *const guild = localPlayer->getGuild();
1398  if (guild != nullptr)
1399  {
1400  const int num = atoi(link.substr(10).c_str());
1402  guild->getMember(mName), num);
1403  }
1404  }
1405  }
1406  else if (link.compare(0, 7, "player_") == 0)
1407  {
1408  if (actorManager != nullptr)
1409  {
1410  mBeingId = fromInt(atoi(link.substr(7).c_str()), BeingId);
1411  being = actorManager->findBeing(mBeingId);
1412  if (being != nullptr)
1413  {
1414  showPopup(getX(), getY(), being);
1415  return;
1416  }
1417  }
1418  }
1419  else if (link.compare(0, 10, "flooritem_") == 0)
1420  {
1421  if (actorManager != nullptr)
1422  {
1423  const BeingId id = fromInt(atoi(
1424  link.substr(10).c_str()), BeingId);
1425  if (id != BeingId_zero)
1426  {
1427  const FloorItem *const item = actorManager->findItem(id);
1428  if (item != nullptr)
1429  {
1430  mFloorItemId = item->getId();
1431  mItemId = item->getItemId();
1432  for (int f = 0; f < maxCards; f ++)
1433  mItemCards[f] = item->getCard(f);
1434  showPopup(getX(), getY(), item);
1435  return;
1436  }
1437  }
1438  }
1439  }
1440  else if (link.compare(0, 12, "hide button_") == 0)
1441  {
1442  if (windowMenu != nullptr)
1443  windowMenu->showButton(link.substr(12), Visible_false);
1444  }
1445  else if (link.compare(0, 12, "show button_") == 0)
1446  {
1447  if (windowMenu != nullptr)
1448  windowMenu->showButton(link.substr(12), Visible_true);
1449  }
1450  else if (link.compare(0, 9, "hide bar_") == 0)
1451  {
1452  if (miniStatusWindow != nullptr)
1453  miniStatusWindow->showBar(link.substr(9), Visible_false);
1454  }
1455  else if (link.compare(0, 9, "show bar_") == 0)
1456  {
1457  if (miniStatusWindow != nullptr)
1458  miniStatusWindow->showBar(link.substr(9), Visible_true);
1459  }
1460  else if (link.compare(0, 12, "show window_") == 0)
1461  {
1462  const int id = atoi(link.substr(12).c_str());
1463  if (id >= 0)
1464  inputManager.executeAction(static_cast<InputActionT>(id));
1465  }
1466  else if (link.compare(0, 6, "mute_+") == 0)
1467  {
1468  if (being != nullptr)
1469  {
1470  const int time = atoi(link.substr(6).c_str());
1471  adminHandler->mute(being, 1, time);
1472  }
1473  }
1474  else if (link.compare(0, 6, "mute_-") == 0)
1475  {
1476  if (being != nullptr)
1477  {
1478  const int time = atoi(link.substr(6).c_str());
1479  adminHandler->mute(being, 0, time);
1480  }
1481  }
1482  else if (!link.empty() && link[0] == '/')
1483  {
1484  std::string cmd = link.substr(1);
1485  replaceAll(cmd, "'NAME'", mName);
1486  replaceAll(cmd, "'ENAME'", escapeString(mName));
1487  replaceAll(cmd, "'EXTNAME'", mExtName);
1488  replaceAll(cmd, "'EEXTNAME'", escapeString(mExtName));
1489  replaceAll(cmd, "'X'", toString(mX));
1490  replaceAll(cmd, "'Y'", toString(mY));
1491  replaceAll(cmd, "'BEINGID'", toString(toInt(mBeingId, int)));
1492  replaceAll(cmd, "'FLOORID'", toString(toInt(mFloorItemId, int)));
1493  replaceAll(cmd, "'ITEMID'", toString(mItemId));
1494  replaceAll(cmd, "'ITEMCOLOR'", toString(toInt(mItemColor, int)));
1495  replaceAll(cmd, "'BEINGTYPEID'", toString(CAST_S32(mType)));
1496  replaceAll(cmd, "'BEINGSUBTYPEID'", toString(CAST_S32(mSubType)));
1497  replaceAll(cmd, "'PLAYER'", localPlayer->getName());
1498  replaceAll(cmd, "'EPLAYER'", escapeString(localPlayer->getName()));
1499  replaceAll(cmd, "'PLAYERX'", toString(localPlayer->getTileX()));
1500  replaceAll(cmd, "'PLAYERY'", toString(localPlayer->getTileY()));
1501  if (mItemIndex >= 0)
1502  replaceAll(cmd, "'INVINDEX'", toString(mItemIndex));
1503  else
1504  replaceAll(cmd, "'INVINDEX'", "0");
1505  if (mMapItem != nullptr)
1506  {
1507  replaceAll(cmd, "'MAPX'", toString(mMapItem->getX()));
1508  replaceAll(cmd, "'MAPY'", toString(mMapItem->getY()));
1509  }
1510  else
1511  {
1512  replaceAll(cmd, "'MAPX'", toString(mX));
1513  replaceAll(cmd, "'MAPY'", toString(mY));
1514  }
1515 
1516  std::string cards;
1517  for (int f = 0; f < maxCards; f ++)
1518  {
1519  const int id = mItemCards[f];
1520  if (id != 0)
1521  {
1522  cards.append(",");
1523  cards.append(toString(id));
1524  }
1525  }
1526  replaceAll(cmd, "'CARDS'", cards);
1527  replaceAll(cmd, "'ECARDS'", escapeString(cards));
1528  if (actorManager != nullptr)
1529  {
1530  if (being == nullptr)
1531  {
1534  }
1535  }
1536  if (being != nullptr)
1537  replaceAll(cmd, "'PARTY'", being->getPartyName());
1538  else
1539  replaceAll(cmd, "'PARTY'", "");
1540 
1541  const size_t pos = cmd.find(' ');
1542  const std::string type(cmd, 0, pos);
1543  std::string args(cmd, pos == std::string::npos ? cmd.size() : pos + 1);
1544  args = trim(args);
1545  inputManager.executeChatCommand(type, args, mTab);
1546  }
1547  // Unknown actions
1548  else if (link != "cancel")
1549  {
1550  reportAlways("PopupMenu: Warning, unknown action '%s'", link.c_str())
1551  }
1552 
1553  if (!mAllowCleanMenu)
1554  return;
1555 
1557 
1560  mItemId = 0;
1561  mItemIndex = -1;
1562  for (int f = 0; f < maxCards; f ++)
1563  mItemCards[f] = 0;
1565  mMapItem = nullptr;
1566  mTab = nullptr;
1567  mSpell = nullptr;
1568  mCallerWindow = nullptr;
1569  mDialog = nullptr;
1570  mButton = nullptr;
1571  mName.clear();
1572  mExtName.clear();
1573  mTextField = nullptr;
1576  mX = 0;
1577  mY = 0;
1578 }
1579 
1580 void PopupMenu::showPopup(Window *const parent,
1581  const int x, const int y,
1582  const Item *const item,
1583  const InventoryTypeT type)
1584 {
1585  if (item == nullptr)
1586  return;
1587 
1588  initPopup();
1589  mItemId = item->getId();
1590  mItemIndex = item->getInvIndex();
1591  for (int f = 0; f < maxCards; f ++)
1592  mItemCards[f] = item->getCard(f);
1593  mItemColor = item->getColor();
1594  mCallerWindow = parent;
1595  mX = x;
1596  mY = y;
1597  mName.clear();
1598  mExtName.clear();
1600 
1601  const int cnt = item->getQuantity();
1602  const bool isProtected = PlayerInfo::isItemProtected(mItemId);
1603 
1604  switch (type)
1605  {
1607  if (tradeWindow != nullptr &&
1609  !isProtected)
1610  {
1611  // TRANSLATORS: popup menu item
1612  // TRANSLATORS: add item to trade
1613  mBrowserBox->addRow("/addtrade 'INVINDEX'", _("Add to trade"));
1614  if (cnt > 1)
1615  {
1616  if (cnt > 10)
1617  {
1618  mBrowserBox->addRow("/addtrade 'INVINDEX' 10",
1619  // TRANSLATORS: popup menu item
1620  // TRANSLATORS: add 10 item amount to trade
1621  _("Add to trade 10"));
1622  }
1623  mBrowserBox->addRow("/addtrade 'INVINDEX' /",
1624  // TRANSLATORS: popup menu item
1625  // TRANSLATORS: add half item amount to trade
1626  _("Add to trade half"));
1627  mBrowserBox->addRow("/addtrade 'INVINDEX' -1",
1628  // TRANSLATORS: popup menu item
1629  // TRANSLATORS: add all amount except one item to trade
1630  _("Add to trade all-1"));
1631  mBrowserBox->addRow("/addtrade 'INVINDEX' all",
1632  // TRANSLATORS: popup menu item
1633  // TRANSLATORS: add all amount item to trade
1634  _("Add to trade all"));
1635  }
1636  mBrowserBox->addSeparator("##3---");
1637  }
1639  {
1640  // TRANSLATORS: popup menu item
1641  // TRANSLATORS: add item to storage
1642  mBrowserBox->addRow("/invtostorage 'INVINDEX'", _("Store"));
1643  if (cnt > 1)
1644  {
1645  if (cnt > 10)
1646  {
1647  mBrowserBox->addRow("/invtostorage 'INVINDEX' 10",
1648  // TRANSLATORS: popup menu item
1649  // TRANSLATORS: add 10 item amount to storage
1650  _("Store 10"));
1651  }
1652  mBrowserBox->addRow("/invtostorage 'INVINDEX' /",
1653  // TRANSLATORS: popup menu item
1654  // TRANSLATORS: add half item amount to storage
1655  _("Store half"));
1656  mBrowserBox->addRow("/invtostorage 'INVINDEX' -1",
1657  // TRANSLATORS: popup menu item
1658  // TRANSLATORS: add all except one item to storage
1659  _("Store all-1"));
1660  mBrowserBox->addRow("/invtostorage 'INVINDEX' all",
1661  // TRANSLATORS: popup menu item
1662  // TRANSLATORS: add all item amount to storage
1663  _("Store all"));
1664  }
1665  mBrowserBox->addSeparator("##3---");
1666  }
1667  if (npcHandler != nullptr)
1668  {
1669  NpcDialog *const dialog = npcHandler->getCurrentNpcDialog();
1670  if ((dialog != nullptr) &&
1672  {
1673  mBrowserBox->addRow("craftmenu",
1674  // TRANSLATORS: popup menu item
1675  // TRANSLATORS: sub menu for craft
1676  _("Move to craft..."));
1677  }
1678  }
1680  addDrop(item, isProtected);
1681  break;
1682 
1684  // TRANSLATORS: popup menu item
1685  // TRANSLATORS: get item from storage
1686  mBrowserBox->addRow("/storagetoinv 'INVINDEX'", _("Retrieve"));
1687  if (cnt > 1)
1688  {
1689  if (cnt > 10)
1690  {
1691  mBrowserBox->addRow("/storagetoinv 'INVINDEX' 10",
1692  // TRANSLATORS: popup menu item
1693  // TRANSLATORS: get 10 item amount from storage
1694  _("Retrieve 10"));
1695  }
1696  mBrowserBox->addRow("/storagetoinv 'INVINDEX' /",
1697  // TRANSLATORS: popup menu item
1698  // TRANSLATORS: get half item amount from storage
1699  _("Retrieve half"));
1700  mBrowserBox->addRow("/storagetoinv 'INVINDEX' -1",
1701  // TRANSLATORS: popup menu item
1702  // TRANSLATORS: get all except one item amount from storage
1703  _("Retrieve all-1"));
1704  mBrowserBox->addRow("/storagetoinv 'INVINDEX' all",
1705  // TRANSLATORS: popup menu item
1706  // TRANSLATORS: get all item amount from storage
1707  _("Retrieve all"));
1708  mBrowserBox->addSeparator("##3---");
1709  }
1711  break;
1712  case InventoryType::Cart:
1714  break;
1715 
1716  case InventoryType::Trade:
1717  case InventoryType::Npc:
1721  case InventoryType::Craft:
1723  default:
1724  break;
1725  }
1726 
1727 
1728  addProtection();
1729  if (config.getBoolValue("enablePickupFilter"))
1730  {
1731  mName = item->getName();
1732  mExtName = mName;
1733  mBrowserBox->addSeparator("##3---");
1735  }
1736  addGmCommands();
1737  // TRANSLATORS: popup menu item
1738  // TRANSLATORS: add item name to chat
1739  mBrowserBox->addRow("/addchat 'ITEMID''CARDS'", _("Add to chat"));
1740  mBrowserBox->addSeparator("##3---");
1741  // TRANSLATORS: popup menu item
1742  // TRANSLATORS: close menu
1743  mBrowserBox->addRow("cancel", _("Cancel"));
1744 
1745  showPopup(x, y);
1746 }
1747 
1748 void PopupMenu::showItemPopup(const int x, const int y,
1749  const int itemId,
1750  const ItemColor color)
1751 {
1752  const Inventory *const inv = PlayerInfo::getInventory();
1753  if (inv == nullptr)
1754  return;
1755 
1756  Item *const item = inv->findItem(itemId, color);
1757  if (item != nullptr)
1758  {
1759  showItemPopup(x, y, item);
1760  }
1761  else
1762  {
1763  initPopup();
1764  mItemId = itemId;
1765  mItemIndex = -1;
1766  mItemColor = color;
1767  for (int f = 0; f < maxCards; f ++)
1768  mItemCards[f] = 0;
1769  mX = x;
1770  mY = y;
1772 
1774  {
1775  // TRANSLATORS: popup menu item
1776  // TRANSLATORS: use item
1777  mBrowserBox->addRow("/use 'ITEMID'", _("Use"));
1778  }
1779  addProtection();
1780  addGmCommands();
1781  mBrowserBox->addSeparator("##3---");
1782  // TRANSLATORS: popup menu item
1783  // TRANSLATORS: close menu
1784  mBrowserBox->addRow("cancel", _("Cancel"));
1785 
1786  showPopup(x, y);
1787  }
1788 }
1789 
1790 void PopupMenu::showItemPopup(const int x, const int y,
1791  const Item *const item)
1792 {
1793  initPopup();
1794  mX = x;
1795  mY = y;
1796  if (item != nullptr)
1797  {
1798  mItemId = item->getId();
1799  mItemColor = item->getColor();
1800  mItemIndex = item->getInvIndex();
1801  for (int f = 0; f < maxCards; f ++)
1802  mItemCards[f] = item->getCard(f);
1803  }
1804  else
1805  {
1806  mItemId = 0;
1808  mItemIndex = -1;
1809  for (int f = 0; f < maxCards; f ++)
1810  mItemCards[f] = 0;
1811  }
1812  mName.clear();
1813  mExtName.clear();
1815 
1816  if (item != nullptr)
1817  {
1818  const bool isProtected = PlayerInfo::isItemProtected(mItemId);
1819  addUse(item);
1820  addDrop(item, isProtected);
1822  {
1823  // TRANSLATORS: popup menu item
1824  // TRANSLATORS: add item to storage
1825  mBrowserBox->addRow("/invtostorage 'INVINDEX'", _("Store"));
1826  }
1827  // TRANSLATORS: popup menu item
1828  // TRANSLATORS: add item name to chat
1829  mBrowserBox->addRow("/addchat 'ITEMID''CARDS'", _("Add to chat"));
1830 
1831  if (config.getBoolValue("enablePickupFilter"))
1832  {
1833  mName = item->getName();
1834  mExtName = mName;
1835  mBrowserBox->addSeparator("##3---");
1837  }
1838  }
1839  addProtection();
1840  addGmCommands();
1841  mBrowserBox->addSeparator("##3---");
1842  // TRANSLATORS: popup menu item
1843  // TRANSLATORS: close menu
1844  mBrowserBox->addRow("cancel", _("Cancel"));
1845 
1846  showPopup(x, y);
1847 }
1848 
1850  const int y,
1851  const Item *const item)
1852 {
1853  initPopup();
1854  mX = x;
1855  mY = y;
1856  mName.clear();
1857  mExtName.clear();
1859 
1860  if (item != nullptr)
1861  {
1862  mItemId = item->getId();
1863  mItemColor = item->getColor();
1864  mItemIndex = item->getInvIndex();
1865  for (int f = 0; f < maxCards; f ++)
1866  mItemCards[f] = item->getCard(f);
1867  const bool isProtected = PlayerInfo::isItemProtected(mItemId);
1868  addUse(item);
1869  addDrop(item, isProtected);
1871  {
1872  // TRANSLATORS: popup menu item
1873  // TRANSLATORS: add item to storage
1874  mBrowserBox->addRow("/invtostorage 'INVINDEX'", _("Store"));
1875  }
1876  addProtection();
1877  // TRANSLATORS: popup menu item
1878  // TRANSLATORS: add item name to chat
1879  mBrowserBox->addRow("/addchat 'ITEMID''CARDS'", _("Add to chat"));
1880  if (config.getBoolValue("enablePickupFilter"))
1881  {
1882  mName = item->getName();
1883  mExtName = mName;
1884  mBrowserBox->addSeparator("##3---");
1886  }
1887  }
1888  addGmCommands();
1889  mBrowserBox->addSeparator("##3---");
1890  // TRANSLATORS: popup menu item
1891  mBrowserBox->addRow("/cleardrops", _("Clear drop window"));
1892  mBrowserBox->addSeparator("##3---");
1893  // TRANSLATORS: popup menu item
1894  // TRANSLATORS: close menu
1895  mBrowserBox->addRow("cancel", _("Cancel"));
1896 
1897  showPopup(x, y);
1898 }
1899 
1900 void PopupMenu::showPopup(const int x, const int y, Button *const button)
1901 {
1902  if ((button == nullptr) || (windowMenu == nullptr))
1903  return;
1904 
1905  initPopup();
1906  mButton = button;
1907  mX = x;
1908  mY = y;
1909 
1911  STD_VECTOR<Button *> names = windowMenu->getButtons();
1912  for (STD_VECTOR<Button *>::const_iterator it = names.begin(),
1913  it_end = names.end(); it != it_end; ++ it)
1914  {
1915  const Button *const btn = *it;
1916  if ((btn == nullptr) || btn->getActionEventId() == "SET")
1917  continue;
1918 
1919  if (btn->mVisible == Visible_true)
1920  {
1921  mBrowserBox->addRow(strprintf("@@hide button_%s|%s %s (%s)@@",
1922  // TRANSLATORS: popup menu item
1923  btn->getActionEventId().c_str(), _("Hide"),
1924  btn->getDescription().c_str(), btn->getCaption().c_str()),
1925  false);
1926  }
1927  else
1928  {
1929  mBrowserBox->addRow(strprintf("@@show button_%s|%s %s (%s)@@",
1930  // TRANSLATORS: popup menu item
1931  btn->getActionEventId().c_str(), _("Show"),
1932  btn->getDescription().c_str(), btn->getCaption().c_str()),
1933  false);
1934  }
1935  }
1936  mBrowserBox->addSeparator("##3---");
1937  // TRANSLATORS: popup menu item
1938  // TRANSLATORS: close menu
1939  mBrowserBox->addRow("cancel", _("Cancel"));
1940 
1941  showPopup(x, y);
1942 }
1943 
1944 void PopupMenu::showPopup(const int x, const int y, const ProgressBar *const b)
1945 {
1946  if ((b == nullptr) || (miniStatusWindow == nullptr))
1947  return;
1948 
1949  initPopup();
1950  mName = b->text();
1951  mExtName = mName;
1952  mX = x;
1953  mY = y;
1954 
1956  STD_VECTOR <ProgressBar*> bars = miniStatusWindow->getBars();
1957  ProgressBar *onlyBar = nullptr;
1958  int cnt = 0;
1959 
1960  // search for alone visible bar
1961  for (STD_VECTOR <ProgressBar*>::const_iterator it = bars.begin(),
1962  it_end = bars.end(); it != it_end; ++it)
1963  {
1964  ProgressBar *const bar = *it;
1965  if (bar == nullptr)
1966  continue;
1967 
1968  if (bar->mVisible == Visible_true)
1969  {
1970  cnt ++;
1971  onlyBar = bar;
1972  }
1973  }
1974  if (cnt > 1)
1975  onlyBar = nullptr;
1976 
1977  for (STD_VECTOR <ProgressBar*>::const_iterator it = bars.begin(),
1978  it_end = bars.end(); it != it_end; ++it)
1979  {
1980  ProgressBar *const bar = *it;
1981  if ((bar == nullptr) || bar == onlyBar)
1982  continue;
1983 
1984  if (bar->mVisible == Visible_true)
1985  {
1986  mBrowserBox->addRow(strprintf("@@hide bar_%s|%s %s@@",
1987  // TRANSLATORS: popup menu item
1988  bar->getActionEventId().c_str(), _("Hide"),
1989  bar->getId().c_str()),
1990  false);
1991  }
1992  else
1993  {
1994  mBrowserBox->addRow(strprintf("@@show bar_%s|%s %s@@",
1995  // TRANSLATORS: popup menu item
1996  bar->getActionEventId().c_str(), _("Show"),
1997  bar->getId().c_str()),
1998  false);
1999  }
2000  }
2001 
2002  mBrowserBox->addSeparator("##3---");
2003  // TRANSLATORS: popup menu item
2004  mBrowserBox->addRow("/yellowbar", _("Open yellow bar settings"));
2005  // TRANSLATORS: popup menu item
2006  mBrowserBox->addRow("/resetmodifiers", _("Reset yellow bar"));
2007  mBrowserBox->addSeparator("##3---");
2008  // TRANSLATORS: popup menu item
2009  // TRANSLATORS: copy status to chat
2010  mBrowserBox->addRow("/bartochat 'NAME'", _("Copy to chat"));
2011  // TRANSLATORS: popup menu item
2012  // TRANSLATORS: close menu
2013  mBrowserBox->addRow("cancel", _("Cancel"));
2014 
2015  showPopup(x, y);
2016 }
2017 
2018 void PopupMenu::showAttackMonsterPopup(const int x, const int y,
2019  const std::string &name,
2020  const int type)
2021 {
2022  if ((localPlayer == nullptr) || (actorManager == nullptr))
2023  return;
2024 
2025  initPopup();
2026  mName = name;
2027  mExtName = name;
2030  mX = x;
2031  mY = y;
2032 
2034 
2035  if (name.empty())
2036  {
2037  // TRANSLATORS: popup menu header
2038  mBrowserBox->addRow(_("(default)"), false);
2039  }
2040  else
2041  {
2042  mBrowserBox->addRow(name, false);
2043  }
2044  switch (type)
2045  {
2046  case MapItemType::ATTACK:
2047  {
2048  const int idx = actorManager->getAttackMobIndex(name);
2049  const int size = actorManager->getAttackMobsSize();
2050  if (idx > 0)
2051  {
2052  // TRANSLATORS: popup menu item
2053  // TRANSLATORS: move attack target up
2054  mBrowserBox->addRow("/moveattackup 'NAME'", _("Move up"));
2055  }
2056  if (idx + 1 < size)
2057  {
2058  // TRANSLATORS: popup menu item
2059  // TRANSLATORS: move attack target down
2060  mBrowserBox->addRow("/moveattackdown 'NAME'", _("Move down"));
2061  }
2062  break;
2063  }
2064  case MapItemType::PRIORITY:
2065  {
2066  const int idx = actorManager->
2067  getPriorityAttackMobIndex(name);
2069  if (idx > 0)
2070  {
2071  mBrowserBox->addRow("/movepriorityattackup 'NAME'",
2072  // TRANSLATORS: popup menu item
2073  // TRANSLATORS: move attack target up
2074  _("Move up"));
2075  }
2076  if (idx + 1 < size)
2077  {
2078  mBrowserBox->addRow("/movepriorityattackdown 'NAME'",
2079  // TRANSLATORS: popup menu item
2080  // TRANSLATORS: move attack target down
2081  _("Move down"));
2082  }
2083  break;
2084  }
2085  case MapItemType::IGNORE_:
2086  default:
2087  break;
2088  }
2089 
2090  // TRANSLATORS: popup menu item
2091  // TRANSLATORS: remove attack target
2092  mBrowserBox->addRow("/removeattack 'NAME'", _("Remove"));
2093  mBrowserBox->addSeparator("##3---");
2094  // TRANSLATORS: popup menu item
2095  // TRANSLATORS: close menu
2096  mBrowserBox->addRow("cancel", _("Cancel"));
2097 
2098  showPopup(x, y);
2099 }
2100 
2101 void PopupMenu::showPickupItemPopup(const int x, const int y,
2102  const std::string &name)
2103 {
2104  if ((localPlayer == nullptr) || (actorManager == nullptr))
2105  return;
2106 
2107  initPopup();
2108  mName = name;
2109  mExtName = name;
2112  mX = x;
2113  mY = y;
2114 
2116 
2117  if (name.empty())
2118  {
2119  // TRANSLATORS: popup menu header
2120  mBrowserBox->addRow(_("(default)"), false);
2121  }
2122  else
2123  {
2124  mBrowserBox->addRow(name, false);
2125  }
2126 
2127  // TRANSLATORS: popup menu item
2128  // TRANSLATORS: remove item from pickup filter
2129  mBrowserBox->addRow("/removepickup 'NAME'", _("Remove"));
2130  mBrowserBox->addSeparator("##3---");
2131  // TRANSLATORS: popup menu item
2132  // TRANSLATORS: close menu
2133  mBrowserBox->addRow("cancel", _("Cancel"));
2134 
2135  showPopup(x, y);
2136 }
2137 
2138 void PopupMenu::showUndressPopup(const int x, const int y,
2139  const Being *const being,
2140  const Item *const item)
2141 {
2142  if ((being == nullptr) || (item == nullptr))
2143  return;
2144 
2145  initPopup();
2146  mBeingId = being->getId();
2147  mItemId = item->getId();
2148  mItemColor = item->getColor();
2149  mItemIndex = item->getInvIndex();
2150  for (int f = 0; f < maxCards; f ++)
2151  mItemCards[f] = item->getCard(f);
2152  mX = x;
2153  mY = y;
2154 
2156 
2157  // TRANSLATORS: popup menu item
2158  // TRANSLATORS: undress item from player
2159  mBrowserBox->addRow("/undress :'BEINGID' 'ITEMID'", _("Undress"));
2160  // TRANSLATORS: popup menu item
2161  // TRANSLATORS: add item name to chat
2162  mBrowserBox->addRow("/addchat 'ITEMID''CARDS'", _("Add to chat"));
2163  addGmCommands();
2164  mBrowserBox->addSeparator("##3---");
2165  // TRANSLATORS: popup menu item
2166  // TRANSLATORS: close menu
2167  mBrowserBox->addRow("cancel", _("Cancel"));
2168 
2169  showPopup(x, y);
2170 }
2171 
2173 {
2174  initPopup();
2175  setMousePos();
2176  mTextField = input;
2177 
2179 
2180  // TRANSLATORS: popup menu item
2181  // TRANSLATORS: copy text to clipboard
2182  mBrowserBox->addRow("clipboard copy", _("Copy"));
2183  // TRANSLATORS: popup menu item
2184  // TRANSLATORS: paste text from clipboard
2185  mBrowserBox->addRow("clipboard paste", _("Paste"));
2186  mBrowserBox->addSeparator("##3---");
2187  // TRANSLATORS: popup menu item
2188  // TRANSLATORS: close menu
2189  mBrowserBox->addRow("cancel", _("Cancel"));
2190 
2191  showPopup(mX, mY);
2192 }
2193 
2194 void PopupMenu::showLinkPopup(const std::string &link)
2195 {
2196  initPopup();
2197  setMousePos();
2198  mName = link;
2199  mExtName = link;
2200 
2202 
2203  // TRANSLATORS: popup menu item
2204  // TRANSLATORS: open link in browser
2205  mBrowserBox->addRow("/open 'NAME'", _("Open link"));
2206  // TRANSLATORS: popup menu item
2207  // TRANSLATORS: copy link to clipboard
2208  mBrowserBox->addRow("/clipboardcopy 'NAME'", _("Copy to clipboard"));
2209  mBrowserBox->addSeparator("##3---");
2210  // TRANSLATORS: popup menu item
2211  // TRANSLATORS: close menu
2212  mBrowserBox->addRow("cancel", _("Cancel"));
2213 
2214  showPopup(mX, mY);
2215 }
2216 
2218 {
2219  initPopup();
2220  setMousePos();
2222  const STD_VECTOR<ButtonText*> &names = windowMenu->getButtonTexts();
2223  // TRANSLATORS: popup menu header
2224  mBrowserBox->addRow(_("Show window"), false);
2225 
2226  FOR_EACH (STD_VECTOR<ButtonText*>::const_iterator, it, names)
2227  {
2228  const ButtonText *const btn = *it;
2229  if (btn == nullptr)
2230  continue;
2231 
2232  mBrowserBox->addRow(strprintf("show window_%d",
2233  CAST_S32(btn->key)),
2234  btn->text.c_str());
2235  }
2236  mBrowserBox->addSeparator("##3---");
2237  // TRANSLATORS: popup menu item
2238  // TRANSLATORS: close menu
2239  mBrowserBox->addRow("cancel", _("Cancel"));
2240 
2241  showPopup(mX, mY);
2242 }
2243 
2245  const int x, const int y)
2246 {
2247  initPopup();
2248  mBeingId = npcId;
2249  mX = x;
2250  mY = y;
2252  // TRANSLATORS: popup menu item
2253  // TRANSLATORS: copy npc text to clipboard
2254  mBrowserBox->addRow("/npcclipboard 'X' 'Y'", _("Copy to clipboard"));
2255  mBrowserBox->addSeparator("##3---");
2256  // TRANSLATORS: popup menu item
2257  // TRANSLATORS: close menu
2258  mBrowserBox->addRow("cancel", _("Cancel"));
2259 
2260  showPopup(x, y);
2261 }
2262 
2264 {
2265  if (info == nullptr)
2266  return;
2267 
2268  initPopup();
2269  setMousePos();
2270 
2271  // using mItemId as skill id
2272  mItemId = info->id;
2273  // using mItemIndex as skill level
2274  mItemIndex = info->level;
2276 
2277  // TRANSLATORS: popup menu header
2278  mBrowserBox->addRow(_("Skill"), false);
2279  mBrowserBox->addRow("/addskillshortcut 'ITEMID'",
2280  // TRANSLATORS: popup menu item
2281  // TRANSLATORS: add skill to shortcurs tab
2282  _("Add skill shortcut"));
2283  mBrowserBox->addSeparator("##3---");
2284  mBrowserBox->addRow("/showskilllevels 'ITEMID'",
2285  // TRANSLATORS: popup menu item
2286  // TRANSLATORS: set skill level
2287  _("Skill level..."));
2288  mBrowserBox->addRow("/showskilltypes 'ITEMID'",
2289  // TRANSLATORS: popup menu item
2290  // TRANSLATORS: set skill cast type
2291  _("Skill cast type..."));
2292  mBrowserBox->addRow("/showskilloffsetx 'ITEMID'",
2293  // TRANSLATORS: popup menu item
2294  // TRANSLATORS: set skill cast offset by x
2295  _("Skill offset by x..."));
2296  mBrowserBox->addRow("/showskilloffsety 'ITEMID'",
2297  // TRANSLATORS: popup menu item
2298  // TRANSLATORS: set skill cast offset by y
2299  _("Skill offset by y..."));
2300  // TRANSLATORS: popup menu item
2301  // TRANSLATORS: close menu
2302  mBrowserBox->addRow("cancel", _("Cancel"));
2303 
2304  showPopup(mX, mY);
2305 }
2306 
2308  const bool isOffsetX)
2309 {
2310  if (info == nullptr)
2311  return;
2312 
2313  initPopup();
2314  setMousePos2();
2315 
2316  // using mItemId as skill id
2317  mItemId = info->id;
2318  // using mItemIndex as skill level
2319  mItemIndex = info->level;
2321  char letter = ' ';
2322 
2323  if (isOffsetX)
2324  {
2325  // TRANSLATORS: popup menu header
2326  mBrowserBox->addRow(_("Skill cast offset by x"), false);
2327  letter = 'x';
2328  }
2329  else
2330  {
2331  // TRANSLATORS: popup menu header
2332  mBrowserBox->addRow(_("Skill cast offset by y"), false);
2333  letter = 'y';
2334  }
2335  for (int f = -9; f <= 9; f ++)
2336  {
2337  const std::string command = strprintf(
2338  "/setskilloffset%c 'ITEMID' %d", letter, f);
2339  if (f == 0)
2340  {
2341  mBrowserBox->addRow(command,
2342  strprintf("%d", f).c_str());
2343  }
2344  else
2345  {
2346  mBrowserBox->addRow(command,
2347  strprintf("%+d", f).c_str());
2348  }
2349  }
2350  // TRANSLATORS: popup menu item
2351  // TRANSLATORS: close menu
2352  mBrowserBox->addRow("cancel", _("Cancel"));
2353  showPopup(mX, mY);
2354 }
2355 
2357 {
2358  if (info == nullptr)
2359  return;
2360 
2361  initPopup();
2362  setMousePos2();
2363 
2364  // using mItemId as skill id
2365  mItemId = info->id;
2366  // using mItemIndex as skill level
2367  mItemIndex = info->level;
2368 
2369  for (int f = 0; f < maxCards; f ++)
2370  mItemCards[f] = 0;
2372  // TRANSLATORS: popup menu item
2373  // TRANSLATORS: skill level header
2374  mBrowserBox->addRow(_("Select skill level"), false);
2375  for (int f = 1; f <= mItemIndex; f ++)
2376  {
2377  mBrowserBox->addRow(strprintf("/selectskilllevel %d %d", mItemId, f),
2378  // TRANSLATORS: popup menu item
2379  // TRANSLATORS: skill level
2380  strprintf(_("Level: %d"), f).c_str());
2381  }
2382  mBrowserBox->addRow(strprintf("/selectskilllevel %d 0", mItemId),
2383  // TRANSLATORS: popup menu item
2384  // TRANSLATORS: skill level
2385  _("Max level"));
2386  mBrowserBox->addSeparator("##3---");
2387  // TRANSLATORS: popup menu item
2388  // TRANSLATORS: close menu
2389  mBrowserBox->addRow("cancel", _("Cancel"));
2390 
2391  showPopup(mX, mY);
2392 }
2393 
2395 {
2396  if (info == nullptr)
2397  return;
2398 
2399  initPopup();
2400  setMousePos2();
2401 
2402  // using mItemId as skill id
2403  mItemId = info->id;
2404  // using mItemIndex as skill level
2405  mItemIndex = info->level;
2406 
2407  for (int f = 0; f < maxCards; f ++)
2408  mItemCards[f] = 0;
2410 
2411  // TRANSLATORS: popup menu item
2412  // TRANSLATORS: skill cast type header
2413  mBrowserBox->addRow(_("Select skill cast type"), false);
2414  mBrowserBox->addRow(strprintf("/selectskilltype %d 0", mItemId),
2415  // TRANSLATORS: popup menu item
2416  // TRANSLATORS: skill cast type
2417  _("Default"));
2418  mBrowserBox->addRow(strprintf("/selectskilltype %d 1", mItemId),
2419  // TRANSLATORS: popup menu item
2420  // TRANSLATORS: skill cast type
2421  _("Target"));
2422  mBrowserBox->addRow(strprintf("/selectskilltype %d 2", mItemId),
2423  // TRANSLATORS: popup menu item
2424  // TRANSLATORS: skill cast type
2425  _("Mouse position"));
2426  mBrowserBox->addRow(strprintf("/selectskilltype %d 3", mItemId),
2427  // TRANSLATORS: popup menu item
2428  // TRANSLATORS: skill cast type
2429  _("Self"));
2430  mBrowserBox->addSeparator("##3---");
2431  // TRANSLATORS: popup menu item
2432  // TRANSLATORS: close menu
2433  mBrowserBox->addRow("cancel", _("Cancel"));
2434 
2435  showPopup(mX, mY);
2436 }
2437 
2438 void PopupMenu::showPopup(int x, int y)
2439 {
2441  const int pad2 = 2 * mPadding;
2445  // add padding to initial size before draw browserbox
2446  int height = mBrowserBox->getHeight();
2447  if (height + pad2 >= mainGraphics->getHeight())
2448  {
2449  height = mainGraphics->getHeight() - pad2;
2451  mScrollArea->setWidth(mBrowserBox->getWidth() + pad2 + 10);
2452  setContentSize(mBrowserBox->getWidth() + pad2 + 20,
2453  height + pad2);
2454  }
2455  else
2456  {
2460  height + pad2);
2461  }
2462  if (mainGraphics->mWidth < (x + getWidth() + 5))
2463  x = mainGraphics->mWidth - getWidth();
2464  if (mainGraphics->mHeight < (y + getHeight() + 5))
2466  mScrollArea->setHeight(height);
2467  setPosition(x, y);
2469  requestMoveToTop();
2470  mAllowCleanMenu = false;
2471 }
2472 
2474 {
2475  // TRANSLATORS: popup menu item
2476  // TRANSLATORS: add player to disregarded list
2477  mBrowserBox->addRow("/disregard 'NAME'", _("Disregard"));
2478  // TRANSLATORS: popup menu item
2479  // TRANSLATORS: add player to ignore list
2480  mBrowserBox->addRow("/ignore 'NAME'", _("Ignore"));
2481  // TRANSLATORS: popup menu item
2482  // TRANSLATORS: add player to black list
2483  mBrowserBox->addRow("/blacklist 'NAME'", _("Black list"));
2484  // TRANSLATORS: popup menu item
2485  // TRANSLATORS: add player to enemy list
2486  mBrowserBox->addRow("/enemy 'NAME'", _("Set as enemy"));
2487  // TRANSLATORS: popup menu item
2488  // TRANSLATORS: add player to erased list
2489  mBrowserBox->addRow("/erase 'NAME'", _("Erase"));
2490 }
2491 
2492 void PopupMenu::addPlayerRelation(const std::string &name)
2493 {
2494  switch (playerRelations.getRelation(name))
2495  {
2496  case Relation::NEUTRAL:
2497  // TRANSLATORS: popup menu item
2498  // TRANSLATORS: add player to friends list
2499  mBrowserBox->addRow("/friend 'NAME'", _("Be friend"));
2501  break;
2502 
2503  case Relation::FRIEND:
2505  break;
2506 
2507  case Relation::BLACKLISTED:
2508  // TRANSLATORS: popup menu item
2509  // TRANSLATORS: remove player from ignore list
2510  mBrowserBox->addRow("/unignore 'NAME'", _("Unignore"));
2511  // TRANSLATORS: popup menu item
2512  // TRANSLATORS: add player to disregarded list
2513  mBrowserBox->addRow("/disregard 'NAME'", _("Disregard"));
2514  // TRANSLATORS: popup menu item
2515  // TRANSLATORS: add player to ignore list
2516  mBrowserBox->addRow("/ignore 'NAME'", _("Ignore"));
2517  // TRANSLATORS: popup menu item
2518  // TRANSLATORS: add player to enemy list
2519  mBrowserBox->addRow("/enemy 'NAME'", _("Set as enemy"));
2520  // TRANSLATORS: popup menu item
2521  // TRANSLATORS: add player to erased list
2522  mBrowserBox->addRow("/erase 'NAME'", _("Erase"));
2523  break;
2524 
2525  case Relation::DISREGARDED:
2526  // TRANSLATORS: popup menu item
2527  // TRANSLATORS: remove player from ignore list
2528  mBrowserBox->addRow("/unignore 'NAME'", _("Unignore"));
2529  // TRANSLATORS: popup menu item
2530  // TRANSLATORS: add player to completle ignore list
2531  mBrowserBox->addRow("/ignore 'NAME'", _("Completely ignore"));
2532  // TRANSLATORS: popup menu item
2533  // TRANSLATORS: add player to erased list
2534  mBrowserBox->addRow("/erase 'NAME'", _("Erase"));
2535  break;
2536 
2537  case Relation::IGNORED:
2538  // TRANSLATORS: popup menu item
2539  // TRANSLATORS: remove player from ignore list
2540  mBrowserBox->addRow("/unignore 'NAME'", _("Unignore"));
2541  // TRANSLATORS: popup menu item
2542  // TRANSLATORS: add player to erased list
2543  mBrowserBox->addRow("/erase 'NAME'", _("Erase"));
2544  break;
2545 
2546  case Relation::ENEMY2:
2547  // TRANSLATORS: popup menu item
2548  // TRANSLATORS: remove player from ignore list
2549  mBrowserBox->addRow("/unignore 'NAME'", _("Unignore"));
2550  // TRANSLATORS: popup menu item
2551  // TRANSLATORS: add player to disregarded list
2552  mBrowserBox->addRow("/disregard 'NAME'", _("Disregard"));
2553  // TRANSLATORS: popup menu item
2554  // TRANSLATORS: add player to ignore list
2555  mBrowserBox->addRow("/ignore 'NAME'", _("Ignore"));
2556  // TRANSLATORS: popup menu item
2557  // TRANSLATORS: add player to black list
2558  mBrowserBox->addRow("/blacklist 'NAME'", _("Black list"));
2559  // TRANSLATORS: popup menu item
2560  // TRANSLATORS: add player to erased list
2561  mBrowserBox->addRow("/erase 'NAME'", _("Erase"));
2562  break;
2563 
2564  case Relation::ERASED:
2565  // TRANSLATORS: popup menu item
2566  // TRANSLATORS: remove player from ignore list
2567  mBrowserBox->addRow("/unignore 'NAME'", _("Unignore"));
2568  // TRANSLATORS: popup menu item
2569  // TRANSLATORS: add player to disregarded list
2570  mBrowserBox->addRow("/disregard 'NAME'", _("Disregard"));
2571  // TRANSLATORS: popup menu item
2572  // TRANSLATORS: add player to ignore list
2573  mBrowserBox->addRow("/ignore 'NAME'", _("Completely ignore"));
2574  break;
2575 
2576  default:
2577  break;
2578  }
2579 }
2580 
2582 {
2583  if (features.getBoolValue("allowFollow"))
2584  {
2585  // TRANSLATORS: popup menu item
2586  mBrowserBox->addRow("/follow 'NAME'", _("Follow"));
2587  }
2588  // TRANSLATORS: popup menu item
2589  // TRANSLATORS: imitate player
2590  mBrowserBox->addRow("/imitation 'NAME'", _("Imitate"));
2591 }
2592 
2593 void PopupMenu::addBuySell(const Being *const being)
2594 {
2596  {
2597  mBrowserBox->addSeparator("##3---");
2598  const bool haveVending =
2600  if (being->isSellShopEnabled())
2601  {
2602  // TRANSLATORS: popup menu item
2603  // TRANSLATORS: buy item
2604  mBrowserBox->addRow("/buy 'NAME'", _("Buy"));
2605  }
2606  else if (!haveVending)
2607  {
2608  // TRANSLATORS: popup menu item
2609  // TRANSLATORS: buy item
2610  mBrowserBox->addRow("/buy 'NAME'", _("Buy (?)"));
2611  }
2612  if (being->isBuyShopEnabled())
2613  {
2614  // TRANSLATORS: popup menu item
2615  // TRANSLATORS: sell item
2616  mBrowserBox->addRow("/sell 'NAME'", _("Sell"));
2617  }
2618  else if (!haveVending)
2619  {
2620  // TRANSLATORS: popup menu item
2621  // TRANSLATORS: sell item
2622  mBrowserBox->addRow("/sell 'NAME'", _("Sell (?)"));
2623  }
2624  }
2625 }
2626 
2628 {
2630  {
2631  mBrowserBox->addSeparator("##3---");
2632  // TRANSLATORS: popup menu item
2633  // TRANSLATORS: buy item
2634  mBrowserBox->addRow("/buy 'NAME'", _("Buy (?)"));
2635  // TRANSLATORS: popup menu item
2636  // TRANSLATORS: sell item
2637  mBrowserBox->addRow("/sell 'NAME'", _("Sell (?)"));
2638  }
2639 }
2640 
2641 void PopupMenu::addPartyName(const std::string &partyName)
2642 {
2643  if (localPlayer->isInParty())
2644  {
2645  if (localPlayer->getParty() != nullptr)
2646  {
2647  if (localPlayer->getParty()->getName() != partyName)
2648  {
2649  // TRANSLATORS: popup menu item
2650  // TRANSLATORS: invite player to party
2651  mBrowserBox->addRow("/party 'NAME'", _("Invite to party"));
2652  }
2653  else
2654  {
2655  // TRANSLATORS: popup menu item
2656  // TRANSLATORS: kick player from party
2657  mBrowserBox->addRow("/kickparty 'NAME'", _("Kick from party"));
2659  }
2660  mBrowserBox->addSeparator("##3---");
2661  }
2662  }
2663 }
2664 
2665 void PopupMenu::addParty(const std::string &nick)
2666 {
2667  if (localPlayer->isInParty())
2668  {
2669  const Party *const party = localPlayer->getParty();
2670  if (party != nullptr)
2671  {
2672  if (!party->isMember(nick))
2673  {
2674  // TRANSLATORS: popup menu item
2675  // TRANSLATORS: invite player to party
2676  mBrowserBox->addRow("/party 'NAME'", _("Invite to party"));
2677  }
2678  else
2679  {
2680  // TRANSLATORS: popup menu item
2681  // TRANSLATORS: kick player from party
2682  mBrowserBox->addRow("/kickparty 'NAME'", _("Kick from party"));
2684  }
2685  mBrowserBox->addSeparator("##3---");
2686  }
2687  }
2688 }
2689 
2690 void PopupMenu::addChat(const Being *const being)
2691 {
2692  if (being == nullptr)
2693  return;
2694  const ChatObject *const chat = being->getChat();
2695  if (chat != nullptr)
2696  {
2697  mBrowserBox->addRow("join chat",
2698  // TRANSLATORS: popup menu item
2699  // TRANSLATORS: invite player to party
2700  strprintf(_("Join chat %s"), chat->title.c_str()).c_str());
2701  mBrowserBox->addSeparator("##3---");
2702  }
2703 }
2704 
2706 {
2707  // TRANSLATORS: popup menu item
2708  mBrowserBox->addRow("/showitems :'BEINGID'", _("Show Items"));
2709  // TRANSLATORS: popup menu item
2710  // TRANSLATORS: undress player
2711  mBrowserBox->addRow("/undress :'BEINGID'", _("Undress"));
2712  // TRANSLATORS: popup menu item
2713  // TRANSLATORS: add comment to player
2714  mBrowserBox->addRow("addcomment", _("Add comment"));
2715 }
2716 
2717 void PopupMenu::addPickupFilter(const std::string &name)
2718 {
2719  if (actorManager->isInPickupList(name)
2721  {
2722  mBrowserBox->addRow("/removepickup 'NAME'",
2723  // TRANSLATORS: popup menu item
2724  // TRANSLATORS: remove item from pickup list
2725  _("Remove from pickup list"));
2726  }
2727  else
2728  {
2729  mBrowserBox->addRow("/addpickup 'NAME'",
2730  // TRANSLATORS: popup menu item
2731  // TRANSLATORS: popup menu item
2732  _("Add to pickup list"));
2733  mBrowserBox->addRow("/ignorepickup 'NAME'",
2734  // TRANSLATORS: popup menu item
2735  // TRANSLATORS: add item to pickup list
2736  _("Add to ignore list"));
2737  }
2738 }
2739 
2740 void PopupMenu::showPopup(const int x, const int y,
2741  ListModel *const model)
2742 {
2743  if (model == nullptr)
2744  return;
2745 
2747  for (int f = 0, sz = model->getNumberOfElements(); f < sz; f ++)
2748  {
2749  mBrowserBox->addRow(strprintf("dropdown_%d", f),
2750  model->getElementAt(f).c_str());
2751  }
2752  // TRANSLATORS: popup menu item
2753  // TRANSLATORS: close menu
2754  mBrowserBox->addRow("cancel", _("Cancel"));
2755  showPopup(x, y);
2756 }
2757 
2759 {
2760  if (mDialog != nullptr)
2761  {
2762  mDialog->close();
2763  mDialog = nullptr;
2764  }
2765  mItemIndex = -1;
2766  mItemId = 0;
2767  for (int f = 0; f < maxCards; f ++)
2768  mItemCards[f] = 0;
2769  mMapItem = nullptr;
2770  mTab = nullptr;
2771  mSpell = nullptr;
2772  mCallerWindow = nullptr;
2773  mButton = nullptr;
2774  mTextField = nullptr;
2775 }
2776 
2778 {
2780  {
2781  mBrowserBox->addSeparator("##3---");
2782  // TRANSLATORS: popup menu item
2783  // TRANSLATORS: remove protection from item
2784  mBrowserBox->addRow("/unprotectitem 'ITEMID'", _("Unprotect item"));
2785  }
2786  else
2787  {
2788  if (mItemId < SPELL_MIN_ID)
2789  {
2790  mBrowserBox->addSeparator("##3---");
2791  // TRANSLATORS: popup menu item
2792  // TRANSLATORS: add protection to item
2793  mBrowserBox->addRow("/protectitem 'ITEMID'", _("Protect item"));
2794  }
2795  }
2796 }
2797 
2798 void PopupMenu::addUse(const Item *const item)
2799 {
2800  const ItemInfo &info = item->getInfo();
2801  const std::string &str = (item->isEquipment() == Equipm_true
2802  && item->isEquipped() == Equipped_true)
2803  ? info.getUseButton2() : info.getUseButton();
2804 
2805  if (str.empty())
2806  {
2807  // TRANSLATORS: popup menu item
2808  mBrowserBox->addRow("/useinv 'INVINDEX'", _("Use"));
2809  }
2810  else
2811  {
2812  // TRANSLATORS: popup menu item
2813  mBrowserBox->addRow("/useinv 'INVINDEX'", str.c_str());
2814  }
2815 }
2816 
2817 void PopupMenu::addItemMenu(const Item *const item,
2818  const InventoryTypeT type)
2819 {
2820  const ItemInfo &info = item->getInfo();
2821  const STD_VECTOR<ItemMenuItem> *menu = nullptr;
2822  switch (type)
2823  {
2825  menu = &info.getInventoryMenuConst();
2826  break;
2828  menu = &info.getStorageMenuConst();
2829  break;
2830  case InventoryType::Cart:
2831  menu = &info.getCartMenuConst();
2832  break;
2833  case InventoryType::Trade:
2834  case InventoryType::Npc:
2838  case InventoryType::Craft:
2840  default:
2841  return;
2842  }
2843 
2844  const bool firstMode = (item->isEquipment() == Equipm_true ?
2845  (item->isEquipped() != Equipped_true) : (item->getQuantity() == 1));
2846 
2847  FOR_EACHP (STD_VECTOR<ItemMenuItem>::const_iterator, it, menu)
2848  {
2849  const ItemMenuItem &menuItem = *it;
2850  const std::string &name = firstMode ?
2851  menuItem.name1 : menuItem.name2;
2852  const std::string &command = firstMode ?
2853  menuItem.command1 : menuItem.command2;
2854  if (command.empty() ||
2855  name.empty())
2856  {
2857  continue;
2858  }
2859  mBrowserBox->addRow("/" + command, name.c_str());
2860  }
2861  mBrowserBox->addSeparator("##3---");
2862 }
2863 
2864 void PopupMenu::addDrop(const Item *const item,
2865  const bool isProtected)
2866 {
2867  if (!isProtected)
2868  {
2869  mBrowserBox->addSeparator("##3---");
2870  if (item->getQuantity() > 1)
2871  {
2872  // TRANSLATORS: popup menu item
2873  // TRANSLATORS: drop item
2874  mBrowserBox->addRow("/dropinv 'INVINDEX'", _("Drop..."));
2875  // TRANSLATORS: popup menu item
2876  // TRANSLATORS: drop all item amount
2877  mBrowserBox->addRow("/dropinvall 'INVINDEX'", _("Drop all"));
2878  }
2879  else
2880  {
2881  // TRANSLATORS: popup menu item
2882  // TRANSLATORS: drop item
2883  mBrowserBox->addRow("/dropinv 'INVINDEX'", _("Drop"));
2884  }
2885  }
2886 }
2887 
2889 {
2890  if (localPlayer->isGM())
2891  {
2892  // TRANSLATORS: popup menu item
2893  // TRANSLATORS: gm commands
2894  mBrowserBox->addRow("gm", _("GM..."));
2895  }
2896 }
2897 
2899 {
2901  // TRANSLATORS: popup menu header
2902  mBrowserBox->addRow(strprintf(_("Show %s"),
2903  mName.c_str()),
2904  false);
2905  if (isAllowCommand(ServerCommandType::accinfo))
2906  {
2907  // TRANSLATORS: popup menu item
2908  // TRANSLATORS: show player account info
2909  mBrowserBox->addRow("/showaccountinfo 'NAME'", _("Account info"));
2910  }
2911  if (isAllowOtherCommand(ServerCommandType::exp))
2912  {
2913  // TRANSLATORS: popup menu item
2914  // TRANSLATORS: show player level
2915  mBrowserBox->addRow("/showlevel 'NAME'", _("Level"));
2916  }
2917  if (isAllowOtherCommand(ServerCommandType::stats))
2918  {
2919  // TRANSLATORS: popup menu item
2920  // TRANSLATORS: show player stats
2921  mBrowserBox->addRow("/showstats 'NAME'", _("Stats"));
2922  }
2923  if (isAllowOtherCommand(ServerCommandType::itemlist))
2924  {
2925  // TRANSLATORS: popup menu item
2926  // TRANSLATORS: show player inventory list
2927  mBrowserBox->addRow("/showinventory 'NAME'", _("Inventory"));
2928  }
2929  if (isAllowOtherCommand(ServerCommandType::storagelist))
2930  {
2931  // TRANSLATORS: popup menu item
2932  // TRANSLATORS: show player storage list
2933  mBrowserBox->addRow("/showstorage 'NAME'", _("Storage"));
2934  }
2935  if (isAllowOtherCommand(ServerCommandType::cartlist))
2936  {
2937  // TRANSLATORS: popup menu item
2938  // TRANSLATORS: show player cart list
2939  mBrowserBox->addRow("/showcart 'NAME'", _("Cart"));
2940  }
2941  if (isAllowOtherCommand(ServerCommandType::commands))
2942  {
2943  // TRANSLATORS: popup menu item
2944  // TRANSLATORS: gm commands
2945  mBrowserBox->addRow("/gmcommands 'NAME'", _("Commands"));
2946  }
2947  if (isAllowOtherCommand(ServerCommandType::charcommands))
2948  {
2949  // TRANSLATORS: popup menu item
2950  // TRANSLATORS: gm char commands
2951  mBrowserBox->addRow("/gmcharcommands 'NAME'", _("Char commands"));
2952  }
2953  // TRANSLATORS: popup menu item
2954  // TRANSLATORS: back to gm menu
2955  mBrowserBox->addRow("gm", _("Back"));
2956  // TRANSLATORS: popup menu item
2957  // TRANSLATORS: close menu
2958  mBrowserBox->addRow("cancel", _("Cancel"));
2959  showPopup(getX(), getY());
2960 }
2961 
2962 void PopupMenu::showPlayerGMCommands(const std::string &name)
2963 {
2964  if (localPlayer == nullptr)
2965  return;
2966  const bool legacy = Net::getNetworkType() == ServerType::TMWATHENA;
2967  if (!legacy && isAllowCommand(ServerCommandType::where))
2968  {
2969  // TRANSLATORS: popup menu item
2970  // TRANSLATORS: find player position
2971  mBrowserBox->addRow("/locateplayer 'NAME'", _("Locate"));
2972  }
2973  if (legacy)
2974  {
2975  // TRANSLATORS: popup menu item
2976  // TRANSLATORS: check player ip
2977  mBrowserBox->addRow("/ipcheck 'NAME'", _("Check ip"));
2978  }
2979  if (isAllowCommand(ServerCommandType::jumpto))
2980  {
2981  // TRANSLATORS: popup menu item
2982  // TRANSLATORS: go to player position
2983  mBrowserBox->addRow("/gotopc 'NAME'", _("Goto"));
2984  }
2985  if (isAllowCommand(ServerCommandType::recall))
2986  {
2987  // TRANSLATORS: popup menu item
2988  // TRANSLATORS: recall player to current position
2989  mBrowserBox->addRow("/recallpc 'NAME'", _("Recall"));
2990  }
2991  if (isAllowOtherCommand(ServerCommandType::alive))
2992  {
2993  // TRANSLATORS: popup menu item
2994  // TRANSLATORS: revive player
2995  mBrowserBox->addRow("/alive 'NAME'", _("Revive"));
2996  }
2997  if (!legacy)
2998  {
2999  Being *const being = actorManager->findBeingByName(name,
3001  if (being != nullptr && being == localPlayer)
3002  {
3003  if (!being->getPartyName().empty() &&
3004  isAllowCommand(ServerCommandType::partyrecall))
3005  {
3006  mBrowserBox->addRow("/partyrecall 'PARTY'",
3007  // TRANSLATORS: popup menu item
3008  // TRANSLATORS: recall all party members to player location
3009  _("Recall party"));
3010  }
3011  if (!being->getGuildName().empty() &&
3012  isAllowCommand(ServerCommandType::guildrecall))
3013  {
3014  mBrowserBox->addRow("/guildrecall 'PARTY'",
3015  // TRANSLATORS: popup menu item
3016  // TRANSLATORS: recall all guild members to player location
3017  _("Recall guild"));
3018  }
3019  }
3020  if (localPlayer->isInParty())
3021  {
3022  const Party *const party = localPlayer->getParty();
3023  if (party != nullptr &&
3024  party->isMember(name) &&
3025  isAllowCommand(ServerCommandType::changeleader))
3026  {
3027  mBrowserBox->addRow("/gmpartyleader 'NAME'",
3028  // TRANSLATORS: popup menu item
3029  // TRANSLATORS: give party leader status
3030  _("Give party leader"));
3031  }
3032  }
3033 
3034  if (isAllowCommand(ServerCommandType::nuke))
3035  {
3036  // TRANSLATORS: popup menu item
3037  // TRANSLATORS: nuke player
3038  mBrowserBox->addRow("/gmnuke 'NAME'", _("Nuke"));
3039  }
3040  if (isAllowOtherCommand(ServerCommandType::kill))
3041  {
3042  // TRANSLATORS: popup menu item
3043  // TRANSLATORS: kill player
3044  mBrowserBox->addRow("/kill 'NAME'", _("Kill"));
3045  }
3046  if (mBeingId != BeingId_zero)
3047  {
3048  mBrowserBox->addSeparator("##3---");
3049  // TRANSLATORS: popup menu item
3050  // TRANSLATORS: show menu
3051  mBrowserBox->addRow("show", _("Show..."));
3052  // TRANSLATORS: popup menu item
3053  // TRANSLATORS: mute menu
3054  mBrowserBox->addRow("mute", _("Mute..."));
3055  }
3056  }
3057  if (legacy)
3058  {
3059  if (localPlayer->getName() == mName)
3060  {
3061  // TRANSLATORS: popup menu item
3062  // TRANSLATORS: hide player
3063  mBrowserBox->addRow("/hide", _("Hide"));
3064  mBrowserBox->addSeparator("##3---");
3065  }
3066  }
3067  else
3068  {
3070  {
3071  // TRANSLATORS: popup menu item
3072  // TRANSLATORS: heal player
3073  mBrowserBox->addRow("/gmheal 'NAME'", _("Heal"));
3074  }
3075  if (isAllowOtherCommand(ServerCommandType::monsterignore))
3076  {
3077  // TRANSLATORS: popup menu item
3078  // TRANSLATORS: enable immortal mode for player
3079  mBrowserBox->addRow("/immortal 'NAME'", _("Immortal"));
3080  }
3081  if (isAllowCommand(ServerCommandType::jail))
3082  {
3083  // TRANSLATORS: popup menu item
3084  // TRANSLATORS: send player to jail
3085  mBrowserBox->addRow("/jail 'NAME'", _("Jail"));
3086  }
3087  if (isAllowCommand(ServerCommandType::unjail))
3088  {
3089  // TRANSLATORS: popup menu item
3090  // TRANSLATORS: restore player from jail
3091  mBrowserBox->addRow("/unjail 'NAME'", _("Unjail"));
3092  }
3093  if (name == localPlayer->getName() &&
3094  isAllowCommand(ServerCommandType::hide))
3095  {
3096  // TRANSLATORS: popup menu item
3097  // TRANSLATORS: hide player
3098  mBrowserBox->addRow("/hide 'NAME'", _("Hide"));
3099  }
3100  mBrowserBox->addSeparator("##3---");
3101  if (isAllowOtherCommand(ServerCommandType::killer))
3102  {
3103  // TRANSLATORS: popup menu item
3104  // TRANSLATORS: set player as killer
3105  mBrowserBox->addRow("/killer 'NAME'", _("Killer"));
3106  }
3107  if (isAllowOtherCommand(ServerCommandType::killable))
3108  {
3109  // TRANSLATORS: popup menu item
3110  // TRANSLATORS: set player as killable
3111  mBrowserBox->addRow("/killable 'NAME'", _("Killable"));
3112  }
3113  if (isAllowOtherCommand(ServerCommandType::save))
3114  {
3115  // TRANSLATORS: popup menu item
3116  // TRANSLATORS: set player save position
3117  mBrowserBox->addRow("/savepos 'NAME'", _("Set save"));
3118  }
3120  {
3121  // TRANSLATORS: popup menu item
3122  // TRANSLATORS: warp player to save position
3123  mBrowserBox->addRow("/loadpos 'NAME'", _("Warp to save"));
3124  }
3125  if (isAllowOtherCommand(ServerCommandType::jump))
3126  {
3127  // TRANSLATORS: popup menu item
3128  // TRANSLATORS: warp player to random position on same map
3129  mBrowserBox->addRow("/randomwarp 'NAME'", _("Warp to random"));
3130  }
3131  mBrowserBox->addSeparator("##3---");
3132  if (isAllowCommand(ServerCommandType::clone))
3133  {
3134  // TRANSLATORS: popup menu item
3135  // TRANSLATORS: spawn player clone
3136  mBrowserBox->addRow("/spawnclone 'NAME'", _("Spawn clone"));
3137  }
3138  if (isAllowCommand(ServerCommandType::slaveclone))
3139  {
3140  mBrowserBox->addRow("/spawnslaveclone 'NAME'",
3141  // TRANSLATORS: popup menu item
3142  // TRANSLATORS: spawn slave player clone
3143  _("Spawn slave clone"));
3144  }
3145  if (isAllowCommand(ServerCommandType::evilclone))
3146  {
3147  mBrowserBox->addRow("/spawnevilclone 'NAME'",
3148  // TRANSLATORS: popup menu item
3149  // TRANSLATORS: spawn evil player clone
3150  _("Spawn evil clone"));
3151  }
3152  mBrowserBox->addSeparator("##3---");
3153  if (isAllowOtherCommand(ServerCommandType::breakguild))
3154  {
3155  // TRANSLATORS: popup menu item
3156  // TRANSLATORS: break guild
3157  mBrowserBox->addRow("/gmbreakguild 'NAME'", _("Break guild"));
3158  }
3159  }
3160  if (mBeingId != BeingId_zero &&
3162  {
3163  mBrowserBox->addSeparator("##3---");
3164  // TRANSLATORS: popup menu item
3165  // TRANSLATORS: kick player
3166  mBrowserBox->addRow("/kick :'BEINGID'", _("Kick"));
3167  }
3168 }
3169 
3171 {
3173  // TRANSLATORS: popup menu header
3174  mBrowserBox->addRow(strprintf(_("Mute %s"),
3175  mName.c_str()),
3176  false);
3177  if (mBeingId != BeingId_zero &&
3179  isAllowCommand(ServerCommandType::mute))
3180  {
3181  mBrowserBox->addRow("mute_+1",
3182  // TRANSLATORS: popup menu item
3183  // TRANSLATORS: mute player
3184  strprintf(_("Mute %d"), 1).c_str());
3185  mBrowserBox->addRow("mute_+5",
3186  // TRANSLATORS: popup menu item
3187  // TRANSLATORS: mute player
3188  strprintf(_("Mute %d"), 5).c_str());
3189  mBrowserBox->addRow("mute_+10",
3190  // TRANSLATORS: popup menu item
3191  // TRANSLATORS: mute player
3192  strprintf(_("Mute %d"), 10).c_str());
3193  mBrowserBox->addRow("mute_+15",
3194  // TRANSLATORS: popup menu item
3195  // TRANSLATORS: mute player
3196  strprintf(_("Mute %d"), 15).c_str());
3197  mBrowserBox->addRow("mute_+30",
3198  // TRANSLATORS: popup menu item
3199  // TRANSLATORS: mute player
3200  strprintf(_("Mute %d"), 30).c_str());
3201 
3202  mBrowserBox->addRow("mute_-1",
3203  // TRANSLATORS: popup menu item
3204  // TRANSLATORS: mute player
3205  strprintf(_("Unmute %d"), 1).c_str());
3206  mBrowserBox->addRow("mute_-5",
3207  // TRANSLATORS: popup menu item
3208  // TRANSLATORS: mute player
3209  strprintf(_("Unmute %d"), 5).c_str());
3210  mBrowserBox->addRow("mute_-10",
3211  // TRANSLATORS: popup menu item
3212  // TRANSLATORS: mute player
3213  strprintf(_("Unmute %d"), 10).c_str());
3214  mBrowserBox->addRow("mute_-15",
3215  // TRANSLATORS: popup menu item
3216  // TRANSLATORS: mute player
3217  strprintf(_("Unmute %d"), 15).c_str());
3218  mBrowserBox->addRow("mute_-30",
3219  // TRANSLATORS: popup menu item
3220  // TRANSLATORS: mute player
3221  strprintf(_("Unmute %d"), 30).c_str());
3222  mBrowserBox->addSeparator("##3---");
3223  }
3224  // TRANSLATORS: popup menu item
3225  // TRANSLATORS: back to gm menu
3226  mBrowserBox->addRow("gm", _("Back"));
3227  // TRANSLATORS: popup menu item
3228  // TRANSLATORS: close menu
3229  mBrowserBox->addRow("cancel", _("Cancel"));
3230  showPopup(getX(), getY());
3231 }
3232 
3234 {
3235  if (mBeingId != BeingId_zero)
3236  {
3238  {
3239  // TRANSLATORS: popup menu item
3240  // TRANSLATORS: kick player
3241  mBrowserBox->addRow("/kick :'BEINGID'", _("Kick"));
3242  }
3243  const bool legacy = Net::getNetworkType() == ServerType::TMWATHENA;
3244  if (!legacy)
3245  {
3246  if (isAllowCommand(ServerCommandType::hidenpc))
3247  {
3248  // TRANSLATORS: popup menu item
3249  // TRANSLATORS: hide npc
3250  mBrowserBox->addRow("/hidenpc 'EXTNAME'", _("Hide"));
3251  }
3252  mBrowserBox->addSeparator("##3---");
3253  if (isAllowCommand(ServerCommandType::npcmove))
3254  {
3255  mBrowserBox->addRow("/npcmove 'EEXTNAME' 'PLAYERX' 'PLAYERY'",
3256  // TRANSLATORS: popup menu item
3257  // TRANSLATORS: warp npc to player location
3258  _("Recall"));
3259  }
3260  if (isAllowCommand(ServerCommandType::disguise))
3261  {
3262  mBrowserBox->addRow("/disguise 'BEINGSUBTYPEID'",
3263  // TRANSLATORS: popup menu item
3264  // TRANSLATORS: disguise to npc
3265  _("Disguise"));
3266  }
3267  if (isAllowCommand(ServerCommandType::tonpc))
3268  {
3269  // TRANSLATORS: popup menu item
3270  // TRANSLATORS: warp to npc
3271  mBrowserBox->addRow("/gotonpc 'EXTNAME'", _("Goto"));
3272  }
3273  }
3274  }
3275 }
3276 
3278 {
3279  if (mBeingId != BeingId_zero)
3280  {
3281  const bool legacy = Net::getNetworkType() == ServerType::TMWATHENA;
3283  {
3284  // TRANSLATORS: popup menu item
3285  // TRANSLATORS: kick monster
3286  mBrowserBox->addRow("/kick :'BEINGID'", _("Kick"));
3287  }
3288  if (isAllowCommand(ServerCommandType::monster))
3289  {
3290  // TRANSLATORS: popup menu item
3291  // TRANSLATORS: spawn monster
3292  mBrowserBox->addRow("/spawn 'BEINGSUBTYPEID'", _("Spawn same"));
3293  }
3294  if (!legacy)
3295  {
3296  if (isAllowCommand(ServerCommandType::summon))
3297  {
3298  mBrowserBox->addRow("/spawnslave 'BEINGSUBTYPEID'",
3299  // TRANSLATORS: popup menu item
3300  // TRANSLATORS: spawn slave monster
3301  _("Spawn slave"));
3302  }
3303  if (isAllowCommand(ServerCommandType::disguise))
3304  {
3305  mBrowserBox->addRow("/disguise 'BEINGSUBTYPEID'",
3306  // TRANSLATORS: popup menu item
3307  // TRANSLATORS: disguise to monster
3308  _("Disguise"));
3309  }
3310  mBrowserBox->addSeparator("##3---");
3311  if (isAllowCommand(ServerCommandType::mobinfo))
3312  {
3313  mBrowserBox->addRow("/monsterinfo 'BEINGSUBTYPEID'",
3314  // TRANSLATORS: popup menu item
3315  // TRANSLATORS: show monster information
3316  _("Info"));
3317  }
3318  if (isAllowCommand(ServerCommandType::mobsearch))
3319  {
3320  mBrowserBox->addRow("/mobsearch 'BEINGSUBTYPEID'",
3321  // TRANSLATORS: popup menu item
3322  // TRANSLATORS: show selected monster in current map
3323  _("Search"));
3324  }
3325  if (isAllowCommand(ServerCommandType::whereis))
3326  {
3327  mBrowserBox->addRow("/mobspawnsearch 'BEINGSUBTYPEID'",
3328  // TRANSLATORS: popup menu item
3329  // TRANSLATORS: show selected monster spawns in all maps
3330  _("Search spawns"));
3331  }
3332  }
3333  }
3334 }
3335 
3337 {
3338  const bool legacy = Net::getNetworkType() == ServerType::TMWATHENA;
3339  if (legacy)
3340  return;
3341  if (isAllowCommand(ServerCommandType::iteminfo))
3342  {
3343  // TRANSLATORS: popup menu item
3344  // TRANSLATORS: show item information
3345  mBrowserBox->addRow("/iteminfo 'ITEMID'", _("Info"));
3346  }
3347  if (isAllowCommand(ServerCommandType::whodrops))
3348  {
3349  // TRANSLATORS: popup menu item
3350  // TRANSLATORS: show who drops item
3351  mBrowserBox->addRow("/whodrops 'ITEMID'", _("Who drops"));
3352  }
3353 }
3354 
3356 {
3357  const bool legacy = Net::getNetworkType() == ServerType::TMWATHENA;
3358  if (legacy)
3359  return;
3360  if (isAllowCommand(ServerCommandType::iteminfo))
3361  {
3362  // TRANSLATORS: popup menu item
3363  // TRANSLATORS: show item information
3364  mBrowserBox->addRow("/iteminfo 'ITEMID'", _("Info"));
3365  }
3366  if (isAllowCommand(ServerCommandType::whodrops))
3367  {
3368  // TRANSLATORS: popup menu item
3369  // TRANSLATORS: show who drops item
3370  mBrowserBox->addRow("/whodrops 'ITEMID'", _("Who drops"));
3371  }
3372  mBrowserBox->addSeparator("##3---");
3373  if (isAllowCommand(ServerCommandType::item))
3374  {
3375  // TRANSLATORS: popup menu item
3376  // TRANSLATORS: gm create item
3377  mBrowserBox->addRow("/createitem 'ITEMID' 1", _("Add 1"));
3378  // TRANSLATORS: popup menu item
3379  // TRANSLATORS: gm create item
3380  mBrowserBox->addRow("/createitem 'ITEMID' 5", _("Add 5"));
3381  // TRANSLATORS: popup menu item
3382  // TRANSLATORS: gm create item
3383  mBrowserBox->addRow("/createitem 'ITEMID' 10", _("Add 10"));
3384  // TRANSLATORS: popup menu item
3385  // TRANSLATORS: gm create item
3386  mBrowserBox->addRow("/createitem 'ITEMID' 100", _("Add 100"));
3387  // TRANSLATORS: popup menu item
3388  // TRANSLATORS: gm create item
3389  mBrowserBox->addRow("/createitem 'ITEMID' 1000", _("Add 1000"));
3390  // TRANSLATORS: popup menu item
3391  // TRANSLATORS: gm create item
3392  mBrowserBox->addRow("/createitem 'ITEMID' 10000", _("Add 10000"));
3393  }
3394 }
3395 
3396 void PopupMenu::showGMPopup(const std::string &name)
3397 {
3399  // TRANSLATORS: popup menu header
3400  mBrowserBox->addRow(_("GM commands"), false);
3401  if (localPlayer->isGM())
3402  {
3403  switch (mType)
3404  {
3405  case ActorType::Player:
3406  showPlayerGMCommands(name);
3407  break;
3408  case ActorType::Npc:
3410  break;
3411  case ActorType::Monster:
3413  break;
3414  case ActorType::FloorItem:
3416  break;
3417  case ActorType::Homunculus:
3419  break;
3420  case ActorType::Pet:
3422  break;
3423  case ActorType::Mercenary:
3425  break;
3426  case ActorType::SkillUnit:
3427  break;
3428  default:
3429  case ActorType::Unknown:
3430  if (mItemId != 0)
3432  break;
3433  case ActorType::Portal:
3434  case ActorType::Avatar:
3435  case ActorType::Elemental:
3436  break;
3437  }
3438  }
3439 
3440  mBrowserBox->addSeparator("##3---");
3441  // TRANSLATORS: popup menu item
3442  // TRANSLATORS: close menu
3443  mBrowserBox->addRow("cancel", _("Cancel"));
3444 
3445  showPopup(getX(), getY());
3446 }
3447 
3449 {
3450 }
3451 
3453 {
3454 }
3455 
3457 {
3458 }
3459 
3461 {
3463 
3464  for (int f = 0; f < 9; f ++)
3465  {
3466  const std::string cmd = strprintf("/craft %d", f);
3467  mBrowserBox->addRow(cmd,
3468  // TRANSLATORS: popup menu item
3469  // TRANSLATORS: move current item to craft slot
3470  strprintf(_("Move to craft %d"), f + 1).c_str());
3471  }
3472 
3473  // TRANSLATORS: popup menu item
3474  // TRANSLATORS: close menu
3475  mBrowserBox->addRow("cancel", _("Cancel"));
3476 
3477  showPopup(mX, mY);
3478 }
3479 
3481 {
3483  return;
3484 
3485  // TRANSLATORS: popup menu item
3486  // TRANSLATORS: open mail dialog
3487  mBrowserBox->addRow("/mailto 'NAME'", _("Mail to..."));
3488 }
3489 
3491 {
3493  return;
3494  // TRANSLATORS: popup menu item
3495  // TRANSLATORS: catch pet command
3496  mBrowserBox->addRow("/catchpet :'BEINGID'", _("Taming pet"));
3497 }
3498 
3500 {
3502  return;
3503  // TRANSLATORS: popup menu item
3504  // TRANSLATORS: adopt child command
3505  mBrowserBox->addRow("/adoptchild 'NAME'", _("Adopt child"));
3506 }
3507 
3509 {
3510  initPopup();
3512  setMousePos();
3513  const Party *const party = localPlayer->getParty();
3514  if (party != nullptr)
3515  {
3516  // TRANSLATORS: popup menu item
3517  // TRANSLATORS: leave party
3518  mBrowserBox->addRow("/leaveparty", _("Leave party"));
3519  }
3520  else
3521  {
3522  // TRANSLATORS: popup menu item
3523  // TRANSLATORS: create party
3524  mBrowserBox->addRow("/createparty", _("Create party"));
3525  }
3526 
3528  {
3529  const Guild *const guild = localPlayer->getGuild();
3530  if (guild != nullptr)
3531  {
3532  // TRANSLATORS: popup menu item
3533  // TRANSLATORS: leave guild
3534  mBrowserBox->addRow("/leaveguild", _("Leave guild"));
3535  }
3536  else
3537  {
3538  // TRANSLATORS: popup menu item
3539  // TRANSLATORS: create guild
3540  mBrowserBox->addRow("/createguild", _("Create guild"));
3541  }
3542  }
3543  mBrowserBox->addSeparator("##3---");
3544 }
3545 
3547 {
3548  addSocialMenu();
3549 
3550  // TRANSLATORS: popup menu item
3551  // TRANSLATORS: close menu
3552  mBrowserBox->addRow("cancel", _("Cancel"));
3553  showPopup(mX, mY);
3554 }
3555 
3557 {
3558  addSocialMenu();
3559 
3560  // TRANSLATORS: popup menu item
3561  // TRANSLATORS: change guild notice message
3562  mBrowserBox->addRow("/guildnotice", _("Change notice"));
3563 
3564  // TRANSLATORS: popup menu item
3565  // TRANSLATORS: close menu
3566  mBrowserBox->addRow("cancel", _("Cancel"));
3567  showPopup(mX, mY);
3568 }
3569 
3571 {
3572  addSocialMenu();
3573 
3574  // TRANSLATORS: popup menu item
3575  // TRANSLATORS: close menu
3576  mBrowserBox->addRow("cancel", _("Cancel"));
3577  showPopup(mX, mY);
3578 }
3579 
3581 {
3582  addSocialMenu();
3583 
3584  // TRANSLATORS: popup menu item
3585  // TRANSLATORS: close menu
3586  mBrowserBox->addRow("cancel", _("Cancel"));
3587  showPopup(mX, mY);
3588 }
3589 
3591 {
3592  addSocialMenu();
3593 
3594  // TRANSLATORS: popup menu item
3595  // TRANSLATORS: close menu
3596  mBrowserBox->addRow("cancel", _("Cancel"));
3597  showPopup(mX, mY);
3598 }
3599 
3601 {
3602  addSocialMenu();
3603 
3604  // TRANSLATORS: popup menu item
3605  // TRANSLATORS: close menu
3606  mBrowserBox->addRow("cancel", _("Cancel"));
3607  showPopup(mX, mY);
3608 }
3609 
3611 {
3612  addSocialMenu();
3613 
3614  // TRANSLATORS: popup menu item
3615  // TRANSLATORS: close menu
3616  mBrowserBox->addRow("cancel", _("Cancel"));
3617  showPopup(mX, mY);
3618 }
3619 
3621 {
3623 }
3624 
3626 {
3628 }
3629 
3631 {
3633 }
ActorManager * actorManager
ActorType ::T ActorTypeT
Definition: actortype.h:43
Net::AdminHandler * adminHandler
Definition: net.cpp:84
int BeingId
Definition: beingid.h:30
const BeingId BeingId_zero
Definition: beingid.h:30
int BeingTypeId
Definition: beingtypeid.h:30
const BeingTypeId BeingTypeId_zero
Definition: beingtypeid.h:30
#define maxCards
Definition: cards.h:25
#define CAST_S32
Definition: cast.h:30
#define CAST_U32
Definition: cast.h:31
#define CAST_SIZE
Definition: cast.h:34
Net::ChatHandler * chatHandler
Definition: net.cpp:86
ChatTabType ::T ChatTabTypeT
Definition: chattabtype.h:49
ChatWindow * chatWindow
Definition: chatwindow.cpp:94
#define reportAlways(...)
Definition: checkutils.h:253
bool isInAttackList(const std::string &name) const
Definition: actormanager.h:341
bool isInIgnoreAttackList(const std::string &name) const
Definition: actormanager.h:343
Being * findBeing(const BeingId id) const
Being * findBeingByName(const std::string &name, const ActorTypeT type) const
bool isInPriorityAttackList(const std::string &name) const
Definition: actormanager.h:342
std::string getSeenPlayerById(const BeingId id) const
int getPriorityAttackMobsSize() const
Definition: actormanager.h:322
bool isInPickupList(const std::string &name) const
Definition: actormanager.h:344
int getAttackMobsSize() const
Definition: actormanager.h:325
FloorItem * findItem(const BeingId id) const
bool isInIgnorePickupList(const std::string &name) const
Definition: actormanager.h:345
int getAttackMobIndex(const std::string &name) const
virtual ActorTypeT getType() const
Definition: actorsprite.h:73
BeingId getId() const
Definition: actorsprite.h:64
std::string getMap() const
Definition: avatar.h:120
virtual void add(Widget *const widget)
Definition: being.h:96
Being * getOwner() const
Definition: being.h:914
Party * getParty() const
Definition: being.h:330
const Guild * getGuild(const std::string &guildName) const
Definition: being.cpp:1258
const std::string getComment() const
Definition: being.h:812
int getTileX() const
Definition: being.h:168
BeingTypeId getSubType() const
Definition: being.h:400
const std::string & getPartyName() const
Definition: being.h:255
int getGroupId() const
Definition: being.h:1087
std::string getGenderSignWithSpace() const
Definition: being.cpp:2538
int getTileY() const
Definition: being.h:174
ChatObject * getChat() const
Definition: being.h:999
bool isGM() const
Definition: being.h:659
const std::string & getName() const
Definition: being.h:232
BeingId getCreatorId() const
Definition: being.h:1028
bool isBuyShopEnabled() const
Definition: being.cpp:5351
const std::string & getGuildName() const
Definition: being.h:259
static std::string loadComment(const std::string &name, const ActorTypeT &type)
Definition: being.cpp:4734
const std::string & getExtName() const
Definition: being.h:235
bool isInParty() const
Definition: being.h:321
void updateComment()
Definition: being.cpp:4725
bool isSellShopEnabled() const
Definition: being.cpp:5357
ActorTypeT getType() const
Definition: being.h:116
const BeingInfo * getInfo() const
Definition: being.h:409
Definition: button.h:102
std::string getDescription() const
Definition: button.h:168
const std::string & getCaption() const
Definition: button.h:222
bool getRemoveNames() const
Definition: chattab.h:164
ChatTabTypeT getType() const
Definition: chattab.h:145
bool getAllowHighlight() const
Definition: chattab.h:158
bool getNoAway() const
Definition: chattab.h:170
bool getBoolValue(const std::string &key) const
std::string getName() const
Definition: flooritem.cpp:146
int getItemId() const
Definition: flooritem.h:82
int getCard(const int index) const
Definition: flooritem.cpp:222
int mWidth
Definition: graphics.h:484
int getHeight() const
Definition: graphics.cpp:648
int mHeight
Definition: graphics.h:485
static uint8_t getMouseState(int &x, int &y)
Definition: gui.cpp:1171
bool havePower() const
Definition: guildmanager.h:81
Definition: guild.h:70
bool getServerGuild() const
Definition: guild.h:206
int16_t getId() const
Definition: guild.h:135
GuildMember * getMember(const BeingId id) const
Definition: guild.cpp:140
void executeAction(const InputActionT keyNum)
bool executeChatCommand(const std::string &cmd, const std::string &args, ChatTab *const tab)
static bool isStorageActive()
Item * findItem(const int itemId, const ItemColor color) const
Definition: inventory.cpp:94
Definition: item.h:50
Equipm isEquipment() const
Definition: item.h:117
int getCard(const int index) const
Definition: item.cpp:159
int getQuantity() const
Definition: item.h:105
Equipped isEquipped() const
Definition: item.h:129
int getInvIndex() const
Definition: item.h:165
std::string getName() const
Definition: item.cpp:140
int getId() const
Definition: item.h:81
ItemColor getColor() const
Definition: item.h:181
const ItemInfo & getInfo() const
Definition: item.h:171
virtual std::string getElementAt(int i)=0
virtual int getNumberOfElements()=0
void removeHome()
void saveHomes()
const std::string & getComment() const
Definition: mapitem.h:68
int getType() const
Definition: mapitem.h:55
int getY() const
Definition: mapitem.h:65
int getX() const
Definition: mapitem.h:62
Definition: map.h:75
SpecialLayer * getSpecialLayer() const
Definition: map.h:241
std::vector< ProgressBar * > & getBars()
void showBar(const std::string &name, const Visible visible)
virtual void mute(const Being *const being, const int type, const int limit) const =0
virtual void joinChat(const ChatObject *const chat, const std::string &password) const =0
virtual void changeMemberPostion(const GuildMember *const member, const int level) const =0
virtual NpcDialog * getCurrentNpcDialog() const =0
NpcInputStateT getInputState()
Definition: npcdialog.h:237
Definition: party.h:63
const std::string & getName() const
Definition: party.h:97
void setNick(const std::string &name)
void setDialog(TextDialog *const dialog)
void setType(const ActorTypeT type)
unsigned int getDefault() const
RelationT getRelation(const std::string &name) const
static void hideItemPopup()
void showSpellPopup(const int x, const int y, TextCommand *const cmd)
Definition: popupmenu.cpp:887
void showMapPopup(const int x, const int y, const int x2, const int y2, const bool isMinimap)
Definition: popupmenu.cpp:805
void addBuySell(const Being *const being)
Definition: popupmenu.cpp:2593
int mItemCards[4]
Definition: popupmenu.h:293
void addBuySellDefault()
Definition: popupmenu.cpp:2627
const GroupInfo * mGroup
Definition: popupmenu.h:303
void addUse(const Item *const item)
Definition: popupmenu.cpp:2798
ActorTypeT mType
Definition: popupmenu.h:307
void showAttackPopup()
Definition: popupmenu.cpp:3570
void addPickupFilter(const std::string &name)
Definition: popupmenu.cpp:2717
StaticBrowserBox * mBrowserBox
Definition: popupmenu.h:286
void showPickupPopup()
Definition: popupmenu.cpp:3590
std::string mName
Definition: popupmenu.h:304
MapItem * mMapItem
Definition: popupmenu.h:295
void showPlayersPopup()
Definition: popupmenu.cpp:3600
void addPlayerMisc()
Definition: popupmenu.cpp:2705
TextCommand * mSpell
Definition: popupmenu.h:297
std::string mExtName
Definition: popupmenu.h:305
void showMonsterGMCommands()
Definition: popupmenu.cpp:3277
void showAdoptCommands()
Definition: popupmenu.cpp:3499
void showAttackMonsterPopup(const int x, const int y, const std::string &name, const int type)
Definition: popupmenu.cpp:2018
ChatTab * mTab
Definition: popupmenu.h:296
ScrollArea * mScrollArea
Definition: popupmenu.h:287
void postInit()
Definition: popupmenu.cpp:146
void showTextFieldPopup(TextField *const input)
Definition: popupmenu.cpp:2172
BeingTypeId mSubType
Definition: popupmenu.h:308
void showSkillTypePopup(const SkillInfo *const info)
Definition: popupmenu.cpp:2394
void showItemGMCommands()
Definition: popupmenu.cpp:3355
void addMailCommands()
Definition: popupmenu.cpp:3480
void initPopup()
Definition: popupmenu.cpp:152
void showFriendsPopup()
Definition: popupmenu.cpp:3610
bool isAllowCommand(const ServerCommandTypeT command)
Definition: popupmenu.cpp:160
void showMercenaryGMCommands()
Definition: popupmenu.cpp:3456
void addPartyName(const std::string &partyName)
Definition: popupmenu.cpp:2641
void addFollow()
Definition: popupmenu.cpp:2581
void showNpcDialogPopup(const BeingId npcId, const int x, const int y)
Definition: popupmenu.cpp:2244
Button * mButton
Definition: popupmenu.h:302
RenameListener mRenameListener
Definition: popupmenu.h:299
void showHomunGMCommands()
Definition: popupmenu.cpp:3448
void showPartyPopup()
Definition: popupmenu.cpp:3546
void addPlayerRelation(const std::string &name)
Definition: popupmenu.cpp:2492
void addSocialMenu()
Definition: popupmenu.cpp:3508
void addDrop(const Item *const item, const bool isProtected)
Definition: popupmenu.cpp:2864
int mItemId
Definition: popupmenu.h:291
void showLinkPopup(const std::string &link)
Definition: popupmenu.cpp:2194
void setMousePos2()
Definition: popupmenu.cpp:553
void showPlayerPopup(const std::string &nick)
Definition: popupmenu.cpp:606
void showPickupItemPopup(const int x, const int y, const std::string &name)
Definition: popupmenu.cpp:2101
void showItemPopup(const int x, const int y, const Item *const item)
Definition: popupmenu.cpp:1790
void addGmCommands()
Definition: popupmenu.cpp:2888
void select()
Definition: popupmenu.cpp:3630
int mItemIndex
Definition: popupmenu.h:292
void showUndressPopup(const int x, const int y, const Being *const being, const Item *const item)
Definition: popupmenu.cpp:2138
void showNavigationPopup()
Definition: popupmenu.cpp:3580
void addParty(const std::string &nick)
Definition: popupmenu.cpp:2665
void showChatPopup(const int x, const int y, ChatTab *const tab)
Definition: popupmenu.cpp:913
BeingId mFloorItemId
Definition: popupmenu.h:290
void showPlayerMenu()
Definition: popupmenu.cpp:2898
void showSkillLevelPopup(const SkillInfo *const info)
Definition: popupmenu.cpp:2356
BeingId mBeingId
Definition: popupmenu.h:289
void addWindowMenu(const Window *const window)
Definition: popupmenu.cpp:1185
void showWindowsPopup()
Definition: popupmenu.cpp:2217
void showFloorItemGMCommands()
Definition: popupmenu.cpp:3336
void addChat(const Being *const being)
Definition: popupmenu.cpp:2690
void setMousePos()
Definition: popupmenu.cpp:540
void addProtection()
Definition: popupmenu.cpp:2777
void showGuildPopup()
Definition: popupmenu.cpp:3556
void addCatchPetCommands()
Definition: popupmenu.cpp:3490
void handleLink(const std::string &link, MouseEvent *event)
Definition: popupmenu.cpp:1251
void clear()
Definition: popupmenu.cpp:2758
void showSkillOffsetPopup(const SkillInfo *const info, const bool isOffsetX)
Definition: popupmenu.cpp:2307
void moveUp()
Definition: popupmenu.cpp:3620
void showOutfitsWindowPopup(const int x, const int y)
Definition: popupmenu.cpp:853
void showPlayerGMCommands(const std::string &name)
Definition: popupmenu.cpp:2962
TextDialog * mDialog
Definition: popupmenu.h:301
void showPetGMCommands()
Definition: popupmenu.cpp:3452
void moveDown()
Definition: popupmenu.cpp:3625
bool isAllowOtherCommand(const ServerCommandTypeT command)
Definition: popupmenu.cpp:183
PlayerListener mPlayerListener
Definition: popupmenu.h:300
void showCraftPopup()
Definition: popupmenu.cpp:3460
void showMuteCommands()
Definition: popupmenu.cpp:3170
void showGMPopup(const std::string &name)
Definition: popupmenu.cpp:3396
void showSkillPopup(const SkillInfo *const info)
Definition: popupmenu.cpp:2263
void showEmoteType()
Definition: popupmenu.cpp:1215
void showChangePos(const int x, const int y)
Definition: popupmenu.cpp:1117
TextField * mTextField
Definition: popupmenu.h:306
void addNormalRelations()
Definition: popupmenu.cpp:2473
void showWindowPopup(Window *const window)
Definition: popupmenu.cpp:1164
bool addBeingMenu()
Definition: popupmenu.cpp:520
void showDropPopup(const int x, const int y, const Item *const item)
Definition: popupmenu.cpp:1849
void showPopup(const int x, const int y, const Being *const being)
Definition: popupmenu.cpp:203
void addItemMenu(const Item *const item, const InventoryTypeT type)
Definition: popupmenu.cpp:2817
Window * mCallerWindow
Definition: popupmenu.h:298
bool mAllowCleanMenu
Definition: popupmenu.h:311
ItemColor mItemColor
Definition: popupmenu.h:294
void showNpcGMCommands()
Definition: popupmenu.cpp:3233
Definition: popup.h:52
void setContentSize(int width, int height)
Definition: popup.cpp:155
int mPadding
Definition: popup.h:181
void postInit()
Definition: popup.h:177
const std::string & text() const
Definition: progressbar.h:119
void setDialog(TextDialog *dialog)
void setMapItem(const MapItem *const mapItem)
void setVerticalScrollPolicy(const ScrollPolicy vPolicy)
void setWidth(int width)
void setHeight(int height)
unsigned int cameraMode
Definition: settings.h:144
void removePortal(const int x, const int y)
void setTile(const int x, const int y, MapItem *const item)
void updateCache()
void addRow(const std::string &row, const bool atTop)
void setOpaque(Opaque opaque)
void addSeparator(const std::string &row)
void setLinkHandler(LinkHandler *linkHandler)
void close()
Definition: textdialog.cpp:141
void setText(const std::string &text)
Definition: textdialog.cpp:133
void handleCopy() const
Definition: textfield.cpp:701
void handlePaste()
Definition: textfield.cpp:629
int mMouseX
Definition: viewport.h:154
Map * getMap() const
Definition: viewport.h:135
int mMouseY
Definition: viewport.h:155
const std::string & getNick() const
Definition: whispertab.h:37
void setVisible(Visible visible)
Definition: widget.cpp:225
void setWidth(const int width)
Definition: widget.cpp:133
virtual void requestMoveToTop()
Definition: widget.cpp:213
static bool widgetExists(const Widget *const widget)
Definition: widget.cpp:361
void addMouseListener(MouseListener *const mouseListener)
Definition: widget.cpp:292
void setActionEventId(const std::string &actionEventId)
Definition: widget.h:596
int getY() const
Definition: widget.h:288
const std::string & getId() const
Definition: widget.h:919
Visible mVisible
Definition: widget.h:963
void addActionListener(ActionListener *const actionListener)
Definition: widget.cpp:252
void setPosition(const int x, const int y)
Definition: widget.cpp:161
int getX() const
Definition: widget.h:269
int getHeight() const
Definition: widget.h:240
const std::string & getActionEventId() const
Definition: widget.h:605
int getWidth() const
Definition: widget.h:221
void showButton(const std::string &name, const Visible visible)
Definition: windowmenu.cpp:447
std::vector< ButtonText * > & getButtonTexts()
Definition: windowmenu.h:76
std::vector< Button * > & getButtons()
Definition: windowmenu.h:73
Definition: window.h:102
virtual void close()
Definition: window.cpp:902
bool isWindowVisible() const
Definition: window.h:484
bool isSticky() const
Definition: window.h:253
bool getAlowClose() const
Definition: window.h:192
void setSticky(const bool sticky)
Definition: window.cpp:766
bool isStickyButtonLock() const
Definition: window.h:264
Configuration config
Configuration features
#define CREATEWIDGET(type,...)
Definition: createwidget.h:29
#define CREATEWIDGETR(type,...)
Definition: createwidget.h:36
#define CREATEWIDGETV(var, type,...)
Definition: createwidget.h:25
#define new
Definition: debug_new.h:147
Viewport * viewport
Definition: viewport.cpp:36
const bool Enable_true
Definition: enable.h:30
const bool Equipm_true
Definition: equipm.h:30
const bool Equipped_true
Definition: equipped.h:30
#define FOR_EACHP(type, iter, array)
Definition: foreach.h:31
#define FOR_EACH(type, iter, array)
Definition: foreach.h:25
#define _(s)
Definition: gettext.h:35
Graphics * mainGraphics
Definition: graphics.cpp:109
std::map< unsigned, std::string > PositionsMap
Definition: guild.h:35
Net::GuildHandler * guildHandler
Definition: net.cpp:92
GuildManager * guildManager
InputAction ::T InputActionT
Definition: inputaction.h:717
InputManager inputManager
#define toInt(val, name)
Definition: intdefines.h:47
#define fromInt(val, name)
Definition: intdefines.h:46
InventoryType ::T InventoryTypeT
Definition: inventorytype.h:42
const ItemColor ItemColor_one
Definition: itemcolor.h:30
uint16_t ItemColor
Definition: itemcolor.h:30
#define nullptr
Definition: localconsts.h:45
#define A_UNUSED
Definition: localconsts.h:160
LocalPlayer * localPlayer
uint32_t guild
uint32_t party
Minimap * minimap
Definition: minimap.cpp:62
MiniStatusWindow * miniStatusWindow
bool kick(InputEvent &event)
Definition: actions.cpp:111
bool where(InputEvent &event)
Definition: actions.cpp:67
bool heal(InputEvent &event)
Definition: actions.cpp:43
bool msg(InputEvent &event)
Definition: chat.cpp:39
bool slide(InputEvent &event)
Definition: commands.cpp:95
bool info(InputEvent &event)
Definition: commands.cpp:57
@ Mercenary
Definition: actortype.h:38
@ Homunculus
Definition: actortype.h:39
@ SkillUnit
Definition: actortype.h:40
@ Elemental
Definition: actortype.h:41
@ FloorItem
Definition: actortype.h:34
void load()
Definition: avatardb.cpp:46
std::string trim(std::string const &str)
std::string toString(T const &value)
converts any type to a string
Definition: catch.hpp:1774
MenuTypeT menu
Definition: menu.cpp:28
NpcDialog * mDialog
Definition: npcrecv.cpp:42
int size()
Definition: emotedb.cpp:306
const GroupInfo * getGroup(const int id)
Definition: groupdb.cpp:399
BeingInfo * get(const BeingTypeId id)
Definition: npcdb.cpp:188
ServerTypeT getNetworkType()
Definition: net.cpp:189
Inventory * getInventory()
Definition: playerinfo.cpp:195
bool isItemProtected(const int id)
Definition: playerinfo.cpp:515
HomunculusInfo * getHomunculus()
Definition: playerinfo.cpp:603
@ DISREGARDED
Definition: relation.h:33
@ ENEMY2
Definition: relation.h:37
@ IGNORED
Definition: relation.h:34
@ FRIEND
Definition: relation.h:32
@ ERASED
Definition: relation.h:35
@ NEUTRAL
Definition: relation.h:31
@ BLACKLISTED
Definition: relation.h:36
Net::NpcHandler * npcHandler
Definition: net.cpp:93
const bool Opaque_false
Definition: opaque.h:30
const bool Opaque_true
Definition: opaque.h:30
OutfitWindow * outfitWindow
PlayerRelationsManager playerRelations
std::string tradePartnerName
Definition: popupmenu.cpp:101
PopupMenu * popupMenu
Definition: popupmenu.cpp:103
ServerCommandType ::T ServerCommandTypeT
Settings settings
Definition: settings.cpp:32
SocialWindow * socialWindow
const int SPELL_MIN_ID
Definition: spells.h:27
std::string & replaceAll(std::string &context, const std::string &from, const std::string &to)
std::string strprintf(const char *const format,...)
std::string escapeString(std::string str)
std::string command
Definition: beingmenuitem.h:41
std::string name
Definition: beingmenuitem.h:40
std::string text
Definition: buttontext.h:42
InputActionT key
Definition: buttontext.h:43
std::string title
Definition: chatobject.h:51
Enable mPermissions[static_cast< size_t >(ServerPermissionType::Max)]
Definition: groupinfo.h:44
ServerCommandEnable::Type mCommands[static_cast< size_t >(ServerCommandType::Max)]
Definition: groupinfo.h:43
std::string command1
Definition: itemmenuitem.h:46
std::string command2
Definition: itemmenuitem.h:47
std::string name2
Definition: itemmenuitem.h:45
std::string name1
Definition: itemmenuitem.h:44
static const unsigned int TRADE
TradeWindow * tradeWindow
Definition: tradewindow.cpp:65
const bool Visible_false
Definition: visible.h:30
const bool Visible_true
Definition: visible.h:30
WindowMenu * windowMenu
Definition: windowmenu.cpp:51