mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-01-09 16:33:50 +00:00
* Adds SIGNAL_HANDLER and SIGNAL_HANDLER_DOES_SLEEP to prevent signal callbacks from blocking (#52761) Adds SIGNAL_HANDLER, a macro that sets SHOULD_NOT_SLEEP(TRUE). This should ideally be required on all new signal callbacks. Adds BLOCKING_SIGNAL_HANDLER, a macro that does nothing except symbolize "this is an older signal that didn't necessitate a code rewrite". It should not be allowed for new work. This comes from discussion around #52735, which yields by calling input, and (though it sets the return type beforehand) will not properly return the flag to prevent attack from slapping. To fix 60% of the yielding cases, WrapAdminProcCall no longer waits for another admin's proc call to finish. I'm not an admin, so I don't know how many behinds this has saved, but if this is problematic for admins I can just make it so that it lets you do it anyway. I'm not sure what the point of this babysitting was anyway. Requested by @optimumtact. Changelog cl admin: Calling a proc while another admin is calling one will no longer wait for the first to finish. You will simply just have to call it again. /cl * Adds SIGNAL_HANDLER and SIGNAL_HANDLER_DOES_SLEEP to prevent signal callbacks from blocking Co-authored-by: Jared-Fogle <35135081+Jared-Fogle@users.noreply.github.com>
115 lines
4.1 KiB
Plaintext
115 lines
4.1 KiB
Plaintext
///Footstep component. Plays footsteps at parents location when it is appropriate.
|
|
/datum/component/footstep
|
|
///How many steps the parent has taken since the last time a footstep was played.
|
|
var/steps = 0
|
|
///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
|
|
|
|
/datum/component/footstep/Initialize(footstep_type_ = FOOTSTEP_MOB_BAREFOOT, volume_ = 0.5, e_range_ = -1)
|
|
if(!isliving(parent))
|
|
return COMPONENT_INCOMPATIBLE
|
|
volume = volume_
|
|
e_range = e_range_
|
|
footstep_type = footstep_type_
|
|
switch(footstep_type)
|
|
if(FOOTSTEP_MOB_HUMAN)
|
|
if(!ishuman(parent))
|
|
return COMPONENT_INCOMPATIBLE
|
|
RegisterSignal(parent, list(COMSIG_MOVABLE_MOVED), .proc/play_humanstep)
|
|
return
|
|
if(FOOTSTEP_MOB_CLAW)
|
|
footstep_sounds = GLOB.clawfootstep
|
|
if(FOOTSTEP_MOB_BAREFOOT)
|
|
footstep_sounds = GLOB.barefootstep
|
|
if(FOOTSTEP_MOB_HEAVY)
|
|
footstep_sounds = GLOB.heavyfootstep
|
|
if(FOOTSTEP_MOB_SHOE)
|
|
footstep_sounds = GLOB.footstep
|
|
if(FOOTSTEP_MOB_SLIME)
|
|
footstep_sounds = 'sound/effects/footstep/slime1.ogg'
|
|
RegisterSignal(parent, list(COMSIG_MOVABLE_MOVED), .proc/play_simplestep) //Note that this doesn't get called for humans.
|
|
|
|
///Prepares a footstep. Determines if it should get played. Returns the turf it should get played on. Note that it is always a /turf/open
|
|
/datum/component/footstep/proc/prepare_step()
|
|
var/turf/open/T = get_turf(parent)
|
|
if(!istype(T))
|
|
return
|
|
|
|
var/mob/living/LM = parent
|
|
if(!T.footstep || LM.buckled || !((LM.mobility_flags & (MOBILITY_STAND | MOBILITY_MOVE)) == (MOBILITY_STAND | MOBILITY_MOVE)) || LM.throwing || LM.movement_type & (VENTCRAWLING | FLYING))
|
|
if (!(LM.mobility_flags & MOBILITY_STAND) && !LM.buckled && !(!T.footstep || LM.movement_type & (VENTCRAWLING | FLYING))) //play crawling sound if we're lying
|
|
playsound(T, 'sound/effects/footstep/crawl1.ogg', 15 * volume)
|
|
return
|
|
|
|
if(iscarbon(LM))
|
|
var/mob/living/carbon/C = LM
|
|
if(!C.get_bodypart(BODY_ZONE_L_LEG) && !C.get_bodypart(BODY_ZONE_R_LEG))
|
|
return
|
|
if(C.m_intent == MOVE_INTENT_WALK)
|
|
return// stealth
|
|
steps++
|
|
|
|
if(steps >= 6)
|
|
steps = 0
|
|
|
|
if(steps % 2)
|
|
return
|
|
|
|
if(steps != 0 && !LM.has_gravity(T)) // don't need to step as often when you hop around
|
|
return
|
|
return T
|
|
|
|
/datum/component/footstep/proc/play_simplestep()
|
|
SIGNAL_HANDLER
|
|
|
|
var/turf/open/T = prepare_step()
|
|
if(!T)
|
|
return
|
|
if(isfile(footstep_sounds) || istext(footstep_sounds))
|
|
playsound(T, footstep_sounds, volume)
|
|
return
|
|
var/turf_footstep
|
|
switch(footstep_type)
|
|
if(FOOTSTEP_MOB_CLAW)
|
|
turf_footstep = T.clawfootstep
|
|
if(FOOTSTEP_MOB_BAREFOOT)
|
|
turf_footstep = T.barefootstep
|
|
if(FOOTSTEP_MOB_HEAVY)
|
|
turf_footstep = T.heavyfootstep
|
|
if(FOOTSTEP_MOB_SHOE)
|
|
turf_footstep = T.footstep
|
|
if(!turf_footstep)
|
|
return
|
|
playsound(T, pick(footstep_sounds[turf_footstep][1]), footstep_sounds[turf_footstep][2] * volume, TRUE, footstep_sounds[turf_footstep][3] + e_range)
|
|
|
|
/datum/component/footstep/proc/play_humanstep()
|
|
SIGNAL_HANDLER
|
|
|
|
if(HAS_TRAIT(parent, TRAIT_SILENT_FOOTSTEPS))
|
|
return
|
|
var/turf/open/T = prepare_step()
|
|
if(!T)
|
|
return
|
|
var/mob/living/carbon/human/H = parent
|
|
var/feetCover = (H.wear_suit && (H.wear_suit.body_parts_covered & FEET)) || (H.w_uniform && (H.w_uniform.body_parts_covered & FEET))
|
|
|
|
if(H.shoes || feetCover) //are we wearing shoes
|
|
playsound(T, pick(GLOB.footstep[T.footstep][1]),
|
|
GLOB.footstep[T.footstep][2] * volume,
|
|
TRUE,
|
|
GLOB.footstep[T.footstep][3] + e_range)
|
|
else
|
|
if(H.dna.species.special_step_sounds)
|
|
playsound(T, pick(H.dna.species.special_step_sounds), 50, TRUE)
|
|
else
|
|
playsound(T, pick(GLOB.barefootstep[T.barefootstep][1]),
|
|
GLOB.barefootstep[T.barefootstep][2] * volume,
|
|
TRUE,
|
|
GLOB.barefootstep[T.barefootstep][3] + e_range)
|