mirror of
				https://github.com/luanti-org/luanti.git
				synced 2025-11-04 09:15:29 +01:00 
			
		
		
		
	ParticleSpawner::step cleanup and rotation fix (#6486)
* Particles: Move spawner code to a separate fucntion
This commit is contained in:
		@@ -281,6 +281,58 @@ ParticleSpawner::ParticleSpawner(IGameDef *gamedef, LocalPlayer *player,
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ParticleSpawner::spawnParticle(ClientEnvironment *env, float radius,
 | 
			
		||||
	bool is_attached, const v3f &attached_pos, float attached_yaw)
 | 
			
		||||
{
 | 
			
		||||
	v3f ppos = m_player->getPosition() / BS;
 | 
			
		||||
	v3f pos = random_v3f(m_minpos, m_maxpos);
 | 
			
		||||
 | 
			
		||||
	// Need to apply this first or the following check
 | 
			
		||||
	// will be wrong for attached spawners
 | 
			
		||||
	if (is_attached) {
 | 
			
		||||
		pos.rotateXZBy(attached_yaw);
 | 
			
		||||
		pos += attached_pos;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (pos.getDistanceFrom(ppos) > radius)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	v3f vel = random_v3f(m_minvel, m_maxvel);
 | 
			
		||||
	v3f acc = random_v3f(m_minacc, m_maxacc);
 | 
			
		||||
 | 
			
		||||
	if (is_attached) {
 | 
			
		||||
		// Apply attachment yaw
 | 
			
		||||
		vel.rotateXZBy(attached_yaw);
 | 
			
		||||
		acc.rotateXZBy(attached_yaw);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	float exptime = rand() / (float)RAND_MAX
 | 
			
		||||
			* (m_maxexptime - m_minexptime)
 | 
			
		||||
			+ m_minexptime;
 | 
			
		||||
	float size = rand() / (float)RAND_MAX
 | 
			
		||||
			* (m_maxsize - m_minsize)
 | 
			
		||||
			+ m_minsize;
 | 
			
		||||
 | 
			
		||||
	m_particlemanager->addParticle(new Particle(
 | 
			
		||||
		m_gamedef,
 | 
			
		||||
		m_player,
 | 
			
		||||
		env,
 | 
			
		||||
		pos,
 | 
			
		||||
		vel,
 | 
			
		||||
		acc,
 | 
			
		||||
		exptime,
 | 
			
		||||
		size,
 | 
			
		||||
		m_collisiondetection,
 | 
			
		||||
		m_collision_removal,
 | 
			
		||||
		m_vertical,
 | 
			
		||||
		m_texture,
 | 
			
		||||
		v2f(0.0, 0.0),
 | 
			
		||||
		v2f(1.0, 1.0),
 | 
			
		||||
		m_animation,
 | 
			
		||||
		m_glow
 | 
			
		||||
	));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ParticleSpawner::step(float dtime, ClientEnvironment* env)
 | 
			
		||||
{
 | 
			
		||||
	m_time += dtime;
 | 
			
		||||
@@ -302,128 +354,33 @@ void ParticleSpawner::step(float dtime, ClientEnvironment* env)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (m_spawntime != 0) // Spawner exists for a predefined timespan
 | 
			
		||||
	{
 | 
			
		||||
		for(std::vector<float>::iterator i = m_spawntimes.begin();
 | 
			
		||||
				i != m_spawntimes.end();)
 | 
			
		||||
		{
 | 
			
		||||
			if ((*i) <= m_time && m_amount > 0)
 | 
			
		||||
			{
 | 
			
		||||
	if (m_spawntime != 0) {
 | 
			
		||||
		// Spawner exists for a predefined timespan
 | 
			
		||||
		for (std::vector<float>::iterator i = m_spawntimes.begin();
 | 
			
		||||
				i != m_spawntimes.end();) {
 | 
			
		||||
			if ((*i) <= m_time && m_amount > 0) {
 | 
			
		||||
				m_amount--;
 | 
			
		||||
 | 
			
		||||
				// Pretend to, but don't actually spawn a particle if it is
 | 
			
		||||
				// attached to an unloaded object or distant from player.
 | 
			
		||||
				if (!unloaded) {
 | 
			
		||||
					v3f ppos = m_player->getPosition() / BS;
 | 
			
		||||
					v3f pos = random_v3f(m_minpos, m_maxpos);
 | 
			
		||||
				if (!unloaded)
 | 
			
		||||
					spawnParticle(env, radius, is_attached, attached_pos, attached_yaw);
 | 
			
		||||
 | 
			
		||||
					// Need to apply this first or the following check
 | 
			
		||||
					// will be wrong for attached spawners
 | 
			
		||||
					if (is_attached)
 | 
			
		||||
						pos += attached_pos;
 | 
			
		||||
 | 
			
		||||
					if (pos.getDistanceFrom(ppos) <= radius) {
 | 
			
		||||
						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);
 | 
			
		||||
							vel.rotateXZBy(attached_yaw);
 | 
			
		||||
							acc.rotateXZBy(attached_yaw);
 | 
			
		||||
						}
 | 
			
		||||
 | 
			
		||||
						float exptime = rand()/(float)RAND_MAX
 | 
			
		||||
								*(m_maxexptime-m_minexptime)
 | 
			
		||||
								+m_minexptime;
 | 
			
		||||
						float size = rand()/(float)RAND_MAX
 | 
			
		||||
								*(m_maxsize-m_minsize)
 | 
			
		||||
								+m_minsize;
 | 
			
		||||
 | 
			
		||||
						Particle* toadd = new Particle(
 | 
			
		||||
							m_gamedef,
 | 
			
		||||
							m_player,
 | 
			
		||||
							env,
 | 
			
		||||
							pos,
 | 
			
		||||
							vel,
 | 
			
		||||
							acc,
 | 
			
		||||
							exptime,
 | 
			
		||||
							size,
 | 
			
		||||
							m_collisiondetection,
 | 
			
		||||
							m_collision_removal,
 | 
			
		||||
							m_vertical,
 | 
			
		||||
							m_texture,
 | 
			
		||||
							v2f(0.0, 0.0),
 | 
			
		||||
							v2f(1.0, 1.0),
 | 
			
		||||
							m_animation,
 | 
			
		||||
							m_glow);
 | 
			
		||||
						m_particlemanager->addParticle(toadd);
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
				i = m_spawntimes.erase(i);
 | 
			
		||||
			}
 | 
			
		||||
			else
 | 
			
		||||
			{
 | 
			
		||||
			} else {
 | 
			
		||||
				++i;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	else // Spawner exists for an infinity timespan, spawn on a per-second base
 | 
			
		||||
	{
 | 
			
		||||
	} else {
 | 
			
		||||
		// Spawner exists for an infinity timespan, spawn on a per-second base
 | 
			
		||||
 | 
			
		||||
		// Skip this step if attached to an unloaded object
 | 
			
		||||
		if (unloaded)
 | 
			
		||||
			return;
 | 
			
		||||
		for (int i = 0; i <= m_amount; i++)
 | 
			
		||||
		{
 | 
			
		||||
			if (rand()/(float)RAND_MAX < dtime)
 | 
			
		||||
			{
 | 
			
		||||
				// Do not spawn particle if distant from player
 | 
			
		||||
				v3f ppos = m_player->getPosition() / BS;
 | 
			
		||||
				v3f pos = random_v3f(m_minpos, m_maxpos);
 | 
			
		||||
 | 
			
		||||
				// Need to apply this first or the following check
 | 
			
		||||
				// will be wrong for attached spawners
 | 
			
		||||
				if (is_attached)
 | 
			
		||||
					pos += attached_pos;
 | 
			
		||||
 | 
			
		||||
				if (pos.getDistanceFrom(ppos) <= radius) {
 | 
			
		||||
					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);
 | 
			
		||||
						vel.rotateXZBy(attached_yaw);
 | 
			
		||||
						acc.rotateXZBy(attached_yaw);
 | 
			
		||||
					}
 | 
			
		||||
 | 
			
		||||
					float exptime = rand()/(float)RAND_MAX
 | 
			
		||||
							*(m_maxexptime-m_minexptime)
 | 
			
		||||
							+m_minexptime;
 | 
			
		||||
					float size = rand()/(float)RAND_MAX
 | 
			
		||||
							*(m_maxsize-m_minsize)
 | 
			
		||||
							+m_minsize;
 | 
			
		||||
 | 
			
		||||
					Particle* toadd = new Particle(
 | 
			
		||||
						m_gamedef,
 | 
			
		||||
						m_player,
 | 
			
		||||
						env,
 | 
			
		||||
						pos,
 | 
			
		||||
						vel,
 | 
			
		||||
						acc,
 | 
			
		||||
						exptime,
 | 
			
		||||
						size,
 | 
			
		||||
						m_collisiondetection,
 | 
			
		||||
						m_collision_removal,
 | 
			
		||||
						m_vertical,
 | 
			
		||||
						m_texture,
 | 
			
		||||
						v2f(0.0, 0.0),
 | 
			
		||||
						v2f(1.0, 1.0),
 | 
			
		||||
						m_animation,
 | 
			
		||||
						m_glow);
 | 
			
		||||
					m_particlemanager->addParticle(toadd);
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		for (int i = 0; i <= m_amount; i++) {
 | 
			
		||||
			if (rand() / (float)RAND_MAX < dtime)
 | 
			
		||||
				spawnParticle(env, radius, is_attached, attached_pos, attached_yaw);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -114,7 +114,7 @@ private:
 | 
			
		||||
 | 
			
		||||
class ParticleSpawner
 | 
			
		||||
{
 | 
			
		||||
	public:
 | 
			
		||||
public:
 | 
			
		||||
	ParticleSpawner(IGameDef* gamedef,
 | 
			
		||||
		LocalPlayer *player,
 | 
			
		||||
		u16 amount,
 | 
			
		||||
@@ -140,8 +140,12 @@ class ParticleSpawner
 | 
			
		||||
	bool get_expired ()
 | 
			
		||||
	{ return (m_amount <= 0) && m_spawntime != 0; }
 | 
			
		||||
 | 
			
		||||
	private:
 | 
			
		||||
	ParticleManager* m_particlemanager;
 | 
			
		||||
private:
 | 
			
		||||
	void spawnParticle(ClientEnvironment *env, float radius,
 | 
			
		||||
			bool is_attached, const v3f &attached_pos,
 | 
			
		||||
			float attached_yaw);
 | 
			
		||||
 | 
			
		||||
	ParticleManager *m_particlemanager;
 | 
			
		||||
	float m_time;
 | 
			
		||||
	IGameDef *m_gamedef;
 | 
			
		||||
	LocalPlayer *m_player;
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user