Add some sort of footstepbox

This commit is contained in:
Sofia 2026-08-07 22:04:42 +03:00
parent 8e8812ee64
commit 99d351885e
9 changed files with 105 additions and 5 deletions

View File

@ -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"

View File

@ -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"]

View File

@ -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]

View File

@ -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<StaticBody3D>,
}

View File

@ -13,6 +13,7 @@ use crate::{
replay::{ReplayPlayer, ReplayPlayerState, StandaloneReplayManager},
};
pub mod footstep_box;
pub mod goal;
pub mod killbox;
pub mod map_resource;

View File

@ -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<Gd<AudioStreamPlayer3D>>,
#[export]
footstep_kind: FootstepKind,
#[export]
footstep_sounds: Dictionary<FootstepKind, Option<Gd<AudioStream>>>,
#[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);
}
}
}

View File

@ -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]

View File

@ -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<T: IPlayer + ICharacterBody3D + WithBaseField> 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::<FootstepBox>() {
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

View File

@ -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]