diff --git a/doc/lua_api.txt b/doc/lua_api.txt index 84080502f0052e99a9e771923e4408c5ecb51206..80e66020dfaf7bf97f9bcd320cdb6391ff572a9e 100644 --- a/doc/lua_api.txt +++ b/doc/lua_api.txt @@ -4152,7 +4152,8 @@ The Biome API is still in an experimental phase and subject to change. -- ^ collision_removal: if true then particle is removed when it collides, -- ^ requires collisiondetection = true to have any effect attached = ObjectRef, - -- ^ attached: if defined, makes particle positions relative to this object. + -- ^ attached: if defined, particle positions, velocities and accelerations + -- ^ are relative to this object's position and yaw. vertical = false, -- ^ vertical: if true faces player using y axis only texture = "image.png", diff --git a/src/clientobject.h b/src/clientobject.h index c4e1a634b056b68d7a5f44faafb77995fcc3b821..83931e438e63194a3981514d6f1d41897bd4bfb8 100644 --- a/src/clientobject.h +++ b/src/clientobject.h @@ -61,6 +61,7 @@ class ClientActiveObject : public ActiveObject virtual bool getCollisionBox(aabb3f *toset){return false;} virtual bool collideWithObjects(){return false;} virtual v3f getPosition(){return v3f(0,0,0);} + virtual float getYaw() const {return 0;} virtual scene::ISceneNode *getSceneNode(){return NULL;} virtual scene::IMeshSceneNode *getMeshSceneNode(){return NULL;} virtual scene::IAnimatedMeshSceneNode *getAnimatedMeshSceneNode(){return NULL;} diff --git a/src/content_cao.cpp b/src/content_cao.cpp index 88ed43a8c8a37697997f74af3f75a47dd85b7211..6b35d5881da39eddb77700c11b0c11549855a898 100644 --- a/src/content_cao.cpp +++ b/src/content_cao.cpp @@ -313,7 +313,8 @@ class ItemCAO : public ClientActiveObject {return &m_selection_box;} v3f getPosition() {return m_position;} - + inline float getYaw() const + {return 0;} std::string infoText() {return m_infotext;} diff --git a/src/content_cao.h b/src/content_cao.h index 5b34718140c7512915a90c7d8d3ee554aff96c7b..a158e8296761a61e957fb3051feff933c8422415 100644 --- a/src/content_cao.h +++ b/src/content_cao.h @@ -136,6 +136,10 @@ class GenericCAO : public ClientActiveObject aabb3f *getSelectionBox(); v3f getPosition(); + inline float getYaw() const + { + return m_yaw; + } scene::ISceneNode *getSceneNode(); diff --git a/src/particles.cpp b/src/particles.cpp index f20fb4083033631a48370ace89c6fc34a57be062..acf9cc8155b22dc2bf6f1e6238092f71b23a0226 100644 --- a/src/particles.cpp +++ b/src/particles.cpp @@ -253,12 +253,17 @@ void ParticleSpawner::step(float dtime, ClientEnvironment* env) m_time += dtime; bool unloaded = false; - v3f attached_offset = v3f(0,0,0); + bool is_attached = false; + v3f attached_pos = v3f(0,0,0); + float attached_yaw = 0; if (m_attached_id != 0) { - if (ClientActiveObject *attached = env->getActiveObject(m_attached_id)) - attached_offset = attached->getPosition() / BS; - else + if (ClientActiveObject *attached = env->getActiveObject(m_attached_id)) { + attached_pos = attached->getPosition() / BS; + attached_yaw = attached->getYaw(); + is_attached = true; + } else { unloaded = true; + } } if (m_spawntime != 0) // Spawner exists for a predefined timespan @@ -277,8 +282,15 @@ void ParticleSpawner::step(float dtime, ClientEnvironment* env) v3f pos = random_v3f(m_minpos, m_maxpos); v3f vel = random_v3f(m_minvel, m_maxvel); v3f acc = random_v3f(m_minacc, m_maxacc); - // Make relative to offest - pos += attached_offset; + + if (is_attached) { + // Apply attachment yaw and position + pos.rotateXZBy(attached_yaw); + pos += attached_pos; + vel.rotateXZBy(attached_yaw); + acc.rotateXZBy(attached_yaw); + } + float exptime = rand()/(float)RAND_MAX *(m_maxexptime-m_minexptime) +m_minexptime; @@ -321,10 +333,18 @@ void ParticleSpawner::step(float dtime, ClientEnvironment* env) { if (rand()/(float)RAND_MAX < dtime) { - v3f pos = random_v3f(m_minpos, m_maxpos) - + attached_offset; + v3f pos = random_v3f(m_minpos, m_maxpos); v3f vel = random_v3f(m_minvel, m_maxvel); v3f acc = random_v3f(m_minacc, m_maxacc); + + if (is_attached) { + // Apply attachment yaw and position + pos.rotateXZBy(attached_yaw); + pos += attached_pos; + vel.rotateXZBy(attached_yaw); + acc.rotateXZBy(attached_yaw); + } + float exptime = rand()/(float)RAND_MAX *(m_maxexptime-m_minexptime) +m_minexptime;