use bevy::color::{Color, ColorCurve, LinearRgba};
use bevy::math::cubic_splines::LinearSpline;
use bevy::math::{Vec2, VectorSpace};
use rand::Rng;
use serde::{Deserialize, Serialize};
use serde::de::DeserializeOwned;
#[derive(Deserialize, Serialize)]
pub struct ParticleEffect {
// -- lifetime / spawning -- //
/// Particle lifetime in seconds
pub lifetime_seconds: RandF32,
/// Delay inbetween each batch of particles spawned
pub batch_spawn_delay_seconds: RandF32,
/// Number of distinct particles spawned per batch
pub particles_in_batch: RandF32,
// -- velocity -- //
/// Initial linear velocity added to the particle's velocity when it is spawned
pub initial_linear_velocity: RandVec2,
/// Initial angular velocity added to the particle's rotation when it is spawned
pub initial_angular_velocity: RandF32,
// -- scale -- //
// Scale curve over the lifetime of the particle
pub scale: ScaleSpline,
// -- color -- //
// Color curve over the lifetime of the particle
pub color: ColorSpline,
}
#[derive(Deserialize, Serialize)]
pub struct ScaleSpline(Vec<f32>);
impl From<ScaleSpline> for LinearSpline<f32> {
fn from(value: ScaleSpline) -> Self {
Self::new(&value.0)
}
}
#[derive(Deserialize, Serialize)]
pub struct ColorSpline(Vec<LinearRgba>);
impl From<ColorSpline> for LinearSpline<LinearRgba> {
fn from(value: ColorSpline) -> Self {
Self::new(&value.0)
}
}
#[derive(Deserialize, Serialize)]
pub struct RandF32 {
pub value: f32,
pub randomness: f32
}
impl RandF32 {
pub fn sample(&self, rng: &mut impl Rng) -> f32 {
rng.random_range(self.value-self.randomness .. self.value+self.randomness)
}
}
#[derive(Deserialize, Serialize)]
pub struct RandVec2 {
pub x: RandF32,
pub y: RandF32,
}
impl RandVec2 {
pub fn sample(&self, rng: &mut impl Rng) -> Vec2 {
Vec2::new(self.x.sample(rng), self.y.sample(rng))
}
}