summaryrefslogtreecommitdiff
path: root/src/progs/manaverse/actions/commands.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/progs/manaverse/actions/commands.cpp')
-rw-r--r--src/progs/manaverse/actions/commands.cpp2225
1 files changed, 2225 insertions, 0 deletions
diff --git a/src/progs/manaverse/actions/commands.cpp b/src/progs/manaverse/actions/commands.cpp
new file mode 100644
index 000000000..3f23fe5e3
--- /dev/null
+++ b/src/progs/manaverse/actions/commands.cpp
@@ -0,0 +1,2225 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2012-2020 The ManaPlus Developers
+ * Copyright (C) 2020-2023 The ManaVerse Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "actions/commands.h"
+
+#include "actormanager.h"
+#include "configuration.h"
+#include "game.h"
+#include "party.h"
+
+#include "actions/actiondef.h"
+
+#include "being/flooritem.h"
+#include "being/localplayer.h"
+#include "being/playerrelations.h"
+#include "being/homunculusinfo.h"
+#include "being/playerinfo.h"
+
+#include "const/resources/skill.h"
+
+#include "gui/viewport.h"
+
+#include "gui/popups/popupmenu.h"
+
+#include "gui/shortcut/emoteshortcut.h"
+#include "gui/shortcut/itemshortcut.h"
+
+#include "gui/windows/mailwindow.h"
+
+#include "gui/windows/chatwindow.h"
+#include "gui/windows/inventorywindow.h"
+#include "gui/windows/npcdialog.h"
+#include "gui/windows/outfitwindow.h"
+#include "gui/windows/shortcutwindow.h"
+#include "gui/windows/skilldialog.h"
+#include "gui/windows/socialwindow.h"
+
+#include "gui/widgets/tabs/chat/whispertab.h"
+
+#include "input/inputactionoperators.h"
+
+#include "listeners/inputactionreplaylistener.h"
+
+#include "net/adminhandler.h"
+#include "net/chathandler.h"
+#include "net/guildhandler.h"
+#include "net/familyhandler.h"
+#include "net/homunculushandler.h"
+#include "net/mail2handler.h"
+#include "net/mailhandler.h"
+#include "net/net.h"
+#include "net/npchandler.h"
+#include "net/partyhandler.h"
+#include "net/serverfeatures.h"
+
+#include "resources/chatobject.h"
+
+#include "resources/db/itemdb.h"
+
+#include "resources/map/map.h"
+
+#include "resources/skill/skillinfo.h"
+
+#include "utils/booleanoptions.h"
+#include "utils/chatutils.h"
+#include "utils/copynpaste.h"
+#include "utils/gmfunctions.h"
+#include "utils/parameters.h"
+#include "utils/process.h"
+
+#ifdef HAVE_MALLOC_TRIM
+#include <malloc.h>
+#endif
+
+#include "debug.h"
+
+namespace Actions
+{
+
+static std::string getNick(const InputEvent &event)
+{
+ std::string args = event.args;
+ if (args.empty())
+ {
+ if (event.tab == nullptr ||
+ event.tab->getType() != ChatTabType::WHISPER)
+ {
+ return std::string();
+ }
+
+ WhisperTab *const whisper = static_cast<WhisperTab *>(event.tab);
+ if (whisper->getNick().empty())
+ {
+ // TRANSLATORS: change relation
+ event.tab->chatLog(_("Please specify a name."),
+ ChatMsgType::BY_SERVER,
+ IgnoreRecord_false,
+ TryRemoveColors_true);
+ return std::string();
+ }
+ args = whisper->getNick();
+ }
+ return args;
+}
+
+static void reportRelation(const InputEvent &event,
+ const RelationT &rel,
+ const std::string &str1,
+ const std::string &str2)
+{
+ if (event.tab != nullptr)
+ {
+ if (playerRelations.getRelation(event.args) == rel)
+ {
+ // TRANSLATORS: unignore command
+ event.tab->chatLog(str1,
+ ChatMsgType::BY_SERVER,
+ IgnoreRecord_false,
+ TryRemoveColors_true);
+ }
+ else
+ {
+ // TRANSLATORS: unignore command
+ event.tab->chatLog(str2,
+ ChatMsgType::BY_SERVER,
+ IgnoreRecord_false,
+ TryRemoveColors_true);
+ }
+ }
+}
+
+static void changeRelation(const InputEvent &event,
+ const RelationT relation,
+ const std::string &relationText)
+{
+ std::string args = getNick(event);
+ if (args.empty())
+ return;
+
+ if (playerRelations.getRelation(args) == relation)
+ {
+ if (event.tab != nullptr)
+ {
+ // TRANSLATORS: change relation
+ event.tab->chatLog(strprintf(_("Player already %s!"),
+ relationText.c_str()),
+ ChatMsgType::BY_SERVER,
+ IgnoreRecord_false,
+ TryRemoveColors_true);
+ return;
+ }
+ }
+ else
+ {
+ playerRelations.setRelation(args, relation);
+ }
+
+ reportRelation(event,
+ relation,
+ // TRANSLATORS: change relation
+ strprintf(_("Player successfully %s!"), relationText.c_str()),
+ // TRANSLATORS: change relation
+ strprintf(_("Player could not be %s!"), relationText.c_str()));
+}
+
+impHandler(chatAnnounce)
+{
+ if (adminHandler != nullptr)
+ {
+ adminHandler->announce(event.args);
+ return true;
+ }
+ return false;
+}
+
+impHandler(chatIgnore)
+{
+ changeRelation(event, Relation::IGNORED, "ignored");
+ return true;
+}
+
+impHandler(chatUnignore)
+{
+ std::string args = getNick(event);
+ if (args.empty())
+ return false;
+
+ const RelationT rel = playerRelations.getRelation(args);
+ if (rel != Relation::NEUTRAL && rel != Relation::FRIEND)
+ {
+ playerRelations.setRelation(args, Relation::NEUTRAL);
+ }
+ else
+ {
+ if (event.tab != nullptr)
+ {
+ // TRANSLATORS: unignore command
+ event.tab->chatLog(_("Player wasn't ignored!"),
+ ChatMsgType::BY_SERVER,
+ IgnoreRecord_false,
+ TryRemoveColors_true);
+ }
+ return true;
+ }
+
+ reportRelation(event,
+ Relation::NEUTRAL,
+ // TRANSLATORS: unignore command
+ _("Player no longer ignored!"),
+ // TRANSLATORS: unignore command
+ _("Player could not be unignored!"));
+ return true;
+}
+
+impHandler(chatErase)
+{
+ std::string args = getNick(event);
+ if (args.empty())
+ return false;
+
+ if (playerRelations.getRelation(args) == Relation::ERASED)
+ {
+ if (event.tab != nullptr)
+ {
+ // TRANSLATORS: erase command
+ event.tab->chatLog(_("Player already erased!"),
+ ChatMsgType::BY_SERVER,
+ IgnoreRecord_false,
+ TryRemoveColors_true);
+ }
+ return true;
+ }
+ playerRelations.setRelation(args, Relation::ERASED);
+
+ reportRelation(event,
+ Relation::ERASED,
+ // TRANSLATORS: erase command
+ _("Player no longer erased!"),
+ // TRANSLATORS: erase command
+ _("Player could not be erased!"));
+ return true;
+}
+
+impHandler(chatFriend)
+{
+ // TRANSLATORS: adding friend command
+ changeRelation(event, Relation::FRIEND, _("friend"));
+ return true;
+}
+
+impHandler(chatDisregard)
+{
+ // TRANSLATORS: disregard command
+ changeRelation(event, Relation::DISREGARDED, _("disregarded"));
+ return true;
+}
+
+impHandler(chatNeutral)
+{
+ // TRANSLATORS: neutral command
+ changeRelation(event, Relation::NEUTRAL, _("neutral"));
+ return true;
+}
+
+impHandler(chatBlackList)
+{
+ // TRANSLATORS: blacklist command
+ changeRelation(event, Relation::BLACKLISTED, _("blacklisted"));
+ return true;
+}
+
+impHandler(chatEnemy)
+{
+ // TRANSLATORS: enemy command
+ changeRelation(event, Relation::ENEMY2, _("enemy"));
+ return true;
+}
+
+impHandler(chatNuke)
+{
+ if (actorManager == nullptr)
+ return false;
+
+ const std::string nick = getNick(event);
+ Being *const being = actorManager->findBeingByName(
+ nick, ActorType::Player);
+ if (being == nullptr)
+ return true;
+
+ actorManager->addBlock(being->getId());
+ actorManager->destroy(being);
+ return true;
+}
+
+impHandler(chatAdd)
+{
+ if (chatWindow == nullptr)
+ return false;
+
+ if (event.args.empty())
+ return true;
+
+ STD_VECTOR<int> str;
+ splitToIntVector(str, event.args, ',');
+ if (str.empty())
+ return true;
+
+ int id = str[0];
+ if (id == 0)
+ return true;
+
+ if (ItemDB::exists(id))
+ {
+ const std::string names = ItemDB::getNamesStr(str);
+ if (!names.empty())
+ chatWindow->addItemText(names);
+ return true;
+ }
+
+ const FloorItem *const floorItem = actorManager->findItem(
+ fromInt(id, BeingId));
+
+ if (floorItem != nullptr)
+ {
+ str[0] = floorItem->getItemId();
+ const std::string names = ItemDB::getNamesStr(str);
+ chatWindow->addItemText(names);
+ }
+ return true;
+}
+
+impHandler0(present)
+{
+ if (chatWindow != nullptr)
+ {
+ chatWindow->doPresent();
+ return true;
+ }
+ return false;
+}
+
+impHandler0(printAll)
+{
+ if (actorManager != nullptr)
+ {
+ actorManager->printAllToChat();
+ return true;
+ }
+ return false;
+}
+
+impHandler(move)
+{
+ int x = 0;
+ int y = 0;
+
+ if ((localPlayer != nullptr) && parse2Int(event.args, x, y))
+ {
+ localPlayer->setDestination(x, y);
+ return true;
+ }
+ return false;
+}
+
+impHandler(setTarget)
+{
+ if ((actorManager == nullptr) || (localPlayer == nullptr))
+ return false;
+
+ Being *const target = actorManager->findNearestByName(event.args,
+ ActorType::Unknown);
+ if (target != nullptr)
+ localPlayer->setTarget(target);
+ return true;
+}
+
+impHandler(commandOutfit)
+{
+ if (outfitWindow != nullptr)
+ {
+ if (!event.args.empty())
+ {
+ const std::string op = event.args.substr(0, 1);
+ if (op == "n")
+ {
+ outfitWindow->wearNextOutfit(true);
+ }
+ else if (op == "p")
+ {
+ outfitWindow->wearPreviousOutfit(true);
+ }
+ else
+ {
+ outfitWindow->wearOutfit(atoi(event.args.c_str()) - 1,
+ false, true);
+ }
+ }
+ else
+ {
+ outfitWindow->wearOutfit(atoi(event.args.c_str()) - 1,
+ false, true);
+ }
+ return true;
+ }
+ return false;
+}
+
+impHandler(commandEmote)
+{
+ LocalPlayer::emote(CAST_U8(atoi(event.args.c_str())));
+ return true;
+}
+
+impHandler(awayMessage)
+{
+ if (localPlayer != nullptr)
+ {
+ localPlayer->setAway(event.args);
+ return true;
+ }
+ return false;
+}
+
+impHandler(pseudoAway)
+{
+ if (localPlayer != nullptr)
+ {
+ LocalPlayer::setPseudoAway(event.args);
+ localPlayer->updateStatus();
+ return true;
+ }
+ return false;
+}
+
+impHandler(follow)
+{
+ if (localPlayer == nullptr)
+ return false;
+
+ if (!features.getBoolValue("allowFollow"))
+ return false;
+
+ if (!event.args.empty())
+ {
+ localPlayer->setFollow(event.args);
+ }
+ else if (event.tab != nullptr &&
+ event.tab->getType() == ChatTabType::WHISPER)
+ {
+ localPlayer->setFollow(static_cast<WhisperTab*>(event.tab)->getNick());
+ }
+ else
+ {
+ const Being *const being = localPlayer->getTarget();
+ if (being != nullptr)
+ localPlayer->setFollow(being->getName());
+ }
+ return true;
+}
+
+impHandler(navigate)
+{
+ if ((localPlayer == nullptr) ||
+ !localPlayer->canMove())
+ {
+ return false;
+ }
+
+ int x = 0;
+ int y = 0;
+
+ if (parse2Int(event.args, x, y))
+ localPlayer->navigateTo(x, y);
+ else
+ localPlayer->navigateClean();
+ return true;
+}
+
+impHandler(navigateTo)
+{
+ if ((localPlayer == nullptr) ||
+ !localPlayer->canMove())
+ {
+ return false;
+ }
+
+ const std::string args = event.args;
+ if (args.empty())
+ return true;
+
+ Being *const being = actorManager->findBeingByName(args,
+ ActorType::Unknown);
+ if (being != nullptr)
+ {
+ localPlayer->navigateTo(being->getTileX(), being->getTileY());
+ }
+ else if (localPlayer->isInParty())
+ {
+ const Party *const party = localPlayer->getParty();
+ if (party != nullptr)
+ {
+ const PartyMember *const m = party->getMember(args);
+ const PartyMember *const o = party->getMember(
+ localPlayer->getName());
+ if (m != nullptr &&
+ o != nullptr &&
+ m->getMap() == o->getMap())
+ {
+ localPlayer->navigateTo(m->getX(), m->getY());
+ }
+ }
+ }
+ return true;
+}
+
+impHandler(moveCamera)
+{
+ int x = 0;
+ int y = 0;
+
+ if (viewport == nullptr)
+ return false;
+
+ if (parse2Int(event.args, x, y))
+ viewport->moveCameraToPosition(x * mapTileSize, y * mapTileSize);
+ return true;
+}
+
+impHandler0(restoreCamera)
+{
+ if (viewport == nullptr)
+ return false;
+
+ viewport->returnCamera();
+ return true;
+}
+
+impHandler(imitation)
+{
+ if (localPlayer == nullptr)
+ return false;
+
+ if (!event.args.empty())
+ {
+ localPlayer->setImitate(event.args);
+ }
+ else if (event.tab != nullptr &&
+ event.tab->getType() == ChatTabType::WHISPER)
+ {
+ localPlayer->setImitate(static_cast<WhisperTab*>(
+ event.tab)->getNick());
+ }
+ else
+ {
+ localPlayer->setImitate("");
+ }
+ return true;
+}
+
+impHandler(sendMail)
+{
+#ifdef TMWA_SUPPORT
+ const ServerTypeT type = Net::getNetworkType();
+ if (type == ServerType::EATHENA || type == ServerType::EVOL2)
+#endif // TMWA_SUPPORT
+ {
+ std::string name;
+ std::string text;
+
+ if (parse2Str(event.args, name, text))
+ {
+ if (settings.enableNewMailSystem)
+ {
+ mail2Handler->queueCheckName(MailQueueType::SendMail,
+ name,
+ // TRANSLATORS: quick mail message caption
+ _("Quick message"),
+ text,
+ 0);
+ }
+ else
+ {
+ // TRANSLATORS: quick mail message caption
+ mailHandler->send(name, _("Quick message"), text);
+ }
+ }
+ }
+#ifdef TMWA_SUPPORT
+ else if (serverConfig.getBoolValue("enableManaMarketBot"))
+ {
+ chatHandler->privateMessage("ManaMarket", "!mail " + event.args);
+ return true;
+ }
+#endif // TMWA_SUPPORT
+
+ return false;
+}
+
+impHandler(info)
+{
+ if (event.tab == nullptr ||
+ localPlayer == nullptr ||
+ Net::getNetworkType() == ServerType::TMWATHENA)
+ {
+ return false;
+ }
+
+ if (guildHandler != nullptr &&
+ event.tab->getType() == ChatTabType::GUILD)
+ {
+ const Guild *const guild = localPlayer->getGuild();
+ if (guild != nullptr)
+ guildHandler->info();
+ }
+ return true;
+}
+
+impHandler(wait)
+{
+ if (localPlayer != nullptr)
+ {
+ localPlayer->waitFor(event.args);
+ return true;
+ }
+ return false;
+}
+
+impHandler(addPriorityAttack)
+{
+ if ((actorManager == nullptr) ||
+ actorManager->isInPriorityAttackList(event.args))
+ {
+ return false;
+ }
+
+ actorManager->removeAttackMob(event.args);
+ actorManager->addPriorityAttackMob(event.args);
+
+ if (socialWindow != nullptr)
+ socialWindow->updateAttackFilter();
+ return true;
+}
+
+impHandler(addAttack)
+{
+ if (actorManager == nullptr)
+ return false;
+
+ actorManager->removeAttackMob(event.args);
+ actorManager->addAttackMob(event.args);
+
+ if (socialWindow != nullptr)
+ socialWindow->updateAttackFilter();
+ return true;
+}
+
+impHandler(removeAttack)
+{
+ if (actorManager == nullptr)
+ return false;
+
+ if (event.args.empty())
+ {
+ if (actorManager->isInAttackList(event.args))
+ {
+ actorManager->removeAttackMob(event.args);
+ actorManager->addIgnoreAttackMob(event.args);
+ }
+ else
+ {
+ actorManager->removeAttackMob(event.args);
+ actorManager->addAttackMob(event.args);
+ }
+ }
+ else
+ {
+ actorManager->removeAttackMob(event.args);
+ }
+
+
+ if (socialWindow != nullptr)
+ socialWindow->updateAttackFilter();
+ return true;
+}
+
+impHandler(addIgnoreAttack)
+{
+ if (actorManager == nullptr)
+ return false;
+
+ actorManager->removeAttackMob(event.args);
+ actorManager->addIgnoreAttackMob(event.args);
+
+ if (socialWindow != nullptr)
+ socialWindow->updateAttackFilter();
+ return true;
+}
+
+impHandler(setDrop)
+{
+ GameModifiers::setQuickDropCounter(atoi(event.args.c_str()));
+ return true;
+}
+
+impHandler(url)
+{
+ if (event.tab != nullptr)
+ {
+ std::string url1 = event.args;
+ if (!strStartWith(url1, "http") && !strStartWith(url1, "ftp") &&
+ !strStartWith(url1, "?"))
+ url1 = "http://" + url1;
+ std::string str(strprintf("[@@%s |%s@@]",
+ url1.c_str(), event.args.c_str()));
+ outStringNormal(event.tab, str, str);
+ return true;
+ }
+ return false;
+}
+
+impHandler(openUrl)
+{
+ std::string url = event.args;
+ if (!strStartWith(url, "http") && !strStartWith(url, "ftp"))
+ url = "http://" + url;
+ openBrowser(url);
+ return true;
+}
+
+impHandler(execute)
+{
+ const size_t idx = event.args.find(' ');
+ std::string name;
+ std::string params;
+ if (idx == std::string::npos)
+ {
+ name = event.args;
+ }
+ else
+ {
+ name = event.args.substr(0, idx);
+ params = event.args.substr(idx + 1);
+ }
+ execFile(name, name, params, "");
+ return true;
+}
+
+impHandler(enableHighlight)
+{
+ if (event.tab != nullptr)
+ {
+ event.tab->setAllowHighlight(true);
+ if (chatWindow != nullptr)
+ {
+ chatWindow->saveState();
+ return true;
+ }
+ }
+ return false;
+}
+
+impHandler(disableHighlight)
+{
+ if (event.tab != nullptr)
+ {
+ event.tab->setAllowHighlight(false);
+ if (chatWindow != nullptr)
+ {
+ chatWindow->saveState();
+ return true;
+ }
+ }
+ return false;
+}
+
+impHandler(dontRemoveName)
+{
+ if (event.tab != nullptr)
+ {
+ event.tab->setRemoveNames(false);
+ if (chatWindow != nullptr)
+ {
+ chatWindow->saveState();
+ return true;
+ }
+ }
+ return false;
+}
+
+impHandler(removeName)
+{
+ if (event.tab != nullptr)
+ {
+ event.tab->setRemoveNames(true);
+ if (chatWindow != nullptr)
+ {
+ chatWindow->saveState();
+ return true;
+ }
+ }
+ return false;
+}
+
+impHandler(disableAway)
+{
+ if (event.tab != nullptr)
+ {
+ event.tab->setNoAway(true);
+ if (chatWindow != nullptr)
+ {
+ chatWindow->saveState();
+ return true;
+ }
+ }
+ return false;
+}
+
+impHandler(enableAway)
+{
+ if (event.tab != nullptr)
+ {
+ event.tab->setNoAway(false);
+ if (chatWindow != nullptr)
+ {
+ chatWindow->saveState();
+ return true;
+ }
+ }
+ return false;
+}
+
+impHandler(testParticle)
+{
+ if (localPlayer != nullptr)
+ {
+ localPlayer->setTestParticle(event.args, true);
+ return true;
+ }
+ return false;
+}
+
+impHandler(talkRaw)
+{
+ if (chatHandler != nullptr)
+ {
+ chatHandler->talkRaw(event.args);
+ return true;
+ }
+ return false;
+}
+
+impHandler(gm)
+{
+ if (chatHandler != nullptr)
+ {
+ Gm::runCommand("wgm", event.args);
+ return true;
+ }
+ return false;
+}
+
+impHandler(hack)
+{
+ if (chatHandler != nullptr)
+ {
+ chatHandler->sendRaw(event.args);
+ return true;
+ }
+ return false;
+}
+
+impHandler(debugSpawn)
+{
+ if (localPlayer == nullptr)
+ return false;
+ int cnt = atoi(event.args.c_str());
+ if (cnt < 1)
+ cnt = 1;
+ const int half = cnt / 2;
+ const Map *const map = localPlayer->getMap();
+ int x1 = -half;
+ if (x1 < 0)
+ x1 = 0;
+ int y1 = x1;
+ int x2 = cnt - half;
+ if (x2 > map->getWidth())
+ x2 = map->getWidth();
+ int y2 = x2;
+
+ for (int x = x1; x < x2; x ++)
+ {
+ for (int y = y1; y < y2; y ++)
+ ActorManager::cloneBeing(localPlayer, x, y, cnt);
+ }
+ return true;
+}
+
+impHandler(serverIgnoreWhisper)
+{
+ std::string args = getNick(event);
+ if (args.empty())
+ return false;
+
+ if (chatHandler != nullptr)
+ {
+ chatHandler->ignore(args);
+ return true;
+ }
+ return false;
+}
+
+impHandler(serverUnIgnoreWhisper)
+{
+ std::string args = getNick(event);
+ if (args.empty())
+ return false;
+
+ if (chatHandler != nullptr)
+ {
+ chatHandler->unIgnore(args);
+ return true;
+ }
+ return false;
+}
+
+impHandler(setHomunculusName)
+{
+ const std::string args = event.args;
+ if (args.empty())
+ {
+ const HomunculusInfo *const info = PlayerInfo::getHomunculus();
+ if (info != nullptr)
+ {
+ // TRANSLATORS: dialog header
+ inputActionReplayListener.openDialog(_("Rename your homun"),
+ info->name,
+ InputAction::HOMUNCULUS_SET_NAME);
+ }
+ return false;
+ }
+
+ if (homunculusHandler != nullptr)
+ {
+ homunculusHandler->setName(args);
+ return true;
+ }
+ return false;
+}
+
+impHandler0(fireHomunculus)
+{
+ if (homunculusHandler != nullptr)
+ {
+ homunculusHandler->fire();
+ return true;
+ }
+ return false;
+}
+
+impHandler0(leaveParty)
+{
+ if (partyHandler != nullptr)
+ {
+ partyHandler->leave();
+ return true;
+ }
+ return false;
+}
+
+impHandler0(leaveGuild)
+{
+ if ((guildHandler != nullptr) && (localPlayer != nullptr))
+ {
+ const Guild *const guild = localPlayer->getGuild();
+ if (guild != nullptr)
+ guildHandler->leave(guild->getId());
+ return true;
+ }
+ return false;
+}
+
+impHandler(warp)
+{
+ int x = 0;
+ int y = 0;
+
+ if ((adminHandler != nullptr) &&
+ (Game::instance() != nullptr) &&
+ parse2Int(event.args, x, y))
+ {
+ adminHandler->warp(Game::instance()->getCurrentMapName(),
+ x, y);
+ return true;
+ }
+ return false;
+}
+
+impHandler(homunTalk)
+{
+ if ((serverFeatures == nullptr) || !serverFeatures->haveTalkPet())
+ return false;
+
+ std::string args = event.args;
+ if (findCutFirst(args, "/me "))
+ args = textToMe(args);
+ if (homunculusHandler != nullptr)
+ {
+ homunculusHandler->talk(args);
+ return true;
+ }
+ return false;
+}
+
+impHandler(homunEmote)
+{
+ if ((serverFeatures == nullptr) || !serverFeatures->haveTalkPet())
+ return false;
+
+ if ((homunculusHandler != nullptr) &&
+ event.action >= InputAction::HOMUN_EMOTE_1 &&
+ event.action <= InputAction::HOMUN_EMOTE_48)
+ {
+ if (emoteShortcut != nullptr)
+ {
+ const int emotion = event.action - InputAction::HOMUN_EMOTE_1;
+ homunculusHandler->emote(emoteShortcut->getEmote(emotion));
+ }
+ if (Game::instance() != nullptr)
+ Game::instance()->setValidSpeed();
+ return true;
+ }
+
+ return false;
+}
+
+impHandler(commandHomunEmote)
+{
+ if ((serverFeatures == nullptr) || !serverFeatures->haveTalkPet())
+ return false;
+
+ if (homunculusHandler != nullptr)
+ {
+ homunculusHandler->emote(CAST_U8(
+ atoi(event.args.c_str())));
+ return true;
+ }
+ return false;
+}
+
+impHandler(createPublicChatRoom)
+{
+ if ((chatHandler == nullptr) || event.args.empty())
+ return false;
+ chatHandler->createChatRoom(event.args, "", 100, true);
+ return true;
+}
+
+impHandler(joinChatRoom)
+{
+ if (chatHandler == nullptr)
+ return false;
+ const std::string args = event.args;
+ if (args.empty())
+ return false;
+ ChatObject *const chat = ChatObject::findByName(args);
+ if (chat == nullptr)
+ return false;
+ chatHandler->joinChat(chat, "");
+ return true;
+}
+
+impHandler0(leaveChatRoom)
+{
+ if (chatHandler != nullptr)
+ {
+ chatHandler->leaveChatRoom();
+ return true;
+ }
+ return false;
+}
+
+impHandler(confSet)
+{
+ std::string name;
+ std::string val;
+
+ if (parse2Str(event.args, name, val))
+ {
+ config.setValue(name, val);
+ return true;
+ }
+ return false;
+}
+
+impHandler(serverConfSet)
+{
+ std::string name;
+ std::string val;
+
+ if (parse2Str(event.args, name, val))
+ {
+ serverConfig.setValue(name, val);
+ return true;
+ }
+ return false;
+}
+
+impHandler(confGet)
+{
+ const std::string args = event.args;
+ if (args.empty())
+ return false;
+
+ // TRANSLATORS: result from command /confget
+ const std::string str = strprintf(_("Config value: %s"),
+ config.getStringValue(args).c_str());
+ outStringNormal(event.tab, str, str);
+ return true;
+}
+
+impHandler(serverConfGet)
+{
+ const std::string args = event.args;
+ if (args.empty())
+ return false;
+
+ // TRANSLATORS: result from command /serverconfget
+ const std::string str = strprintf(_("Server config value: %s"),
+ serverConfig.getStringValue(args).c_str());
+ outStringNormal(event.tab, str, str);
+ return true;
+}
+
+impHandler(slide)
+{
+ int x = 0;
+ int y = 0;
+
+ if ((adminHandler != nullptr) && parse2Int(event.args, x, y))
+ {
+ adminHandler->slide(x, y);
+ return true;
+ }
+ return false;
+}
+
+impHandler(selectSkillLevel)
+{
+ int skill = 0;
+ int level = 0;
+
+ if ((skillDialog != nullptr) && parse2Int(event.args, skill, level))
+ {
+ skillDialog->selectSkillLevel(skill, level);
+ return true;
+ }
+ return false;
+}
+
+impHandler(skill)
+{
+ StringVect vect;
+ splitToStringVector(vect, event.args, ' ');
+ const int sz = CAST_S32(vect.size());
+ if (sz < 1)
+ return true;
+ const int skillId = atoi(vect[0].c_str());
+ int level = 0;
+ std::string text;
+ if (sz > 1)
+ {
+ level = atoi(vect[1].c_str());
+ if (sz > 2)
+ text = vect[2];
+ }
+ // +++ add here also cast type and offsets
+ if (text.empty())
+ {
+ SkillDialog::useSkill(skillId,
+ AutoTarget_true,
+ level,
+ false,
+ "",
+ CastType::Default,
+ 0,
+ 0);
+ }
+ else
+ {
+ SkillDialog::useSkill(skillId,
+ AutoTarget_true,
+ level,
+ true,
+ text,
+ CastType::Default,
+ 0,
+ 0);
+ }
+ return true;
+}
+
+impHandler(craft)
+{
+ const std::string args = event.args;
+ if (args.empty() || (inventoryWindow == nullptr))
+ return false;
+
+ inventoryWindow->moveItemToCraft(atoi(args.c_str()));
+ return true;
+}
+
+impHandler(npcClipboard)
+{
+ if (npcHandler != nullptr)
+ {
+ int x = 0;
+ int y = 0;
+
+ NpcDialog *const dialog = npcHandler->getCurrentNpcDialog();
+
+ if ((dialog != nullptr) && parse2Int(event.args, x, y))
+ {
+ dialog->copyToClipboard(x, y);
+ return true;
+ }
+ }
+ return false;
+}
+
+impHandler(clipboardCopy)
+{
+ const std::string args = event.args;
+ if (args.empty())
+ return false;
+ sendBuffer(args);
+ return true;
+}
+
+impHandler(addPickup)
+{
+ if (actorManager != nullptr)
+ {
+ actorManager->removePickupItem(event.args);
+ actorManager->addPickupItem(event.args);
+ if (socialWindow != nullptr)
+ socialWindow->updatePickupFilter();
+ return true;
+ }
+ return false;
+}
+
+impHandler(removePickup)
+{
+ if (actorManager != nullptr)
+ {
+ if (event.args.empty())
+ { // default pickup manipulation
+ if (actorManager->checkDefaultPickup())
+ {
+ actorManager->removePickupItem(event.args);
+ actorManager->addIgnorePickupItem(event.args);
+ }
+ else
+ {
+ actorManager->removePickupItem(event.args);
+ actorManager->addPickupItem(event.args);
+ }
+ }
+ else
+ { // any other pickups
+ actorManager->removePickupItem(event.args);
+ }
+ if (socialWindow != nullptr)
+ socialWindow->updatePickupFilter();
+ return true;
+ }
+ return false;
+}
+
+impHandler(ignorePickup)
+{
+ if (actorManager != nullptr)
+ {
+ actorManager->removePickupItem(event.args);
+ actorManager->addIgnorePickupItem(event.args);
+ if (socialWindow != nullptr)
+ socialWindow->updatePickupFilter();
+ return true;
+ }
+ return false;
+}
+
+impHandler(monsterInfo)
+{
+ const std::string args = event.args;
+ if (args.empty())
+ return false;
+ adminHandler->monsterInfo(args);
+ return true;
+}
+
+impHandler(itemInfo)
+{
+ const std::string args = event.args;
+ if (args.empty())
+ return false;
+ adminHandler->itemInfo(args);
+ return true;
+}
+
+impHandler(whoDrops)
+{
+ const std::string args = event.args;
+ if (args.empty())
+ return false;
+ adminHandler->whoDrops(args);
+ return true;
+}
+
+impHandler(mobSearch)
+{
+ const std::string args = event.args;
+ if (args.empty())
+ return false;
+ adminHandler->mobSearch(args);
+ return true;
+}
+
+impHandler(mobSpawnSearch)
+{
+ const std::string args = event.args;
+ if (args.empty())
+ return false;
+ adminHandler->mobSpawnSearch(args);
+ return true;
+}
+
+impHandler(playerGmCommands)
+{
+ adminHandler->playerGmCommands(event.args);
+ return true;
+}
+
+impHandler(playerCharGmCommands)
+{
+ adminHandler->playerCharGmCommands(event.args);
+ return true;
+}
+
+impHandler(commandShowLevel)
+{
+ adminHandler->showLevel(event.args);
+ return true;
+}
+
+impHandler(commandShowStats)
+{
+ adminHandler->showStats(event.args);
+ return true;
+}
+
+impHandler(commandShowStorage)
+{
+ adminHandler->showStorageList(event.args);
+ return true;
+}
+
+impHandler(commandShowCart)
+{
+ adminHandler->showCartList(event.args);
+ return true;
+}
+
+impHandler(commandShowInventory)
+{
+ adminHandler->showInventoryList(event.args);
+ return true;
+}
+
+impHandler(locatePlayer)
+{
+ const std::string args = event.args;
+ if (args.empty())
+ return false;
+ adminHandler->locatePlayer(args);
+ return true;
+}
+
+impHandler(commandShowAccountInfo)
+{
+ const std::string args = event.args;
+ if (args.empty())
+ return false;
+ adminHandler->showAccountInfo(args);
+ return true;
+}
+
+impHandler(commandSpawn)
+{
+ const std::string args = event.args;
+ if (args.empty())
+ return false;
+ adminHandler->spawn(args);
+ return true;
+}
+
+impHandler(commandSpawnSlave)
+{
+ const std::string args = event.args;
+ if (args.empty())
+ return false;
+ adminHandler->spawnSlave(args);
+ return true;
+}
+
+impHandler(commandSpawnClone)
+{
+ const std::string args = event.args;
+ if (args.empty())
+ return false;
+ adminHandler->spawnClone(args);
+ return true;
+}
+
+impHandler(commandSpawnSlaveClone)
+{
+ const std::string args = event.args;
+ if (args.empty())
+ return false;
+ adminHandler->spawnSlaveClone(args);
+ return true;
+}
+
+impHandler(commandSpawnEvilClone)
+{
+ const std::string args = event.args;
+ if (args.empty())
+ return false;
+ adminHandler->spawnEvilClone(args);
+ return true;
+}
+
+impHandler(commandSavePosition)
+{
+ adminHandler->savePosition(event.args);
+ return true;
+}
+
+impHandler(commandLoadPosition)
+{
+ adminHandler->loadPosition(event.args);
+ return true;
+}
+
+impHandler(commandRandomWarp)
+{
+ adminHandler->randomWarp(event.args);
+ return true;
+}
+
+impHandler(commandGotoNpc)
+{
+ const std::string args = event.args;
+ if (args.empty())
+ return false;
+ adminHandler->gotoNpc(args);
+ return true;
+}
+
+impHandler(commandGotoPc)
+{
+ const std::string args = event.args;
+ if (args.empty())
+ return false;
+ adminHandler->gotoName(args);
+ return true;
+}
+
+impHandler(commandRecallPc)
+{
+ const std::string args = event.args;
+ if (args.empty())
+ return false;
+ adminHandler->recallName(args);
+ return true;
+}
+
+impHandler(commandIpCheck)
+{
+ const std::string args = event.args;
+ if (args.empty())
+ return false;
+ adminHandler->ipcheckName(args);
+ return true;
+}
+
+impHandler(commandKiller)
+{
+ adminHandler->killer(event.args);
+ return true;
+}
+
+impHandler(commandKillable)
+{
+ adminHandler->killable(event.args);
+ return true;
+}
+
+impHandler(commandHeal)
+{
+ adminHandler->heal(event.args);
+ return true;
+}
+
+impHandler(commandAlive)
+{
+ adminHandler->alive(event.args);
+ return true;
+}
+
+impHandler(commandDisguise)
+{
+ const std::string args = event.args;
+ if (args.empty())
+ return false;
+ adminHandler->disguise(args);
+ return true;
+}
+
+impHandler(commandImmortal)
+{
+ adminHandler->immortal(event.args);
+ return true;
+}
+
+impHandler(commandHide)
+{
+ adminHandler->hide(event.args);
+ return true;
+}
+
+impHandler(commandNuke)
+{
+ const std::string args = event.args;
+ if (args.empty())
+ return false;
+ adminHandler->nuke(args);
+ return true;
+}
+
+impHandler(commandKill)
+{
+ adminHandler->kill(event.args);
+ return true;
+}
+
+impHandler(commandJail)
+{
+ const std::string args = event.args;
+ if (args.empty())
+ return false;
+ adminHandler->jail(args);
+ return true;
+}
+
+impHandler(commandUnjail)
+{
+ const std::string args = event.args;
+ if (args.empty())
+ return false;
+ adminHandler->unjail(args);
+ return true;
+}
+
+impHandler(commandNpcMove)
+{
+ const std::string args = event.args;
+ if (args.empty())
+ return false;
+ StringVect pars;
+ if (!splitParameters(pars, args, " ,", '\"'))
+ return false;
+
+ if (pars.size() != 3)
+ return false;
+
+ adminHandler->npcMove(pars[0],
+ atoi(pars[1].c_str()),
+ atoi(pars[2].c_str()));
+ return true;
+}
+
+impHandler(commandNpcHide)
+{
+ const std::string args = event.args;
+ if (args.empty())
+ return false;
+ adminHandler->hideNpc(args);
+ return true;
+}
+
+impHandler(commandNpcShow)
+{
+ const std::string args = event.args;
+ if (args.empty())
+ return false;
+ adminHandler->showNpc(args);
+ return true;
+}
+
+impHandler(commandChangePartyLeader)
+{
+ const std::string args = event.args;
+ if (args.empty())
+ return false;
+ adminHandler->changePartyLeader(args);
+ return true;
+}
+
+impHandler(commandPartyRecall)
+{
+ const std::string args = event.args;
+ if (args.empty())
+ return false;
+ adminHandler->partyRecall(args);
+ return true;
+}
+
+impHandler(commandBreakGuild)
+{
+ adminHandler->breakGuild(event.args);
+ return true;
+}
+
+impHandler(commandGuildRecall)
+{
+ const std::string args = event.args;
+ if (args.empty())
+ return false;
+ adminHandler->guildRecall(args);
+ return true;
+}
+
+impHandler(mailTo)
+{
+ if (mailWindow == nullptr)
+ return false;
+ const std::string args = event.args;
+ if (settings.enableNewMailSystem)
+ {
+ mail2Handler->queueCheckName(MailQueueType::EditMail,
+ args,
+ std::string(),
+ std::string(),
+ 0);
+ }
+ else
+ {
+ MailWindow::createMail(args);
+ }
+ return true;
+}
+
+impHandler(adoptChild)
+{
+ const std::string nick = getNick(event);
+ Being *const being = actorManager->findBeingByName(
+ nick, ActorType::Player);
+ if (being == nullptr)
+ return true;
+ familyHandler->askForChild(being);
+ return true;
+}
+
+impHandler(showSkillLevels)
+{
+ const std::string args = event.args;
+ if (args.empty())
+ return false;
+ const SkillInfo *restrict const skill = skillDialog->getSkill(
+ atoi(args.c_str()));
+ if (skill == nullptr)
+ return false;
+ popupMenu->showSkillLevelPopup(skill);
+ return true;
+}
+
+impHandler(showSkillType)
+{
+ const std::string args = event.args;
+ if (args.empty())
+ return false;
+ const SkillInfo *restrict const skill = skillDialog->getSkill(
+ atoi(args.c_str()));
+ if (skill == nullptr)
+ return false;
+ popupMenu->showSkillTypePopup(skill);
+ return true;
+}
+
+impHandler(selectSkillType)
+{
+ int skill = 0;
+ int type = 0;
+
+ if ((skillDialog != nullptr) && parse2Int(event.args, skill, type))
+ {
+ skillDialog->selectSkillCastType(skill,
+ static_cast<CastTypeT>(type));
+ return true;
+ }
+ return false;
+}
+
+impHandler(showSkillOffsetX)
+{
+ const std::string args = event.args;
+ if (args.empty())
+ return false;
+ const SkillInfo *restrict const skill = skillDialog->getSkill(
+ atoi(args.c_str()));
+ if (skill == nullptr)
+ return false;
+ popupMenu->showSkillOffsetPopup(skill, true);
+ return true;
+}
+
+impHandler(showSkillOffsetY)
+{
+ const std::string args = event.args;
+ if (args.empty())
+ return false;
+ const SkillInfo *restrict const skill = skillDialog->getSkill(
+ atoi(args.c_str()));
+ if (skill == nullptr)
+ return false;
+ popupMenu->showSkillOffsetPopup(skill, false);
+ return true;
+}
+
+impHandler(setSkillOffsetX)
+{
+ int skill = 0;
+ int offset = 0;
+
+ if ((skillDialog != nullptr) && parse2Int(event.args, skill, offset))
+ {
+ skillDialog->setSkillOffsetX(skill, offset);
+ return true;
+ }
+ return false;
+}
+
+impHandler(setSkillOffsetY)
+{
+ int skill = 0;
+ int offset = 0;
+
+ if ((skillDialog != nullptr) && parse2Int(event.args, skill, offset))
+ {
+ skillDialog->setSkillOffsetY(skill, offset);
+ return true;
+ }
+ return false;
+}
+
+impHandler(partyItemShare)
+{
+ if (localPlayer == nullptr)
+ return false;
+
+ if (localPlayer->isInParty() == false)
+ return true;
+
+ ChatTab *tab = event.tab;
+ if (tab == nullptr)
+ tab = localChatTab;
+ if (tab == nullptr)
+ return true;
+
+ const std::string args = event.args;
+ if (args.empty())
+ {
+ switch (partyHandler->getShareItems())
+ {
+ case PartyShare::YES:
+ // TRANSLATORS: chat message
+ tab->chatLog(_("Item sharing enabled."),
+ ChatMsgType::BY_SERVER,
+ IgnoreRecord_false,
+ TryRemoveColors_true);
+ return true;
+ case PartyShare::NO:
+ // TRANSLATORS: chat message
+ tab->chatLog(_("Item sharing disabled."),
+ ChatMsgType::BY_SERVER,
+ IgnoreRecord_false,
+ TryRemoveColors_true);
+ return true;
+ case PartyShare::NOT_POSSIBLE:
+ // TRANSLATORS: chat message
+ tab->chatLog(_("Item sharing not possible."),
+ ChatMsgType::BY_SERVER,
+ IgnoreRecord_false,
+ TryRemoveColors_true);
+ return true;
+ case PartyShare::UNKNOWN:
+ // TRANSLATORS: chat message
+ tab->chatLog(_("Item sharing unknown."),
+ ChatMsgType::BY_SERVER,
+ IgnoreRecord_false,
+ TryRemoveColors_true);
+ return true;
+ default:
+ break;
+ }
+ }
+
+ const signed char opt = parseBoolean(args);
+
+ switch (opt)
+ {
+ case 1:
+ partyHandler->setShareItems(
+ PartyShare::YES);
+ break;
+ case 0:
+ partyHandler->setShareItems(
+ PartyShare::NO);
+ break;
+ case -1:
+ tab->chatLog(strprintf(BOOLEAN_OPTIONS, "item"),
+ ChatMsgType::BY_SERVER,
+ IgnoreRecord_false,
+ TryRemoveColors_true);
+ break;
+ default:
+ break;
+ }
+ return true;
+}
+
+impHandler(partyExpShare)
+{
+ if (localPlayer == nullptr)
+ return false;
+
+ if (localPlayer->isInParty() == false)
+ return true;
+
+ ChatTab *tab = event.tab;
+ if (tab == nullptr)
+ tab = localChatTab;
+ if (tab == nullptr)
+ return true;
+
+ const std::string args = event.args;
+ if (args.empty())
+ {
+ switch (partyHandler->getShareExperience())
+ {
+ case PartyShare::YES:
+ // TRANSLATORS: chat message
+ tab->chatLog(_("Experience sharing enabled."),
+ ChatMsgType::BY_SERVER,
+ IgnoreRecord_false,
+ TryRemoveColors_true);
+ return true;
+ case PartyShare::NO:
+ // TRANSLATORS: chat message
+ tab->chatLog(_("Experience sharing disabled."),
+ ChatMsgType::BY_SERVER,
+ IgnoreRecord_false,
+ TryRemoveColors_true);
+ return true;
+ case PartyShare::NOT_POSSIBLE:
+ // TRANSLATORS: chat message
+ tab->chatLog(_("Experience sharing not possible."),
+ ChatMsgType::BY_SERVER,
+ IgnoreRecord_false,
+ TryRemoveColors_true);
+ return true;
+ case PartyShare::UNKNOWN:
+ // TRANSLATORS: chat message
+ tab->chatLog(_("Experience sharing unknown."),
+ ChatMsgType::BY_SERVER,
+ IgnoreRecord_false,
+ TryRemoveColors_true);
+ return true;
+ default:
+ break;
+ }
+ }
+
+ const signed char opt = parseBoolean(args);
+
+ switch (opt)
+ {
+ case 1:
+ partyHandler->setShareExperience(
+ PartyShare::YES);
+ break;
+ case 0:
+ partyHandler->setShareExperience(
+ PartyShare::NO);
+ break;
+ case -1:
+ tab->chatLog(strprintf(BOOLEAN_OPTIONS, "exp"),
+ ChatMsgType::BY_SERVER,
+ IgnoreRecord_false,
+ TryRemoveColors_true);
+ break;
+ default:
+ break;
+ }
+ return true;
+}
+
+impHandler(partyAutoItemShare)
+{
+ if (localPlayer == nullptr)
+ return false;
+
+ if (localPlayer->isInParty() == false)
+ return true;
+
+ ChatTab *tab = event.tab;
+ if (tab == nullptr)
+ tab = localChatTab;
+ if (tab == nullptr)
+ return true;
+
+ const std::string args = event.args;
+ if (args.empty())
+ {
+ switch (partyHandler->getShareAutoItems())
+ {
+ case PartyShare::YES:
+ // TRANSLATORS: chat message
+ tab->chatLog(_("Auto item sharing enabled."),
+ ChatMsgType::BY_SERVER,
+ IgnoreRecord_false,
+ TryRemoveColors_true);
+ return true;
+ case PartyShare::NO:
+ // TRANSLATORS: chat message
+ tab->chatLog(_("Auto item sharing disabled."),
+ ChatMsgType::BY_SERVER,
+ IgnoreRecord_false,
+ TryRemoveColors_true);
+ return true;
+ case PartyShare::NOT_POSSIBLE:
+ // TRANSLATORS: chat message
+ tab->chatLog(_("Auto item sharing not possible."),
+ ChatMsgType::BY_SERVER,
+ IgnoreRecord_false,
+ TryRemoveColors_true);
+ return true;
+ case PartyShare::UNKNOWN:
+ // TRANSLATORS: chat message
+ tab->chatLog(_("Auto item sharing unknown."),
+ ChatMsgType::BY_SERVER,
+ IgnoreRecord_false,
+ TryRemoveColors_true);
+ return true;
+ default:
+ break;
+ }
+ }
+
+ const signed char opt = parseBoolean(args);
+
+ switch (opt)
+ {
+ case 1:
+ partyHandler->setShareAutoItems(
+ PartyShare::YES);
+ break;
+ case 0:
+ partyHandler->setShareAutoItems(
+ PartyShare::NO);
+ break;
+ case -1:
+ tab->chatLog(strprintf(BOOLEAN_OPTIONS, "item"),
+ ChatMsgType::BY_SERVER,
+ IgnoreRecord_false,
+ TryRemoveColors_true);
+ break;
+ default:
+ break;
+ }
+ return true;
+}
+
+impHandler0(outfitToChat)
+{
+ if ((outfitWindow == nullptr) || (chatWindow == nullptr))
+ return false;
+
+ const std::string str = outfitWindow->getOutfitString();
+ if (!str.empty())
+ chatWindow->addInputText(str, true);
+ return true;
+}
+
+impHandler0(outfitClear)
+{
+ if (outfitWindow == nullptr)
+ return false;
+
+ outfitWindow->clearCurrentOutfit();
+ return true;
+}
+
+impHandler(moveAttackUp)
+{
+ if (actorManager == nullptr)
+ return false;
+ const std::string args = event.args;
+ const int idx = actorManager->getAttackMobIndex(args);
+ if (idx > 0)
+ {
+ std::list<std::string> mobs
+ = actorManager->getAttackMobs();
+ std::list<std::string>::iterator it = mobs.begin();
+ std::list<std::string>::iterator it2 = it;
+ while (it != mobs.end())
+ {
+ if (*it == args)
+ {
+ -- it2;
+ mobs.splice(it2, mobs, it);
+ actorManager->setAttackMobs(mobs);
+ actorManager->rebuildAttackMobs();
+ break;
+ }
+ ++ it;
+ ++ it2;
+ }
+
+ if (socialWindow != nullptr)
+ socialWindow->updateAttackFilter();
+ return true;
+ }
+ return false;
+}
+
+impHandler(moveAttackDown)
+{
+ if (actorManager == nullptr)
+ return false;
+ const std::string args = event.args;
+ const int idx = actorManager->getAttackMobIndex(args);
+ const int size = actorManager->getAttackMobsSize();
+ if (idx + 1 < size)
+ {
+ std::list<std::string> mobs
+ = actorManager->getAttackMobs();
+ std::list<std::string>::iterator it = mobs.begin();
+ std::list<std::string>::iterator it2 = it;
+ while (it != mobs.end())
+ {
+ if (*it == args)
+ {
+ ++ it2;
+ if (it2 == mobs.end())
+ break;
+
+ mobs.splice(it, mobs, it2);
+ actorManager->setAttackMobs(mobs);
+ actorManager->rebuildAttackMobs();
+ break;
+ }
+ ++ it;
+ ++ it2;
+ }
+
+ if (socialWindow != nullptr)
+ socialWindow->updateAttackFilter();
+ return true;
+ }
+ return false;
+}
+
+impHandler(movePriorityAttackUp)
+{
+ if (actorManager == nullptr)
+ return false;
+ const std::string args = event.args;
+ const int idx = actorManager->
+ getPriorityAttackMobIndex(args);
+ if (idx > 0)
+ {
+ std::list<std::string> mobs
+ = actorManager->getPriorityAttackMobs();
+ std::list<std::string>::iterator it = mobs.begin();
+ std::list<std::string>::iterator it2 = it;
+ while (it != mobs.end())
+ {
+ if (*it == args)
+ {
+ -- it2;
+ mobs.splice(it2, mobs, it);
+ actorManager->setPriorityAttackMobs(mobs);
+ actorManager->rebuildPriorityAttackMobs();
+ break;
+ }
+ ++ it;
+ ++ it2;
+ }
+
+ if (socialWindow != nullptr)
+ socialWindow->updateAttackFilter();
+ return true;
+ }
+ return false;
+}
+
+impHandler(movePriorityAttackDown)
+{
+ if (actorManager == nullptr)
+ return false;
+ const std::string args = event.args;
+ const int idx = actorManager
+ ->getPriorityAttackMobIndex(args);
+ const int size = actorManager->getPriorityAttackMobsSize();
+ if (idx + 1 < size)
+ {
+ std::list<std::string> mobs
+ = actorManager->getPriorityAttackMobs();
+ std::list<std::string>::iterator it = mobs.begin();
+ std::list<std::string>::iterator it2 = it;
+ while (it != mobs.end())
+ {
+ if (*it == args)
+ {
+ ++ it2;
+ if (it2 == mobs.end())
+ break;
+
+ mobs.splice(it, mobs, it2);
+ actorManager->setPriorityAttackMobs(mobs);
+ actorManager->rebuildPriorityAttackMobs();
+ break;
+ }
+ ++ it;
+ ++ it2;
+ }
+
+ if (socialWindow != nullptr)
+ socialWindow->updateAttackFilter();
+ return true;
+ }
+ return false;
+}
+
+impHandler(addSkillShortcut)
+{
+ const std::string args = event.args;
+ if (args.empty() ||
+ itemShortcutWindow == nullptr)
+ {
+ return false;
+ }
+ const SkillInfo *restrict const skill = skillDialog->getSkill(
+ atoi(args.c_str()));
+ if (skill == nullptr)
+ return false;
+
+ const int num = itemShortcutWindow->getTabIndex();
+ if (num < 0 ||
+ num >= CAST_S32(SHORTCUT_TABS) ||
+ num == CAST_S32(SHORTCUT_AUTO_TAB))
+ {
+ return false;
+ }
+
+ ItemShortcut *const selShortcut = itemShortcut[num];
+ const size_t index = selShortcut->getFreeIndex();
+ if (index == SHORTCUT_ITEMS)
+ return true;
+
+ selShortcut->setItem(index,
+ skill->id + SKILL_MIN_ID,
+ fromInt(skill->customSelectedLevel, ItemColor));
+ selShortcut->setItemData(index,
+ skill->toDataStr());
+
+// popupMenu->showSkillLevelPopup(skill);
+ return true;
+}
+
+impHandler0(trimMemory)
+{
+#ifdef HAVE_MALLOC_TRIM
+ malloc_trim(0);
+#else
+ // TRANSLATORS: chat error about trim command
+ localChatTab->chatLog(_("Trim memory not supported"),
+ ChatMsgType::BY_SERVER,
+ IgnoreRecord_false,
+ TryRemoveColors_true);
+#endif
+ return true;
+}
+
+} // namespace Actions