diff options
author | Andrei Karas <akaras@inbox.ru> | 2013-08-31 21:54:52 +0300 |
---|---|---|
committer | Andrei Karas <akaras@inbox.ru> | 2013-08-31 21:54:52 +0300 |
commit | 5919cdc663d5f60a8c5cc7e50ad0c43a18cf9829 (patch) | |
tree | 8c5be5f1f93551b676660e76b4d639ea2501e972 /src/particle.cpp | |
parent | 8a999b66fd697404c6640778a6dd1ce0e747334a (diff) | |
download | plus-5919cdc663d5f60a8c5cc7e50ad0c43a18cf9829.tar.gz plus-5919cdc663d5f60a8c5cc7e50ad0c43a18cf9829.tar.bz2 plus-5919cdc663d5f60a8c5cc7e50ad0c43a18cf9829.tar.xz plus-5919cdc663d5f60a8c5cc7e50ad0c43a18cf9829.zip |
move particles into particle dir.
Diffstat (limited to 'src/particle.cpp')
-rw-r--r-- | src/particle.cpp | 477 |
1 files changed, 0 insertions, 477 deletions
diff --git a/src/particle.cpp b/src/particle.cpp deleted file mode 100644 index dcd9422a1..000000000 --- a/src/particle.cpp +++ /dev/null @@ -1,477 +0,0 @@ -/* - * The ManaPlus Client - * Copyright (C) 2006-2009 The Mana World Development Team - * Copyright (C) 2009-2010 The Mana Developers - * Copyright (C) 2011-2013 The ManaPlus Developers - * - * This file is part of The ManaPlus Client. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -#include "particle.h" - -#include "animationparticle.h" -#include "configuration.h" -#include "resources/dye.h" -#include "logger.h" -#include "map.h" -#include "particleemitter.h" -#include "rotationalparticle.h" -#include "textparticle.h" - -#include "resources/resourcemanager.h" - -#include "gui/sdlfont.h" - -#include "utils/dtor.h" -#include "utils/mathutils.h" - -#include <guichan/color.hpp> - -#include <algorithm> -#include <cmath> - -#include "debug.h" - -static const float SIN45 = 0.707106781f; - -class Graphics; -class Image; - -int Particle::particleCount = 0; -int Particle::maxCount = 0; -int Particle::fastPhysics = 0; -int Particle::emitterSkip = 1; -bool Particle::enabled = true; -const float Particle::PARTICLE_SKY = 800.0f; - -Particle::Particle(Map *const map) : - Actor(), - mAlpha(1.0f), - mLifetimeLeft(-1), - mLifetimePast(0), - mFadeOut(0), - mFadeIn(0), - mVelocity(), - mAlive(ALIVE), - mChildEmitters(), - mChildParticles(), - 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) -{ - setMap(map); - Particle::particleCount++; -} - -Particle::~Particle() -{ - // Delete child emitters and child particles - clear(); - Particle::particleCount--; -} - -void Particle::setupEngine() -{ - Particle::maxCount = config.getIntValue("particleMaxCount"); - Particle::fastPhysics = config.getIntValue("particleFastPhysics"); - Particle::emitterSkip = config.getIntValue("particleEmitterSkip") + 1; - if (!Particle::emitterSkip) - Particle::emitterSkip = 1; - Particle::enabled = config.getBoolValue("particleeffects"); - disableAutoDelete(); - logger->log1("Particle engine set up"); -} - -bool Particle::draw(Graphics *const, const int, const int) const -{ - return false; -} - -bool Particle::update() -{ - if (!mMap) - return false; - - if (mLifetimeLeft == 0 && mAlive == ALIVE) - mAlive = DEAD_TIMEOUT; - - const Vector oldPos = mPos; - - if (mAlive == ALIVE) - { - // calculate particle movement - if (mMomentum != 1.0f) - mVelocity *= mMomentum; - - if (mTarget && mAcceleration != 0.0f) - { - Vector dist = mPos - mTarget->mPos; - dist.x *= SIN45; - float invHypotenuse; - - switch (Particle::fastPhysics) - { - case 1: - invHypotenuse = fastInvSqrt( - dist.x * dist.x + dist.y * dist.y + dist.z * dist.z); - break; - case 2: - if (!dist.x) - { - 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; - default: - invHypotenuse = 1.0f / static_cast<float>(sqrt( - dist.x * dist.x + dist.y * dist.y + dist.z * dist.z)); - break; - } - - if (invHypotenuse) - { - if (mInvDieDistance > 0.0f && invHypotenuse > mInvDieDistance) - mAlive = DEAD_IMPACT; - const float accFactor = invHypotenuse * mAcceleration; - mVelocity -= dist * accFactor; - } - } - - if (mRandomness > 0) - { - mVelocity.x += static_cast<float>((rand() % mRandomness - rand() - % mRandomness)) / 1000.0f; - mVelocity.y += static_cast<float>((rand() % mRandomness - rand() - % mRandomness)) / 1000.0f; - mVelocity.z += static_cast<float>((rand() % mRandomness - rand() - % 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 (mLifetimeLeft > 0) - mLifetimeLeft--; - - mLifetimePast++; - - if (mPos.z < 0.0f) - { - if (mBounce > 0.0f) - { - mPos.z *= -mBounce; - mVelocity *= mBounce; - mVelocity.z = -mVelocity.z; - } - else - { - mAlive = DEAD_FLOOR; - } - } - else if (mPos.z > PARTICLE_SKY) - { - mAlive = DEAD_SKY; - } - - // Update child emitters - if (Particle::emitterSkip && (mLifetimePast - 1) - % Particle::emitterSkip == 0) - { - FOR_EACH (EmitterConstIterator, e, mChildEmitters) - { - Particles newParticles = (*e)->createParticles(mLifetimePast); - FOR_EACH (ParticleConstIterator, it, newParticles) - { - Particle *const p = *it; - p->moveBy(mPos); - mChildParticles.push_back(p); - } - } - } - } - - // create death effect when the particle died - if (mAlive != ALIVE && mAlive != DEAD_LONG_AGO) - { - if ((mAlive & mDeathEffectConditions) > 0x00 && !mDeathEffect.empty()) - { - Particle *const deathEffect = particleEngine->addEffect( - mDeathEffect, 0, 0); - if (deathEffect) - deathEffect->moveBy(mPos); - } - mAlive = DEAD_LONG_AGO; - } - - const Vector change = mPos - oldPos; - - // Update child particles - - for (ParticleIterator p = mChildParticles.begin(), - p2 = mChildParticles.end(); p != p2; ) - { - Particle *const particle = *p; - // move particle with its parent if desired - if (particle->mFollow) - particle->moveBy(change); - - // update particle - if (particle->update()) - { - ++p; - } - else - { - delete particle; - p = mChildParticles.erase(p); - } - } - if (mAlive != ALIVE && mChildParticles.empty() && mAutoDelete) - return false; - - return true; -} - -void Particle::moveBy(const Vector &change) -{ - mPos += change; - FOR_EACH (ParticleConstIterator, p, mChildParticles) - { - Particle *const particle = *p; - if (particle->mFollow) - particle->moveBy(change); - } -} - -void Particle::moveTo(const float x, const float y) -{ - moveTo(Vector(x, y, mPos.z)); -} - -Particle *Particle::createChild() -{ - Particle *const newParticle = new Particle(mMap); - mChildParticles.push_back(newParticle); - return newParticle; -} - -Particle *Particle::addEffect(const std::string &particleEffectFile, - const int pixelX, const int pixelY, - const int rotation) -{ - Particle *newParticle = nullptr; - - const size_t pos = particleEffectFile.find('|'); - const std::string dyePalettes = (pos != std::string::npos) - ? particleEffectFile.substr(pos + 1) : ""; - XML::Document doc(particleEffectFile.substr(0, pos)); - const XmlNodePtr rootNode = doc.rootNode(); - - if (!rootNode || !xmlNameEqual(rootNode, "effect")) - { - logger->log("Error loading particle: %s", particleEffectFile.c_str()); - return nullptr; - } - - ResourceManager *const resman = ResourceManager::getInstance(); - - // 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"))) - { - newParticle = new AnimationParticle(mMap, node, dyePalettes); - } - // Rotational - else if ((node = XML::findFirstChildByName( - effectChildNode, "rotation"))) - { - newParticle = new RotationalParticle(mMap, node, dyePalettes); - } - // Image - else if ((node = XML::findFirstChildByName(effectChildNode, "image"))) - { - std::string imageSrc = reinterpret_cast<const char*>( - node->xmlChildrenNode->content); - if (!imageSrc.empty() && !dyePalettes.empty()) - Dye::instantiate(imageSrc, dyePalettes); - Image *const img = resman->getImage(imageSrc); - - newParticle = new ImageParticle(mMap, img); - } - // Other - else - { - newParticle = new Particle(mMap); - } - - // Read and set the basic properties of the particle - const float offsetX = static_cast<float>(XML::getFloatProperty( - effectChildNode, "position-x", 0)); - const float offsetY = static_cast<float>(XML::getFloatProperty( - effectChildNode, "position-y", 0)); - const float offsetZ = static_cast<float>(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 *const newEmitter = new ParticleEmitter( - emitterNode, newParticle, mMap, rotation, dyePalettes); - newParticle->addEmitter(newEmitter); - } - else if (xmlNameEqual(emitterNode, "deatheffect")) - { - const std::string deathEffect = reinterpret_cast<const char*>( - emitterNode->xmlChildrenNode->content); - - char deathEffectConditions = 0x00; - if (XML::getBoolProperty(emitterNode, "on-floor", true)) - { - deathEffectConditions += static_cast<signed char>( - Particle::DEAD_FLOOR); - } - if (XML::getBoolProperty(emitterNode, "on-sky", true)) - { - deathEffectConditions += static_cast<signed char>( - Particle::DEAD_SKY); - } - if (XML::getBoolProperty(emitterNode, "on-other", false)) - { - deathEffectConditions += static_cast<signed char>( - Particle::DEAD_OTHER); - } - if (XML::getBoolProperty(emitterNode, "on-impact", true)) - { - deathEffectConditions += static_cast<signed char>( - Particle::DEAD_IMPACT); - } - if (XML::getBoolProperty(emitterNode, "on-timeout", true)) - { - deathEffectConditions += static_cast<signed char>( - Particle::DEAD_TIMEOUT); - } - newParticle->setDeathEffect( - deathEffect, deathEffectConditions); - } - } - - mChildParticles.push_back(newParticle); - } - - return newParticle; -} - -Particle *Particle::addTextSplashEffect(const std::string &text, - const int x, const int y, - const gcn::Color *const color, - gcn::Font *const font, - const bool outline) -{ - Particle *const newParticle = new TextParticle( - mMap, text, color, font, outline); - 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 *Particle::addTextRiseFadeOutEffect(const std::string &text, - const int x, const int y, - const gcn::Color *const color, - gcn::Font *const font, - const bool outline) -{ - Particle *const newParticle = new TextParticle( - mMap, text, color, font, outline); - 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 Particle::adjustEmitterSize(const int w, const int h) -{ - if (mAllowSizeAdjust) - { - FOR_EACH (EmitterConstIterator, e, mChildEmitters) - (*e)->adjustSize(w, h); - } -} - -void Particle::clear() -{ - delete_all(mChildEmitters); - mChildEmitters.clear(); - - delete_all(mChildParticles); - mChildParticles.clear(); -} |