Refactor special_step_sounds out of existence, Human steps now depend on leg type, Digitigrade legs use claw footstep sfx (#87006)

## About The Pull Request

1. Deletes `special_step_sounds`. Unused anyways. 
2. Human footstep type is now determined by its legs. 
- This means a human with two different legs, with two different
footstep types, now alternate between footstep type every other step.
3. Digitigrade legs now use claw footstep sfx

## Why It's Good For The Game

Less random species vars, more dynamic human code, and a little bit more
immersion

## Changelog

🆑 Melbert
refactor: Refactored footsteps for humans. Human footstep sound effects
are now determined by your leg type. Report any oddities.
qol: Digitigrade legs now play claw footstep SFX. "plat plat" is dead,
long live "tap tap".
/🆑
This commit is contained in:
MrMelbert
2024-11-11 00:43:40 -08:00
committed by Majkl-J
parent 0a30ce7572
commit 1cf875363a
5 changed files with 104 additions and 45 deletions
+78 -42
View File
@@ -80,31 +80,42 @@
playsound(turf, 'sound/effects/footstep/crawl1.ogg', 15 * volume, falloff_distance = 1, vary = sound_vary)
return
if(iscarbon(source))
var/mob/living/carbon/carbon_source = source
if(!carbon_source.get_bodypart(BODY_ZONE_L_LEG) && !carbon_source.get_bodypart(BODY_ZONE_R_LEG))
return
if(carbon_source.move_intent == MOVE_INTENT_WALK)
return// stealth
if(iscarbon(source) && source.move_intent == MOVE_INTENT_WALK)
return // stealth
steps_for_living[source] += 1
var/steps = steps_for_living[source]
if(steps >= 6)
if(steps >= 24)
// right foot = 0, 4, 8, 12, 16, 20
// left foot = 2, 6, 10, 14, 18, 22
// 24 -> return to 0 -> right foot, repeat
steps_for_living[source] = 0
steps = 0
if(steps % 2)
// skipping every other step, anyways. gets noisy otherwise
return
if(steps != 0 && !source.has_gravity()) // don't need to step as often when you hop around
if(steps % 6 != 0 && !source.has_gravity())
// don't need to step as often when you hop around
return
. = list(FOOTSTEP_MOB_SHOE = turf.footstep, FOOTSTEP_MOB_BAREFOOT = turf.barefootstep, FOOTSTEP_MOB_HEAVY = turf.heavyfootstep, FOOTSTEP_MOB_CLAW = turf.clawfootstep, STEP_SOUND_PRIORITY = STEP_SOUND_NO_PRIORITY)
var/overriden = SEND_SIGNAL(turf, COMSIG_TURF_PREPARE_STEP_SOUND, .) & FOOTSTEP_OVERRIDEN
//The turf has no footstep sound (e.g. open space) and none of the objects on that turf (e.g. catwalks) overrides it
if(!overriden && isnull(turf.footstep))
var/list/footstep_data = list(
FOOTSTEP_MOB_SHOE = turf.footstep,
FOOTSTEP_MOB_BAREFOOT = turf.barefootstep,
FOOTSTEP_MOB_HEAVY = turf.heavyfootstep,
FOOTSTEP_MOB_CLAW = turf.clawfootstep,
STEP_SOUND_PRIORITY = STEP_SOUND_NO_PRIORITY,
)
var/sigreturn = SEND_SIGNAL(turf, COMSIG_TURF_PREPARE_STEP_SOUND, footstep_data)
if(sigreturn & FOOTSTEP_OVERRIDEN)
return footstep_data
if(isnull(turf.footstep))
// The turf has no footstep sound (e.g. open space)
// and none of the objects on that turf (e.g. catwalks) overrides it
return null
return .
return footstep_data
/datum/element/footstep/proc/play_simplestep(mob/living/source, atom/oldloc, direction, forced, list/old_locs, momentum_change)
SIGNAL_HANDLER
@@ -137,6 +148,48 @@
if (forced || SHOULD_DISABLE_FOOTSTEPS(source) || !momentum_change)
return
var/list/prepared_steps = prepare_step(source)
if(isnull(prepared_steps))
return
var/footstep_type = null
var/list/footstep_sounds
var/stepcount = steps_for_living[source]
// any leg covering sounds defaults to shoe sounds
if((source.wear_suit?.body_parts_covered|source.w_uniform?.body_parts_covered|source.shoes?.body_parts_covered) & FEET)
footstep_type = FOOTSTEP_MOB_SHOE
// now pick whether to draw from left foot or right foot sounds
else
var/obj/item/bodypart/leg/left_leg = source.get_bodypart(BODY_ZONE_L_LEG)
var/obj/item/bodypart/leg/right_leg = source.get_bodypart(BODY_ZONE_R_LEG)
if(stepcount == 2 || stepcount == 6)
footstep_sounds = left_leg?.special_footstep_sounds || right_leg?.special_footstep_sounds
footstep_type = left_leg?.footstep_type || right_leg?.footstep_type
else
footstep_sounds = right_leg?.special_footstep_sounds || left_leg?.special_footstep_sounds
footstep_type = right_leg?.footstep_type || left_leg?.footstep_type
// allow for snowflake effects to take priority
if(!length(footstep_sounds))
switch(footstep_type)
if(FOOTSTEP_MOB_CLAW)
footstep_sounds = GLOB.clawfootstep[prepared_steps[footstep_type]]
if(FOOTSTEP_MOB_BAREFOOT)
footstep_sounds = GLOB.barefootstep[prepared_steps[footstep_type]]
if(FOOTSTEP_MOB_HEAVY)
footstep_sounds = GLOB.heavyfootstep[prepared_steps[footstep_type]]
if(FOOTSTEP_MOB_SHOE)
footstep_sounds = GLOB.footstep[prepared_steps[footstep_type]]
if(null)
return
else
// Got an unsupported type, somehow
CRASH("Invalid footstep type for human footstep: \[[footstep_type]\]")
// no snowflake, and no (found) footstep sounds, nothing to do
if(!length(footstep_sounds))
return
var/volume_multiplier = 1
var/range_adjustment = 0
@@ -144,37 +197,20 @@
volume_multiplier = 0.6
range_adjustment = -2
var/list/prepared_steps = prepare_step(source)
if(isnull(prepared_steps))
return
//cache for sanic speed (lists are references anyways)
var/footstep_sounds = GLOB.footstep
///list returned by playsound() filled by client mobs who heard the footstep. given to play_fov_effect()
// list returned by playsound() filled by client mobs who heard the footstep. given to play_fov_effect()
var/list/heard_clients
var/picked_sound = pick(footstep_sounds[1])
var/picked_volume = footstep_sounds[2] * volume * volume_multiplier
var/picked_range = footstep_sounds[3] + e_range + range_adjustment
if((source.wear_suit?.body_parts_covered | source.w_uniform?.body_parts_covered | source.shoes?.body_parts_covered) & FEET)
// we are wearing shoes
var/shoestep_type = prepared_steps[FOOTSTEP_MOB_SHOE]
if(!isnull(shoestep_type) && footstep_sounds[shoestep_type]) // shoestep type can be null
heard_clients = playsound(source.loc, pick(footstep_sounds[shoestep_type][1]),
footstep_sounds[shoestep_type][2] * volume * volume_multiplier,
TRUE,
footstep_sounds[shoestep_type][3] + e_range + range_adjustment, falloff_distance = 1, vary = sound_vary)
else
// we are barefoot
if(source.dna.species.special_step_sounds)
heard_clients = playsound(source.loc, pick(source.dna.species.special_step_sounds), 50, TRUE, falloff_distance = 1, vary = sound_vary)
else
var/barefoot_type = prepared_steps[FOOTSTEP_MOB_BAREFOOT]
var/bare_footstep_sounds = GLOB.barefootstep
if(!isnull(barefoot_type) && bare_footstep_sounds[barefoot_type]) // barefoot_type can be null
heard_clients = playsound(source.loc, pick(bare_footstep_sounds[barefoot_type][1]),
bare_footstep_sounds[barefoot_type][2] * volume * volume_multiplier,
TRUE,
bare_footstep_sounds[barefoot_type][3] + e_range + range_adjustment, falloff_distance = 1, vary = sound_vary)
heard_clients = playsound(
source = source,
soundin = picked_sound,
vol = picked_volume,
vary = sound_vary,
extrarange = picked_range,
falloff_distance = 1,
)
if(heard_clients)
play_fov_effect(source, 5, "footstep", direction, ignore_self = TRUE, override_list = heard_clients)
@@ -125,8 +125,6 @@ GLOBAL_LIST_EMPTY(features_by_species)
var/inert_mutation = /datum/mutation/human/dwarfism
///Used to set the mob's death_sound upon species change
var/death_sound
///Sounds to override barefeet walking
var/list/special_step_sounds
///Special sound for grabbing
var/grab_sound
/// A path to an outfit that is important for species life e.g. plasmaman outfit
+21 -1
View File
@@ -396,11 +396,31 @@
unarmed_damage_low = 7
unarmed_damage_high = 15
unarmed_effectiveness = 15
biological_state = BIO_STANDARD_JOINTED
/// Datum describing how to offset things worn on the foot of this leg, note that an x offset won't do anything here
var/datum/worn_feature_offset/worn_foot_offset
/// Used by the bloodysoles component to make footprints
var/footprint_sprite = FOOTPRINT_SPRITE_SHOES
biological_state = BIO_STANDARD_JOINTED
/// What does our footsteps (barefoot) sound like? Only BAREFOOT, CLAW, HEAVY, and SHOE (or null, I guess) are valid
var/footstep_type = FOOTSTEP_MOB_BAREFOOT
/// You can set this to a list of sounds to pick from when a footstep is played rather than use the footstep types
/// Requires special formatting: list(list(sounds, go, here), volume, range modifier)
var/list/special_footstep_sounds
/obj/item/bodypart/leg/Initialize(mapload)
. = ..()
if(PERFORM_ALL_TESTS(focus_only/humanstep_validity))
// Update this list if more types are suported in the footstep element
var/list/supported_types = list(
null,
FOOTSTEP_MOB_BAREFOOT,
FOOTSTEP_MOB_CLAW,
FOOTSTEP_MOB_HEAVY,
FOOTSTEP_MOB_SHOE,
)
if(!(footstep_type in supported_types))
stack_trace("Invalid footstep type set on leg: \[[footstep_type]\] \
If you want to use this type, you will need to create a global footstep index for it.")
/obj/item/bodypart/leg/Destroy()
QDEL_NULL(worn_foot_offset)
@@ -53,6 +53,7 @@
limb_id = BODYPART_ID_DIGITIGRADE
bodyshape = BODYSHAPE_HUMANOID | BODYSHAPE_DIGITIGRADE
footprint_sprite = FOOTPRINT_SPRITE_CLAWS
footstep_type = FOOTSTEP_MOB_CLAW
/obj/item/bodypart/leg/left/digitigrade/update_limb(dropping_limb = FALSE, is_creating = FALSE)
. = ..()
@@ -69,6 +70,7 @@
limb_id = BODYPART_ID_DIGITIGRADE
bodyshape = BODYSHAPE_HUMANOID | BODYSHAPE_DIGITIGRADE
footprint_sprite = FOOTPRINT_SPRITE_CLAWS
footstep_type = FOOTSTEP_MOB_CLAW
/obj/item/bodypart/leg/right/digitigrade/update_limb(dropping_limb = FALSE, is_creating = FALSE)
. = ..()
@@ -50,3 +50,6 @@
/// Ensures only whitelisted planes can have TOPDOWN_LAYERing, and vis versa
/datum/unit_test/focus_only/topdown_filtering
/// Catches any invalid footstep types set for humans
/datum/unit_test/focus_only/humanstep_validity