GCC Code Coverage Report
Directory: src/ Exec Total Coverage
File: src/net/tmwa/playerhandler.cpp Lines: 1 224 0.4 %
Date: 2017-11-29 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-2017  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, base, notify); \
216
    if (mod != NoStat) \
217
        PlayerInfo::setStatMod(stat, mod)
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(base);
229
            PlayerInfo::setStatBase(Attributes::PLAYER_WALK_SPEED, base);
230
            PlayerInfo::setStatMod(Attributes::PLAYER_WALK_SPEED, 0);
231
            break;
232
        case Sp::BASEEXP:
233
            PlayerInfo::setAttribute(Attributes::PLAYER_EXP, base);
234
            break;
235
        case Sp::JOBEXP:
236
            PlayerInfo::setAttribute(Attributes::PLAYER_JOB_EXP, base);
237
            break;
238
        case Sp::KARMA:
239
            PlayerInfo::setStatBase(Attributes::PLAYER_KARMA, base);
240
            PlayerInfo::setStatMod(Attributes::PLAYER_KARMA, 0);
241
            break;
242
        case Sp::MANNER:
243
            PlayerInfo::setStatBase(Attributes::PLAYER_MANNER, base);
244
            PlayerInfo::setStatMod(Attributes::PLAYER_MANNER, 0);
245
            break;
246
        case Sp::HP:
247
            PlayerInfo::setAttribute(Attributes::PLAYER_HP, base);
248
            if (localPlayer->isInParty() && (Party::getParty(1) != nullptr))
249
            {
250
                PartyMember *const m = Party::getParty(1)
251
                    ->getMember(localPlayer->getId());
252
                if (m != nullptr)
253
                {
254
                    m->setHp(base);
255
                    m->setMaxHp(PlayerInfo::getAttribute(
256
                        Attributes::PLAYER_MAX_HP));
257
                }
258
            }
259
            break;
260
        case Sp::MAXHP:
261
            PlayerInfo::setAttribute(Attributes::PLAYER_MAX_HP, base);
262
263
            if (localPlayer->isInParty() && (Party::getParty(1) != nullptr))
264
            {
265
                PartyMember *const m = Party::getParty(1)->getMember(
266
                    localPlayer->getId());
267
                if (m != nullptr)
268
                {
269
                    m->setHp(PlayerInfo::getAttribute(Attributes::PLAYER_HP));
270
                    m->setMaxHp(base);
271
                }
272
            }
273
            break;
274
        case Sp::SP:
275
            PlayerInfo::setAttribute(Attributes::PLAYER_MP, base);
276
            break;
277
        case Sp::MAXSP:
278
            PlayerInfo::setAttribute(Attributes::PLAYER_MAX_MP, base);
279
            break;
280
        case Sp::STATUSPOINT:
281
            PlayerInfo::setAttribute(Attributes::PLAYER_CHAR_POINTS, base);
282
            break;
283
        case Sp::BASELEVEL:
284
            PlayerInfo::setAttribute(Attributes::PLAYER_BASE_LEVEL, base);
285
            if (localPlayer != nullptr)
286
            {
287
                localPlayer->setLevel(base);
288
                localPlayer->updateName();
289
            }
290
            break;
291
        case Sp::SKILLPOINT:
292
            PlayerInfo::setAttribute(Attributes::PLAYER_SKILL_POINTS, base);
293
            if (skillDialog != nullptr)
294
                skillDialog->update();
295
            break;
296
        case Sp::STR:
297
            setStatComplex(Attributes::PLAYER_STR);
298
            break;
299
        case Sp::AGI:
300
            setStatComplex(Attributes::PLAYER_AGI);
301
            break;
302
        case Sp::VIT:
303
            setStatComplex(Attributes::PLAYER_VIT);
304
            break;
305
        case Sp::INT:
306
            setStatComplex(Attributes::PLAYER_INT);
307
            break;
308
        case Sp::DEX:
309
            setStatComplex(Attributes::PLAYER_DEX);
310
            break;
311
        case Sp::LUK:
312
            setStatComplex(Attributes::PLAYER_LUK);
313
            break;
314
        case Sp::ZENY:
