diff options
Diffstat (limited to 'src/particle')
-rw-r--r-- | src/particle/animationparticle.cpp | 42 | ||||
-rw-r--r-- | src/particle/animationparticle.h | 45 | ||||
-rw-r--r-- | src/particle/imageparticle.cpp | 92 | ||||
-rw-r--r-- | src/particle/imageparticle.h | 61 | ||||
-rw-r--r-- | src/particle/particle.cpp | 590 | ||||
-rw-r--r-- | src/particle/particle.h | 329 | ||||
-rw-r--r-- | src/particle/particlecontainer.cpp | 55 | ||||
-rw-r--r-- | src/particle/particlecontainer.h | 71 | ||||
-rw-r--r-- | src/particle/particleemitter.cpp | 632 | ||||
-rw-r--r-- | src/particle/particleemitter.h | 172 | ||||
-rw-r--r-- | src/particle/particleemitterprop.h | 127 | ||||
-rw-r--r-- | src/particle/particleengine.cpp | 343 | ||||
-rw-r--r-- | src/particle/particleengine.h | 130 | ||||
-rw-r--r-- | src/particle/particleinfo.h | 42 | ||||
-rw-r--r-- | src/particle/particlelist.cpp | 106 | ||||
-rw-r--r-- | src/particle/particlelist.h | 69 | ||||
-rw-r--r-- | src/particle/particletimer.h | 43 | ||||
-rw-r--r-- | src/particle/particlevector.cpp | 109 | ||||
-rw-r--r-- | src/particle/particlevector.h | 71 | ||||
-rw-r--r-- | src/particle/rotationalparticle.cpp | 43 | ||||
-rw-r--r-- | src/particle/rotationalparticle.h | 44 | ||||
-rw-r--r-- | src/particle/textparticle.cpp | 96 | ||||
-rw-r--r-- | src/particle/textparticle.h | 69 |
23 files changed, 0 insertions, 3381 deletions
diff --git a/src/particle/animationparticle.cpp b/src/particle/animationparticle.cpp deleted file mode 100644 index baeb0701e..000000000 --- a/src/particle/animationparticle.cpp +++ /dev/null @@ -1,42 +0,0 @@ -/* - * The ManaPlus Client - * Copyright (C) 2006-2009 The Mana World Development Team - * Copyright (C) 2009-2010 The Mana Developers - * Copyright (C) 2011-2017 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/>. - */ - -#include "particle/animationparticle.h" - -#include "resources/animation/simpleanimation.h" - -#include "debug.h" - -AnimationParticle::AnimationParticle(Animation *restrict const animation) : - ImageParticle(nullptr) -{ - mType = ParticleType::Animation; - mAnimation = new SimpleAnimation(animation); -} - -AnimationParticle::AnimationParticle(XmlNodePtrConst animationNode, - const std::string &restrict dyePalettes) : - ImageParticle(nullptr) -{ - mType = ParticleType::Animation; - mAnimation = new SimpleAnimation(animationNode, dyePalettes); -} diff --git a/src/particle/animationparticle.h b/src/particle/animationparticle.h deleted file mode 100644 index 9c5e6af5d..000000000 --- a/src/particle/animationparticle.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * The ManaPlus Client - * Copyright (C) 2006-2009 The Mana World Development Team - * Copyright (C) 2009-2010 The Mana Developers - * Copyright (C) 2011-2017 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_ANIMATIONPARTICLE_H -#define PARTICLE_ANIMATIONPARTICLE_H - -#include "particle/imageparticle.h" - -#include "utils/xml.h" - -class Animation; - -class AnimationParticle final : public ImageParticle -{ - public: - explicit AnimationParticle(Animation *restrict const animation) - A_NONNULL(2); - - explicit AnimationParticle(XmlNodePtrConst animationNode, - const std::string &restrict dyePalettes - = std::string()); - - A_DELETE_COPY(AnimationParticle) -}; - -#endif // PARTICLE_ANIMATIONPARTICLE_H diff --git a/src/particle/imageparticle.cpp b/src/particle/imageparticle.cpp deleted file mode 100644 index 859fc6a15..000000000 --- a/src/particle/imageparticle.cpp +++ /dev/null @@ -1,92 +0,0 @@ -/* - * The ManaPlus Client - * Copyright (C) 2006-2009 The Mana World Development Team - * Copyright (C) 2009-2010 The Mana Developers - * Copyright (C) 2011-2017 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/>. - */ - -#include "particle/imageparticle.h" - -#include "render/graphics.h" - -#include "resources/image/image.h" - -#include "debug.h" - -StringIntMap ImageParticle::imageParticleCountByName; - -ImageParticle::ImageParticle(Image *restrict const image) : - Particle() -{ - mType = ParticleType::Image; - mImage = image; - if (mImage != nullptr) - { - mImage->incRef(); - - const std::string &restrict name = mImage->mIdPath; - StringIntMapIter it - = ImageParticle::imageParticleCountByName.find(name); - if (it == ImageParticle::imageParticleCountByName.end()) - ImageParticle::imageParticleCountByName[name] = 1; - else - (*it).second ++; - } -} - -void ImageParticle::draw(Graphics *restrict const graphics, - const int offsetX, - const int offsetY) const restrict2 -{ - FUNC_BLOCK("ImageParticle::draw", 1) - if (mAlive != AliveStatus::ALIVE || (mImage == nullptr)) - return; - - const int w = mImage->mBounds.w; - const int h = mImage->mBounds.h; - const int screenX = CAST_S32(mPos.x) - + offsetX - w / 2; - const int screenY = CAST_S32(mPos.y) - CAST_S32(mPos.z) - + offsetY - h / 2; - - // Check if on screen - if (screenX + w < 0 || - screenX > graphics->mWidth || - screenY + h < 0 || - screenY > graphics->mHeight) - { - return; - } - - float alphafactor = mAlpha; - - if ((mFadeOut != 0) && mLifetimeLeft > -1 && mLifetimeLeft < mFadeOut) - { - alphafactor *= static_cast<float>(mLifetimeLeft) - / static_cast<float>(mFadeOut); - } - - if ((mFadeIn != 0) && mLifetimePast < mFadeIn) - { - alphafactor *= static_cast<float>(mLifetimePast) - / static_cast<float>(mFadeIn); - } - - mImage->setAlpha(alphafactor); - graphics->drawImage(mImage, screenX, screenY); -} diff --git a/src/particle/imageparticle.h b/src/particle/imageparticle.h deleted file mode 100644 index 9e2f03904..000000000 --- a/src/particle/imageparticle.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * The ManaPlus Client - * Copyright (C) 2006-2009 The Mana World Development Team - * Copyright (C) 2009-2010 The Mana Developers - * Copyright (C) 2011-2017 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_IMAGEPARTICLE_H -#define PARTICLE_IMAGEPARTICLE_H - -#include "particle/particle.h" - -#include "utils/stringmap.h" - -class Image; - -/** - * A particle that uses an image for its visualization. - */ -class ImageParticle notfinal : public Particle -{ - public: - /** - * Constructor. The image is reference counted by this particle. - * - * @param image an Image instance, may not be NULL - */ - explicit ImageParticle(Image *restrict const image); - - A_DELETE_COPY(ImageParticle) - - /** - * Draws the particle image - */ - void draw(Graphics *restrict const graphics, - const int offsetX, - const int offsetY) const - restrict2 override final A_NONNULL(2); - - void setAlpha(const float alpha) restrict2 override final - { mAlpha = alpha; } - - static StringIntMap imageParticleCountByName; -}; - -#endif // PARTICLE_IMAGEPARTICLE_H diff --git a/src/particle/particle.cpp b/src/particle/particle.cpp deleted file mode 100644 index 40b1b7a5a..000000000 --- a/src/particle/particle.cpp +++ /dev/null @@ -1,590 +0,0 @@ -/* - * The ManaPlus Client - * Copyright (C) 2006-2009 The Mana World Development Team - * Copyright (C) 2009-2010 The Mana Developers - * Copyright (C) 2011-2017 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/>. - */ - -#include "particle/particle.h" - -#include "actormanager.h" -#include "logger.h" - -#include "being/actorsprite.h" - -#include "particle/animationparticle.h" -#include "particle/particleemitter.h" -#include "particle/rotationalparticle.h" - -#include "resources/animation/simpleanimation.h" - -#include "resources/dye/dye.h" - -#include "resources/image/image.h" - -#include "resources/loaders/imageloader.h" -#include "resources/loaders/xmlloader.h" - -#include "utils/delete2.h" -#include "utils/dtor.h" -#include "utils/foreach.h" -#include "utils/likely.h" -#include "utils/mathutils.h" -#include "utils/mrand.h" - -#include "debug.h" - -static const float SIN45 = 0.707106781F; -static const double PI = M_PI; -static const float PI2 = 2 * M_PI; - -class Graphics; - -Particle::Particle() : - Actor(), - mAlpha(1.0F), - mLifetimeLeft(-1), - mLifetimePast(0), - mFadeOut(0), - mFadeIn(0), - mVelocity(), - mAlive(AliveStatus::ALIVE), - mType(ParticleType::Normal), - mAnimation(nullptr), - mImage(nullptr), - mActor(BeingId_zero), - mChildEmitters(), - mChildParticles(), - mChildMoveParticles(), - mDeathEffect(), - mGravity(0.0F), - mBounce(0.0F), - mAcceleration(0.0F), - mInvDieDistance(-1.0F), - mMomentum(1.0F), - mTarget(nullptr), - mRandomness(0), - mDeathEffectConditions(0x00), - mAutoDelete(true), - mAllowSizeAdjust(false), - mFollow(false) -{ - ParticleEngine::particleCount++; -} - -Particle::~Particle() -{ - if (mActor != BeingId_zero && - (actorManager != nullptr)) - { - ActorSprite *const actor = actorManager->findActor(mActor); - if (actor != nullptr) - actor->controlParticleDeleted(this); - } - // Delete child emitters and child particles - clear(); - delete2(mAnimation); - if (mImage != nullptr) - { - if (mType == ParticleType::Image) - { - const std::string &restrict name = mImage->mIdPath; - StringIntMapIter it - = ImageParticle::imageParticleCountByName.find(name); - if (it != ImageParticle::imageParticleCountByName.end()) - { - int &cnt = (*it).second; - if (cnt > 0) - cnt --; - } - mImage->decRef(); - } - mImage = nullptr; - } - - ParticleEngine::particleCount--; -} - -void Particle::draw(Graphics *restrict const graphics A_UNUSED, - const int offsetX A_UNUSED, - const int offsetY A_UNUSED) const restrict2 -{ -} - -void Particle::updateSelf() restrict2 -{ - // calculate particle movement - if (A_LIKELY(mMomentum != 1.0F)) - mVelocity *= mMomentum; - - if ((mTarget != nullptr) && mAcceleration != 0.0F) - { - Vector dist = mPos - mTarget->mPos; - dist.x *= SIN45; - float invHypotenuse; - - switch (ParticleEngine::fastPhysics) - { - case ParticlePhysics::Normal: - invHypotenuse = fastInvSqrt( - dist.x * dist.x + dist.y * dist.y + dist.z * dist.z); - break; - case ParticlePhysics::Fast: - if (dist.x == 0.0f) - { - invHypotenuse = 0; - break; - } - - invHypotenuse = 2.0F / (static_cast<float>(fabs(dist.x)) - + static_cast<float>(fabs(dist.y)) - + static_cast<float>(fabs(dist.z))); - break; - case ParticlePhysics::Best: - default: - invHypotenuse = 1.0F / static_cast<float>(sqrt( - dist.x * dist.x + dist.y * dist.y + dist.z * dist.z)); - break; - } - - if (invHypotenuse != 0.0f) - { - if (mInvDieDistance > 0.0F && invHypotenuse > mInvDieDistance) - mAlive = AliveStatus::DEAD_IMPACT; - const float accFactor = invHypotenuse * mAcceleration; - mVelocity -= dist * accFactor; - } - } - - if (A_LIKELY(mRandomness >= 10)) // reduce useless calculations - { - const int rand2 = mRandomness * 2; - mVelocity.x += static_cast<float>(mrand() % rand2 - mRandomness) - / 1000.0F; - mVelocity.y += static_cast<float>(mrand() % rand2 - mRandomness) - / 1000.0F; - mVelocity.z += static_cast<float>(mrand() % rand2 - mRandomness) - / 1000.0F; - } - - mVelocity.z -= mGravity; - - // Update position - mPos.x += mVelocity.x; - mPos.y += mVelocity.y * SIN45; - mPos.z += mVelocity.z * SIN45; - - // Update other stuff - if (A_LIKELY(mLifetimeLeft > 0)) - mLifetimeLeft--; - - mLifetimePast++; - - if (mPos.z < 0.0F) - { - if (mBounce > 0.0F) - { - mPos.z *= -mBounce; - mVelocity *= mBounce; - mVelocity.z = -mVelocity.z; - } - else - { - mAlive = AliveStatus::DEAD_FLOOR; - } - } - else if (mPos.z > ParticleEngine::PARTICLE_SKY) - { - mAlive = AliveStatus::DEAD_SKY; - } - - // Update child emitters - if ((ParticleEngine::emitterSkip != 0) && - (mLifetimePast - 1) % ParticleEngine::emitterSkip == 0) - { - FOR_EACH (EmitterConstIterator, e, mChildEmitters) - { - STD_VECTOR<Particle*> newParticles; - (*e)->createParticles(mLifetimePast, newParticles); - FOR_EACH (STD_VECTOR<Particle*>::const_iterator, - it, - newParticles) - { - Particle *const p = *it; - p->moveBy(mPos); - mChildParticles.push_back(p); - if (p->mFollow) - mChildMoveParticles.push_back(p); - } - } - } - - // create death effect when the particle died - if (A_UNLIKELY(mAlive != AliveStatus::ALIVE && - mAlive != AliveStatus::DEAD_LONG_AGO)) - { - if ((CAST_U32(mAlive) & mDeathEffectConditions) - > 0x00 && !mDeathEffect.empty()) - { - Particle *restrict const deathEffect = particleEngine->addEffect( - mDeathEffect, 0, 0); - if (deathEffect != nullptr) - deathEffect->moveBy(mPos); - } - mAlive = AliveStatus::DEAD_LONG_AGO; - } -} - -bool Particle::update() restrict2 -{ - if (A_LIKELY(mAlive == AliveStatus::ALIVE)) - { - if (A_UNLIKELY(mLifetimeLeft == 0)) - { - mAlive = AliveStatus::DEAD_TIMEOUT; - if (mChildParticles.empty()) - { - if (mAutoDelete) - return false; - return true; - } - } - else - { - if (mAnimation != nullptr) - { - if (mType == ParticleType::Animation) - { - // particle engine is updated every 10ms - mAnimation->update(10); - } - else // ParticleType::Rotational - { - // TODO: cache velocities to avoid spamming atan2() - const int size = mAnimation->getLength(); - if (size == 0) - return false; - - float rad = static_cast<float>(atan2(mVelocity.x, - mVelocity.y)); - if (rad < 0) - rad = PI2 + rad; - - const float range = static_cast<float>(PI / size); - - // Determines which frame the particle should play - if (A_UNLIKELY(rad < range || rad > PI2 - range)) - { - mAnimation->setFrame(0); - } - else - { - const float range2 = 2 * range; - // +++ need move condition outside of for - for (int c = 1; c < size; c++) - { - const float cRange = static_cast<float>(c) * - range2; - if (cRange - range < rad && - rad < cRange + range) - { - mAnimation->setFrame(c); - break; - } - } - } - } - mImage = mAnimation->getCurrentImage(); - } - const Vector oldPos = mPos; - - updateSelf(); - - const Vector change = mPos - oldPos; - if (mChildParticles.empty()) - { - if (mAlive != AliveStatus::ALIVE && - mAutoDelete) - { - return false; - } - return true; - } - for (ParticleIterator p = mChildMoveParticles.begin(), - fp2 = mChildMoveParticles.end(); p != fp2; ) - { - // move particle with its parent if desired - (*p)->moveBy(change); - ++p; - } - } - - // Update child particles - for (ParticleIterator p = mChildParticles.begin(), - fp2 = mChildParticles.end(); p != fp2; ) - { - Particle *restrict const particle = *p; - // update particle - if (A_LIKELY(particle->update())) - { - ++p; - } - else - { - mChildMoveParticles.remove(*p); - delete particle; - p = mChildParticles.erase(p); - } - } - if (A_UNLIKELY(mAlive != AliveStatus::ALIVE && - mChildParticles.empty() && - mAutoDelete)) - { - return false; - } - } - else - { - if (mChildParticles.empty()) - { - if (mAutoDelete) - return false; - return true; - } - // Update child particles - for (ParticleIterator p = mChildParticles.begin(), - fp2 = mChildParticles.end(); p != fp2; ) - { - Particle *restrict const particle = *p; - // update particle - if (A_LIKELY(particle->update())) - { - ++p; - } - else - { - mChildMoveParticles.remove(*p); - delete particle; - p = mChildParticles.erase(p); - } - } - if (A_UNLIKELY(mChildParticles.empty() && - mAutoDelete)) - { - return false; - } - } - - return true; -} - -void Particle::moveBy(const Vector &restrict change) restrict2 -{ - mPos += change; - FOR_EACH (ParticleConstIterator, p, mChildMoveParticles) - { - (*p)->moveBy(change); - } -} - -void Particle::moveTo(const float x, const float y) restrict2 -{ - moveTo(Vector(x, y, mPos.z)); -} - -Particle *Particle::addEffect(const std::string &restrict particleEffectFile, - const int pixelX, const int pixelY, - const int rotation) restrict2 -{ - Particle *newParticle = nullptr; - - const size_t pos = particleEffectFile.find('|'); - const std::string dyePalettes = (pos != std::string::npos) - ? particleEffectFile.substr(pos + 1) : ""; - XML::Document *doc = Loader::getXml(particleEffectFile.substr(0, pos), - UseVirtFs_true, - SkipError_false); - if (doc == nullptr) - return nullptr; - XmlNodeConstPtrConst rootNode = doc->rootNode(); - - if ((rootNode == nullptr) || !xmlNameEqual(rootNode, "effect")) - { - logger->log("Error loading particle: %s", particleEffectFile.c_str()); - doc->decRef(); - return nullptr; - } - - // Parse particles - for_each_xml_child_node(effectChildNode, rootNode) - { - // We're only interested in particles - if (!xmlNameEqual(effectChildNode, "particle")) - continue; - - // Determine the exact particle type - XmlNodePtr node; - - // Animation - if ((node = XML::findFirstChildByName(effectChildNode, "animation")) != - nullptr) - { - newParticle = new AnimationParticle(node, dyePalettes); - newParticle->setMap(mMap); - } - // Rotational - else if ((node = XML::findFirstChildByName( - effectChildNode, "rotation")) != nullptr) - { - newParticle = new RotationalParticle(node, dyePalettes); - newParticle->setMap(mMap); - } - // Image - else if ((node = XML::findFirstChildByName(effectChildNode, - "image")) != nullptr) - { - std::string imageSrc; - if (XmlHaveChildContent(node)) - imageSrc = XmlChildContent(node); - if (!imageSrc.empty() && !dyePalettes.empty()) - Dye::instantiate(imageSrc, dyePalettes); - Image *const img = Loader::getImage(imageSrc); - - newParticle = new ImageParticle(img); - newParticle->setMap(mMap); - } - // Other - else - { - newParticle = new Particle; - newParticle->setMap(mMap); - } - - // Read and set the basic properties of the particle - const float offsetX = XML::getFloatProperty( - effectChildNode, "position-x", 0); - const float offsetY = XML::getFloatProperty( - effectChildNode, "position-y", 0); - const float offsetZ = XML::getFloatProperty( - effectChildNode, "position-z", 0); - const Vector position(mPos.x + static_cast<float>(pixelX) + offsetX, - mPos.y + static_cast<float>(pixelY) + offsetY, - mPos.z + offsetZ); - newParticle->moveTo(position); - - const int lifetime = XML::getProperty(effectChildNode, "lifetime", -1); - newParticle->setLifetime(lifetime); - const bool resizeable = "false" != XML::getProperty(effectChildNode, - "size-adjustable", "false"); - - newParticle->setAllowSizeAdjust(resizeable); - - // Look for additional emitters for this particle - for_each_xml_child_node(emitterNode, effectChildNode) - { - if (xmlNameEqual(emitterNode, "emitter")) - { - ParticleEmitter *restrict const newEmitter = - new ParticleEmitter( - emitterNode, - newParticle, - mMap, - rotation, - dyePalettes); - newParticle->addEmitter(newEmitter); - } - else if (xmlNameEqual(emitterNode, "deatheffect")) - { - std::string deathEffect; - if ((node != nullptr) && XmlHaveChildContent(node)) - deathEffect = XmlChildContent(emitterNode); - - char deathEffectConditions = 0x00; - if (XML::getBoolProperty(emitterNode, "on-floor", true)) - { - deathEffectConditions += CAST_S8( - AliveStatus::DEAD_FLOOR); - } - if (XML::getBoolProperty(emitterNode, "on-sky", true)) - { - deathEffectConditions += CAST_S8( - AliveStatus::DEAD_SKY); - } - if (XML::getBoolProperty(emitterNode, "on-other", false)) - { - deathEffectConditions += CAST_S8( - AliveStatus::DEAD_OTHER); - } - if (XML::getBoolProperty(emitterNode, "on-impact", true)) - { - deathEffectConditions += CAST_S8( - AliveStatus::DEAD_IMPACT); - } - if (XML::getBoolProperty(emitterNode, "on-timeout", true)) - { - deathEffectConditions += CAST_S8( - AliveStatus::DEAD_TIMEOUT); - } - newParticle->setDeathEffect( - deathEffect, deathEffectConditions); - } - } - - mChildParticles.push_back(newParticle); - } - - doc->decRef(); - return newParticle; -} - -void Particle::adjustEmitterSize(const int w, const int h) restrict2 -{ - if (mAllowSizeAdjust) - { - FOR_EACH (EmitterConstIterator, e, mChildEmitters) - (*e)->adjustSize(w, h); - } -} - -void Particle::prepareToDie() restrict2 -{ - FOR_EACH (ParticleIterator, p, mChildParticles) - { - Particle *restrict const particle = *p; - if (particle == nullptr) - continue; - particle->prepareToDie(); - if (particle->isAlive() && - particle->mLifetimeLeft == -1 && - particle->mAutoDelete) - { - particle->kill(); - } - } -} - -void Particle::clear() restrict2 -{ - delete_all(mChildEmitters); - mChildEmitters.clear(); - - delete_all(mChildParticles); - mChildParticles.clear(); - - mChildMoveParticles.clear(); -} diff --git a/src/particle/particle.h b/src/particle/particle.h deleted file mode 100644 index 7004af0e6..000000000 --- a/src/particle/particle.h +++ /dev/null @@ -1,329 +0,0 @@ -/* - * The ManaPlus Client - * Copyright (C) 2006-2009 The Mana World Development Team - * Copyright (C) 2009-2010 The Mana Developers - * Copyright (C) 2011-2017 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_PARTICLE_H -#define PARTICLE_PARTICLE_H - -#include "being/actor.h" - -#include "enums/particle/alivestatus.h" -#include "enums/particle/particletype.h" - -#include "enums/simpletypes/beingid.h" - -#include "particle/particleengine.h" - -#include "localconsts.h" - -class Image; -class ParticleEmitter; -class SimpleAnimation; - -/** - * A particle spawned by a ParticleEmitter. - */ -class Particle notfinal : public Actor -{ - public: - friend class ParticleEngine; - - Particle(); - - A_DELETE_COPY(Particle) - - /** - * Destructor. - */ - virtual ~Particle(); - - /** - * Deletes all child particles and emitters. - */ - void clear() restrict2; - - /** - * Updates particle position, returns false when the particle should - * be deleted. - */ - bool update() restrict2; - - /** - * Draws the particle image. - */ - void draw(Graphics *restrict const graphics, - const int offsetX, - const int offsetY) const restrict2 override - A_CONST A_NONNULL(2); - - /** - * Necessary for sorting with the other sprites. - */ - int getPixelY() const restrict2 override A_WARN_UNUSED - { return CAST_S32(mPos.y) - 16; } - - /** - * Necessary for sorting with the other sprites for sorting only. - */ - int getSortPixelY() const restrict2 override A_WARN_UNUSED - { return CAST_S32(mPos.y) - 16; } - - /** - * Creates a child particle that hosts some emitters described in the - * particleEffectFile. - */ - Particle *addEffect(const std::string &restrict particleEffectFile, - const int pixelX, const int pixelY, - const int rotation = 0) restrict2; - - /** - * Adds an emitter to the particle. - */ - void addEmitter(ParticleEmitter *const emitter) restrict2 A_NONNULL(2) - { mChildEmitters.push_back(emitter); } - - /** - * Sets the position in 3 dimensional space in pixels relative to map. - */ - void moveTo(const Vector &restrict pos) restrict2 - { moveBy(pos - mPos); } - - /** - * Sets the position in 2 dimensional space in pixels relative to map. - */ - void moveTo(const float x, const float y) restrict2; - - /** - * Changes the particle position relative - */ - void moveBy(const Vector &restrict change) restrict2; - - /** - * Sets the time in game ticks until the particle is destroyed. - */ - void setLifetime(const int lifetime) restrict2 noexcept2 - { mLifetimeLeft = lifetime; mLifetimePast = 0; } - - /** - * Sets the age of the pixel in game ticks where the particle has - * faded in completely. - */ - void setFadeOut(const int fadeOut) restrict2 noexcept2 - { mFadeOut = fadeOut; } - - /** - * Sets the remaining particle lifetime where the particle starts to - * fade out. - */ - void setFadeIn(const int fadeIn) restrict2 noexcept2 - { mFadeIn = fadeIn; } - - /** - * Sets the current velocity in 3 dimensional space. - */ - void setVelocity(const float x, - const float y, - const float z) restrict2 noexcept2 - { mVelocity.x = x; mVelocity.y = y; mVelocity.z = z; } - - /** - * Sets the downward acceleration. - */ - void setGravity(const float gravity) restrict2 noexcept2 - { mGravity = gravity; } - - /** - * Sets the ammount of random vector changes - */ - void setRandomness(const int r) restrict2 noexcept2 - { mRandomness = r; } - - /** - * Sets the ammount of velocity particles retain after - * hitting the ground. - */ - void setBounce(const float bouncieness) restrict2 noexcept2 - { mBounce = bouncieness; } - - /** - * Sets the flag if the particle is supposed to be moved by its parent - */ - void setFollow(const bool follow) restrict2 noexcept2 - { mFollow = follow; } - - /** - * Gets the flag if the particle is supposed to be moved by its parent - */ - bool doesFollow() const restrict2 noexcept2 A_WARN_UNUSED - { return mFollow; } - - /** - * Makes the particle move toward another particle with a - * given acceleration and momentum - */ - void setDestination(Particle *restrict const target, - const float accel, - const float moment) restrict2 noexcept2 - A_NONNULL(2) - { mTarget = target; mAcceleration = accel; mMomentum = moment; } - - /** - * Sets the distance in pixel the particle can come near the target - * particle before it is destroyed. Does only make sense after a target - * particle has been set using setDestination. - */ - void setDieDistance(const float dist) restrict2 - { mInvDieDistance = 1.0F / dist; } - - /** - * Changes the size of the emitters so that the effect fills a - * rectangle of this size - */ - void adjustEmitterSize(const int w, const int h) restrict2; - - void setAllowSizeAdjust(const bool adjust) restrict2 noexcept2 - { mAllowSizeAdjust = adjust; } - - bool isAlive() const restrict2 noexcept2 A_WARN_UNUSED - { return mAlive == AliveStatus::ALIVE; } - - void prepareToDie() restrict2; - - /** - * Determines whether the particle and its children are all dead - */ - bool isExtinct() const restrict2 noexcept2 A_WARN_UNUSED - { return !isAlive() && mChildParticles.empty(); } - - /** - * Manually marks the particle for deletion. - */ - void kill() restrict2 noexcept2 - { mAlive = AliveStatus::DEAD_OTHER; mAutoDelete = true; } - - /** - * After calling this function the particle will only request - * deletion when kill() is called - */ - void disableAutoDelete() restrict2 noexcept2 - { mAutoDelete = false; } - - /** We consider particles (at least for now) to be one layer-sprites */ - int getNumberOfLayers() const restrict2 override final - { return 1; } - - float getAlpha() const restrict2 override final - { return 1.0F; } - - void setAlpha(const float alpha A_UNUSED) restrict2 override - { } - - virtual void setDeathEffect(const std::string &restrict effectFile, - const signed char conditions) restrict2 - { mDeathEffect = effectFile; mDeathEffectConditions = conditions; } - - void setActor(const BeingId actor) - { mActor = actor; } - - protected: - void updateSelf() restrict2; - - // Opacity of the graphical representation of the particle - float mAlpha; - - // Lifetime left in game ticks - int mLifetimeLeft; - - // Age of the particle in game ticks - int mLifetimePast; - - // Lifetime in game ticks left where fading out begins - int mFadeOut; - - // Age in game ticks where fading in is finished - int mFadeIn; - - // Speed in pixels per game-tick. - Vector mVelocity; - - // Is the particle supposed to be drawn and updated? - AliveStatusT mAlive; - - ParticleTypeT mType; - - /**< Used animation for this particle */ - SimpleAnimation *restrict mAnimation; - - /**< The image used for this particle. */ - Image *restrict mImage; - - BeingId mActor; - - private: - // List of child emitters. - Emitters mChildEmitters; - - // List of particles controlled by this particle - Particles mChildParticles; - - Particles mChildMoveParticles; - - // Particle effect file to be spawned when the particle dies - std::string mDeathEffect; - - // dynamic particle - // Downward acceleration in pixels per game-tick. - float mGravity; - - // How much the particle bounces off when hitting the ground - float mBounce; - - // Acceleration towards the target particle in pixels per game-tick - float mAcceleration; - - // Distance in pixels from the target particle that causes - // the destruction of the particle - float mInvDieDistance; - - // How much speed the particle retains after each game tick - float mMomentum; - - // The particle that attracts this particle - Particle *restrict mTarget; - - // Ammount of random vector change - int mRandomness; - - // Bitfield of death conditions which trigger spawning - // of the death particle - signed char mDeathEffectConditions; - - // May the particle request its deletion by the parent particle? - bool mAutoDelete; - - // Can the effect size be adjusted by the object props in the map file? - bool mAllowSizeAdjust; - - // is this particle moved when its parent particle moves? - bool mFollow; -}; - -#endif // PARTICLE_PARTICLE_H diff --git a/src/particle/particlecontainer.cpp b/src/particle/particlecontainer.cpp deleted file mode 100644 index b69cd091d..000000000 --- a/src/particle/particlecontainer.cpp +++ /dev/null @@ -1,55 +0,0 @@ -/* - * The ManaPlus Client - * Copyright (C) 2008-2009 The Mana World Development Team - * Copyright (C) 2009-2010 The Mana Developers - * Copyright (C) 2011-2017 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/>. - */ - -#include "particle/particlecontainer.h" - -#include "utils/delete2.h" - -#include "debug.h" - -ParticleContainer::ParticleContainer(ParticleContainer *const parent, - const bool delParent) : - mNext(parent), - mDelParent(delParent) -{ -} - -ParticleContainer::~ParticleContainer() -{ - // +++ call virtul method in destructor - clearLocally(); - if (mDelParent) - delete2(mNext) -} - -void ParticleContainer::clear() -{ - clearLocally(); - if (mNext != nullptr) - mNext->clear(); -} - -void ParticleContainer::moveTo(const float x, const float y) -{ - if (mNext != nullptr) - mNext->moveTo(x, y); -} diff --git a/src/particle/particlecontainer.h b/src/particle/particlecontainer.h deleted file mode 100644 index 7b8f9f83f..000000000 --- a/src/particle/particlecontainer.h +++ /dev/null @@ -1,71 +0,0 @@ -/* - * The ManaPlus Client - * Copyright (C) 2008-2009 The Mana World Development Team - * Copyright (C) 2009-2010 The Mana Developers - * Copyright (C) 2011-2017 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_PARTICLECONTAINER_H -#define PARTICLE_PARTICLECONTAINER_H - -#include "localconsts.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 notfinal -{ - 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. - */ - explicit ParticleContainer(ParticleContainer *const parent = nullptr, - const bool delParent = true); - - A_DELETE_COPY(ParticleContainer) - - virtual ~ParticleContainer(); - - /** - * 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 moveTo(const float x, const float y); - - protected: - ParticleContainer *mNext; /**< Contained container, if any */ - bool mDelParent; /**< Delete mNext in destructor */ -}; - -#endif // PARTICLE_PARTICLECONTAINER_H diff --git a/src/particle/particleemitter.cpp b/src/particle/particleemitter.cpp deleted file mode 100644 index 642acd851..000000000 --- a/src/particle/particleemitter.cpp +++ /dev/null @@ -1,632 +0,0 @@ -/* - * The ManaPlus Client - * Copyright (C) 2006-2009 The Mana World Development Team - * Copyright (C) 2009-2010 The Mana Developers - * Copyright (C) 2011-2017 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/>. - */ - -#include "particle/particleemitter.h" - -#include "logger.h" - -#include "const/resources/map/map.h" - -#include "particle/animationparticle.h" -#include "particle/rotationalparticle.h" - -#include "utils/foreach.h" - -#include "resources/imageset.h" - -#include "resources/dye/dye.h" - -#include "resources/image/image.h" - -#include "resources/loaders/imageloader.h" -#include "resources/loaders/imagesetloader.h" -#include "resources/loaders/subimageloader.h" -#include "resources/loaders/subimagesetloader.h" - -#include "debug.h" - -static const float SIN45 = 0.707106781F; -static const float DEG_RAD_FACTOR = 0.017453293F; - -typedef STD_VECTOR<ImageSet*>::const_iterator ImageSetVectorCIter; -typedef std::list<ParticleEmitter>::const_iterator ParticleEmitterListCIter; - -ParticleEmitter::ParticleEmitter(XmlNodeConstPtrConst emitterNode, - Particle *const target, - Map *const map, const int rotation, - const std::string& dyePalettes) : - mParticleTarget(target), - mMap(map), - mOutput(), - mOutputPause(), - mParticleImage(nullptr), - mParticleAnimation("particle animation"), - mParticleRotation("particle rotation"), - mParticleAlpha(), - mDeathEffect(), - mParticleChildEmitters(), - mTempSets(), - mOutputPauseLeft(0), - mDeathEffectConditions(0), - mParticleFollow(false) -{ - // Initializing default values - mParticlePosX.set(0.0F); - mParticlePosY.set(0.0F); - mParticlePosZ.set(0.0F); - mParticleAngleHorizontal.set(0.0F); - mParticleAngleVertical.set(0.0F); - mParticlePower.set(0.0F); - mParticleGravity.set(0.0F); - mParticleRandomness.set(0); - mParticleBounce.set(0.0F); - mParticleAcceleration.set(0.0F); - mParticleDieDistance.set(-1.0F); - mParticleMomentum.set(1.0F); - mParticleLifetime.set(-1); - mParticleFadeOut.set(0); - mParticleFadeIn.set(0); - mOutput.set(1); - mOutputPause.set(0); - mParticleAlpha.set(1.0F); - - if (emitterNode == nullptr) - return; - for_each_xml_child_node(propertyNode, emitterNode) - { - if (xmlNameEqual(propertyNode, "property")) - { - const std::string name = XML::getProperty( - propertyNode, "name", ""); - - if (name == "position-x") - { - mParticlePosX = readParticleEmitterProp(propertyNode, 0.0F); - } - else if (name == "position-y") - { - mParticlePosY = readParticleEmitterProp(propertyNode, 0.0F); - mParticlePosY.minVal *= SIN45; - mParticlePosY.maxVal *= SIN45; - mParticlePosY.changeAmplitude *= SIN45; - } - else if (name == "position-z") - { - mParticlePosZ = readParticleEmitterProp(propertyNode, 0.0F); - mParticlePosZ.minVal *= SIN45; - mParticlePosZ.maxVal *= SIN45; - mParticlePosZ.changeAmplitude *= SIN45; - } - else if (name == "image") - { - std::string image = XML::getProperty( - propertyNode, "value", ""); - // Don't leak when multiple images are defined - if (!image.empty() && (mParticleImage == nullptr)) - { - if (!dyePalettes.empty()) - Dye::instantiate(image, dyePalettes); - mParticleImage = Loader::getImage(image); - } - } - else if (name == "subimage") - { - std::string image = XML::getProperty( - propertyNode, "value", ""); - // Don't leak when multiple images are defined - if (!image.empty() && (mParticleImage == nullptr)) - { - if (!dyePalettes.empty()) - Dye::instantiate(image, dyePalettes); - Image *img = Loader::getImage(image); - if (img != nullptr) - { - mParticleImage = Loader::getSubImage(img, - XML::getProperty(propertyNode, "x", 0), - XML::getProperty(propertyNode, "y", 0), - XML::getProperty(propertyNode, "width", 0), - XML::getProperty(propertyNode, "height", 0)); - img->decRef(); - } - else - { - mParticleImage = nullptr; - } - } - } - else if (name == "horizontal-angle") - { - mParticleAngleHorizontal = - readParticleEmitterProp(propertyNode, 0.0F); - mParticleAngleHorizontal.minVal - += static_cast<float>(rotation); - mParticleAngleHorizontal.minVal *= DEG_RAD_FACTOR; - mParticleAngleHorizontal.maxVal - += static_cast<float>(rotation); - mParticleAngleHorizontal.maxVal *= DEG_RAD_FACTOR; - mParticleAngleHorizontal.changeAmplitude *= DEG_RAD_FACTOR; - } - else if (name == "vertical-angle") - { - mParticleAngleVertical = - readParticleEmitterProp(propertyNode, 0.0F); - mParticleAngleVertical.minVal *= DEG_RAD_FACTOR; - mParticleAngleVertical.maxVal *= DEG_RAD_FACTOR; - mParticleAngleVertical.changeAmplitude *= DEG_RAD_FACTOR; - } - else if (name == "power") - { - mParticlePower = readParticleEmitterProp(propertyNode, 0.0F); - } - else if (name == "gravity") - { - mParticleGravity = readParticleEmitterProp(propertyNode, 0.0F); - } - else if (name == "randomnes" - || name == "randomness") // legacy bug - { - mParticleRandomness = readParticleEmitterProp(propertyNode, 0); - } - else if (name == "bounce") - { - mParticleBounce = readParticleEmitterProp(propertyNode, 0.0F); - } - else if (name == "lifetime") - { - mParticleLifetime = readParticleEmitterProp(propertyNode, 0); - mParticleLifetime.minVal += 1; - } - else if (name == "output") - { - mOutput = readParticleEmitterProp(propertyNode, 0); - mOutput.maxVal += 1; - } - else if (name == "output-pause") - { - mOutputPause = readParticleEmitterProp(propertyNode, 0); - mOutputPauseLeft = mOutputPause.value(0); - } - else if (name == "acceleration") - { - mParticleAcceleration = readParticleEmitterProp( - propertyNode, 0.0F); - } - else if (name == "die-distance") - { - mParticleDieDistance = readParticleEmitterProp( - propertyNode, 0.0F); - } - else if (name == "momentum") - { - mParticleMomentum = readParticleEmitterProp( - propertyNode, 1.0F); - } - else if (name == "fade-out") - { - mParticleFadeOut = readParticleEmitterProp(propertyNode, 0); - } - else if (name == "fade-in") - { - mParticleFadeIn = readParticleEmitterProp(propertyNode, 0); - } - else if (name == "alpha") - { - mParticleAlpha = readParticleEmitterProp(propertyNode, 1.0F); - } - else if (name == "follow-parent") - { - const std::string value = XML::getProperty(propertyNode, - "value", "0"); - if (value == "1" || value == "true") - mParticleFollow = true; - } - else - { - logger->log("Particle Engine: Warning, " - "unknown emitter property \"%s\"", - name.c_str()); - } - } - else if (xmlNameEqual(propertyNode, "emitter")) - { - ParticleEmitter newEmitter(propertyNode, mParticleTarget, map, - rotation, dyePalettes); - mParticleChildEmitters.push_back(newEmitter); - } - else if (xmlNameEqual(propertyNode, "rotation") - || xmlNameEqual(propertyNode, "animation")) - { - ImageSet *const imageset = getImageSet(propertyNode); - if (imageset == nullptr) - { - logger->log1("Error: no valid imageset"); - continue; - } - mTempSets.push_back(imageset); - - Animation &animation = (xmlNameEqual(propertyNode, "rotation")) != - 0 ? mParticleRotation : mParticleAnimation; - - // Get animation frames - for_each_xml_child_node(frameNode, propertyNode) - { - const int delay = XML::getIntProperty( - frameNode, "delay", 0, 0, 100000); - const int offsetX = XML::getProperty(frameNode, "offsetX", 0) - - imageset->getWidth() / 2 + mapTileSize / 2; - const int offsetY = XML::getProperty(frameNode, "offsetY", 0) - - imageset->getHeight() + mapTileSize; - const int rand = XML::getIntProperty( - frameNode, "rand", 100, 0, 100); - - if (xmlNameEqual(frameNode, "frame")) - { - const int index = XML::getProperty(frameNode, "index", -1); - - if (index < 0) - { - logger->log1("No valid value for 'index'"); - continue; - } - - Image *const img = imageset->get(index); - - if (img == nullptr) - { - logger->log("No image at index %d", index); - continue; - } - - animation.addFrame(img, delay, - offsetX, offsetY, rand); - } - else if (xmlNameEqual(frameNode, "sequence")) - { - int start = XML::getProperty(frameNode, "start", -1); - const int end = XML::getProperty(frameNode, "end", -1); - - if (start < 0 || end < 0) - { - logger->log1("No valid value for 'start' or 'end'"); - continue; - } - - while (end >= start) - { - Image *const img = imageset->get(start); - if (img == nullptr) - { - logger->log("No image at index %d", start); - continue; - } - - animation.addFrame(img, delay, - offsetX, offsetY, rand); - start ++; - } - } - else if (xmlNameEqual(frameNode, "end")) - { - animation.addTerminator(rand); - } - } // for frameNode - } - else if (xmlNameEqual(propertyNode, "deatheffect")) - { - if (!XmlHaveChildContent(propertyNode)) - continue; - mDeathEffect = XmlChildContent(propertyNode); - mDeathEffectConditions = 0x00; - if (XML::getBoolProperty(propertyNode, "on-floor", true)) - { - mDeathEffectConditions += CAST_S8( - AliveStatus::DEAD_FLOOR); - } - if (XML::getBoolProperty(propertyNode, "on-sky", true)) - { - mDeathEffectConditions += CAST_S8( - AliveStatus::DEAD_SKY); - } - if (XML::getBoolProperty(propertyNode, "on-other", false)) - { - mDeathEffectConditions += CAST_S8( - AliveStatus::DEAD_OTHER); - } - if (XML::getBoolProperty(propertyNode, "on-impact", true)) - { - mDeathEffectConditions += CAST_S8( - AliveStatus::DEAD_IMPACT); - } - if (XML::getBoolProperty(propertyNode, "on-timeout", true)) - { - mDeathEffectConditions += CAST_S8( - AliveStatus::DEAD_TIMEOUT); - } - } - } -} - -ParticleEmitter::ParticleEmitter(const ParticleEmitter &o) -{ - *this = o; -} - -ImageSet *ParticleEmitter::getImageSet(XmlNodePtrConst node) -{ - ImageSet *imageset = nullptr; - const int subX = XML::getProperty(node, "subX", -1); - if (subX != -1) - { - Image *const img = Loader::getImage(XML::getProperty( - node, "imageset", "")); - if (img == nullptr) - return nullptr; - - Image *const img2 = Loader::getSubImage(img, subX, - XML::getProperty(node, "subY", 0), - XML::getProperty(node, "subWidth", 0), - XML::getProperty(node, "subHeight", 0)); - if (img2 == nullptr) - { - img->decRef(); - return nullptr; - } - - imageset = Loader::getSubImageSet(img2, - XML::getProperty(node, "width", 0), - XML::getProperty(node, "height", 0)); - img2->decRef(); - img->decRef(); - } - else - { - imageset = Loader::getImageSet( - XML::getProperty(node, "imageset", ""), - XML::getProperty(node, "width", 0), - XML::getProperty(node, "height", 0)); - } - return imageset; -} - -ParticleEmitter & ParticleEmitter::operator=(const ParticleEmitter &o) -{ - mParticlePosX = o.mParticlePosX; - mParticlePosY = o.mParticlePosY; - mParticlePosZ = o.mParticlePosZ; - mParticleAngleHorizontal = o.mParticleAngleHorizontal; - mParticleAngleVertical = o.mParticleAngleVertical; - mParticlePower = o.mParticlePower; - mParticleGravity = o.mParticleGravity; - mParticleRandomness = o.mParticleRandomness; - mParticleBounce = o.mParticleBounce; - mParticleFollow = o.mParticleFollow; - mParticleTarget = o.mParticleTarget; - mParticleAcceleration = o.mParticleAcceleration; - mParticleDieDistance = o.mParticleDieDistance; - mParticleMomentum = o.mParticleMomentum; - mParticleLifetime = o.mParticleLifetime; - mParticleFadeOut = o.mParticleFadeOut; - mParticleFadeIn = o.mParticleFadeIn; - mParticleAlpha = o.mParticleAlpha; - mMap = o.mMap; - mOutput = o.mOutput; - mOutputPause = o.mOutputPause; - mParticleImage = o.mParticleImage; - mParticleAnimation = o.mParticleAnimation; - mParticleRotation = o.mParticleRotation; - mParticleChildEmitters = o.mParticleChildEmitters; - mDeathEffectConditions = o.mDeathEffectConditions; - mDeathEffect = o.mDeathEffect; - mTempSets = o.mTempSets; - - FOR_EACH (ImageSetVectorCIter, i, mTempSets) - { - if (*i != nullptr) - (*i)->incRef(); - } - - mOutputPauseLeft = 0; - - if (mParticleImage != nullptr) - mParticleImage->incRef(); - - return *this; -} - -ParticleEmitter::~ParticleEmitter() -{ - FOR_EACH (ImageSetVectorCIter, i, mTempSets) - { - if (*i != nullptr) - (*i)->decRef(); - } - mTempSets.clear(); - - if (mParticleImage != nullptr) - { - mParticleImage->decRef(); - mParticleImage = nullptr; - } -} - -template <typename T> ParticleEmitterProp<T> -ParticleEmitter::readParticleEmitterProp(XmlNodePtrConst propertyNode, T def) -{ - ParticleEmitterProp<T> retval; - - def = static_cast<T>(XML::getDoubleProperty(propertyNode, "value", - static_cast<double>(def))); - retval.set(static_cast<T>(XML::getDoubleProperty(propertyNode, "min", - static_cast<double>(def))), static_cast<T>(XML::getDoubleProperty( - propertyNode, "max", static_cast<double>(def)))); - - const std::string change = XML::getProperty( - propertyNode, "change-func", "none"); - T amplitude = static_cast<T>(XML::getDoubleProperty(propertyNode, - "change-amplitude", 0.0)); - - const int period = XML::getProperty(propertyNode, "change-period", 0); - const int phase = XML::getProperty(propertyNode, "change-phase", 0); - if (change == "saw" || change == "sawtooth") - { - retval.setFunction(ParticleChangeFunc::FUNC_SAW, - amplitude, period, phase); - } - else if (change == "sine" || change == "sinewave") - { - retval.setFunction(ParticleChangeFunc::FUNC_SINE, - amplitude, period, phase); - } - else if (change == "triangle") - { - retval.setFunction(ParticleChangeFunc::FUNC_TRIANGLE, - amplitude, period, phase); - } - else if (change == "square") - { - retval.setFunction(ParticleChangeFunc::FUNC_SQUARE, - amplitude, period, phase); - } - - return retval; -} - -void ParticleEmitter::createParticles(const int tick, - STD_VECTOR<Particle*> &newParticles) -{ - if (mOutputPauseLeft > 0) - { - mOutputPauseLeft --; - return; - } - mOutputPauseLeft = mOutputPause.value(tick); - - for (int i = mOutput.value(tick); i > 0; i--) - { - // Limit maximum particles - if (ParticleEngine::particleCount > ParticleEngine::maxCount) - break; - - Particle *newParticle = nullptr; - if (mParticleImage != nullptr) - { - const std::string &name = mParticleImage->mIdPath; - if (ImageParticle::imageParticleCountByName.find(name) == - ImageParticle::imageParticleCountByName.end()) - { - ImageParticle::imageParticleCountByName[name] = 0; - } - - if (ImageParticle::imageParticleCountByName[name] > 200) - break; - - newParticle = new ImageParticle(mParticleImage); - newParticle->setMap(mMap); - } - else if (!mParticleRotation.mFrames.empty()) - { - Animation *const newAnimation = new Animation(mParticleRotation); - newParticle = new RotationalParticle(newAnimation); - newParticle->setMap(mMap); - } - else if (!mParticleAnimation.mFrames.empty()) - { - Animation *const newAnimation = new Animation(mParticleAnimation); - newParticle = new AnimationParticle(newAnimation); - newParticle->setMap(mMap); - } - else - { - newParticle = new Particle; - newParticle->setMap(mMap); - } - - const Vector position(mParticlePosX.value(tick), - mParticlePosY.value(tick), - mParticlePosZ.value(tick)); - newParticle->moveTo(position); - - const float angleH = mParticleAngleHorizontal.value(tick); - const float cosAngleH = static_cast<float>(cos(angleH)); - const float sinAngleH = static_cast<float>(sin(angleH)); - const float angleV = mParticleAngleVertical.value(tick); - const float cosAngleV = static_cast<float>(cos(angleV)); - const float sinAngleV = static_cast<float>(sin(angleV)); - const float power = mParticlePower.value(tick); - newParticle->setVelocity(cosAngleH * cosAngleV * power, - sinAngleH * cosAngleV * power, - sinAngleV * power); - - newParticle->setRandomness(mParticleRandomness.value(tick)); - newParticle->setGravity(mParticleGravity.value(tick)); - newParticle->setBounce(mParticleBounce.value(tick)); - newParticle->setFollow(mParticleFollow); - - newParticle->setDestination(mParticleTarget, - mParticleAcceleration.value(tick), - mParticleMomentum.value(tick)); - - newParticle->setDieDistance(mParticleDieDistance.value(tick)); - - newParticle->setLifetime(mParticleLifetime.value(tick)); - newParticle->setFadeOut(mParticleFadeOut.value(tick)); - newParticle->setFadeIn(mParticleFadeIn.value(tick)); - newParticle->setAlpha(mParticleAlpha.value(tick)); - - FOR_EACH (ParticleEmitterListCIter, it, mParticleChildEmitters) - newParticle->addEmitter(new ParticleEmitter(*it)); - - if (!mDeathEffect.empty()) - newParticle->setDeathEffect(mDeathEffect, mDeathEffectConditions); - - newParticles.push_back(newParticle); - } -} - -void ParticleEmitter::adjustSize(const int w, const int h) -{ - if (w == 0 || h == 0) - return; // new dimensions are illegal - - // calculate the old rectangle - const int oldArea = CAST_S32( - mParticlePosX.maxVal - mParticlePosX.minVal) * CAST_S32( - mParticlePosX.maxVal - mParticlePosY.minVal); - if (oldArea == 0) - { - // when the effect has no dimension it is - // not designed to be resizeable - return; - } - - // set the new dimensions - mParticlePosX.set(0, static_cast<float>(w)); - mParticlePosY.set(0, static_cast<float>(h)); - const int newArea = w * h; - // adjust the output so that the particle density stays the same - const float outputFactor = static_cast<float>(newArea) - / static_cast<float>(oldArea); - mOutput.minVal = CAST_S32(static_cast<float>( - mOutput.minVal) * outputFactor); - mOutput.maxVal = CAST_S32(static_cast<float>( - mOutput.maxVal) * outputFactor); -} diff --git a/src/particle/particleemitter.h b/src/particle/particleemitter.h deleted file mode 100644 index ec01b88df..000000000 --- a/src/particle/particleemitter.h +++ /dev/null @@ -1,172 +0,0 @@ -/* - * The ManaPlus Client - * Copyright (C) 2006-2009 The Mana World Development Team - * Copyright (C) 2009-2010 The Mana Developers - * Copyright (C) 2011-2017 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_PARTICLEEMITTER_H -#define PARTICLE_PARTICLEEMITTER_H - -#include "particle/particleemitterprop.h" - -#include "resources/animation/animation.h" - -#include "utils/xml.h" - -#include <list> - -class Image; -class ImageSet; -class Map; -class Particle; - -/** - * Every Particle can have one or more particle emitters that create new - * particles when they are updated - */ -class ParticleEmitter final -{ - public: - ParticleEmitter(XmlNodeConstPtrConst emitterNode, - Particle *const target, - Map *const map, - const int rotation = 0, - const std::string& dyePalettes = std::string()) - A_NONNULL(3); - - /** - * Copy Constructor (necessary for reference counting of particle images) - */ - ParticleEmitter(const ParticleEmitter &o); - - A_DEFAULT_COPY(ParticleEmitter) - - /** - * Assignment operator that calls the copy constructor - */ - ParticleEmitter & operator=(const ParticleEmitter &o); - - /** - * Destructor. - */ - ~ParticleEmitter(); - - /** - * Spawns new particles - */ - void createParticles(const int tick, - STD_VECTOR<Particle*> &newParticles); - - /** - * Sets the target of the particles that are created - */ - void setTarget(Particle *const target) - { mParticleTarget = target; } - - /** - * Changes the size of the emitter so that the effect fills a - * rectangle of this size - */ - void adjustSize(const int w, const int h); - - private: - template <typename T> static ParticleEmitterProp<T> - readParticleEmitterProp(XmlNodePtrConst propertyNode, T def); - - ImageSet *getImageSet(XmlNodePtrConst node); - - /** - * initial position of particles: - */ - ParticleEmitterProp<float> mParticlePosX, mParticlePosY, mParticlePosZ; - - /** - * initial vector of particles: - */ - ParticleEmitterProp<float> mParticleAngleHorizontal, - mParticleAngleVertical; - - /** - * Initial velocity of particles - */ - ParticleEmitterProp<float> mParticlePower; - - /* - * Vector changing of particles: - */ - ParticleEmitterProp<float> mParticleGravity; - ParticleEmitterProp<int> mParticleRandomness; - ParticleEmitterProp<float> mParticleBounce; - - /* - * Properties of targeting particles: - */ - Particle *mParticleTarget; - ParticleEmitterProp<float> mParticleAcceleration; - ParticleEmitterProp<float> mParticleDieDistance; - ParticleEmitterProp<float> mParticleMomentum; - - /* - * Behavior over time of the particles: - */ - ParticleEmitterProp<int> mParticleLifetime; - ParticleEmitterProp<int> mParticleFadeOut; - ParticleEmitterProp<int> mParticleFadeIn; - - // Map the particles are spawned on - Map *mMap; - - // Number of particles spawned per update - ParticleEmitterProp<int> mOutput; - - // Pause in frames between two spawns - ParticleEmitterProp<int> mOutputPause; - - /* - * Graphical representation of the particles - */ - // Particle image, if used - Image *mParticleImage; - - // Filename of particle animation file - Animation mParticleAnimation; - - // Filename of particle rotation file - Animation mParticleRotation; - - // Opacity of the graphical representation of the particles - ParticleEmitterProp<float> mParticleAlpha; - - /* - * Death effect of the particles - */ - std::string mDeathEffect; - - // List of emitters the spawned particles are equipped with - std::list<ParticleEmitter> mParticleChildEmitters; - - STD_VECTOR<ImageSet*> mTempSets; - - int mOutputPauseLeft; - - signed char mDeathEffectConditions; - - bool mParticleFollow; -}; -#endif // PARTICLE_PARTICLEEMITTER_H diff --git a/src/particle/particleemitterprop.h b/src/particle/particleemitterprop.h deleted file mode 100644 index da7d0ac5b..000000000 --- a/src/particle/particleemitterprop.h +++ /dev/null @@ -1,127 +0,0 @@ -/* - * The ManaPlus Client - * Copyright (C) 2006-2009 The Mana World Development Team - * Copyright (C) 2009-2010 The Mana Developers - * Copyright (C) 2011-2017 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_PARTICLEEMITTERPROP_H -#define PARTICLE_PARTICLEEMITTERPROP_H - -#include <cmath> - -#include "enums/particle/particlechangefunc.h" - -#include "localconsts.h" - -template <typename T> struct ParticleEmitterProp final -{ - ParticleEmitterProp() : - minVal(0), - maxVal(0), - changeFunc(ParticleChangeFunc::FUNC_NONE), - changeAmplitude(0), - changePeriod(0), - changePhase(0) - { - } - - A_DEFAULT_COPY(ParticleEmitterProp) - - void set(const T min, const T max) - { - minVal = min; - maxVal = max; - } - - void set(const T val) - { - set(val, val); - } - - void setFunction(ParticleChangeFuncT func, - T amplitude, - const int period, - const int phase) - { - changeFunc = func; - changeAmplitude = amplitude; - changePeriod = period; - if (changePeriod == 0) - changePeriod = 1; - changePhase = phase; - } - - T value(int tick) const - { - tick += changePhase; - T val = static_cast<T>(minVal + (maxVal - minVal) - * (rand() / (static_cast<double>(RAND_MAX) + 1))); - - switch (changeFunc) - { - case ParticleChangeFunc::FUNC_SINE: - val += static_cast<T>(std::sin(M_PI * 2 * (static_cast<double>( - tick % changePeriod) / static_cast<double>( - changePeriod)))) * changeAmplitude; - break; - case ParticleChangeFunc::FUNC_SAW: - val += static_cast<T>(changeAmplitude * (static_cast<double>( - tick % changePeriod) / static_cast<double>( - changePeriod))) * 2 - changeAmplitude; - break; - case ParticleChangeFunc::FUNC_TRIANGLE: - if ((tick % changePeriod) * 2 < changePeriod) - { - val += changeAmplitude - static_cast<T>(( - tick % changePeriod) / static_cast<double>( - changePeriod)) * changeAmplitude * 4; - } - else - { - val += changeAmplitude * -3 + static_cast<T>(( - tick % changePeriod) / static_cast<double>( - changePeriod)) * changeAmplitude * 4; - // I have no idea why this works but it does - } - break; - case ParticleChangeFunc::FUNC_SQUARE: - if ((tick % changePeriod) * 2 < changePeriod) - val += changeAmplitude; - else - val -= changeAmplitude; - break; - case ParticleChangeFunc::FUNC_NONE: - default: - // nothing - break; - } - - return val; - } - - T minVal; - T maxVal; - - ParticleChangeFuncT changeFunc; - T changeAmplitude; - int changePeriod; - int changePhase; -}; - -#endif // PARTICLE_PARTICLEEMITTERPROP_H diff --git a/src/particle/particleengine.cpp b/src/particle/particleengine.cpp deleted file mode 100644 index 25e85fe94..000000000 --- a/src/particle/particleengine.cpp +++ /dev/null @@ -1,343 +0,0 @@ -/* - * The ManaPlus Client - * Copyright (C) 2006-2009 The Mana World Development Team - * Copyright (C) 2009-2010 The Mana Developers - * Copyright (C) 2011-2017 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/>. - */ - -#include "configuration.h" - -#include "gui/viewport.h" - -#include "particle/animationparticle.h" -#include "particle/particleemitter.h" -#include "particle/rotationalparticle.h" -#include "particle/textparticle.h" - -#include "resources/dye/dye.h" - -#include "resources/loaders/imageloader.h" -#include "resources/loaders/xmlloader.h" - -#include "utils/dtor.h" - -#include "debug.h" - -ParticleEngine *particleEngine = nullptr; - -class Image; - -int ParticleEngine::particleCount = 0; -int ParticleEngine::maxCount = 0; -ParticlePhysicsT ParticleEngine::fastPhysics = ParticlePhysics::Best; -int ParticleEngine::emitterSkip = 1; -bool ParticleEngine::enabled = true; -const float ParticleEngine::PARTICLE_SKY = 800.0F; - -ParticleEngine::ParticleEngine() : - mChildParticles(), - mChildMoveParticles(), - mMap(nullptr) -{ - ParticleEngine::particleCount++; -} - -ParticleEngine::~ParticleEngine() -{ - // Delete child emitters and child particles - clear(); - ParticleEngine::particleCount--; -} - -void ParticleEngine::setupEngine() restrict2 -{ - ParticleEngine::maxCount = config.getIntValue("particleMaxCount"); - ParticleEngine::fastPhysics = fromInt(config.getIntValue( - "particleFastPhysics"), - ParticlePhysicsT); - ParticleEngine::emitterSkip = - config.getIntValue("particleEmitterSkip") + 1; - if (ParticleEngine::emitterSkip == 0) - ParticleEngine::emitterSkip = 1; - ParticleEngine::enabled = config.getBoolValue("particleeffects"); - logger->log1("Particle engine set up"); -} - -bool ParticleEngine::update() restrict2 -{ - if (mChildParticles.empty() || (mMap == nullptr)) - return true; - - // Update child particles - - const int cameraX = viewport->getCameraX(); - const int cameraY = viewport->getCameraY(); - const float x1 = static_cast<float>(cameraX - 3000); - const float y1 = static_cast<float>(cameraY - 2000); - const float x2 = static_cast<float>(cameraX + 3000); - const float y2 = static_cast<float>(cameraY + 2000); - - for (ParticleIterator p = mChildParticles.begin(), - fp2 = mChildParticles.end(); p != fp2; ) - { - Particle *restrict const particle = *p; - const float posX = particle->mPos.x; - const float posY = particle->mPos.y; - if (posX < x1 || posX > x2 || posY < y1 || posY > y2) - { - ++p; - continue; - } - // update particle - if (particle->update()) - { - ++p; - } - else - { - mChildMoveParticles.remove(*p); - delete particle; - p = mChildParticles.erase(p); - } - } - return true; -} - -Particle *ParticleEngine::createChild() restrict2 -{ - Particle *const newParticle = new Particle; - newParticle->setMap(mMap); - mChildParticles.push_back(newParticle); - return newParticle; -} - -Particle *ParticleEngine::addEffect(const std::string &restrict - particleEffectFile, - const int pixelX, - const int pixelY, - const int rotation) restrict2 -{ - Particle *newParticle = nullptr; - - const size_t pos = particleEffectFile.find('|'); - const std::string dyePalettes = (pos != std::string::npos) - ? particleEffectFile.substr(pos + 1) : ""; - XML::Document *doc = Loader::getXml( - particleEffectFile.substr(0, pos), - UseVirtFs_true, - SkipError_false); - if (doc == nullptr) - return nullptr; - - XmlNodeConstPtrConst rootNode = doc->rootNode(); - - if ((rootNode == nullptr) || !xmlNameEqual(rootNode, "effect")) - { - logger->log("Error loading particle: %s", particleEffectFile.c_str()); - doc->decRef(); - return nullptr; - } - - // Parse particles - for_each_xml_child_node(effectChildNode, rootNode) - { - // We're only interested in particles - if (!xmlNameEqual(effectChildNode, "particle")) - continue; - - // Determine the exact particle type - XmlNodePtr node; - - // Animation - if ((node = XML::findFirstChildByName(effectChildNode, "animation")) != - nullptr) - { - newParticle = new AnimationParticle(node, dyePalettes); - newParticle->setMap(mMap); - } - // Rotational - else if ((node = XML::findFirstChildByName( - effectChildNode, "rotation")) != nullptr) - { - newParticle = new RotationalParticle(node, dyePalettes); - newParticle->setMap(mMap); - } - // Image - else if ((node = XML::findFirstChildByName(effectChildNode, - "image")) != nullptr) - { - std::string imageSrc; - if (XmlHaveChildContent(node)) - imageSrc = XmlChildContent(node); - if (!imageSrc.empty() && !dyePalettes.empty()) - Dye::instantiate(imageSrc, dyePalettes); - Image *const img = Loader::getImage(imageSrc); - - newParticle = new ImageParticle(img); - newParticle->setMap(mMap); - } - // Other - else - { - newParticle = new Particle; - newParticle->setMap(mMap); - } - - // Read and set the basic properties of the particle - const float offsetX = XML::getFloatProperty( - effectChildNode, "position-x", 0); - const float offsetY = XML::getFloatProperty( - effectChildNode, "position-y", 0); - const float offsetZ = XML::getFloatProperty( - effectChildNode, "position-z", 0); - const Vector position(static_cast<float>(pixelX) + offsetX, - static_cast<float>(pixelY) + offsetY, - offsetZ); - newParticle->moveTo(position); - - const int lifetime = XML::getProperty(effectChildNode, "lifetime", -1); - newParticle->setLifetime(lifetime); - const bool resizeable = "false" != XML::getProperty(effectChildNode, - "size-adjustable", "false"); - - newParticle->setAllowSizeAdjust(resizeable); - - // Look for additional emitters for this particle - for_each_xml_child_node(emitterNode, effectChildNode) - { - if (xmlNameEqual(emitterNode, "emitter")) - { - ParticleEmitter *restrict const newEmitter = - new ParticleEmitter( - emitterNode, - newParticle, - mMap, - rotation, - dyePalettes); - newParticle->addEmitter(newEmitter); - } - else if (xmlNameEqual(emitterNode, "deatheffect")) - { - std::string deathEffect; - if ((node != nullptr) && XmlHaveChildContent(node)) - deathEffect = XmlChildContent(emitterNode); - - char deathEffectConditions = 0x00; - if (XML::getBoolProperty(emitterNode, "on-floor", true)) - { - deathEffectConditions += CAST_S8( - AliveStatus::DEAD_FLOOR); - } - if (XML::getBoolProperty(emitterNode, "on-sky", true)) - { - deathEffectConditions += CAST_S8( - AliveStatus::DEAD_SKY); - } - if (XML::getBoolProperty(emitterNode, "on-other", false)) - { - deathEffectConditions += CAST_S8( - AliveStatus::DEAD_OTHER); - } - if (XML::getBoolProperty(emitterNode, "on-impact", true)) - { - deathEffectConditions += CAST_S8( - AliveStatus::DEAD_IMPACT); - } - if (XML::getBoolProperty(emitterNode, "on-timeout", true)) - { - deathEffectConditions += CAST_S8( - AliveStatus::DEAD_TIMEOUT); - } - newParticle->setDeathEffect( - deathEffect, deathEffectConditions); - } - } - - mChildParticles.push_back(newParticle); - } - - doc->decRef(); - return newParticle; -} - -Particle *ParticleEngine::addTextSplashEffect(const std::string &restrict text, - const int x, - const int y, - const Color *restrict const - color, - Font *restrict const font, - const bool outline) restrict2 -{ - Particle *const newParticle = new TextParticle( - text, - color, - font, - outline); - newParticle->setMap(mMap); - newParticle->moveTo(static_cast<float>(x), - static_cast<float>(y)); - newParticle->setVelocity( - static_cast<float>((rand() % 100) - 50) / 200.0F, // X - static_cast<float>((rand() % 100) - 50) / 200.0F, // Y - (static_cast<float>((rand() % 100)) / 200.0F) + 4.0F); // Z - - newParticle->setGravity(0.1F); - newParticle->setBounce(0.5F); - newParticle->setLifetime(200); - newParticle->setFadeOut(100); - - mChildParticles.push_back(newParticle); - - return newParticle; -} - -Particle *ParticleEngine::addTextRiseFadeOutEffect(const std::string &restrict - text, - const int x, - const int y, - const Color *restrict const - color, - Font *restrict const font, - const bool outline) - restrict2 -{ - Particle *const newParticle = new TextParticle( - text, - color, - font, - outline); - newParticle->setMap(mMap); - newParticle->moveTo(static_cast<float>(x), - static_cast<float>(y)); - newParticle->setVelocity(0.0F, 0.0F, 0.5F); - newParticle->setGravity(0.0015F); - newParticle->setLifetime(300); - newParticle->setFadeOut(100); - newParticle->setFadeIn(0); - - mChildParticles.push_back(newParticle); - - return newParticle; -} - -void ParticleEngine::clear() restrict2 -{ - delete_all(mChildParticles); - mChildParticles.clear(); - mChildMoveParticles.clear(); -} diff --git a/src/particle/particleengine.h b/src/particle/particleengine.h deleted file mode 100644 index 19a9c4e9f..000000000 --- a/src/particle/particleengine.h +++ /dev/null @@ -1,130 +0,0 @@ -/* - * The ManaPlus Client - * Copyright (C) 2006-2009 The Mana World Development Team - * Copyright (C) 2009-2010 The Mana Developers - * Copyright (C) 2011-2017 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_PARTICLEENGINE_H -#define PARTICLE_PARTICLEENGINE_H - -#include "enums/particle/particlephysics.h" - -#include <list> -#include <string> - -#include "localconsts.h" - -class Color; -class Font; -class Map; -class Particle; -class ParticleEmitter; - -typedef std::list<Particle *> Particles; -typedef Particles::iterator ParticleIterator; -typedef Particles::const_iterator ParticleConstIterator; -typedef std::list<ParticleEmitter *> Emitters; -typedef Emitters::iterator EmitterIterator; -typedef Emitters::const_iterator EmitterConstIterator; - -class ParticleEngine final -{ - public: - static const float PARTICLE_SKY; // Maximum Z position of particles - static ParticlePhysicsT fastPhysics; // Mode of squareroot calculation - static int particleCount; // Current number of particles - static int maxCount; // Maximum number of particles - static int emitterSkip; // Duration of pause between two - // emitter updates in ticks - static bool enabled; // true when non-crucial particle effects - // are disabled - - ParticleEngine(); - - A_DELETE_COPY(ParticleEngine) - - /** - * Destructor. - */ - ~ParticleEngine(); - - /** - * Deletes all child particles and emitters. - */ - void clear() restrict2; - - /** - * Gives a particle the properties of an engine root particle and loads - * the particle-related config settings. - */ - void setupEngine() restrict2; - - /** - * Updates particle position, returns false when the particle should - * be deleted. - */ - bool update() restrict2; - - /** - * Creates a blank particle as a child of the current particle - * Useful for creating target particles - */ - Particle *createChild() restrict2; - - /** - * Creates a child particle that hosts some emitters described in the - * particleEffectFile. - */ - Particle *addEffect(const std::string &restrict particleEffectFile, - const int pixelX, const int pixelY, - const int rotation = 0) restrict2; - - /** - * Creates a standalone text particle. - */ - Particle *addTextSplashEffect(const std::string &restrict text, - const int x, const int y, - const Color *restrict const color, - Font *restrict const font, - const bool outline = false) - restrict2 A_NONNULL(5, 6); - - /** - * Creates a standalone text particle. - */ - Particle *addTextRiseFadeOutEffect(const std::string &restrict text, - const int x, const int y, - const Color *restrict const color, - Font *restrict const font, - const bool outline = false) - restrict2 A_NONNULL(5, 6); - - void setMap(Map *const map) - { mMap = map; } - - private: - // List of particles controlled by this particle - Particles mChildParticles; - Particles mChildMoveParticles; - Map *mMap; -}; - -extern ParticleEngine *particleEngine; - -#endif // PARTICLE_PARTICLEENGINE_H diff --git a/src/particle/particleinfo.h b/src/particle/particleinfo.h deleted file mode 100644 index 48129f553..000000000 --- a/src/particle/particleinfo.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * The ManaPlus Client - * Copyright (C) 2013-2017 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 "utils/vector.h" - -struct ParticleInfo final -{ - ParticleInfo() : - files(), - particles() - { - } - - A_DELETE_COPY(ParticleInfo) - - STD_VECTOR<std::string> files; - STD_VECTOR<Particle*> particles; -}; - -#endif // PARTICLE_PARTICLEINFO_H diff --git a/src/particle/particlelist.cpp b/src/particle/particlelist.cpp deleted file mode 100644 index 26194453b..000000000 --- a/src/particle/particlelist.cpp +++ /dev/null @@ -1,106 +0,0 @@ -/* - * The ManaPlus Client - * Copyright (C) 2008-2009 The Mana World Development Team - * Copyright (C) 2009-2010 The Mana Developers - * Copyright (C) 2011-2017 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/>. - */ - -#include "particle/particlelist.h" - -#include "utils/foreach.h" - -#include "particle/particle.h" - -#include "debug.h" - -typedef std::list<Particle *>::iterator ParticleListIter; -typedef std::list<Particle *>::const_iterator ParticleListCIter; - -ParticleList::ParticleList(ParticleContainer *const parent, - const bool delParent) : - ParticleContainer(parent, delParent), - mElements(), - mSize(0U) -{} - -ParticleList::~ParticleList() -{ -} - -void ParticleList::addLocally(Particle *const particle) -{ - if (particle != nullptr) - { - mElements.push_back(particle); - mSize ++; - } -} - -void ParticleList::removeLocally(const Particle *const particle) -{ - for (std::list<Particle *>::iterator it = mElements.begin(); - it != mElements.end(); ) - { - Particle *const p = *it; - if (p == particle) - { - p->kill(); - p->prepareToDie(); - it = mElements.erase(it); - mSize --; - } - else - { - ++it; - } - } -} - -void ParticleList::clearLocally() -{ - FOR_EACH (ParticleListCIter, it, mElements) - { - (*it)->kill(); - (*it)->prepareToDie(); - } - - mElements.clear(); - mSize = 0U; -} - -void ParticleList::moveTo(const float x, const float y) -{ - ParticleContainer::moveTo(x, y); - - for (std::list<Particle *>::iterator it = mElements.begin(); - it != mElements.end(); ) - { - Particle *const p = *it; - p->moveTo(x, y); - if (p->isExtinct()) - { - p->kill(); - it = mElements.erase(it); - mSize --; - } - else - { - ++it; - } - } -} diff --git a/src/particle/particlelist.h b/src/particle/particlelist.h deleted file mode 100644 index 83c23a454..000000000 --- a/src/particle/particlelist.h +++ /dev/null @@ -1,69 +0,0 @@ -/* - * The ManaPlus Client - * Copyright (C) 2008-2009 The Mana World Development Team - * Copyright (C) 2009-2010 The Mana Developers - * Copyright (C) 2011-2017 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_PARTICLELIST_H -#define PARTICLE_PARTICLELIST_H - -#include "particle/particlecontainer.h" - -#include <list> - -#include "localconsts.h" - -class Particle; - -/** - * Linked list of particle effects. - */ -class ParticleList final : public ParticleContainer -{ - public: - explicit ParticleList(ParticleContainer *const parent = nullptr, - const bool delParent = true); - - A_DELETE_COPY(ParticleList) - - ~ParticleList(); - - /** - * Takes control of and adds a particle - */ - void addLocally(Particle *const particle); - - /** - * `kills' and removes a particle - */ - void removeLocally(const Particle *const particle); - - void clearLocally() override final; - - void moveTo(const float x, const float y) override final; - - size_t size() const - { return mSize; } - - protected: - std::list<Particle *> mElements; /**< Contained particle effects */ - size_t mSize; -}; - -#endif // PARTICLE_PARTICLELIST_H diff --git a/src/particle/particletimer.h b/src/particle/particletimer.h deleted file mode 100644 index 5a4e5045a..000000000 --- a/src/particle/particletimer.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * The ManaPlus Client - * Copyright (C) 2015-2017 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_PARTICLETIMER_H -#define PARTICLE_PARTICLETIMER_H - -#include "localconsts.h" - -class Particle; - -struct ParticleTimer final -{ - ParticleTimer(Particle *const particle0, - const time_t endTime0) A_NONNULL(2) : - particle(particle0), - endTime(endTime0) - { - } - - A_DEFAULT_COPY(ParticleTimer) - - Particle *const particle; - const time_t endTime; -}; - -#endif // PARTICLE_PARTICLETIMER_H diff --git a/src/particle/particlevector.cpp b/src/particle/particlevector.cpp deleted file mode 100644 index 8fba56244..000000000 --- a/src/particle/particlevector.cpp +++ /dev/null @@ -1,109 +0,0 @@ -/* - * The ManaPlus Client - * Copyright (C) 2008-2009 The Mana World Development Team - * Copyright (C) 2009-2010 The Mana Developers - * Copyright (C) 2011-2017 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/>. - */ - -#include "particle/particle.h" -#include "particle/particlevector.h" - -#include "debug.h" - -ParticleVector::ParticleVector(ParticleContainer *const parent, - const bool delParent) : - ParticleContainer(parent, delParent), - mIndexedElements() -{} - -ParticleVector::~ParticleVector() -{} - -void ParticleVector::setLocally(const int index, Particle *const particle) -{ - if (index < 0) - return; - - delLocally(index); - - if (mIndexedElements.size() <= CAST_SIZE(index)) - mIndexedElements.resize(index + 1, nullptr); - - if (particle != nullptr) - particle->disableAutoDelete(); - mIndexedElements[index] = particle; -} - -void ParticleVector::delLocally(const int index) -{ - if (index < 0) - return; - - if (mIndexedElements.size() <= CAST_SIZE(index)) - return; - - Particle *const p = mIndexedElements[index]; - if (p != nullptr) - { - mIndexedElements[index] = nullptr; - p->kill(); - } -} - -void ParticleVector::clearLocally() -{ - for (unsigned int i = 0; - i < CAST_U32(mIndexedElements.size()); - i++) - { - delLocally(i); - } -} - -void ParticleVector::moveTo(const float x, const float y) -{ - ParticleContainer::moveTo(x, y); - - for (STD_VECTOR<Particle *>::iterator it = mIndexedElements.begin(); - it != mIndexedElements.end(); ++it) - { - Particle *const p = *it; - if (p != nullptr) - { - p->moveTo(x, y); - - if (p->isExtinct()) - { - p->kill(); - *it = nullptr; - } - } - } -} - -size_t ParticleVector::usedSize() const -{ - size_t cnt = 0; - for (STD_VECTOR<Particle *>::const_iterator it = mIndexedElements.begin(); - it != mIndexedElements.end(); ++it) - { - if (*it != nullptr) - cnt ++; - } - return cnt; -} diff --git a/src/particle/particlevector.h b/src/particle/particlevector.h deleted file mode 100644 index dce4ae156..000000000 --- a/src/particle/particlevector.h +++ /dev/null @@ -1,71 +0,0 @@ -/* - * The ManaPlus Client - * Copyright (C) 2008-2009 The Mana World Development Team - * Copyright (C) 2009-2010 The Mana Developers - * Copyright (C) 2011-2017 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_PARTICLEVECTOR_H -#define PARTICLE_PARTICLEVECTOR_H - -#include "particle/particlecontainer.h" - -#include "utils/vector.h" - -#include "localconsts.h" - -class Particle; - -/** - * Particle container with indexing facilities - */ -class ParticleVector final : public ParticleContainer -{ - public: - explicit ParticleVector(ParticleContainer *const parent = nullptr, - const bool delParent = true); - - A_DELETE_COPY(ParticleVector) - - ~ParticleVector(); - - /** - * Sets a particle at a specified index. Kills the previous particle - * there, if needed. - */ - void setLocally(const int index, Particle *const particle); - - /** - * Removes a particle at a specified index - */ - void delLocally(const int index); - - void clearLocally() override final; - - void moveTo(const float x, const float y) override final; - - size_t size() const - { return mIndexedElements.size(); } - - size_t usedSize() const; - - protected: - STD_VECTOR<Particle *> mIndexedElements; -}; - -#endif // PARTICLE_PARTICLEVECTOR_H diff --git a/src/particle/rotationalparticle.cpp b/src/particle/rotationalparticle.cpp deleted file mode 100644 index 0693530d6..000000000 --- a/src/particle/rotationalparticle.cpp +++ /dev/null @@ -1,43 +0,0 @@ -/* - * The ManaPlus Client - * Copyright (C) 2006-2009 The Mana World Development Team - * Copyright (C) 2009-2010 The Mana Developers - * Copyright (C) 2011-2017 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/>. - */ - -#include "particle/rotationalparticle.h" - -#include "resources/animation/simpleanimation.h" - -#include "debug.h" - -RotationalParticle::RotationalParticle(Animation *restrict const animation) : - ImageParticle(nullptr) -{ - mType = ParticleType::Rotational; - mAnimation = new SimpleAnimation(animation); -} - -RotationalParticle::RotationalParticle(XmlNodeConstPtr animationNode, - const std::string &restrict - dyePalettes) : - ImageParticle(nullptr) -{ - mType = ParticleType::Rotational; - mAnimation = new SimpleAnimation(animationNode, dyePalettes); -} diff --git a/src/particle/rotationalparticle.h b/src/particle/rotationalparticle.h deleted file mode 100644 index 60c8461b1..000000000 --- a/src/particle/rotationalparticle.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * The ManaPlus Client - * Copyright (C) 2006-2009 The Mana World Development Team - * Copyright (C) 2009-2010 The Mana Developers - * Copyright (C) 2011-2017 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_ROTATIONALPARTICLE_H -#define PARTICLE_ROTATIONALPARTICLE_H - -#include "particle/imageparticle.h" - -#include "utils/xml.h" - -class Animation; - -class RotationalParticle final : public ImageParticle -{ - public: - explicit RotationalParticle(Animation *restrict const animation); - - explicit RotationalParticle(XmlNodeConstPtr animationNode, - const std::string &restrict dyePalettes - = std::string()); - - A_DELETE_COPY(RotationalParticle) -}; - -#endif // PARTICLE_ROTATIONALPARTICLE_H diff --git a/src/particle/textparticle.cpp b/src/particle/textparticle.cpp deleted file mode 100644 index dd25e5945..000000000 --- a/src/particle/textparticle.cpp +++ /dev/null @@ -1,96 +0,0 @@ -/* - * The ManaPlus Client - * Copyright (C) 2006-2009 The Mana World Development Team - * Copyright (C) 2009-2010 The Mana Developers - * Copyright (C) 2011-2017 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/>. - */ - -#include "particle/textparticle.h" - -#include "gui/theme.h" - -#include "gui/fonts/font.h" - -#include "render/graphics.h" - -#include "debug.h" - -TextParticle::TextParticle(const std::string &restrict text, - const Color *restrict const color, - Font *restrict const font, - const bool outline) : - Particle(), - mText(text), - mTextFont(font), - mColor(color), - mTextWidth(mTextFont != nullptr ? mTextFont->getWidth(mText) / 2 : 1), - mOutline(outline) -{ - mType = ParticleType::Text; -} - -void TextParticle::draw(Graphics *restrict const graphics, - const int offsetX, - const int offsetY) const restrict2 -{ - BLOCK_START("TextParticle::draw") - if (!isAlive()) - { - BLOCK_END("TextParticle::draw") - return; - } - - const int screenX = CAST_S32(mPos.x) + offsetX; - const int screenY = CAST_S32(mPos.y) - CAST_S32(mPos.z) - + offsetY; - - float alpha = mAlpha * 255.0F; - - if ((mFadeOut != 0) && mLifetimeLeft > -1 && mLifetimeLeft < mFadeOut) - { - alpha *= static_cast<float>(mLifetimeLeft) - / static_cast<float>(mFadeOut); - } - - if ((mFadeIn != 0) && mLifetimePast < mFadeIn) - { - alpha *= static_cast<float>(mLifetimePast) - / static_cast<float>(mFadeIn); - } - - Color color = *mColor; - color.a = CAST_U32(alpha); - - graphics->setColor(color); - if (mOutline) - { - const Color &restrict color2 = theme->getColor(ThemeColorId::OUTLINE, - CAST_S32(alpha)); - mTextFont->drawString(graphics, - color, color2, - mText, - screenX - mTextWidth, screenY); - } - else - { - mTextFont->drawString(graphics, - color, color, - mText, screenX - mTextWidth, screenY); - } - BLOCK_END("TextParticle::draw") -} diff --git a/src/particle/textparticle.h b/src/particle/textparticle.h deleted file mode 100644 index e67120688..000000000 --- a/src/particle/textparticle.h +++ /dev/null @@ -1,69 +0,0 @@ -/* - * The ManaPlus Client - * Copyright (C) 2006-2009 The Mana World Development Team - * Copyright (C) 2009-2010 The Mana Developers - * Copyright (C) 2011-2017 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_TEXTPARTICLE_H -#define PARTICLE_TEXTPARTICLE_H - -#include "particle/particle.h" - -class TextParticle final : public Particle -{ - public: - /** - * Constructor. - */ - TextParticle(const std::string &text, - const Color *restrict const color, - Font *restrict const font, - const bool outline = false) A_NONNULL(3, 4); - - A_DELETE_COPY(TextParticle) - - /** - * Draws the particle image. - */ - void draw(Graphics *restrict const graphics, - const int offsetX, - const int offsetY) const - restrict2 override final A_NONNULL(2); - - // hack to improve text visibility - int getPixelY() const restrict2 override final A_WARN_UNUSED - { return CAST_S32(mPos.y + mPos.z); } - - // hack to improve text visibility (for sorting only) - int getSortPixelY() const restrict2 override final A_WARN_UNUSED - { return CAST_S32(mPos.y + mPos.z); } - - private: - /**< Text of the particle. */ - std::string mText; - /**< Font used for drawing the text. */ - Font *restrict mTextFont A_NONNULLPOINTER; - /**< Color used for drawing the text. */ - const Color *restrict mColor A_NONNULLPOINTER; - int mTextWidth; - /**< Make the text better readable */ - bool mOutline; -}; - -#endif // PARTICLE_TEXTPARTICLE_H |