ManaPlus
colordb.cpp
Go to the documentation of this file.
1 /*
2  * The ManaPlus Client
3  * Copyright (C) 2008 Aethyra Development Team
4  * Copyright (C) 2011-2019 The ManaPlus Developers
5  * Copyright (C) 2019-2021 Andrei Karas
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/colordb.h"
24 
25 #include "configuration.h"
26 
27 #include "utils/cast.h"
28 #include "utils/checkutils.h"
29 
30 #include "resources/beingcommon.h"
31 
32 #include "debug.h"
33 
34 namespace
35 {
36  int mHairColorsSize = 0;
37  bool mLoaded = false;
38  std::string mFail("#ffffff");
40 } // namespace
41 
43 {
44  if (mLoaded)
45  unload();
46 
47  logger->log1("Initializing color database...");
48 
49  std::map<ItemColor, ItemColorData> colors;
50  ColorListsIterator it = mColorLists.find("hair");
51  if (it != mColorLists.end())
52  colors = it->second;
53  loadHair(paths.getStringValue("hairColorFile"),
54  colors,
56  loadHair(paths.getStringValue("hairColorPatchFile"),
57  colors,
59  StringVect list;
61  "hairColorPatchDir"), list, ".xml");
62  FOR_EACH (StringVectCIter, it2, list)
63  loadHair(*it2, colors, SkipError_true);
64 
65  mColorLists["hair"] = colors;
66 
67  loadColorLists(paths.getStringValue("itemColorsFile"),
69  loadColorLists(paths.getStringValue("itemColorsPatchFile"),
71  loadXmlDir("itemColorsPatchDir", loadColorLists)
72 
73  it = mColorLists.find("hair");
74  if (it != mColorLists.end())
75  mHairColorsSize = CAST_S32((*it).second.size());
76  else
77  mHairColorsSize = 0;
78  mLoaded = true;
79 }
80 
81 void ColorDB::loadHair(const std::string &fileName,
82  std::map<ItemColor, ItemColorData> &colors,
83  const SkipError skipError)
84 {
87  skipError);
88  XmlNodeConstPtrConst root = doc->rootNode();
89 
90  if ((root == nullptr) || !xmlNameEqual(root, "colors"))
91  {
92  logger->log("ColorDB: Failed to find hair colors file.");
93  if (colors.find(ItemColor_zero) == colors.end())
94  colors[ItemColor_zero] = ItemColorData(ItemColor_zero, "", "");
95  delete doc;
96  return;
97  }
98 
99  reportAlways("Found legacy hair.xml")
100  for_each_xml_child_node(node, root)
101  {
102  if (xmlNameEqual(node, "include"))
103  {
104  const std::string name = XML::getProperty(node, "name", "");
105  if (!name.empty())
106  loadHair(name, colors, skipError);
107  continue;
108  }
109  else if (xmlNameEqual(node, "color"))
110  {
112  node, "id", 0), ItemColor);
113 
114  if (colors.find(id) != colors.end())
115  {
116  reportAlways("ColorDB: Redefinition of dye ID %d",
117  toInt(id, int))
118  }
119 
120  colors[id] = ItemColorData(id, XML::langProperty(node, "name", ""),
121  XML::getProperty(node, "value", "#FFFFFF"));
122  }
123  }
124 
125  delete doc;
126 }
127 
128 void ColorDB::loadColorLists(const std::string &fileName,
129  const SkipError skipError)
130 {
133  skipError);
134  XmlNodeConstPtrConst root = doc->rootNode();
135  if (root == nullptr)
136  {
137  delete doc;
138  return;
139  }
140 
141  for_each_xml_child_node(node, root)
142  {
143  if (xmlNameEqual(node, "include"))
144  {
145  const std::string name = XML::getProperty(node, "name", "");
146  if (!name.empty())
147  loadColorLists(name, skipError);
148  continue;
149  }
150  else if (xmlNameEqual(node, "list"))
151  {
152  const std::string name = XML::getProperty(node, "name", "");
153  if (name.empty())
154  continue;
155 
156  std::map <ItemColor, ItemColorData> colors;
157  const ColorListsIterator it = mColorLists.find(name);
158 
159  if (it != mColorLists.end())
160  colors = it->second;
161 
162  for_each_xml_child_node(colorNode, node)
163  {
164  if (xmlNameEqual(colorNode, "color"))
165  {
166  const int id = XML::getProperty(colorNode, "id", -1);
167  if (id > -1)
168  {
170  XML::langProperty(colorNode, "name", ""),
171  XML::getProperty(colorNode, "value", ""));
172  colors[c.id] = c;
173  }
174  }
175  }
176  mColorLists[name] = colors;
177  }
178  }
179  delete doc;
180 }
181 
183 {
184  logger->log1("Unloading color database...");
185 
186  mColorLists.clear();
187  mLoaded = false;
188 }
189 
190 std::string &ColorDB::getHairColorName(const ItemColor id)
191 {
192  if (!mLoaded)
193  load();
194 
195  const ColorListsIterator it = mColorLists.find("hair");
196  if (it == mColorLists.end())
197  {
198  reportAlways("ColorDB: Error, hair colors list empty")
199  return mFail;
200  }
201 
202  const ColorIterator i = (*it).second.find(id);
203 
204  if (i == (*it).second.end())
205  {
206  reportAlways("ColorDB: Error, unknown dye ID# %d",
207  toInt(id, int))
208  return mFail;
209  }
210  return i->second.name;
211 }
212 
214 {
215  return mHairColorsSize;
216 }
217 
218 const std::map <ItemColor, ItemColorData>
219  *ColorDB::getColorsList(const std::string &name)
220 {
221  const ColorListsIterator it = mColorLists.find(name);
222 
223  if (it != mColorLists.end())
224  return &it->second;
225  return nullptr;
226 }
#define loadXmlDir(name, function)
Definition: beingcommon.h:39
#define CAST_S32
Definition: cast.h:30
#define reportAlways(...)
Definition: checkutils.h:253
std::string getStringValue(const std::string &key) const
ItemColor id
Definition: itemcolordata.h:52
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 FOR_EACH(type, iter, array)
Definition: foreach.h:25
#define toInt(val, name)
Definition: intdefines.h:47
#define fromInt(val, name)
Definition: intdefines.h:46
uint16_t ItemColor
Definition: itemcolor.h:30
const ItemColor ItemColor_zero
Definition: itemcolor.h:30
#define for_each_xml_child_node(var, parent)
Definition: libxml.h:161
Logger * logger
Definition: logger.cpp:89
void load()
Definition: avatardb.cpp:46
const std::map< ItemColor, ItemColorData > * getColorsList(const std::string &name)
Definition: colordb.cpp:219
void unload()
Definition: colordb.cpp:182
Colors::iterator ColorIterator
Definition: colordb.h:69
void loadColorLists(const std::string &fileName, const SkipError skipError)
Definition: colordb.cpp:128
std::map< std::string, std::map< ItemColor, ItemColorData > > ColorLists
Definition: colordb.h:71
void loadHair(const std::string &fileName, std::map< ItemColor, ItemColorData > &colors, const SkipError skipError)
Definition: colordb.cpp:81
ColorLists::iterator ColorListsIterator
Definition: colordb.h:72
int getHairSize()
Definition: colordb.cpp:213
void load()
Definition: colordb.cpp:42
std::string & getHairColorName(const ItemColor id)
Definition: colordb.cpp:190
void unload()
Definition: net.cpp:180
void getFilesInDir(const std::string &dir, StringVect &list, const std::string &ext)
Definition: tools.cpp:81
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::string mFail("#ffffff")
ColorDB::ColorLists mColorLists
Definition: colordb.cpp:39
const bool SkipError_false
Definition: skiperror.h:30
const bool SkipError_true
Definition: skiperror.h:30
bool SkipError
Definition: skiperror.h:30
StringVect::const_iterator StringVectCIter
Definition: stringvector.h:31
std::vector< std::string > StringVect
Definition: stringvector.h:29
std::string fileName
Definition: testmain.cpp:39
const bool UseVirtFs_true
Definition: usevirtfs.h:30