GCC Code Coverage Report
Directory: src/ Exec Total Coverage
File: src/resources/db/elementaldb.cpp Lines: 2 58 3.4 %
Date: 2017-11-29 Branches: 0 108 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 "resources/db/elementaldb.h"
24
25
#include "configuration.h"
26
27
#include "resources/beingcommon.h"
28
#include "resources/beinginfo.h"
29
30
#include "utils/checkutils.h"
31
#include "utils/dtor.h"
32
33
#include "debug.h"
34
35
namespace
36
{
37
2
    BeingInfos mElementalInfos;
38
    bool mLoaded = false;
39
}  // namespace
40
41
void ElementalDb::load()
42
{
43
    if (mLoaded)
44
        unload();
45
46
    logger->log1("Initializing elemental database...");
47
    loadXmlFile(paths.getStringValue("elementalsFile"), SkipError_false);
48
    loadXmlFile(paths.getStringValue("elementalsPatchFile"), SkipError_true);
49
    loadXmlDir("elementalsPatchDir", loadXmlFile);
50
51
    mLoaded = true;
52
}
53
54
void ElementalDb::loadXmlFile(const std::string &fileName,
55
                              const SkipError skipError)
56
{
57
    XML::Document doc(fileName, UseVirtFs_true, skipError);
58
    XmlNodeConstPtr rootNode = doc.rootNode();
59
60
    if ((rootNode == nullptr) || !xmlNameEqual(rootNode, "elementals"))
61
    {
62
        logger->log("Elemental Database: Error while loading %s!",
63
            paths.getStringValue("elementalsFile").c_str());
64
        mLoaded = true;
65
        return;
66
    }
67
68
    const int offset = XML::getProperty(rootNode, "offset", 0);
69
70
    // iterate <elemental>s
71
    for_each_xml_child_node(elementalNode, rootNode)
72
    {
73
        if (xmlNameEqual(elementalNode, "include"))
74
        {
75
            const std::string name = XML::getProperty(
76
                elementalNode, "name", "");
77
            if (!name.empty())
78
                loadXmlFile(name, skipError);
79
            continue;
80
        }
81
        if (!xmlNameEqual(elementalNode, "elemental"))
82
            continue;
83
84
        const int id = XML::getProperty(elementalNode, "id", 0);
85
        BeingInfo *currentInfo = nullptr;
86
        if (mElementalInfos.find(fromInt(id + offset, BeingTypeId))
87
            != mElementalInfos.end())
88
        {
89
            logger->log("ElementalDb: Redefinition of elemental ID %d", id);
90
            currentInfo = mElementalInfos[fromInt(id + offset, BeingTypeId)];
91
        }
92
        if (currentInfo == nullptr)
93
            currentInfo = new BeingInfo;
94
95
        currentInfo->setBlockType(BlockType::NONE);
96
        BeingCommon::readBasicAttributes(currentInfo,
97
            elementalNode, "attack");
98
        BeingCommon::readWalkingAttributes(currentInfo,
99
            elementalNode,
100
            0);
101
102
        currentInfo->setMaxHP(XML::getProperty(elementalNode, "maxHP", 0));
103
104
        currentInfo->setDeadSortOffsetY(XML::getProperty(
105
            elementalNode, "deadSortOffsetY", 31));
106
107
        currentInfo->setColorsList(XML::getProperty(elementalNode,
108
            "colors", ""));
109
110
        if (currentInfo->getMaxHP() != 0)
111
            currentInfo->setStaticMaxHP(true);
112
113
        SpriteDisplay display;
114
115
        // iterate <sprite>s and <sound>s
116
        for_each_xml_child_node(spriteNode, elementalNode)
117
        {
118
            BeingCommon::readObjectNodes(spriteNode, display,
119
                currentInfo, "ElementalDb");
120
        }
121
        currentInfo->setDisplay(display);
122
123
        mElementalInfos[fromInt(id + offset, BeingTypeId)] = currentInfo;
124
    }
125
}
126
127
void ElementalDb::unload()
128
{
129
    logger->log1("Unloading elemental database...");
130
    delete_all(mElementalInfos);
131
    mElementalInfos.clear();
132
133
    mLoaded = false;
134
}
135
136
137
BeingInfo *ElementalDb::get(const BeingTypeId id)
138
{
139
    BeingInfoIterator i = mElementalInfos.find(id);
140
141
    if (i == mElementalInfos.end())
142
    {
143
        i = mElementalInfos.find(id);
144
        if (i == mElementalInfos.end())
145
        {
146
            reportAlways("ElementalDb: Warning, unknown elemental ID "
147
                "%d requested",
148
                toInt(id, int));
149
            return BeingInfo::unknown;
150
        }
151
    }
152
    return i->second;
153
4
}