GCC Code Coverage Report
Directory: src/ Exec Total Coverage
File: src/progs/manaplus/actions/commands.cpp Lines: 1 928 0.1 %
Date: 2017-11-29 Branches: 0 987 0.0 %

Line Branch Exec Source
1
/*
2
 *  The ManaPlus Client
3
 *  Copyright (C) 2012-2017  The ManaPlus Developers
4
 *
5
 *  This file is part of The ManaPlus Client.
6
 *
7
 *  This program is free software; you can redistribute it and/or modify
8
 *  it under the terms of the GNU General Public License as published by
9
 *  the Free Software Foundation; either version 2 of the License, or
10
 *  any later version.
11
 *
12
 *  This program is distributed in the hope that it will be useful,
13
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 *  GNU General Public License for more details.
16
 *
17
 *  You should have received a copy of the GNU General Public License
18
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
19
 */
20
21
#include "actions/commands.h"
22
23
#include "actormanager.h"
24
#include "configuration.h"
25
#include "game.h"
26
#include "party.h"
27
28
#include "actions/actiondef.h"
29
30
#include "being/flooritem.h"
31
#include "being/localplayer.h"
32
#include "being/playerrelations.h"
33
#include "being/homunculusinfo.h"
34
#include "being/playerinfo.h"
35
36
#include "const/resources/skill.h"
37
38
#include "gui/viewport.h"
39
40
#include "gui/popups/popupmenu.h"
41
42
#include "gui/shortcut/emoteshortcut.h"
43
#include "gui/shortcut/itemshortcut.h"
44
45
#include "gui/windows/mailwindow.h"
46
47
#include "gui/windows/chatwindow.h"
48
#include "gui/windows/inventorywindow.h"
49
#include "gui/windows/npcdialog.h"
50
#include "gui/windows/outfitwindow.h"
51
#include "gui/windows/shortcutwindow.h"
52
#include "gui/windows/skilldialog.h"
53
#include "gui/windows/socialwindow.h"
54
55
#include "gui/widgets/tabs/chat/whispertab.h"
56
57
#include "input/inputactionoperators.h"
58
59
#include "listeners/inputactionreplaylistener.h"
60
61
#include "net/adminhandler.h"
62
#include "net/chathandler.h"
63
#include "net/guildhandler.h"
64
#include "net/familyhandler.h"
65
#include "net/homunculushandler.h"
66
#include "net/mail2handler.h"
67
#include "net/mailhandler.h"
68
#include "net/net.h"
69
#include "net/npchandler.h"
70
#include "net/partyhandler.h"
71
#include "net/serverfeatures.h"
72
73
#include "resources/chatobject.h"
74
75
#include "resources/db/itemdb.h"
76
77
#include "resources/map/map.h"
78
79
#include "resources/skill/skillinfo.h"
80
81
#include "utils/booleanoptions.h"
82
#include "utils/chatutils.h"
83
#include "utils/copynpaste.h"
84
#include "utils/gmfunctions.h"
85
#include "utils/parameters.h"
86
#include "utils/process.h"
87
88
#include "debug.h"
89
90
namespace Actions
91
{
92
93
static std::string getNick(const InputEvent &event)
94
{
95
    std::string args = event.args;
96
    if (args.empty())
97
    {
98
        if (event.tab == nullptr ||
99
            event.tab->getType() != ChatTabType::WHISPER)
100
        {
101
            return std::string();
102
        }
103
104
        WhisperTab *const whisper = static_cast<WhisperTab *>(event.tab);
105
        if (whisper->getNick().empty())
106
        {
107
            // TRANSLATORS: change relation
108
            event.tab->chatLog(_("Please specify a name."),
109
                ChatMsgType::BY_SERVER);
110
            return std::string();
111
        }
112
        args = whisper->getNick();
113
    }
114
    return args;
115
}
116
117
static void reportRelation(const InputEvent &event,
118
                           const RelationT &rel,
119
                           const std::string &str1,
120
                           const std::string &str2)
121
{
122
    if (event.tab != nullptr)
123
    {
124
        if (playerRelations.getRelation(event.args) == rel)
125
        {
126
            // TRANSLATORS: unignore command
127
            event.tab->chatLog(str1, ChatMsgType::BY_SERVER);
128
        }
129
        else
130
        {
131
            // TRANSLATORS: unignore command
132
            event.tab->chatLog(str2, ChatMsgType::BY_SERVER);
133
        }
134
    }
135
}
136
137
static void changeRelation(const InputEvent &event,
138
                           const RelationT relation,
139
                           const std::string &relationText)
140
{
141
    std::string args = getNick(event);
142
    if (args.empty())
143
        return;
144
145
    if (playerRelations.getRelation(args) == relation)
146
    {
147
        if (event.tab != nullptr)
148
        {
149
            // TRANSLATORS: change relation
150
            event.tab->chatLog(strprintf(_("Player already %s!"),
151
                relationText.c_str()), ChatMsgType::BY_SERVER);
152
            return;
153
        }
154
    }
155
    else
156
    {
157
        playerRelations.setRelation(args, relation);
158
    }
159
160
    reportRelation(event,
161
        relation,
162
        // TRANSLATORS: change relation
163
        strprintf(_("Player successfully %s!"), relationText.c_str()),
164
        // TRANSLATORS: change relation
165
        strprintf(_("Player could not be %s!"), relationText.c_str()));
166
}
167
168
impHandler(chatAnnounce)
169
{
170
    if (adminHandler != nullptr)
171
    {
172
        adminHandler->announce(event.args);
173
        return true;
174
    }
175
    return false;
176
}
177
178
impHandler(chatIgnore)
179
{
180
    changeRelation(event, Relation::IGNORED, "ignored");
181
    return true;
182
}
183
184
impHandler(chatUnignore)
185
{
186
    std::string args = getNick(event);
187
    if (args.empty())
188
        return false;
189
190
    const RelationT rel = playerRelations.getRelation(args);
191
    if (rel != Relation::NEUTRAL && rel != Relation::FRIEND)
192
    {
193
        playerRelations.setRelation(args, Relation::NEUTRAL);
194
    }
195
    else
196
    {
197
        if (event.tab != nullptr)
198
        {
199
            // TRANSLATORS: unignore command
200
            event.tab->chatLog(_("Player wasn't ignored!"),
201
                ChatMsgType::BY_SERVER);
202
        }
203
        return true;
204
    }
205
206
    reportRelation(event,
207
        Relation::NEUTRAL,
208
        // TRANSLATORS: unignore command
209
        _("Player no longer ignored!"),
210
        // TRANSLATORS: unignore command
211
        _("Player could not be unignored!"));
212
    return true;
213
}
214
215
impHandler(chatErase)
216
{
217
    std::string args = getNick(event);
218
    if (args.empty())
219
        return false;
220
221
    if (playerRelations.getRelation(args) == Relation::ERASED)
222
    {
223
        if (event.tab != nullptr)
224
        {
225
            // TRANSLATORS: erase command
226
            event.tab->chatLog(_("Player already erased!"),
227
                ChatMsgType::BY_SERVER);
228
        }
229
        return true;
230
    }
231
    playerRelations.setRelation(args, Relation::ERASED);
232
233
    reportRelation(event,
234
        Relation::ERASED,
235
        // TRANSLATORS: erase command
236
        _("Player no longer erased!"),
237
        // TRANSLATORS: erase command
238
        _("Player could not be erased!"));
239
    return true;
240
}
241
242
impHandler(chatFriend)
243
{
244
    // TRANSLATORS: adding friend command
245
    changeRelation(event, Relation::FRIEND, _("friend"));
246
    return true;
247
}
248
249
impHandler(chatDisregard)
250
{
251
    // TRANSLATORS: disregard command
252
    changeRelation(event, Relation::DISREGARDED, _("disregarded"));
253
    return true;
254
}
255
256
impHandler(chatNeutral)
257
{
258
    // TRANSLATORS: neutral command
259
    changeRelation(event, Relation::NEUTRAL, _("neutral"));
260
    return true;
261
}
262
263
impHandler(chatBlackList)
264
{
265
    // TRANSLATORS: blacklist command
266
    changeRelation(event, Relation::BLACKLISTED, _("blacklisted"));
267
    return true;
268
}
269
270
impHandler(chatEnemy)
271
{
272
    // TRANSLATORS: enemy command
273
    changeRelation(event, Relation::ENEMY2, _("enemy"));
274
    return true;
275
}
276
277
impHandler(chatNuke)
278
{
279
    if (actorManager == nullptr)
280
        return false;
281
282
    const std::string nick = getNick(event);
283
    Being *const being = actorManager->findBeingByName(
284
        nick, ActorType::Player);
285
    if (being == nullptr)
286
        return true;
287
288
    actorManager->addBlock(being->getId());
289
    actorManager->destroy(being);
290
    return true;
291
}
292
293
impHandler(chatAdd)
294
{
295
    if (chatWindow == nullptr)
296
        return false;
297
298
    if (event.args.empty())
299
        return true;
300
301
    STD_VECTOR<int> str;
302
    splitToIntVector(str, event.args, ',');
303
    if (str.empty())
304
        return true;
305
306
    int id = str[0];
307
    if (id == 0)
308
        return true;
309
310
    if (ItemDB::exists(id))
311
    {
312
        const std::string names = ItemDB::getNamesStr(str);
313
        if (!names.empty())
314
            chatWindow->addItemText(names);
315
        return true;
316
    }
317
318
    const FloorItem *const floorItem = actorManager->findItem(
319
        fromInt(id, BeingId));
320
321
    if (floorItem != nullptr)
322
    {
323
        str[0] =  floorItem->getItemId();
324
        const std::string names = ItemDB::getNamesStr(str);
325
        chatWindow->addItemText(names);
326
    }
327
    return true;
328
}
329
330
impHandler0(present)
331
{
332
    if (chatWindow != nullptr)
333
    {
334
        chatWindow->doPresent();
335
        return true;
336
    }
337
    return false;
338
}
339
340
impHandler0(printAll)
341
{
342
    if (actorManager != nullptr)
343
    {
344
        actorManager->printAllToChat();
345
        return true;
346
    }
347
    return false;
348
}
349
350
impHandler(move)
351
{
352
    int x = 0;
353
    int y = 0;
354
355
    if ((localPlayer != nullptr) && parse2Int(event.args, x, y))
356
    {
357
        localPlayer->setDestination(x, y);
358
        return true;
359
    }
360
    return false;
361
}
362
363
impHandler(setTarget)
364
{
365
    if ((actorManager == nullptr) || (localPlayer == nullptr))
366
        return false;
367
368
    Being *const target = actorManager->findNearestByName(event.args);
369
    if (target != nullptr)
370
        localPlayer->setTarget(target);
371
    return true;
372
}
373
374
impHandler(commandOutfit)
375
{
376
    if (outfitWindow != nullptr)
377
    {
378
        if (!event.args.empty())
379
        {
380
            const std::string op = event.args.substr(0, 1);
381
            if (op == "n")
382
            {
383
                outfitWindow->wearNextOutfit(true);
384
            }
385
            else if (op == "p")
386
            {
387
                outfitWindow->wearPreviousOutfit(true);
388
            }
389
            else
390
            {
391
                outfitWindow->wearOutfit(atoi(event.args.c_str()) - 1,
392
                    false, true);
393
            }
394
        }
395
        else
396
        {
397
            outfitWindow->wearOutfit(atoi(event.args.c_str()) - 1,
398
                false, true);
399
        }
400
        return true;
401
    }
402
    return false;
403
}
404
405
impHandler(commandEmote)
406
{
407
    LocalPlayer::emote(CAST_U8(atoi(event.args.c_str())));
408
    return true;
409
}
410
411
impHandler(awayMessage)
412
{
413
    if (localPlayer != nullptr)
414
    {
415
        localPlayer->setAway(event.args);
416
        return true;
417
    }
418
    return false;
419
}
420
421
impHandler(pseudoAway)
422
{
423
    if (localPlayer != nullptr)
424
    {
425
        LocalPlayer::setPseudoAway(event.args);
426
        localPlayer->updateStatus();
427
        return true;
428
    }
429
    return false;
430
}
431
432
impHandler(follow)
433
{
434
    if (localPlayer == nullptr)
435
        return false;
436
437
    if (!features.getBoolValue("allowFollow"))
438
        return false;
439
440
    if (!event.args.empty())
441
    {
442
        localPlayer->setFollow(event.args);
443
    }
444
    else if (event.tab != nullptr &&
445
             event.tab->getType() == ChatTabType::WHISPER)
446
    {
447
        localPlayer->setFollow(static_cast<WhisperTab*>(event.tab)->getNick());
448
    }
449
    else
450
    {
451
        const Being *const being = localPlayer->getTarget();
452
        if (being != nullptr)
453
            localPlayer->setFollow(being->getName());
454
    }
455
    return true;
456
}
457
458
impHandler(navigate)
459
{
460
    if ((localPlayer == nullptr) ||
461
        !localPlayer->canMove())
462
    {
463
        return false;
464
    }
465
466
    int x = 0;
467
    int y = 0;
468
469
    if (parse2Int(event.args, x, y))
470
        localPlayer->navigateTo(x, y);
471
    else
472
        localPlayer->navigateClean();
473
    return true;
474
}
475
476
impHandler(navigateTo)
477
{
478
    if ((localPlayer == nullptr) ||
479
        !localPlayer->canMove())
480
    {
481
        return false;
482
    }
483
484
    const std::string args = event.args;
485
    if (args.empty())
486
        return true;
487
488
    Being *const being = actorManager->findBeingByName(args);
489
    if (being != nullptr)
490
    {
491
        localPlayer->navigateTo(being->getTileX(), being->getTileY());
492
    }
493
    else if (localPlayer->isInParty())
494
    {
495
        const Party *const party = localPlayer->getParty();
496
        if (party != nullptr)
497
        {
498
            const PartyMember *const m = party->getMember(args);
499
            const PartyMember *const o = party->getMember(
500
                localPlayer->getName());
501
            if (m != nullptr &&
502
                o != nullptr &&
503
                m->getMap() == o->getMap())
504
            {
505
                localPlayer->navigateTo(m->getX(), m->getY());
506
            }
507
        }
508
    }
509
    return true;
510
}
511
512
impHandler(moveCamera)
513
{
514
    int x = 0;
515
    int y = 0;
516
517
    if (viewport == nullptr)
518
        return false;
519
520
    if (parse2Int(event.args, x, y))
521
        viewport->moveCameraToPosition(x * mapTileSize, y * mapTileSize);
522
    return true;
523
}
524
525
impHandler0(restoreCamera)
526
{
527
    if (viewport == nullptr)
528
        return false;
529
530
    viewport->returnCamera();
531
    return true;
532
}
533
534
impHandler(imitation)
535
{
536
    if (localPlayer == nullptr)
537
        return false;
538
539
    if (!event.args.empty())
540
    {
541
        localPlayer->setImitate(event.args);
542
    }
543
    else if (event.tab != nullptr &&
544
             event.tab->getType() == ChatTabType::WHISPER)
545
    {
546
        localPlayer->setImitate(static_cast<WhisperTab*>(
547
            event.tab)->getNick());
548
    }
549
    else
550
    {
551
        localPlayer->setImitate("");
552
    }
553
    return true;
554
}
555
556
impHandler(sendMail)
557
{
558
#ifdef TMWA_SUPPORT
559
    const ServerTypeT type = Net::getNetworkType();
560
    if (type == ServerType::EATHENA || type == ServerType::EVOL2)
561
#endif  // TMWA_SUPPORT
562
    {
563
        std::string name;
564
        std::string text;
565
566
        if (parse2Str(event.args, name, text))
567
        {
568
            if (settings.enableNewMailSystem)
569
            {
570
                mail2Handler->queueCheckName(MailQueueType::SendMail,
571
                    name,
572
                    // TRANSLATORS: quick mail message caption
573
                    _("Quick message"),
574
                    text,
575
                    0);
576
            }
577
            else
578
            {
579
                // TRANSLATORS: quick mail message caption
580
                mailHandler->send(name, _("Quick message"), text);
581
            }
582
        }
583
    }
584
#ifdef TMWA_SUPPORT
585
    else if (serverConfig.getBoolValue("enableManaMarketBot"))
586
    {
587
        chatHandler->privateMessage("ManaMarket", "!mail " + event.args);
588
        return true;
589
    }
590
#endif  // TMWA_SUPPORT
591
592
    return false;
593
}
594
595
impHandler(info)
596
{
597
    if (event.tab == nullptr ||
598
        localPlayer == nullptr ||
599
        Net::getNetworkType() == ServerType::TMWATHENA)
600
    {
601
        return false;
602
    }
603
604
    if (guildHandler != nullptr &&
605
        event.tab->getType() == ChatTabType::GUILD)
606
    {
607
        const Guild *const guild = localPlayer->getGuild();
608
        if (guild != nullptr)
609
            guildHandler->info();
610
    }
611
    return true;
612
}
613
614
impHandler(wait)
615
{
616
    if (localPlayer != nullptr)
617
    {
618
        localPlayer->waitFor(event.args);
619
        return true;
620
    }
621
    return false;
622
}
623
624
impHandler(addPriorityAttack)
625
{
626
    if ((actorManager == nullptr) ||
627
        actorManager->isInPriorityAttackList(event.args))
628
    {
629
        return false;
630
    }
631
632
    actorManager->removeAttackMob(event.args);
633
    actorManager->addPriorityAttackMob(event.args);
634
635
    if (socialWindow != nullptr)
636
        socialWindow->updateAttackFilter();
637
    return true;
638
}
639
640
impHandler(addAttack)
641
{
642
    if (actorManager == nullptr)
643
        return false;
644
645
    actorManager->removeAttackMob(event.args);
646
    actorManager->addAttackMob(event.args);
647
648
    if (socialWindow != nullptr)
649
        socialWindow->updateAttackFilter();
650
    return true;
651
}
652
653
impHandler(removeAttack)
654
{
655
    if (actorManager == nullptr)
656
        return false;
657
658
    if (event.args.empty())
659
    {
660
        if (actorManager->isInAttackList(event.args))
661
        {
662
            actorManager->removeAttackMob(event.args);
663
            actorManager->addIgnoreAttackMob(event.args);
664
        }
665
        else
666
        {
667
            actorManager->removeAttackMob(event.args);
668
            actorManager->addAttackMob(event.args);
669
        }
670
    }
671
    else
672
    {
673
        actorManager->removeAttackMob(event.args);
674
    }
675
676
677
    if (socialWindow != nullptr)
678
        socialWindow->updateAttackFilter();
679
    return true;
680
}
681
682
impHandler(addIgnoreAttack)
683
{
684
    if (actorManager == nullptr)
685
        return false;
686
687
    actorManager->removeAttackMob(event.args);
688
    actorManager->addIgnoreAttackMob(event.args);
689
690
    if (socialWindow != nullptr)
691
        socialWindow->updateAttackFilter();
692
    return true;
693
}
694
695
impHandler(setDrop)
696
{
697
    GameModifiers::setQuickDropCounter(atoi(event.args.c_str()));
698
    return true;
699
}
700
701
impHandler(url)
702
{
703
    if (event.tab != nullptr)
704
    {
705
        std::string url1 = event.args;
706
        if (!strStartWith(url1, "http") && !strStartWith(url1, "?"))
707
            url1 = "http://" + url1;
708
        std::string str(strprintf("[@@%s |%[email protected]@]",
709
            url1.c_str(), event.args.c_str()));
710
        outStringNormal(event.tab, str, str);
711
        return true;
712
    }
713
    return false;
714
}
715
716
impHandler(openUrl)
717
{
718
    std::string url = event.args;
719
    if (!strStartWith(url, "http"))
720
        url = "http://" + url;
721
    openBrowser(url);
722
    return true;
723
}
724
725
impHandler(execute)
726
{
727
    const size_t idx = event.args.find(' ');
728
    std::string name;
729
    std::string params;
730
    if (idx == std::string::npos)
731
    {
732
        name = event.args;
733
    }
734
    else
735
    {
736
        name = event.args.substr(0, idx);
737
        params = event.args.substr(idx + 1);
738
    }
739
    execFile(name, name, params, "");
740
    return true;
741
}
742
743
impHandler(enableHighlight)
744
{
745
    if (event.tab != nullptr)
746
    {
747
        event.tab->setAllowHighlight(true);
748
        if (chatWindow != nullptr)
749
        {
750
            chatWindow->saveState();
751
            return true;
752
        }
753
    }
754
    return false;
755
}
756
757
impHandler(disableHighlight)
758
{
759
    if (event.tab != nullptr)
760
    {
761
        event.tab->setAllowHighlight(false);
762
        if (chatWindow != nullptr)
763
        {
764
            chatWindow->saveState();
765
            return true;
766
        }
767
    }
768
    return false;
769
}
770
771
impHandler(dontRemoveName)
772
{
773
    if (event.tab != nullptr)
774
    {
775
        event.tab->setRemoveNames(false);
776
        if (chatWindow != nullptr)
777
        {
778
            chatWindow->saveState();
779
            return true;
780
        }
781
    }
782
    return false;
783
}
784
785
impHandler(removeName)
786
{
787
    if (event.tab != nullptr)
788
    {
789
        event.tab->setRemoveNames(true);
790
        if (chatWindow != nullptr)
791
        {
792
            chatWindow->saveState();
793
            return true;
794
        }
795
    }
796
    return false;
797
}
798
799
impHandler(disableAway)
800
{
801
    if (event.tab != nullptr)
802
    {
803
        event.tab->setNoAway(true);
804
        if (chatWindow != nullptr)
805
        {
806
            chatWindow->saveState();
807
            return true;
808
        }
809
    }
810
    return false;
811
}
812
813
impHandler(enableAway)
814
{
815
    if (event.tab != nullptr)
816
    {
817
        event.tab->setNoAway(false);
818
        if (chatWindow != nullptr)
819
        {
820
            chatWindow->saveState();
821
            return true;
822
        }
823
    }
824
    return false;
825
}
826
827
impHandler(testParticle)
828
{
829
    if (localPlayer != nullptr)
830
    {
831
        localPlayer->setTestParticle(event.args);
832
        return true;
833
    }
834
    return false;
835
}
836
837
impHandler(talkRaw)
838
{
839
    if (chatHandler != nullptr)
840
    {
841
        chatHandler->talkRaw(event.args);
842
        return true;
843
    }
844
    return false;
845
}
846
847
impHandler(gm)
848
{
849
    if (chatHandler != nullptr)
850
    {
851
        Gm::runCommand("wgm", event.args);
852
        return true;
853
    }
854
    return false;
855
}
856
857
impHandler(hack)
858
{
859
    if (chatHandler != nullptr)
860
    {
861
        chatHandler->sendRaw(event.args);
862
        return true;
863
    }
864
    return false;
865
}
866
867
impHandler(debugSpawn)
868
{
869
    if (localPlayer == nullptr)
870
        return false;
871
    int cnt = atoi(event.args.c_str());
872
    if (cnt < 1)
873
        cnt = 1;
874
    const int half = cnt / 2;
875
    const Map *const map = localPlayer->getMap();
876
    int x1 = -half;
877
    if (x1 < 0)
878
        x1 = 0;
879
    int y1 = x1;
880
    int x2 = cnt - half;
881
    if (x2 > map->getWidth())
882
        x2 = map->getWidth();
883
    int y2 = x2;
884
885
    for (int x = x1; x < x2; x ++)
886
    {
887
        for (int y = y1; y < y2; y ++)
888
            ActorManager::cloneBeing(localPlayer, x, y, cnt);
889
    }
890
    return true;
891
}
892
893
impHandler(serverIgnoreWhisper)
894
{
895
    std::string args = getNick(event);
896
    if (args.empty())
897
        return false;
898
899
    if (chatHandler != nullptr)
900
    {
901
        chatHandler->ignore(args);
902
        return true;
903
    }
904
    return false;
905
}
906
907
impHandler(serverUnIgnoreWhisper)
908
{
909
    std::string args = getNick(event);
910
    if (args.empty())
911
        return false;
912
913
    if (chatHandler != nullptr)
914
    {
915
        chatHandler->unIgnore(args);
916
        return true;
917
    }
918
    return false;
919
}
920
921
impHandler(setHomunculusName)
922
{
923
    const std::string args = event.args;
924
    if (args.empty())
925
    {
926
        const HomunculusInfo *const info = PlayerInfo::getHomunculus();
927
        if (info != nullptr)
928
        {
929
            // TRANSLATORS: dialog header
930
            inputActionReplayListener.openDialog(_("Rename your homun"),
931
                info->name,
932
                InputAction::HOMUNCULUS_SET_NAME);
933
        }
934
        return false;
935
    }
936
937
    if (homunculusHandler != nullptr)
938
    {
939
        homunculusHandler->setName(args);
940
        return true;
941
    }
942
    return false;
943
}
944
945
impHandler0(fireHomunculus)
946
{
947
    if (homunculusHandler != nullptr)
948
    {
949
        homunculusHandler->fire();
950
        return true;
951
    }
952
    return false;
953
}
954
955
impHandler0(leaveParty)
956
{
957
    if (partyHandler != nullptr)
958
    {
959
        partyHandler->leave();
960
        return true;
961
    }
962
    return false;
963
}
964
965
impHandler0(leaveGuild)
966
{
967
    if ((guildHandler != nullptr) && (localPlayer != nullptr))
968
    {
969
        const Guild *const guild = localPlayer->getGuild();
970
        if (guild != nullptr)
971
            guildHandler->leave(guild->getId());
972
        return true;
973
    }
974
    return false;
975
}
976
977
impHandler(warp)
978
{
979
    int x = 0;
980
    int y = 0;
981
982
    if ((adminHandler != nullptr) &&
983
        (Game::instance() != nullptr) &&
984
        parse2Int(event.args, x, y))
985
    {
986
        adminHandler->warp(Game::instance()->getCurrentMapName(),
987
            x, y);
988
        return true;
989
    }
990
    return false;
991
}
992
993
impHandler(homunTalk)
994
{
995
    if ((serverFeatures == nullptr) || !serverFeatures->haveTalkPet())
996
        return false;
997
998
    std::string args = event.args;
999
    if (findCutFirst(args, "/me "))
1000
        args = textToMe(args);
1001
    if (homunculusHandler != nullptr)
1002
    {
1003
        homunculusHandler->talk(args);
1004
        return true;
1005
    }
1006
    return false;
1007
}
1008
1009
impHandler(homunEmote)
1010
{
1011
    if ((serverFeatures == nullptr) || !serverFeatures->haveTalkPet())
1012
        return false;
1013
1014
    if ((homunculusHandler != nullptr) &&
1015
        event.action >= InputAction::HOMUN_EMOTE_1 &&
1016
        event.action <= InputAction::HOMUN_EMOTE_48)
1017
    {
1018
        const int emotion = event.action - InputAction::HOMUN_EMOTE_1;
1019
        if (emoteShortcut != nullptr)
1020
            homunculusHandler->emote(emoteShortcut->getEmote(emotion));
1021
        if (Game::instance() != nullptr)
1022
            Game::instance()->setValidSpeed();
1023
        return true;
1024
    }
1025
1026
    return false;
1027
}
1028
1029
impHandler(commandHomunEmote)
1030
{
1031
    if ((serverFeatures == nullptr) || !serverFeatures->haveTalkPet())
1032
        return false;
1033
1034
    if (homunculusHandler != nullptr)
1035
    {
1036
        homunculusHandler->emote(CAST_U8(
1037
            atoi(event.args.c_str())));
1038
        return true;
1039
    }
1040
    return false;
1041
}
1042
1043
impHandler(createPublicChatRoom)
1044
{
1045
    if ((chatHandler == nullptr) || event.args.empty())
1046
        return false;
1047
    chatHandler->createChatRoom(event.args, "", 100, true);
1048
    return true;
1049
}
1050
1051
impHandler(joinChatRoom)
1052
{
1053
    if (chatHandler == nullptr)
1054
        return false;
1055
    const std::string args = event.args;
1056
    if (args.empty())
1057
        return false;
1058
    ChatObject *const chat = ChatObject::findByName(args);
1059
    if (chat == nullptr)
1060
        return false;
1061
    chatHandler->joinChat(chat, "");
1062
    return true;
1063
}
1064
1065
impHandler0(leaveChatRoom)
1066
{
1067
    if (chatHandler != nullptr)
1068
    {
1069
        chatHandler->leaveChatRoom();
1070
        return true;
1071
    }
1072
    return false;
1073
}
1074
1075
impHandler(confSet)
1076
{
1077
    std::string name;
1078
    std::string val;
1079
1080
    if (parse2Str(event.args, name, val))
1081
    {
1082
        config.setValue(name, val);
1083
        return true;
1084
    }
1085
    return false;
1086
}
1087
1088
impHandler(serverConfSet)
1089
{
1090
    std::string name;
1091
    std::string val;
1092
1093
    if (parse2Str(event.args, name, val))
1094
    {
1095
        serverConfig.setValue(name, val);
1096
        return true;
1097
    }
1098
    return false;
1099
}
1100
1101
impHandler(confGet)
1102
{
1103
    const std::string args = event.args;
1104
    if (args.empty())
1105
        return false;
1106
1107
    // TRANSLATORS: result from command /confget
1108
    const std::string str = strprintf(_("Config value: %s"),
1109
        config.getStringValue(args).c_str());
1110
    outStringNormal(event.tab, str, str);
1111
    return true;
1112
}
1113
1114
impHandler(serverConfGet)
1115
{
1116
    const std::string args = event.args;
1117
    if (args.empty())
1118
        return false;
1119
1120
    // TRANSLATORS: result from command /serverconfget
1121
    const std::string str = strprintf(_("Server config value: %s"),
1122
        serverConfig.getStringValue(args).c_str());
1123
    outStringNormal(event.tab, str, str);
1124
    return true;
1125
}
1126
1127
impHandler(slide)
1128
{
1129
    int x = 0;
1130
    int y = 0;
1131
1132
    if ((adminHandler != nullptr) && parse2Int(event.args, x, y))
1133
    {
1134
        adminHandler->slide(x, y);
1135
        return true;
1136
    }
1137
    return false;
1138
}
1139
1140
impHandler(selectSkillLevel)
1141
{
1142
    int skill = 0;
1143
    int level = 0;
1144
1145
    if ((skillDialog != nullptr) && parse2Int(event.args, skill, level))
1146
    {
1147
        skillDialog->selectSkillLevel(skill, level);
1148
        return true;
1149
    }
1150
    return false;
1151
}
1152
1153
impHandler(skill)
1154
{
1155
    StringVect vect;
1156
    splitToStringVector(vect, event.args, ' ');
1157
    const int sz = CAST_S32(vect.size());
1158
    if (sz < 1)
1159
        return true;
1160
    const int skillId = atoi(vect[0].c_str());
1161
    int level = 0;
1162
    std::string text;
1163
    if (sz > 1)
1164
    {
1165
        level = atoi(vect[1].c_str());
1166
        if (sz > 2)
1167
            text = vect[2];
1168
    }
1169
    // +++ add here also cast type and offsets
1170
    if (text.empty())
1171
    {
1172
        SkillDialog::useSkill(skillId,
1173
            AutoTarget_true,
1174
            level,
1175
            false,
1176
            "",
1177
            CastType::Default,
1178
            0,
1179
            0);
1180
    }
1181
    else
1182
    {
1183
        SkillDialog::useSkill(skillId,
1184
            AutoTarget_true,
1185
            level,
1186
            true,
1187
            text,
1188
            CastType::Default,
1189
            0,
1190
            0);
1191
    }
1192
    return true;
1193
}
1194
1195
impHandler(craft)
1196
{
1197
    const std::string args = event.args;
1198
    if (args.empty() || (inventoryWindow == nullptr))
1199
        return false;
1200
1201
    inventoryWindow->moveItemToCraft(atoi(args.c_str()));
1202
    return true;
1203
}
1204
1205
impHandler(npcClipboard)
1206
{
1207
    if (npcHandler != nullptr)
1208
    {
1209
        int x = 0;
1210
        int y = 0;
1211
1212
        NpcDialog *const dialog = npcHandler->getCurrentNpcDialog();
1213
1214
        if ((dialog != nullptr) && parse2Int(event.args, x, y))
1215
        {
1216
            dialog->copyToClipboard(x, y);
1217
            return true;
1218
        }
1219
    }
1220
    return false;
1221
}
1222
1223
impHandler(clipboardCopy)
1224
{
1225
    const std::string args = event.args;
1226
    if (args.empty())
1227
        return false;
1228
    sendBuffer(args);
1229
    return true;
1230
}
1231
1232
impHandler(addPickup)
1233
{
1234
    if (actorManager != nullptr)
1235
    {
1236
        actorManager->removePickupItem(event.args);
1237
        actorManager->addPickupItem(event.args);
1238
        if (socialWindow != nullptr)
1239
            socialWindow->updatePickupFilter();
1240
        return true;
1241
    }
1242
    return false;
1243
}
1244
1245
impHandler(removePickup)
1246
{
1247
    if (actorManager != nullptr)
1248
    {
1249
        if (event.args.empty())
1250
        {   // default pickup manipulation
1251
            if (actorManager->checkDefaultPickup())
1252
            {
1253
                actorManager->removePickupItem(event.args);
1254
                actorManager->addIgnorePickupItem(event.args);
1255
            }
1256
            else
1257
            {
1258
                actorManager->removePickupItem(event.args);
1259
                actorManager->addPickupItem(event.args);
1260
            }
1261
        }
1262
        else
1263
        {   // any other pickups
1264
            actorManager->removePickupItem(event.args);
1265
        }
1266
        if (socialWindow != nullptr)
1267
            socialWindow->updatePickupFilter();
1268
        return true;
1269
    }
1270
    return false;
1271
}
1272
1273
impHandler(ignorePickup)
1274
{
1275
    if (actorManager != nullptr)
1276
    {
1277
        actorManager->removePickupItem(event.args);
1278
        actorManager->addIgnorePickupItem(event.args);
1279
        if (socialWindow != nullptr)
1280
            socialWindow->updatePickupFilter();
1281
        return true;
1282
    }
1283
    return false;
1284
}
1285
1286
impHandler(monsterInfo)
1287
{
1288
    const std::string args = event.args;
1289
    if (args.empty())
1290
        return false;
1291
    adminHandler->monsterInfo(args);
1292
    return true;
1293
}
1294
1295
impHandler(itemInfo)
1296
{
1297
    const std::string args = event.args;
1298
    if (args.empty())
1299
        return false;
1300
    adminHandler->itemInfo(args);
1301
    return true;
1302
}
1303
1304
impHandler(whoDrops)
1305
{
1306
    const std::string args = event.args;
1307
    if (args.empty())
1308
        return false;
1309
    adminHandler->whoDrops(args);
1310
    return true;
1311
}
1312
1313
impHandler(mobSearch)
1314
{
1315
    const std::string args = event.args;
1316
    if (args.empty())
1317
        return false;
1318
    adminHandler->mobSearch(args);
1319
    return true;
1320
}
1321
1322
impHandler(mobSpawnSearch)
1323
{
1324
    const std::string args = event.args;
1325
    if (args.empty())
1326
        return false;
1327
    adminHandler->mobSpawnSearch(args);
1328
    return true;
1329
}
1330
1331
impHandler(playerGmCommands)
1332
{
1333
    adminHandler->playerGmCommands(event.args);
1334
    return true;
1335
}
1336
1337
impHandler(playerCharGmCommands)
1338
{
1339
    adminHandler->playerCharGmCommands(event.args);
1340
    return true;
1341
}
1342
1343
impHandler(commandShowLevel)
1344
{
1345
    adminHandler->showLevel(event.args);
1346
    return true;
1347
}
1348
1349
impHandler(commandShowStats)
1350
{
1351
    adminHandler->showStats(event.args);
1352
    return true;
1353
}
1354
1355
impHandler(commandShowStorage)
1356
{
1357
    adminHandler->showStorageList(event.args);
1358
    return true;
1359
}
1360
1361
impHandler(commandShowCart)
1362
{
1363
    adminHandler->showCartList(event.args);
1364
    return true;
1365
}
1366
1367
impHandler(commandShowInventory)
1368
{
1369
    adminHandler->showInventoryList(event.args);
1370
    return true;
1371
}
1372
1373
impHandler(locatePlayer)
1374
{
1375
    const std::string args = event.args;
1376
    if (args.empty())
1377
        return false;
1378
    adminHandler->locatePlayer(args);
1379
    return true;
1380
}
1381
1382
impHandler(commandShowAccountInfo)
1383
{
1384
    const std::string args = event.args;
1385
    if (args.empty())
1386
        return false;
1387
    adminHandler->showAccountInfo(args);
1388
    return true;
1389
}
1390
1391
impHandler(commandSpawn)
1392
{
1393
    const std::string args = event.args;
1394
    if (args.empty())
1395
        return false;
1396
    adminHandler->spawn(args);
1397
    return true;
1398
}
1399
1400
impHandler(commandSpawnSlave)
1401
{
1402
    const std::string args = event.args;
1403
    if (args.empty())
1404
        return false;
1405
    adminHandler->spawnSlave(args);
1406
    return true;
1407
}
1408
1409
impHandler(commandSpawnClone)
1410
{
1411
    const std::string args = event.args;
1412
    if (args.empty())
1413
        return false;
1414
    adminHandler->spawnClone(args);
1415
    return true;
1416
}
1417
1418
impHandler(commandSpawnSlaveClone)
1419
{
1420
    const std::string args = event.args;
1421
    if (args.empty())
1422
        return false;
1423
    adminHandler->spawnSlaveClone(args);
1424
    return true;
1425
}
1426
1427
impHandler(commandSpawnEvilClone)
1428
{
1429
    const std::string args = event.args;
1430
    if (args.empty())
1431
        return false;
1432
    adminHandler->spawnEvilClone(args);
1433
    return true;
1434
}
1435
1436
impHandler(commandSavePosition)
1437
{
1438
    adminHandler->savePosition(event.args);
1439
    return true;
1440
}
1441
1442
impHandler(commandLoadPosition)
1443
{
1444
    adminHandler->loadPosition(event.args);
1445
    return true;
1446
}
1447
1448
impHandler(commandRandomWarp)
1449
{
1450
    adminHandler->randomWarp(event.args);
1451
    return true;
1452
}
1453
1454
impHandler(commandGotoNpc)
1455
{
1456
    const std::string args = event.args;
1457
    if (args.empty())
1458
        return false;
1459
    adminHandler->gotoNpc(args);
1460
    return true;
1461
}
1462
1463
impHandler(commandGotoPc)
1464
{
1465
    const std::string args = event.args;
1466
    if (args.empty())
1467
        return false;
1468
    adminHandler->gotoName(args);
1469
    return true;
1470
}
1471
1472
impHandler(commandRecallPc)
1473
{
1474
    const std::string args = event.args;
1475
    if (args.empty())
1476
        return false;
1477
    adminHandler->recallName(args);
1478
    return true;
1479
}
1480
1481
impHandler(commandIpCheck)
1482
{
1483
    const std::string args = event.args;
1484
    if (args.empty())
1485
        return false;
1486
    adminHandler->ipcheckName(args);
1487
    return true;
1488
}
1489
1490
impHandler(commandKiller)
1491
{
1492
    adminHandler->killer(event.args);
1493
    return true;
1494
}
1495
1496
impHandler(commandKillable)
1497
{
1498
    adminHandler->killable(event.args);
1499
    return true;
1500
}
1501
1502
impHandler(commandHeal)
1503
{
1504
    adminHandler->heal(event.args);
1505
    return true;
1506
}
1507
1508
impHandler(commandAlive)
1509
{
1510
    adminHandler->alive(event.args);
1511
    return true;
1512
}
1513
1514
impHandler(commandDisguise)
1515
{
1516
    const std::string args = event.args;
1517
    if (args.empty())
1518
        return false;
1519
    adminHandler->disguise(args);
1520
    return true;
1521
}
1522
1523
impHandler(commandImmortal)
1524
{
1525
    adminHandler->immortal(event.args);
1526
    return true;
1527
}
1528
1529
impHandler(commandHide)
1530
{
1531
    adminHandler->hide(event.args);
1532
    return true;
1533
}
1534
1535
impHandler(commandNuke)
1536
{
1537
    const std::string args = event.args;
1538
    if (args.empty())
1539
        return false;
1540
    adminHandler->nuke(args);
1541
    return true;
1542
}
1543
1544
impHandler(commandKill)
1545
{
1546
    adminHandler->kill(event.args);
1547
    return true;
1548
}
1549
1550
impHandler(commandJail)
1551
{
1552
    const std::string args = event.args;
1553
    if (args.empty())
1554
        return false;
1555
    adminHandler->jail(args);
1556
    return true;
1557
}
1558
1559
impHandler(commandUnjail)
1560
{
1561
    const std::string args = event.args;
1562
    if (args.empty())
1563
        return false;
1564
    adminHandler->unjail(args);
1565
    return true;
1566
}
1567
1568
impHandler(commandNpcMove)
1569
{
1570
    const std::string args = event.args;
1571
    if (args.empty())
1572
        return false;
1573
    StringVect pars;
1574
    if (!splitParameters(pars, args, " ,", '\"'))
1575
        return false;
1576
1577
    if (pars.size() != 3)
1578
        return false;
1579
1580
    adminHandler->npcMove(pars[0],
1581
        atoi(pars[1].c_str()),
1582
        atoi(pars[2].c_str()));
1583
    return true;
1584
}
1585
1586
impHandler(commandNpcHide)
1587
{
1588
    const std::string args = event.args;
1589
    if (args.empty())
1590
        return false;
1591
    adminHandler->hideNpc(args);
1592
    return true;
1593
}
1594
1595
impHandler(commandNpcShow)
1596
{
1597
    const std::string args = event.args;
1598
    if (args.empty())
1599
        return false;
1600
    adminHandler->showNpc(args);
1601
    return true;
1602
}
1603
1604
impHandler(commandChangePartyLeader)
1605
{
1606
    const std::string args = event.args;
1607
    if (args.empty())
1608
        return false;
1609
    adminHandler->changePartyLeader(args);
1610
    return true;
1611
}
1612
1613
impHandler(commandPartyRecall)
1614
{
1615
    const std::string args = event.args;
1616
    if (args.empty())
1617
        return false;
1618
    adminHandler->partyRecall(args);
1619
    return true;
1620
}
1621
1622
impHandler(commandBreakGuild)
1623
{
1624
    adminHandler->breakGuild(event.args);
1625
    return true;
1626
}
1627
1628
impHandler(commandGuildRecall)
1629
{
1630
    const std::string args = event.args;
1631
    if (args.empty())
1632
        return false;
1633
    adminHandler->guildRecall(args);
1634
    return true;
1635
}
1636
1637
impHandler(mailTo)
1638
{
1639
    if (mailWindow == nullptr)
1640
        return false;
1641
    const std::string args = event.args;
1642
    if (settings.enableNewMailSystem)
1643
    {
1644
        mail2Handler->queueCheckName(MailQueueType::EditMail,
1645
            args,
1646
            std::string(),
1647
            std::string(),
1648
            0);
1649
    }
1650
    else
1651
    {
1652
        mailWindow->createMail(args);
1653
    }
1654
    return true;
1655
}
1656
1657
impHandler(adoptChild)
1658
{
1659
    const std::string nick = getNick(event);
1660
    Being *const being = actorManager->findBeingByName(
1661
        nick, ActorType::Player);
1662
    if (being == nullptr)
1663
        return true;
1664
    familyHandler->askForChild(being);
1665
    return true;
1666
}
1667
1668
impHandler(showSkillLevels)
1669
{
1670
    const std::string args = event.args;
1671
    if (args.empty())
1672
        return false;
1673
    const SkillInfo *restrict const skill = skillDialog->getSkill(
1674
        atoi(args.c_str()));
1675
    if (skill == nullptr)
1676
        return false;
1677
    popupMenu->showSkillLevelPopup(skill);
1678
    return true;
1679
}
1680
1681
impHandler(showSkillType)
1682
{
1683
    const std::string args = event.args;
1684
    if (args.empty())
1685
        return false;
1686
    const SkillInfo *restrict const skill = skillDialog->getSkill(
1687
        atoi(args.c_str()));
1688
    if (skill == nullptr)
1689
        return false;
1690
    popupMenu->showSkillTypePopup(skill);
1691
    return true;
1692
}
1693
1694
impHandler(selectSkillType)
1695
{
1696
    int skill = 0;
1697
    int type = 0;
1698
1699
    if ((skillDialog != nullptr) && parse2Int(event.args, skill, type))
1700
    {
1701
        skillDialog->selectSkillCastType(skill,
1702
            static_cast<CastTypeT>(type));
1703
        return true;
1704
    }
1705
    return false;
1706
}
1707
1708
impHandler(showSkillOffsetX)
1709
{
1710
    const std::string args = event.args;
1711
    if (args.empty())
1712
        return false;
1713
    const SkillInfo *restrict const skill = skillDialog->getSkill(
1714
        atoi(args.c_str()));
1715
    if (skill == nullptr)
1716
        return false;
1717
    popupMenu->showSkillOffsetPopup(skill, true);
1718
    return true;
1719
}
1720
1721
impHandler(showSkillOffsetY)
1722
{
1723
    const std::string args = event.args;
1724
    if (args.empty())
1725
        return false;
1726
    const SkillInfo *restrict const skill = skillDialog->getSkill(
1727
        atoi(args.c_str()));
1728
    if (skill == nullptr)
1729
        return false;
1730
    popupMenu->showSkillOffsetPopup(skill, false);
1731
    return true;
1732
}
1733
1734
impHandler(setSkillOffsetX)
1735
{
1736
    int skill = 0;
1737
    int offset = 0;
1738
1739
    if ((skillDialog != nullptr) && parse2Int(event.args, skill, offset))
1740
    {
1741
        skillDialog->setSkillOffsetX(skill, offset);
1742
        return true;
1743
    }
1744
    return false;
1745
}
1746
1747
impHandler(setSkillOffsetY)
1748
{
1749
    int skill = 0;
1750
    int offset = 0;
1751
1752
    if ((skillDialog != nullptr) && parse2Int(event.args, skill, offset))
1753
    {
1754
        skillDialog->setSkillOffsetY(skill, offset);
1755
        return true;
1756
    }
1757
    return false;
1758
}
1759
1760
impHandler(partyItemShare)
1761
{
1762
    if (localPlayer == nullptr)
1763
        return false;
1764
1765
    if (localPlayer->isInParty() == false)
1766
        return true;
1767
1768
    ChatTab *tab = event.tab;
1769
    if (tab == nullptr)
1770
        tab = localChatTab;
1771
    if (tab == nullptr)
1772
        return true;
1773
1774
    const std::string args = event.args;
1775
    if (args.empty())
1776
    {
1777
        switch (partyHandler->getShareItems())
1778
        {
1779
            case PartyShare::YES:
1780
                // TRANSLATORS: chat message
1781
                tab->chatLog(_("Item sharing enabled."),
1782
                    ChatMsgType::BY_SERVER);
1783
                return true;
1784
            case PartyShare::NO:
1785
                // TRANSLATORS: chat message
1786
                tab->chatLog(_("Item sharing disabled."),
1787
                    ChatMsgType::BY_SERVER);
1788
                return true;
1789
            case PartyShare::NOT_POSSIBLE:
1790
                // TRANSLATORS: chat message
1791
                tab->chatLog(_("Item sharing not possible."),
1792
                    ChatMsgType::BY_SERVER);
1793
                return true;
1794
            case PartyShare::UNKNOWN:
1795
                // TRANSLATORS: chat message
1796
                tab->chatLog(_("Item sharing unknown."),
1797
                    ChatMsgType::BY_SERVER);
1798
                return true;
1799
            default:
1800
                break;
1801
        }
1802
    }
1803
1804
    const signed char opt = parseBoolean(args);
1805
1806
    switch (opt)
1807
    {
1808
        case 1:
1809
            partyHandler->setShareItems(
1810
                PartyShare::YES);
1811
            break;
1812
        case 0:
1813
            partyHandler->setShareItems(
1814
                PartyShare::NO);
1815
            break;
1816
        case -1:
1817
            tab->chatLog(strprintf(BOOLEAN_OPTIONS, "item"),
1818
                ChatMsgType::BY_SERVER);
1819
            break;
1820
        default:
1821
            break;
1822
    }
1823
    return true;
1824
}
1825
1826
impHandler(partyExpShare)
1827
{
1828
    if (localPlayer == nullptr)
1829
        return false;
1830
1831
    if (localPlayer->isInParty() == false)
1832
        return true;
1833
1834
    ChatTab *tab = event.tab;
1835
    if (tab == nullptr)
1836
        tab = localChatTab;
1837
    if (tab == nullptr)
1838
        return true;
1839
1840
    const std::string args = event.args;
1841
    if (args.empty())
1842
    {
1843
        switch (partyHandler->getShareExperience())
1844
        {
1845
            case PartyShare::YES:
1846
                // TRANSLATORS: chat message
1847
                tab->chatLog(_("Experience sharing enabled."),
1848
                    ChatMsgType::BY_SERVER);
1849
                return true;
1850
            case PartyShare::NO:
1851
                // TRANSLATORS: chat message
1852
                tab->chatLog(_("Experience sharing disabled."),
1853
                    ChatMsgType::BY_SERVER);
1854
                return true;
1855
            case PartyShare::NOT_POSSIBLE:
1856
                // TRANSLATORS: chat message
1857
                tab->chatLog(_("Experience sharing not possible."),
1858
                    ChatMsgType::BY_SERVER);
1859
                return true;
1860
            case PartyShare::UNKNOWN:
1861
                // TRANSLATORS: chat message
1862
                tab->chatLog(_("Experience sharing unknown."),
1863
                    ChatMsgType::BY_SERVER);
1864
                return true;
1865
            default:
1866
                break;
1867
        }
1868
    }
1869
1870
    const signed char opt = parseBoolean(args);
1871
1872
    switch (opt)
1873
    {
1874
        case 1:
1875
            partyHandler->setShareExperience(
1876
                PartyShare::YES);
1877
            break;
1878
        case 0:
1879
            partyHandler->setShareExperience(
1880
                PartyShare::NO);
1881
            break;
1882
        case -1:
1883
            tab->chatLog(strprintf(BOOLEAN_OPTIONS, "exp"),
1884
                ChatMsgType::BY_SERVER);
1885
            break;
1886
        default:
1887
            break;
1888
    }
1889
    return true;
1890
}
1891
1892
impHandler(partyAutoItemShare)
1893
{
1894
    if (localPlayer == nullptr)
1895
        return false;
1896
1897
    if (localPlayer->isInParty() == false)
1898
        return true;
1899
1900
    ChatTab *tab = event.tab;
1901
    if (tab == nullptr)
1902
        tab = localChatTab;
1903
    if (tab == nullptr)
1904
        return true;
1905
1906
    const std::string args = event.args;
1907
    if (args.empty())
1908
    {
1909
        switch (partyHandler->getShareAutoItems())
1910
        {
1911
            case PartyShare::YES:
1912
                // TRANSLATORS: chat message
1913
                tab->chatLog(_("Auto item sharing enabled."),
1914
                    ChatMsgType::BY_SERVER);
1915
                return true;
1916
            case PartyShare::NO:
1917
                // TRANSLATORS: chat message
1918
                tab->chatLog(_("Auto item sharing disabled."),
1919
                    ChatMsgType::BY_SERVER);
1920
                return true;
1921
            case PartyShare::NOT_POSSIBLE:
1922
                // TRANSLATORS: chat message
1923
                tab->chatLog(_("Auto item sharing not possible."),
1924
                    ChatMsgType::BY_SERVER);
1925
                return true;
1926
            case PartyShare::UNKNOWN:
1927
                // TRANSLATORS: chat message
1928
                tab->chatLog(_("Auto item sharing unknown."),
1929
                    ChatMsgType::BY_SERVER);
1930
                return true;
1931
            default:
1932
                break;
1933
        }
1934
    }
1935
1936
    const signed char opt = parseBoolean(args);
1937
1938
    switch (opt)
1939
    {
1940
        case 1:
1941
            partyHandler->setShareAutoItems(
1942
                PartyShare::YES);
1943
            break;
1944
        case 0:
1945
            partyHandler->setShareAutoItems(
1946
                PartyShare::NO);
1947
            break;
1948
        case -1:
1949
            tab->chatLog(strprintf(BOOLEAN_OPTIONS, "item"),
1950
                ChatMsgType::BY_SERVER);
1951
            break;
1952
        default:
1953
            break;
1954
    }
1955
    return true;
1956
}
1957
1958
impHandler0(outfitToChat)
1959
{
1960
    if ((outfitWindow == nullptr) || (chatWindow == nullptr))
1961
        return false;
1962
1963
    const std::string str = outfitWindow->getOutfitString();
1964
    if (!str.empty())
1965
        chatWindow->addInputText(str);
1966
    return true;
1967
}
1968
1969
impHandler0(outfitClear)
1970
{
1971
    if (outfitWindow == nullptr)
1972
        return false;
1973
1974
    outfitWindow->clearCurrentOutfit();
1975
    return true;
1976
}
1977
1978
impHandler(moveAttackUp)
1979
{
1980
    if (actorManager == nullptr)
1981
        return false;
1982
    const std::string args = event.args;
1983
    const int idx = actorManager->getAttackMobIndex(args);
1984
    if (idx > 0)
1985
    {
1986
        std::list<std::string> mobs
1987
            = actorManager->getAttackMobs();
1988
        std::list<std::string>::iterator it = mobs.begin();
1989
        std::list<std::string>::iterator it2 = it;
1990
        while (it != mobs.end())
1991
        {
1992
            if (*it == args)
1993
            {
1994
                -- it2;
1995
                mobs.splice(it2, mobs, it);
1996
                actorManager->setAttackMobs(mobs);
1997
                actorManager->rebuildAttackMobs();
1998
                break;
1999
            }
2000
            ++ it;
2001
            ++ it2;
2002
        }
2003
2004
        if (socialWindow != nullptr)
2005
            socialWindow->updateAttackFilter();
2006
        return true;
2007
    }
2008
    return false;
2009
}
2010
2011
impHandler(moveAttackDown)
2012
{
2013
    if (actorManager == nullptr)
2014
        return false;
2015
    const std::string args = event.args;
2016
    const int idx = actorManager->getAttackMobIndex(args);
2017
    const int size = actorManager->getAttackMobsSize();
2018
    if (idx + 1 < size)
2019
    {
2020
        std::list<std::string> mobs
2021
            = actorManager->getAttackMobs();
2022
        std::list<std::string>::iterator it = mobs.begin();
2023
        std::list<std::string>::iterator it2 = it;
2024
        while (it != mobs.end())
2025
        {
2026
            if (*it == args)
2027
            {
2028
                ++ it2;
2029
                if (it2 == mobs.end())
2030
                    break;
2031
2032
                mobs.splice(it, mobs, it2);
2033
                actorManager->setAttackMobs(mobs);
2034
                actorManager->rebuildAttackMobs();
2035
                break;
2036
            }
2037
            ++ it;
2038
            ++ it2;
2039
        }
2040
2041
        if (socialWindow != nullptr)
2042
            socialWindow->updateAttackFilter();
2043
        return true;
2044
    }
2045
    return false;
2046
}
2047
2048
impHandler(movePriorityAttackUp)
2049
{
2050
    if (actorManager == nullptr)
2051
        return false;
2052
    const std::string args = event.args;
2053
    const int idx = actorManager->
2054
        getPriorityAttackMobIndex(args);
2055
    if (idx > 0)
2056
    {
2057
        std::list<std::string> mobs
2058
            = actorManager->getPriorityAttackMobs();
2059
        std::list<std::string>::iterator it = mobs.begin();
2060
        std::list<std::string>::iterator it2 = it;
2061
        while (it != mobs.end())
2062
        {
2063
            if (*it == args)
2064
            {
2065
                -- it2;
2066
                mobs.splice(it2, mobs, it);
2067
                actorManager->setPriorityAttackMobs(mobs);
2068
                actorManager->rebuildPriorityAttackMobs();
2069
                break;
2070
            }
2071
            ++ it;
2072
            ++ it2;
2073
        }
2074
2075
        if (socialWindow != nullptr)
2076
            socialWindow->updateAttackFilter();
2077
        return true;
2078
    }
2079
    return false;
2080
}
2081
2082
impHandler(movePriorityAttackDown)
2083
{
2084
    if (actorManager == nullptr)
2085
        return false;
2086
    const std::string args = event.args;
2087
    const int idx = actorManager
2088
        ->getPriorityAttackMobIndex(args);
2089
    const int size = actorManager->getPriorityAttackMobsSize();
2090
    if (idx + 1 < size)
2091
    {
2092
        std::list<std::string> mobs
2093
            = actorManager->getPriorityAttackMobs();
2094
        std::list<std::string>::iterator it = mobs.begin();
2095
        std::list<std::string>::iterator it2 = it;
2096
        while (it != mobs.end())
2097
        {
2098
            if (*it == args)
2099
            {
2100
                ++ it2;
2101
                if (it2 == mobs.end())
2102
                    break;
2103
2104
                mobs.splice(it, mobs, it2);
2105
                actorManager->setPriorityAttackMobs(mobs);
2106
                actorManager->rebuildPriorityAttackMobs();
2107
                break;
2108
            }
2109
            ++ it;
2110
            ++ it2;
2111
        }
2112
2113
        if (socialWindow != nullptr)
2114
            socialWindow->updateAttackFilter();
2115
        return true;
2116
    }
2117
    return false;
2118
}
2119
2120
impHandler(addSkillShortcut)
2121
{
2122
    const std::string args = event.args;
2123
    if (args.empty() ||
2124
        itemShortcutWindow == nullptr)
2125
    {
2126
        return false;
2127
    }
2128
    const SkillInfo *restrict const skill = skillDialog->getSkill(
2129
        atoi(args.c_str()));
2130
    if (skill == nullptr)
2131
        return false;
2132
2133
    const int num = itemShortcutWindow->getTabIndex();
2134
    if (num < 0 ||
2135
        num >= CAST_S32(SHORTCUT_TABS) ||
2136
        num == CAST_S32(SHORTCUT_AUTO_TAB))
2137
    {
2138
        return false;
2139
    }
2140
2141
    ItemShortcut *const selShortcut = itemShortcut[num];
2142
    const size_t index = selShortcut->getFreeIndex();
2143
    if (index == SHORTCUT_ITEMS)
2144
        return true;
2145
2146
    selShortcut->setItem(index,
2147
        skill->id + SKILL_MIN_ID,
2148
        fromInt(skill->customSelectedLevel, ItemColor));
2149
    selShortcut->setItemData(index,
2150
        skill->toDataStr());
2151
2152
//    popupMenu->showSkillLevelPopup(skill);
2153
    return true;
2154
}
2155
2156
4
}  // namespace Actions