Exemplo n.º 1
0
ParticleEmitter::ParticleEmitter(const xmlNodePtr &emitterNode, Particle *target,
                                 Map *map, const int rotation):
    mOutputPauseLeft(0),
    mParticleImage(0)
{
    mMap = map;
    mParticleTarget = target;

    // 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);
    mParticleFollow = false;
    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);

    for_each_xml_child_node(propertyNode, emitterNode)
    {
        if (xmlStrEqual(propertyNode->name, BAD_CAST "property"))
        {
            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)
                {
                    ResourceManager *resman = ResourceManager::getInstance();
                    mParticleImage = resman->getImage(image);
                }
            }
            else if (name == "horizontal-angle")
            {
                mParticleAngleHorizontal = readParticleEmitterProp(propertyNode, 0.0f);
                mParticleAngleHorizontal.minVal += rotation;
                mParticleAngleHorizontal.minVal *= DEG_RAD_FACTOR;
                mParticleAngleHorizontal.maxVal += 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")
                mParticleFollow = true;
            else
            {
                logger->log("Particle Engine: Warning, unknown emitter property \"%s\"",
                            name.c_str());
            }
        }
        else if (xmlStrEqual(propertyNode->name, BAD_CAST "emitter"))
        {
            ParticleEmitter newEmitter(propertyNode, mParticleTarget, map);
            mParticleChildEmitters.push_back(newEmitter);
        }
        else if (xmlStrEqual(propertyNode->name, BAD_CAST "rotation"))
        {
            ImageSet *imageset = ResourceManager::getInstance()->getImageSet(
                XML::getProperty(propertyNode, "imageset", ""),
                XML::getProperty(propertyNode, "width", 0),
                XML::getProperty(propertyNode, "height", 0));

            // Get animation frames
            for_each_xml_child_node(frameNode, propertyNode)
            {
                int delay = XML::getProperty(frameNode, "delay", 0);
                int offsetX = XML::getProperty(frameNode, "offsetX", 0);
                int offsetY = XML::getProperty(frameNode, "offsetY", 0);
                offsetY -= imageset->getHeight() - mMap->getTileHeight();
                offsetX -= (imageset->getWidth() - mMap->getTileWidth()) / 2;

                if (xmlStrEqual(frameNode->name, BAD_CAST "frame"))
                {
                    int index = XML::getProperty(frameNode, "index", -1);

                    if (index < 0)
                    {
                        logger->log("No valid value for 'index'");
                        continue;
                    }

                    Image *img = imageset->get(index);

                    if (!img)
                    {
                        logger->log("No image at index %d", index);
                        continue;
                    }

                    mParticleRotation.addFrame(img, delay, offsetX, offsetY);
                }
                else if (xmlStrEqual(frameNode->name, BAD_CAST "sequence"))
                {
                    int start = XML::getProperty(frameNode, "start", -1);
                    int end = XML::getProperty(frameNode, "end", -1);

                    if (start < 0 || end < 0)
                    {
                        logger->log("No valid value for 'start' or 'end'");
                        continue;
                    }

                    while (end >= start)
                    {
                        Image *img = imageset->get(start);

                        if (!img)
                        {
                            logger->log("No image at index %d", start);
                            continue;
                        }

                        mParticleRotation.addFrame(img, delay, offsetX, offsetY);
                        start++;
                    }
                }
                else if (xmlStrEqual(frameNode->name, BAD_CAST "end"))
                    mParticleRotation.addTerminator();

            } // for frameNode
        }
Exemplo n.º 2
0
ParticleEmitter::ParticleEmitter(const XmlNodePtrConst emitterNode,
                                 Particle *const target,
                                 Map *const map, const int rotation,
                                 const std::string& dyePalettes) :
    mParticleTarget(target),
    mMap(map),
    mParticleImage(nullptr),
    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);

    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)
                {
                    if (!dyePalettes.empty())
                        Dye::instantiate(image, dyePalettes);

                    ResourceManager *const resman
                        = ResourceManager::getInstance();
                    mParticleImage = resman->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)
                {
                    if (!dyePalettes.empty())
                        Dye::instantiate(image, dyePalettes);

                    ResourceManager *const resman
                        = ResourceManager::getInstance();
                    Image *img = resman->getImage(image);
                    if (img)
                    {
                        mParticleImage = resman->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)
            {
                logger->log1("Error: no valid imageset");
                continue;
            }
            mTempSets.push_back(imageset);

            Animation &animation = (xmlNameEqual(propertyNode, "rotation")) ?
                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)
                    {
                        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)
                        {
                            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"))