scummvm/engines/wintermute/base/particles/part_emitter.cpp
Einar Johan Trøan Sømåen 7027741de7 WINTERMUTE: Fix warnings
2012-08-31 20:00:41 +02:00

1257 lines
40 KiB
C++

/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* 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 (at your option) 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, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
/*
* This file is based on WME Lite.
* http://dead-code.org/redir.php?target=wmelite
* Copyright (c) 2011 Jan Nedoma
*/
#include "engines/wintermute/base/particles/part_emitter.h"
#include "engines/wintermute/base/particles/part_particle.h"
#include "engines/wintermute/math/vector2.h"
#include "engines/wintermute/math/matrix4.h"
#include "engines/wintermute/base/scriptables/script_value.h"
#include "engines/wintermute/base/scriptables/script_stack.h"
#include "engines/wintermute/base/base_game.h"
#include "engines/wintermute/base/base_region.h"
#include "engines/wintermute/base/base_file_manager.h"
#include "engines/wintermute/utils/utils.h"
#include "engines/wintermute/platform_osystem.h"
#include "common/str.h"
#include "common/math.h"
namespace Wintermute {
IMPLEMENT_PERSISTENT(PartEmitter, false)
//////////////////////////////////////////////////////////////////////////
PartEmitter::PartEmitter(BaseGame *inGame, BaseScriptHolder *owner) : BaseObject(inGame) {
_width = _height = 0;
BasePlatform::setRectEmpty(&_border);
_borderThicknessLeft = _borderThicknessRight = _borderThicknessTop = _borderThicknessBottom = 0;
_angle1 = _angle2 = 0;
_velocity1 = _velocity2 = 0.0f;
_velocityZBased = false;
_scale1 = _scale2 = 100.0f;
_scaleZBased = false;
_maxParticles = 100;
_lifeTime1 = _lifeTime2 = 1000;
_lifeTimeZBased = false;
_lastGenTime = 0;
_genInterval = 0;
_genAmount = 1;
_overheadTime = 0;
_running = false;
_maxBatches = 0;
_batchesGenerated = 0;
_fadeInTime = _fadeOutTime = 0;
_alpha1 = _alpha2 = 255;
_alphaTimeBased = false;
_rotation1 = _rotation2 = 0.0f;
_angVelocity1 = _angVelocity2 = 0.0f;
_growthRate1 = _growthRate2 = 0.0f;
_exponentialGrowth = false;
_useRegion = false;
_emitEvent = NULL;
_owner = owner;
}
//////////////////////////////////////////////////////////////////////////
PartEmitter::~PartEmitter(void) {
for (uint32 i = 0; i < _particles.size(); i++) {
delete _particles[i];
}
_particles.clear();
for (uint32 i = 0; i < _forces.size(); i++) {
delete _forces[i];
}
_forces.clear();
for (uint32 i = 0; i < _sprites.size(); i++) {
delete[] _sprites[i];
}
_sprites.clear();
delete[] _emitEvent;
_emitEvent = NULL;
}
//////////////////////////////////////////////////////////////////////////
bool PartEmitter::addSprite(const char *filename) {
if (!filename) {
return STATUS_FAILED;
}
// do we already have the file?
for (uint32 i = 0; i < _sprites.size(); i++) {
if (scumm_stricmp(filename, _sprites[i]) == 0) {
return STATUS_OK;
}
}
// check if file exists
Common::SeekableReadStream *File = BaseFileManager::getEngineInstance()->openFile(filename);
if (!File) {
_gameRef->LOG(0, "Sprite '%s' not found", filename);
return STATUS_FAILED;
} else {
BaseFileManager::getEngineInstance()->closeFile(File);
}
char *str = new char[strlen(filename) + 1];
strcpy(str, filename);
_sprites.add(str);
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
bool PartEmitter::removeSprite(const char *filename) {
for (uint32 i = 0; i < _sprites.size(); i++) {
if (scumm_stricmp(filename, _sprites[i]) == 0) {
delete[] _sprites[i];
_sprites.remove_at(i);
return STATUS_OK;
}
}
return STATUS_FAILED;
}
//////////////////////////////////////////////////////////////////////////
bool PartEmitter::initParticle(PartParticle *particle, uint32 currentTime, uint32 timerDelta) {
if (!particle) {
return STATUS_FAILED;
}
if (_sprites.size() == 0) {
return STATUS_FAILED;
}
int posX = BaseUtils::randomInt(_posX, _posX + _width);
int posY = BaseUtils::randomInt(_posY, _posY + _height);
float posZ = BaseUtils::randomFloat(0.0f, 100.0f);
float velocity;
if (_velocityZBased) {
velocity = _velocity1 + posZ * (_velocity2 - _velocity1) / 100;
} else {
velocity = BaseUtils::randomFloat(_velocity1, _velocity2);
}
float scale;
if (_scaleZBased) {
scale = _scale1 + posZ * (_scale2 - _scale1) / 100;
} else {
scale = BaseUtils::randomFloat(_scale1, _scale2);
}
int lifeTime;
if (_lifeTimeZBased) {
lifeTime = (int)(_lifeTime2 - posZ * (_lifeTime2 - _lifeTime1) / 100);
} else {
lifeTime = BaseUtils::randomInt(_lifeTime1, _lifeTime2);
}
float angle = BaseUtils::randomAngle(_angle1, _angle2);
int spriteIndex = BaseUtils::randomInt(0, _sprites.size() - 1);
float rotation = BaseUtils::randomAngle(_rotation1, _rotation2);
float angVelocity = BaseUtils::randomFloat(_angVelocity1, _angVelocity2);
float growthRate = BaseUtils::randomFloat(_growthRate1, _growthRate2);
if (!BasePlatform::isRectEmpty(&_border)) {
int thicknessLeft = (int)(_borderThicknessLeft - (float)_borderThicknessLeft * posZ / 100.0f);
int thicknessRight = (int)(_borderThicknessRight - (float)_borderThicknessRight * posZ / 100.0f);
int thicknessTop = (int)(_borderThicknessTop - (float)_borderThicknessTop * posZ / 100.0f);
int thicknessBottom = (int)(_borderThicknessBottom - (float)_borderThicknessBottom * posZ / 100.0f);
particle->_border = _border;
particle->_border.left += thicknessLeft;
particle->_border.right -= thicknessRight;
particle->_border.top += thicknessTop;
particle->_border.bottom -= thicknessBottom;
}
Vector2 vecPos((float)posX, (float)posY);
Vector2 vecVel(0, velocity);
Matrix4 matRot;
matRot.rotationZ(Common::deg2rad(BaseUtils::normalizeAngle(angle - 180)));
matRot.transformVector2(vecVel);
if (_alphaTimeBased) {
particle->_alpha1 = _alpha1;
particle->_alpha2 = _alpha2;
} else {
int alpha = BaseUtils::randomInt(_alpha1, _alpha2);
particle->_alpha1 = alpha;
particle->_alpha2 = alpha;
}
particle->_creationTime = currentTime;
particle->_pos = vecPos;
particle->_posZ = posZ;
particle->_velocity = vecVel;
particle->_scale = scale;
particle->_lifeTime = lifeTime;
particle->_rotation = rotation;
particle->_angVelocity = angVelocity;
particle->_growthRate = growthRate;
particle->_exponentialGrowth = _exponentialGrowth;
particle->_isDead = DID_FAIL(particle->setSprite(_sprites[spriteIndex]));
particle->fadeIn(currentTime, _fadeInTime);
if (particle->_isDead) {
return STATUS_FAILED;
} else {
return STATUS_OK;
}
}
//////////////////////////////////////////////////////////////////////////
bool PartEmitter::update() {
if (!_running) {
return STATUS_OK;
} else {
return updateInternal(_gameRef->_timer, _gameRef->_timerDelta);
}
}
//////////////////////////////////////////////////////////////////////////
bool PartEmitter::updateInternal(uint32 currentTime, uint32 timerDelta) {
int numLive = 0;
for (uint32 i = 0; i < _particles.size(); i++) {
_particles[i]->update(this, currentTime, timerDelta);
if (!_particles[i]->_isDead) {
numLive++;
}
}
// we're understaffed
if (numLive < _maxParticles) {
bool needsSort = false;
if ((int)(currentTime - _lastGenTime) > _genInterval) {
_lastGenTime = currentTime;
_batchesGenerated++;
if (_maxBatches > 0 && _batchesGenerated > _maxBatches) {
return STATUS_OK;
}
int toGen = MIN(_genAmount, _maxParticles - numLive);
while (toGen > 0) {
int firstDeadIndex = -1;
for (uint32 i = 0; i < _particles.size(); i++) {
if (_particles[i]->_isDead) {
firstDeadIndex = i;
break;
}
}
PartParticle *particle;
if (firstDeadIndex >= 0) {
particle = _particles[firstDeadIndex];
} else {
particle = new PartParticle(_gameRef);
_particles.add(particle);
}
initParticle(particle, currentTime, timerDelta);
needsSort = true;
toGen--;
}
}
if (needsSort && (_scaleZBased || _velocityZBased || _lifeTimeZBased)) {
sortParticlesByZ();
}
// we actually generated some particles and we're not in fast-forward mode
if (needsSort && _overheadTime == 0) {
if (_owner && _emitEvent) {
_owner->applyEvent(_emitEvent);
}
}
}
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
bool PartEmitter::display(BaseRegion *region) {
if (_sprites.size() <= 1) {
_gameRef->_renderer->startSpriteBatch();
}
for (uint32 i = 0; i < _particles.size(); i++) {
if (region != NULL && _useRegion) {
if (!region->pointInRegion((int)_particles[i]->_pos.x, (int)_particles[i]->_pos.y)) {
continue;
}
}
_particles[i]->display(this);
}
if (_sprites.size() <= 1) {
_gameRef->_renderer->endSpriteBatch();
}
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
bool PartEmitter::start() {
for (uint32 i = 0; i < _particles.size(); i++) {
_particles[i]->_isDead = true;
}
_running = true;
_batchesGenerated = 0;
if (_overheadTime > 0) {
uint32 delta = 500;
int steps = _overheadTime / delta;
uint32 currentTime = _gameRef->_timer - _overheadTime;
for (int i = 0; i < steps; i++) {
updateInternal(currentTime, delta);
currentTime += delta;
}
_overheadTime = 0;
}
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
bool PartEmitter::sortParticlesByZ() {
// sort particles by _posY
Common::sort(_particles.begin(), _particles.end(), PartEmitter::compareZ);
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
int PartEmitter::compareZ(const void *obj1, const void *obj2) {
const PartParticle *p1 = *(const PartParticle *const *)obj1;
const PartParticle *p2 = *(const PartParticle *const *)obj2;
if (p1->_posZ < p2->_posZ) {
return -1;
} else if (p1->_posZ > p2->_posZ) {
return 1;
} else {
return 0;
}
}
//////////////////////////////////////////////////////////////////////////
bool PartEmitter::setBorder(int x, int y, int width, int height) {
BasePlatform::setRect(&_border, x, y, x + width, y + height);
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
bool PartEmitter::setBorderThickness(int thicknessLeft, int thicknessRight, int thicknessTop, int thicknessBottom) {
_borderThicknessLeft = thicknessLeft;
_borderThicknessRight = thicknessRight;
_borderThicknessTop = thicknessTop;
_borderThicknessBottom = thicknessBottom;
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
PartForce *PartEmitter::addForceByName(const Common::String &name) {
PartForce *force = NULL;
for (uint32 i = 0; i < _forces.size(); i++) {
if (scumm_stricmp(name.c_str(), _forces[i]->getName()) == 0) {
force = _forces[i];
break;
}
}
if (!force) {
force = new PartForce(_gameRef);
if (force) {
force->setName(name.c_str());
_forces.add(force);
}
}
return force;
}
//////////////////////////////////////////////////////////////////////////
bool PartEmitter::addForce(const Common::String &name, PartForce::TForceType type, int posX, int posY, float angle, float strength) {
PartForce *force = addForceByName(name);
if (!force) {
return STATUS_FAILED;
}
force->_type = type;
force->_pos = Vector2(posX, posY);
force->_direction = Vector2(0, strength);
Matrix4 matRot;
matRot.rotationZ(Common::deg2rad(BaseUtils::normalizeAngle(angle - 180)));
matRot.transformVector2(force->_direction);
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
bool PartEmitter::removeForce(const Common::String &name) {
for (uint32 i = 0; i < _forces.size(); i++) {
if (scumm_stricmp(name.c_str(), _forces[i]->getName()) == 0) {
delete _forces[i];
_forces.remove_at(i);
return STATUS_OK;
}
}
return STATUS_FAILED;
}
//////////////////////////////////////////////////////////////////////////
// high level scripting interface
//////////////////////////////////////////////////////////////////////////
bool PartEmitter::scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack, const char *name) {
//////////////////////////////////////////////////////////////////////////
// SetBorder
//////////////////////////////////////////////////////////////////////////
if (strcmp(name, "SetBorder") == 0) {
stack->correctParams(4);
int borderX = stack->pop()->getInt();
int borderY = stack->pop()->getInt();
int borderWidth = stack->pop()->getInt();
int borderHeight = stack->pop()->getInt();
stack->pushBool(DID_SUCCEED(setBorder(borderX, borderY, borderWidth, borderHeight)));
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
// SetBorderThickness
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "SetBorderThickness") == 0) {
stack->correctParams(4);
int left = stack->pop()->getInt();
int right = stack->pop()->getInt();
int top = stack->pop()->getInt();
int bottom = stack->pop()->getInt();
stack->pushBool(DID_SUCCEED(setBorderThickness(left, right, top, bottom)));
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
// AddSprite
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "AddSprite") == 0) {
stack->correctParams(1);
const char *spriteFile = stack->pop()->getString();
stack->pushBool(DID_SUCCEED(addSprite(spriteFile)));
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
// RemoveSprite
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "RemoveSprite") == 0) {
stack->correctParams(1);
const char *spriteFile = stack->pop()->getString();
stack->pushBool(DID_SUCCEED(removeSprite(spriteFile)));
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
// Start
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "Start") == 0) {
stack->correctParams(1);
_overheadTime = stack->pop()->getInt();
stack->pushBool(DID_SUCCEED(start()));
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
// Stop
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "Stop") == 0) {
stack->correctParams(0);
for (uint32 i = 0; i < _particles.size(); i++) {
delete _particles[i];
}
_particles.clear();
_running = false;
stack->pushBool(true);
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
// Pause
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "Pause") == 0) {
stack->correctParams(0);
_running = false;
stack->pushBool(true);
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
// Resume
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "Resume") == 0) {
stack->correctParams(0);
_running = true;
stack->pushBool(true);
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
// AddGlobalForce
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "AddGlobalForce") == 0) {
stack->correctParams(3);
const char *forceName = stack->pop()->getString();
float angle = stack->pop()->getFloat();
float strength = stack->pop()->getFloat();
stack->pushBool(DID_SUCCEED(addForce(forceName, PartForce::FORCE_GLOBAL, 0, 0, angle, strength)));
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
// AddPointForce
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "AddPointForce") == 0) {
stack->correctParams(5);
const char *forceName = stack->pop()->getString();
int posX = stack->pop()->getInt();
int posY = stack->pop()->getInt();
float angle = stack->pop()->getFloat();
float strength = stack->pop()->getFloat();
stack->pushBool(DID_SUCCEED(addForce(forceName, PartForce::FORCE_GLOBAL, posX, posY, angle, strength)));
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
// RemoveForce
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "RemoveForce") == 0) {
stack->correctParams(1);
const char *forceName = stack->pop()->getString();
stack->pushBool(DID_SUCCEED(removeForce(forceName)));
return STATUS_OK;
} else {
return BaseObject::scCallMethod(script, stack, thisStack, name);
}
}
//////////////////////////////////////////////////////////////////////////
ScValue *PartEmitter::scGetProperty(const char *name) {
_scValue->setNULL();
//////////////////////////////////////////////////////////////////////////
// Type
//////////////////////////////////////////////////////////////////////////
if (strcmp(name, "Type") == 0) {
_scValue->setString("particle-emitter");
return _scValue;
}
//////////////////////////////////////////////////////////////////////////
// X
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "X") == 0) {
_scValue->setInt(_posX);
return _scValue;
}
//////////////////////////////////////////////////////////////////////////
// Y
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "Y") == 0) {
_scValue->setInt(_posY);
return _scValue;
}
//////////////////////////////////////////////////////////////////////////
// Width
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "Width") == 0) {
_scValue->setInt(_width);
return _scValue;
}
//////////////////////////////////////////////////////////////////////////
// Height
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "Height") == 0) {
_scValue->setInt(_height);
return _scValue;
}
//////////////////////////////////////////////////////////////////////////
// Scale1
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "Scale1") == 0) {
_scValue->setFloat(_scale1);
return _scValue;
}
//////////////////////////////////////////////////////////////////////////
// Scale2
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "Scale2") == 0) {
_scValue->setFloat(_scale2);
return _scValue;
}
//////////////////////////////////////////////////////////////////////////
// ScaleZBased
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "ScaleZBased") == 0) {
_scValue->setBool(_scaleZBased);
return _scValue;
}
//////////////////////////////////////////////////////////////////////////
// Velocity1
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "Velocity1") == 0) {
_scValue->setFloat(_velocity1);
return _scValue;
}
//////////////////////////////////////////////////////////////////////////
// Velocity2
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "Velocity2") == 0) {
_scValue->setFloat(_velocity2);
return _scValue;
}
//////////////////////////////////////////////////////////////////////////
// VelocityZBased
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "VelocityZBased") == 0) {
_scValue->setBool(_velocityZBased);
return _scValue;
}
//////////////////////////////////////////////////////////////////////////
// LifeTime1
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "LifeTime1") == 0) {
_scValue->setInt(_lifeTime1);
return _scValue;
}
//////////////////////////////////////////////////////////////////////////
// LifeTime2
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "LifeTime2") == 0) {
_scValue->setInt(_lifeTime2);
return _scValue;
}
//////////////////////////////////////////////////////////////////////////
// LifeTimeZBased
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "LifeTimeZBased") == 0) {
_scValue->setBool(_lifeTimeZBased);
return _scValue;
}
//////////////////////////////////////////////////////////////////////////
// Angle1
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "Angle1") == 0) {
_scValue->setInt(_angle1);
return _scValue;
}
//////////////////////////////////////////////////////////////////////////
// Angle2
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "Angle2") == 0) {
_scValue->setInt(_angle2);
return _scValue;
}
//////////////////////////////////////////////////////////////////////////
// AngVelocity1
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "AngVelocity1") == 0) {
_scValue->setFloat(_angVelocity1);
return _scValue;
}
//////////////////////////////////////////////////////////////////////////
// AngVelocity2
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "AngVelocity2") == 0) {
_scValue->setFloat(_angVelocity2);
return _scValue;
}
//////////////////////////////////////////////////////////////////////////
// Rotation1
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "Rotation1") == 0) {
_scValue->setFloat(_rotation1);
return _scValue;
}
//////////////////////////////////////////////////////////////////////////
// Rotation2
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "Rotation2") == 0) {
_scValue->setFloat(_rotation2);
return _scValue;
}
//////////////////////////////////////////////////////////////////////////
// Alpha1
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "Alpha1") == 0) {
_scValue->setInt(_alpha1);
return _scValue;
}
//////////////////////////////////////////////////////////////////////////
// Alpha2
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "Alpha2") == 0) {
_scValue->setInt(_alpha2);
return _scValue;
}
//////////////////////////////////////////////////////////////////////////
// AlphaTimeBased
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "AlphaTimeBased") == 0) {
_scValue->setBool(_alphaTimeBased);
return _scValue;
}
//////////////////////////////////////////////////////////////////////////
// MaxParticles
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "MaxParticles") == 0) {
_scValue->setInt(_maxParticles);
return _scValue;
}
//////////////////////////////////////////////////////////////////////////
// NumLiveParticles (RO)
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "NumLiveParticles") == 0) {
int numAlive = 0;
for (uint32 i = 0; i < _particles.size(); i++) {
if (_particles[i] && !_particles[i]->_isDead) {
numAlive++;
}
}
_scValue->setInt(numAlive);
return _scValue;
}
//////////////////////////////////////////////////////////////////////////
// GenerationInterval
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "GenerationInterval") == 0) {
_scValue->setInt(_genInterval);
return _scValue;
}
//////////////////////////////////////////////////////////////////////////
// GenerationAmount
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "GenerationAmount") == 0) {
_scValue->setInt(_genAmount);
return _scValue;
}
//////////////////////////////////////////////////////////////////////////
// MaxBatches
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "MaxBatches") == 0) {
_scValue->setInt(_maxBatches);
return _scValue;
}
//////////////////////////////////////////////////////////////////////////
// FadeInTime
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "FadeInTime") == 0) {
_scValue->setInt(_fadeInTime);
return _scValue;
}
//////////////////////////////////////////////////////////////////////////
// FadeOutTime
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "FadeOutTime") == 0) {
_scValue->setInt(_fadeOutTime);
return _scValue;
}
//////////////////////////////////////////////////////////////////////////
// GrowthRate1
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "GrowthRate1") == 0) {
_scValue->setFloat(_growthRate1);
return _scValue;
}
//////////////////////////////////////////////////////////////////////////
// GrowthRate2
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "GrowthRate2") == 0) {
_scValue->setFloat(_growthRate2);
return _scValue;
}
//////////////////////////////////////////////////////////////////////////
// ExponentialGrowth
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "ExponentialGrowth") == 0) {
_scValue->setBool(_exponentialGrowth);
return _scValue;
}
//////////////////////////////////////////////////////////////////////////
// UseRegion
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "UseRegion") == 0) {
_scValue->setBool(_useRegion);
return _scValue;
}
//////////////////////////////////////////////////////////////////////////
// EmitEvent
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "EmitEvent") == 0) {
if (!_emitEvent) {
_scValue->setNULL();
} else {
_scValue->setString(_emitEvent);
}
return _scValue;
} else {
return BaseObject::scGetProperty(name);
}
}
//////////////////////////////////////////////////////////////////////////
bool PartEmitter::scSetProperty(const char *name, ScValue *value) {
//////////////////////////////////////////////////////////////////////////
// X
//////////////////////////////////////////////////////////////////////////
if (strcmp(name, "X") == 0) {
_posX = value->getInt();
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
// Y
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "Y") == 0) {
_posY = value->getInt();
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
// Width
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "Width") == 0) {
_width = value->getInt();
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
// Height
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "Height") == 0) {
_height = value->getInt();
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
// Scale1
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "Scale1") == 0) {
_scale1 = value->getFloat();
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
// Scale2
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "Scale2") == 0) {
_scale2 = value->getFloat();
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
// ScaleZBased
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "ScaleZBased") == 0) {
_scaleZBased = value->getBool();
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
// Velocity1
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "Velocity1") == 0) {
_velocity1 = value->getFloat();
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
// Velocity2
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "Velocity2") == 0) {
_velocity2 = value->getFloat();
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
// VelocityZBased
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "VelocityZBased") == 0) {
_velocityZBased = value->getBool();
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
// LifeTime1
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "LifeTime1") == 0) {
_lifeTime1 = value->getInt();
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
// LifeTime2
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "LifeTime2") == 0) {
_lifeTime2 = value->getInt();
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
// LifeTimeZBased
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "LifeTimeZBased") == 0) {
_lifeTimeZBased = value->getBool();
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
// Angle1
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "Angle1") == 0) {
_angle1 = value->getInt();
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
// Angle2
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "Angle2") == 0) {
_angle2 = value->getInt();
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
// AngVelocity1
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "AngVelocity1") == 0) {
_angVelocity1 = value->getFloat();
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
// AngVelocity2
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "AngVelocity2") == 0) {
_angVelocity2 = value->getFloat();
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
// Rotation1
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "Rotation1") == 0) {
_rotation1 = value->getFloat();
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
// Rotation2
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "Rotation2") == 0) {
_rotation2 = value->getFloat();
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
// Alpha1
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "Alpha1") == 0) {
_alpha1 = value->getInt();
if (_alpha1 < 0) {
_alpha1 = 0;
}
if (_alpha1 > 255) {
_alpha1 = 255;
}
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
// Alpha2
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "Alpha2") == 0) {
_alpha2 = value->getInt();
if (_alpha2 < 0) {
_alpha2 = 0;
}
if (_alpha2 > 255) {
_alpha2 = 255;
}
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
// AlphaTimeBased
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "AlphaTimeBased") == 0) {
_alphaTimeBased = value->getBool();
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
// MaxParticles
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "MaxParticles") == 0) {
_maxParticles = value->getInt();
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
// GenerationInterval
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "GenerationInterval") == 0) {
_genInterval = value->getInt();
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
// GenerationAmount
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "GenerationAmount") == 0) {
_genAmount = value->getInt();
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
// MaxBatches
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "MaxBatches") == 0) {
_maxBatches = value->getInt();
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
// FadeInTime
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "FadeInTime") == 0) {
_fadeInTime = value->getInt();
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
// FadeOutTime
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "FadeOutTime") == 0) {
_fadeOutTime = value->getInt();
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
// GrowthRate1
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "GrowthRate1") == 0) {
_growthRate1 = value->getFloat();
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
// GrowthRate2
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "GrowthRate2") == 0) {
_growthRate2 = value->getFloat();
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
// ExponentialGrowth
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "ExponentialGrowth") == 0) {
_exponentialGrowth = value->getBool();
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
// UseRegion
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "UseRegion") == 0) {
_useRegion = value->getBool();
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
// EmitEvent
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "EmitEvent") == 0) {
delete[] _emitEvent;
_emitEvent = NULL;
if (!value->isNULL()) {
BaseUtils::setString(&_emitEvent, value->getString());
}
return STATUS_OK;
} else {
return BaseObject::scSetProperty(name, value);
}
}
//////////////////////////////////////////////////////////////////////////
const char *PartEmitter::scToString() {
return "[particle emitter]";
}
//////////////////////////////////////////////////////////////////////////
bool PartEmitter::persist(BasePersistenceManager *persistMgr) {
BaseObject::persist(persistMgr);
persistMgr->transfer(TMEMBER(_width));
persistMgr->transfer(TMEMBER(_height));
persistMgr->transfer(TMEMBER(_angle1));
persistMgr->transfer(TMEMBER(_angle2));
persistMgr->transfer(TMEMBER(_velocity1));
persistMgr->transfer(TMEMBER(_velocity2));
persistMgr->transfer(TMEMBER(_velocityZBased));
persistMgr->transfer(TMEMBER(_scale1));
persistMgr->transfer(TMEMBER(_scale2));
persistMgr->transfer(TMEMBER(_scaleZBased));
persistMgr->transfer(TMEMBER(_maxParticles));
persistMgr->transfer(TMEMBER(_lifeTime1));
persistMgr->transfer(TMEMBER(_lifeTime2));
persistMgr->transfer(TMEMBER(_lifeTimeZBased));
persistMgr->transfer(TMEMBER(_genInterval));
persistMgr->transfer(TMEMBER(_genAmount));
persistMgr->transfer(TMEMBER(_running));
persistMgr->transfer(TMEMBER(_overheadTime));
persistMgr->transfer(TMEMBER(_border));
persistMgr->transfer(TMEMBER(_borderThicknessLeft));
persistMgr->transfer(TMEMBER(_borderThicknessRight));
persistMgr->transfer(TMEMBER(_borderThicknessTop));
persistMgr->transfer(TMEMBER(_borderThicknessBottom));
persistMgr->transfer(TMEMBER(_fadeInTime));
persistMgr->transfer(TMEMBER(_fadeOutTime));
persistMgr->transfer(TMEMBER(_alpha1));
persistMgr->transfer(TMEMBER(_alpha2));
persistMgr->transfer(TMEMBER(_alphaTimeBased));
persistMgr->transfer(TMEMBER(_angVelocity1));
persistMgr->transfer(TMEMBER(_angVelocity2));
persistMgr->transfer(TMEMBER(_rotation1));
persistMgr->transfer(TMEMBER(_rotation2));
persistMgr->transfer(TMEMBER(_growthRate1));
persistMgr->transfer(TMEMBER(_growthRate2));
persistMgr->transfer(TMEMBER(_exponentialGrowth));
persistMgr->transfer(TMEMBER(_useRegion));
persistMgr->transfer(TMEMBER_INT(_maxBatches));
persistMgr->transfer(TMEMBER_INT(_batchesGenerated));
persistMgr->transfer(TMEMBER(_emitEvent));
persistMgr->transfer(TMEMBER(_owner));
_sprites.persist(persistMgr);
uint32 numForces;
if (persistMgr->getIsSaving()) {
numForces = _forces.size();
persistMgr->transfer(TMEMBER(numForces));
for (uint32 i = 0; i < _forces.size(); i++) {
_forces[i]->persist(persistMgr);
}
} else {
persistMgr->transfer(TMEMBER(numForces));
for (uint32 i = 0; i < numForces; i++) {
PartForce *force = new PartForce(_gameRef);
force->persist(persistMgr);
_forces.add(force);
}
}
uint32 numParticles;
if (persistMgr->getIsSaving()) {
numParticles = _particles.size();
persistMgr->transfer(TMEMBER(numParticles));
for (uint32 i = 0; i < _particles.size(); i++) {
_particles[i]->persist(persistMgr);
}
} else {
persistMgr->transfer(TMEMBER(numParticles));
for (uint32 i = 0; i < numParticles; i++) {
PartParticle *particle = new PartParticle(_gameRef);
particle->persist(persistMgr);
_particles.add(particle);
}
}
return STATUS_OK;
}
} // end of namespace Wintermute