GCC Code Coverage Report
Directory: src/ Exec Total Coverage
File: src/net/tmwa/playerhandler.cpp Lines: 1 203 0.5 %
Date: 2021-03-17 Branches: 0 150 0.0 %

Line Branch Exec Source
1
/*
2
 *  The ManaPlus Client
3
 *  Copyright (C) 2004-2009  The Mana World Development Team
4
 *  Copyright (C) 2009-2010  The Mana Developers
5
 *  Copyright (C) 2011-2019  The ManaPlus Developers
6
 *  Copyright (C) 2019-2021  Andrei Karas
7
 *
8
 *  This file is part of The ManaPlus Client.
9
 *
10
 *  This program is free software; you can redistribute it and/or modify
11
 *  it under the terms of the GNU General Public License as published by
12
 *  the Free Software Foundation; either version 2 of the License, or
13
 *  any later version.
14
 *
15
 *  This program is distributed in the hope that it will be useful,
16
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
17
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18
 *  GNU General Public License for more details.
19
 *
20
 *  You should have received a copy of the GNU General Public License
21
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
22
 */
23
24
#include "net/tmwa/playerhandler.h"
25
26
#include "notifymanager.h"
27
#include "party.h"
28
29
#include "being/localplayer.h"
30
#include "being/playerinfo.h"
31
32
#include "const/net/nostat.h"
33
34
#include "enums/resources/notifytypes.h"
35
36
#include "gui/windows/skilldialog.h"
37
#include "gui/windows/statuswindow.h"
38
39
#include "net/ea/inventoryhandler.h"
40
41
#include "net/tmwa/messageout.h"
42
#include "net/tmwa/protocolout.h"
43
#include "net/tmwa/sp.h"
44
45
#include "resources/db/unitsdb.h"
46
47
#include "debug.h"
48
49
namespace TmwAthena
50
{
51
52
PlayerHandler::PlayerHandler() :
53
    Ea::PlayerHandler()
54
{
55
    playerHandler = this;
56
}
57
58
PlayerHandler::~PlayerHandler()
59
{
60
    playerHandler = nullptr;
61
}
62
63
void PlayerHandler::attack(const BeingId id,
64
                           const Keep keep) const
65
{
66
    createOutPacket(CMSG_PLAYER_CHANGE_ACT);
67
    outMsg.writeBeingId(id, "target id");
68
    if (keep == Keep_true)
69
        outMsg.writeInt8(7, "action");
70
    else
71
        outMsg.writeInt8(0, "action");
72
}
73
74
void PlayerHandler::stopAttack() const
75
{
76
    createOutPacket(CMSG_PLAYER_STOP_ATTACK);
77
}
78
79
void PlayerHandler::emote(const uint8_t emoteId) const
80
{
81
    createOutPacket(CMSG_PLAYER_EMOTE);
82
    outMsg.writeInt8(emoteId, "emote id");
83
}
84
85
void PlayerHandler::increaseAttribute(const AttributesT attr,
86
                                      const int amount A_UNUSED) const
87
{
88
    if (attr >= Attributes::PLAYER_STR && attr <= Attributes::PLAYER_LUK)
89
    {
90
        createOutPacket(CMSG_STAT_UPDATE_REQUEST);
91
        outMsg.writeInt16(CAST_S16(attr), "attribute id");
92
        outMsg.writeInt8(1, "increment");
93
    }
94
}
95
96
void PlayerHandler::increaseSkill(const uint16_t skillId) const
97
{
98
    if (PlayerInfo::getAttribute(Attributes::PLAYER_SKILL_POINTS) <= 0)
99
        return;
100
101
    createOutPacket(CMSG_SKILL_LEVELUP_REQUEST);
102
    outMsg.writeInt16(skillId, "skill id");
103
}
104
105
void PlayerHandler::pickUp(const FloorItem *const floorItem) const
106
{
107
    if (floorItem == nullptr)
108
        return;
109
110
    createOutPacket(CMSG_ITEM_PICKUP);
111
    outMsg.writeBeingId(floorItem->getId(), "object id");
112
    Ea::InventoryHandler::pushPickup(floorItem->getId());
113
}
114
115
void PlayerHandler::setDirection(const unsigned char direction) const
116
{
117
    createOutPacket(CMSG_PLAYER_CHANGE_DIR);
118
    outMsg.writeInt16(0, "unused");
119
    outMsg.writeInt8(direction, "direction");
120
}
121
122
void PlayerHandler::setDestination(const int x, const int y,
123
                                   const int direction) const
124
{
125
    createOutPacket(CMSG_PLAYER_CHANGE_DEST);
126
    outMsg.writeCoordinates(CAST_U16(x),
127
        CAST_U16(y),
128
        CAST_U8(direction), "destination");
129
}
130
131
void PlayerHandler::changeAction(const BeingActionT &action) const
132
{
133
    char type;
134
    switch (action)
135
    {
136
        case BeingAction::SIT:
137
            type = 2;
138
            break;
139
        case BeingAction::STAND:
140
        case BeingAction::PRESTAND:
141
            type = 3;
142
            break;
143
        default:
144
        case BeingAction::MOVE:
145
        case BeingAction::ATTACK:
146
        case BeingAction::DEAD:
147
        case BeingAction::HURT:
148
        case BeingAction::SPAWN:
149
        case BeingAction::CAST:
150
            return;
151
    }
152
153
    createOutPacket(CMSG_PLAYER_CHANGE_ACT);
154
    outMsg.writeInt32(0, "unused");
155
    outMsg.writeInt8(type, "action");
156
}
157
158
void PlayerHandler::respawn() const
159
{
160
    createOutPacket(CMSG_PLAYER_RESTART);
161
    outMsg.writeInt8(0, "action");
162
}
163
164
void PlayerHandler::requestOnlineList() const
165
{
166
    createOutPacket(CMSG_ONLINE_LIST);
167
}
168
169
void PlayerHandler::removeOption() const
170
{
171
}
172
173
void PlayerHandler::changeCart(const int type A_UNUSED) const
174
{
175
}
176
177
void PlayerHandler::setMemo() const
178
{
179
}
180
181
void PlayerHandler::updateStatus(const uint8_t status A_UNUSED) const
182
{
183
}
184
185
void PlayerHandler::setShortcut(const int idx A_UNUSED,
186
                                const int tab A_UNUSED,
187
                                const uint8_t type A_UNUSED,
188
                                const int id A_UNUSED,
189
                                const int level A_UNUSED) const
190
{
191
}
192
193
void PlayerHandler::doriDori() const
194
{
195
}
196
197
void PlayerHandler::explosionSpirits() const
198
{
199
}
200
201
void PlayerHandler::requestPvpInfo() const
202
{
203
}
204
205
void PlayerHandler::revive() const
206
{
207
}
208
209
void PlayerHandler::shortcutShiftRow(const int row A_UNUSED,
210
                                     const int tab A_UNUSED) const
211
{
212
}
213
214
void PlayerHandler::setConfigOption(const int id A_UNUSED,
215
                                    const int data A_UNUSED) const
216
{
217
}
218
219
#define setStatComplex(stat) \
220
    PlayerInfo::setStatBase(stat, CAST_S32(base), notify); \
221
    if (mod != NoStat) \
222
        PlayerInfo::setStatMod(stat, mod, Notify_true)
223
224
void PlayerHandler::setStat(Net::MessageIn &msg,
225
                            const int type,
226
                            const int64_t base,
227
                            const int mod,
228
                            const Notify notify) const
229
{
230
    switch (type)
231
    {
232
        case Sp::SPEED:
233
            localPlayer->setWalkSpeed(CAST_S32(base));
234
            PlayerInfo::setStatBase(Attributes::PLAYER_WALK_SPEED,
235
                CAST_S32(base),
236
                Notify_true);
237
            PlayerInfo::setStatMod(Attributes::PLAYER_WALK_SPEED,
238
                0,
239
                Notify_true);
240
            break;
241
        case Sp::BASEEXP:
242
            PlayerInfo::setAttribute(Attributes::PLAYER_EXP,
243
                base,
244
                Notify_true);
245
            break;
246
        case Sp::JOBEXP:
247
            PlayerInfo::setAttribute(Attributes::PLAYER_JOB_EXP,
248
                base,
249
                Notify_true);
250
            break;
251
        case Sp::KARMA:
252
            PlayerInfo::setStatBase(Attributes::PLAYER_KARMA,
253
                CAST_S32(base),
254
                Notify_true);
255
            PlayerInfo::setStatMod(Attributes::PLAYER_KARMA,
256
                0,
257
                Notify_true);
258
            break;
259
        case Sp::MANNER:
260
            PlayerInfo::setStatBase(Attributes::PLAYER_MANNER,
261
                CAST_S32(base),
262
                Notify_true);
263
            PlayerInfo::setStatMod(Attributes::PLAYER_MANNER,
264
                0,
265
                Notify_true);
266
            break;
267
        case Sp::HP:
268
            PlayerInfo::setAttribute(Attributes::PLAYER_HP,
269
                base,
270
                Notify_true);
271
            if (localPlayer->isInParty() && (Party::getParty(1) != nullptr))
272
            {
273
                PartyMember *const m = Party::getParty(1)
274
                    ->getMember(localPlayer->getId());
275
                if (m != nullptr)
276
                {
277
                    m->setHp(CAST_S32(base));
278
                    m->setMaxHp(PlayerInfo::getAttribute(
279
                        Attributes::PLAYER_MAX_HP));
280
                }
281
            }
282
            break;
283
        case Sp::MAXHP:
284
            PlayerInfo::setAttribute(Attributes::PLAYER_MAX_HP,
285
                base,
286
                Notify_true);
287
288
            if (localPlayer->isInParty() && (Party::getParty(1) != nullptr))
289
            {
290
                PartyMember *const m = Party::getParty(1)->getMember(
291
                    localPlayer->getId());
292
                if (m != nullptr)
293
                {
294
                    m->setHp(PlayerInfo::getAttribute(Attributes::PLAYER_HP));
295
                    m->setMaxHp(CAST_S32(base));
296
                }
297
            }
298
            break;
299
        case Sp::SP:
300
            PlayerInfo::setAttribute(Attributes::PLAYER_MP,
301
                base,
302
                Notify_true);
303
            break;
304
        case Sp::MAXSP:
305
            PlayerInfo::setAttribute(Attributes::PLAYER_MAX_MP,
306
                base,
307
                Notify_true);
308
            break;
309
        case Sp::STATUSPOINT:
310
            PlayerInfo::setAttribute(Attributes::PLAYER_CHAR_POINTS,
311
                base,
312
                Notify_true);
313
            break;
314
        case Sp::BASELEVEL:
315
            PlayerInfo::setAttribute(Attributes::PLAYER_BASE_LEVEL,
316
                base,
317
                Notify_true);
318
            if (localPlayer != nullptr)
319
            {
320
                localPlayer->setLevel(CAST_S32(base));
321
                localPlayer->updateName();
322
            }
323
            break;
324
        case Sp::SKILLPOINT:
325
            PlayerInfo::setAttribute(Attributes::PLAYER_SKILL_POINTS,
326
                base,
327
                Notify_true);
328
            if (skillDialog != nullptr)
329
                skillDialog->update();
330
            break;
331
        case Sp::STR:
332
            setStatComplex(Attributes::PLAYER_STR);
333
            break;
334
        case Sp::AGI:
335
            setStatComplex(Attributes::PLAYER_AGI);
336
            break;
337
        case Sp::VIT:
338
            setStatComplex(Attributes::PLAYER_VIT);
339
            break;
340
        case Sp::INT:
341
            setStatComplex(Attributes::PLAYER_INT);
342
            break;
343
        case Sp::DEX:
344
            setStatComplex(Attributes::PLAYER_DEX);
345
            break;
346
        case Sp::LUK:
347
            setStatComplex(Attributes::PLAYER_LUK);
348
            break;
349
        case Sp::ZENY:
350
        {
351
            const int oldMoney = PlayerInfo::getAttribute(Attributes::MONEY);
352
            const int newMoney = CAST_S32(base);
353
            if (newMoney > oldMoney)
354
            {
355
                NotifyManager::notify(NotifyTypes::MONEY_GET,
356
                    UnitsDb::formatCurrency(newMoney - oldMoney));
357
            }
358
            else if (newMoney < oldMoney)
359
            {
360
                NotifyManager::notify(NotifyTypes::MONEY_SPENT,
361
                    UnitsDb::formatCurrency(oldMoney - newMoney).c_str());
362
            }
363
364
            PlayerInfo::setAttribute(Attributes::MONEY,
365
                newMoney,
366
                Notify_true);
367
            break;
368
        }
369
        case Sp::NEXTBASEEXP:
370
            PlayerInfo::setAttribute(Attributes::PLAYER_EXP_NEEDED,
371
                base,
372
                Notify_true);
373
            break;
374
        case Sp::JOB_MOD:
375
            PlayerInfo::setAttribute(Attributes::PLAYER_JOB_EXP_NEEDED,
376
                base,
377
                Notify_true);
378
            break;
379
        case Sp::WEIGHT:
380
            PlayerInfo::setAttribute(Attributes::TOTAL_WEIGHT,
381
                base,
382
                Notify_true);
383
            break;
384
        case Sp::MAXWEIGHT:
385
            PlayerInfo::setAttribute(Attributes::MAX_WEIGHT,
386
                base,
387
                Notify_true);
388
            break;
389
        case Sp::USTR:
390
            statusWindow->setPointsNeeded(Attributes::PLAYER_STR,
391
                CAST_S32(base));
392
            break;
393
        case Sp::UAGI:
394
            statusWindow->setPointsNeeded(Attributes::PLAYER_AGI,
395
                CAST_S32(base));
396
            break;
397
        case Sp::UVIT:
398
            statusWindow->setPointsNeeded(Attributes::PLAYER_VIT,
399
                CAST_S32(base));
400
            break;
401
        case Sp::UINT:
402
            statusWindow->setPointsNeeded(Attributes::PLAYER_INT,
403
                CAST_S32(base));
404
            break;
405
        case Sp::UDEX:
406
            statusWindow->setPointsNeeded(Attributes::PLAYER_DEX,
407
                CAST_S32(base));
408
            break;
409
        case Sp::ULUK:
410
            statusWindow->setPointsNeeded(Attributes::PLAYER_LUK,
411
                CAST_S32(base));
412
            break;
413
        case Sp::ATK1:
414
            PlayerInfo::setStatBase(Attributes::PLAYER_ATK,
415
                CAST_S32(base),
416
                Notify_true);
417
            PlayerInfo::updateAttrs();
418
            break;
419
        case Sp::ATK2:
420
            PlayerInfo::setStatMod(Attributes::PLAYER_ATK,
421
                CAST_S32(base),
422
                Notify_true);
423
            PlayerInfo::updateAttrs();
424
            break;
425
        case Sp::MATK1:
426
            PlayerInfo::setStatBase(Attributes::PLAYER_MATK,
427
                CAST_S32(base),
428
                Notify_true);
429
            break;
430
        case Sp::MATK2:
431
            PlayerInfo::setStatMod(Attributes::PLAYER_MATK,
432
                CAST_S32(base),
433
                Notify_true);
434
            break;
435
        case Sp::DEF1:
436
            PlayerInfo::setStatBase(Attributes::PLAYER_DEF,
437
                CAST_S32(base),
438
                Notify_true);
439
            break;
440
        case Sp::DEF2:
441
            PlayerInfo::setStatMod(Attributes::PLAYER_DEF,
442
                CAST_S32(base),
443
                Notify_true);
444
            break;
445
        case Sp::MDEF1:
446
            PlayerInfo::setStatBase(Attributes::PLAYER_MDEF,
447
                CAST_S32(base),
448
                Notify_true);
449
            break;
450
        case Sp::MDEF2:
451
            PlayerInfo::setStatMod(Attributes::PLAYER_MDEF,
452
                CAST_S32(base),
453
                Notify_true);
454
            break;
455
        case Sp::HIT:
456
            PlayerInfo::setStatBase(Attributes::PLAYER_HIT,
457
                CAST_S32(base),
458
                Notify_true);
459
            break;
460
        case Sp::FLEE1:
461
            PlayerInfo::setStatBase(Attributes::PLAYER_FLEE,
462
                CAST_S32(base),
463
                Notify_true);
464
            break;
465
        case Sp::FLEE2:
466
            PlayerInfo::setStatMod(Attributes::PLAYER_FLEE,
467
                CAST_S32(base),
468
                Notify_true);
469
            break;
470
        case Sp::CRITICAL:
471
            PlayerInfo::setStatBase(Attributes::PLAYER_CRIT,
472
                CAST_S32(base),
473
                Notify_true);
474
            break;
475
        case Sp::ASPD:
476
            localPlayer->setAttackSpeed(CAST_S32(base));
477
            PlayerInfo::setStatBase(Attributes::PLAYER_ATTACK_DELAY,
478
                CAST_S32(base),
479
                Notify_true);
480
            PlayerInfo::setStatMod(Attributes::PLAYER_ATTACK_DELAY,
481
                0,
482
                Notify_true);
483
            PlayerInfo::updateAttrs();
484
            break;
485
        case Sp::JOBLEVEL:
486
            PlayerInfo::setAttribute(Attributes::PLAYER_JOB_LEVEL,
487
                base,
488
                Notify_true);
489
            break;
490
        case Sp::GM_LEVEL:
491
            localPlayer->setGroupId(CAST_S32(base));
492
            break;
493
494
        default:
495
            UNIMPLEMENTEDPACKETFIELD(type);
496
            break;
497
    }
498
}
499
500
#undef setStatComplex
501
502
void PlayerHandler::selectStyle(const int headColor A_UNUSED,
503
                                const int headStyle A_UNUSED,
504
                                const int bodyColor A_UNUSED,
505
                                const int topStyle A_UNUSED,
506
                                const int middleStyle A_UNUSED,
507
                                const int bottomStyle A_UNUSED,
508
                                const int bodyStyle A_UNUSED) const
509
{
510
}
511
512
void PlayerHandler::setTitle(const int titleId A_UNUSED) const
513
{
514
}
515
516
void PlayerHandler::closeStyleWindow() const
517
{
518
}
519
520
2
}  // namespace TmwAthena