aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/lua_api.txt3
-rw-r--r--src/clientobject.h1
-rw-r--r--src/content_cao.cpp3
-rw-r--r--src/content_cao.h4
-rw-r--r--src/particles.cpp36
5 files changed, 37 insertions, 10 deletions
diff --git a/doc/lua_api.txt b/doc/lua_api.txt
index 84080502f..80e66020d 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 c4e1a634b..83931e438 100644
--- a/src/clientobject.h
+++ b/src/clientobject.h
@@ -61,6 +61,7 @@ public:
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 88ed43a8c..6b35d5881 100644
--- a/src/content_cao.cpp
+++ b/src/content_cao.cpp
@@ -313,7 +313,8 @@ public:
{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 5b3471814..a158e8296 100644
--- a/src/content_cao.h
+++ b/src/content_cao.h
@@ -136,6 +136,10 @@ public:
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 f20fb4083..acf9cc815 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;