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