diff --git a/src/framework/const.h b/src/framework/const.h index fff914aa..5aef959e 100644 --- a/src/framework/const.h +++ b/src/framework/const.h @@ -27,6 +27,8 @@ namespace Fw { + static const double pi = 3.14159265; + // NOTE: AABBGGRR order enum GlobalColor : uint32 { alpha = 0x00000000, diff --git a/src/framework/graphics/particlesmanager.cpp b/src/framework/graphics/particlesmanager.cpp index f96faa53..b1af75dc 100644 --- a/src/framework/graphics/particlesmanager.cpp +++ b/src/framework/graphics/particlesmanager.cpp @@ -1,7 +1,25 @@ #include "particlesmanager.h" +#include +#include ParticlesManager g_particlesManager; +bool ParticlesManager::load(const std::string& filename) +{ + if(!g_resources.fileExists(filename)) + return false; + + try { + OTMLDocumentPtr doc = OTMLDocument::parse(filename); + //for(const OTMLNodePtr& child : doc->children()) + //m_confsMap[child->tag()] = child->value(); + return true; + } catch(Exception& e) { + logError("could not load configurations: ", e.what()); + return false; + } +} + void ParticlesManager::add(ParticlesSystem particleSystem) { // check it has emitters diff --git a/src/framework/graphics/particlesmanager.h b/src/framework/graphics/particlesmanager.h index cb6f8f0a..e057b4e4 100644 --- a/src/framework/graphics/particlesmanager.h +++ b/src/framework/graphics/particlesmanager.h @@ -2,6 +2,8 @@ class ParticlesManager { public: + bool load(const std::string& filename); + void add(ParticlesSystem particleSystem); void render(); diff --git a/src/framework/graphics/particlessystem.cpp b/src/framework/graphics/particlessystem.cpp index b4c12e61..2a60aa1a 100644 --- a/src/framework/graphics/particlessystem.cpp +++ b/src/framework/graphics/particlessystem.cpp @@ -29,9 +29,9 @@ void Particle::render() if(!m_texture) g_painter.drawFilledRect(m_rect); else { - g_painter.setCompositionMode(Painter::CompositionMode_AdditiveSource); + //g_painter.setCompositionMode(Painter::CompositionMode_AdditiveSource); g_painter.drawTexturedRect(m_rect, m_texture); - g_painter.setCompositionMode(Painter::CompositionMode_SourceOver); + //g_painter.setCompositionMode(Painter::CompositionMode_SourceOver); } } @@ -50,28 +50,33 @@ void Particle::update() m_iy + (m_vy * t / 1000.0) + (m_ay * t*t / (2.0 * 1000 * 1000))); } -ParticleEmitter::ParticleEmitter(const Point& position, float duration, int particlesPerSecond) +ParticleEmitter::ParticleEmitter(const Point& position, float duration, float burstRate, float burstCount) { m_position = position; m_duration = duration; - m_particlesPerSecond = particlesPerSecond; - m_createdParticles = 0; + m_burstRate = burstRate; m_burstCount = burstCount; + m_currentBurst = 0; m_startTicks = g_clock.ticks(); m_finished = false; - // particles default configuration. (make them reasonable detect missing properties on scripts) + // particles default configuration. (make them reasonable for user detect missing properties on scripts) m_pPositionMinRadius = 0; m_pPositionMaxRadius = 3; - m_pPositionMinAngle = 0; m_pPositionMaxAngle = 90; + m_pPositionMinAngle = -Fw::pi; m_pPositionMaxAngle = Fw::pi; m_pMinSize = Size(32, 32); m_pMaxSize = Size(32, 32); m_pMinDuration = 0; m_pMaxDuration = 10; + + m_pMinVelocity = 32; m_pMaxVelocity = 64; + m_pMinVelocityAngle = -Fw::pi; m_pMaxVelocityAngle = Fw::pi; + + m_pMinAcceleration = 32; m_pMaxAcceleration = 64; + m_pMinAccelerationAngle = -Fw::pi; m_pMaxAccelerationAngle = Fw::pi; + + m_pColor = Color(255, 0, 0, 128); + m_pTexture = nullptr; } void ParticleEmitter::render() { - // testing - //g_graphics.bindColor(Color(255, 255, 255)); - //g_graphics.drawFilledRect(Rect(0, 0, 400, 400)); - for(auto it = m_particles.begin(), end = m_particles.end(); it != end; ++it) (*it)->render(); } @@ -98,24 +103,37 @@ void ParticleEmitter::update() } // create some particles - TexturePtr tex = g_textures.getTexture("circle2.png"); + m_pTexture = g_textures.getTexture("circle2.png"); // remove this, 'll be parsed on loader - int currentParticles = 1 + elapsedTicks / 1000.0 * m_particlesPerSecond; - for(int i = m_createdParticles; i < currentParticles; ++i) { + int currentBurst = elapsedTicks / 1000.0 / m_burstRate + 1; + for(int b = m_currentBurst; b < currentBurst; ++b) { - // \/ not working properly + // every burst created at same position. float pRadius = Fw::randomRange(m_pPositionMinRadius, m_pPositionMaxRadius); - float pAngle = Fw::randomRange(m_pPositionMinAngle, m_pPositionMaxAngle) * 3.141592 / 180.0; + float pAngle = Fw::randomRange(m_pPositionMinAngle, m_pPositionMaxAngle); + Point pPosition = Point(pRadius * cos(pAngle), pRadius * sin(pAngle)); - Point pPosition = Point(cos(pAngle * pRadius), sin(pAngle * pRadius)); + for(int p = 0; p < m_burstCount; ++p) { - Size pSize = Size(Fw::randomRange(m_pMinSize.width(), m_pMaxSize.width()), Fw::randomRange(m_pMinSize.height(), m_pMaxSize.height())); - float pDuration = Fw::randomRange(m_pMinDuration, m_pMaxDuration); + Size pSize = Size(Fw::randomRange(m_pMinSize.width(), m_pMaxSize.width()), Fw::randomRange(m_pMinSize.height(), m_pMaxSize.height())); + float pDuration = Fw::randomRange(m_pMinDuration, m_pMaxDuration); - // todo: add random data generation - m_particles.push_back(ParticlePtr(new Particle(Rect(m_position + pPosition, pSize), 16, 8, 0, 0, pDuration, Color(255, 0, 0, 32), tex))); + // particles initial velocity + float pVelocity = Fw::randomRange(m_pMinVelocity, m_pMaxVelocity); + float pVelocityAngle = Fw::randomRange(m_pMinVelocityAngle, m_pMaxVelocityAngle); + + // particles initial acceleration + float pAcceleration = Fw::randomRange(m_pMinAcceleration, m_pMaxAcceleration); + float pAccelerationAngle = Fw::randomRange(m_pMinAccelerationAngle, m_pMaxAccelerationAngle); + + m_particles.push_back(ParticlePtr(new Particle(Rect(m_position + pPosition, pSize), + pVelocity * cos(pVelocityAngle), pVelocity * sin(pVelocityAngle), + pAcceleration * cos(pAccelerationAngle), pAcceleration * sin(pAccelerationAngle), + pDuration, m_pColor, m_pTexture))); + } } - m_createdParticles = currentParticles; + + m_currentBurst = currentBurst; } void ParticlesSystem::add(const ParticleEmitterPtr& emitter) diff --git a/src/framework/graphics/particlessystem.h b/src/framework/graphics/particlessystem.h index d9b99a63..c3b460c6 100644 --- a/src/framework/graphics/particlessystem.h +++ b/src/framework/graphics/particlessystem.h @@ -31,7 +31,7 @@ typedef std::shared_ptr ParticlePtr; class ParticleEmitter { public: - ParticleEmitter(const Point& position, float duration, int particlesPerSecond); + ParticleEmitter(const Point& position, float duration, float burstRate, float burstCount); void render(); void update(); @@ -44,7 +44,8 @@ private: int m_duration; ticks_t m_startTicks; bool m_finished; - int m_particlesPerSecond, m_createdParticles; + float m_burstRate, m_burstCount; + int m_currentBurst; std::list m_particles; // particles size @@ -55,21 +56,19 @@ private: float m_pPositionMinAngle, m_pPositionMaxAngle; // particles initial velocity - float minVelocity, maxVelocity; - float minVelocityAngle, maxVelocityAngle; + float m_pMinVelocity, m_pMaxVelocity; + float m_pMinVelocityAngle, m_pMaxVelocityAngle; // particles initial acceleration - float minAcceleration, maxAcceleration; - float minAccelerationAngle, maxAccelerationAngle; + float m_pMinAcceleration, m_pMaxAcceleration; + float m_pMinAccelerationAngle, m_pMaxAccelerationAngle; // particles duration float m_pMinDuration, m_pMaxDuration; - // color ralated - Color color; - - - // texture related + // visual ralated + Color m_pColor; + TexturePtr m_pTexture; }; typedef std::shared_ptr ParticleEmitterPtr; @@ -81,7 +80,7 @@ public: class Gravity270Affector : public Affector { public: void update() { - + // earth gravity is 9.8 m/s². -> in tibia, 32 pixels are equal to 1 meter -> 32 pixels/m -> 9.8 * 32 is gravity constant } }; diff --git a/src/otclient/core/creature.cpp b/src/otclient/core/creature.cpp index 08bf079e..a55a1f57 100644 --- a/src/otclient/core/creature.cpp +++ b/src/otclient/core/creature.cpp @@ -344,15 +344,12 @@ void Creature::setHealthPercent(uint8 healthPercent) void Creature::setDirection(Otc::Direction direction) { - if(direction >= 4) { - if(direction == Otc::NorthEast || direction == Otc::SouthEast) - m_xPattern = Otc::East; - else if(direction == Otc::NorthWest || direction == Otc::SouthWest) - m_xPattern = Otc::West; - } - else { + if(direction == Otc::NorthEast || direction == Otc::SouthEast) + m_xPattern = Otc::East; + else if(direction == Otc::NorthWest || direction == Otc::SouthWest) + m_xPattern = Otc::West; + else m_xPattern = direction; - } m_direction = direction; } diff --git a/src/otclient/net/protocolgameparse.cpp b/src/otclient/net/protocolgameparse.cpp index 45d9b3d4..5e31fcc6 100644 --- a/src/otclient/net/protocolgameparse.cpp +++ b/src/otclient/net/protocolgameparse.cpp @@ -532,7 +532,7 @@ void ProtocolGame::parseMagicEffect(InputMessage& msg) // test particles ParticlesSystem particlesSystem; - particlesSystem.add(ParticleEmitterPtr(new ParticleEmitter(Point(100, 100), -1, 40))); + particlesSystem.add(ParticleEmitterPtr(new ParticleEmitter(Point(100, 100), -1, 2, 10))); g_particlesManager.add(particlesSystem); }