mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-22 12:41:09 +01:00
adds a playsoundtoken proc that allows one-shot sound tokens playing, and adds support for it to emotes. (#96519)
This commit is contained in:
@@ -1096,6 +1096,15 @@ GLOBAL_LIST_INIT(layers_to_offset, list(
|
||||
/// Helper macro that determines if the mob is at the threshold to start vomitting due to high toxin levels
|
||||
#define AT_TOXIN_VOMIT_THRESHOLD(mob) (mob.get_tox_loss() > 45 && mob.nutrition > 20)
|
||||
|
||||
/// Shared cooldown for manually triggered emote audio
|
||||
#define MANUAL_GENERAL_EMOTE_AUDIO_COOLDOWN "manual_general_emote_audio_cooldown"
|
||||
/// Per emote cooldown for manually triggered emote audio
|
||||
#define MANUAL_SPECIFIC_EMOTE_AUDIO_COOLDOWN(type) "manual_specific_emote_audio_cooldown_[type]"
|
||||
/// Shared cooldown for forced emote audio
|
||||
#define FORCED_GENERAL_EMOTE_AUDIO_COOLDOWN "forced_general_emote_audio_cooldown"
|
||||
/// Per emote cooldown for forced emote audio
|
||||
#define FORCED_SPECIFIC_EMOTE_AUDIO_COOLDOWN(type) "forced_specific_emote_audio_cooldown_[type]"
|
||||
|
||||
/// The duration of the flip emote animation
|
||||
#define FLIP_EMOTE_DURATION 0.7 SECONDS
|
||||
///The duration of a taunt emote, so how long they can deflect projectiles
|
||||
|
||||
+26
-8
@@ -61,12 +61,18 @@
|
||||
var/cooldown = 0.8 SECONDS
|
||||
/// Does this message have a message that can be modified by the user?
|
||||
var/can_message_change = FALSE
|
||||
/// How long is the shared emote cooldown triggered by this emote?
|
||||
var/general_emote_audio_cooldown = 2 SECONDS
|
||||
/// How long is the specific emote cooldown triggered by this emote?
|
||||
var/specific_emote_audio_cooldown = 5 SECONDS
|
||||
/// How long is the shared emote cooldown triggered by this emote when used intentionally?
|
||||
var/manual_general_emote_audio_cooldown = 2 SECONDS
|
||||
/// How long is the specific emote cooldown triggered by this emote when used intentionally?
|
||||
var/manual_specific_emote_audio_cooldown = 5 SECONDS
|
||||
/// How long is the shared emote cooldown triggered by this emote when forced?
|
||||
var/forced_general_emote_audio_cooldown = 2 SECONDS
|
||||
/// How long is the specific emote cooldown triggered by this emote when forced?
|
||||
var/forced_specific_emote_audio_cooldown = 2 SECONDS
|
||||
/// Does this emote's sound ignore walls?
|
||||
var/sound_wall_ignore = FALSE
|
||||
///Does this emote use sound tokens? this means it also ignores walls.
|
||||
var/use_sound_tokens = FALSE
|
||||
|
||||
/datum/emote/New()
|
||||
switch(mob_type_allowed_typecache)
|
||||
@@ -112,15 +118,27 @@
|
||||
user.log_message(msg, LOG_EMOTE)
|
||||
|
||||
var/tmp_sound = get_sound(user)
|
||||
if(tmp_sound && should_play_sound(user, intentional) && TIMER_COOLDOWN_FINISHED(user, "general_emote_audio_cooldown") && TIMER_COOLDOWN_FINISHED(user, type))
|
||||
TIMER_COOLDOWN_START(user, type, specific_emote_audio_cooldown)
|
||||
TIMER_COOLDOWN_START(user, "general_emote_audio_cooldown", general_emote_audio_cooldown)
|
||||
if(tmp_sound && should_play_sound(user, intentional))
|
||||
if(intentional)
|
||||
if(!TIMER_COOLDOWN_FINISHED(user, MANUAL_GENERAL_EMOTE_AUDIO_COOLDOWN) || !TIMER_COOLDOWN_FINISHED(user, MANUAL_SPECIFIC_EMOTE_AUDIO_COOLDOWN(type)) || !TIMER_COOLDOWN_FINISHED(user, FORCED_GENERAL_EMOTE_AUDIO_COOLDOWN) || !TIMER_COOLDOWN_FINISHED(user, FORCED_SPECIFIC_EMOTE_AUDIO_COOLDOWN(type)))
|
||||
return FALSE
|
||||
else
|
||||
if(!TIMER_COOLDOWN_FINISHED(user, FORCED_GENERAL_EMOTE_AUDIO_COOLDOWN) || !TIMER_COOLDOWN_FINISHED(user, FORCED_SPECIFIC_EMOTE_AUDIO_COOLDOWN(type)))
|
||||
return FALSE
|
||||
TIMER_COOLDOWN_START(user, MANUAL_SPECIFIC_EMOTE_AUDIO_COOLDOWN(type), manual_specific_emote_audio_cooldown)
|
||||
TIMER_COOLDOWN_START(user, MANUAL_GENERAL_EMOTE_AUDIO_COOLDOWN, manual_general_emote_audio_cooldown)
|
||||
TIMER_COOLDOWN_START(user, FORCED_SPECIFIC_EMOTE_AUDIO_COOLDOWN(type), forced_specific_emote_audio_cooldown)
|
||||
TIMER_COOLDOWN_START(user, FORCED_GENERAL_EMOTE_AUDIO_COOLDOWN, forced_general_emote_audio_cooldown)
|
||||
|
||||
var/frequency = null
|
||||
if (affected_by_pitch && SStts.tts_enabled && SStts.pitch_enabled)
|
||||
frequency = rand(MIN_EMOTE_PITCH, MAX_EMOTE_PITCH) * (1 + sqrt(abs(user.pitch)) * sign(user.pitch) * EMOTE_TTS_PITCH_MULTIPLIER)
|
||||
else if(vary)
|
||||
frequency = rand(MIN_EMOTE_PITCH, MAX_EMOTE_PITCH)
|
||||
playsound(source = user,soundin = tmp_sound,vol = 50, vary = FALSE, ignore_walls = sound_wall_ignore, frequency = frequency)
|
||||
if(use_sound_tokens && sound_wall_ignore)
|
||||
playsoundtoken(source = user, soundin = tmp_sound, range = SOUND_RANGE, volume = 50)
|
||||
else
|
||||
playsound(source = user,soundin = tmp_sound,vol = 50, vary = FALSE, ignore_walls = sound_wall_ignore, frequency = frequency)
|
||||
|
||||
|
||||
var/is_important = running_emote_type & EMOTE_IMPORTANT
|
||||
|
||||
@@ -6,7 +6,8 @@
|
||||
var/atom/source
|
||||
/// k:v list of mob : sound status
|
||||
var/list/listeners = list()
|
||||
|
||||
///k:v list of mobs : bool. Used to quickly check whether a mob is allowed to hear this noise. This is null by default which means ANY MOB can hear this.
|
||||
var/list/allowed_listeners
|
||||
/// Sound maximum range
|
||||
var/range
|
||||
/// Sound volume
|
||||
@@ -29,10 +30,14 @@
|
||||
var/start_time
|
||||
/// Duration of the current sound file in deciseconds. Used to wrap offset for looping sounds.
|
||||
var/sound_duration
|
||||
/// Duration of the current sound file in deciseconds. Used to wrap offset for looping sounds.
|
||||
var/sound_duration_override
|
||||
/// Cell tracker managing spatial grid cells within range of the source. The wizards say this is the fastest.
|
||||
var/datum/cell_tracker/cell_tracker
|
||||
///Should we destroy the datum when the sound is done?
|
||||
var/delete_on_end = FALSE
|
||||
|
||||
/datum/sound_token/New(atom/_source, _sound, _range = 10, _volume = 50, _falloff_exponent = SOUND_FALLOFF_EXPONENT, _falloff_distance = SOUND_DEFAULT_FALLOFF_DISTANCE)
|
||||
/datum/sound_token/New(atom/_source, _sound, _range = 10, _volume = 50, _falloff_exponent = SOUND_FALLOFF_EXPONENT, _falloff_distance = SOUND_DEFAULT_FALLOFF_DISTANCE, _allowed_listeners, _sound_duration_override, _delete_on_end)
|
||||
source = _source
|
||||
RegisterSignal(source, COMSIG_QDELETING, PROC_REF(source_deleted))
|
||||
RegisterSignal(source, COMSIG_MOVABLE_MOVED, PROC_REF(source_moved))
|
||||
@@ -42,6 +47,13 @@
|
||||
volume = _volume
|
||||
falloff_exponent = _falloff_exponent
|
||||
falloff_distance = _falloff_distance
|
||||
sound_duration_override = _sound_duration_override
|
||||
if(_delete_on_end)
|
||||
delete_on_end = _delete_on_end
|
||||
|
||||
if(_allowed_listeners)
|
||||
for(var/allowed_mob in _allowed_listeners)
|
||||
allowed_listeners[allowed_mob] = TRUE
|
||||
|
||||
update_sound(_sound)
|
||||
|
||||
@@ -68,25 +80,32 @@
|
||||
if(!sound_channel)
|
||||
sound_channel = SSsounds.reserve_sound_channel_for_datum(src)
|
||||
sound.channel = sound_channel
|
||||
sound_duration = SSsounds.get_sound_length(_sound)
|
||||
sound_duration = sound_duration_override || SSsounds.get_sound_length(_sound)
|
||||
start_time = REALTIMEOFDAY
|
||||
if(start_playing)
|
||||
force_update_all_listeners(FALSE)
|
||||
if(delete_on_end)
|
||||
addtimer(CALLBACK(src, PROC_REF(on_sound_ended)), sound_duration, TIMER_UNIQUE | TIMER_OVERRIDE)
|
||||
|
||||
|
||||
/// Updates the data of a listener, or adds them if they are not present.
|
||||
/datum/sound_token/proc/add_or_update_listener(mob/listener_mob)
|
||||
if(isnull(listeners[listener_mob]))
|
||||
add_listener(listener_mob)
|
||||
if(!add_listener(listener_mob))
|
||||
return FALSE
|
||||
else
|
||||
update_listener(listener_mob)
|
||||
|
||||
/// Adds a listener to the sound.
|
||||
/// Adds a listener to the sound. returns TRUE if we already were added, or for some reason couldnt be added.
|
||||
/datum/sound_token/proc/add_listener(mob/listener_mob)
|
||||
if(!isnull(listeners[listener_mob]))
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
if(!listener_mob.client || isnewplayer(listener_mob))
|
||||
return
|
||||
return FALSE
|
||||
|
||||
if(allowed_listeners && !allowed_listeners[listener_mob])
|
||||
return FALSE
|
||||
|
||||
listeners[listener_mob] = NONE
|
||||
listener_mob.client.sound_tokens += src
|
||||
@@ -284,3 +303,7 @@
|
||||
|
||||
if(!still_in_range)
|
||||
remove_listener(listener_mob)
|
||||
|
||||
///The sound should have ended on all clients. Time to destroy the sound token.
|
||||
/datum/sound_token/proc/on_sound_ended()
|
||||
qdel(src)
|
||||
|
||||
@@ -219,3 +219,12 @@
|
||||
return soundin
|
||||
var/datum/sound_effect/sfx = GLOB.sfx_datum_by_key[soundin]
|
||||
return sfx?.return_sfx() || soundin
|
||||
|
||||
|
||||
/**
|
||||
* Creates a soundtoken datum (a sound that updates for movement).
|
||||
* allowed_listeners is an optional list of mobs that are the only ones that can hear this sound ever.
|
||||
* sound_length is an optional length of the sound. Things like TTS need to pass this since we can't dynamically grab the length in that case.
|
||||
*/
|
||||
/proc/playsoundtoken(atom/source, soundin, volume, range, falloff_exponent = SOUND_FALLOFF_EXPONENT, falloff_distance = SOUND_DEFAULT_FALLOFF_DISTANCE, allowed_listeners, sound_length)
|
||||
return new /datum/sound_token(source, soundin, range, volume, falloff_exponent, falloff_distance, allowed_listeners, sound_length, _delete_on_end = TRUE)
|
||||
|
||||
@@ -63,7 +63,7 @@
|
||||
message = "screeches!"
|
||||
message_mime = "screeches silently."
|
||||
emote_type = EMOTE_AUDIBLE | EMOTE_VISIBLE
|
||||
specific_emote_audio_cooldown = 10 SECONDS
|
||||
manual_specific_emote_audio_cooldown = 10 SECONDS
|
||||
vary = FALSE
|
||||
|
||||
/datum/emote/living/carbon/human/screech/get_sound(mob/living/carbon/human/user)
|
||||
|
||||
@@ -303,7 +303,7 @@
|
||||
message = "laughs."
|
||||
message_mime = "laughs silently!"
|
||||
emote_type = EMOTE_VISIBLE | EMOTE_AUDIBLE
|
||||
specific_emote_audio_cooldown = 8 SECONDS
|
||||
manual_specific_emote_audio_cooldown = 8 SECONDS
|
||||
vary = TRUE
|
||||
|
||||
/datum/emote/living/laugh/can_run_emote(mob/living/user, status_check = TRUE , intentional, params)
|
||||
@@ -419,7 +419,9 @@
|
||||
emote_type = EMOTE_VISIBLE | EMOTE_AUDIBLE
|
||||
mob_type_blacklist_typecache = list(/mob/living/brain)
|
||||
sound_wall_ignore = TRUE
|
||||
specific_emote_audio_cooldown = 10 SECONDS
|
||||
use_sound_tokens = TRUE
|
||||
manual_specific_emote_audio_cooldown = 10 SECONDS
|
||||
forced_specific_emote_audio_cooldown = 4 SECONDS
|
||||
vary = TRUE
|
||||
|
||||
/datum/emote/living/scream/run_emote(mob/user, params, type_override, intentional = FALSE)
|
||||
|
||||
Reference in New Issue
Block a user