GCC Code Coverage Report
Directory: src/ Exec Total Coverage
File: src/resources/db/itemoptiondb.cpp Lines: 8 58 13.8 %
Date: 2021-03-17 Branches: 2 104 1.9 %

Line Branch Exec Source
1
/*
2
 *  The ManaPlus Client
3
 *  Copyright (C) 2016-2019  The ManaPlus Developers
4
 *  Copyright (C) 2019-2021  Andrei Karas
5
 *
6
 *  This file is part of The ManaPlus Client.
7
 *
8
 *  This program is free software; you can redistribute it and/or modify
9
 *  it under the terms of the GNU General Public License as published by
10
 *  the Free Software Foundation; either version 2 of the License, or
11
 *  any later version.
12
 *
13
 *  This program is distributed in the hope that it will be useful,
14
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 *  GNU General Public License for more details.
17
 *
18
 *  You should have received a copy of the GNU General Public License
19
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
 */
21
22
#include "resources/db/itemoptiondb.h"
23
24
#include "configuration.h"
25
26
#include "utils/checkutils.h"
27
28
#include "resources/beingcommon.h"
29
30
#include "resources/db/itemfielddb.h"
31
32
#include "debug.h"
33
34
namespace
35
{
36
1
    ItemOptionDb::OptionInfos mOptions;
37
1
    const STD_VECTOR<ItemFieldType*> mEmptyOption;
38
    bool mLoaded = false;
39
}  // namespace
40
41
void ItemOptionDb::load()
42
{
43
    if (mLoaded)
44
        unload();
45
46
    logger->log1("Initializing item options database...");
47
    loadXmlFile(paths.getStringValue("itemOptionsFile"), SkipError_false);
48
    loadXmlFile(paths.getStringValue("itemOptionsPatchFile"), SkipError_true);
49
    loadXmlDir("itemOptionsPatchDir", loadXmlFile)
50
    mLoaded = true;
51
}
52
53
static void addFieldByName(STD_VECTOR<ItemFieldType*> &options,
54
                           XmlNodeConstPtr node,
55
                           const ItemFieldInfos &fields,
56
                           const char *const name)
57
{
58
    std::string value = XML::getProperty(node, name, "");
59
    if (value.empty())
60
        return;
61
62
    FOR_EACH (ItemFieldInfos::const_iterator, it, fields)
63
    {
64
        const std::string fieldName = (*it).first;
65
        if (fieldName == value)
66
        {
67
            options.push_back((*it).second);
68
            return;
69
        }
70
    }
71
}
72
73
static void readOptionFields(STD_VECTOR<ItemFieldType*> &options,
74
                             XmlNodeConstPtr node,
75
                             const ItemFieldInfos &fields)
76
{
77
    addFieldByName(options, node, fields, "field");
78
    for (int f = 0; f < 15; f ++)
79
    {
80
        const std::string field = strprintf("field%d", f);
81
        addFieldByName(options, node, fields, field.c_str());
82
    }
83
}
84
85
void ItemOptionDb::loadXmlFile(const std::string &fileName,
86
                               const SkipError skipError)
87
{
88
    XML::Document doc(fileName,
89
        UseVirtFs_true,
90
        skipError);
91
    XmlNodeConstPtrConst rootNode = doc.rootNode();
92
93
    if ((rootNode == nullptr) || !xmlNameEqual(rootNode, "itemoptions"))
94
    {
95
        if (skipError == SkipError_true)
96
        {
97
            logger->log("ItemFieldDb: Error while loading %s!",
98
                fileName.c_str());
99
        }
100
        else
101
        {
102
            reportAlways("ItemFieldDb: Error while loading %s!",
103
                fileName.c_str())
104
        }
105
        return;
106
    }
107
108
    const ItemFieldInfos &requiredFields =
109
        ItemFieldDb::getRequiredFields();
110
    const ItemFieldInfos &addFields =
111
        ItemFieldDb::getAddFields();
112
113
    for_each_xml_child_node(node, rootNode)
114
    {
115
        if (xmlNameEqual(node, "include"))
116
        {
117
            const std::string name = XML::getProperty(node, "name", "");
118
            if (!name.empty())
119
                loadXmlFile(name, skipError);
120
            continue;
121
        }
122
        if (xmlNameEqual(node, "option"))
123
        {
124
            const int id = XML::getProperty(node,
125
                "id",
126
                0);
127
            if (id <= 0)
128
            {
129
                reportAlways("Empty id field in ItemOptionDb")
130
                continue;
131
            }
132
            STD_VECTOR<ItemFieldType*> &options = mOptions[id];
133
            readOptionFields(options, node, requiredFields);
134
            readOptionFields(options, node, addFields);
135
        }
136
    }
137
}
138
139
215
void ItemOptionDb::unload()
140
{
141
215
    logger->log1("Unloading item options database...");
142
215
    mOptions.clear();
143
215
    mLoaded = false;
144
215
}
145
146
const STD_VECTOR<ItemFieldType*> &ItemOptionDb::getFields(const int id)
147
{
148
    OptionInfos::const_iterator it = mOptions.find(id);
149
    if (it == mOptions.end())
150
        return mEmptyOption;
151
    return (*it).second;
152

3
}