ManaPlus
horsedb.cpp
Go to the documentation of this file.
1 /*
2  * The ManaPlus Client
3  * Copyright (C) 2009 Aethyra Development Team
4  * Copyright (C) 2011-2019 The ManaPlus Developers
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/horsedb.h"
23 
24 #include "configuration.h"
25 
27 
28 #include "resources/beingcommon.h"
29 #include "resources/horseinfo.h"
30 
31 #include "utils/checkutils.h"
32 #include "utils/dtor.h"
33 
34 #include "debug.h"
35 
36 namespace
37 {
40  bool mLoaded = false;
41 } // namespace
42 
43 #define loadSprite(name) \
44  { \
45  SpriteReference *const currentSprite = new SpriteReference; \
46  currentSprite->sprite = pathJoin(paths.getStringValue("sprites"), \
47  XmlChildContent(spriteNode)); \
48  currentSprite->variant = XML::getProperty( \
49  spriteNode, "variant", 0); \
50  currentInfo->name.push_back(currentSprite); \
51  }
52 
53 static void loadDownSprites(XmlNodePtrConst parentNode,
54  HorseInfo *const currentInfo);
55 
56 static void loadUpSprites(XmlNodePtrConst parentNode,
57  HorseInfo *const currentInfo);
58 
60 {
61  if (mLoaded)
62  unload();
63 
64  logger->log1("Initializing horse database...");
65 
66  SpriteReference *currentSprite = new SpriteReference;
67  currentSprite->sprite = pathJoin(paths.getStringValue("sprites"),
68  paths.getStringValue("spriteErrorFile"));
69  currentSprite->variant = 0;
70  mUnknown.downSprites.push_back(currentSprite);
71 
72  currentSprite = new SpriteReference;
73  currentSprite->sprite = pathJoin(paths.getStringValue("sprites"),
74  paths.getStringValue("spriteErrorFile"));
75  currentSprite->variant = 0;
76  mUnknown.upSprites.push_back(currentSprite);
77 
79  loadXmlFile(paths.getStringValue("horsesPatchFile"), SkipError_true);
80  loadXmlDir("horsesPatchDir", loadXmlFile)
81 
82  mLoaded = true;
83 }
84 
85 static int parseDirectionName(const std::string &name)
86 {
87  int id = -1;
88  if (name == "down")
89  {
91  }
92  else if (name == "downleft" || name == "leftdown")
93  {
95  }
96  else if (name == "left")
97  {
99  }
100  else if (name == "upleft" || name == "leftup")
101  {
103  }
104  else if (name == "up")
105  {
106  id = SpriteDirection::UP;
107  }
108  else if (name == "upright" || name == "rightup")
109  {
111  }
112  else if (name == "right")
113  {
115  }
116  else if (name == "downright" || name == "rightdown")
117  {
119  }
120  // hack for died action.
121  else if (name == "died")
122  {
123  id = 9;
124  }
125 
126  return id;
127 }
128 
129 static void loadRiderOffset(XmlNodePtrConst node,
130  HorseInfo *const currentInfo)
131 {
132  const std::string dirName = XML::getProperty(node,
133  "direction", "");
134  const int dir = parseDirectionName(dirName);
135  if (dir == -1)
136  {
137  reportAlways("Wrong or missing horse rider direcion: %s",
138  dirName.c_str())
139  return;
140  }
141  HorseOffset &offset = currentInfo->offsets[dir];
142  offset.riderOffsetX = XML::getProperty(node,
143  "riderOffsetX", 0);
144  offset.riderOffsetY = XML::getProperty(node,
145  "riderOffsetY", 0);
146 }
147 
148 void HorseDB::loadXmlFile(const std::string &fileName,
149  const SkipError skipError)
150 {
153  skipError);
154  XmlNodePtrConst rootNode = doc.rootNode();
155 
156  if ((rootNode == nullptr) || !xmlNameEqual(rootNode, "horses"))
157  {
158  logger->log("Horse Database: Error while loading %s!",
159  fileName.c_str());
160  return;
161  }
162 
163  // iterate <emote>s
164  for_each_xml_child_node(horseNode, rootNode)
165  {
166  if (xmlNameEqual(horseNode, "include"))
167  {
168  const std::string name = XML::getProperty(horseNode, "name", "");
169  if (!name.empty())
170  loadXmlFile(name, skipError);
171  continue;
172  }
173  else if (!xmlNameEqual(horseNode, "horse"))
174  {
175  continue;
176  }
177 
178  const int id = XML::getProperty(horseNode, "id", -1);
179 
180  if (id == -1)
181  {
182  reportAlways("Horse Database: Horse with missing ID in %s!",
183  paths.getStringValue("horsesFile").c_str())
184  continue;
185  }
186  HorseInfo *currentInfo = nullptr;
187  if (mHorseInfos.find(id) != mHorseInfos.end())
188  currentInfo = mHorseInfos[id];
189  else
190  currentInfo = new HorseInfo;
191 
192  if (currentInfo == nullptr)
193  continue;
194  for_each_xml_child_node(spriteNode, horseNode)
195  {
196  if (xmlNameEqual(spriteNode, "down"))
197  loadDownSprites(spriteNode, currentInfo);
198  else if (xmlNameEqual(spriteNode, "up"))
199  loadUpSprites(spriteNode, currentInfo);
200  else if (xmlNameEqual(spriteNode, "offset"))
201  loadRiderOffset(spriteNode, currentInfo);
202  }
203  mHorseInfos[id] = currentInfo;
204  }
205 }
206 
207 static void loadOffset(XmlNodePtrConst node,
208  HorseInfo *const currentInfo,
209  const bool isUp)
210 {
211  const std::string dirName = XML::getProperty(node,
212  "direction", "");
213  const int dir = parseDirectionName(dirName);
214  if (dir == -1)
215  {
216  reportAlways("Wrong or missing horse direcion: %s",
217  dirName.c_str())
218  return;
219  }
220  HorseOffset &offset = currentInfo->offsets[dir];
221  if (isUp)
222  {
223  offset.upOffsetX = XML::getProperty(node,
224  "horseOffsetX", 0);
225  offset.upOffsetY = XML::getProperty(node,
226  "horseOffsetY", 0);
227  }
228  else
229  {
230  offset.downOffsetX = XML::getProperty(node,
231  "horseOffsetX", 0);
232  offset.downOffsetY = XML::getProperty(node,
233  "horseOffsetY", 0);
234  }
235 }
236 
237 static void loadDownSprites(XmlNodePtrConst parentNode,
238  HorseInfo *const currentInfo)
239 {
240  for_each_xml_child_node(spriteNode, parentNode)
241  {
242  if (xmlNameEqual(spriteNode, "offset"))
243  loadOffset(spriteNode, currentInfo, false);
244  if (!XmlHaveChildContent(spriteNode))
245  continue;
246  if (xmlNameEqual(spriteNode, "sprite"))
247  loadSprite(downSprites)
248  }
249 }
250 
251 static void loadUpSprites(XmlNodePtrConst parentNode,
252  HorseInfo *const currentInfo)
253 {
254  for_each_xml_child_node(spriteNode, parentNode)
255  {
256  if (xmlNameEqual(spriteNode, "offset"))
257  loadOffset(spriteNode, currentInfo, true);
258  if (!XmlHaveChildContent(spriteNode))
259  continue;
260  if (xmlNameEqual(spriteNode, "sprite"))
261  loadSprite(upSprites)
262  }
263 }
264 
266 {
267  logger->log1("Unloading horse database...");
268  FOR_EACH (HorseInfos::const_iterator, i, mHorseInfos)
269  {
270  delete_all(i->second->upSprites);
271  delete_all(i->second->downSprites);
272  delete i->second;
273  }
274  mHorseInfos.clear();
275 
278  mUnknown.upSprites.clear();
279  mUnknown.downSprites.clear();
280 
281  mLoaded = false;
282 }
283 
284 HorseInfo *HorseDB::get(const int id, const bool allowNull)
285 {
286  const HorseInfos::const_iterator i = mHorseInfos.find(id);
287 
288  if (i == mHorseInfos.end())
289  {
290  if (allowNull)
291  return nullptr;
292  reportAlways("HorseDB: Warning, unknown horse ID %d requested",
293  id)
294  return &mUnknown;
295  }
296  return i->second;
297 }
298 
300 {
301  return static_cast<signed int>(mHorseInfos.size());
302 }
SkipError
bool SkipError
Definition: skiperror.h:29
horseinfo.h
reportAlways
#define reportAlways(...)
Definition: checkutils.h:252
SpriteDirection::DOWN
@ DOWN
Definition: spritedirection.h:32
horsedb.h
SkipError_true
const bool SkipError_true
Definition: skiperror.h:29
HorseDB::size
int size()
Definition: horsedb.cpp:299
SpriteDirection::UPLEFT
@ UPLEFT
Definition: spritedirection.h:35
anonymous_namespace{horsedb.cpp}::mUnknown
HorseInfo mUnknown
Definition: horsedb.cpp:39
Net::unload
void unload()
Definition: net.cpp:179
parseDirectionName
static int parseDirectionName(const std::string &name)
Definition: horsedb.cpp:85
anonymous_namespace{horsedb.cpp}::mLoaded
bool mLoaded
Definition: horsedb.cpp:40
paths
Configuration paths
Definition: configuration.cpp:55
loadSprite
#define loadSprite(name)
Definition: horsedb.cpp:43
HorseInfo::offsets
HorseOffset offsets[10]
Definition: horseinfo.h:53
SkipError_false
const bool SkipError_false
Definition: skiperror.h:29
SpriteDirection::DOWNLEFT
@ DOWNLEFT
Definition: spritedirection.h:37
pathJoin
std::string pathJoin(std::string str1, const std::string &str2)
Definition: stringutils.cpp:1036
XML::Document
Definition: libxml.h:52
HorseDB::get
HorseInfo * get(const int id, const bool allowNull)
Definition: horsedb.cpp:284
HorseOffset::downOffsetX
int downOffsetX
Definition: horseoffset.h:41
XML::getProperty
int getProperty(const xmlNodePtr node, const char *const name, int def)
Definition: libxml.cpp:173
logger
Logger * logger
Definition: logger.cpp:88
HorseDB::loadXmlFile
void loadXmlFile(const std::string &fileName, const SkipError skipError)
Definition: horsedb.cpp:148
fileName
std::string fileName
Definition: testmain.cpp:38
SpriteReference
Definition: spritereference.h:30
SpriteDirection::LEFT
@ LEFT
Definition: spritedirection.h:33
HorseInfo::upSprites
std::vector< SpriteReference * > upSprites
Definition: horseinfo.h:52
loadXmlDir
#define loadXmlDir(name, function)
Definition: beingcommon.h:38
SpriteDirection::DOWNRIGHT
@ DOWNRIGHT
Definition: spritedirection.h:38
checkutils.h
anonymous_namespace{horsedb.cpp}::mHorseInfos
HorseInfos mHorseInfos
Definition: horsedb.cpp:38
SpriteDirection::UP
@ UP
Definition: spritedirection.h:31
beingcommon.h
loadXmlFile
static void loadXmlFile(const std::string &file, const std::string &name, BadgesInfos &arr, const SkipError skipError)
Definition: badgesdb.cpp:42
UseVirtFs_true
const bool UseVirtFs_true
Definition: usevirtfs.h:29
Configuration::getStringValue
std::string getStringValue(const std::string &key) const
Definition: configuration.cpp:487
HorseDB::unload
void unload()
Definition: horsedb.cpp:265
HorseInfos
std::map< int, HorseInfo * > HorseInfos
Definition: horsedb.h:32
Logger::log1
void log1(const char *const log_text)
Definition: logger.cpp:237
loadDownSprites
static void loadDownSprites(xmlNode *const parentNode, HorseInfo *const currentInfo)
Definition: horsedb.cpp:237
loadRiderOffset
static void loadRiderOffset(xmlNode *const node, HorseInfo *const currentInfo)
Definition: horsedb.cpp:129
delete_all
void delete_all(Container &c)
Definition: dtor.h:55
configuration.h
SpriteReference::variant
int variant
Definition: spritereference.h:48
SpriteDirection::UPRIGHT
@ UPRIGHT
Definition: spritedirection.h:36
SpriteDirection::RIGHT
@ RIGHT
Definition: spritedirection.h:34
XML::Document::rootNode
xmlNodePtr rootNode()
Definition: libxml.cpp:168
HorseInfo
Definition: horseinfo.h:31
loadOffset
static void loadOffset(xmlNode *const node, HorseInfo *const currentInfo, const bool isUp)
Definition: horsedb.cpp:207
HorseOffset::upOffsetX
int upOffsetX
Definition: horseoffset.h:39
HorseOffset::riderOffsetY
int riderOffsetY
Definition: horseoffset.h:44
dtor.h
for_each_xml_child_node
#define for_each_xml_child_node(var, parent)
Definition: libxml.h:160
SpriteReference::sprite
std::string sprite
Definition: spritereference.h:47
loadUpSprites
static void loadUpSprites(xmlNode *const parentNode, HorseInfo *const currentInfo)
Definition: horsedb.cpp:251
HorseInfo::downSprites
std::vector< SpriteReference * > downSprites
Definition: horseinfo.h:51
HorseOffset::riderOffsetX
int riderOffsetX
Definition: horseoffset.h:43
HorseOffset::downOffsetY
int downOffsetY
Definition: horseoffset.h:42
Logger::log
void log(const char *const log_text,...)
Definition: logger.cpp:268
FOR_EACH
#define FOR_EACH(type, iter, array)
Definition: foreach.h:24
debug.h
HorseOffset
Definition: horseoffset.h:26
HorseDB::load
void load()
Definition: horsedb.cpp:59
spritedirection.h
HorseOffset::upOffsetY
int upOffsetY
Definition: horseoffset.h:40