diff options
-rw-r--r-- | src/Makefile.am | 2 | ||||
-rw-r--r-- | src/being.cpp | 34 | ||||
-rw-r--r-- | src/being.h | 12 | ||||
-rw-r--r-- | src/particlecontainer.cpp | 158 | ||||
-rw-r--r-- | src/particlecontainer.h | 106 |
5 files changed, 281 insertions, 31 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index 3387690a..e9d69b5e 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -279,6 +279,8 @@ tmw_SOURCES = gui/widgets/resizegrip.cpp \ particleemitter.cpp \ particleemitter.h \ particleemitterprop.h \ + particlecontainer.cpp \ + particlecontainer.h \ player.cpp \ player.h \ player_relations.cpp \ diff --git a/src/being.cpp b/src/being.cpp index ef257f43..7c6d91e7 100644 --- a/src/being.cpp +++ b/src/being.cpp @@ -74,7 +74,9 @@ Being::Being(int id, int job, Map *map): mPx(0), mPy(0), mSprites(VECTOREND_SPRITE, NULL), mSpriteIDs(VECTOREND_SPRITE, 0), - mSpriteColors(VECTOREND_SPRITE, "") + mSpriteColors(VECTOREND_SPRITE, ""), + mStatusParticleEffects(&mStunParticleEffects, false), + mChildParticleEffects(&mStatusParticleEffects, false) { setMap(map); @@ -95,13 +97,6 @@ Being::~Being() std::for_each(mSprites.begin(), mSprites.end(), make_dtor(mSprites)); clearPath(); - for ( std::list<Particle *>::iterator i = mChildParticleEffects.begin(); - i != mChildParticleEffects.end(); - i++) - { - (*i)->kill(); - } - setMap(NULL); instances--; @@ -233,12 +228,7 @@ Being::setMap(Map *map) void Being::controlParticle(Particle *particle) { - if (particle) - { - // The effect may not die without the beings permission or we segfault - particle->disableAutoDelete(); - mChildParticleEffects.push_back(particle); - } + mChildParticleEffects.addLocally(particle); } void @@ -413,21 +403,7 @@ Being::logic() } //Update particle effects - for ( std::list<Particle *>::iterator i = mChildParticleEffects.begin(); - i != mChildParticleEffects.end(); - - ) - { - (*i)->setPosition((float)mPx + 16.0f, (float)mPy + 32.0f); - if ((*i)->isExtinct()) - { - (*i)->kill(); - i = mChildParticleEffects.erase(i); - } - else { - i++; - } - } + mChildParticleEffects.setPositions((float)mPx + 16.0f, (float)mPy + 32.0f); } void diff --git a/src/being.h b/src/being.h index 0dbc41db..568d51c7 100644 --- a/src/being.h +++ b/src/being.h @@ -26,13 +26,15 @@ #include <memory> #include <string> #include <SDL_types.h> -#include <vector> +#include <bitset> #include "sprite.h" #include "map.h" #include "animatedsprite.h" +#include "particlecontainer.h" #define FIRST_IGNORE_EMOTE 14 +#define STATUS_EFFECTS 32 class AnimatedSprite; class Equipment; @@ -405,6 +407,8 @@ class Being : public Sprite std::string mName; /**< Name of character */ SpriteIterator mSpriteIterator; + typedef std::bitset<STATUS_EFFECTS> StatusEffects; + /** Engine-related infos about weapon. */ const ItemInfo* mEquippedWeapon; @@ -414,11 +418,15 @@ class Being : public Sprite Uint8 mGender; Uint32 mSpeechTime; Sint32 mPx, mPy; /**< Pixel coordinates */ + Uint16 mStunMode; /**< Stun mode; zero if not stunned */ + StatusEffects mStatusEffects; /**< Bitset of active status effects */ std::vector<AnimatedSprite*> mSprites; std::vector<int> mSpriteIDs; std::vector<std::string> mSpriteColors; - std::list<Particle *> mChildParticleEffects; + ParticleContainer mStunParticleEffects; + ParticleVector mStatusParticleEffects; + ParticleContainer mChildParticleEffects; private: /** diff --git a/src/particlecontainer.cpp b/src/particlecontainer.cpp new file mode 100644 index 00000000..4df45b26 --- /dev/null +++ b/src/particlecontainer.cpp @@ -0,0 +1,158 @@ +/* + * The Mana World + * Copyright 2008 The Mana World Development Team + * + * This file is part of The Mana World. + * + * The Mana World is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * The Mana World is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with The Mana World; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <cassert> + +#include "particlecontainer.h" + + +ParticleContainer::ParticleContainer(ParticleContainer *parent, bool delParent) : + mDelParent(delParent), + mNext(parent) +{}; + +ParticleContainer::~ParticleContainer() +{ + clearLocally(); + if (mNext && mDelParent) + delete mNext; +} + +void +ParticleContainer::addLocally(Particle *particle) +{ + if (particle) + { + // The effect may not die without the beings permission or we segfault + particle->disableAutoDelete(); + mElements.push_back(particle); + } +} + +void +ParticleContainer::removeLocally(Particle *particle) +{ + for (std::list<Particle *>::iterator it = mElements.begin(); + it != mElements.end(); it++) + if (*it == particle) { + (*it)->kill(); + mElements.erase(it); + } +} + +void +ParticleContainer::clear() +{ + clearLocally(); + if (mNext) + mNext->clear(); +} + +void +ParticleContainer::clearLocally() +{ + for (std::list<Particle *>::iterator it = mElements.begin(); + it != mElements.end(); it++) + (*it)->kill(); + + mElements.clear(); +} + +void +ParticleContainer::setPositions(float x, float y) +{ + for (std::list<Particle *>::iterator it = mElements.begin(); + it != mElements.end();) + { + (*it)->setPosition(x, y); + if ((*it)->isExtinct()) + { + (*it)->kill(); + it = mElements.erase(it); + } + else + it++; + } +} + + + + +ParticleVector::ParticleVector(ParticleContainer *next, bool delParent) +{ + ParticleContainer::ParticleContainer(next, delParent); +} + +void +ParticleVector::setLocally(int index, Particle *particle) +{ + assert(index >= 0); + + delLocally(index); + + if (mIndexedElements.size() <= (unsigned) index) + mIndexedElements.resize(index + 1, NULL); + + mIndexedElements[index] = particle; +} + +void +ParticleVector::delLocally(int index) +{ + assert(index >= 0); + + if (mIndexedElements.size() <= (unsigned) index) + return; + + Particle *p = mIndexedElements[index]; + if (p) + { + mIndexedElements[index] = NULL; + p->kill(); + } +} + +void +ParticleVector::clearLocally() +{ + for (unsigned int i = 0; i < mIndexedElements.size(); i++) + delLocally(i); +} + +void +ParticleVector::setPositions(float x, float y) +{ + ParticleContainer::setPositions(x, y); + + for (std::vector<Particle *>::iterator it = mIndexedElements.begin(); + it != mIndexedElements.end(); it++) + if (*it) + { + (*it)->setPosition(x, y); + + if ((*it)->isExtinct()) + { + (*it)->kill(); + *it = NULL; + } + } +} + diff --git a/src/particlecontainer.h b/src/particlecontainer.h new file mode 100644 index 00000000..a6a1b1c8 --- /dev/null +++ b/src/particlecontainer.h @@ -0,0 +1,106 @@ +/* + * The Mana World + * Copyright 2008 The Mana World Development Team + * + * This file is part of The Mana World. + * + * The Mana World is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * The Mana World is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with The Mana World; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _PARTICLE_CONTAINER_H +#define _PARTICLE_CONTAINER_H + +#include <list> +#include <vector> + +#include "particle.h" + + +/** + * Set of particle effects. May be stacked with other ParticleContainers. All + * operations herein affect such stacked containers, unless the operations end + * in `Locally'. + */ +class ParticleContainer +{ +public: + /** + * Constructs a new particle container and assumes responsibility for + * its parent (for all operations defined herein, except when ending in `Locally') + * + * delParent means that the destructor should also free the parent. + */ + ParticleContainer(ParticleContainer *parent = NULL, bool delParent = true); + ~ParticleContainer(); + + /** + * Takes control of and adds a particle + */ + void addLocally(Particle *); + + /** + * `kills' and removes a particle + */ + void removeLocally(Particle *); + + /** + * Kills and removes all particle effects + */ + void clear(); + + /** + * Kills and removes all particle effects (only in this container) + */ + virtual void clearLocally(); + + /** + * Sets the positions of all elements + */ + virtual void setPositions(float x, float y); + +protected: + bool mDelParent; /**< Delete mNext in destructor */ + std::list<Particle *> mElements; /**< Contained particle effects */ + ParticleContainer *mNext; /**< Contained container, if any */ +}; + + +/** + * Particle container with indexing facilities + */ +class ParticleVector : public ParticleContainer +{ +public: + ParticleVector(ParticleContainer *parent = NULL, bool delParent = true); + + /** + * Sets a particle at a specified index. Kills the previous particle + * there, if needed. + */ + virtual void setLocally(int index, Particle *particle); + + /** + * Removes a particle at a specified index + */ + virtual void delLocally(int index); + + virtual void clearLocally(); + virtual void setPositions(float x, float y); + +protected: + std::vector<Particle *> mIndexedElements; +}; + +#endif |