GCC Code Coverage Report
Directory: src/ Exec Total Coverage
File: src/resources/db/statuseffectdb.cpp Lines: 8 116 6.9 %
Date: 2018-12-09 Branches: 7 188 3.7 %

Line Branch Exec Source
1
/*
2
 *  The ManaPlus Client
3
 *  Copyright (C) 2008-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 "resources/db/statuseffectdb.h"
24
25
#include "configuration.h"
26
#include "statuseffect.h"
27
28
#include "utils/checkutils.h"
29
30
#include "resources/beingcommon.h"
31
32
#include "debug.h"
33
34
namespace
35
{
36
    typedef std::map<int, StatusEffect *> IdToEffectMap[2];
37
    bool mLoaded = false;
38
    int fakeId = 10000;
39

7
    IdToEffectMap statusEffects;
40
1
    OptionsMap optionToIdMap;
41
1
    OptionsMap opt1ToIdMap;
42
1
    OptionsMap opt2ToIdMap;
43
1
    OptionsMap opt3ToIdMap;
44
}  // namespace
45
46
StatusEffect *StatusEffectDB::getStatusEffect(const int index,
47
                                              const Enable enabling)
48
{
49
    std::map<int, StatusEffect *> &effects
50
        = statusEffects[enabling == Enable_true];
51
    const std::map<int, StatusEffect *>::iterator it = effects.find(index);
52
    if (it != effects.end())
53
        return (*it).second;
54
    reportAlways("Missing status effect: %d",
55
        index)
56
    return nullptr;
57
}
58
59
void StatusEffectDB::load()
60
{
61
    if (mLoaded)
62
        unload();
63
64
    logger->log1("Initializing status effect database...");
65
66
    loadXmlFile(paths.getStringValue("statusEffectsFile"), SkipError_false);
67
    loadXmlFile(paths.getStringValue("statusEffectsPatchFile"),
68
        SkipError_true);
69
    loadXmlDir("statusEffectsPatchDir", loadXmlFile)
70
71
    mLoaded = true;
72
}
73
74
void StatusEffectDB::loadXmlFile(const std::string &fileName,
75
                                 const SkipError skipError)
76
{
77
    XML::Document doc(fileName, UseVirtFs_true, skipError);
78
    XmlNodeConstPtrConst rootNode = doc.rootNode();
79
80
    if ((rootNode == nullptr) || !xmlNameEqual(rootNode, "status-effects"))
81
    {
82
        logger->log("Error loading status effects file: " + fileName);
83
        return;
84
    }
85
86
    for_each_xml_child_node(node, rootNode)
87
    {
88
        if (xmlNameEqual(node, "include"))
89
        {
90
            const std::string incName = XML::getProperty(node, "name", "");
91
            if (!incName.empty())
92
                loadXmlFile(incName, skipError);
93
            continue;
94
        }
95
        else if (!xmlNameEqual(node, "status-effect"))
96
        {
97
            continue;
98
        }
99
100
        int id = XML::getProperty(node, "id", -1);
101
        if (id == -1)
102
        {
103
            id = fakeId;
104
            fakeId ++;
105
        }
106
        const int option = XML::getProperty(node, "option", 0);
107
        const int opt1 = XML::getProperty(node, "opt1", 0);
108
        const int opt2 = XML::getProperty(node, "opt2", 0);
109
        const int opt3 = XML::getProperty(node, "opt3", 0);
110
        if (option != 0)
111
        {
112
            optionToIdMap[option] = id;
113
        }
114
        if (opt1 != 0)
115
        {
116
            opt1ToIdMap[opt1] = id;
117
        }
118
        if (opt2 != 0)
119
        {
120
            opt2ToIdMap[opt2] = id;
121
        }
122
        if (opt3 != 0)
123
        {
124
            opt3ToIdMap[opt3] = id;
125
        }
126
127
        StatusEffect *startEffect = statusEffects[1][id];
128
        StatusEffect *endEffect = statusEffects[0][id];
129
        const std::string name = XML::getProperty(node, "name", "");
130
        const std::string name2 = XML::langProperty(node, "name", "");
131
        if (startEffect == nullptr)
132
            startEffect = new StatusEffect;
133
        if (endEffect == nullptr)
134
            endEffect = new StatusEffect;
135
136
        startEffect->mName = name2;
137
        startEffect->mIsPoison =
138
            (name == paths.getStringValue("poisonEffectName"));
139
        startEffect->mIsCart =
140
            (name == paths.getStringValue("cartEffectName"));
141
        startEffect->mIsRiding =
142
            (name == paths.getStringValue("ridingEffectName"));
143
        startEffect->mIsTrickDead =
144
            (name == paths.getStringValue("trickDeadEffectName"));
145
        startEffect->mIsPostDelay =
146
            (name == paths.getStringValue("postDelayName"));
147
        startEffect->mMessage = XML::getProperty(
148
            node, "start-message", "");
149
        startEffect->mSFXEffect = XML::getProperty(
150
            node, "start-audio", "");
151
        startEffect->mStartParticleEffect = XML::getProperty(
152
            node, "start-particle", "");
153
        startEffect->mParticleEffect = XML::getProperty(
154
            node, "particle", "");
155
156
        startEffect->mIcon = XML::getProperty(node, "icon", "");
157
        startEffect->mAction = XML::getProperty(node, "action", "");
158
        startEffect->mIsPersistent = (XML::getProperty(
159
            node, "persistent-particle-effect", "no")) != "no";
160
161
        endEffect->mName = startEffect->mName;
162
        endEffect->mIsPoison = startEffect->mIsPoison;
163
        endEffect->mIsCart = startEffect->mIsCart;
164
        endEffect->mIsRiding = startEffect->mIsRiding;
165
        endEffect->mIsTrickDead = startEffect->mIsTrickDead;
166
        endEffect->mIsPostDelay = startEffect->mIsPostDelay;
167
        endEffect->mMessage = XML::getProperty(node, "end-message", "");
168
        endEffect->mSFXEffect = XML::getProperty(node, "end-audio", "");
169
        endEffect->mStartParticleEffect = XML::getProperty(
170
            node, "end-particle", "");
171
172
        statusEffects[1][id] = startEffect;
173
        statusEffects[0][id] = endEffect;
174
    }
175
}
176
177
static void unloadMap(std::map<int, StatusEffect *> &map)
178
{
179
    for (std::map<int, StatusEffect *>::iterator it = map.begin();
180
         it != map.end(); ++it)
181
    {
182
        delete (*it).second;
183
    }
184
185
    map.clear();
186
}
187
188
215
void StatusEffectDB::unload()
189
{
190
215
    if (!mLoaded)
191
        return;
192
193
    logger->log1("Unloading status effect database...");
194
195
    fakeId = 10000;
196
    unloadMap(statusEffects[0]);
197
    unloadMap(statusEffects[1]);
198
199
    optionToIdMap.clear();
200
    opt1ToIdMap.clear();
201
    opt2ToIdMap.clear();
202
    opt3ToIdMap.clear();
203
204
    mLoaded = false;
205
}
206
207
const OptionsMap& StatusEffectDB::getOptionMap()
208
{
209
    return optionToIdMap;
210
}
211
212
const OptionsMap& StatusEffectDB::getOpt1Map()
213
{
214
    return opt1ToIdMap;
215
}
216
217
const OptionsMap& StatusEffectDB::getOpt2Map()
218
{
219
    return opt2ToIdMap;
220
}
221
222
const OptionsMap& StatusEffectDB::getOpt3Map()
223
{
224
    return opt3ToIdMap;
225

3
}