From 44e5d8bcb7fea443ca9ed3844454b11ac6e4dbed Mon Sep 17 00:00:00 2001 From: Andrei Karas Date: Sun, 10 Nov 2013 14:53:33 +0300 Subject: add support for item particles. For this used particlefx tag in items.xml --- src/CMakeLists.txt | 1 + src/Makefile.am | 1 + src/being/being.cpp | 85 +++++++++++++++++++++++++++++++++++++++++++++ src/being/being.h | 14 ++++++++ src/game.cpp | 5 +++ src/particle/particleinfo.h | 34 ++++++++++++++++++ src/resources/db/itemdb.cpp | 5 +++ 7 files changed, 145 insertions(+) create mode 100644 src/particle/particleinfo.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index e516662e8..e2e019117 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -708,6 +708,7 @@ SET(SRCS particle/particleemitter.cpp particle/particleemitter.h particle/particleemitterprop.h + particle/particleinfo.h party.cpp party.h being/playerinfo.cpp diff --git a/src/Makefile.am b/src/Makefile.am index fc1b6a9c9..6a2ad876a 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -843,6 +843,7 @@ manaplus_SOURCES += gui/widgets/avatarlistbox.cpp \ particle/particleemitter.cpp \ particle/particleemitter.h \ particle/particleemitterprop.h \ + particle/particleinfo.h \ party.cpp \ party.h \ being/playerinfo.cpp \ diff --git a/src/being/being.cpp b/src/being/being.cpp index cda6557e4..f28ea591b 100644 --- a/src/being/being.cpp +++ b/src/being/being.cpp @@ -37,6 +37,7 @@ #include "being/playerrelations.h" #include "particle/particle.h" +#include "particle/particleinfo.h" #include "gui/sdlfont.h" @@ -238,6 +239,8 @@ Being::~Being() mOwner->setPet(nullptr); if (mPet) mPet->setOwner(nullptr); + + removeAllItemsParticles(); } void Being::setSubtype(const uint16_t subtype, const uint8_t look) @@ -1934,6 +1937,7 @@ void Being::setSprite(const unsigned int slot, const int id, if (pet) removePet(); } + removeItemParticles(id1); } } else @@ -1964,6 +1968,8 @@ void Being::setSprite(const unsigned int slot, const int id, CompoundSprite::setSprite(slot, equipmentSprite); + addItemParticles(id, info.getDisplay()); + if (isWeapon) mEquippedWeapon = &ItemDB::get(id); @@ -3092,3 +3098,82 @@ void Being::setMap(Map *const map) if (mMap) mOffsetY = mMap->getHeightOffset(mX, mY); } + +void Being::removeAllItemsParticles() +{ + FOR_EACH (SpriteParticleInfoIter, it, mSpriteParticles) + { + delete (*it).second; + } + mSpriteParticles.clear(); +} + +void Being::addItemParticles(const int id, const SpriteDisplay &display) +{ + SpriteParticleInfoIter it = mSpriteParticles.find(id); + ParticleInfo *pi = nullptr; + if (it == mSpriteParticles.end()) + { + pi = new ParticleInfo(); + mSpriteParticles[id] = pi; + } + else + { + pi = (*it).second; + } + + if (!pi->particles.empty()) + return; + + // setup particle effects + if (Particle::enabled && particleEngine) + { + FOR_EACH (StringVectCIter, itr, display.particles) + { + Particle *const p = particleEngine->addEffect(*itr, 0, 0); + controlParticle(p); + pi->files.push_back(*itr); + pi->particles.push_back(p); + } + } + else + { + FOR_EACH (StringVectCIter, itr, display.particles) + pi->files.push_back(*itr); + } +} + +void Being::removeItemParticles(const int id) +{ + SpriteParticleInfoIter it = mSpriteParticles.find(id); + if (it == mSpriteParticles.end()) + return; + ParticleInfo *const pi = (*it).second; + if (pi) + { + FOR_EACH (std::vector::const_iterator, itp, pi->particles) + mChildParticleEffects.removeLocally(*itp); + delete pi; + } + mSpriteParticles.erase(it); +} + +void Being::recreateItemParticles() +{ + FOR_EACH (SpriteParticleInfoIter, it, mSpriteParticles) + { + ParticleInfo *const pi = (*it).second; + if (pi && !pi->files.empty()) + { + FOR_EACH (std::vector::const_iterator, itp, pi->particles) + mChildParticleEffects.removeLocally(*itp); + + FOR_EACH (std::vector::const_iterator, str, pi->files) + { + Particle *const p = particleEngine->addEffect(*str, 0, 0); + controlParticle(p); + pi->particles.push_back(p); + } + } + } +} diff --git a/src/being/being.h b/src/being/being.h index 313a92c2d..a2316d607 100644 --- a/src/being/being.h +++ b/src/being/being.h @@ -53,6 +53,8 @@ class Party; class SpeechBubble; class Text; +struct ParticleInfo; + extern volatile int cur_time; enum Gender @@ -903,6 +905,8 @@ class Being : public ActorSprite, public ConfigListener void setMap(Map *const map); + void recreateItemParticles(); + protected: /** * Updates name's location. @@ -911,6 +915,12 @@ class Being : public ActorSprite, public ConfigListener void showName(); + void addItemParticles(const int id, const SpriteDisplay &display); + + void removeAllItemsParticles(); + + void removeItemParticles(const int id); + static int getDefaultEffectId(const int type); BeingInfo *mInfo; @@ -942,9 +952,13 @@ class Being : public ActorSprite, public ConfigListener Vector mDest; /**< destination coordinates. */ + typedef std::map SpriteParticleInfo; + typedef SpriteParticleInfo::iterator SpriteParticleInfoIter; + StringVect mSpriteColors; std::vector mSpriteIDs; std::vector mSpriteColorsIds; + SpriteParticleInfo mSpriteParticles; // Character guild information std::map mGuilds; diff --git a/src/game.cpp b/src/game.cpp index 80d27a4a1..5766f724f 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -1013,6 +1013,7 @@ void Game::changeMap(const std::string &mapPath) if (newMap) newMap->initializeParticleEffects(particleEngine); + // Start playing new music file when necessary const std::string oldMusic = mCurrentMap ? mCurrentMap->getMusicFile() : ""; @@ -1038,6 +1039,10 @@ void Game::changeMap(const std::string &mapPath) if (mumbleManager) mumbleManager->setMap(mapPath); #endif + + if (player_node) + player_node->recreateItemParticles(); + Net::getGameHandler()->mapLoadedEvent(); BLOCK_END("Game::changeMap") } diff --git a/src/particle/particleinfo.h b/src/particle/particleinfo.h new file mode 100644 index 000000000..70c4fb19f --- /dev/null +++ b/src/particle/particleinfo.h @@ -0,0 +1,34 @@ +/* + * The ManaPlus Client + * Copyright (C) 2013 The ManaPlus Developers + * + * This file is part of The ManaPlus Client. + * + * This program 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. + * + * This program 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 this program. If not, see . + */ + +#ifndef PARTICLE_PARTICLEINFO_H +#define PARTICLE_PARTICLEINFO_H + +#include "particle/particle.h" + +#include + +struct ParticleInfo +{ + std::vector files; + std::vector particles; +}; + +#endif // PARTICLE_PARTICLEINFO_H diff --git a/src/resources/db/itemdb.cpp b/src/resources/db/itemdb.cpp index f7b1f6349..51fcb69d9 100644 --- a/src/resources/db/itemdb.cpp +++ b/src/resources/db/itemdb.cpp @@ -419,6 +419,11 @@ void ItemDB::loadXmlFile(const std::string &fileName, int &tagNum) loadSpriteRef(itemInfo, itemChild); } + else if (xmlNameEqual(itemChild, "particlefx")) + { + display.particles.push_back(reinterpret_cast( + itemChild->xmlChildrenNode->content)); + } else if (xmlNameEqual(itemChild, "sound")) { loadSoundRef(itemInfo, itemChild); -- cgit v1.2.3-70-g09d2