bool ImpactParticle::idle(const Uint64 delta_t)
	{
		const float float_time = delta_t / 1000000.0;
		switch (type)
		{
			case ImpactEffect::MAGIC_PROTECTION:
			{
				const alpha_t scalar = 1.0
					- pow_randfloat(float_time * 4.0f);
				alpha -= scalar;
				if (alpha < 0.02)
					return false;
				break;
			}
			case ImpactEffect::SHIELD:
			{
				const alpha_t scalar = 1.0
					- pow_randfloat(float_time * 4.0f);
				alpha -= scalar;
				if (alpha < 0.02)
					return false;
				break;
			}
			case ImpactEffect::MAGIC_IMMUNITY:
			{
				const alpha_t scalar = 1.0
					- pow_randfloat(float_time * 2.0f);
				alpha -= scalar;
				if (alpha < 0.02)
					return false;
				break;
			}
			case ImpactEffect::POISON:
			{
				const alpha_t scalar = 1.0
					- pow_randfloat(float_time * 1.4f);
				alpha -= scalar;
				if (alpha < 0.02)
					return false;
				break;
			}
			case ImpactEffect::BLOOD:
			{
				const alpha_t scalar = 1.0
					- pow_randfloat(float_time * 0.8f);
				alpha -= scalar;
				if (alpha < 0.02)
					return false;
				break;
			}
		}

		return true;
	}
	bool CandleEffect::idle(const Uint64 usec)
	{
		if ((recall) && (particles.size() == 0))
			return false;

		if (recall)
			return true;

		while (((int)particles.size() < LOD * 20)
			&& ((pow_randfloat((LOD * 20 - particles.size()) * (interval_t)usec / 80 / square(LOD)) < 0.5) || ((int)particles.size() < LOD * 10)))
		{
			Vec3 coords = spawner->get_new_coords();
			coords.y += 0.1 * sqrt_scale;
			coords += *pos;
			Vec3 velocity;
			velocity.randomize(0.02 * sqrt_scale);
			velocity.y *= 5.0;
			velocity.y += 0.04 * sqrt_scale;
			Particle
				* p =
					new CandleParticle(this, mover, coords, velocity, hue_adjust, saturation_adjust, scale, LOD);
			if (!base->push_back_particle(p))
				break;
		}

		return true;
	}
	bool TeleporterEffect::idle(const Uint64 usec)
	{
		if ((recall) && (particles.size() == 0))
			return false;

		if (recall)
			return true;

		while (((int)particles.size() < LOD * 50)
			&& (pow_randfloat((float)usec / 100000 * LOD) < 0.5))
		{
			const Vec3 coords = spawner->get_new_coords() + *pos + Vec3(0.0,
				randcoord() * randcoord() * 8.0 * sqrt_LOD, 0.0);
			Vec3 velocity;
			velocity.randomize(0.2);
			Particle
				* p =
					new TeleporterParticle(this, mover, coords, velocity, hue_adjust, saturation_adjust, size_scalar);
			if (!base->push_back_particle(p))
				break;
		}

		for (int i = 0; i < (int)targets.size();)
		{
			std::vector< std::pair<float *, Uint64> >::iterator iter =
				targets.begin() + i;
			Uint64 age = get_time() - iter->second;
			if (age < 500000)
			{
				*(iter->first) = 1.0 - (age / 500000.0);;
				i++;
			}
			else if (age < 1000000)
			{
				*(iter->first) = (age - 500000.0) / 500000.0;;
				i++;
			}
			else
			{
				*(iter->first) = 1.0;
				targets.erase(iter);
			}
		}

		return true;
	}
	bool SwordEffect::idle(const Uint64 usec)
	{
		if ((recall) && (particles.size() == 0))
			return false;

		if (recall)
			return true;

		const Vec3 pos_change = old_end - *end;
		float speed= square(pos_change.magnitude() * 1000000.0 / usec) * 0.666667;
		float bias = 0.5f;
		switch (type)
		{
			case SERPENT:
			case CUTLASS:
			case EMERALD_CLAYMORE:
			case SUNBREAKER:
			case ORC_SLAYER:
			case EAGLE_WING:
			case JAGGED_SABER:
			{
				bias = randfloat(0.33);
				if (speed > 2.0)
					speed = 2.0f;
				else if (speed < 0.05)
					speed = 0.05;
			}
			case SWORD_OF_FIRE:
			case SWORD_OF_ICE:
			case SWORD_OF_MAGIC:
			{
				if (speed > 3.0f)
					speed = 3.0f;
				else if (speed < 0.25f)
					speed = 0.25f;
			}
		}

		while (pow_randfloat((float)usec * 0.000083f * speed) < bias)
		{
			const percent_t percent= square(randpercent());
			Vec3 randcoords;
			randcoords.randomize(0.0025);
			const Vec3 coords = (*start * percent) + (*end * (1.0 - percent))
				+ randcoords;
			Vec3 velocity;
			velocity.randomize(0.005);
			Vec3 direction = *end - *start;
			direction.normalize(0.05 + randfloat(0.25) * randfloat(0.25));
			velocity += direction;
			Particle* p = new SwordParticle(this, mover, coords, velocity, size - 0.25 + randfloat(0.25), 0.25 + randalpha(percent), color[0], color[1], color[2], texture, LOD);
			if (!base->push_back_particle(p))
				break;
			if (randfloat(2.0f) < 0.1f) {
				p = new SwordParticle(this, mover, coords, velocity, 1.5, 1.0, 2.0, 2.0, 2.0, EC_TWINFLARE, LOD);
				base->push_back_particle(p);
			}
		}

		old_end = *end;

		return true;
	}
	bool BreathParticle::idle(const Uint64 delta_t)
	{
		if (effect->recall)
			return false;

		const interval_t float_time = delta_t / 1000000.0f;
		velocity *= std::pow(0.5f, float_time * velocity.magnitude()
			/ 8.0f);

		switch (type)
		{
			case BreathEffect::ICE:
			case BreathEffect::POISON:
			case BreathEffect::MAGIC:
			case BreathEffect::FIRE:
			{
				if (state == 0)
				{
					if ((get_time() - born
						> (type == BreathEffect::POISON ? 100000 : 400000))
						|| (pow_randfloat(float_time * 5.0f)) < 0.5)
						state = 1;
				}
				else
				{
					if (alpha < 0.02)
						return false;

					if ((state == 1) && (alpha < 0.05))
					{
						state = 2;
						if (type == BreathEffect::FIRE)
						{
							Vec3 velocity_offset;
							velocity_offset.randomize(0.2);
							base->push_back_particle(new BreathSmokeParticle(effect, mover, pos, velocity + velocity_offset, size * 1.25, 0.06, texture, LOD, type));
						}
					}

					const alpha_t scalar = pow_randfloat(float_time * 5.0f);
					alpha *= scalar;

					const coord_t size_scalar =
						std::pow(0.5f, (float)delta_t / 1500000);
					size = std::min(3.0f, size / size_scalar * 0.125f + size * 0.5f);
				}
				break;
			}
			case BreathEffect::WIND:
			{
				if (state == 0)
				{
					if ((get_time() - born > 400000)
						|| (pow_randfloat(float_time * 70.0f)) < 0.5)
						state = 1;
				}
				else
				{
					if (alpha < 0.02)
						return false;

					if ((state == 1) && (alpha < 0.04))
					{
						state = 2;
						if ((rand() & 0x07) == 0x07)
						{
							Vec3 velocity_offset;
							velocity_offset.randomize(1.0);
							base->push_back_particle(new BreathSmokeParticle(effect, mover, pos, velocity + velocity_offset, size * 5.0, 1.0, texture, LOD, type));
						}
					}

					const alpha_t scalar = pow_randfloat(float_time * 20.0f);
					alpha *= scalar;

					const coord_t size_scalar =
						std::pow(0.5f, (float)delta_t / 1500000);
					size = std::min(3.0f, size / size_scalar * 0.125f + size * 0.5f);
				}
				break;
			}
			case BreathEffect::LIGHTNING:
			{
				if (state == 0)
				{
					if ((get_time() - born > 400000)
						|| (pow_randfloat(float_time * 10.0f)) < 0.5)
						state = 1;
				}
				else
				{
					if (alpha < 0.02)
						return false;

					if ((state == 1) && (alpha < 0.04))
					{
						state = 2;
						if ((rand() & 0x3F) == 0x3F)
						{
							Vec3 velocity_offset;
							velocity_offset.randomize();
							velocity_offset.normalize();
							Particle * p = new BreathParticle(effect, mover, pos, velocity_offset * 3.6, size / 2, 1.0, color[0], color[1], color[2], EC_SHIMMER, LOD, type);
							p->state = 2;
							base->push_back_particle(p);
							p = new BreathParticle(effect, mover, pos, velocity_offset * 3.4, size / 2, 1.0, color[0], color[1], color[2], EC_SHIMMER, LOD, type);
							p->state = 2;
							base->push_back_particle(p);
							p = new BreathParticle(effect, mover, pos, velocity_offset * 3.2, size / 2, 1.0, color[0], color[1], color[2], EC_SHIMMER, LOD, type);
							p->state = 2;
							base->push_back_particle(p);
							p = new BreathParticle(effect, mover, pos, velocity_offset * 3.0, size / 2, 1.0, color[0], color[1], color[2], EC_SHIMMER, LOD, type);
							p->state = 2;
							base->push_back_particle(p);
							p = new BreathParticle(effect, mover, pos, velocity_offset * 2.8, size / 2, 1.0, color[0], color[1], color[2], EC_SHIMMER, LOD, type);
							p->state = 2;
							base->push_back_particle(p);
							p = new BreathParticle(effect, mover, pos, velocity_offset * 2.6, size / 2, 1.0, color[0], color[1], color[2], EC_SHIMMER, LOD, type);
							p->state = 2;
							base->push_back_particle(p);
							p = new BreathParticle(effect, mover, pos, velocity_offset * 2.4, size / 2, 1.0, color[0], color[1], color[2], EC_SHIMMER, LOD, type);
							p->state = 2;
							base->push_back_particle(p);
							p = new BreathParticle(effect, mover, pos, velocity_offset * 2.2, size / 2, 1.0, color[0], color[1], color[2], EC_SHIMMER, LOD, type);
							p->state = 2;
							base->push_back_particle(p);
							p = new BreathParticle(effect, mover, pos, velocity_offset * 2.0, size / 2, 1.0, color[0], color[1], color[2], EC_SHIMMER, LOD, type);
							p->state = 2;
							base->push_back_particle(p);
							p = new BreathParticle(effect, mover, pos, velocity_offset * 1.8, size / 2, 1.0, color[0], color[1], color[2], EC_SHIMMER, LOD, type);
							p->state = 2;
							base->push_back_particle(p);
							p = new BreathParticle(effect, mover, pos, velocity_offset * 1.6, size / 2, 1.0, color[0], color[1], color[2], EC_SHIMMER, LOD, type);
							p->state = 2;
							base->push_back_particle(p);
							p = new BreathParticle(effect, mover, pos, velocity_offset * 1.4, size / 2, 1.0, color[0], color[1], color[2], EC_SHIMMER, LOD, type);
							p->state = 2;
							base->push_back_particle(p);
						}
					}

					const alpha_t scalar = pow_randfloat(float_time * 5.0f);
					alpha *= scalar;
					if (state == 2)
						alpha *= square(scalar);

					const coord_t size_scalar =
						std::pow(0.5f, (float)delta_t / 1500000);
					size = std::min(2.0f, size / size_scalar * 0.125f + size * 0.5f);
				}
				break;
			}
		}

		return true;
	}
	bool HarvestingParticle::idle(const Uint64 delta_t)
	{
		if (effect->recall)
			return false;

		const interval_t float_time = delta_t / 1000000.0;
		const Uint64 age = get_time() - born;
		switch (type)
		{
			case HarvestingEffect::RADON_POUCH:
			{
				if (alpha < 0.01)
					return false;

				const alpha_t scalar =
					pow_randfloat(float_time * 2);
				alpha *= scalar;

				break;
			}
			case HarvestingEffect::TOOL_BREAK:
			{
				if (alpha < 0.01)
					return false;

				const alpha_t scalar =
					pow_randfloat(float_time * 2);
				const float age_f = (float)(age)/1000000.0f;
				alpha *= scalar;
				velocity.x *= 1.0f / (1.0f + age_f);
				velocity.z *= 1.0f / (1.0f + age_f);
				velocity.y = -age_f * 0.25f;

				break;
			}
			case HarvestingEffect::CAVERN_WALL:
			{
				if (pos.y < -2.0)
					return false;

				break;
			}
			case HarvestingEffect::MOTHER_NATURE:
			{
				if (alpha < 0.01)
					return false;

				const alpha_t scalar =
					pow_randfloat(float_time * 3);
				if (size < 10)
					size /= scalar;
				alpha *= scalar;

				break;
			}
			case HarvestingEffect::QUEEN_OF_NATURE:
			{
				if (alpha < 0.01)
					return false;

				const alpha_t scalar =
					pow_randfloat(float_time);
				alpha *= scalar;

				break;
			}
			case HarvestingEffect::BEES:
			{
				size = 0.5f + randfloat(0.5f);
				const float age_f = (float)(age)/1000000.0f;
				if (age_f < 2.5f)
					break;
				if (2.5f + randfloat(3.75f) < age_f)
					return false;
				break;
			}
			case HarvestingEffect::BAG_OF_GOLD:
			{
				if (age > 220000)
				{
					const alpha_t alpha_scalar =
						std::pow(0.5f, float_time * 6.0f);
					alpha *= alpha_scalar;

					if (alpha < 0.02)
						return false;
				}

				break;
			}
			case HarvestingEffect::RARE_STONE:
			{
				color[0] = 0.7 + 0.3 * std::sin(age / 530000.0);
				color[1] = 0.7 + 0.3 * std::sin(age / 970000.0 + 1.3);
				color[2] = 0.7 + 0.3 * std::sin(age / 780000.0 + 1.9);

				if (age < 700000)
				{
					if (state == 0)
						size = age / 45000.0;
				}
				else
				{
					const percent_t scalar =
						std::pow(0.5f, float_time * 0.5f);
					size *= scalar;
					alpha *= scalar;

					if (alpha < 0.01)
						return false;
				}
				break;
			}
		}

		return true;
	}