Ports Bees ambience, reverb & sound system (#19559)

* ambience part 1

* almost there

* p3

* 420blazeit

* jesus christ im sorry

* virofix

* hm

* increase max time
This commit is contained in:
azzzertyy
2023-07-12 20:36:22 +01:00
committed by GitHub
parent 9790bdc966
commit 2b4079d1e5
49 changed files with 793 additions and 194 deletions

View File

@@ -5,13 +5,25 @@
#define CHANNEL_JUKEBOX 1021
#define CHANNEL_JUSTICAR_ARK 1020
#define CHANNEL_HEARTBEAT 1019 //sound channel for heartbeats
#define CHANNEL_AMBIENCE 1018
#define CHANNEL_AMBIENT_EFFECTS 1018
#define CHANNEL_AMBIENT_MUSIC 1017
#define CHANNEL_BUZZ 1017
#define CHANNEL_BICYCLE 1016
#define CHANNEL_VOICE_ANNOUNCE 1015
#define CHANNEL_MEGAFAUNA 1014 // battle music
#define CHANNEL_CHARGED_SPELL 1013
///Default range of a sound.
#define SOUND_RANGE 17
///default extra range for sounds considered to be quieter
#define SHORT_RANGE_SOUND_EXTRARANGE -9
///The range deducted from sound range for things that are considered silent / sneaky
#define SILENCED_SOUND_EXTRARANGE -11
///Percentage of sound's range where no falloff is applied
#define SOUND_DEFAULT_FALLOFF_DISTANCE 1 //For a normal sound this would be 1 tile of no falloff
///The default exponent of sound falloff
#define SOUND_FALLOFF_EXPONENT 6
//THIS SHOULD ALWAYS BE THE LOWEST ONE!
//KEEP IT UPDATED
@@ -22,69 +34,71 @@
#define SOUND_MINIMUM_PRESSURE 10
#define FALLOFF_SOUNDS 1
//Ambience types
#define GENERIC list('sound/ambience/ambigen1.ogg','sound/ambience/ambigen3.ogg',\
'sound/ambience/ambigen4.ogg','sound/ambience/ambigen5.ogg',\
'sound/ambience/ambigen6.ogg','sound/ambience/ambigen7.ogg',\
'sound/ambience/ambigen8.ogg','sound/ambience/ambigen9.ogg',\
'sound/ambience/ambigen10.ogg','sound/ambience/ambigen11.ogg',\
'sound/ambience/ambigen12.ogg','sound/ambience/ambigen14.ogg','sound/ambience/ambigen15.ogg')
#define HOLY list('sound/ambience/ambicha1.ogg','sound/ambience/ambicha2.ogg','sound/ambience/ambicha3.ogg',\
'sound/ambience/ambicha4.ogg', 'sound/ambience/ambiholy.ogg', 'sound/ambience/ambiholy2.ogg',\
'sound/ambience/ambiholy3.ogg')
#define HIGHSEC list('sound/ambience/ambidanger.ogg', 'sound/ambience/ambidanger2.ogg')
#define RUINS list('sound/ambience/ambimine.ogg', 'sound/ambience/ambicave.ogg', 'sound/ambience/ambiruin.ogg',\
'sound/ambience/ambiruin2.ogg', 'sound/ambience/ambiruin3.ogg', 'sound/ambience/ambiruin4.ogg',\
'sound/ambience/ambiruin5.ogg', 'sound/ambience/ambiruin6.ogg', 'sound/ambience/ambiruin7.ogg',\
'sound/ambience/ambidanger.ogg', 'sound/ambience/ambidanger2.ogg', 'sound/ambience/ambitech3.ogg',\
'sound/ambience/ambimystery.ogg', 'sound/ambience/ambimaint1.ogg')
#define ENGINEERING list('sound/ambience/ambisin1.ogg','sound/ambience/ambisin2.ogg','sound/ambience/ambisin3.ogg','sound/ambience/ambisin4.ogg',\
'sound/ambience/ambiatmos.ogg', 'sound/ambience/ambiatmos2.ogg', 'sound/ambience/ambitech.ogg', 'sound/ambience/ambitech2.ogg', 'sound/ambience/ambitech3.ogg')
#define MINING list('sound/ambience/ambimine.ogg', 'sound/ambience/ambicave.ogg', 'sound/ambience/ambiruin.ogg',\
'sound/ambience/ambiruin2.ogg', 'sound/ambience/ambiruin3.ogg', 'sound/ambience/ambiruin4.ogg',\
'sound/ambience/ambiruin5.ogg', 'sound/ambience/ambiruin6.ogg', 'sound/ambience/ambiruin7.ogg',\
'sound/ambience/ambidanger.ogg', 'sound/ambience/ambidanger2.ogg', 'sound/ambience/ambimaint1.ogg',\
'sound/ambience/ambilava1.ogg', 'sound/ambience/ambilava2.ogg', 'sound/ambience/ambilava3.ogg')
#define MEDICAL list('sound/ambience/ambinice.ogg')
#define SPOOKY list('sound/ambience/ambimo1.ogg','sound/ambience/ambimo2.ogg','sound/ambience/ambiruin7.ogg','sound/ambience/ambiruin6.ogg',\
'sound/ambience/ambiodd.ogg', 'sound/ambience/ambimystery.ogg')
#define SPACE list('sound/ambience/ambispace.ogg', 'sound/ambience/ambispace2.ogg', 'sound/ambience/title2.ogg', 'sound/ambience/ambiatmos.ogg')
#define MAINTENANCE list('sound/ambience/ambimaint1.ogg', 'sound/ambience/ambimaint2.ogg', 'sound/ambience/ambimaint3.ogg', 'sound/ambience/ambimaint4.ogg',\
'sound/ambience/ambimaint5.ogg', 'sound/voice/lowHiss2.ogg', 'sound/voice/lowHiss3.ogg', 'sound/voice/lowHiss4.ogg', 'sound/ambience/ambitech2.ogg' )
#define AWAY_MISSION list('sound/ambience/ambitech.ogg', 'sound/ambience/ambitech2.ogg', 'sound/ambience/ambiruin.ogg',\
'sound/ambience/ambiruin2.ogg', 'sound/ambience/ambiruin3.ogg', 'sound/ambience/ambiruin4.ogg',\
'sound/ambience/ambiruin5.ogg', 'sound/ambience/ambiruin6.ogg', 'sound/ambience/ambiruin7.ogg',\
'sound/ambience/ambidanger.ogg', 'sound/ambience/ambidanger2.ogg', 'sound/ambience/ambimaint.ogg',\
'sound/ambience/ambiatmos.ogg', 'sound/ambience/ambiatmos2.ogg', 'sound/ambience/ambiodd.ogg')
#define REEBE list('sound/ambience/ambireebe1.ogg', 'sound/ambience/ambireebe2.ogg', 'sound/ambience/ambireebe3.ogg')
#define CREEPY_SOUNDS list('sound/effects/ghost.ogg', 'sound/effects/ghost2.ogg', 'sound/effects/heart_beat.ogg', 'sound/effects/screech.ogg',\
'sound/hallucinations/behind_you1.ogg', 'sound/hallucinations/behind_you2.ogg', 'sound/hallucinations/far_noise.ogg', 'sound/hallucinations/growl1.ogg', 'sound/hallucinations/growl2.ogg',\
'sound/hallucinations/growl3.ogg', 'sound/hallucinations/im_here1.ogg', 'sound/hallucinations/im_here2.ogg', 'sound/hallucinations/i_see_you1.ogg', 'sound/hallucinations/i_see_you2.ogg',\
'sound/hallucinations/look_up1.ogg', 'sound/hallucinations/look_up2.ogg', 'sound/hallucinations/over_here1.ogg', 'sound/hallucinations/over_here2.ogg', 'sound/hallucinations/over_here3.ogg',\
'sound/hallucinations/turn_around1.ogg', 'sound/hallucinations/turn_around2.ogg', 'sound/hallucinations/veryfar_noise.ogg', 'sound/hallucinations/wail.ogg')
#define INTERACTION_SOUND_RANGE_MODIFIER -3
#define EQUIP_SOUND_VOLUME 30
#define PICKUP_SOUND_VOLUME 40
#define DROP_SOUND_VOLUME 50
#define YEET_SOUND_VOLUME 90
#define AMBIENCE_GENERIC "generic"
#define AMBIENCE_HOLY "holy"
#define AMBIENCE_DANGER "danger"
#define AMBIENCE_RUINS "ruins"
#define AMBIENCE_ENGI "engi"
#define AMBIENCE_MINING "mining"
#define AMBIENCE_MEDICAL "med"
#define AMBIENCE_SPOOKY "spooky"
#define AMBIENCE_SPACE "space"
#define AMBIENCE_MAINT "maint"
#define AMBIENCE_AWAY "away"
#define AMBIENCE_REEBE "reebe"
#define AMBIENCE_AI "ai"
#define AMBIENCE_CREEPY "creepy" //not to be confused with spooky
//default byond sound environments
#define SOUND_ENVIRONMENT_NONE -1
#define SOUND_ENVIRONMENT_GENERIC 0
#define SOUND_ENVIRONMENT_PADDED_CELL 1
#define SOUND_ENVIRONMENT_ROOM 2
#define SOUND_ENVIRONMENT_BATHROOM 3
#define SOUND_ENVIRONMENT_LIVINGROOM 4
#define SOUND_ENVIRONMENT_STONEROOM 5
#define SOUND_ENVIRONMENT_AUDITORIUM 6
#define SOUND_ENVIRONMENT_CONCERT_HALL 7
#define SOUND_ENVIRONMENT_CAVE 8
#define SOUND_ENVIRONMENT_ARENA 9
#define SOUND_ENVIRONMENT_HANGAR 10
#define SOUND_ENVIRONMENT_CARPETED_HALLWAY 11
#define SOUND_ENVIRONMENT_HALLWAY 12
#define SOUND_ENVIRONMENT_STONE_CORRIDOR 13
#define SOUND_ENVIRONMENT_ALLEY 14
#define SOUND_ENVIRONMENT_FOREST 15
#define SOUND_ENVIRONMENT_CITY 16
#define SOUND_ENVIRONMENT_MOUNTAINS 17
#define SOUND_ENVIRONMENT_QUARRY 18
#define SOUND_ENVIRONMENT_PLAIN 19
#define SOUND_ENVIRONMENT_PARKING_LOT 20
#define SOUND_ENVIRONMENT_SEWER_PIPE 21
#define SOUND_ENVIRONMENT_UNDERWATER 22
#define SOUND_ENVIRONMENT_DRUGGED 23
#define SOUND_ENVIRONMENT_DIZZY 24
#define SOUND_ENVIRONMENT_PSYCHOTIC 25
//If we ever make custom ones add them here
//"sound areas": easy way of keeping different types of areas consistent.
#define SOUND_AREA_STANDARD_STATION SOUND_ENVIRONMENT_PARKING_LOT
#define SOUND_AREA_LARGE_ENCLOSED SOUND_ENVIRONMENT_QUARRY
#define SOUND_AREA_SMALL_ENCLOSED SOUND_ENVIRONMENT_BATHROOM
#define SOUND_AREA_TUNNEL_ENCLOSED SOUND_ENVIRONMENT_STONEROOM
#define SOUND_AREA_LARGE_SOFTFLOOR SOUND_ENVIRONMENT_CARPETED_HALLWAY
#define SOUND_AREA_MEDIUM_SOFTFLOOR SOUND_ENVIRONMENT_LIVINGROOM
#define SOUND_AREA_SMALL_SOFTFLOOR SOUND_ENVIRONMENT_ROOM
#define SOUND_AREA_ASTEROID SOUND_ENVIRONMENT_CAVE
#define SOUND_AREA_SPACE SOUND_ENVIRONMENT_UNDERWATER
#define SOUND_AREA_LAVALAND SOUND_ENVIRONMENT_MOUNTAINS
#define SOUND_AREA_WOODFLOOR SOUND_ENVIRONMENT_CITY
///Announcer audio keys
#define ANNOUNCER_AIMALF "announcer_aimalf"
#define ANNOUNCER_ALIENS "announcer_aliens"

