From 99d351885e3c06587ff0b5d84720456264e46b16 Mon Sep 17 00:00:00 2001 From: Sofia Date: Fri, 7 Aug 2026 22:04:42 +0300 Subject: [PATCH] Add some sort of footstepbox --- credits.toml | 6 ++++++ godot/maps/default_map/map0.tscn | 19 ++++++++++++++++++- godot/scenes/player/effects.tscn | 4 ++++ rust/src/map/footstep_box.rs | 15 +++++++++++++++ rust/src/map/mod.rs | 1 + rust/src/player/effects.rs | 28 +++++++++++++++++++++++++++- rust/src/player/local_player.rs | 8 +++++++- rust/src/player/mod.rs | 21 ++++++++++++++++++++- rust/src/player/remote_player.rs | 8 +++++++- 9 files changed, 105 insertions(+), 5 deletions(-) create mode 100644 rust/src/map/footstep_box.rs diff --git a/credits.toml b/credits.toml index 76c22b3..f3da589 100644 --- a/credits.toml +++ b/credits.toml @@ -149,3 +149,9 @@ name = "LuminousDragonGames" [[people.credits]] credit = "2 seamless lava tiles" link = "https://opengameart.org/content/2-seamless-lava-tiles" + +[[people]] +name = "Fantozzi" +[[people.credits]] +credit = "Fantozzi's Footsteps (Grass/Sand & Stone)" +link = "https://opengameart.org/content/fantozzis-footsteps-grasssand-stone" diff --git a/godot/maps/default_map/map0.tscn b/godot/maps/default_map/map0.tscn index 468ed40..9292aa6 100644 --- a/godot/maps/default_map/map0.tscn +++ b/godot/maps/default_map/map0.tscn @@ -28,6 +28,12 @@ material = SubResource("StandardMaterial3D_vwb5y") [sub_resource type="BoxShape3D" id="BoxShape3D_oqkce"] size = Vector3(5, 5, 5) +[sub_resource type="BoxShape3D" id="BoxShape3D_m77kh"] +size = Vector3(10, 1, 10) + +[sub_resource type="BoxMesh" id="BoxMesh_1cgct"] +size = Vector3(10, 1, 10) + [node name="map" type="Map" unique_id=914577955 node_paths=PackedStringArray("spawners", "ball_spawner")] spawners = [NodePath("team1_spawner"), NodePath("team2_spawner")] ball_spawner = NodePath("ball_spawner") @@ -64,7 +70,6 @@ team = 1 transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 8.417626, 0.0050001144, -3.8839006) [node name="static_body_3d" type="StaticBody3D" parent="." unique_id=203785193] -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.526536, 0, 10.695821) collision_layer = 7 collision_mask = 7 @@ -92,5 +97,17 @@ transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.7171593, -2.5604024, 0.873 [node name="collision_shape_3d" type="CollisionShape3D" parent="triggerable/proximity_trigger" unique_id=329578045] shape = SubResource("BoxShape3D_oqkce") +[node name="footstep_box" type="FootstepBox" parent="." unique_id=431592617] +kind = "Sand" +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 6.734, -0.5, -55) +collision_layer = 4 +collision_mask = 4 + +[node name="collision_shape_3d" type="CollisionShape3D" parent="footstep_box" unique_id=663129546] +shape = SubResource("BoxShape3D_m77kh") + +[node name="mesh_instance_3d" type="MeshInstance3D" parent="footstep_box" unique_id=1860240696] +mesh = SubResource("BoxMesh_1cgct") + [connection signal="on_shot" from="triggerable/shootable_trigger" to="triggerable" method="activate" unbinds=2] [connection signal="on_trigger" from="triggerable/proximity_trigger" to="triggerable" method="activate"] diff --git a/godot/scenes/player/effects.tscn b/godot/scenes/player/effects.tscn index ee36c09..cc04c14 100644 --- a/godot/scenes/player/effects.tscn +++ b/godot/scenes/player/effects.tscn @@ -1,5 +1,6 @@ [gd_scene format=3 uid="uid://cl66unms2gim0"] +[ext_resource type="AudioStream" uid="uid://b3xnffwvltdey" path="res://raw_assets/sfx/footsteps/zapsplat_foley_footstep_single_on_large_fallen_tree_trunk_001_23222.mp3" id="1_hrrbg"] [ext_resource type="AudioStream" uid="uid://bfg31e3s4jv8c" path="res://raw_assets/sfx/Hit.mp3" id="1_uh1ab"] [ext_resource type="AudioStream" uid="uid://d0lpgmlqxum4u" path="res://raw_assets/sfx/footstep.mp3" id="2_orba0"] @@ -35,6 +36,9 @@ stream_0/stream = ExtResource("2_orba0") splorch = NodePath("splorch") hit_sound = NodePath("hit_sound") walk_sound = NodePath("walk") +footstep_sounds = Dictionary[String, AudioStream]({ +"Normal": ExtResource("1_hrrbg") +}) walk_sfx_cd = 0.5 [node name="splorch" type="GPUParticles3D" parent="." unique_id=986677517] diff --git a/rust/src/map/footstep_box.rs b/rust/src/map/footstep_box.rs new file mode 100644 index 0000000..366d73f --- /dev/null +++ b/rust/src/map/footstep_box.rs @@ -0,0 +1,15 @@ +use godot::{ + classes::{IStaticBody3D, StaticBody3D}, + prelude::*, +}; + +use crate::player::effects::FootstepKind; + +#[derive(GodotClass)] +#[class(base=StaticBody3D, init)] +pub struct FootstepBox { + #[export] + pub kind: FootstepKind, + + base: Base, +} diff --git a/rust/src/map/mod.rs b/rust/src/map/mod.rs index 9357b3c..3c6dfc7 100644 --- a/rust/src/map/mod.rs +++ b/rust/src/map/mod.rs @@ -13,6 +13,7 @@ use crate::{ replay::{ReplayPlayer, ReplayPlayerState, StandaloneReplayManager}, }; +pub mod footstep_box; pub mod goal; pub mod killbox; pub mod map_resource; diff --git a/rust/src/player/effects.rs b/rust/src/player/effects.rs index 44b0fa4..ab9ada9 100644 --- a/rust/src/player/effects.rs +++ b/rust/src/player/effects.rs @@ -1,8 +1,18 @@ +use std::collections::HashMap; + use godot::{ - classes::{AudioStreamPlayer3D, GpuParticles3D}, + 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, +} + #[derive(GodotClass)] #[class(base=Node3D, init)] pub struct PlayerEffects { @@ -13,6 +23,10 @@ pub struct PlayerEffects { #[export] walk_sound: Option>, #[export] + footstep_kind: FootstepKind, + #[export] + footstep_sounds: Dictionary>>, + #[export] walk_sfx_cd: f64, walk_sfx_cd_remaining: f64, @@ -59,4 +73,16 @@ impl PlayerEffects { } 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); + } + } } diff --git a/rust/src/player/local_player.rs b/rust/src/player/local_player.rs index c447ae8..4e050cd 100644 --- a/rust/src/player/local_player.rs +++ b/rust/src/player/local_player.rs @@ -24,7 +24,7 @@ use crate::{ player::{ DamageSource, DamageSourceSignal, IPlayer, PlayerCommon, buffs::{Buff, Buffs}, - effects::PlayerEffects, + effects::{FootstepKind, PlayerEffects}, remote_player::RemotePlayer, shootable::Shootable, soldier_mesh::SoldierMesh, @@ -432,6 +432,12 @@ impl IPlayer for LocalPlayer { self.telefrag_area = Some(area); } } + + fn set_walk_kind(&mut self, kind: FootstepKind) { + if let Some(fx) = &mut self.effects { + fx.bind_mut().change_walk_kind(kind); + } + } } #[godot_api] diff --git a/rust/src/player/mod.rs b/rust/src/player/mod.rs index db18a3d..440fb4d 100644 --- a/rust/src/player/mod.rs +++ b/rust/src/player/mod.rs @@ -9,10 +9,11 @@ use serde::{Deserialize, Serialize}; use crate::{ game::{Game, opts::GameOption}, - map::{killbox::KillboxKind, pickup::PickupKind}, + map::{footstep_box::FootstepBox, killbox::KillboxKind, pickup::PickupKind}, net::{network_manager::NetworkManager, util::NetTransform}, player::{ buffs::{Buff, Buffs}, + effects::FootstepKind, shootable::Shootable, telegrenade::Telegrenade, weapon::{BallWeapon, Weapon, WeaponType}, @@ -72,6 +73,7 @@ pub trait IPlayer { fn new_buff(&mut self, buff: Buff); fn set_buffs(&mut self, buffs: Buffs); fn set_telefrag_frame(&mut self); + fn set_walk_kind(&mut self, kind: FootstepKind); } pub trait PlayerCommon { @@ -107,6 +109,23 @@ impl PlayerCommon for T { } else { self.base_mut().set_velocity(speed); self.base_mut().move_and_slide(); + + if let Some(collision) = self.base().get_last_slide_collision() + && let Some(collider) = collision.get_collider() + { + // Detect if it's floor we're contacting with + if collision.get_normal().dot(Vector3::UP) > 0.95 { + if let Ok(footstep_box) = collider.try_cast::() { + godot_print!("{:?}", footstep_box.bind().kind); + self.set_walk_kind(footstep_box.bind().kind); + } else { + godot_print!("{:?}", FootstepKind::default()); + self.set_walk_kind(FootstepKind::default()); + } + } else { + godot_print!("{}", collision.get_normal()); + } + } } // Check if hitting a ceiling; if so, stop upwards velocity (done here instead of diff --git a/rust/src/player/remote_player.rs b/rust/src/player/remote_player.rs index 8b7d2e6..519d07c 100644 --- a/rust/src/player/remote_player.rs +++ b/rust/src/player/remote_player.rs @@ -13,7 +13,7 @@ use crate::{ player::{ DamageSource, DamageSourceSignal, IPlayer, NetTransform, PlayerCommon, buffs::{Buff, Buffs}, - effects::PlayerEffects, + effects::{FootstepKind, PlayerEffects}, shootable::Shootable, soldier_mesh::SoldierMesh, telegrenade::Telegrenade, @@ -379,6 +379,12 @@ impl IPlayer for RemotePlayer { self.telefrag_area = Some(area); } } + + fn set_walk_kind(&mut self, kind: FootstepKind) { + if let Some(fx) = &mut self.effects { + fx.bind_mut().change_walk_kind(kind); + } + } } #[godot_api]