GCC Code Coverage Report
Directory: src/ Exec Total Coverage
File: src/net/tmwa/playerhandler.cpp Lines: 1 224 0.4 %
Date: 2018-05-24 20:11:55 Branches: 0 146 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::setViewEquipment(const bool allow A_UNUSED) const
211
{
212
}
213
214
#define setStatComplex(stat) \
215
    PlayerInfo::setStatBase(stat, CAST_S32(base), notify); \
216
    if (mod != NoStat) \
217
        PlayerInfo::setStatMod(stat, mod, Notify_true)
218
219
void PlayerHandler::setStat(Net::MessageIn &msg,
220
                            const int type,
221
                            const int64_t base,
222
                            const int mod,
223
                            const Notify notify) const
224
{
225
    switch (type)
226
    {
227
        case Sp::SPEED:
228
            localPlayer->setWalkSpeed(CAST_S32(base));
229
            PlayerInfo::setStatBase(Attributes::PLAYER_WALK_SPEED,
230
                CAST_S32(base),
231
                Notify_true);
232
            PlayerInfo::setStatMod(Attributes::PLAYER_WALK_SPEED,
233
                0,
234
                Notify_true);
235
            break;
236
        case Sp::BASEEXP:
237
            PlayerInfo::setAttribute(Attributes::PLAYER_EXP,
238
                base,
239
                Notify_true);
240
            break;
241
        case Sp::JOBEXP:
242
            PlayerInfo::setAttribute(Attributes::PLAYER_JOB_EXP,
243
                base,
244
                Notify_true);
245
            break;
246
        case Sp::KARMA:
247
            PlayerInfo::setStatBase(Attributes::PLAYER_KARMA,
248
                CAST_S32(base),
249
                Notify_true);
250
            PlayerInfo::setStatMod(Attributes::PLAYER_KARMA,
251
                0,
252
                Notify_true);
253
            break;
254
        case Sp::MANNER:
255
            PlayerInfo::setStatBase(Attributes::PLAYER_MANNER,
256
                CAST_S32(base),
257
                Notify_true);
258
            PlayerInfo::setStatMod(Attributes::PLAYER_MANNER,
259
                0,
260
                Notify_true);
261
            break;
262
        case Sp::HP:
263
            PlayerInfo::setAttribute(Attributes::PLAYER_HP,
264
                base,
265
                Notify_true);
266
            if (localPlayer->isInParty() && (Party::getParty(1) != nullptr))
267
            {
268
                PartyMember *const m = Party::getParty(1)
269
                    ->getMember(localPlayer->getId());
270
                if (m != nullptr)
271
                {
272
                    m->setHp(CAST_S32(base));
273
                    m->setMaxHp(PlayerInfo::getAttribute(
274
                        Attributes::PLAYER_MAX_HP));
275
                }
276
            }
277
            break;
278
        case Sp::MAXHP:
279
            PlayerInfo::setAttribute(Attributes::PLAYER_MAX_HP,
280
                base,
281
                Notify_true);
282
283
            if (localPlayer->isInParty() && (Party::getParty(1) != nullptr))
284
            {
285
                PartyMember *const m = Party::getParty(1)->getMember(
286
                    localPlayer->getId());
287
                if (m != nullptr)
288
                {
289
                    m->setHp(PlayerInfo::getAttribute(Attributes::PLAYER_HP));
290
                    m->setMaxHp(CAST_S32(base));
291
                }
292
            }
293
            break;
294
        case Sp::SP:
295
            PlayerInfo::setAttribute(Attributes::PLAYER_MP,
296
                base,
297
                Notify_true);
298
            break;
299
        case Sp::MAXSP:
300
            PlayerInfo::setAttribute(Attributes::PLAYER_MAX_MP,
301
                base,
302
                Notify_true);
303
            break;
304
        case Sp::STATUSPOINT:
305
            PlayerInfo::setAttribute(Attributes::PLAYER_CHAR_POINTS,
306
                base,
307
                Notify_true);
308
            break;
309
        case Sp::BASELEVEL:
310
            PlayerInfo::setAttribute(Attributes::PLAYER_BASE_LEVEL,
311
                base,
312
                Notify_true);
313
            if (localPlayer != nullptr)
314
            {
315
                localPlayer->setLevel(CAST_S32(base));
316
                localPlayer->updateName();
317
            }
318
            break;
319
        case Sp::SKILLPOINT:
320
            PlayerInfo::setAttribute(Attributes::PLAYER_SKILL_POINTS,
321
                base,
322
                Notify_true);
323
            if (skillDialog != nullptr)
324
                skillDialog->update();
325
            break;
326
        case Sp::STR:
327
            setStatComplex(Attributes::PLAYER_STR);
328
            break;
329
        case Sp::AGI:
330
            setStatComplex(Attributes::PLAYER_AGI);
331
            break;
332
        case Sp::VIT:
333
            setStatComplex(Attributes::PLAYER_VIT);
334
            break;
335
        case Sp::INT:
336
            setStatComplex(Attributes::PLAYER_INT);
337
            break;
338
        case Sp::DEX:
339
            setStatComplex(Attributes::PLAYER_DEX);
340
            break;
341
        case Sp::LUK:
342
            setStatComplex(Attributes::PLAYER_LUK);
343
            break;
344
        case Sp::ZENY:
345
        {
346
            const int oldMoney = PlayerInfo::getAttribute(Attributes::MONEY);
347
            const int newMoney = CAST_S32(base);
348
            if (newMoney > oldMoney)
349
            {
350
                NotifyManager::notify(NotifyTypes::MONEY_GET,
351
                    UnitsDb::formatCurrency(newMoney - oldMoney));
352
            }
353
            else if (newMoney < oldMoney)
354
            {
355
                NotifyManager::notify(NotifyTypes::MONEY_SPENT,
356
                    UnitsDb::formatCurrency(oldMoney - newMoney).c_str());
357
            }
358
359
            PlayerInfo::setAttribute(Attributes::MONEY,
360
                newMoney,
361
                Notify_true);
362
            break;
363
        }
364
        case Sp::NEXTBASEEXP:
365
            PlayerInfo::setAttribute(Attributes::PLAYER_EXP_NEEDED,
366
                base,
367
                Notify_true);
368
            break;
369
        case Sp::JOB_MOD:
370
            PlayerInfo::setAttribute(Attributes::PLAYER_JOB_EXP_NEEDED,
371
                base,
372
                Notify_true);
373
            break;
374
        case Sp::WEIGHT:
375
            PlayerInfo::setAttribute(Attributes::TOTAL_WEIGHT,
376
                base,
377
                Notify_true);
378
            break;
379
        case Sp::MAXWEIGHT:
380
            PlayerInfo::setAttribute(Attributes::MAX_WEIGHT,
381
                base,
382
                Notify_true);
383
            break;
384
        case Sp::USTR:
385
            statusWindow->setPointsNeeded(Attributes::PLAYER_STR,
386
                CAST_S32(base));
387
            break;
388
        case Sp::UAGI:
389
            statusWindow->setPointsNeeded(Attributes::PLAYER_AGI,
390
                CAST_S32(base));
391
            break;
392
        case Sp::UVIT:
393
            statusWindow->setPointsNeeded(Attributes::PLAYER_VIT,
394
                CAST_S32(base));
395
            break;
396
        case Sp::UINT:
397
            statusWindow->setPointsNeeded(Attributes::PLAYER_INT,
398
                CAST_S32(base));
399
            break;
400
        case Sp::UDEX:
401
            statusWindow->setPointsNeeded(Attributes::PLAYER_DEX,
402
                CAST_S32(base));
403
            break;
404
        case Sp::ULUK:
405
            statusWindow->setPointsNeeded(Attributes::PLAYER_LUK,
406
                CAST_S32(base));
407
            break;
408
        case Sp::ATK1:
409
            PlayerInfo::setStatBase(Attributes::PLAYER_ATK,
410
                CAST_S32(base),
411
                Notify_true);
412
            PlayerInfo::updateAttrs();
413
            break;
414
        case Sp::ATK2:
415
            PlayerInfo::setStatMod(Attributes::PLAYER_ATK,
416
                CAST_S32(base),
417
                Notify_true);
418
            PlayerInfo::updateAttrs();
419
            break;
420
        case Sp::MATK1:
421
            PlayerInfo::setStatBase(Attributes::PLAYER_MATK,
422
                CAST_S32(base),
423
                Notify_true);
424
            break;
425
        case Sp::MATK2:
426
            PlayerInfo::setStatMod(Attributes::PLAYER_MATK,
427
                CAST_S32(base),
428
                Notify_true);
429
            break;
430
        case Sp::DEF1:
431
            PlayerInfo::setStatBase(Attributes::PLAYER_DEF,
432
                CAST_S32(base),
433
                Notify_true);
434
            break;
435
        case Sp::DEF2:
436
            PlayerInfo::setStatMod(Attributes::PLAYER_DEF,
437
                CAST_S32(base),
438
                Notify_true);
439
            break;
440
        case Sp::MDEF1:
441
            PlayerInfo::setStatBase(Attributes::PLAYER_MDEF,
442
                CAST_S32(base),
443
                Notify_true);
444
            break;
445
        case Sp::MDEF2:
446
            PlayerInfo::setStatMod(Attributes::PLAYER_MDEF,
447
                CAST_S32(base),
448
                Notify_true);
449
            break;
450
        case Sp::HIT:
451
            PlayerInfo::setStatBase(Attributes::PLAYER_HIT,
452
                CAST_S32(base),
453
                Notify_true);
454
            break;
455
        case Sp::FLEE1:
456
            PlayerInfo::setStatBase(Attributes::PLAYER_FLEE,
457
                CAST_S32(base),
458
                Notify_true);
459
            break;
460
        case Sp::FLEE2:
461
            PlayerInfo::setStatMod(Attributes::PLAYER_FLEE,
462
                CAST_S32(base),
463
                Notify_true);
464
            break;
465
        case Sp::CRITICAL:
466
            PlayerInfo::setStatBase(Attributes::PLAYER_CRIT,
467
                CAST_S32(base),
468
                Notify_true);
469
            break;
470
        case Sp::ASPD:
471
            localPlayer->setAttackSpeed(CAST_S32(base));
472
            PlayerInfo::setStatBase(Attributes::PLAYER_ATTACK_DELAY,
473
                CAST_S32(base),
474
                Notify_true);
475
            PlayerInfo::setStatMod(Attributes::PLAYER_ATTACK_DELAY,
476
                0,
477
                Notify_true);
478
            PlayerInfo::updateAttrs();
479
            break;
480
        case Sp::JOBLEVEL:
481
            PlayerInfo::setAttribute(Attributes::PLAYER_JOB_LEVEL,
482
                base,
483
                Notify_true);
484
            break;
485
        case Sp::GM_LEVEL:
486
            localPlayer->setGroupId(CAST_S32(base));
487
            break;
488
489
        default:
490
            UNIMPLEMENTEDPACKETFIELD(type);
491
            break;
492
    }
493
}
494
495
#undef setStatComplex
496
497
4
}  // namespace TmwAthena