View File

@@ -172,6 +172,7 @@
// Subsystem fire priority, from lowest to highest priority
// If the subsystem isn't listed here it's either DEFAULT or PROCESS (if it's a processing subsystem child)
#define FIRE_PRIORITY_AMBIENCE 10
#define FIRE_PRIORITY_IDLE_NPC 10
#define FIRE_PRIORITY_SERVER_MAINT 10
#define FIRE_PRIORITY_RESEARCH 10

View File

@@ -0,0 +1,184 @@
GLOBAL_LIST_INIT(generic_ambience,list(
'sound/ambience/ambigen1.ogg',
'sound/ambience/ambigen3.ogg',
'sound/ambience/ambigen4.ogg',
'sound/ambience/ambigen5.ogg',
'sound/ambience/ambigen6.ogg',
'sound/ambience/ambigen7.ogg',
'sound/ambience/ambigen8.ogg',
'sound/ambience/ambigen9.ogg',
'sound/ambience/ambigen10.ogg',
'sound/ambience/ambigen11.ogg',
'sound/ambience/ambigen12.ogg',
'sound/ambience/ambigen14.ogg',
'sound/ambience/ambigen15.ogg'))
GLOBAL_LIST_INIT(holy_ambience,list(
'sound/ambience/ambicha1.ogg',
'sound/ambience/ambicha2.ogg',
'sound/ambience/ambicha3.ogg',
'sound/ambience/ambicha4.ogg',
'sound/ambience/ambiholy.ogg',
'sound/ambience/ambiholy2.ogg',
'sound/ambience/ambiholy3.ogg'))
GLOBAL_LIST_INIT(danger_ambience,list(
'sound/ambience/ambidanger.ogg',
'sound/ambience/ambidanger2.ogg'))
GLOBAL_LIST_INIT(ruins_ambience,list(
'sound/ambience/ambimine.ogg',
'sound/ambience/ambicave.ogg',
'sound/ambience/ambiruin.ogg',
'sound/ambience/ambiruin2.ogg',
'sound/ambience/ambiruin3.ogg',
'sound/ambience/ambiruin4.ogg',
'sound/ambience/ambiruin5.ogg',
'sound/ambience/ambiruin6.ogg',
'sound/ambience/ambiruin7.ogg',
'sound/ambience/ambidanger.ogg',
'sound/ambience/ambidanger2.ogg',
'sound/ambience/ambitech3.ogg',
'sound/ambience/ambimystery.ogg',
'sound/ambience/ambimaint1.ogg'))
GLOBAL_LIST_INIT(engi_ambience,list(
'sound/ambience/ambisin1.ogg',
'sound/ambience/ambisin2.ogg',
'sound/ambience/ambisin3.ogg',
'sound/ambience/ambisin4.ogg',
'sound/ambience/ambiatmos.ogg',
'sound/ambience/ambiatmos2.ogg',
'sound/ambience/ambitech.ogg',
'sound/ambience/ambitech2.ogg',
'sound/ambience/ambitech3.ogg'))
GLOBAL_LIST_INIT(mining_ambience,list(
'sound/ambience/ambimine.ogg',
'sound/ambience/ambicave.ogg',
'sound/ambience/ambiruin.ogg',
'sound/ambience/ambiruin2.ogg',
'sound/ambience/ambiruin3.ogg',
'sound/ambience/ambiruin4.ogg',
'sound/ambience/ambiruin5.ogg',
'sound/ambience/ambiruin6.ogg',
'sound/ambience/ambiruin7.ogg',
'sound/ambience/ambidanger.ogg',
'sound/ambience/ambidanger2.ogg',
'sound/ambience/ambimaint1.ogg',
'sound/ambience/ambilava1.ogg',
'sound/ambience/ambilava2.ogg',
'sound/ambience/ambilava3.ogg'))
GLOBAL_LIST_INIT(medical_ambience,list(
'sound/ambience/ambinice.ogg',
'sound/ambience/ambiruin2.ogg',
'sound/ambience/ambiodd.ogg',
'sound/ambience/ambiviro.ogg',
'sound/ambience/ambiviro1.ogg',
'sound/ambience/ambiviro2.ogg',
'sound/ambience/cavesound3.ogg'))
GLOBAL_LIST_INIT(spooky_ambience,list(
'sound/ambience/ambimo1.ogg',
'sound/ambience/ambimo2.ogg',
'sound/ambience/ambiruin7.ogg',
'sound/ambience/ambiruin6.ogg',
'sound/ambience/ambiodd.ogg',
'sound/ambience/ambimystery.ogg',
'sound/ambience/maintambience.ogg',
'sound/voice/lowHiss1.ogg'))
GLOBAL_LIST_INIT(space_ambient_music,list(
'sound/ambience/ambispace.ogg',
'sound/ambience/ambispace2.ogg',
'sound/ambience/title2.ogg',
'sound/ambience/ambiatmos.ogg'))
GLOBAL_LIST_INIT(maint_ambience,list(
'sound/ambience/ambimaint1.ogg',
'sound/ambience/ambimaint2.ogg',
'sound/ambience/ambimaint3.ogg',
'sound/ambience/ambimaint4.ogg',
'sound/ambience/ambimaint5.ogg',
'sound/voice/lowHiss2.ogg',
'sound/voice/lowHiss3.ogg',
'sound/voice/lowHiss4.ogg',
'sound/ambience/ambitech2.ogg',
'sound/ambience/maintambience.ogg'))
GLOBAL_LIST_INIT(away_ambience,list(
'sound/ambience/ambitech.ogg',
'sound/ambience/ambitech2.ogg',
'sound/ambience/ambiruin.ogg',
'sound/ambience/ambiruin2.ogg',
'sound/ambience/ambiruin3.ogg',
'sound/ambience/ambiruin4.ogg',
'sound/ambience/ambiruin5.ogg',
'sound/ambience/ambiruin6.ogg',
'sound/ambience/ambiruin7.ogg',
'sound/ambience/ambidanger.ogg',
'sound/ambience/ambidanger2.ogg',
'sound/ambience/ambimaint.ogg',
'sound/ambience/ambiatmos.ogg',
'sound/ambience/ambiatmos2.ogg',
'sound/ambience/ambiodd.ogg'))
GLOBAL_LIST_INIT(reebe_ambience,list(
'sound/ambience/ambireebe1.ogg',
'sound/ambience/ambireebe2.ogg',
'sound/ambience/ambireebe3.ogg'))
GLOBAL_LIST_INIT(ai_ambience, list(
'sound/ambience/ambimalf.ogg',
'sound/ambience/ambitech.ogg',
'sound/ambience/ambitech2.ogg',
'sound/ambience/ambiatmos.ogg',
'sound/ambience/ambiatmos2.ogg',
'sound/ambience/ambimalf2.ogg'))
GLOBAL_LIST_INIT(creepy_ambience,list(
'sound/effects/ghost.ogg',
'sound/effects/ghost2.ogg',
'sound/effects/heart_beat.ogg',
'sound/effects/screech.ogg',
'sound/hallucinations/behind_you1.ogg',
'sound/hallucinations/behind_you2.ogg',
'sound/hallucinations/far_noise.ogg',
'sound/hallucinations/growl1.ogg',
'sound/hallucinations/growl2.ogg',
'sound/hallucinations/growl3.ogg',
'sound/hallucinations/im_here1.ogg',
'sound/hallucinations/im_here2.ogg',
'sound/hallucinations/i_see_you1.ogg',
'sound/hallucinations/i_see_you2.ogg',
'sound/hallucinations/look_up1.ogg',
'sound/hallucinations/look_up2.ogg',
'sound/hallucinations/over_here1.ogg',
'sound/hallucinations/over_here2.ogg',
'sound/hallucinations/over_here3.ogg',
'sound/hallucinations/turn_around1.ogg',
'sound/hallucinations/turn_around2.ogg',
'sound/hallucinations/veryfar_noise.ogg',
'sound/hallucinations/wail.ogg'))
GLOBAL_LIST_INIT(ambience_assoc,list(
AMBIENCE_GENERIC = GLOB.generic_ambience,
AMBIENCE_HOLY = GLOB.holy_ambience,
AMBIENCE_DANGER = GLOB.danger_ambience,
AMBIENCE_RUINS = GLOB.ruins_ambience,
AMBIENCE_ENGI = GLOB.engi_ambience,
AMBIENCE_MINING = GLOB.mining_ambience,
AMBIENCE_MEDICAL = GLOB.medical_ambience,
AMBIENCE_SPOOKY = GLOB.spooky_ambience,
AMBIENCE_MAINT = GLOB.maint_ambience,
AMBIENCE_AWAY = GLOB.away_ambience,
AMBIENCE_REEBE = GLOB.reebe_ambience,
AMBIENCE_CREEPY = GLOB.creepy_ambience,
AMBIENCE_AI = GLOB.ai_ambience,
AMBIENCE_NONE = list()))
GLOBAL_LIST_INIT(ambient_music_assoc, list(
AMBIENCE_SPACE = GLOB.space_ambient_music
))

View File

@@ -0,0 +1,82 @@
/// The subsystem used to play ambience to users every now and then, makes them real excited.
SUBSYSTEM_DEF(ambience)
name = "Ambience"
flags = SS_BACKGROUND|SS_NO_INIT
priority = FIRE_PRIORITY_AMBIENCE
runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME
wait = 2
///Assoc list of listening client - next ambience time
var/list/ambience_listening_clients = list()
var/list/currentrun = list()
/datum/controller/subsystem/ambience/fire(resumed)
if(!resumed)
currentrun = ambience_listening_clients.Copy()
var/list/cached_clients = currentrun
for(var/client/client_iterator as anything in cached_clients)
if(isnull(client_iterator))
continue
if(isnewplayer(client_iterator.mob))
continue
process_ambience_client(client_iterator)
if(MC_TICK_CHECK)
return
/datum/controller/subsystem/ambience/proc/process_ambience_client(client/to_process)
var/mob/current_mob = to_process.mob
var/area/current_area = get_area(current_mob)
if(!current_area) //Something's gone horribly wrong
stack_trace("[key_name(to_process)] has somehow ended up in nullspace. WTF did you do -xoxo ambience subsystem")
ambience_listening_clients -= to_process
return
if(current_area.ambient_buzz)
play_buzz(current_mob, current_area)
if(ambience_listening_clients[to_process] > world.time)
return //Not ready for the next sound
if(current_area.ambientsounds && length(current_area.ambientsounds))
var/ambi_fx = pick(current_area.ambientsounds)
play_ambience_effects(current_mob, ambi_fx, current_area)
if(current_area.ambientmusic && length(current_area.ambientmusic))
var/ambi_music = pick(current_area.ambientmusic)
play_ambience_music(current_mob, ambi_music, current_area)
ambience_listening_clients[to_process] = world.time + rand(current_area.min_ambience_cooldown, current_area.max_ambience_cooldown)
/datum/controller/subsystem/ambience/proc/add_ambience_client(client/to_add)
if(SSambience.ambience_listening_clients[to_add] > world.time)
return // If already properly set we don't want to reset the timer.
SSambience.ambience_listening_clients[to_add] = world.time + 10 SECONDS //Just wait 10 seconds before the next one aight mate? cheers.
/datum/controller/subsystem/ambience/proc/remove_ambience_client(client/to_remove)
ambience_listening_clients -= to_remove
currentrun -= to_remove
///Buzzing sound, the low ship drone that plays constantly, IC (requires the user to be able to hear)
/datum/controller/subsystem/ambience/proc/play_buzz(mob/M, area/A)
if (A.ambient_buzz && (M.client.prefs.toggles & SOUND_SHIP_AMBIENCE) && M.can_hear_ambience())
if (!M.client.buzz_playing || (A.ambient_buzz != M.client.buzz_playing))
SEND_SOUND(M, sound(A.ambient_buzz, repeat = 1, wait = 0, volume = A.ambient_buzz_vol, channel = CHANNEL_BUZZ))
M.client.buzz_playing = A.ambient_buzz // It's done this way so I can tell when the user switches to an area that has a different buzz effect, so we can seamlessly swap over to that one
return
if(M.client.buzz_playing) // If it's playing, and it shouldn't be, stop it
M.stop_sound_channel(CHANNEL_BUZZ)
M.client.buzz_playing = null
///Effect, random sounds that will play at random times, IC (requires the user to be able to hear)
/datum/controller/subsystem/ambience/proc/play_ambience_effects(mob/M, _ambi_fx, area/A)
if(M.can_hear_ambience() && !M.client?.channel_in_use(CHANNEL_AMBIENT_EFFECTS))
SEND_SOUND(M, sound(_ambi_fx, repeat = 0, wait = 0, volume = 45, channel = CHANNEL_AMBIENT_EFFECTS))
///Play background music, the more OOC ambience, like eerie space music
/datum/controller/subsystem/ambience/proc/play_ambience_music(mob/M, _ambi_music, area/A)
if(!M.client?.channel_in_use(CHANNEL_AMBIENT_MUSIC))
SEND_SOUND(M, sound(_ambi_music, repeat = 0, wait = 0, volume = 75, channel = CHANNEL_AMBIENT_MUSIC))

