ManaPlus
spritedef.cpp
Go to the documentation of this file.
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-2019 The ManaPlus Developers
6  * Copyright (C) 2019-2021 Andrei Karas
7  *
8  * This file is part of The ManaPlus Client.
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program. If not, see <http://www.gnu.org/licenses/>.
22  */
23 
25 
26 #include "configuration.h"
27 #include "settings.h"
28 
30 
32 
33 #include "utils/checkutils.h"
34 #include "utils/foreach.h"
35 
36 #include "resources/action.h"
37 #include "resources/imageset.h"
38 
40 
41 #include "resources/dye/dye.h"
42 
45 
47 
48 #include "debug.h"
49 
51 
52 const Action *SpriteDef::getAction(const std::string &action,
53  const unsigned num) const
54 {
55  Actions::const_iterator i = mActions.find(num);
56  if (i == mActions.end() && num != 100)
57  i = mActions.find(100);
58 
59  if (i == mActions.end() || ((*i).second == nullptr))
60  return nullptr;
61 
62  const ActionMap *const actMap = (*i).second;
63  if (actMap == nullptr)
64  return nullptr;
65  const ActionMap::const_iterator it = actMap->find(action);
66 
67  if (it == actMap->end())
68  {
69  logger->log("Warning: no action \"%s\" defined!", action.c_str());
70  return nullptr;
71  }
72 
73  return (*it).second;
74 }
75 
76 unsigned SpriteDef::findNumber(const unsigned num) const
77 {
78  unsigned min = 101;
79  FOR_EACH (Actions::const_iterator, it, mActions)
80  {
81  const unsigned n = (*it).first;
82  if (n >= num && n < min)
83  min = n;
84  }
85  if (min == 101)
86  return 0;
87  return min;
88 }
89 
90 SpriteDef *SpriteDef::load(const std::string &animationFile,
91  const int variant, const bool prot)
92 {
93  BLOCK_START("SpriteDef::load")
94  const size_t pos = animationFile.find('|');
95  std::string palettes;
96  if (pos != std::string::npos)
97  palettes = animationFile.substr(pos + 1);
98 
99  XML::Document *const doc = Loader::getXml(animationFile.substr(0, pos),
102  if (doc == nullptr)
103  return nullptr;
104  XmlNodePtrConst rootNode = doc->rootNode();
105 
106  if ((rootNode == nullptr) || !xmlNameEqual(rootNode, "sprite"))
107  {
108  reportAlways("Error, failed to parse sprite %s",
109  animationFile.c_str())
110  const std::string errorFile = pathJoin(paths.getStringValue("sprites"),
111  paths.getStringValue("spriteErrorFile"));
112  BLOCK_END("SpriteDef::load")
113  doc->decRef();
114  if (animationFile != errorFile)
115  return load(errorFile, 0, prot);
116  return nullptr;
117  }
118 
119  SpriteDef *const def = new SpriteDef;
120  def->mSource = animationFile;
121  def->mProcessedFiles.insert(animationFile);
122  def->loadSprite(rootNode, variant, palettes);
123  def->substituteActions();
125  def->fixDeadAction();
126  if (prot)
127  {
128  def->incRef();
129  def->mProtected = true;
130  }
131  doc->decRef();
132  BLOCK_END("SpriteDef::load")
133  return def;
134 }
135 
137 {
139  {
140  ActionMap *const d = (*it).second;
141  if (d == nullptr)
142  continue;
143  const ActionMap::iterator i = d->find(SpriteAction::DEAD);
144  const ActionMap::iterator i2 = d->find(SpriteAction::STAND);
145  // search dead action and check what it not same with stand action
146  if (i != d->end() &&
147  i->second != nullptr &&
148  (i2 == d->end() || i->second != i2->second))
149  {
150  (i->second)->setLastFrameDelay(0);
151  }
152  }
153 }
154 
155 void SpriteDef::substituteAction(const std::string &restrict complete,
156  const std::string &restrict with)
157 {
159  {
160  ActionMap *const d = (*it).second;
161  if (reportTrue(d == nullptr))
162  continue;
163  if (d->find(complete) == d->end())
164  {
165  const ActionMap::iterator i = d->find(with);
166  if (i != d->end())
167  (*d)[complete] = i->second;
168  }
169  }
170 }
171 
173 {
203 }
204 
205 void SpriteDef::loadSprite(XmlNodeConstPtr spriteNode,
206  const int variant,
207  const std::string &palettes)
208 {
209  BLOCK_START("SpriteDef::loadSprite")
210  if (spriteNode == nullptr)
211  {
212  BLOCK_END("SpriteDef::loadSprite")
213  return;
214  }
215  // Get the variant
216  const int variantCount = XML::getProperty(spriteNode, "variants", 0);
217  int variant_offset = 0;
218 
219  if (variantCount > 0 && variant < variantCount)
220  {
221  variant_offset = variant * XML::getProperty(spriteNode,
222  "variant_offset",
223  0);
224  }
225 
226  for_each_xml_child_node(node, spriteNode)
227  {
228  if (xmlNameEqual(node, "imageset"))
229  loadImageSet(node, palettes);
230  else if (xmlNameEqual(node, "action"))
231  loadAction(node, variant_offset);
232  else if (xmlNameEqual(node, "include"))
233  includeSprite(node, variant);
234  }
235  BLOCK_END("SpriteDef::loadSprite")
236 }
237 
238 void SpriteDef::loadImageSet(XmlNodeConstPtr node,
239  const std::string &palettes)
240 {
241  const std::string name = XML::getProperty(node, "name", "");
242 
243  // We don't allow redefining image sets. This way, an included sprite
244  // definition will use the already loaded image set with the same name.
245  if (mImageSets.find(name) != mImageSets.end())
246  return;
247 
248  const int width = XML::getProperty(node, "width", 0);
249  const int height = XML::getProperty(node, "height", 0);
250  std::string imageSrc = XML::getProperty(node, "src", "");
251  Dye::instantiate(imageSrc, palettes);
252 
253  ImageSet *const imageSet = Loader::getImageSet(imageSrc,
254  width, height);
255 
256  if (imageSet == nullptr)
257  {
258  reportAlways("%s: Couldn't load imageset: %s",
259  mSource.c_str(),
260  imageSrc.c_str())
261  return;
262  }
263 
264  imageSet->setOffsetX(XML::getProperty(node, "offsetX", 0));
265  imageSet->setOffsetY(XML::getProperty(node, "offsetY", 0));
266  mImageSets[name] = imageSet;
267 }
268 
269 const ImageSet *SpriteDef::getImageSet(const std::string &imageSetName) const
270 {
271  const ImageSetCIterator si = mImageSets.find(imageSetName);
272  if (si == mImageSets.end())
273  {
274  reportAlways("%s: Imageset \"%s\" not defined in %s",
275  mSource.c_str(),
276  imageSetName.c_str(),
277  mIdPath.c_str())
278  return nullptr;
279  }
280  return si->second;
281 }
282 
283 void SpriteDef::loadAction(XmlNodeConstPtr node,
284  const int variant_offset)
285 {
286  if (node == nullptr)
287  return;
288 
289  const std::string actionName = XML::getProperty(node, "name", "");
290  const std::string imageSetName = XML::getProperty(node, "imageset", "");
291  const unsigned hp = XML::getProperty(node, "hp", 100);
292  const ImageSet *const imageSet = getImageSet(imageSetName);
293 
294  if (actionName == SpriteAction::INVALID)
295  {
296  reportAlways("%s: Unknown action \"%s\" defined in %s",
297  mSource.c_str(),
298  actionName.c_str(),
299  mIdPath.c_str())
300  return;
301  }
302  Action *const action = new Action(actionName);
303  action->setNumber(hp);
304  addAction(hp, actionName, action);
305 
306  // dirty hack to fix bad resources in tmw server
307  if (actionName == "attack_stab")
308  {
309  reportAlways("Found legacy attribute attack_stab in animation")
310  addAction(hp, "attack", action);
311  }
312 
313  // When first action, set it as default direction.
314  // i here always correct, because hp was added above.
315  const Actions::const_iterator i = mActions.find(hp);
316  if ((*i).second->size() == 1)
317  addAction(hp, SpriteAction::DEFAULT, action);
318 
319  // Load animations
320  for_each_xml_child_node(animationNode, node)
321  {
322  if (xmlNameEqual(animationNode, "animation"))
323  loadAnimation(animationNode, action, imageSet, variant_offset);
324  }
325 }
326 
327 void SpriteDef::loadAnimation(XmlNodeConstPtr animationNode,
328  Action *const action,
329  const ImageSet *const imageSet0,
330  const int variant_offset) const
331 {
332  if (action == nullptr ||
333  imageSet0 == nullptr ||
334  animationNode == nullptr)
335  {
336  return;
337  }
338 
339  const std::string directionName =
340  XML::getProperty(animationNode, "direction", "");
341  const SpriteDirection::Type directionType
342  = makeSpriteDirection(directionName);
343 
344  if (directionType == SpriteDirection::INVALID)
345  {
346  reportAlways("%s: Unknown direction \"%s\" used in %s",
347  mSource.c_str(),
348  directionName.c_str(),
349  mIdPath.c_str())
350  return;
351  }
352 
353  Animation *const animation = new Animation(directionName);
354  action->setAnimation(directionType, animation);
355 
356  // Get animation frames
357  for_each_xml_child_node(frameNode, animationNode)
358  {
359  const int delay = XML::getIntProperty(
360  frameNode, "delay", 0, 0, 100000);
361  const std::string imageSetName = XML::getProperty(frameNode,
362  "imageset",
363  "");
364  const ImageSet *imageSet = imageSet0;
365  if (!imageSetName.empty())
366  {
367  imageSet = getImageSet(imageSetName);
368  if (imageSet == nullptr)
369  imageSet = imageSet0;
370  }
371  const int offsetX = XML::getProperty(frameNode, "offsetX", 0)
372  + imageSet->getOffsetX() - imageSet->getWidth() / 2
373  + mapTileSize / 2;
374  const int offsetY = XML::getProperty(frameNode, "offsetY", 0)
375  + imageSet->getOffsetY() - imageSet->getHeight() + mapTileSize;
376  const int rand = XML::getIntProperty(frameNode, "rand", 100, 0, 100);
377 
378  if (xmlNameEqual(frameNode, "frame"))
379  {
380  const int index = XML::getProperty(frameNode, "index", -1);
381 
382  if (index < 0)
383  {
384  reportAlways(
385  "%s: No valid value for 'index' at direction '%s'",
386  mSource.c_str(),
387  directionName.c_str())
388  continue;
389  }
390 
391  Image *const img = imageSet->get(index + variant_offset);
392  if (img == nullptr)
393  {
394  reportAlways("%s: No image at index %d at direction '%s'",
395  mSource.c_str(),
396  index + variant_offset,
397  directionName.c_str())
398  continue;
399  }
400 
401  animation->addFrame(img, delay, offsetX, offsetY, rand);
402  }
403  else if (xmlNameEqual(frameNode, "sequence"))
404  {
405  const int start = XML::getProperty(frameNode, "start", -1);
406  const int end = XML::getProperty(frameNode, "end", -1);
407  const std::string value = XML::getProperty(frameNode, "value", "");
408  const int repeat = XML::getIntProperty(
409  frameNode, "repeat", 1, 0, 100);
410 
411  if (repeat < 1)
412  {
413  reportAlways("%s: No valid value for 'repeat' at direction %s",
414  mSource.c_str(),
415  directionName.c_str())
416  continue;
417  }
418 
419  if (value.empty())
420  {
421  if (addSequence(start, end, delay, offsetX, offsetY,
422  variant_offset, repeat, rand, imageSet, animation))
423  {
424  continue;
425  }
426  }
427  else
428  {
429  StringVect vals;
430  splitToStringVector(vals, value, ',');
431  FOR_EACH (StringVectCIter, it, vals)
432  {
433  const std::string str = *it;
434  const size_t idx = str.find('-');
435  if (str == "p")
436  {
437  animation->addPause(delay, rand);
438  }
439  else if (idx != std::string::npos)
440  {
441  const int v1 = atoi(str.substr(0, idx).c_str());
442  const int v2 = atoi(str.substr(idx + 1).c_str());
443  addSequence(v1, v2, delay, offsetX, offsetY,
444  variant_offset, repeat, rand, imageSet, animation);
445  }
446  else
447  {
448  Image *const img = imageSet->get(atoi(
449  str.c_str()) + variant_offset);
450  if (img != nullptr)
451  {
452  animation->addFrame(img, delay,
453  offsetX, offsetY, rand);
454  }
455  }
456  }
457  }
458  }
459  else if (xmlNameEqual(frameNode, "pause"))
460  {
461  animation->addPause(delay, rand);
462  }
463  else if (xmlNameEqual(frameNode, "end"))
464  {
465  animation->addTerminator(rand);
466  }
467  else if (xmlNameEqual(frameNode, "jump"))
468  {
469  animation->addJump(XML::getProperty(
470  frameNode, "action", ""), rand);
471  }
472  else if (xmlNameEqual(frameNode, "label"))
473  {
474  const std::string name = XML::getProperty(frameNode, "name", "");
475  if (!name.empty())
476  animation->addLabel(name);
477  }
478  else if (xmlNameEqual(frameNode, "goto"))
479  {
480  const std::string name = XML::getProperty(frameNode, "label", "");
481  if (!name.empty())
482  animation->addGoto(name, rand);
483  }
484  } // for frameNode
485 }
486 
487 void SpriteDef::includeSprite(XmlNodeConstPtr includeNode, const int variant)
488 {
489  std::string filename = XML::getProperty(includeNode, "file", "");
490 
491  if (filename.empty())
492  return;
493  filename = pathJoin(paths.getStringValue("sprites"), filename);
494 
495  if (mProcessedFiles.find(filename) != mProcessedFiles.end())
496  {
497  reportAlways("%s: Tried to include %s which already is included.",
498  mSource.c_str(),
499  filename.c_str())
500  return;
501  }
502  mProcessedFiles.insert(filename);
503 
504  XML::Document *const doc = Loader::getXml(filename,
507  if (doc == nullptr)
508  return;
509  XmlNodeConstPtr rootNode = doc->rootNode();
510 
511  if ((rootNode == nullptr) || !xmlNameEqual(rootNode, "sprite"))
512  {
513  reportAlways("%s: No sprite root node in %s",
514  mSource.c_str(),
515  filename.c_str())
516  doc->decRef();
517  return;
518  }
519 
520  loadSprite(rootNode, variant, std::string());
521  doc->decRef();
522 }
523 
525 {
526  // Actions are shared, so ensure they are deleted only once.
527  std::set<Action*> actions;
528  FOR_EACH (Actions::iterator, i, mActions)
529  {
530  FOR_EACHP (ActionMap::iterator, it, (*i).second)
531  actions.insert(it->second);
532  delete (*i).second;
533  }
534 
535  FOR_EACH (std::set<Action*>::const_iterator, i, actions)
536  delete *i;
537 
538  mActions.clear();
539 
541  {
542  if (i->second != nullptr)
543  {
544  i->second->decRef();
545  i->second = nullptr;
546  }
547  }
548  mImageSets.clear();
549 }
550 
552  &direction)
553 {
554  if (direction.empty() || direction == "default")
556  else if (direction == "up")
557  return SpriteDirection::UP;
558  else if (direction == "left")
559  return SpriteDirection::LEFT;
560  else if (direction == "right")
561  return SpriteDirection::RIGHT;
562  else if (direction == "down")
563  return SpriteDirection::DOWN;
564  else if (direction == "upleft")
566  else if (direction == "upright")
568  else if (direction == "downleft")
570  else if (direction == "downright")
572  else
574 }
575 
576 void SpriteDef::addAction(const unsigned hp, const std::string &name,
577  Action *const action)
578 {
579  const Actions::const_iterator i = mActions.find(hp);
580  if (i == mActions.end())
581  mActions[hp] = new ActionMap;
582 
583  (*mActions[hp])[name] = action;
584 }
585 
587  const int end,
588  const int delay,
589  const int offsetX,
590  const int offsetY,
591  const int variant_offset,
592  int repeat,
593  const int rand,
594  const ImageSet *const imageSet,
595  Animation *const animation) const
596 {
597  if ((imageSet == nullptr) || (animation == nullptr))
598  return true;
599 
600  if (start < 0 || end < 0)
601  {
602  reportAlways("%s: No valid value for 'start' or 'end'",
603  mSource.c_str())
604  return true;
605  }
606 
607  if (start <= end)
608  {
609  while (repeat > 0)
610  {
611  int pos = start;
612  while (end >= pos)
613  {
614  Image *const img = imageSet->get(pos + variant_offset);
615 
616  if (img == nullptr)
617  {
618  reportAlways("%s: No image at index %d",
619  mSource.c_str(),
620  pos + variant_offset)
621  pos ++;
622  continue;
623  }
624 
625  animation->addFrame(img, delay,
626  offsetX, offsetY, rand);
627  pos ++;
628  }
629  repeat --;
630  }
631  }
632  else
633  {
634  while (repeat > 0)
635  {
636  int pos = start;
637  while (end <= pos)
638  {
639  Image *const img = imageSet->get(pos + variant_offset);
640 
641  if (img == nullptr)
642  {
643  reportAlways("%s: No image at index %d",
644  mSource.c_str(),
645  pos + variant_offset)
646  pos ++;
647  continue;
648  }
649 
650  animation->addFrame(img, delay,
651  offsetX, offsetY, rand);
652  pos --;
653  }
654  repeat --;
655  }
656  }
657  return false;
658 }
659 
661 {
662  int sz = static_cast<int>(sizeof(SpriteDef) +
663  sizeof(ImageSets) +
664  sizeof(Actions) +
665  sizeof(std::set<std::string>)) +
667  FOR_EACH (std::set<std::string>::const_iterator, it, mProcessedFiles)
668  {
669  sz += static_cast<int>((*it).capacity());
670  }
671  return sz;
672 }
673 
674 int SpriteDef::calcMemoryChilds(const int level) const
675 {
676  int sz = 0;
677  FOR_EACH (ImageSets::const_iterator, it, mImageSets)
678  {
679  sz += static_cast<int>((*it).first.capacity());
680  const ImageSet *const imageSet = (*it).second;
681  sz += imageSet->calcMemory(level + 1);
682  }
684  {
685  sz += sizeof(unsigned);
686  const ActionMap *const actionMap = (*it).second;
687  FOR_EACHP (ActionMap::const_iterator, it2, actionMap)
688  {
689  sz += static_cast<int>((*it2).first.capacity());
690  const Action *const action = (*it2).second;
691  sz += action->calcMemory(level + 1);
692  }
693  }
694  return sz;
695 }
static const BeingActionT actions[]
#define reportTrue(val)
Definition: checkutils.h:252
#define reportAlways(...)
Definition: checkutils.h:253
Definition: action.h:41
void setAnimation(const SpriteDirection::Type direction, Animation *const animation)
Definition: action.cpp:74
void setNumber(const unsigned n)
Definition: action.h:58
void addLabel(const std::string &name)
Definition: animation.cpp:67
void addGoto(const std::string &name, const int rand)
Definition: animation.cpp:73
void addJump(const std::string &name, const int rand)
Definition: animation.cpp:61
void addTerminator(const int rand)
Definition: animation.cpp:56
void addFrame(Image *const image, const int delay, const int offsetX, const int offsetY, const int rand)
Definition: animation.cpp:46
void addPause(const int delay, const int rand)
Definition: animation.cpp:79
std::string getStringValue(const std::string &key) const
static void instantiate(std::string &target, const std::string &palettes)
Definition: dye.cpp:97
int getWidth() const
Definition: imageset.h:60
Image * get(const size_type i) const
Definition: imageset.cpp:67
void setOffsetX(const int n)
Definition: imageset.h:79
int getOffsetY() const
Definition: imageset.h:82
int getOffsetX() const
Definition: imageset.h:76
void setOffsetY(const int n)
Definition: imageset.h:85
int getHeight() const
Definition: imageset.h:66
void log(const char *const log_text,...)
Definition: logger.cpp:269
int calcMemory(const int level) const
bool mProtected
Definition: resource.h:88
std::string mIdPath
Definition: resource.h:84
virtual void incRef()
Definition: resource.cpp:38
virtual void decRef()
Definition: resource.cpp:50
std::string mSource
Definition: resource.h:85
int calcMemoryLocal() const
Definition: resource.cpp:76
bool fixDeadAnimation
Definition: settings.h:160
void loadSprite(const xmlNodePtr spriteNode, const int variant, const std::string &palettes)
Definition: spritedef.cpp:205
const Action * getAction(const std::string &action, const unsigned num) const
Definition: spritedef.cpp:52
Actions::const_iterator ActionsCIter
Definition: spritedef.h:160
static SpriteDirection::Type makeSpriteDirection(const std::string &direction)
Definition: spritedef.cpp:551
void includeSprite(const xmlNodePtr includeNode, const int variant)
Definition: spritedef.cpp:487
void loadImageSet(const xmlNodePtr node, const std::string &palettes)
Definition: spritedef.cpp:238
std::map< std::string, ImageSet * > ImageSets
Definition: spritedef.h:153
std::set< std::string > mProcessedFiles
Definition: spritedef.h:164
const ImageSet * getImageSet(const std::string &imageSetName) const
Definition: spritedef.cpp:269
ImageSets::const_iterator ImageSetCIterator
Definition: spritedef.h:155
void fixDeadAction()
Definition: spritedef.cpp:136
void substituteActions()
Definition: spritedef.cpp:172
int calcMemoryLocal() const
Definition: spritedef.cpp:660
std::map< std::string, Action * > ActionMap
Definition: spritedef.h:156
unsigned findNumber(const unsigned num) const
Definition: spritedef.cpp:76
SpriteDef()
Definition: spritedef.h:89
std::map< unsigned, ActionMap * > Actions
Definition: spritedef.h:157
ImageSets mImageSets
Definition: spritedef.h:162
void addAction(const unsigned hp, const std::string &name, Action *const action)
Definition: spritedef.cpp:576
int calcMemoryChilds(const int level) const
Definition: spritedef.cpp:674
void loadAnimation(const xmlNodePtr animationNode, Action *const action, const ImageSet *const imageSet, const int variant_offset) const
Definition: spritedef.cpp:327
static SpriteDef * load(const std::string &file, const int variant, const bool prot)
Definition: spritedef.cpp:90
Actions mActions
Definition: spritedef.h:163
bool addSequence(const int start, const int end, const int delay, const int offsetX, const int offsetY, const int variant_offset, int repeat, const int rand, const ImageSet *const imageSet, Animation *const animation) const
Definition: spritedef.cpp:586
Actions::iterator ActionsIter
Definition: spritedef.h:159
Actions::const_iterator ActionsConstIter
Definition: spritedef.h:158
void loadAction(const xmlNodePtr node, const int variant_offset)
Definition: spritedef.cpp:283
ImageSets::iterator ImageSetIterator
Definition: spritedef.h:154
void substituteAction(const std::string &complete, const std::string &with)
Definition: spritedef.cpp:155
xmlNodePtr rootNode()
Definition: libxml.cpp:169
Configuration paths
static const int mapTileSize
Definition: map.h:27
#define FOR_EACHP(type, iter, array)
Definition: foreach.h:31
#define FOR_EACH(type, iter, array)
Definition: foreach.h:25
#define for_each_xml_child_node(var, parent)
Definition: libxml.h:161
#define restrict
Definition: localconsts.h:165
Logger * logger
Definition: logger.cpp:89
XML::Document * getXml(const std::string &idPath, const UseVirtFs useResman, const SkipError skipError)
Definition: xmlloader.cpp:56
ImageSet * getImageSet(const std::string &imagePath, const int w, const int h)
static const std::string ATTACKWATER("attackwater")
static const std::string STANDWATER("standwater")
static const std::string SPAWNRIDE("spawnride")
static const std::string ATTACKSKY("attacksky")
static const std::string STANDRIDE("standride")
static const std::string RIDE("ride")
static const std::string SIT("sit")
static const std::string SWIM("swim")
static const std::string FLY("fly")
static const std::string CASTSKY("castsky")
static const std::string STAND("stand")
static const std::string DEFAULT("stand")
static const std::string SITRIDE("sitride")
static const std::string SITSKY("sitsky")
static const std::string MOVE("walk")
static const std::string CASTWATER("castwater")
static const std::string SPAWNWATER("spawnwater")
static const std::string DEADRIDE("deadride")
static const std::string DEAD("dead")
static const std::string SITWATER("sitwater")
static const std::string STANDSKY("standsky")
static const std::string DEADSKY("deadsky")
static const std::string CASTRIDE("castride")
static const std::string CAST("cast")
static const std::string INVALID
Definition: spriteaction.h:72
static const std::string DEADWATER("deadwater")
static const std::string ATTACKRIDE("attackride")
static const std::string SITTOP("sittop")
static const std::string SPAWN("spawn")
static const std::string ATTACK("attack")
static const std::string SPAWNSKY("spawnsky")
int getProperty(const xmlNodePtr node, const char *const name, int def)
Definition: libxml.cpp:174
int getIntProperty(const xmlNodePtr node, const char *const name, int def, const int min, const int max)
Definition: libxml.cpp:190
#define BLOCK_END(name)
Definition: perfomance.h:80
#define BLOCK_START(name)
Definition: perfomance.h:79
Settings settings
Definition: settings.cpp:32
const bool SkipError_false
Definition: skiperror.h:30
void splitToStringVector(StringVect &tokens, const std::string &text, const char separator)
std::string pathJoin(std::string str1, const std::string &str2)
StringVect::const_iterator StringVectCIter
Definition: stringvector.h:31
std::vector< std::string > StringVect
Definition: stringvector.h:29
static SpriteReference * Empty
const bool UseVirtFs_true
Definition: usevirtfs.h:30