GCC Code Coverage Report
Directory: src/ Exec Total Coverage
File: src/net/tmwa/skillrecv.cpp Lines: 1 71 1.4 %
Date: 2021-03-17 Branches: 0 80 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/skillrecv.h"
25
26
#include "notifymanager.h"
27
28
#include "being/localplayer.h"
29
#include "being/playerinfo.h"
30
31
#include "const/net/skill.h"
32
33
#include "enums/resources/notifytypes.h"
34
35
#include "gui/windows/skilldialog.h"
36
37
#include "net/messagein.h"
38
39
#include "utils/gettext.h"
40
41
#include "debug.h"
42
43
namespace TmwAthena
44
{
45
46
void SkillRecv::processPlayerSkills(Net::MessageIn &msg)
47
{
48
    msg.readInt16("len");
49
    const int skillCount = (msg.getLength() - 4) / 37;
50
    int updateSkill = 0;
51
52
    for (int k = 0; k < skillCount; k++)
53
    {
54
        const int skillId = msg.readInt16("skill id");
55
        const SkillType::SkillType inf = static_cast<SkillType::SkillType>(
56
            msg.readInt16("inf"));
57
        msg.readInt16("skill pool flags");
58
        const int level = msg.readInt16("skill level");
59
        const int sp = msg.readInt16("sp");
60
        const int range = msg.readInt16("range");
61
        msg.skip(24, "unused");
62
        const Modifiable up = fromBool(msg.readUInt8("up flag"), Modifiable);
63
        const int oldLevel = PlayerInfo::getSkillLevel(skillId);
64
        if ((oldLevel != 0) && oldLevel != level)
65
            updateSkill = skillId;
66
        PlayerInfo::setSkillLevel(skillId, level);
67
        if (skillDialog != nullptr)
68
        {
69
            if (!skillDialog->updateSkill(skillId, range, up, inf, sp))
70
            {
71
                skillDialog->addSkill(SkillOwner::Player,
72
                    skillId, "", level, range, up, inf, sp);
73
            }
74
        }
75
    }
76
    if (skillDialog != nullptr)
77
    {
78
        skillDialog->update();
79
        if (updateSkill != 0)
80
            skillDialog->playUpdateEffect(updateSkill);
81
    }
82
}
83
84
void SkillRecv::processSkillFailed(Net::MessageIn &msg)
85
{
86
    // Action failed (ex. sit because you have not reached the
87
    // right level)
88
    const int skillId   = msg.readInt16("skill id");
89
    const int16_t bskill  = msg.readInt16("bskill");
90
    msg.readInt16("btype");
91
    const signed char success = msg.readUInt8("success");
92
    const signed char reason  = msg.readUInt8("reason");
93
    if (success != CAST_S32(SKILL_FAILED)
94
        && bskill == CAST_S32(BSKILL_EMOTE))
95
    {
96
        logger->log("Action: %d/%d", bskill, success);
97
    }
98
99
    std::string txt;
100
    if (success == CAST_S32(SKILL_FAILED)
101
        && skillId == CAST_S32(SKILL_BASIC))
102
    {
103
        if ((localPlayer != nullptr) &&
104
            bskill == CAST_S32(BSKILL_EMOTE) &&
105
            reason == CAST_S32(RFAIL_SKILLDEP))
106
        {
107
            localPlayer->stopAdvert();
108
        }
109
110
        switch (bskill)
111
        {
112
            case BSKILL_TRADE:
113
                // TRANSLATORS: error message
114
                txt = _("Trade failed!");
115
                break;
116
            case BSKILL_EMOTE:
117
                // TRANSLATORS: error message
118
                txt = _("Emote failed!");
119
                break;
120
            case BSKILL_SIT:
121
                // TRANSLATORS: error message
122
                txt = _("Sit failed!");
123
                break;
124
            case BSKILL_CREATECHAT:
125
                // TRANSLATORS: error message
126
                txt = _("Chat creating failed!");
127
                break;
128
            case BSKILL_JOINPARTY:
129
                // TRANSLATORS: error message
130
                txt = _("Could not join party!");
131
                break;
132
            case BSKILL_SHOUT:
133
                // TRANSLATORS: error message
134
                txt = _("Cannot shout!");
135
                break;
136
            default:
137
                UNIMPLEMENTEDPACKETFIELD(bskill);
138
                break;
139
        }
140
141
        txt.append(" ");
142
143
        switch (reason)
144
        {
145
            case RFAIL_SKILLDEP:
146
                // TRANSLATORS: error message
147
                txt.append(_("You have not yet reached a high enough lvl!"));
148
                break;
149
            case RFAIL_INSUFHP:
150
                // TRANSLATORS: error message
151
                txt.append(_("Insufficient HP!"));
152
                break;
153
            case RFAIL_INSUFSP:
154
                // TRANSLATORS: error message
155
                txt.append(_("Insufficient SP!"));
156
                break;
157
            case RFAIL_NOMEMO:
158
                // TRANSLATORS: error message
159
                txt.append(_("You have no memos!"));
160
                break;
161
            case RFAIL_SKILLDELAY:
162
                // TRANSLATORS: error message
163
                txt.append(_("You cannot do that right now!"));
164
                break;
165
            case RFAIL_ZENY:
166
                // TRANSLATORS: error message
167
                txt.append(_("Seems you need more money... ;-)"));
168
                break;
169
            case RFAIL_WEAPON:
170
                // TRANSLATORS: error message
171
                txt.append(_("You cannot use this skill with that "
172
                    "kind of weapon!"));
173
                break;
174
            case RFAIL_REDGEM:
175
                // TRANSLATORS: error message
176
                txt.append(_("You need another red gem!"));
177
                break;
178
            case RFAIL_BLUEGEM:
179
                // TRANSLATORS: error message
180
                txt.append(_("You need another blue gem!"));
181
                break;
182
            case RFAIL_OVERWEIGHT:
183
                // TRANSLATORS: error message
184
                txt.append(_("You're carrying to much to do this!"));
185
                break;
186
            default:
187
                // TRANSLATORS: error message
188
                txt.append(_("Huh? What's that?"));
189
                UNIMPLEMENTEDPACKETFIELD(reason);
190
                break;
191
        }
192
    }
193
    else
194
    {
195
        switch (skillId)
196
        {
197
            case SKILL_WARP :
198
                // TRANSLATORS: error message
199
                txt = _("Warp failed...");
200
                break;
201
            case SKILL_STEAL :
202
                // TRANSLATORS: error message
203
                txt = _("Could not steal anything...");
204
                break;
205
            case SKILL_ENVENOM :
206
                // TRANSLATORS: error message
207
                txt = _("Poison had no effect...");
208
                break;
209
            default:
210
                UNIMPLEMENTEDPACKETFIELD(skillId);
211
                break;
212
        }
213
    }
214
215
    NotifyManager::notify(NotifyTypes::SKILL_FAIL_MESSAGE, txt);
216
}
217
218
2
}  // namespace TmwAthena