View File

@@ -0,0 +1,127 @@
/*
* Sound subsystem:
* Used for things that need constant updating (sound fading in / out)
*/
SUBSYSTEM_DEF(sound_effects)
name = "Sound"
wait = 1
priority = FIRE_PRIORITY_AMBIENCE
flags = SS_NO_INIT
//Note: Make sure you update this if you use sound fading pre-game
runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME
var/list/acting_effects = list() //key = sound, value = datum
var/list/currentrun = list()
/datum/controller/subsystem/sound_effects/fire(resumed = 0)
if (!resumed)
src.currentrun = acting_effects.Copy()
//cache for sanic speed (lists are references anyways)
var/list/currentrun = src.currentrun
while(LAZYLEN(currentrun))
var/datum/sound_effect/sound_effect = currentrun[currentrun[currentrun.len]]
currentrun.len--
sound_effect.update_effect()
if(world.time > sound_effect.end_tick)
sound_effect.end_effect()
acting_effects -= sound_effect.effect_id
if (MC_TICK_CHECK)
return
// ===== Sound effect procs =====
/proc/sound_fade(sound/S, start_volume = 100, end_volume = 0, time = 10, var/listeners)
//Check basics
if(!S)
CRASH("sound_fade called without a sound file.")
if(!listeners)
return
//Check in list format
var/listeners_list = listeners
if(!islist(listeners_list))
listeners_list = list(listeners)
//Create datum
new /datum/sound_effect/fade(S, listeners_list, time, start_volume, end_volume)
// ===== Sound effect datum =====
/datum/sound_effect
var/name = "null"
var/sound/sound
var/list/listeners
var/start_tick
var/end_tick
var/effect_id
/datum/sound_effect/New(S, list/_listeners, time)
. = ..()
sound = S
listeners = _listeners
start_tick = world.time
end_tick = world.time + time
effect_id = generate_id()
start_sound()
/datum/sound_effect/proc/generate_id()
var/id = "[name][sound.file]"
for(var/A in listeners)
id = "[id][REF(A)]"
return id
/datum/sound_effect/proc/send_sound()
for(var/receiver in listeners)
SEND_SOUND(receiver, sound)
/datum/sound_effect/proc/update_effect()
return //Not implemented
/datum/sound_effect/proc/end_effect()
return //Not implemented
// Send the sound to the person it's affecting and add it to the sound subsystem.
// Should be overridden to account for if an effect is already playing for that sound.
/datum/sound_effect/proc/start_sound()
send_sound()
SSsound_effects.acting_effects[effect_id] = src
//============== Fade =============
/datum/sound_effect/fade
name = "fade"
var/in_vol
var/out_vol
//Calculated
var/current_vol
/datum/sound_effect/fade/New(S, list/_listeners, time, start_vol, end_vol)
in_vol = start_vol
out_vol = end_vol
. = ..(S, _listeners, time)
/datum/sound_effect/fade/start_sound()
//If the sound is already playing, make it fade from the current point
if(SSsound_effects.acting_effects[effect_id])
var/datum/sound_effect/fade/old_sound = SSsound_effects.acting_effects[effect_id]
in_vol = old_sound.current_vol
else
send_sound()
SSsound_effects.acting_effects[effect_id] = src
/datum/sound_effect/fade/update_effect()
var/time_multiplier = clamp((world.time - start_tick) / (end_tick - start_tick), 0, 1)
current_vol = (time_multiplier * out_vol) + ((1-time_multiplier) * in_vol)
sound.status = SOUND_UPDATE
sound.volume = current_vol
for(var/receiver in listeners)
SEND_SOUND(receiver, sound)
/datum/sound_effect/fade/end_effect()
if(!out_vol)
sound.repeat = FALSE

View File

@@ -41,7 +41,7 @@
to_chat(H, span_warning("You feel [pick("full", "nauseated", "sweaty", "weak", "tired", "short on breath", "uneasy")]."))
if(3 to 4)
if(!sound)
H.playsound_local(H, 'sound/health/slowbeat.ogg',40,0, channel = CHANNEL_HEARTBEAT)
H.playsound_local(H, 'sound/health/slowbeat.ogg',40,0, channel = CHANNEL_HEARTBEAT, use_reverb = FALSE)
sound = TRUE
if(prob(3))
to_chat(H, span_danger("You feel a sharp pain in your chest!"))

View File

