mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-07-22 05:25:15 +01:00
Changes how weather sends sound to players, reduces sound loop overtime (#59284)
* Converts looping sounds from a list of play locations to just the one * Updates all uses of looping sounds to match the new arg * Adds an area based sound manager that hooks into looping sounds to drive the actual audio. I'll be using this to redo how weather effects handle sound * Some structrual stuff to make everything else smoother Timers now properly return the time left for client based timers Weather sends global signals when it starts/stops Looping sounds now use their timerid var for all their sound related timers, not just the main loop * This is the painful part Adds an area sound manager component, it handles the logic of moving into new areas potentially creating new sound loops. We do some extra work to prevent stacking sound loops. Adds an ash storm listener element that adds a tailored area sound manager to clients on the lavaland z level. It's removed on logout. Adds the ash_storm_sounds assoc list, a reference to this is passed into area sound managers, and it's modified in a manner that doesn't break the reference in ash_storm (This is what I hate) * Hooks ash storm listener into cliented mobs and possessed objects * Documents the odd ref stuff, adds an ignore start var to looping sounds, fixes some errors and lint issues * Applies kyler's review banging Co-authored-by: Kylerace <kylerlumpkin1@gmail.com> * Cleans up some var names, reduces the amount of looping we do in some areas * Makes the code compile, redoes the movement listener to be more general * fuck * We don't need to detach on del if we're just removing signals on detach * Should? work * if(direct) memes Co-authored-by: Kylerace <kylerlumpkin1@gmail.com>
This commit is contained in:
@@ -40,6 +40,11 @@
|
||||
#define LINKED_UP (1<<0)
|
||||
/// an obj/item is created! (obj/item/created_item)
|
||||
#define COMSIG_GLOB_NEW_ITEM "!new_item"
|
||||
/// a weather event of some kind occured
|
||||
#define COMSIG_WEATHER_TELEGRAPH(event_type) "!weather_telegraph [event_type]"
|
||||
#define COMSIG_WEATHER_START(event_type) "!weather_start [event_type]"
|
||||
#define COMSIG_WEATHER_WINDDOWN(event_type) "!weather_winddown [event_type]"
|
||||
#define COMSIG_WEATHER_END(event_type) "!weather_end [event_type]"
|
||||
|
||||
/// signals from globally accessible objects
|
||||
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
//A reference to this list is passed into area sound managers, and it's modified in a manner that preserves that reference in ash_storm.dm
|
||||
GLOBAL_LIST_EMPTY(ash_storm_sounds)
|
||||
@@ -632,7 +632,9 @@ SUBSYSTEM_DEF(timer)
|
||||
timer_subsystem = timer_subsystem || SStimer
|
||||
//id is string
|
||||
var/datum/timedevent/timer = timer_subsystem.timer_id_dict[id]
|
||||
return (timer && !timer.spent) ? timer.timeToRun - world.time : null
|
||||
if(!timer || timer.spent)
|
||||
return null
|
||||
return timer.timeToRun - (timer.flags & TIMER_CLIENT_TIME ? REALTIMEOFDAY : world.time)
|
||||
|
||||
#undef BUCKET_LEN
|
||||
#undef BUCKET_POS
|
||||
|
||||
@@ -16,22 +16,21 @@ SUBSYSTEM_DEF(weather)
|
||||
/datum/controller/subsystem/weather/fire()
|
||||
// process active weather
|
||||
for(var/V in processing)
|
||||
var/datum/weather/W = V
|
||||
if(W.aesthetic || W.stage != MAIN_STAGE)
|
||||
var/datum/weather/our_event = V
|
||||
if(our_event.aesthetic || our_event.stage != MAIN_STAGE)
|
||||
continue
|
||||
for(var/i in GLOB.mob_living_list)
|
||||
var/mob/living/L = i
|
||||
if(W.can_weather_act(L))
|
||||
W.weather_act(L)
|
||||
for(var/mob/act_on as anything in GLOB.mob_living_list)
|
||||
if(our_event.can_weather_act(act_on))
|
||||
our_event.weather_act(act_on)
|
||||
|
||||
// start random weather on relevant levels
|
||||
for(var/z in eligible_zlevels)
|
||||
var/possible_weather = eligible_zlevels[z]
|
||||
var/datum/weather/W = pickweight(possible_weather)
|
||||
run_weather(W, list(text2num(z)))
|
||||
var/datum/weather/our_event = pickweight(possible_weather)
|
||||
run_weather(our_event, list(text2num(z)))
|
||||
eligible_zlevels -= z
|
||||
var/randTime = rand(3000, 6000)
|
||||
next_hit_by_zlevel["[z]"] = addtimer(CALLBACK(src, .proc/make_eligible, z, possible_weather), randTime + initial(W.weather_duration_upper), TIMER_UNIQUE|TIMER_STOPPABLE) //Around 5-10 minutes between weathers
|
||||
next_hit_by_zlevel["[z]"] = addtimer(CALLBACK(src, .proc/make_eligible, z, possible_weather), randTime + initial(our_event.weather_duration_upper), TIMER_UNIQUE|TIMER_STOPPABLE) //Around 5-10 minutes between weathers
|
||||
|
||||
/datum/controller/subsystem/weather/Initialize(start_timeofday)
|
||||
for(var/V in subtypesof(/datum/weather))
|
||||
|
||||
@@ -50,7 +50,7 @@
|
||||
var/atom/parent_atom = parent
|
||||
RegisterSignal(parent, COMSIG_ATOM_UPDATE_OVERLAYS, .proc/on_update_overlays)
|
||||
parent_atom.update_appearance()
|
||||
sizzle = new(list(parent), TRUE)
|
||||
sizzle = new(parent, TRUE)
|
||||
START_PROCESSING(SSacid, src)
|
||||
|
||||
/datum/component/acid/Destroy(force, silent)
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
///Allows you to set a theme for a set of areas without tying them to looping sounds explicitly
|
||||
/datum/component/area_sound_manager
|
||||
///area -> looping sound type
|
||||
var/list/area_to_looping_type = list()
|
||||
///Current sound loop
|
||||
var/datum/looping_sound/our_loop
|
||||
///A list of "acceptable" z levels to be on. If you leave this, we're gonna delete ourselves
|
||||
var/list/accepted_zs
|
||||
///The timer id of our current start delay, if it exists
|
||||
var/timerid
|
||||
|
||||
/datum/component/area_sound_manager/Initialize(area_loop_pairs, change_on, remove_on, acceptable_zs)
|
||||
if(!ismovable(parent))
|
||||
return
|
||||
area_to_looping_type = area_loop_pairs
|
||||
accepted_zs = acceptable_zs
|
||||
change_the_track()
|
||||
|
||||
RegisterSignal(parent, COMSIG_MOVABLE_MOVED, .proc/react_to_move)
|
||||
RegisterSignal(parent, COMSIG_MOVABLE_Z_CHANGED, .proc/react_to_z_move)
|
||||
RegisterSignal(parent, change_on, .proc/handle_change)
|
||||
RegisterSignal(parent, remove_on, .proc/handle_removal)
|
||||
|
||||
/datum/component/area_sound_manager/Destroy(force, silent)
|
||||
QDEL_NULL(our_loop)
|
||||
. = ..()
|
||||
|
||||
/datum/component/area_sound_manager/proc/react_to_move(datum/source, atom/oldloc, dir, forced)
|
||||
SIGNAL_HANDLER
|
||||
var/list/loop_lookup = area_to_looping_type
|
||||
if(loop_lookup[get_area(oldloc)] == loop_lookup[get_area(parent)])
|
||||
return
|
||||
change_the_track(TRUE)
|
||||
|
||||
/datum/component/area_sound_manager/proc/react_to_z_move(datum/source, old_z, new_z)
|
||||
SIGNAL_HANDLER
|
||||
if(!length(accepted_zs) || (new_z in accepted_zs))
|
||||
return
|
||||
qdel(src)
|
||||
|
||||
/datum/component/area_sound_manager/proc/handle_removal(datum/source)
|
||||
SIGNAL_HANDLER
|
||||
qdel(src)
|
||||
|
||||
/datum/component/area_sound_manager/proc/handle_change(datum/source)
|
||||
SIGNAL_HANDLER
|
||||
change_the_track()
|
||||
|
||||
/datum/component/area_sound_manager/proc/change_the_track(skip_start = FALSE)
|
||||
var/time_remaining = 0
|
||||
|
||||
if(our_loop)
|
||||
var/our_id = our_loop.timerid || timerid
|
||||
if(our_id)
|
||||
time_remaining = timeleft(our_id, SSsound_loops) || 0
|
||||
//Time left will sometimes return negative values, just ignore them and start a new sound loop now
|
||||
time_remaining = max(time_remaining, 0)
|
||||
QDEL_NULL(our_loop)
|
||||
|
||||
var/area/our_area = get_area(parent)
|
||||
var/new_loop_type = area_to_looping_type[our_area]
|
||||
if(!new_loop_type)
|
||||
return
|
||||
|
||||
our_loop = new new_loop_type(parent, FALSE, TRUE, skip_start)
|
||||
|
||||
//If we're still playing, wait a bit before changing the sound so we don't double up
|
||||
if(time_remaining)
|
||||
timerid = addtimer(CALLBACK(src, .proc/start_looping_sound), time_remaining, TIMER_UNIQUE | TIMER_CLIENT_TIME | TIMER_STOPPABLE | TIMER_NO_HASH_WAIT | TIMER_DELETE_ME, SSsound_loops)
|
||||
return
|
||||
timerid = null
|
||||
our_loop.start()
|
||||
|
||||
/datum/component/area_sound_manager/proc/start_looping_sound()
|
||||
timerid = null
|
||||
if(our_loop)
|
||||
our_loop.start()
|
||||
@@ -0,0 +1,45 @@
|
||||
///This element just handles creating and destroying an area sound manager that's hooked into weather stuff
|
||||
/datum/element/weather_listener
|
||||
element_flags = ELEMENT_BESPOKE
|
||||
id_arg_index = 2
|
||||
var/weather_type
|
||||
//What events to change the track on
|
||||
var/list/sound_change_signals
|
||||
//The weather type we're working with
|
||||
var/weather_trait
|
||||
//The playlist of sounds to draw from. Pass by ref
|
||||
var/list/playlist
|
||||
|
||||
|
||||
/datum/element/weather_listener/Attach(datum/target, w_type, trait, weather_playlist)
|
||||
. = ..()
|
||||
if(!weather_type)
|
||||
weather_type = w_type
|
||||
sound_change_signals = list(
|
||||
COMSIG_WEATHER_TELEGRAPH(weather_type),
|
||||
COMSIG_WEATHER_START(weather_type),
|
||||
COMSIG_WEATHER_WINDDOWN(weather_type),
|
||||
COMSIG_WEATHER_END(weather_type)
|
||||
)
|
||||
weather_trait = trait
|
||||
playlist = weather_playlist
|
||||
|
||||
RegisterSignal(target, COMSIG_MOVABLE_Z_CHANGED, .proc/handle_z_level_change)
|
||||
RegisterSignal(target, COMSIG_MOB_LOGOUT, .proc/handle_logout)
|
||||
|
||||
/datum/element/weather_listener/Detach(datum/source)
|
||||
. = ..()
|
||||
UnregisterSignal(source, COMSIG_MOVABLE_Z_CHANGED, COMSIG_MOB_LOGOUT)
|
||||
|
||||
/datum/element/weather_listener/proc/handle_z_level_change(datum/source, old_z, new_z)
|
||||
SIGNAL_HANDLER
|
||||
var/list/fitting_z_levels = SSmapping.levels_by_trait(weather_trait)
|
||||
if(!(new_z in fitting_z_levels))
|
||||
return
|
||||
var/datum/component/our_comp = source.AddComponent(/datum/component/area_sound_manager, playlist, list(), COMSIG_MOB_LOGOUT, fitting_z_levels)
|
||||
our_comp.RegisterSignal(SSdcs, sound_change_signals, /datum/component/area_sound_manager/proc/handle_change)
|
||||
|
||||
/datum/element/weather_listener/proc/handle_logout(datum/source)
|
||||
SIGNAL_HANDLER
|
||||
source.RemoveElement(/datum/element/weather_listener, weather_type, weather_trait, playlist)
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
direct (bool) If true plays directly to provided atoms instead of from them
|
||||
*/
|
||||
/datum/looping_sound
|
||||
var/list/atom/output_atoms
|
||||
var/atom/parent
|
||||
var/mid_sounds
|
||||
var/mid_length
|
||||
///Override for volume of start sound
|
||||
@@ -34,38 +34,46 @@
|
||||
var/falloff_exponent
|
||||
var/timerid
|
||||
var/falloff_distance
|
||||
var/skip_starting_sounds = FALSE
|
||||
var/loop_started = FALSE
|
||||
|
||||
/datum/looping_sound/New(list/_output_atoms=list(), start_immediately=FALSE, _direct=FALSE)
|
||||
/datum/looping_sound/New(_parent, start_immediately=FALSE, _direct=FALSE, _skip_starting_sounds = FALSE)
|
||||
if(!mid_sounds)
|
||||
WARNING("A looping sound datum was created without sounds to play.")
|
||||
return
|
||||
|
||||
output_atoms = _output_atoms
|
||||
set_parent(_parent)
|
||||
direct = _direct
|
||||
skip_starting_sounds = _skip_starting_sounds
|
||||
|
||||
if(start_immediately)
|
||||
start()
|
||||
|
||||
/datum/looping_sound/Destroy()
|
||||
stop()
|
||||
output_atoms = null
|
||||
stop(TRUE)
|
||||
return ..()
|
||||
|
||||
/datum/looping_sound/proc/start(atom/add_thing)
|
||||
if(add_thing)
|
||||
output_atoms |= add_thing
|
||||
/datum/looping_sound/proc/start(on_behalf_of)
|
||||
if(on_behalf_of)
|
||||
set_parent(on_behalf_of)
|
||||
if(timerid)
|
||||
return
|
||||
on_start()
|
||||
|
||||
/datum/looping_sound/proc/stop(atom/remove_thing)
|
||||
if(remove_thing)
|
||||
output_atoms -= remove_thing
|
||||
/datum/looping_sound/proc/stop(null_parent)
|
||||
if(null_parent)
|
||||
set_parent(null)
|
||||
if(!timerid)
|
||||
return
|
||||
on_stop()
|
||||
deltimer(timerid, SSsound_loops)
|
||||
timerid = null
|
||||
loop_started = FALSE
|
||||
|
||||
/datum/looping_sound/proc/start_sound_loop()
|
||||
loop_started = TRUE
|
||||
sound_loop()
|
||||
timerid = addtimer(CALLBACK(src, .proc/sound_loop, world.time), mid_length, TIMER_CLIENT_TIME | TIMER_STOPPABLE | TIMER_LOOP | TIMER_DELETE_ME, SSsound_loops)
|
||||
|
||||
/datum/looping_sound/proc/sound_loop(starttime)
|
||||
if(max_loops && world.time >= starttime + mid_length * max_loops)
|
||||
@@ -73,21 +81,15 @@
|
||||
return
|
||||
if(!chance || prob(chance))
|
||||
play(get_sound(starttime))
|
||||
if(!timerid)
|
||||
timerid = addtimer(CALLBACK(src, .proc/sound_loop, world.time), mid_length, TIMER_CLIENT_TIME | TIMER_STOPPABLE | TIMER_LOOP, SSsound_loops)
|
||||
|
||||
/datum/looping_sound/proc/play(soundfile, volume_override)
|
||||
var/list/atoms_cache = output_atoms
|
||||
var/sound/S = sound(soundfile)
|
||||
if(direct)
|
||||
S.channel = SSsounds.random_available_channel()
|
||||
S.volume = volume_override || volume //Use volume as fallback if theres no override
|
||||
for(var/i in 1 to atoms_cache.len)
|
||||
var/atom/thing = atoms_cache[i]
|
||||
if(direct)
|
||||
SEND_SOUND(thing, S)
|
||||
else
|
||||
playsound(thing, S, volume, vary, extra_range, falloff_exponent = falloff_exponent, falloff_distance = falloff_distance)
|
||||
SEND_SOUND(parent, S)
|
||||
else
|
||||
playsound(parent, S, volume, vary, extra_range, falloff_exponent = falloff_exponent, falloff_distance = falloff_distance)
|
||||
|
||||
/datum/looping_sound/proc/get_sound(starttime, _mid_sounds)
|
||||
. = _mid_sounds || mid_sounds
|
||||
@@ -96,11 +98,22 @@
|
||||
|
||||
/datum/looping_sound/proc/on_start()
|
||||
var/start_wait = 0
|
||||
if(start_sound)
|
||||
if(start_sound && !skip_starting_sounds)
|
||||
play(start_sound, start_volume)
|
||||
start_wait = start_length
|
||||
addtimer(CALLBACK(src, .proc/sound_loop), start_wait, TIMER_CLIENT_TIME, SSsound_loops)
|
||||
timerid = addtimer(CALLBACK(src, .proc/start_sound_loop), start_wait, TIMER_CLIENT_TIME | TIMER_DELETE_ME | TIMER_STOPPABLE, SSsound_loops)
|
||||
|
||||
/datum/looping_sound/proc/on_stop()
|
||||
if(end_sound)
|
||||
if(end_sound && loop_started)
|
||||
play(end_sound, end_volume)
|
||||
|
||||
/datum/looping_sound/proc/set_parent(new_parent)
|
||||
if(parent)
|
||||
UnregisterSignal(parent, COMSIG_PARENT_QDELETING)
|
||||
parent = new_parent
|
||||
if(parent)
|
||||
RegisterSignal(parent, COMSIG_PARENT_QDELETING, .proc/handle_parent_del)
|
||||
|
||||
/datum/looping_sound/proc/handle_parent_del(datum/source)
|
||||
SIGNAL_HANDLER
|
||||
set_parent(null)
|
||||
|
||||
@@ -51,6 +51,3 @@
|
||||
mid_length = 1669 // exact length of the music in ticks
|
||||
volume = 100
|
||||
extra_range = 30
|
||||
|
||||
/datum/looping_sound/void_loop/start(atom/add_thing)
|
||||
. = ..()
|
||||
|
||||
@@ -94,6 +94,7 @@
|
||||
/datum/weather/proc/telegraph()
|
||||
if(stage == STARTUP_STAGE)
|
||||
return
|
||||
SEND_GLOBAL_SIGNAL(COMSIG_WEATHER_TELEGRAPH(type))
|
||||
stage = STARTUP_STAGE
|
||||
var/list/affectareas = list()
|
||||
for(var/V in get_areas(area_type))
|
||||
@@ -109,13 +110,15 @@
|
||||
weather_duration = rand(weather_duration_lower, weather_duration_upper)
|
||||
START_PROCESSING(SSweather, src)
|
||||
update_areas()
|
||||
for(var/M in GLOB.player_list)
|
||||
var/turf/mob_turf = get_turf(M)
|
||||
if(mob_turf && (mob_turf.z in impacted_z_levels))
|
||||
for(var/z_level in impacted_z_levels)
|
||||
for(var/mob/player as anything in SSmobs.clients_by_zlevel[z_level])
|
||||
var/turf/mob_turf = get_turf(player)
|
||||
if(!mob_turf)
|
||||
continue
|
||||
if(telegraph_message)
|
||||
to_chat(M, telegraph_message)
|
||||
to_chat(player, telegraph_message)
|
||||
if(telegraph_sound)
|
||||
SEND_SOUND(M, sound(telegraph_sound))
|
||||
SEND_SOUND(player, sound(telegraph_sound))
|
||||
addtimer(CALLBACK(src, .proc/start), telegraph_duration)
|
||||
|
||||
/**
|
||||
@@ -128,15 +131,18 @@
|
||||
/datum/weather/proc/start()
|
||||
if(stage >= MAIN_STAGE)
|
||||
return
|
||||
SEND_GLOBAL_SIGNAL(COMSIG_WEATHER_START(type))
|
||||
stage = MAIN_STAGE
|
||||
update_areas()
|
||||
for(var/M in GLOB.player_list)
|
||||
var/turf/mob_turf = get_turf(M)
|
||||
if(mob_turf && (mob_turf.z in impacted_z_levels))
|
||||
for(var/z_level in impacted_z_levels)
|
||||
for(var/mob/player as anything in SSmobs.clients_by_zlevel[z_level])
|
||||
var/turf/mob_turf = get_turf(player)
|
||||
if(!mob_turf)
|
||||
continue
|
||||
if(weather_message)
|
||||
to_chat(M, weather_message)
|
||||
to_chat(player, weather_message)
|
||||
if(weather_sound)
|
||||
SEND_SOUND(M, sound(weather_sound))
|
||||
SEND_SOUND(player, sound(weather_sound))
|
||||
if(!perpetual)
|
||||
addtimer(CALLBACK(src, .proc/wind_down), weather_duration)
|
||||
|
||||
@@ -150,15 +156,18 @@
|
||||
/datum/weather/proc/wind_down()
|
||||
if(stage >= WIND_DOWN_STAGE)
|
||||
return
|
||||
SEND_GLOBAL_SIGNAL(COMSIG_WEATHER_WINDDOWN(type))
|
||||
stage = WIND_DOWN_STAGE
|
||||
update_areas()
|
||||
for(var/M in GLOB.player_list)
|
||||
var/turf/mob_turf = get_turf(M)
|
||||
if(mob_turf && (mob_turf.z in impacted_z_levels))
|
||||
for(var/z_level in impacted_z_levels)
|
||||
for(var/mob/player as anything in SSmobs.clients_by_zlevel[z_level])
|
||||
var/turf/mob_turf = get_turf(player)
|
||||
if(!mob_turf)
|
||||
continue
|
||||
if(end_message)
|
||||
to_chat(M, end_message)
|
||||
to_chat(player, end_message)
|
||||
if(end_sound)
|
||||
SEND_SOUND(M, sound(end_sound))
|
||||
SEND_SOUND(player, sound(end_sound))
|
||||
addtimer(CALLBACK(src, .proc/end), end_duration)
|
||||
|
||||
/**
|
||||
@@ -170,7 +179,8 @@
|
||||
*/
|
||||
/datum/weather/proc/end()
|
||||
if(stage == END_STAGE)
|
||||
return 1
|
||||
return
|
||||
SEND_GLOBAL_SIGNAL(COMSIG_WEATHER_END(type))
|
||||
stage = END_STAGE
|
||||
STOP_PROCESSING(SSweather, src)
|
||||
update_areas()
|
||||
@@ -179,13 +189,13 @@
|
||||
* Returns TRUE if the living mob can be affected by the weather
|
||||
*
|
||||
*/
|
||||
/datum/weather/proc/can_weather_act(mob/living/L)
|
||||
var/turf/mob_turf = get_turf(L)
|
||||
/datum/weather/proc/can_weather_act(mob/living/act_on)
|
||||
var/turf/mob_turf = get_turf(act_on)
|
||||
if(mob_turf && !(mob_turf.z in impacted_z_levels))
|
||||
return
|
||||
if(immunity_type in L.weather_immunities)
|
||||
if(immunity_type in act_on.weather_immunities)
|
||||
return
|
||||
if(!(get_area(L) in impacted_areas))
|
||||
if(!(get_area(act_on) in impacted_areas))
|
||||
return
|
||||
return TRUE
|
||||
|
||||
|
||||
@@ -25,55 +25,41 @@
|
||||
probability = 90
|
||||
|
||||
barometer_predictable = TRUE
|
||||
|
||||
var/datum/looping_sound/active_outside_ashstorm/sound_ao = new(list(), FALSE, TRUE)
|
||||
var/datum/looping_sound/active_inside_ashstorm/sound_ai = new(list(), FALSE, TRUE)
|
||||
var/datum/looping_sound/weak_outside_ashstorm/sound_wo = new(list(), FALSE, TRUE)
|
||||
var/datum/looping_sound/weak_inside_ashstorm/sound_wi = new(list(), FALSE, TRUE)
|
||||
var/list/weak_sounds = list()
|
||||
var/list/strong_sounds = list()
|
||||
|
||||
/datum/weather/ash_storm/telegraph()
|
||||
. = ..()
|
||||
var/list/inside_areas = list()
|
||||
var/list/outside_areas = list()
|
||||
var/list/eligible_areas = list()
|
||||
for (var/z in impacted_z_levels)
|
||||
eligible_areas += SSmapping.areas_in_z["[z]"]
|
||||
for(var/i in 1 to eligible_areas.len)
|
||||
var/area/place = eligible_areas[i]
|
||||
if(place.outdoors)
|
||||
outside_areas += place
|
||||
weak_sounds[place] = /datum/looping_sound/weak_outside_ashstorm
|
||||
strong_sounds[place] = /datum/looping_sound/active_outside_ashstorm
|
||||
else
|
||||
inside_areas += place
|
||||
weak_sounds[place] = /datum/looping_sound/weak_inside_ashstorm
|
||||
strong_sounds[place] = /datum/looping_sound/active_inside_ashstorm
|
||||
CHECK_TICK
|
||||
|
||||
sound_ao.output_atoms = outside_areas
|
||||
sound_ai.output_atoms = inside_areas
|
||||
sound_wo.output_atoms = outside_areas
|
||||
sound_wi.output_atoms = inside_areas
|
||||
|
||||
sound_wo.start()
|
||||
sound_wi.start()
|
||||
//We modify this list instead of setting it to weak/stron sounds in order to preserve things that hold a reference to it
|
||||
//It's essentially a playlist for a bunch of components that chose what sound to loop based on the area a player is in
|
||||
GLOB.ash_storm_sounds += weak_sounds
|
||||
return ..()
|
||||
|
||||
/datum/weather/ash_storm/start()
|
||||
. = ..()
|
||||
sound_wo.stop()
|
||||
sound_wi.stop()
|
||||
|
||||
sound_ao.start()
|
||||
sound_ai.start()
|
||||
GLOB.ash_storm_sounds -= weak_sounds
|
||||
GLOB.ash_storm_sounds += strong_sounds
|
||||
return ..()
|
||||
|
||||
/datum/weather/ash_storm/wind_down()
|
||||
. = ..()
|
||||
sound_ao.stop()
|
||||
sound_ai.stop()
|
||||
|
||||
sound_wo.start()
|
||||
sound_wi.start()
|
||||
GLOB.ash_storm_sounds -= strong_sounds
|
||||
GLOB.ash_storm_sounds += weak_sounds
|
||||
return ..()
|
||||
|
||||
/datum/weather/ash_storm/end()
|
||||
. = ..()
|
||||
sound_wo.stop()
|
||||
sound_wi.stop()
|
||||
GLOB.ash_storm_sounds -= weak_sounds
|
||||
return ..()
|
||||
|
||||
/datum/weather/ash_storm/proc/is_ash_immune(atom/L)
|
||||
while (L && !isturf(L))
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
|
||||
/obj/machinery/fat_sucker/Initialize()
|
||||
. = ..()
|
||||
soundloop = new(list(src), FALSE)
|
||||
soundloop = new(src, FALSE)
|
||||
update_appearance()
|
||||
|
||||
/obj/machinery/fat_sucker/Destroy()
|
||||
|
||||
@@ -51,7 +51,7 @@
|
||||
|
||||
/obj/machinery/roulette/Initialize()
|
||||
. = ..()
|
||||
jackpot_loop = new(list(src), FALSE)
|
||||
jackpot_loop = new(src, FALSE)
|
||||
wires = new /datum/wires/roulette(src)
|
||||
|
||||
/obj/machinery/roulette/Destroy()
|
||||
|
||||
@@ -84,7 +84,7 @@ GLOBAL_LIST_EMPTY(telecomms_list)
|
||||
|
||||
/obj/machinery/telecomms/Initialize(mapload)
|
||||
. = ..()
|
||||
soundloop = new(list(src), on)
|
||||
soundloop = new(src, on)
|
||||
GLOB.telecomms_list += src
|
||||
if(mapload && autolinkers.len)
|
||||
return INITIALIZE_HINT_LATELOAD
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
. = ..()
|
||||
START_PROCESSING(SSobj, src)
|
||||
|
||||
soundloop = new(list(src), FALSE)
|
||||
soundloop = new(src, FALSE)
|
||||
|
||||
/obj/item/geiger_counter/Destroy()
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
|
||||
@@ -23,8 +23,8 @@
|
||||
|
||||
/obj/item/reverse_bear_trap/Initialize()
|
||||
. = ..()
|
||||
soundloop = new(list(src))
|
||||
soundloop2 = new(list(src))
|
||||
soundloop = new(src)
|
||||
soundloop2 = new(src)
|
||||
|
||||
/obj/item/reverse_bear_trap/Destroy()
|
||||
QDEL_NULL(soundloop)
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
. = ..()
|
||||
if(starting_tape_type)
|
||||
mytape = new starting_tape_type(src)
|
||||
soundloop = new(list(src))
|
||||
soundloop = new(src)
|
||||
update_appearance()
|
||||
|
||||
/obj/item/taperecorder/Destroy()
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
. = ..()
|
||||
create_reagents(reagent_capacity)
|
||||
reagents.add_reagent(reagent_id, reagent_capacity)
|
||||
soundloop = new(list(src), FALSE)
|
||||
soundloop = new(src, FALSE)
|
||||
AddComponent(/datum/component/plumbing/simple_demand)
|
||||
var/static/list/loc_connections = list(
|
||||
COMSIG_ATOM_ENTERED = .proc/on_entered,
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
usr.name = O.name
|
||||
usr.reset_perspective(O)
|
||||
usr.control_object = O
|
||||
O.AddElement(/datum/element/weather_listener, /datum/weather/ash_storm, ZTRAIT_ASHSTORM, GLOB.ash_storm_sounds)
|
||||
SSblackbox.record_feedback("tally", "admin_verb", 1, "Possess Object") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
/proc/release()
|
||||
@@ -38,7 +39,7 @@
|
||||
var/mob/living/carbon/human/H = usr
|
||||
H.name = H.get_visible_name()
|
||||
|
||||
|
||||
usr.control_object.RemoveElement(/datum/element/weather_listener, /datum/weather/ash_storm, ZTRAIT_ASHSTORM, GLOB.ash_storm_sounds)
|
||||
usr.forceMove(get_turf(usr.control_object))
|
||||
usr.reset_perspective()
|
||||
usr.control_object = null
|
||||
|
||||
@@ -191,7 +191,7 @@
|
||||
waltzing.client?.give_award(/datum/award/achievement/misc/void_ascension, waltzing)
|
||||
priority_announce("$^@&#*$^@(#&$(@&#^$&#^@# The nobleman of void [waltzing.real_name] has arrived, step along the Waltz that ends worlds! $^@&#*$^@(#&$(@&#^$&#^@#","#$^@&#*$^@(#&$(@&#^$&#^@#", ANNOUNCER_SPANOMALIES)
|
||||
|
||||
sound_loop = new(list(user),TRUE,TRUE)
|
||||
sound_loop = new(user, TRUE, TRUE)
|
||||
return ..()
|
||||
|
||||
/datum/eldritch_knowledge/final/void_final/on_death()
|
||||
|
||||
@@ -103,7 +103,7 @@
|
||||
corner.active = TRUE
|
||||
corner.update_appearance()
|
||||
RegisterSignal(corner, COMSIG_PARENT_QDELETING, .proc/unregister_signals)
|
||||
soundloop = new(list(src), TRUE)
|
||||
soundloop = new(src, TRUE)
|
||||
soundloop.volume = 5
|
||||
|
||||
/**
|
||||
|
||||
@@ -158,7 +158,7 @@
|
||||
|
||||
/obj/item/clothing/head/helmet/justice/Initialize()
|
||||
. = ..()
|
||||
weewooloop = new(list(src), FALSE, FALSE)
|
||||
weewooloop = new(src, FALSE, FALSE)
|
||||
|
||||
/obj/item/clothing/head/helmet/justice/Destroy()
|
||||
QDEL_NULL(weewooloop)
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
|
||||
/obj/item/clothing/head/helmet/space/hardsuit/Initialize()
|
||||
. = ..()
|
||||
soundloop = new(list(), FALSE, TRUE)
|
||||
soundloop = new(src, FALSE, TRUE)
|
||||
soundloop.volume = 5
|
||||
START_PROCESSING(SSobj, src)
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@ GLOBAL_LIST_INIT(oilfry_blacklisted_items, typecacheof(list(
|
||||
. = ..()
|
||||
create_reagents(50, OPENCONTAINER)
|
||||
reagents.add_reagent(/datum/reagent/consumable/cooking_oil, 25)
|
||||
fry_loop = new(list(src), FALSE)
|
||||
fry_loop = new(src, FALSE)
|
||||
|
||||
/obj/machinery/deepfryer/Destroy()
|
||||
QDEL_NULL(fry_loop)
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
|
||||
/obj/machinery/griddle/Initialize()
|
||||
. = ..()
|
||||
grill_loop = new(list(src), FALSE)
|
||||
grill_loop = new(src, FALSE)
|
||||
if(isnum(variant))
|
||||
variant = rand(1,3)
|
||||
RegisterSignal(src, COMSIG_ATOM_EXPOSE_REAGENT, .proc/on_expose_reagent)
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
|
||||
/obj/machinery/grill/Initialize()
|
||||
. = ..()
|
||||
grill_loop = new(list(src), FALSE)
|
||||
grill_loop = new(src, FALSE)
|
||||
|
||||
/obj/machinery/grill/Destroy()
|
||||
QDEL_NULL(grill_loop)
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
. = ..()
|
||||
wires = new /datum/wires/microwave(src)
|
||||
create_reagents(100)
|
||||
soundloop = new(list(src), FALSE)
|
||||
soundloop = new(src, FALSE)
|
||||
|
||||
/obj/machinery/microwave/Destroy()
|
||||
eject()
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
* * grant any actions the mob has to the client
|
||||
* * calls [auto_deadmin_on_login](mob.html#proc/auto_deadmin_on_login)
|
||||
* * send signal COMSIG_MOB_CLIENT_LOGIN
|
||||
* * attaches the ash listener element so clients can hear weather
|
||||
* client can be deleted mid-execution of this proc, chiefly on parent calls, with lag
|
||||
*/
|
||||
/mob/Login()
|
||||
@@ -94,6 +95,8 @@
|
||||
SEND_SIGNAL(src, COMSIG_MOB_CLIENT_LOGIN, client)
|
||||
client.init_verbs()
|
||||
|
||||
AddElement(/datum/element/weather_listener, /datum/weather/ash_storm, ZTRAIT_ASHSTORM, GLOB.ash_storm_sounds)
|
||||
|
||||
return TRUE
|
||||
|
||||
|
||||
|
||||
@@ -61,7 +61,7 @@
|
||||
comp_light_color = "#FFFFFF"
|
||||
idle_threads = list()
|
||||
if(looping_sound)
|
||||
soundloop = new(list(src), enabled)
|
||||
soundloop = new(src, enabled)
|
||||
update_appearance()
|
||||
|
||||
/obj/item/modular_computer/Destroy()
|
||||
|
||||
@@ -32,7 +32,7 @@ GLOBAL_LIST_EMPTY(gravity_generators) // We will keep track of this by adding ne
|
||||
|
||||
/obj/machinery/gravity_generator/main/Initialize()
|
||||
. = ..()
|
||||
soundloop = new(list(src), TRUE)
|
||||
soundloop = new(src, TRUE)
|
||||
|
||||
/obj/machinery/gravity_generator/main/Destroy()
|
||||
. = ..()
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
|
||||
/obj/machinery/power/port_gen/Initialize()
|
||||
. = ..()
|
||||
soundloop = new(list(src), active)
|
||||
soundloop = new(src, active)
|
||||
|
||||
/obj/machinery/power/port_gen/Destroy()
|
||||
QDEL_NULL(soundloop)
|
||||
|
||||
@@ -242,7 +242,7 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal)
|
||||
AddElement(/datum/element/bsa_blocker)
|
||||
RegisterSignal(src, COMSIG_ATOM_BSA_BEAM, .proc/call_explode)
|
||||
|
||||
soundloop = new(list(src), TRUE)
|
||||
soundloop = new(src, TRUE)
|
||||
if(ispath(psyOverlay))
|
||||
psyOverlay = new psyOverlay()
|
||||
else
|
||||
|
||||
@@ -151,6 +151,7 @@
|
||||
#include "code\__DEFINES\vehicles.dm"
|
||||
#include "code\__DEFINES\vv.dm"
|
||||
#include "code\__DEFINES\wall_dents.dm"
|
||||
#include "code\__DEFINES\weather.dm"
|
||||
#include "code\__DEFINES\wiremod.dm"
|
||||
#include "code\__DEFINES\wires.dm"
|
||||
#include "code\__DEFINES\wounds.dm"
|
||||
@@ -486,6 +487,7 @@
|
||||
#include "code\datums\components\acid.dm"
|
||||
#include "code\datums\components\anti_magic.dm"
|
||||
#include "code\datums\components\aquarium.dm"
|
||||
#include "code\datums\components\area_sound_manager.dm"
|
||||
#include "code\datums\components\areabound.dm"
|
||||
#include "code\datums\components\armor_plate.dm"
|
||||
#include "code\datums\components\bane.dm"
|
||||
@@ -737,6 +739,7 @@
|
||||
#include "code\datums\elements\volatile_gas_storage.dm"
|
||||
#include "code\datums\elements\waddling.dm"
|
||||
#include "code\datums\elements\weapon_description.dm"
|
||||
#include "code\datums\elements\weather_listener.dm"
|
||||
#include "code\datums\elements\decals\_decal.dm"
|
||||
#include "code\datums\elements\decals\blood.dm"
|
||||
#include "code\datums\elements\food\dunkable.dm"
|
||||
|
||||
Reference in New Issue
Block a user