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