mirror of
https://github.com/CHOMPStation2/CHOMPStation2.git
synced 2025-12-10 18:22:39 +00:00
Footstep element (#8576)
This commit is contained in:
171
modular_chomp/code/datums/elements/footstep.dm
Normal file
171
modular_chomp/code/datums/elements/footstep.dm
Normal file
@@ -0,0 +1,171 @@
|
||||
#define SHOULD_DISABLE_FOOTSTEPS(source)
|
||||
|
||||
///Footstep element. Plays footsteps at parents location when it is appropriate.
|
||||
/datum/element/footstep
|
||||
element_flags = ELEMENT_DETACH_ON_HOST_DESTROY|ELEMENT_BESPOKE
|
||||
argument_hash_start_idx = 2
|
||||
///A list containing living mobs and the number of steps they have taken since the last time their footsteps were played.
|
||||
var/list/steps_for_living = list()
|
||||
///volume determines the extra volume of the footstep. This is multiplied by the base volume, should there be one.
|
||||
var/volume
|
||||
///e_range stands for extra range - aka how far the sound can be heard. This is added to the base value and ignored if there isn't a base value.
|
||||
var/e_range
|
||||
///footstep_type is a define which determines what kind of sounds should get chosen.
|
||||
var/footstep_type
|
||||
///This can be a list OR a soundfile OR null. Determines whatever sound gets played.
|
||||
var/footstep_sounds
|
||||
///Whether or not to add variation to the sounds played
|
||||
var/sound_vary = FALSE
|
||||
|
||||
/datum/element/footstep/Attach(datum/target, footstep_type = FOOTSTEP_MOB_BAREFOOT, volume = 0.5, e_range = -8, sound_vary = FALSE)
|
||||
. = ..()
|
||||
if(!ismovable(target))
|
||||
return ELEMENT_INCOMPATIBLE
|
||||
src.volume = volume
|
||||
src.e_range = e_range
|
||||
src.footstep_type = footstep_type
|
||||
src.sound_vary = sound_vary
|
||||
|
||||
if(ishuman(target))
|
||||
RegisterSignal(target, COMSIG_MOVABLE_MOVED, PROC_REF(play_humanstep))
|
||||
steps_for_living[target] = 0
|
||||
return
|
||||
|
||||
footstep_sounds = check_footstep_type(footstep_type)
|
||||
|
||||
RegisterSignal(target, COMSIG_MOVABLE_MOVED, PROC_REF(play_simplestep))
|
||||
steps_for_living[target] = 0
|
||||
|
||||
/datum/element/footstep/proc/check_footstep_type(footstep_type)
|
||||
var/footstep_ret
|
||||
switch(footstep_type)
|
||||
if(FOOTSTEP_MOB_TESHARI)
|
||||
footstep_ret = GLOB.lightclawfootstep
|
||||
if(FOOTSTEP_MOB_CLAW)
|
||||
footstep_ret = GLOB.clawfootstep
|
||||
if(FOOTSTEP_MOB_BAREFOOT)
|
||||
footstep_ret = GLOB.barefootstep
|
||||
if(FOOTSTEP_MOB_HEAVY)
|
||||
footstep_ret = GLOB.heavyfootstep
|
||||
if(FOOTSTEP_MOB_SHOE)
|
||||
footstep_ret = GLOB.footstep
|
||||
if(FOOTSTEP_MOB_SLIME)
|
||||
footstep_ret = 'modular_chomp/sound/effects/footstep/slime1.ogg'
|
||||
return footstep_ret
|
||||
|
||||
/datum/element/footstep/Detach(atom/movable/source)
|
||||
UnregisterSignal(source, COMSIG_MOVABLE_MOVED)
|
||||
steps_for_living -= source
|
||||
return ..()
|
||||
|
||||
///Prepares a footstep for living mobs. Determines if it should get played. Returns the turf it should get played on. Note that it is always a /turf/simulated
|
||||
/datum/element/footstep/proc/prepare_step(mob/living/source)
|
||||
var/turf/simulated/turf = get_turf(source)
|
||||
if(!istype(turf))
|
||||
return
|
||||
|
||||
if(source.is_incorporeal())
|
||||
return
|
||||
|
||||
if(source.buckled || source.throwing || source.movement_type & (source.is_ventcrawling | source.flying))
|
||||
return
|
||||
|
||||
if(source.lying) //play crawling sound if we're lying
|
||||
if(turf.footstep)
|
||||
playsound(turf, 'modular_chomp/sound/effects/footstep/crawl1.ogg', 15 * volume, falloff = 1, vary = sound_vary)
|
||||
return
|
||||
|
||||
if(iscarbon(source))
|
||||
var/mob/living/carbon/carbon_source = source
|
||||
if(!carbon_source.get_organ(BP_L_LEG) && !carbon_source.get_organ(BP_R_LEG))
|
||||
return
|
||||
if(carbon_source.m_intent == "walk")
|
||||
return// stealth
|
||||
steps_for_living[source] += 1
|
||||
var/steps = steps_for_living[source]
|
||||
|
||||
if(steps >= 6)
|
||||
steps_for_living[source] = 0
|
||||
steps = 0
|
||||
|
||||
if(steps % 2)
|
||||
return
|
||||
|
||||
if(steps != 0 && !has_gravity(source)) // 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))
|
||||
return null
|
||||
return .
|
||||
|
||||
/datum/element/footstep/proc/play_simplestep(mob/living/source, atom/oldloc, direction, forced, list/old_locs, momentum_change)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
var/list/prepared_steps = prepare_step(source)
|
||||
if(isnull(prepared_steps))
|
||||
return
|
||||
|
||||
if(isfile(footstep_sounds) || istext(footstep_sounds))
|
||||
playsound(source.loc, footstep_sounds, volume, falloff = 1, vary = sound_vary)
|
||||
return
|
||||
|
||||
var/turf_footstep = prepared_steps[footstep_type]
|
||||
if(isnull(turf_footstep) || !footstep_sounds[turf_footstep])
|
||||
return
|
||||
playsound(source.loc, pick(footstep_sounds[turf_footstep][1]), footstep_sounds[turf_footstep][2] * volume, TRUE, footstep_sounds[turf_footstep][3] + e_range, falloff = 1, vary = sound_vary)
|
||||
|
||||
/datum/element/footstep/proc/play_humanstep(mob/living/carbon/human/source, atom/oldloc, direction, forced, list/old_locs, momentum_change)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
var/volume_multiplier = 1
|
||||
var/range_adjustment = 0
|
||||
|
||||
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
|
||||
|
||||
if( source.shoes || ( source.wear_suit && (source.wear_suit.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
|
||||
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 = 1, vary = sound_vary)
|
||||
else
|
||||
// we are barefoot
|
||||
|
||||
if(source.species.special_step_sounds)
|
||||
playsound(source.loc, pick(source.species.special_step_sounds), 50, TRUE, falloff = 1, vary = sound_vary)
|
||||
else if (istype(source.species, /datum/species/shapeshifter/promethean))
|
||||
playsound(source.loc, 'modular_chomp/sound/effects/footstep/slime1.ogg', 25, TRUE, falloff = 1)
|
||||
else
|
||||
var/barefoot_type = prepared_steps[FOOTSTEP_MOB_BAREFOOT]
|
||||
var/bare_footstep_sounds
|
||||
if(source.species.footstep != FOOTSTEP_MOB_HUMAN)
|
||||
bare_footstep_sounds = check_footstep_type(source.species.footstep)
|
||||
else
|
||||
bare_footstep_sounds = GLOB.barefootstep
|
||||
if(!isnull(barefoot_type) && bare_footstep_sounds[barefoot_type]) // barefoot_type can be null
|
||||
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 = 1, vary = sound_vary)
|
||||
|
||||
///Prepares a footstep for machine walking
|
||||
/datum/element/footstep/proc/play_simplestep_machine(atom/movable/source, atom/oldloc, direction, forced, list/old_locs, momentum_change)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
var/turf/simulated/source_loc = get_turf(source)
|
||||
if(!istype(source_loc))
|
||||
return
|
||||
|
||||
playsound(source_loc, footstep_sounds, 50, falloff = 1, vary = sound_vary)
|
||||
#undef SHOULD_DISABLE_FOOTSTEPS
|
||||
81
modular_chomp/code/datums/elements/footstep_override.dm
Normal file
81
modular_chomp/code/datums/elements/footstep_override.dm
Normal file
@@ -0,0 +1,81 @@
|
||||
///When attached, the footstep sound played by the footstep element will be replaced by this one's
|
||||
/datum/element/footstep_override
|
||||
element_flags = ELEMENT_BESPOKE|ELEMENT_DETACH_ON_HOST_DESTROY
|
||||
argument_hash_start_idx = 2
|
||||
///The sound played for movables with claw step sound type.
|
||||
var/clawfootstep
|
||||
///The sound played for movables with barefoot step sound type.
|
||||
var/barefootstep
|
||||
///The sound played for movables with heavy step sound type.
|
||||
var/heavyfootstep
|
||||
///The sound played for movables with shoed step sound type.
|
||||
var/footstep
|
||||
///The priority this element has in relation to other elements of the same type attached to other movables on the same turf.
|
||||
var/priority
|
||||
/**
|
||||
* A list of turfs occupied by the movables this element is attached to.
|
||||
* Needed so it stops listening the turf's signals ONLY when it has no movable with the element.
|
||||
*/
|
||||
var/list/occupied_turfs = list()
|
||||
|
||||
/datum/element/footstep_override/Attach(atom/movable/target, clawfootstep = FOOTSTEP_HARD_CLAW, barefootstep = FOOTSTEP_HARD_BAREFOOT, heavyfootstep = FOOTSTEP_GENERIC_HEAVY, footstep = FOOTSTEP_FLOOR, priority = STEP_SOUND_NO_PRIORITY)
|
||||
. = ..()
|
||||
if(!ismovable(target))
|
||||
return ELEMENT_INCOMPATIBLE
|
||||
|
||||
src.clawfootstep = clawfootstep
|
||||
src.barefootstep = barefootstep
|
||||
src.heavyfootstep = heavyfootstep
|
||||
src.footstep = footstep
|
||||
src.priority = priority
|
||||
|
||||
RegisterSignal(target, COMSIG_MOVABLE_MOVED, PROC_REF(on_moved))
|
||||
if(isturf(target.loc))
|
||||
occupy_turf(target, target.loc)
|
||||
|
||||
/datum/element/footstep_override/Detach(atom/movable/source)
|
||||
if(isturf(source.loc))
|
||||
vacate_turf(source, source.loc)
|
||||
return ..()
|
||||
|
||||
/datum/element/footstep_override/proc/on_moved(atom/movable/source, atom/oldloc)
|
||||
SIGNAL_HANDLER
|
||||
if(isturf(oldloc))
|
||||
vacate_turf(source, oldloc)
|
||||
if(isturf(source.loc))
|
||||
occupy_turf(source, source.loc)
|
||||
|
||||
/**
|
||||
* Adds the movable to the list of movables with the element occupying the turf.
|
||||
* If the turf was not on the list of occupied turfs before, a signal will be registered
|
||||
* to it.
|
||||
*/
|
||||
/datum/element/footstep_override/proc/occupy_turf(atom/movable/movable, turf/location)
|
||||
if(occupied_turfs[location])
|
||||
occupied_turfs[location] |= movable
|
||||
return
|
||||
occupied_turfs[location] = list(movable)
|
||||
RegisterSignal(location, COMSIG_TURF_PREPARE_STEP_SOUND, PROC_REF(prepare_steps))
|
||||
|
||||
/**
|
||||
* Removes the movable from the list of movables with the element occupying the turf.
|
||||
* If the turf is no longer occupied, it'll be removed from the list, and the signal
|
||||
* unregistered from it
|
||||
*/
|
||||
/datum/element/footstep_override/proc/vacate_turf(atom/movable/movable, turf/location)
|
||||
LAZYREMOVE(occupied_turfs[location], movable)
|
||||
if(!occupied_turfs[location])
|
||||
occupied_turfs -= location
|
||||
UnregisterSignal(location, COMSIG_TURF_PREPARE_STEP_SOUND)
|
||||
|
||||
///Changes the sound types to be played if the element priority is higher than the one in the steps list.
|
||||
/datum/element/footstep_override/proc/prepare_steps(turf/source, list/steps)
|
||||
SIGNAL_HANDLER
|
||||
if(steps[STEP_SOUND_PRIORITY] > priority)
|
||||
return
|
||||
steps[FOOTSTEP_MOB_SHOE] = footstep
|
||||
steps[FOOTSTEP_MOB_BAREFOOT] = barefootstep
|
||||
steps[FOOTSTEP_MOB_HEAVY] = heavyfootstep
|
||||
steps[FOOTSTEP_MOB_CLAW] = clawfootstep
|
||||
steps[STEP_SOUND_PRIORITY] = priority
|
||||
return FOOTSTEP_OVERRIDEN
|
||||
94
modular_chomp/code/datums/elements/slosh.dm
Normal file
94
modular_chomp/code/datums/elements/slosh.dm
Normal file
@@ -0,0 +1,94 @@
|
||||
/datum/element/slosh
|
||||
element_flags = ELEMENT_DETACH_ON_HOST_DESTROY|ELEMENT_BESPOKE
|
||||
var/step_count
|
||||
var/vore_organs_reagents
|
||||
var/vore_footstep_volume
|
||||
var/vore_footstep_chance
|
||||
|
||||
/datum/element/slosh/Attach(datum/target)
|
||||
. = ..()
|
||||
if(!isliving(target))
|
||||
return ELEMENT_INCOMPATIBLE
|
||||
|
||||
RegisterSignal(target, COMSIG_MOVABLE_MOVED, PROC_REF(handle_footstep))
|
||||
step_count = 0
|
||||
vore_organs_reagents = list()
|
||||
vore_footstep_volume = 0
|
||||
vore_footstep_chance = 0
|
||||
return
|
||||
|
||||
/datum/element/slosh/Detach(datum/source)
|
||||
UnregisterSignal(source, COMSIG_MOVABLE_MOVED)
|
||||
step_count -= source
|
||||
return ..()
|
||||
|
||||
/datum/element/slosh/proc/handle_footstep(mob/living/source)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
if(ishuman(source))
|
||||
var/mob/living/carbon/human/source_human = source
|
||||
if(source_human.m_intent == "walk" && step_count++ % 20 == 0)
|
||||
return
|
||||
if(source_human.m_intent == "run" && step_count++ % 2 != 0)
|
||||
return
|
||||
choose_vorefootstep(source)
|
||||
if(issilicon(source))
|
||||
if(step_count++ % 2)
|
||||
choose_vorefootstep(source)
|
||||
|
||||
|
||||
/datum/element/slosh/proc/choose_vorefootstep(mob/living/source)
|
||||
if(step_count++ >= 5)
|
||||
|
||||
vore_organs_reagents = list()
|
||||
var/highest_vol = 0
|
||||
|
||||
for(var/obj/belly/B in source.vore_organs)
|
||||
var/total_volume = B.reagents.total_volume
|
||||
vore_organs_reagents += total_volume
|
||||
|
||||
if(B.show_liquids && B.vorefootsteps_sounds && highest_vol < total_volume)
|
||||
highest_vol = total_volume
|
||||
|
||||
if(highest_vol < 20)
|
||||
vore_footstep_volume = 0
|
||||
vore_footstep_chance = 0
|
||||
else
|
||||
vore_footstep_volume = 20 + highest_vol * 4/5
|
||||
vore_footstep_chance = highest_vol/4
|
||||
|
||||
step_count = 0
|
||||
|
||||
if(!vore_footstep_volume || !vore_footstep_chance)
|
||||
return
|
||||
|
||||
if(prob(vore_footstep_chance))
|
||||
handle_vorefootstep(source)
|
||||
|
||||
/datum/element/slosh/proc/handle_vorefootstep(mob/living/source)
|
||||
if(!CONFIG_GET(number/vorefootstep_volume) || !vore_footstep_volume)
|
||||
return
|
||||
|
||||
var/S = pick(GLOB.slosh)
|
||||
if(!S) return
|
||||
var/volume = CONFIG_GET(number/vorefootstep_volume) * (vore_footstep_volume/100)
|
||||
|
||||
if(ishuman(source))
|
||||
var/mob/living/carbon/human/human_source = source
|
||||
|
||||
if(!human_source.shoes || human_source.m_intent == "walk")
|
||||
volume = CONFIG_GET(number/vorefootstep_volume) * (vore_footstep_volume/100) * 0.75
|
||||
else if(human_source.shoes)
|
||||
var/obj/item/clothing/shoes/feet = human_source.shoes
|
||||
if(istype(feet))
|
||||
volume = feet.step_volume_mod * CONFIG_GET(number/vorefootstep_volume) * (vore_footstep_volume/100) * 0.75
|
||||
if(!human_source.has_organ(BP_L_FOOT) && !human_source.has_organ(BP_R_FOOT))
|
||||
return
|
||||
|
||||
if(source.buckled || source.lying || source.throwing)
|
||||
return
|
||||
if(!has_gravity(source) && prob(75))
|
||||
return
|
||||
|
||||
playsound(source.loc, S, volume, FALSE, preference = /datum/client_preference/digestion_noises)
|
||||
return
|
||||
Reference in New Issue
Block a user