ManaPlus
statdb.cpp
Go to the documentation of this file.
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/statdb.h"
23 
24 #include "configuration.h"
25 
27 
28 #include "utils/checkutils.h"
29 
30 #include "resources/beingcommon.h"
31 
32 #include "utils/gettext.h"
33 
34 #include "debug.h"
35 
36 namespace
37 {
38  bool mLoaded = false;
39  STD_VECTOR<BasicStat> mBasicStats;
40  std::map<std::string, STD_VECTOR<BasicStat> > mStats;
41  STD_VECTOR<std::string> mPages;
42 } // namespace
43 
45 {
47  "str",
48  // TRANSLATORS: player stat
49  _("Strength")));
51  "agi",
52  // TRANSLATORS: player stat
53  _("Agility")));
55  "vit",
56  // TRANSLATORS: player stat
57  _("Vitality")));
59  "int",
60  // TRANSLATORS: player stat
61  _("Intelligence")));
63  "dex",
64  // TRANSLATORS: player stat
65  _("Dexterity")));
67  "luk",
68  // TRANSLATORS: player stat
69  _("Luck")));
70 }
71 
72 const STD_VECTOR<BasicStat> &StatDb::getBasicStats()
73 {
74  return mBasicStats;
75 }
76 
77 const STD_VECTOR<BasicStat> &StatDb::getStats(const std::string &page)
78 {
79  return mStats[page];
80 }
81 
82 const STD_VECTOR<std::string> &StatDb::getPages()
83 {
84  return mPages;
85 }
86 
88 {
89  if (mLoaded)
90  unload();
91 
92  logger->log1("Initializing stat database...");
93 
96  loadXmlDir("statPatchDir", loadXmlFile)
97  mLoaded = true;
98 }
99 
100 static void loadBasicStats(XmlNodeConstPtr rootNode)
101 {
102  const int maxAttr = static_cast<int>(Attributes::MAX_ATTRIBUTE);
103  for_each_xml_child_node(node, rootNode)
104  {
105  if (xmlNameEqual(node, "stat"))
106  {
107  const std::string name = XML::getProperty(node, "name", "");
108  const std::string attr = XML::getProperty(node, "attr", "");
109  if (attr.empty() || AttributesEnum::find(attr) == false)
110  {
111  const int id = XML::getProperty(node, "id", 0);
112  if (id <= 0 || id >= maxAttr)
113  {
114  reportAlways("Wrong attr or id for basic "
115  "stat with name %s",
116  name.c_str())
117  continue;
118  }
119  const std::string tag = XML::getProperty(node, "tag", "");
120  mBasicStats.push_back(BasicStat(static_cast<AttributesT>(id),
121  tag,
122  name));
123  }
124  else
125  {
126  const std::string tag = XML::getProperty(node, "tag", "");
127  mBasicStats.push_back(BasicStat(AttributesEnum::get(attr),
128  tag,
129  name));
130  }
131  }
132  }
133 }
134 
135 static void loadStats(XmlNodeConstPtr rootNode,
136  const std::string &page)
137 {
138  const int maxAttr = static_cast<int>(Attributes::MAX_ATTRIBUTE);
139  STD_VECTOR<BasicStat> &stats = mStats[page];
140  mPages.push_back(page);
141  for_each_xml_child_node(node, rootNode)
142  {
143  if (xmlNameEqual(node, "stat"))
144  {
145  const std::string name = XML::getProperty(node, "name", "");
146  const std::string attr = XML::getProperty(node, "attr", "");
147  if (attr.empty() || AttributesEnum::find(attr) == false)
148  {
149  const int id = XML::getProperty(node, "id", 0);
150  if (id <= 0 || id >= maxAttr)
151  {
152  reportAlways("Wrong attr or id for extended "
153  "stat with name %s",
154  name.c_str())
155  continue;
156  }
157  stats.push_back(BasicStat(static_cast<AttributesT>(id),
158  std::string(),
159  name));
160  }
161  else
162  {
163  stats.push_back(BasicStat(AttributesEnum::get(attr),
164  std::string(),
165  name));
166  }
167  }
168  }
169 }
170 
171 void StatDb::loadXmlFile(const std::string &fileName,
172  const SkipError skipError)
173 {
176  skipError);
177  XmlNodeConstPtrConst rootNode = doc.rootNode();
178 
179  if ((rootNode == nullptr) || !xmlNameEqual(rootNode, "stats"))
180  {
181  logger->log("StatDb: Error while loading %s!",
182  fileName.c_str());
183  if (skipError == SkipError_false)
184  addDefaultStats();
185  return;
186  }
187 
188  for_each_xml_child_node(node, rootNode)
189  {
190  if (xmlNameEqual(node, "include"))
191  {
192  const std::string name = XML::getProperty(node, "name", "");
193  if (!name.empty())
194  loadXmlFile(name, skipError);
195  continue;
196  }
197  else if (xmlNameEqual(node, "basic"))
198  {
199  loadBasicStats(node);
200  }
201  else if (xmlNameEqual(node, "extended"))
202  {
203  // TRANSLATORS: stats page name
204  loadStats(node, _("Extended"));
205  }
206  else if (xmlNameEqual(node, "page"))
207  {
208  std::string page = XML::langProperty(node, "name", "");
209  if (page.empty())
210  {
211  reportAlways("Page without name in stats.xml")
212  page = "Unknown";
213  }
214  loadStats(node, page);
215  }
216  }
217  if (skipError == SkipError_false)
218  {
219  if (mBasicStats.empty() &&
220  mStats.empty())
221  {
222  reportAlways("StatDb: no stats found")
223  addDefaultStats();
224  }
225  }
226 }
227 
229 {
230  logger->log1("Unloading stat database...");
231 
232  mBasicStats.clear();
233  mStats.clear();
234  mPages.clear();
235  mLoaded = false;
236 }
Attributes ::T AttributesT
Definition: attributes.h:118
static void loadXmlFile(const std::string &file, const std::string &name, BadgesInfos &arr, const SkipError skipError)
Definition: badgesdb.cpp:43
#define loadXmlDir(name, function)
Definition: beingcommon.h:39
#define reportAlways(...)
Definition: checkutils.h:253
std::string getStringValue(const std::string &key) const
void log(const char *const log_text,...)
Definition: logger.cpp:269
void log1(const char *const log_text)
Definition: logger.cpp:238
xmlNodePtr rootNode()
Definition: libxml.cpp:169
Configuration paths
#define _(s)
Definition: gettext.h:35
#define for_each_xml_child_node(var, parent)
Definition: libxml.h:161
Logger * logger
Definition: logger.cpp:89
bool find(const std::string &key)
AttributesT get(const std::string &key)
void unload()
Definition: net.cpp:180
const std::vector< BasicStat > & getBasicStats()
Definition: statdb.cpp:72
void load()
Definition: statdb.cpp:87
void addDefaultStats()
Definition: statdb.cpp:44
void unload()
Definition: statdb.cpp:228
const std::vector< BasicStat > & getStats(const std::string &page)
Definition: statdb.cpp:77
const std::vector< std::string > & getPages()
Definition: statdb.cpp:82
void loadXmlFile(const std::string &fileName, const SkipError skipError)
Definition: statdb.cpp:171
std::string langProperty(const xmlNodePtr node, const char *const name, const std::string &def)
Definition: libxml.cpp:258
int getProperty(const xmlNodePtr node, const char *const name, int def)
Definition: libxml.cpp:174
std::map< std::string, std::vector< BasicStat > > mStats
Definition: statdb.cpp:40
std::vector< std::string > mPages
Definition: statdb.cpp:41
std::vector< BasicStat > mBasicStats
Definition: statdb.cpp:39
const bool SkipError_false
Definition: skiperror.h:30
const bool SkipError_true
Definition: skiperror.h:30
bool SkipError
Definition: skiperror.h:30
static void loadStats(const xmlNodePtr rootNode, const std::string &page)
Definition: statdb.cpp:135
static void loadBasicStats(const xmlNodePtr rootNode)
Definition: statdb.cpp:100
std::string fileName
Definition: testmain.cpp:39
const bool UseVirtFs_true
Definition: usevirtfs.h:30