-
-
Notifications
You must be signed in to change notification settings - Fork 444
/
Copy path_looping_sound.dm
108 lines (90 loc) · 3.02 KB
/
_looping_sound.dm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
/*
output_atoms (list of atoms) The destination(s) for the sounds
mid_sounds (list or soundfile) Since this can be either a list or a single soundfile you can have random sounds. May contain further lists but must contain a soundfile at the end.
mid_length (num) The length to wait between playing mid_sounds
start_sound (soundfile) Played before starting the mid_sounds loop
start_length (num) How long to wait before starting the main loop after playing start_sound
end_sound (soundfile) The sound played after the main loop has concluded
chance (num) Chance per loop to play a mid_sound
volume (num) Sound output volume
max_loops (num) The max amount of loops to run for.
direct (bool) If true plays directly to provided atoms instead of from them
*/
/datum/looping_sound
var/list/atom/output_atoms
var/mid_sounds
var/mid_length
var/start_sound
var/start_length
var/end_sound
var/chance
var/volume = 100
var/max_loops
var/direct
var/extra_range
var/timerid
/datum/looping_sound/New(list/_output_atoms=list(), start_immediately=FALSE, _direct=FALSE)
if(!mid_sounds)
WARNING("A looping sound datum was created without sounds to play.")
return
output_atoms = _output_atoms
direct = _direct
if(start_immediately)
start()
/datum/looping_sound/Destroy()
stop()
output_atoms = null
return ..()
/datum/looping_sound/proc/start(atom/add_thing)
if(add_thing)
output_atoms |= add_thing
if(timerid)
return
on_start()
/datum/looping_sound/proc/stop(atom/remove_thing)
if(remove_thing)
output_atoms -= remove_thing
if(!timerid)
return
on_stop()
deltimer(timerid)
timerid = null
/// The proc that handles starting the actual core sound loop.
/datum/looping_sound/proc/start_sound_loop()
timerid = null // Because we're done with our starting sound.
sound_loop()
/datum/looping_sound/proc/sound_loop(starttime)
if(max_loops && world.time >= starttime + mid_length * max_loops)
stop()
return
if(!chance || prob(chance))
play(get_sound(starttime))
if(!timerid)
timerid = addtimer(CALLBACK(src, PROC_REF(sound_loop), world.time), mid_length, TIMER_CLIENT_TIME | TIMER_DELETE_ME | TIMER_STOPPABLE | TIMER_LOOP)
/datum/looping_sound/proc/play(soundfile)
var/list/atoms_cache = output_atoms
var/sound/S = sound(soundfile)
if(direct)
S.channel = SSsounds.random_available_channel()
S.volume = volume
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, extra_range)
/datum/looping_sound/proc/get_sound(starttime, _mid_sounds)
. = _mid_sounds || mid_sounds
while(!isfile(.) && !isnull(.))
. = pickweight(.)
/datum/looping_sound/proc/on_start()
var/start_wait = 0
if(start_sound)
play(start_sound)
start_wait = start_length
timerid = addtimer(CALLBACK(src, PROC_REF(start_sound_loop)), start_wait, TIMER_CLIENT_TIME | TIMER_DELETE_ME | TIMER_STOPPABLE)
/datum/looping_sound/proc/on_stop()
if(end_sound)
play(end_sound)
/datum/looping_sound/proc/is_active()
return !!timerid