315
        {
316
            const int oldMoney = PlayerInfo::getAttribute(Attributes::MONEY);
317
            const int newMoney = base;
318
            if (newMoney > oldMoney)
319
            {
320
                NotifyManager::notify(NotifyTypes::MONEY_GET,
321
                    UnitsDb::formatCurrency(newMoney - oldMoney));
322
            }
323
            else if (newMoney < oldMoney)
324
            {
325
                NotifyManager::notify(NotifyTypes::MONEY_SPENT,
326
                    UnitsDb::formatCurrency(oldMoney - newMoney).c_str());
327
            }
328
329
            PlayerInfo::setAttribute(Attributes::MONEY, newMoney);
330
            break;
331
        }
332
        case Sp::NEXTBASEEXP:
333
            PlayerInfo::setAttribute(Attributes::PLAYER_EXP_NEEDED, base);
334
            break;
335
        case Sp::JOB_MOD:
336
            PlayerInfo::setAttribute(Attributes::PLAYER_JOB_EXP_NEEDED, base);
337
            break;
338
        case Sp::WEIGHT:
339
            PlayerInfo::setAttribute(Attributes::TOTAL_WEIGHT, base);
340
            break;
341
        case Sp::MAXWEIGHT:
342
            PlayerInfo::setAttribute(Attributes::MAX_WEIGHT, base);
343
            break;
344
        case Sp::USTR:
345
            statusWindow->setPointsNeeded(Attributes::PLAYER_STR, base);
346
            break;
347
        case Sp::UAGI:
348
            statusWindow->setPointsNeeded(Attributes::PLAYER_AGI, base);
349
            break;
350
        case Sp::UVIT:
351
            statusWindow->setPointsNeeded(Attributes::PLAYER_VIT, base);
352
            break;
353
        case Sp::UINT:
354
            statusWindow->setPointsNeeded(Attributes::PLAYER_INT, base);
355
            break;
356
        case Sp::UDEX:
357
            statusWindow->setPointsNeeded(Attributes::PLAYER_DEX, base);
358
            break;
359
        case Sp::ULUK:
360
            statusWindow->setPointsNeeded(Attributes::PLAYER_LUK, base);
361
            break;
362
363
        case Sp::ATK1:
364
            PlayerInfo::setStatBase(Attributes::PLAYER_ATK, base);
365
            PlayerInfo::updateAttrs();
366
            break;
367
        case Sp::ATK2:
368
            PlayerInfo::setStatMod(Attributes::PLAYER_ATK, base);
369
            PlayerInfo::updateAttrs();
370
            break;
371
        case Sp::MATK1:
372
            PlayerInfo::setStatBase(Attributes::PLAYER_MATK, base);
373
            break;
374
        case Sp::MATK2:
375
            PlayerInfo::setStatMod(Attributes::PLAYER_MATK, base);
376
            break;
377
        case Sp::DEF1:
378
            PlayerInfo::setStatBase(Attributes::PLAYER_DEF, base);
379
            break;
380
        case Sp::DEF2:
381
            PlayerInfo::setStatMod(Attributes::PLAYER_DEF, base);
382
            break;
383
        case Sp::MDEF1:
384
            PlayerInfo::setStatBase(Attributes::PLAYER_MDEF, base);
385
            break;
386
        case Sp::MDEF2:
387
            PlayerInfo::setStatMod(Attributes::PLAYER_MDEF, base);
388
            break;
389
        case Sp::HIT:
390
            PlayerInfo::setStatBase(Attributes::PLAYER_HIT, base);
391
            break;
392
        case Sp::FLEE1:
393
            PlayerInfo::setStatBase(Attributes::PLAYER_FLEE, base);
394
            break;
395
        case Sp::FLEE2:
396
            PlayerInfo::setStatMod(Attributes::PLAYER_FLEE, base);
397
            break;
398
        case Sp::CRITICAL:
399
            PlayerInfo::setStatBase(Attributes::PLAYER_CRIT, base);
400
            break;
401
        case Sp::ASPD:
402
            localPlayer->setAttackSpeed(base);
403
            PlayerInfo::setStatBase(Attributes::PLAYER_ATTACK_DELAY, base);
404
            PlayerInfo::setStatMod(Attributes::PLAYER_ATTACK_DELAY, 0);
405
            PlayerInfo::updateAttrs();
406
            break;
407
        case Sp::JOBLEVEL:
408
            PlayerInfo::setAttribute(Attributes::PLAYER_JOB_LEVEL, base);
409
            break;
410
        case Sp::GM_LEVEL:
411
            localPlayer->setGroupId(base);
412
            break;
413
414
        default:
415
            UNIMPLEMENTEDPACKETFIELD(type);
416
            break;
417
    }
418
}
419
420
#undef setStatComplex
421
422
4
}  // namespace TmwAthena