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/action.cpp | 3 +- src/resources/action.h | 7 ++++ src/resources/spritedef.cpp | 78 +++++++++++++++++++++++++++++++++++---------- src/resources/spritedef.h | 12 +++++-- 4 files changed, 80 insertions(+), 20 deletions(-) (limited to 'src/resources') diff --git a/src/resources/action.cpp b/src/resources/action.cpp index c2af3ff9b..f940bffcb 100644 --- a/src/resources/action.cpp +++ b/src/resources/action.cpp @@ -29,7 +29,8 @@ #include "debug.h" -Action::Action() +Action::Action() : + mNumber(100) { } diff --git a/src/resources/action.h b/src/resources/action.h index 05b326d8f..9ab6f98d5 100644 --- a/src/resources/action.h +++ b/src/resources/action.h @@ -43,10 +43,17 @@ class Action Animation *getAnimation(int direction) const; + unsigned getNumber() + { return mNumber; } + + void setNumber(unsigned n) + { mNumber = n; } + protected: typedef std::map Animations; typedef Animations::iterator AnimationIterator; Animations mAnimations; + unsigned mNumber; }; #endif 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; +} diff --git a/src/resources/spritedef.h b/src/resources/spritedef.h index b2939fca1..642962c0b 100644 --- a/src/resources/spritedef.h +++ b/src/resources/spritedef.h @@ -117,7 +117,9 @@ class SpriteDef : public Resource /** * Returns the specified action. */ - Action *getAction(std::string action) const; + Action *getAction(std::string action, unsigned num) const; + + unsigned findNumber(unsigned num) const; /** * Converts a string into a SpriteDirection enum. @@ -125,11 +127,14 @@ class SpriteDef : public Resource static SpriteDirection makeSpriteDirection(const std::string &direction); + void addAction(unsigned hp, std::string name, Action *action); + private: /** * Constructor. */ - SpriteDef() {} + SpriteDef() + { } /** * Destructor. @@ -178,7 +183,8 @@ class SpriteDef : public Resource typedef std::map ImageSets; typedef ImageSets::iterator ImageSetIterator; - typedef std::map Actions; +// typedef std::map*> Actions; + typedef std::map*> Actions; ImageSets mImageSets; Actions mActions; -- cgit v1.2.3-60-g2f50