@@ -134,12 +134,12 @@
self_penalty_mult = 0.5
user.visible_message(span_danger("[user] begins cauterizing [victim]'s [limb.name] with [I]..."), span_warning("You begin cauterizing [user == victim ? "your" : "[victim]'s"] [limb.name] with [I]..."))
playsound(I, 'sound/surgery/cautery1.ogg', 75, TRUE, falloff = 1)
playsound(I, 'sound/surgery/cautery1.ogg', 75, TRUE, falloff_exponent = 1)
if(!do_after(user, base_treat_time * self_penalty_mult * improv_penalty_mult * I.toolspeed, victim, extra_checks = CALLBACK(src, PROC_REF(still_exists))))
return
playsound(I, 'sound/surgery/cautery2.ogg', 75, TRUE, falloff = 1)
playsound(I, 'sound/surgery/cautery2.ogg', 75, TRUE, falloff_exponent = 1)
user.visible_message(span_green("[user] cauterizes some of the bleeding on [victim]."), span_green("You cauterize some of the bleeding on [victim]."))
limb.receive_damage(burn = 2 + severity, wound_bonus = CANT_WOUND)
if(prob(30))

View File

@@ -165,12 +165,12 @@
if(LAZYLEN(user.mind?.antag_datums) && severity > WOUND_SEVERITY_MODERATE) //antagonists can heal wounds better with ghetto alternatives, since they don't have as much access to proper medical treatment
self_penalty_mult = 1
user.visible_message(span_warning("[user] begins aiming [lasgun] directly at [victim]'s [limb.name]..."), span_userdanger("You begin aiming [lasgun] directly at [user == victim ? "your" : "[victim]'s"] [limb.name]..."))
playsound(lasgun, 'sound/surgery/cautery1.ogg', 75, TRUE, falloff = 1)
playsound(lasgun, 'sound/surgery/cautery1.ogg', 75, TRUE, falloff_exponent = 1)
if(!do_after(user, base_treat_time * self_penalty_mult, victim, extra_checks = CALLBACK(src, PROC_REF(still_exists))))
return
playsound(lasgun, 'sound/surgery/cautery2.ogg', 75, TRUE, falloff = 1)
playsound(lasgun, 'sound/surgery/cautery2.ogg', 75, TRUE, falloff_exponent = 1)
var/damage = lasgun.chambered.BB.damage
lasgun.chambered.BB.bare_wound_bonus = 0
lasgun.chambered.BB.wound_bonus -= 30
@@ -189,12 +189,12 @@
self_penalty_mult = 0.5
improv_penalty_mult = 1
user.visible_message(span_danger("[user] begins cauterizing [victim]'s [limb.name] with [I]..."), span_warning("You begin cauterizing [user == victim ? "your" : "[victim]'s"] [limb.name] with [I]..."))
playsound(I, 'sound/surgery/cautery1.ogg', 75, TRUE, falloff = 1)
playsound(I, 'sound/surgery/cautery1.ogg', 75, TRUE, falloff_exponent = 1)
if(!do_after(user, base_treat_time * self_penalty_mult * improv_penalty_mult * I.toolspeed, victim, extra_checks = CALLBACK(src, PROC_REF(still_exists))))
return
playsound(I, 'sound/surgery/cautery2.ogg', 75, TRUE, falloff = 1)
playsound(I, 'sound/surgery/cautery2.ogg', 75, TRUE, falloff_exponent = 1)
user.visible_message(span_green("[user] cauterizes some of the bleeding on [victim]."), span_green("You cauterize some of the bleeding on [victim]."))
limb.receive_damage(burn = 2 + severity, wound_bonus = CANT_WOUND)
if(prob(30))

View File

@@ -28,8 +28,11 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
power_environ = FALSE
valid_territory = FALSE
outdoors = TRUE
ambientsounds = SPACE
blob_allowed = FALSE //Eating up space doesn't count for victory as a blob.
ambience_index = null
ambient_music_index = AMBIENCE_SPACE
ambient_buzz = null
sound_environment = SOUND_AREA_SPACE
/area/space/nearstation
icon_state = "space_near"
@@ -41,7 +44,8 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
requires_power = FALSE
dynamic_lighting = DYNAMIC_LIGHTING_DISABLED
has_gravity = STANDARD_GRAVITY
ambience_index = null
ambient_buzz = null
/area/testroom
requires_power = FALSE
@@ -58,11 +62,12 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
has_gravity = STANDARD_GRAVITY
blob_allowed = FALSE //Nope, no winning on the asteroid as a blob. Gotta eat the station.
valid_territory = FALSE
ambientsounds = MINING
ambience_index = AMBIENCE_MINING
sound_environment = SOUND_AREA_ASTEROID
/area/asteroid/nearstation
dynamic_lighting = DYNAMIC_LIGHTING_FORCED
ambientsounds = RUINS
ambience_index = AMBIENCE_RUINS
always_unpowered = FALSE
requires_power = TRUE
blob_allowed = TRUE
@@ -75,11 +80,15 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
//Maintenance
/area/maintenance
ambientsounds = MAINTENANCE
ambience_index = AMBIENCE_MAINT
sound_environment = SOUND_AREA_TUNNEL_ENCLOSED
valid_territory = FALSE
minimap_color = "#4f4e3a"
airlock_wires = /datum/wires/airlock/maint
ambient_buzz = 'sound/ambience/source_corridor2.ogg'
ambient_buzz_vol = 20
min_ambience_cooldown = 20 SECONDS
max_ambience_cooldown = 35 SECONDS
//Departments
@@ -95,6 +104,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
/area/maintenance/department/crew_quarters/bar
name = "Bar Maintenance"
icon_state = "maint_bar"
sound_environment = SOUND_AREA_WOODFLOOR
/area/maintenance/department/crew_quarters/dorms
name = "Dormitory Maintenance"
@@ -242,6 +252,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
/area/hallway
minimap_color = "#8d8c68"
sound_environment = SOUND_AREA_STANDARD_STATION
/area/hallway/primary/aft
name = "Aft (S) Primary Hallway"
@@ -299,14 +310,17 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
ambientsounds = list('sound/ambience/signal.ogg')
minimap_color = "#0400a2"
airlock_wires = /datum/wires/airlock/command
sound_environment = SOUND_AREA_STANDARD_STATION
/area/bridge/meeting_room
name = "Heads of Staff Meeting Room"
icon_state = "meeting"
sound_environment = SOUND_AREA_MEDIUM_SOFTFLOOR
/area/bridge/meeting_room/council
name = "Council Chamber"
icon_state = "meeting"
sound_environment = SOUND_AREA_MEDIUM_SOFTFLOOR
/area/bridge/showroom/corporate
name = "Corporate Showroom"
@@ -320,10 +334,12 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
name = "Captain's Office"
icon_state = "captain"
minimap_color = "#2900d8"
sound_environment = SOUND_AREA_WOODFLOOR
/area/crew_quarters/heads/captain/private
name = "Captain's Quarters"
icon_state = "captain"
sound_environment = SOUND_ENVIRONMENT_ROOM
/area/crew_quarters/heads/chief
name = "Chief Engineer's Office"
@@ -353,15 +369,18 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
/area/comms
name = "Communications Relay"
icon_state = "tcomsatcham"
sound_environment = SOUND_AREA_STANDARD_STATION
/area/server
name = "Messaging Server Room"
icon_state = "server"
sound_environment = SOUND_AREA_STANDARD_STATION
//Crew
/area/crew_quarters
minimap_color = "#b0e1ff"
sound_environment = SOUND_AREA_STANDARD_STATION
/area/crew_quarters/dorms
name = "Dormitories"
@@ -378,6 +397,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
name = "Dormitory Toilets"
icon_state = "toilet"
minimap_color = "#b0e1ff"
sound_environment = SOUND_AREA_SMALL_ENCLOSED
/area/crew_quarters/toilet/auxiliary
name = "Auxiliary Restrooms"
@@ -400,6 +420,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
/area/crew_quarters/lounge
name = "Lounge"
icon_state = "yellow"
sound_environment = SOUND_AREA_SMALL_SOFTFLOOR
/area/crew_quarters/fitness
name = "Fitness Room"
@@ -427,6 +448,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
/area/crew_quarters/kitchen/coldroom
name = "Kitchen Cold Room"
icon_state = "kitchen_cold"
sound_environment = SOUND_AREA_SMALL_ENCLOSED
/area/crew_quarters/bar
name = "Bar"
@@ -435,6 +457,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
mood_bonus = 5
mood_message = span_nicegreen("I love being in the bar!\n")
airlock_wires = /datum/wires/airlock/service
sound_environment = SOUND_AREA_WOODFLOOR
/area/crew_quarters/bar/Initialize(mapload)
. = ..()
@@ -443,6 +466,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
/area/crew_quarters/bar/atrium
name = "Atrium"
icon_state = "bar"
sound_environment = SOUND_AREA_WOODFLOOR
/area/crew_quarters/electronic_marketing_den
name = "Electronic Marketing Den"
@@ -459,6 +483,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
name = "Theatre"
icon_state = "Theatre"
minimap_color = "#5ac866"
sound_environment = SOUND_AREA_WOODFLOOR
/area/crew_quarters/theatre/abandoned
name = "Abandoned Theatre"
@@ -473,6 +498,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
/area/library/lounge
name = "Library Lounge"
icon_state = "library"
sound_environment = SOUND_AREA_LARGE_SOFTFLOOR
/area/library/abandoned
name = "Abandoned Library"
@@ -481,7 +507,8 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
/area/chapel
icon_state = "chapel"
ambientsounds = HOLY
ambience_index = AMBIENCE_HOLY
sound_environment = SOUND_AREA_LARGE_ENCLOSED
flags_1 = NONE
clockwork_warp_allowed = FALSE
clockwork_warp_fail = "The consecration here prevents you from warping in."
@@ -500,6 +527,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
/area/chapel/asteroid
name = "Chapel Asteroid"
icon_state = "explored"
sound_environment = SOUND_AREA_ASTEROID
/area/chapel/asteroid/monastery
name = "Monastery Asteroid"
@@ -512,12 +540,14 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
name = "Law Office"
icon_state = "law"
minimap_color = "#b12527"
sound_environment = SOUND_AREA_SMALL_SOFTFLOOR
//Engineering
/area/engine
ambientsounds = ENGINEERING
ambience_index = AMBIENCE_ENGI
sound_environment = SOUND_AREA_LARGE_ENCLOSED
minimap_color = "#edea00"
airlock_wires = /datum/wires/airlock/engineering
@@ -546,6 +576,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
/area/engine/atmos/engine
name = "\improper Atmospherics Engine"
icon_state = "atmos_engine"
sound_environment = SOUND_AREA_LARGE_ENCLOSED
/area/engine/atmos/pumproom
name = "\improper Atmospherics Pumping Room"
@@ -566,18 +597,22 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
/area/engine/atmos/hfr
name = "\improper Atmospherics HFR Room"
icon_state = "atmos_hfr"
sound_environment = SOUND_AREA_SMALL_ENCLOSED
/area/engine/supermatter
name = "Supermatter Engine"
icon_state = "engine_sm"
sound_environment = SOUND_AREA_SMALL_ENCLOSED
/area/engine/foyer
name = "Engineering Foyer"
icon_state = "engine_foyer"
sound_environment = SOUND_AREA_STANDARD_STATION
/area/engine/break_room
name = "Engineering Break Room"
icon_state = "engine_foyer"
sound_environment = SOUND_AREA_SMALL_ENCLOSED
/area/engine/gravity_generator
name = "Gravity Generator Room"
@@ -588,6 +623,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
/area/engine/storage
name = "Engineering Storage"
icon_state = "engi_storage"
sound_environment = SOUND_AREA_SMALL_ENCLOSED
/area/engine/storage_shared
name = "Shared Engineering Storage"
@@ -606,13 +642,15 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
valid_territory = FALSE
blob_allowed = FALSE
flags_1 = NONE
ambientsounds = ENGINEERING
ambience_index = AMBIENCE_ENGI
sound_environment = SOUND_AREA_SPACE
minimap_color = "#6b6b6b"
airlock_wires = /datum/wires/airlock/engineering
/area/solar/fore
name = "Fore (N) Solar Array"
icon_state = "yellow"
sound_environment = SOUND_AREA_STANDARD_STATION
/area/solar/aft
name = "Aft (S) Solar Array"
@@ -686,14 +724,16 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
/area/teleporter
name = "Teleporter Room"
icon_state = "teleporter"
ambientsounds = ENGINEERING
ambience_index = AMBIENCE_ENGI
sound_environment = SOUND_AREA_STANDARD_STATION
minimap_color = "#6b6b6b"
airlock_wires = /datum/wires/airlock/command
/area/gateway
name = "Gateway"
icon_state = "gateway"
ambientsounds = ENGINEERING
ambience_index = AMBIENCE_ENGI
sound_environment = SOUND_AREA_STANDARD_STATION
minimap_color = "#5d57a5"
airlock_wires = /datum/wires/airlock/command
@@ -702,7 +742,8 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
/area/medical
name = "Medical"
icon_state = "medbay3"
ambientsounds = MEDICAL
ambience_index = AMBIENCE_MEDICAL
sound_environment = SOUND_AREA_STANDARD_STATION
minimap_color = "#5d57a5"
airlock_wires = /datum/wires/airlock/medbay
@@ -710,6 +751,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
name = "Abandoned Medbay"
icon_state = "medbay3"
ambientsounds = list('sound/ambience/signal.ogg')
sound_environment = SOUND_AREA_SMALL_ENCLOSED
/area/medical/medbay/central
name = "Medbay Central"
@@ -744,6 +786,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
/area/medical/patients_rooms
name = "Patients' Rooms"
icon_state = "patients"
sound_environment = SOUND_AREA_SMALL_SOFTFLOOR
/area/medical/patients_rooms/room_a
name = "Patient Room A"
@@ -762,11 +805,14 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
icon_state = "virology"
flags_1 = NONE
minimap_color = "#01f5b3"
ambience_index = AMBIENCE_MEDICAL
sound_environment = SOUND_AREA_SMALL_ENCLOSED
/area/medical/morgue
name = "Morgue"
icon_state = "morgue"
ambientsounds = SPOOKY
ambience_index = AMBIENCE_SPOOKY
sound_environment = SOUND_AREA_SMALL_ENCLOSED
/area/medical/chemistry
name = "Chemistry"
@@ -803,7 +849,8 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
/area/security
name = "Security"
icon_state = "security"
ambientsounds = HIGHSEC
ambience_index = AMBIENCE_DANGER
sound_environment = SOUND_AREA_STANDARD_STATION
minimap_color = "#b12527"
airlock_wires = /datum/wires/airlock/security
@@ -822,6 +869,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
/area/security/courtroom
name = "Courtroom"
icon_state = "courtroom"
sound_environment = SOUND_AREA_LARGE_ENCLOSED
/area/security/prison
name = "Prison Wing"
@@ -838,10 +886,12 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
/area/security/processing/cremation
name = "Security Crematorium"
icon_state = "sec_prison"
sound_environment = SOUND_AREA_SMALL_ENCLOSED
/area/security/warden
name = "Brig Control"
icon_state = "Warden"
sound_environment = SOUND_AREA_SMALL_SOFTFLOOR
/area/security/detectives_office
name = "Detective's Office"
@@ -851,6 +901,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
/area/security/detectives_office/private_investigators_office
name = "Private Investigator's Office"
icon_state = "detective"
sound_environment = SOUND_AREA_SMALL_SOFTFLOOR
/area/security/range
name = "Firing Range"
@@ -928,14 +979,17 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
icon_state = "quart"
minimap_color = "#936f3c"
airlock_wires = /datum/wires/airlock/service
sound_environment = SOUND_AREA_STANDARD_STATION
/area/quartermaster/sorting
name = "Delivery Office"
icon_state = "cargo_delivery"
sound_environment = SOUND_AREA_STANDARD_STATION
/area/quartermaster/warehouse
name = "Warehouse"
icon_state = "cargo_warehouse"
sound_environment = SOUND_AREA_LARGE_ENCLOSED
/area/quartermaster/office
name = "Cargo Office"
@@ -945,6 +999,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
/area/quartermaster/storage
name = "Cargo Bay"
icon_state = "cargo_bay"
sound_environment = SOUND_AREA_LARGE_ENCLOSED
/area/quartermaster/qm
name = "Quartermaster's Office"
@@ -964,6 +1019,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
flags_1 = NONE
minimap_color = "#cc00ff"
airlock_wires = /datum/wires/airlock/service
sound_environment = SOUND_AREA_SMALL_ENCLOSED
/area/janitor/a //yogs start added two new areas
name = "Custodial Closet A"
@@ -980,6 +1036,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
icon_state = "hydro"
minimap_color = "#5ac866"
airlock_wires = /datum/wires/airlock/service
sound_environment = SOUND_AREA_STANDARD_STATION
/area/hydroponics/upper
name = "Upper Hydroponics"
@@ -993,6 +1050,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
/area/hydroponics/garden/abandoned
name = "Abandoned Garden"
icon_state = "abandoned_garden"
sound_environment = SOUND_AREA_SMALL_ENCLOSED
/area/hydroponics/garden/monastery
name = "Monastery Garden"
@@ -1006,6 +1064,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
icon_state = "toxlab"
minimap_color = "#75009b"
airlock_wires = /datum/wires/airlock/science
sound_environment = SOUND_AREA_STANDARD_STATION
/area/science/lab
name = "Research and Development"
@@ -1068,6 +1127,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
/area/science/research/abandoned
name = "Abandoned Research Lab"
icon_state = "medresearch"
sound_environment = SOUND_AREA_SMALL_ENCLOSED
/area/science/nanite
name = "Nanite Lab"
@@ -1077,6 +1137,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
/area/storage
minimap_color = "#f8ff83"
sound_environment = SOUND_AREA_STANDARD_STATION
/area/storage/tools
name = "Auxiliary Tool Storage"
@@ -1119,12 +1180,14 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
/area/construction
name = "Construction Area"
icon_state = "yellow"
ambientsounds = ENGINEERING
ambience_index = AMBIENCE_ENGI
sound_environment = SOUND_AREA_STANDARD_STATION
minimap_color = "#4f4e3a"
/area/construction/mining/aux_base
name = "Auxiliary Base Construction"
icon_state = "aux_base_construction"
sound_environment = SOUND_AREA_LARGE_ENCLOSED
/area/construction/storage_wing
name = "Storage Wing"
@@ -1134,7 +1197,8 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
/area/vacant_room
name = "Vacant Room"
icon_state = "yellow"
ambientsounds = MAINTENANCE
ambience_index = AMBIENCE_MAINT
sound_environment = SOUND_AREA_MEDIUM_SOFTFLOOR
icon_state = "vacant_room"
minimap_color = "#4f4e3a"
@@ -1151,7 +1215,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
/area/ai_monitored/security/armory
name = "Armory"
icon_state = "armory"
ambientsounds = HIGHSEC
ambience_index = AMBIENCE_DANGER
minimap_color = "#b12527"
airlock_wires = /datum/wires/airlock/security
@@ -1161,20 +1225,20 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
/area/ai_monitored/storage/eva
name = "EVA Storage"
icon_state = "eva"
ambientsounds = HIGHSEC
ambience_index = AMBIENCE_DANGER
minimap_color = "#c8c0ff"
/area/ai_monitored/storage/satellite
name = "AI Satellite Maint"
icon_state = "storage"
ambientsounds = HIGHSEC
ambience_index = AMBIENCE_DANGER
minimap_color = "#4f4e3a"
airlock_wires = /datum/wires/airlock/ai
/area/ai_monitored/storage/satellite/teleporter
name = "AI Satellite Access Teleporter"
icon_state = "storage"
ambientsounds = HIGHSEC
ambience_index = AMBIENCE_DANGER
minimap_color = "#4f4e3a"
airlock_wires = /datum/wires/airlock/ai
@@ -1182,16 +1246,18 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
name = "AI Secondary Datacore Monitoring"
icon_state = "ai"
minimap_color = "#00fff6"
ambience_index = AMBIENCE_DANGER
/area/ai_monitored/secondarydatacoreserver
name = "AI Secondary Datacore Servers"
icon_state = "ai"
minimap_color = "#00fff6"
ambience_index = AMBIENCE_DANGER
//Turret_protected
/area/ai_monitored/turret_protected
ambientsounds = list('sound/ambience/ambimalf.ogg', 'sound/ambience/ambitech.ogg', 'sound/ambience/ambitech2.ogg', 'sound/ambience/ambiatmos.ogg', 'sound/ambience/ambiatmos2.ogg', 'sound/ambience/ambimalf2.ogg')
ambience_index = AMBIENCE_AI
minimap_color = "#00fff6"
airlock_wires = /datum/wires/airlock/ai
@@ -1199,10 +1265,12 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
name = "AI Upload Chamber"
icon_state = "ai_upload"
minimap_color = "#4f4e3a"
sound_environment = SOUND_AREA_SMALL_ENCLOSED
/area/ai_monitored/turret_protected/ai_upload_foyer
name = "AI Upload Access"
icon_state = "ai_foyer"
sound_environment = SOUND_AREA_SMALL_ENCLOSED
/area/ai_monitored/turret_protected/ai
name = "AI Chamber"
@@ -1211,7 +1279,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
/area/ai_monitored/turret_protected/aisat
name = "AI Satellite"
icon_state = "ai"
sound_environment = SOUND_ENVIRONMENT_ROOM
/area/ai_monitored/turret_protected/aisat/atmos
name = "AI Satellite Atmos"
icon_state = "ai"
@@ -1237,6 +1305,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
/area/ai_monitored/turret_protected/aisat_interior
name = "AI Satellite Antechamber"
icon_state = "ai"
sound_environment = SOUND_AREA_LARGE_ENCLOSED
/area/ai_monitored/turret_protected/AIsatextAS
name = "AI Sat Ext"
@@ -1260,6 +1329,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
/area/tcommsat/computer
name = "Telecomms Control Room"
icon_state = "tcomsatcomp"
sound_environment = SOUND_AREA_MEDIUM_SOFTFLOOR
/area/tcommsat/server
name = "Telecomms Server Room"

View File

@@ -3,6 +3,7 @@
clockwork_warp_allowed = FALSE
var/list/obj/machinery/camera/motioncameras = list()
var/list/datum/weakref/motionTargets = list()
sound_environment = SOUND_AREA_STANDARD_STATION
/area/ai_monitored/Initialize(mapload)
. = ..()

View File

@@ -79,7 +79,25 @@
var/global/global_uid = 0
var/uid
var/list/ambientsounds = GENERIC
var/ambience_index = AMBIENCE_GENERIC
var/list/ambientsounds
///Ambient buzz of the station, plays repeatedly, also IC
var/ambient_buzz = 'sound/ambience/shipambience.ogg'
///The volume of the ambient buzz
var/ambient_buzz_vol = 30
///Used to decide what the minimum time between ambience is
var/min_ambience_cooldown = 30 SECONDS
///Used to decide what the maximum time between ambience is
var/max_ambience_cooldown = 240 SECONDS
///Used to decide what kind of reverb the area makes sound have
var/sound_environment = SOUND_ENVIRONMENT_NONE
var/ambient_music_index
var/list/ambientmusic
flags_1 = CAN_BE_DIRTY_1
var/list/firedoors
@@ -165,6 +183,13 @@ GLOBAL_LIST_EMPTY(teleportlocs)
map_name = name // Save the initial (the name set in the map) name of the area.
canSmoothWithAreas = typecacheof(canSmoothWithAreas)
if(!ambientsounds && ambience_index)
ambientsounds = GLOB.ambience_assoc[ambience_index]
if(!ambientmusic && ambient_music_index)
ambientmusic = GLOB.ambient_music_assoc[ambient_music_index]
if(requires_power)
luminosity = 0
else
@@ -652,28 +677,6 @@ GLOBAL_LIST_EMPTY(teleportlocs)
set waitfor = FALSE
SEND_SIGNAL(src, COMSIG_AREA_ENTERED, M)
SEND_SIGNAL(M, COMSIG_ENTER_AREA, src) //The atom that enters the area
if(!isliving(M))
return
var/mob/living/L = M
if(!L.ckey)
return
// Ambience goes down here -- make sure to list each area separately for ease of adding things in later, thanks! Note: areas adjacent to each other should have the same sounds to prevent cutoff when possible.- LastyScratch
if(L.client && !L.client.ambience_playing && L.client.prefs.toggles & SOUND_SHIP_AMBIENCE)
L.client.ambience_playing = 1
SEND_SOUND(L, sound('sound/ambience/shipambience.ogg', repeat = 1, wait = 0, volume = 35, channel = CHANNEL_BUZZ))
if(!(L.client && (L.client.prefs.toggles & SOUND_AMBIENCE)))
return //General ambience check is below the ship ambience so one can play without the other
if(prob(35))
var/sound = pick(ambientsounds)
if(!L.client.played)
SEND_SOUND(L, sound(sound, repeat = 0, wait = 0, volume = 25, channel = CHANNEL_AMBIENCE))
L.client.played = TRUE
addtimer(CALLBACK(L.client, /client/proc/ResetAmbiencePlayed), 1 MINUTES)
/**
* Called when an atom exits an area
@@ -684,12 +687,6 @@ GLOBAL_LIST_EMPTY(teleportlocs)
SEND_SIGNAL(src, COMSIG_AREA_EXITED, M)
SEND_SIGNAL(M, COMSIG_EXIT_AREA, src) //The atom that exits the area
/**
* Reset the played var to false on the client
*/
/client/proc/ResetAmbiencePlayed()
played = FALSE
/**
* Returns true if this atom has gravity for the passed in turf
*

View File

@@ -8,7 +8,8 @@ Unused icons for new areas are "awaycontent1" ~ "awaycontent30"
name = "Strange Location"
icon_state = "away"
has_gravity = STANDARD_GRAVITY
ambientsounds = AWAY_MISSION
ambience_index = AMBIENCE_AWAY
sound_environment = SOUND_ENVIRONMENT_ROOM
unique = TRUE

View File

@@ -145,7 +145,7 @@
noteleport = TRUE
blob_allowed = FALSE //Not... entirely sure this will ever come up... but if the bus makes blobs AND ops, it shouldn't aim for the ops to win.
flags_1 = NONE
ambientsounds = HIGHSEC
ambience_index = AMBIENCE_DANGER
/area/syndicate_mothership/control
name = "Syndicate Control Room"
@@ -208,7 +208,7 @@
has_gravity = STANDARD_GRAVITY
noteleport = TRUE
hidden = TRUE
ambientsounds = REEBE
ambience_index = AMBIENCE_REEBE
/area/reebe/city_of_cogs
name = "City of Cogs"

View File

@@ -4,6 +4,9 @@
icon_state = "mining"
has_gravity = STANDARD_GRAVITY
area_flags = FLORA_ALLOWED
ambient_buzz = 'sound/ambience/magma.ogg'
ambient_buzz_vol = 10
/area/mine/explored
name = "Mine"
@@ -16,8 +19,10 @@
power_light = FALSE
outdoors = TRUE
flags_1 = NONE
ambientsounds = MINING
ambience_index = AMBIENCE_MINING
area_flags = NONE
ambient_buzz = 'sound/ambience/magma.ogg'
ambient_buzz_vol = 20
/area/mine/unexplored
name = "Mine"
@@ -30,8 +35,9 @@
power_light = FALSE
outdoors = TRUE
flags_1 = NONE
ambientsounds = MINING
ambience_index = AMBIENCE_MINING
area_flags = CAVES_ALLOWED | FLORA_ALLOWED | MOB_SPAWN_ALLOWED | MEGAFAUNA_SPAWN_ALLOWED
ambient_buzz = 'sound/ambience/magma.ogg'
map_generator = /datum/map_generator/cave_generator
/area/mine/lobby
@@ -91,7 +97,7 @@
/area/mine/laborcamp/security
name = "Labor Camp Security"
icon_state = "security"
ambientsounds = HIGHSEC
ambience_index = AMBIENCE_DANGER
@@ -103,6 +109,7 @@
has_gravity = STANDARD_GRAVITY
flags_1 = NONE
area_flags = FLORA_ALLOWED
ambient_buzz = 'sound/ambience/magma.ogg'
/area/lavaland/surface
name = "Lavaland"
@@ -113,7 +120,8 @@
power_equip = FALSE
power_light = FALSE
requires_power = TRUE
ambientsounds = MINING
ambience_index = AMBIENCE_MINING
ambient_buzz = 'sound/ambience/magma.ogg'
/area/lavaland/underground
name = "Lavaland Caves"
@@ -124,7 +132,8 @@
power_environ = FALSE
power_equip = FALSE
power_light = FALSE
ambientsounds = MINING
ambience_index = AMBIENCE_MINING
ambient_buzz = 'sound/ambience/magma.ogg'
/area/lavaland/surface/outdoors
@@ -163,7 +172,7 @@
power_equip = FALSE
power_light = FALSE
requires_power = TRUE
ambientsounds = MINING
ambience_index = AMBIENCE_MINING
/area/icemoon/surface/outdoors
name = "Icemoon Wastes"
@@ -190,7 +199,7 @@
power_environ = FALSE
power_equip = FALSE
power_light = FALSE
ambientsounds = MINING
ambience_index = AMBIENCE_MINING
/area/icemoon/underground/unexplored // mobs and megafauna and ruins spawn here
name = "Icemoon Caves"

View File

@@ -6,7 +6,7 @@
has_gravity = STANDARD_GRAVITY
hidden = FALSE
dynamic_lighting = DYNAMIC_LIGHTING_FORCED
ambientsounds = RUINS
ambience_index = AMBIENCE_RUINS
/area/ruin/unpowered

View File

@@ -80,7 +80,9 @@
/area/ruin/powered/syndicate_lava_base
name = "Syndicate Lavaland"
icon_state = "syndie-control"
ambientsounds = HIGHSEC
ambience_index = AMBIENCE_DANGER
ambient_buzz = 'sound/ambience/magma.ogg'
ambient_buzz_vol = 10
hidden = FALSE
requires_power = TRUE
@@ -138,3 +140,4 @@
//ash walker nest
/area/ruin/unpowered/ash_walkers
icon_state = "red"
ambient_buzz = 'sound/ambience/magma.ogg'

View File

@@ -22,8 +22,11 @@
power_environ = FALSE
valid_territory = FALSE
outdoors = TRUE
ambientsounds = SPACE
blob_allowed = FALSE
ambience_index = null
ambient_music_index = AMBIENCE_SPACE
ambient_buzz = null
sound_environment = SOUND_AREA_SPACE
/////////////

View File

@@ -33,7 +33,7 @@
/area/shuttle/syndicate
name = "Syndicate Infiltrator"
blob_allowed = FALSE
ambientsounds = HIGHSEC
ambience_index = AMBIENCE_DANGER
canSmoothWithAreas = /area/shuttle/syndicate
/area/shuttle/syndicate/bridge

View File

@@ -206,7 +206,7 @@ GLOBAL_LIST_INIT(arcade_prize_pool, list(
blocked = TRUE
var/attackamt = rand(2,6)
temp = "You attack for [attackamt] damage!"
playsound(loc, 'sound/arcade/hit.ogg', 50, 1, extrarange = -3, falloff = 10)
playsound(loc, 'sound/arcade/hit.ogg', 50, 1, extrarange = -3, falloff_exponent = 10)
updateUsrDialog()
if(turtle > 0)
turtle--
@@ -220,7 +220,7 @@ GLOBAL_LIST_INIT(arcade_prize_pool, list(
var/pointamt = rand(1,3)
var/healamt = rand(6,8)
temp = "You use [pointamt] magic to heal for [healamt] damage!"
playsound(loc, 'sound/arcade/heal.ogg', 50, 1, extrarange = -3, falloff = 10)
playsound(loc, 'sound/arcade/heal.ogg', 50, 1, extrarange = -3, falloff_exponent = 10)
updateUsrDialog()
turtle++
@@ -235,7 +235,7 @@ GLOBAL_LIST_INIT(arcade_prize_pool, list(
blocked = TRUE
var/chargeamt = rand(4,7)
temp = "You regain [chargeamt] points"
playsound(loc, 'sound/arcade/mana.ogg', 50, 1, extrarange = -3, falloff = 10)
playsound(loc, 'sound/arcade/mana.ogg', 50, 1, extrarange = -3, falloff_exponent = 10)
player_mp += chargeamt
if(turtle > 0)
turtle--
@@ -270,7 +270,7 @@ GLOBAL_LIST_INIT(arcade_prize_pool, list(
if(!gameover)
gameover = TRUE
temp = "[enemy_name] has fallen! Rejoice!"
playsound(loc, 'sound/arcade/win.ogg', 50, 1, extrarange = -3, falloff = 10)
playsound(loc, 'sound/arcade/win.ogg', 50, 1, extrarange = -3, falloff_exponent = 10)
if(obj_flags & EMAGGED)
new /obj/effect/spawner/newbomb/timer/syndicate(loc)
@@ -287,13 +287,13 @@ GLOBAL_LIST_INIT(arcade_prize_pool, list(
else if ((obj_flags & EMAGGED) && (turtle >= 4))
var/boomamt = rand(5,10)
temp = "[enemy_name] throws a bomb, exploding you for [boomamt] damage!"
playsound(loc, 'sound/arcade/boom.ogg', 50, 1, extrarange = -3, falloff = 10)
playsound(loc, 'sound/arcade/boom.ogg', 50, 1, extrarange = -3, falloff_exponent = 10)
player_hp -= boomamt
else if ((enemy_mp <= 5) && (prob(70)))
var/stealamt = rand(2,3)
temp = "[enemy_name] steals [stealamt] of your power!"
playsound(loc, 'sound/arcade/steal.ogg', 50, 1, extrarange = -3, falloff = 10)
playsound(loc, 'sound/arcade/steal.ogg', 50, 1, extrarange = -3, falloff_exponent = 10)
player_mp -= stealamt
updateUsrDialog()
@@ -301,27 +301,27 @@ GLOBAL_LIST_INIT(arcade_prize_pool, list(
gameover = TRUE
sleep(1 SECONDS)
temp = "You have been drained! GAME OVER"
playsound(loc, 'sound/arcade/lose.ogg', 50, 1, extrarange = -3, falloff = 10)
playsound(loc, 'sound/arcade/lose.ogg', 50, 1, extrarange = -3, falloff_exponent = 10)
if(obj_flags & EMAGGED)
usr.gib()
SSblackbox.record_feedback("nested tally", "arcade_results", 1, list("loss", "mana", (obj_flags & EMAGGED ? "emagged":"normal")))
else if ((enemy_hp <= 10) && (enemy_mp > 4))
temp = "[enemy_name] heals for 4 health!"
playsound(loc, 'sound/arcade/heal.ogg', 50, 1, extrarange = -3, falloff = 10)
playsound(loc, 'sound/arcade/heal.ogg', 50, 1, extrarange = -3, falloff_exponent = 10)
enemy_hp += 4
enemy_mp -= 4
else
var/attackamt = rand(3,6)
temp = "[enemy_name] attacks for [attackamt] damage!"
playsound(loc, 'sound/arcade/hit.ogg', 50, 1, extrarange = -3, falloff = 10)
playsound(loc, 'sound/arcade/hit.ogg', 50, 1, extrarange = -3, falloff_exponent = 10)
player_hp -= attackamt
if ((player_mp <= 0) || (player_hp <= 0))
gameover = TRUE
temp = "You have been crushed! GAME OVER"
playsound(loc, 'sound/arcade/lose.ogg', 50, 1, extrarange = -3, falloff = 10)
playsound(loc, 'sound/arcade/lose.ogg', 50, 1, extrarange = -3, falloff_exponent = 10)
if(obj_flags & EMAGGED)
usr.gib()
SSblackbox.record_feedback("nested tally", "arcade_results", 1, list("loss", "hp", (obj_flags & EMAGGED ? "emagged":"normal")))
@@ -1165,7 +1165,7 @@ GLOBAL_LIST_INIT(arcade_prize_pool, list(
var/obj/item/bodypart/chopchop = c_user.get_bodypart(which_hand)
chopchop.dismember()
qdel(chopchop)
playsound(loc, 'sound/arcade/win.ogg', 50, 1, extrarange = -3, falloff = 10)
playsound(loc, 'sound/arcade/win.ogg', 50, 1, extrarange = -3, falloff_exponent = 10)
for(var/i=1; i<=rand(3,5); i++)
prizevend(user)
else

View File

@@ -161,9 +161,9 @@
//target_pad.sparks()
flick("qpad-beam", src)
playsound(get_turf(src), 'sound/weapons/emitter2.ogg', 25, 1, extrarange = 3, falloff = 5)
playsound(get_turf(src), 'sound/weapons/emitter2.ogg', 25, 1, extrarange = 3, falloff_exponent = 5)
flick("qpad-beam", target_pad)
playsound(get_turf(target_pad), 'sound/weapons/emitter2.ogg', 25, 1, extrarange = 3, falloff = 5)
playsound(get_turf(target_pad), 'sound/weapons/emitter2.ogg', 25, 1, extrarange = 3, falloff_exponent = 5)
for(var/atom/movable/ROI in get_turf(src))
if(QDELETED(ROI))
continue //sleeps in CHECK_TICK

View File

@@ -526,7 +526,7 @@
. = ..()
if(world.time >= music_time)
SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "motivation", /datum/mood_event/motivation) //lets refresh the moodlet
M.stop_sound_channel(CHANNEL_AMBIENCE)
M.stop_sound_channel(CHANNEL_AMBIENT_EFFECTS)
music_time = 0
/obj/structure/chair/comfy/plastic/proc/motivate(mob/living/M)
@@ -534,5 +534,5 @@
return
SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "motivation", /datum/mood_event/motivation)
if(M.client && (M.client.prefs.toggles & SOUND_JUKEBOX))
M.stop_sound_channel(CHANNEL_AMBIENCE)
M.playsound_local(M, 'sound/ambience/burythelight.ogg',60,0, channel = CHANNEL_AMBIENCE)
M.stop_sound_channel(CHANNEL_AMBIENT_EFFECTS)
M.playsound_local(M, 'sound/ambience/burythelight.ogg',60,0, channel = CHANNEL_AMBIENT_EFFECTS)

View File

@@ -5,7 +5,50 @@ GLOBAL_LIST_INIT(alt_sound_overrides, list(
'sound/items/pshoom_2.ogg' = 'sound/items/pshoom.ogg',
))
/proc/playsound(atom/source, soundin, vol as num, vary, extrarange as num, falloff, frequency = null, channel = 0, pressure_affected = TRUE, ignore_walls = TRUE)
///Default override for echo
/sound
echo = list(
0, // Direct
0, // DirectHF
-10000, // Room, -10000 means no low frequency sound reverb
-10000, // RoomHF, -10000 means no high frequency sound reverb
0, // Obstruction
0, // ObstructionLFRatio
0, // Occlusion
0.25, // OcclusionLFRatio
1.5, // OcclusionRoomRatio
1.0, // OcclusionDirectRatio
0, // Exclusion
1.0, // ExclusionLFRatio
0, // OutsideVolumeHF
0, // DopplerFactor
0, // RolloffFactor
0, // RoomRolloffFactor
1.0, // AirAbsorptionFactor
0, // Flags (1 = Auto Direct, 2 = Auto Room, 4 = Auto RoomHF)
)
environment = SOUND_ENVIRONMENT_NONE //Default to none so sounds without overrides dont get reverb
/*! playsound
playsound is a proc used to play a 3D sound in a specific range. This uses SOUND_RANGE + extra_range to determine that.
source - Origin of sound
soundin - Either a file, or a string that can be used to get an SFX
vol - The volume of the sound, excluding falloff and pressure affection.
vary - bool that determines if the sound changes pitch every time it plays
extrarange - modifier for sound range. This gets added on top of SOUND_RANGE
falloff_exponent - Rate of falloff for the audio. Higher means quicker drop to low volume. Should generally be over 1 to indicate a quick dive to 0 rather than a slow dive.
frequency - playback speed of audio
channel - The channel the sound is played at
pressure_affected - Whether or not difference in pressure affects the sound (E.g. if you can hear in space)
ignore_walls - Whether or not the sound can pass through walls.
falloff_distance - Distance at which falloff begins. Sound is at peak volume (in regards to falloff) aslong as it is in this range.
*/
/proc/playsound(atom/source, soundin, vol as num, vary, extrarange as num, falloff_exponent = SOUND_FALLOFF_EXPONENT, frequency = null, channel = 0, pressure_affected = TRUE, ignore_walls = TRUE, falloff_distance = SOUND_DEFAULT_FALLOFF_DISTANCE, use_reverb = TRUE)
if(isarea(source))
CRASH("playsound(): source is an area")
@@ -19,7 +62,7 @@ GLOBAL_LIST_INIT(alt_sound_overrides, list(
// Looping through the player list has the added bonus of working for mobs inside containers
var/sound/S = sound(get_sfx(soundin))
var/maxdistance = (world.view + extrarange)
var/maxdistance = (SOUND_RANGE + extrarange)
var/z = turf_source.z
var/list/listeners = SSmobs.clients_by_zlevel[z]
if(!ignore_walls) //these sounds don't carry through walls
@@ -27,13 +70,30 @@ GLOBAL_LIST_INIT(alt_sound_overrides, list(
for(var/P in listeners)
var/mob/M = P
if(get_dist(M, turf_source) <= maxdistance)
M.playsound_local(turf_source, soundin, vol, vary, frequency, falloff, channel, pressure_affected, S)
M.playsound_local(turf_source, soundin, vol, vary, frequency, falloff_exponent, channel, pressure_affected, S, maxdistance, falloff_distance, 1, use_reverb)
for(var/P in SSmobs.dead_players_by_zlevel[z])
var/mob/M = P
if(get_dist(M, turf_source) <= maxdistance)
M.playsound_local(turf_source, soundin, vol, vary, frequency, falloff, channel, pressure_affected, S)
M.playsound_local(turf_source, soundin, vol, vary, frequency, falloff_exponent, channel, pressure_affected, S, maxdistance, falloff_distance, 1, use_reverb)
/mob/proc/playsound_local(turf/turf_source, soundin, vol as num, vary, frequency, falloff, channel = 0, pressure_affected = TRUE, sound/S, distance_multiplier = 1)
/*! playsound
playsound_local is a proc used to play a sound directly on a mob from a specific turf.
This is called by playsound to send sounds to players, in which case it also gets the max_distance of that sound.
turf_source - Origin of sound
soundin - Either a file, or a string that can be used to get an SFX
vol - The volume of the sound, excluding falloff
vary - bool that determines if the sound changes pitch every time it plays
frequency - playback speed of audio
falloff_exponent - Rate of falloff for the audio. Higher means quicker drop to low volume. Should generally be over 1 to indicate a quick dive to 0 rather than a slow dive.
channel - The channel the sound is played at
pressure_affected - Whether or not difference in pressure affects the sound (E.g. if you can hear in space)
max_distance - The peak distance of the sound, if this is a 3D sound
falloff_distance - Distance at which falloff begins, if this is a 3D sound
distance_multiplier - Can be used to multiply the distance at which the sound is heard
*/
/mob/proc/playsound_local(turf/turf_source, soundin, vol as num, vary, frequency, falloff_exponent = SOUND_FALLOFF_EXPONENT, channel = 0, pressure_affected = TRUE, sound/S, max_distance, falloff_distance = SOUND_DEFAULT_FALLOFF_DISTANCE, distance_multiplier = 1, use_reverb = TRUE)
if(!client || !can_hear())
return
@@ -61,7 +121,9 @@ GLOBAL_LIST_INIT(alt_sound_overrides, list(
distance *= distance_multiplier
S.volume -= max(distance - world.view, 0) * 2 //multiplicative falloff to add on top of natural audio falloff.
if(max_distance) //If theres no max_distance we're not a 3D sound, so no falloff.
S.volume -= (max(distance - falloff_distance, 0) ** (1 / falloff_exponent)) / ((max(max_distance, distance) - falloff_distance) ** (1 / falloff_exponent)) * S.volume
//https://www.desmos.com/calculator/sqdfl8ipgf
if(pressure_affected)
//Atmosphere affects sound
@@ -92,17 +154,30 @@ GLOBAL_LIST_INIT(alt_sound_overrides, list(
var/dy = (turf_source.z - T.z) * 5 * distance_multiplier // Hearing from above / below, multiplied by 5 because we assume height is further along coords.
S.y = dy
S.falloff = (falloff ? falloff : FALLOFF_SOUNDS)
S.falloff = max_distance || 1 //use max_distance, else just use 1 as we are a direct sound so falloff isnt relevant.
// Sounds can't have their own environment. A sound's environment will be:
// 1. the mob's
// 2. the area's (defaults to SOUND_ENVRIONMENT_NONE)
if(sound_environment_override != SOUND_ENVIRONMENT_NONE)
S.environment = sound_environment_override
else
var/area/A = get_area(src)
S.environment = A.sound_environment
if(use_reverb && S.environment != SOUND_ENVIRONMENT_NONE) //We have reverb, reset our echo setting
S.echo[3] = 0 //Room setting, 0 means normal reverb
S.echo[4] = 0 //RoomHF setting, 0 means normal reverb.
SEND_SOUND(src, S)
/proc/sound_to_playing_players(soundin, volume = 100, vary = FALSE, frequency = 0, falloff = FALSE, channel = 0, pressure_affected = FALSE, sound/S)
/proc/sound_to_playing_players(soundin, volume = 100, vary = FALSE, frequency = 0, channel = 0, pressure_affected = FALSE, sound/S)
if(!S)
S = sound(get_sfx(soundin))
for(var/m in GLOB.player_list)
if(ismob(m) && !isnewplayer(m))
var/mob/M = m
M.playsound_local(M, null, volume, vary, frequency, falloff, channel, pressure_affected, S)
M.playsound_local(M, null, volume, vary, frequency, null, channel, pressure_affected, S)
/mob/proc/stop_sound_channel(chan)
SEND_SOUND(src, sound(null, repeat = 0, wait = 0, channel = chan))
@@ -205,3 +280,22 @@ GLOBAL_LIST_INIT(alt_sound_overrides, list(
if("switch") //stolen from nsv
soundin = pick('sound/machines/switch1.ogg','sound/machines/switch2.ogg','sound/machines/switch3.ogg')
return soundin
/client/proc/channel_in_use(channel)
for (var/sound/S in src.SoundQuery())
if (S.channel == channel)
return TRUE
return FALSE
/mob/proc/can_hear_ambience()
if (!src.can_hear()) // If they can't hear they can't hear
return FALSE
var/turf/T = get_turf(src)
var/datum/gas_mixture/hearer_env = T.return_air()
if (!hearer_env || hearer_env.return_pressure() < SOUND_MINIMUM_PRESSURE) // They can't hear ambience if there isn't enough pressure
return FALSE
return TRUE

View File

@@ -22,7 +22,7 @@
for(var/mob/M in GLOB.player_list)
if(M.z == z)
if(get_dist(src, M) >= 7)
M.playsound_local(src, 'sound/magic/blink.ogg', 10, FALSE, falloff = 10)
M.playsound_local(src, 'sound/magic/blink.ogg', 10, FALSE, falloff_exponent = 10)
else
M.playsound_local(src, 'sound/magic/blink.ogg', 50, FALSE)

View File

@@ -207,9 +207,9 @@
if(last_accent_sound < world.time && prob(20))
var/aggression = min(((critical_threshold_proximity / 800) * ((power_level) / 5)), 1.0) * 100
if(critical_threshold_proximity >= 300)
playsound(src, "hypertorusmelting", max(50, aggression), FALSE, 40, 30, falloff = 10)
playsound(src, "hypertorusmelting", max(50, aggression), FALSE, 40, 30, falloff_exponent = 10)
else
playsound(src, "hypertoruscalm", max(50, aggression), FALSE, 25, 25, falloff = 10)
playsound(src, "hypertoruscalm", max(50, aggression), FALSE, 25, 25, falloff_exponent = 10)
var/next_sound = round((100 - aggression) * 5) + 5
last_accent_sound = world.time + max(HYPERTORUS_ACCENT_SOUND_MIN_COOLDOWN, next_sound)
@@ -291,11 +291,11 @@
/obj/machinery/atmospherics/components/unary/hypertorus/core/proc/alarm()
switch(get_status())
if(HYPERTORUS_MELTING)
playsound(src, 'sound/misc/bloblarm.ogg', 100, FALSE, 40, 30, falloff = 10)
playsound(src, 'sound/misc/bloblarm.ogg', 100, FALSE, 40, 30, falloff_exponent = 10)
if(HYPERTORUS_EMERGENCY)
playsound(src, 'sound/machines/engine_alert1.ogg', 100, FALSE, 30, 30, falloff = 10)
playsound(src, 'sound/machines/engine_alert1.ogg', 100, FALSE, 30, 30, falloff_exponent = 10)
if(HYPERTORUS_DANGER)
playsound(src, 'sound/machines/engine_alert2.ogg', 100, FALSE, 30, 30, falloff = 10)
playsound(src, 'sound/machines/engine_alert2.ogg', 100, FALSE, 30, 30, falloff_exponent = 10)
if(HYPERTORUS_WARNING)
playsound(src, 'sound/machines/terminal_alert.ogg', 75)

View File

@@ -38,7 +38,7 @@
var/path = "sound/chatter/[phomeme]_[length].ogg"
playsound(loc, path,
vol = 40, vary = 0, extrarange = 3, falloff = FALSE)
vol = 40, vary = 0, extrarange = 3, falloff_exponent = FALSE)
sleep((length + 1) * chatter_get_sleep_multiplier(phomeme))

View File

@@ -49,10 +49,9 @@
///////////////
//SOUND STUFF//
///////////////
///Currently playing ambience sound
var/ambience_playing = null
///Whether an ambience sound has been played and one shouldn't be played again, unset by a callback
var/played = FALSE
var/buzz_playing = null
////////////
//SECURITY//
////////////

View File

@@ -436,7 +436,7 @@ GLOBAL_LIST_INIT(blacklisted_builds, list(
if(!winexists(src, "asset_cache_browser")) // The client is using a custom skin, tell them.
to_chat(src, span_warning("Unable to access asset cache browser, if you are using a custom skin file, please allow DS to download the updated version, if you are not, then make a bug report. This is not a critical issue but can cause issues with resource downloading, as it is impossible to know when extra resources arrived to you."))
update_ambience_pref()
//This is down here because of the browse() calls in tooltip/New()
if(!tooltips)
tooltips = new /datum/tooltip(src)
@@ -508,6 +508,8 @@ GLOBAL_LIST_INIT(blacklisted_builds, list(
GLOB.directory -= ckey
GLOB.clients -= src
SSambience.remove_ambience_client(src)
var/datum/connection_log/CL = GLOB.connection_logs[ckey]
if(CL)
CL.logout(mob)
@@ -1095,3 +1097,11 @@ GLOBAL_LIST_INIT(blacklisted_builds, list(
SEND_SOUND(usr, sound(null))
tgui_panel?.stop_music()
SSblackbox.record_feedback("nested tally", "preferences_verb", 1, list("Stop Self Sounds"))
/client/proc/update_ambience_pref()
if(prefs.toggles & SOUND_AMBIENCE)
if(SSambience.ambience_listening_clients[src] > world.time)
return // If already properly set we don't want to reset the timer.
SSambience.ambience_listening_clients[src] = world.time + 10 SECONDS //Just wait 10 seconds before the next one aight mate? cheers.
else
SSambience.ambience_listening_clients -= src

View File

@@ -865,7 +865,7 @@ GLOBAL_LIST_INIT(hallucination_list, list(
target.playsound_local(source, pick('sound/voice/human/manlaugh1.ogg', 'sound/voice/human/manlaugh2.ogg'), 50, 1)
if("creepy")
//These sounds are (mostly) taken from Hidden: Source
target.playsound_local(source, pick(CREEPY_SOUNDS), 50, 1)
target.playsound_local(source, pick(GLOB.creepy_ambience), 50, 1)
if("tesla") //Tesla loose!
target.playsound_local(source, 'sound/magic/lightningbolt.ogg', 35, 1)
sleep(3 SECONDS)

View File

@@ -87,5 +87,5 @@
L.apply_status_effect(STATUS_EFFECT_GOOD_MUSIC)
if(!(M?.client?.prefs?.toggles & SOUND_INSTRUMENTS))
continue
M.playsound_local(source, null, volume * using_instrument.volume_multiplier, falloff = 5, S = music_played)
M.playsound_local(source, null, volume * using_instrument.volume_multiplier, falloff_exponent = 5, S = music_played)
// Could do environment and echo later but not for now

View File

@@ -214,3 +214,5 @@
var/datum/client_interface/mock_client
var/create_area_cooldown
var/sound_environment_override = SOUND_ENVIRONMENT_NONE

View File

@@ -24,7 +24,7 @@
sleep(0.5 SECONDS)
if(boss_hp <= 0)
heads_up = "You have crushed [boss_name]! Rejoice!"
playsound(computer.loc, 'sound/arcade/win.ogg', 50, TRUE, extrarange = -3, falloff = 10)
playsound(computer.loc, 'sound/arcade/win.ogg', 50, TRUE, extrarange = -3, falloff_exponent = 10)
game_active = FALSE
program_icon_state = "arcade_off"
if(istype(computer))
@@ -34,7 +34,7 @@
return
else if(player_hp <= 0 || player_mp <= 0)
heads_up = "You have been defeated... how will the station survive?"
playsound(computer.loc, 'sound/arcade/lose.ogg', 50, TRUE, extrarange = -3, falloff = 10)
playsound(computer.loc, 'sound/arcade/lose.ogg', 50, TRUE, extrarange = -3, falloff_exponent = 10)
game_active = FALSE
program_icon_state = "arcade_off"
if(istype(computer))
@@ -55,17 +55,17 @@
return
if (boss_mp <= 5)
heads_up = "[boss_mpamt] magic power has been stolen from you!"
playsound(computer.loc, 'sound/arcade/steal.ogg', 50, TRUE, extrarange = -3, falloff = 10)
playsound(computer.loc, 'sound/arcade/steal.ogg', 50, TRUE, extrarange = -3, falloff_exponent = 10)
player_mp -= boss_mpamt
boss_mp += boss_mpamt
else if(boss_mp > 5 && boss_hp <12)
heads_up = "[boss_name] heals for [bossheal] health!"
playsound(computer.loc, 'sound/arcade/heal.ogg', 50, TRUE, extrarange = -3, falloff = 10)
playsound(computer.loc, 'sound/arcade/heal.ogg', 50, TRUE, extrarange = -3, falloff_exponent = 10)
boss_hp += bossheal
boss_mp -= boss_mpamt
else
heads_up = "[boss_name] attacks you for [boss_attackamt] damage!"
playsound(computer.loc, 'sound/arcade/hit.ogg', 50, TRUE, extrarange = -3, falloff = 10)
playsound(computer.loc, 'sound/arcade/hit.ogg', 50, TRUE, extrarange = -3, falloff_exponent = 10)
player_hp -= boss_attackamt
pause_state = FALSE
@@ -104,7 +104,7 @@
pause_state = TRUE
heads_up = "You attack for [attackamt] damage."
computer.play_interact_sound()
playsound(computer.loc, 'sound/arcade/hit.ogg', 50, TRUE, extrarange = -3, falloff = 10)
playsound(computer.loc, 'sound/arcade/hit.ogg', 50, TRUE, extrarange = -3, falloff_exponent = 10)
boss_hp -= attackamt
sleep(1 SECONDS)
game_check()
@@ -119,7 +119,7 @@
pause_state = TRUE
heads_up = "You heal for [healamt] damage."
computer.play_interact_sound()
playsound(computer.loc, 'sound/arcade/heal.ogg', 50, TRUE, extrarange = -3, falloff = 10)
playsound(computer.loc, 'sound/arcade/heal.ogg', 50, TRUE, extrarange = -3, falloff_exponent = 10)
player_hp += healamt
player_mp -= healcost
sleep(1 SECONDS)
@@ -133,7 +133,7 @@
pause_state = TRUE
heads_up = "You regain [rechargeamt] magic power."
computer.play_interact_sound()
playsound(computer.loc, 'sound/arcade/mana.ogg', 50, TRUE, extrarange = -3, falloff = 10)
playsound(computer.loc, 'sound/arcade/mana.ogg', 50, TRUE, extrarange = -3, falloff_exponent = 10)
player_mp += rechargeamt
sleep(1 SECONDS)
game_check()

View File

@@ -181,7 +181,7 @@
var/obj/item/modular_computer/comp = host
comp.play_computer_sound(sound, 50, 0)
else
playsound(get_turf(host), sound, 50, 0, extrarange = -3, falloff = 10)
playsound(get_turf(host), sound, 50, 0, extrarange = -3, falloff_exponent = 10)
/datum/minesweeper/proc/vis_msg(msg, local_msg)
if(istype(host, /obj/item/modular_computer))

View File

@@ -90,7 +90,7 @@
return TRUE
drawing = FALSE
to_chat(user, span_notice("You draw back the bowstring."))
playsound(src, draw_sound, 75, 0, falloff = 3) //gets way too high pitched if the freq varies
playsound(src, draw_sound, 75, 0, falloff_exponent = 3) //gets way too high pitched if the freq varies
chamber_round()
return TRUE

View File

@@ -806,7 +806,7 @@
for(var/mob/M in SSmobs.clients_by_zlevel[z])
var/dist_far = get_dist(M, distant_source)
if(dist_far <= long_range && dist_far > range)
M.playsound_local(distant_source, "sound/effects/[selected_sound]_distance.ogg", 100, falloff = 20)
M.playsound_local(distant_source, "sound/effects/[selected_sound]_distance.ogg", 100, falloff_exponent = 20)
else if(dist_far <= range)
var/source
if(engine_list.len == 0)
@@ -818,7 +818,7 @@
if(dist_near < closest_dist)
source = O
closest_dist = dist_near
M.playsound_local(source, "sound/effects/[selected_sound].ogg", 100, falloff = range / 2)
M.playsound_local(source, "sound/effects/[selected_sound].ogg", 100, falloff_exponent = range / 2)
// Losing all initial engines should get you 2
// Adding another set of engines at 0.5 time

View File

@@ -79,7 +79,7 @@
var/datum/surgery/procedure = new S.type(M, selected_zone, affecting)
user.visible_message("[user] prepares to operate on [M]'s [parse_zone(selected_zone)].", \
span_notice("You prepare to operate on [M]'s [parse_zone(selected_zone)]."))
playsound(get_turf(M), 'sound/items/handling/cloth_drop.ogg', 30, TRUE, falloff = 1)
playsound(get_turf(M), 'sound/items/handling/cloth_drop.ogg', 30, TRUE, falloff_exponent = 1)
log_combat(user, M, "operated on", null, "(OPERATION TYPE: [procedure.name]) (TARGET AREA: [selected_zone])")
if(S.self_operable || user != M)
procedure.next_step(user, user.a_intent)

View File

@@ -170,7 +170,7 @@
sound_file_use = preop_sound
if(!sound_file_use)
return
playsound(get_turf(target), sound_file_use, 30, TRUE, falloff = 2)
playsound(get_turf(target), sound_file_use, 30, TRUE, falloff_exponent = 2)
/datum/surgery_step/proc/success(mob/user, mob/living/target, target_zone, obj/item/tool, datum/surgery/surgery)
display_results(user, target, span_notice("You succeed."),
@@ -191,7 +191,7 @@
sound_file_use = success_sound
if(!sound_file_use)
return
playsound(get_turf(target), sound_file_use, 30, TRUE, falloff = 2)
playsound(get_turf(target), sound_file_use, 30, TRUE, falloff_exponent = 2)
/datum/surgery_step/proc/failure(mob/user, mob/living/target, target_zone, obj/item/tool, datum/surgery/surgery)
display_results(user, target, span_warning("You screw up!"),
@@ -212,7 +212,7 @@
sound_file_use = failure_sound
if(!sound_file_use)
return
playsound(get_turf(target), sound_file_use, 30, TRUE, falloff = 2)
playsound(get_turf(target), sound_file_use, 30, TRUE, falloff_exponent = 2)
/datum/surgery_step/proc/tool_check(mob/user, obj/item/tool)
return TRUE

BIN
sound/ambience/ambiviro.ogg Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
sound/ambience/magma.ogg Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -259,6 +259,7 @@
#include "code\_globalvars\lists\objects.dm"
#include "code\_globalvars\lists\poll_ignore.dm"
#include "code\_globalvars\lists\typecache.dm"
#include "code\_globalvars\lists\ambience.dm"
#include "code\_js\byjax.dm"
#include "code\_js\menus.dm"
#include "code\_onclick\adjacent.dm"
@@ -402,6 +403,7 @@
#include "code\controllers\subsystem\processing\slowprocess.dm"
#include "code\controllers\subsystem\processing\station.dm"
#include "code\controllers\subsystem\processing\wet_floors.dm"
#include "code\controllers\subsystem\ambience.dm"
#include "code\datums\ai_laws.dm"
#include "code\datums\armor.dm"
#include "code\datums\beam.dm"

View File

@@ -7,7 +7,7 @@
has_gravity = TRUE
noteleport = TRUE
flags_1 = NONE
ambientsounds = HIGHSEC
ambience_index = AMBIENCE_DANGER
dynamic_lighting = DYNAMIC_LIGHTING_FORCED
/area/yogs/infiltrator_base/poweralert(state, obj/source)

View File

@@ -23,9 +23,9 @@
return
if(board.game_status == MINESWEEPER_IDLE || board.game_status == MINESWEEPER_DEAD || board.game_status == MINESWEEPER_VICTORY)
if(obj_flags & EMAGGED)
playsound(loc, 'yogstation/sound/arcade/minesweeper_emag2.ogg', 50, 0, extrarange = -3, falloff = 10)
playsound(loc, 'yogstation/sound/arcade/minesweeper_emag2.ogg', 50, 0, extrarange = -3, falloff_exponent = 10)
else
playsound(loc, 'yogstation/sound/arcade/minesweeper_startup.ogg', 50, 0, extrarange = -3, falloff = 10)
playsound(loc, 'yogstation/sound/arcade/minesweeper_startup.ogg', 50, 0, extrarange = -3, falloff_exponent = 10)
if(obj_flags & EMAGGED)
do_sparks(5, 1, src)
@@ -154,8 +154,8 @@
obj_flags |= EMAGGED
if(board.game_status != MINESWEEPER_CONTINUE)
to_chat(user, span_warning("An ominous tune plays from the arcade's speakers!"))
playsound(user, 'yogstation/sound/arcade/minesweeper_emag1.ogg', 100, 0, extrarange = 3, falloff = 10)
playsound(user, 'yogstation/sound/arcade/minesweeper_emag1.ogg', 100, 0, extrarange = 3, falloff_exponent = 10)
else //Can't let you do that, star fox!
to_chat(user, span_warning("The machine buzzes and sparks... the game has been reset!"))
playsound(user, 'sound/machines/buzz-sigh.ogg', 100, 0, extrarange = 3, falloff = 10) //Loud buzz
playsound(user, 'sound/machines/buzz-sigh.ogg', 100, 0, extrarange = 3, falloff_exponent = 10) //Loud buzz
board.game_status = MINESWEEPER_IDLE

View File

@@ -71,7 +71,7 @@
playsound(src, 'yogstation/sound/creatures/progenitor_roar.ogg', 50, TRUE)
for(var/mob/M in GLOB.player_list)
if(get_dist(M, src) > 7)
M.playsound_local(src, 'yogstation/sound/creatures/progenitor_distant.ogg', 25, FALSE, falloff = 5)
M.playsound_local(src, 'yogstation/sound/creatures/progenitor_distant.ogg', 25, FALSE, falloff_exponent = 5)
else if(isliving(M))
var/mob/living/L = M
if(L != src) //OH GOD OH FUCK I'M SCARING MYSELF

View File

@@ -16,7 +16,7 @@ GLOBAL_LIST_EMPTY(pocket_mirrors)
unique = FALSE
requires_power = FALSE
show_on_sensors = FALSE
ambientsounds = SPACE
ambience_index = AMBIENCE_SPACE
parallax_movedir = EAST
/obj/effect/landmark/pocket_dimension_corner