summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrei Karas <akaras@inbox.ru>2013-11-10 14:53:33 +0300
committerAndrei Karas <akaras@inbox.ru>2013-11-10 15:41:25 +0300
commit44e5d8bcb7fea443ca9ed3844454b11ac6e4dbed (patch)
tree1af016870cd47c00e860673d1710b0b98a3bf101
parente5f83f094dd658163150ea2a41c5d4a67f21019c (diff)
downloadplus-44e5d8bcb7fea443ca9ed3844454b11ac6e4dbed.tar.gz
plus-44e5d8bcb7fea443ca9ed3844454b11ac6e4dbed.tar.bz2
plus-44e5d8bcb7fea443ca9ed3844454b11ac6e4dbed.tar.xz
plus-44e5d8bcb7fea443ca9ed3844454b11ac6e4dbed.zip
add support for item particles.
For this used particlefx tag in items.xml
-rw-r--r--src/CMakeLists.txt1
-rw-r--r--src/Makefile.am1
-rw-r--r--src/being/being.cpp85
-rw-r--r--src/being/being.h14
-rw-r--r--src/game.cpp5
-rw-r--r--src/particle/particleinfo.h34
-rw-r--r--src/resources/db/itemdb.cpp5
7 files changed, 145 insertions, 0 deletions
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<Particle*>::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<Particle*>::const_iterator, itp, pi->particles)
+ mChildParticleEffects.removeLocally(*itp);
+
+ FOR_EACH (std::vector<std::string>::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<int, ParticleInfo*> SpriteParticleInfo;
+ typedef SpriteParticleInfo::iterator SpriteParticleInfoIter;
+
StringVect mSpriteColors;
std::vector<int> mSpriteIDs;
std::vector<int> mSpriteColorsIds;
+ SpriteParticleInfo mSpriteParticles;
// Character guild information
std::map<int, Guild*> 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 <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef PARTICLE_PARTICLEINFO_H
+#define PARTICLE_PARTICLEINFO_H
+
+#include "particle/particle.h"
+
+#include <string>
+
+struct ParticleInfo
+{
+ std::vector<std::string> files;
+ std::vector<Particle*> 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<const char*>(
+ itemChild->xmlChildrenNode->content));
+ }
else if (xmlNameEqual(itemChild, "sound"))
{
loadSoundRef(itemInfo, itemChild);