From 8e5861c3cfd41574351547a1a518efcf9007666a Mon Sep 17 00:00:00 2001 From: Andrei Karas Date: Wed, 23 Nov 2011 04:40:34 +0300 Subject: Add ability to play different animation depend on monster hp. Disabled for legacy servers because monster hp unknown and compilated hp can be wrong (version <= 0). For usage need add to action tag attribute hp="xx" Example: ... Here 50 mean 50% of health or less. Default action tag mean hp=100 --- src/resources/spritedef.cpp | 78 +++++++++++++++++++++++++++++++++++---------- 1 file changed, 62 insertions(+), 16 deletions(-) (limited to 'src/resources/spritedef.cpp') diff --git a/src/resources/spritedef.cpp b/src/resources/spritedef.cpp index 3e2aac785..6b856c5d3 100644 --- a/src/resources/spritedef.cpp +++ b/src/resources/spritedef.cpp @@ -41,17 +41,41 @@ SpriteReference *SpriteReference::Empty = nullptr; -Action *SpriteDef::getAction(std::string action) const +Action *SpriteDef::getAction(std::string action, unsigned num) const { - Actions::const_iterator i = mActions.find(action); + Actions::const_iterator i = mActions.find(num); + if (i == mActions.end() && num != 100) + i = mActions.find(100); if (i == mActions.end()) + return nullptr; + + std::map::const_iterator it + = ((*i).second)->find(action); + + if (it == ((*i).second)->end()) { logger->log("Warning: no action \"%s\" defined!", action.c_str()); return nullptr; } - return i->second; + return (*it).second; +} + +unsigned SpriteDef::findNumber(unsigned num) const +{ + unsigned min = 101; + Actions::const_iterator it = mActions.begin(); + Actions::const_iterator it_end = mActions.end(); + for (; it != it_end; ++ it) + { + unsigned n = (*it).first; + if (n >= num && n < min) + min = n; + } + if (min == 101) + return 0; + return min; } SpriteDef *SpriteDef::load(const std::string &animationFile, int variant) @@ -84,11 +108,17 @@ SpriteDef *SpriteDef::load(const std::string &animationFile, int variant) void SpriteDef::substituteAction(std::string complete, std::string with) { - if (mActions.find(complete) == mActions.end()) + Actions::const_iterator it = mActions.begin(); + Actions::const_iterator it_end = mActions.end(); + for (; it != it_end; ++ it) { - Actions::const_iterator i = mActions.find(with); - if (i != mActions.end()) - mActions[complete] = i->second; + std::map *d = (*it).second; + if (d->find(complete) == d->end()) + { + std::map::iterator i = d->find(with); + if (i != d->end()) + (*d)[complete] = i->second; + } } } @@ -162,6 +192,7 @@ void SpriteDef::loadAction(xmlNodePtr node, int variant_offset) { const std::string actionName = XML::getProperty(node, "name", ""); const std::string imageSetName = XML::getProperty(node, "imageset", ""); + const unsigned hp = XML::getProperty(node, "hp", 100); ImageSetIterator si = mImageSets.find(imageSetName); if (si == mImageSets.end()) @@ -179,15 +210,17 @@ void SpriteDef::loadAction(xmlNodePtr node, int variant_offset) return; } Action *action = new Action; - mActions[actionName] = action; + action->setNumber(hp); + addAction(hp, actionName, action); // dirty hack to fix bad resources in tmw server if (actionName == "attack_stab") - mActions["attack"] = action; + addAction(hp, "attack", action); // When first action set it as default direction - if (mActions.size() == 1) - mActions[SpriteAction::DEFAULT] = action; + Actions::const_iterator i = mActions.find(hp); + if ((*i).second->size() == 1) + addAction(hp, SpriteAction::DEFAULT, action); // Load animations for_each_xml_child_node(animationNode, node) @@ -339,14 +372,18 @@ void SpriteDef::includeSprite(xmlNodePtr includeNode) SpriteDef::~SpriteDef() { // Actions are shared, so ensure they are deleted only once. - std::set< Action * > actions; - for (Actions::const_iterator i = mActions.begin(), + std::set actions; + for (Actions::iterator i = mActions.begin(), i_end = mActions.end(); i != i_end; ++i) { - actions.insert(i->second); + std::map::iterator it = (*i).second->begin(); + std::map::iterator it_end = (*i).second->end(); + for (; it != it_end; ++ it) + actions.insert(it->second); + delete (*i).second; } - for (std::set< Action * >::const_iterator i = actions.begin(), + for (std::set::const_iterator i = actions.begin(), i_end = actions.end(); i != i_end; ++i) { delete *i; @@ -355,7 +392,7 @@ SpriteDef::~SpriteDef() mActions.clear(); for (ImageSetIterator i = mImageSets.begin(); - i != mImageSets.end(); ++i) + i != mImageSets.end(); ++i) { if (i->second) { @@ -388,3 +425,12 @@ SpriteDirection SpriteDef::makeSpriteDirection(const std::string &direction) else return DIRECTION_INVALID; } + +void SpriteDef::addAction(unsigned hp, std::string name, Action *action) +{ + Actions::const_iterator i = mActions.find(hp); + if (i == mActions.end()) + mActions[hp] = new std::map(); + + (*mActions[hp])[name] = action; +} -- cgit v1.2.3-70-g09d2