GCC Code Coverage Report
Directory: src/ Exec Total Coverage
File: src/progs/manaplus/actions/commands.cpp Lines: 1 939 0.1 %
Date: 2018-07-14 Branches: 0 1019 0.0 %

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