use std::collections::HashMap; use godot::{ classes::{AudioStream, AudioStreamPlayer3D, GpuParticles3D}, prelude::*, }; #[derive(Debug, Clone, Copy, GodotConvert, Export, Var, Default, PartialEq, PartialOrd, Eq)] #[godot(via = GString)] pub enum FootstepKind { #[default] Normal, Sand, Bone, Grass, Gravel, Metal, Grate, Tile, Water, Wood, } #[derive(GodotClass)] #[class(base=Node3D, init)] pub struct PlayerEffects { #[export] splorch: Option>, #[export] hit_sound: Option>, #[export] walk_sound: Option>, #[export] footstep_kind: FootstepKind, #[export] footstep_sounds: Dictionary>>, #[export] walk_sfx_cd: f64, walk_sfx_cd_remaining: f64, base: Base, } #[godot_api] impl INode3D for PlayerEffects { fn process(&mut self, delta: f64) { self.walk_sfx_cd_remaining -= delta; } } impl PlayerEffects { pub fn death(&mut self) { if let Some(splorch) = &mut self.splorch { splorch.set_emitting(true); } if let Some(sfx) = &mut self.hit_sound { sfx.play(); } } pub fn hit(&mut self) { if let Some(sfx) = &mut self.hit_sound { sfx.play(); } } pub fn walk(&mut self) { if self.walk_sfx_cd_remaining > 0. { return; } if let Some(walk) = &mut self.walk_sound { walk.play(); } self.walk_sfx_cd_remaining = self.walk_sfx_cd; } pub fn jump(&mut self) { if let Some(walk) = &mut self.walk_sound { walk.play(); } self.walk_sfx_cd_remaining = 0.; } pub fn change_walk_kind(&mut self, kind: FootstepKind) { if self.footstep_kind == kind { return; } self.footstep_kind = kind; if let Some(Some(sound)) = self.footstep_sounds.get(kind) && let Some(sfx) = &mut self.walk_sound { sfx.set_stream(&sound); } } }