diff --git a/code/__defines/dcs/helpers.dm b/code/__defines/dcs/helpers.dm index 144e94f1fe..c5c7e3c42d 100644 --- a/code/__defines/dcs/helpers.dm +++ b/code/__defines/dcs/helpers.dm @@ -6,6 +6,10 @@ #define SEND_GLOBAL_SIGNAL(sigtype, arguments...) ( SEND_SIGNAL(SSdcs, sigtype, ##arguments) ) +/// Signifies that this proc is used to handle signals. +/// Every proc you pass to RegisterSignal must have this. +#define SIGNAL_HANDLER SHOULD_NOT_SLEEP(TRUE) + /// A wrapper for _AddElement that allows us to pretend we're using normal named arguments #define AddElement(arguments...) _AddElement(list(##arguments)) /// A wrapper for _RemoveElement that allows us to pretend we're using normal named arguments diff --git a/code/__defines/instruments.dm b/code/__defines/instruments.dm new file mode 100644 index 0000000000..fa09eee0dd --- /dev/null +++ b/code/__defines/instruments.dm @@ -0,0 +1,24 @@ +#define INSTRUMENT_MIN_OCTAVE 1 +#define INSTRUMENT_MAX_OCTAVE 9 +#define INSTRUMENT_MIN_KEY 0 +#define INSTRUMENT_MAX_KEY 127 + +/// Max number of playing notes per instrument. +#define CHANNELS_PER_INSTRUMENT 128 + +/// Maximum length a note should ever go for +#define INSTRUMENT_MAX_TOTAL_SUSTAIN (5 SECONDS) + +/// These are per decisecond. +#define INSTRUMENT_EXP_FALLOFF_MIN 1.025 //100/(1.025^50) calculated for [INSTRUMENT_MIN_SUSTAIN_DROPOFF] to be 30. +#define INSTRUMENT_EXP_FALLOFF_MAX 10 + +/// Minimum volume for when the sound is considered dead. +#define INSTRUMENT_MIN_SUSTAIN_DROPOFF 0 + +#define SUSTAIN_LINEAR 1 +#define SUSTAIN_EXPONENTIAL 2 + +// /datum/instrument instrument_flags +#define INSTRUMENT_LEGACY (1<<0) //Legacy instrument. Implies INSTRUMENT_DO_NOT_AUTOSAMPLE +#define INSTRUMENT_DO_NOT_AUTOSAMPLE (1<<1) //Do not automatically sample diff --git a/code/__defines/misc.dm b/code/__defines/misc.dm index 91c3d508b5..cf34b37aa1 100644 --- a/code/__defines/misc.dm +++ b/code/__defines/misc.dm @@ -423,6 +423,7 @@ GLOBAL_LIST_EMPTY(##LIST_NAME);\ #define VOLUME_CHANNEL_ALARMS "Alarms" #define VOLUME_CHANNEL_VORE "Vore" #define VOLUME_CHANNEL_DOORS "Doors" +#define VOLUME_CHANNEL_INSTRUMENTS "Instruments" // Make sure you update this or clients won't be able to adjust the channel GLOBAL_LIST_INIT(all_volume_channels, list( @@ -431,6 +432,7 @@ GLOBAL_LIST_INIT(all_volume_channels, list( VOLUME_CHANNEL_ALARMS, VOLUME_CHANNEL_VORE, VOLUME_CHANNEL_DOORS, + VOLUME_CHANNEL_INSTRUMENTS )) #define APPEARANCECHANGER_CHANGED_RACE "Race" diff --git a/code/__defines/sound.dm b/code/__defines/sound.dm index a0d5fe5be4..570170bb93 100644 --- a/code/__defines/sound.dm +++ b/code/__defines/sound.dm @@ -18,43 +18,47 @@ #define SOUND_MINIMUM_PRESSURE 10 #define FALLOFF_SOUNDS 0.5 -//Sound environment defines. Reverb preset for sounds played in an area, see sound datum reference for more. -#define GENERIC 0 -#define PADDED_CELL 1 -#define ROOM 2 -#define BATHROOM 3 -#define LIVINGROOM 4 -#define STONEROOM 5 -#define AUDITORIUM 6 -#define CONCERT_HALL 7 -#define CAVE 8 -#define ARENA 9 -#define HANGAR 10 -#define CARPETED_HALLWAY 11 -#define HALLWAY 12 -#define STONE_CORRIDOR 13 -#define ALLEY 14 -#define FOREST 15 -#define CITY 16 -#define MOUNTAINS 17 -#define QUARRY 18 -#define PLAIN 19 -#define PARKING_LOT 20 -#define SEWER_PIPE 21 -#define UNDERWATER 22 -#define DRUGGED 23 -#define DIZZY 24 -#define PSYCHOTIC 25 +#define MAX_INSTRUMENT_CHANNELS (128 * 6) -#define STANDARD_STATION STONEROOM -#define LARGE_ENCLOSED HANGAR -#define SMALL_ENCLOSED BATHROOM -#define TUNNEL_ENCLOSED CAVE -#define LARGE_SOFTFLOOR CARPETED_HALLWAY -#define MEDIUM_SOFTFLOOR LIVINGROOM -#define SMALL_SOFTFLOOR ROOM -#define ASTEROID CAVE -#define SPACE UNDERWATER +//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 + +#define STANDARD_STATION SOUND_ENVIRONMENT_STONEROOM +#define LARGE_ENCLOSED SOUND_ENVIRONMENT_HANGAR +#define SMALL_ENCLOSED SOUND_ENVIRONMENT_BATHROOM +#define TUNNEL_ENCLOSED SOUND_ENVIRONMENT_CAVE +#define LARGE_SOFTFLOOR SOUND_ENVIRONMENT_CARPETED_HALLWAY +#define MEDIUM_SOFTFLOOR SOUND_ENVIRONMENT_LIVINGROOM +#define SMALL_SOFTFLOOR SOUND_ENVIRONMENT_ROOM +#define ASTEROID SOUND_ENVIRONMENT_CAVE +#define SPACE SOUND_ENVIRONMENT_UNDERWATER // Ambience presets. // All you need to do to make an area play one of these is set their ambience var to one of these lists. diff --git a/code/__defines/subsystems.dm b/code/__defines/subsystems.dm index ba97a1114a..92b35d7c72 100644 --- a/code/__defines/subsystems.dm +++ b/code/__defines/subsystems.dm @@ -58,6 +58,8 @@ var/global/list/runlevel_flags = list(RUNLEVEL_LOBBY, RUNLEVEL_SETUP, RUNLEVEL_G #define INIT_ORDER_CHEMISTRY 35 #define INIT_ORDER_SKYBOX 30 #define INIT_ORDER_MAPPING 25 +#define INIT_ORDER_SOUNDS 23 +#define INIT_ORDER_INSTRUMENTS 22 #define INIT_ORDER_DECALS 20 #define INIT_ORDER_PLANTS 19 // Must initialize before atoms. #define INIT_ORDER_PLANETS 18 @@ -92,8 +94,9 @@ var/global/list/runlevel_flags = list(RUNLEVEL_LOBBY, RUNLEVEL_SETUP, RUNLEVEL_G #define FIRE_PRIORITY_SUPPLY 5 #define FIRE_PRIORITY_NIGHTSHIFT 5 #define FIRE_PRIORITY_PLANTS 5 -#define FIRE_PRIORITY_ORBIT 8 -#define FIRE_PRIORITY_VOTE 9 +#define FIRE_PRIORITY_ORBIT 7 +#define FIRE_PRIORITY_VOTE 8 +#define FIRE_PRIORITY_INSTRUMENTS 9 #define FIRE_PRIORITY_AI 10 #define FIRE_PRIORITY_GARBAGE 15 #define FIRE_PRIORITY_ALARM 20 diff --git a/code/controllers/subsystems/processing/instruments.dm b/code/controllers/subsystems/processing/instruments.dm new file mode 100644 index 0000000000..ee0fd1ea00 --- /dev/null +++ b/code/controllers/subsystems/processing/instruments.dm @@ -0,0 +1,56 @@ +PROCESSING_SUBSYSTEM_DEF(instruments) + name = "Instruments" + wait = 0.5 + init_order = INIT_ORDER_INSTRUMENTS + flags = SS_KEEP_TIMING + priority = FIRE_PRIORITY_INSTRUMENTS + /// List of all instrument data, associative id = datum + var/static/list/datum/instrument/instrument_data = list() + /// List of all song datums. + var/static/list/datum/song/songs = list() + /// Max lines in songs + var/static/musician_maxlines = 600 + /// Max characters per line in songs + var/static/musician_maxlinechars = 300 + /// Deciseconds between hearchecks. Too high and instruments seem to lag when people are moving around in terms of who can hear it. Too low and the server lags from this. + var/static/musician_hearcheck_mindelay = 5 + /// Maximum instrument channels total instruments are allowed to use. This is so you don't have instruments deadlocking all sound channels. + var/static/max_instrument_channels = MAX_INSTRUMENT_CHANNELS + /// Current number of channels allocated for instruments + var/static/current_instrument_channels = 0 + /// Single cached list for synthesizer instrument ids, so you don't have to have a new list with every synthesizer. + var/static/list/synthesizer_instrument_ids + +/datum/controller/subsystem/processing/instruments/Initialize() + initialize_instrument_data() + synthesizer_instrument_ids = get_allowed_instrument_ids() + return ..() + +/datum/controller/subsystem/processing/instruments/proc/on_song_new(datum/song/S) + songs += S + +/datum/controller/subsystem/processing/instruments/proc/on_song_del(datum/song/S) + songs -= S + +/datum/controller/subsystem/processing/instruments/proc/initialize_instrument_data() + for(var/path in subtypesof(/datum/instrument)) + var/datum/instrument/I = path + if(initial(I.abstract_type) == path) + continue + I = new path + I.Initialize() + if(!I.id) + qdel(I) + continue + instrument_data[I.id] = I + CHECK_TICK + +/datum/controller/subsystem/processing/instruments/proc/get_instrument(id_or_path) + return instrument_data["[id_or_path]"] + +/datum/controller/subsystem/processing/instruments/proc/reserve_instrument_channel(datum/instrument/I) + if(current_instrument_channels > max_instrument_channels) + return + . = SSsounds.reserve_sound_channel(I) + if(!isnull(.)) + current_instrument_channels++ diff --git a/code/controllers/subsystems/sounds.dm b/code/controllers/subsystems/sounds.dm new file mode 100644 index 0000000000..7d94a3d21d --- /dev/null +++ b/code/controllers/subsystems/sounds.dm @@ -0,0 +1,135 @@ +#define DATUMLESS "NO_DATUM" + +SUBSYSTEM_DEF(sounds) + name = "Sounds" + flags = SS_NO_FIRE + init_order = INIT_ORDER_SOUNDS + var/static/using_channels_max = CHANNEL_HIGHEST_AVAILABLE //BYOND max channels + /// Amount of channels to reserve for random usage rather than reservations being allowed to reserve all channels. Also a nice safeguard for when someone screws up. + var/static/random_channels_min = 50 + + // Hey uh these two needs to be initialized fast because the whole "things get deleted before init" thing. + /// Assoc list, `"[channel]" =` either the datum using it or TRUE for an unsafe-reserved (datumless reservation) channel + var/list/using_channels + /// Assoc list datum = list(channel1, channel2, ...) for what channels something reserved. + var/list/using_channels_by_datum + // Special datastructure for fast channel management + /// List of all channels as numbers + var/list/channel_list + /// Associative list of all reserved channels associated to their position. `"[channel_number]" =` index as number + var/list/reserved_channels + /// lower iteration position - Incremented and looped to get "random" sound channels for normal sounds. The channel at this index is returned when asking for a random channel. + var/channel_random_low + /// higher reserve position - decremented and incremented to reserve sound channels, anything above this is reserved. The channel at this index is the highest unreserved channel. + var/channel_reserve_high + +/datum/controller/subsystem/sounds/Initialize() + setup_available_channels() + return ..() + +/datum/controller/subsystem/sounds/proc/setup_available_channels() + channel_list = list() + reserved_channels = list() + using_channels = list() + using_channels_by_datum = list() + for(var/i in 1 to using_channels_max) + channel_list += i + channel_random_low = 1 + channel_reserve_high = length(channel_list) + +/// Removes a channel from using list. +/datum/controller/subsystem/sounds/proc/free_sound_channel(channel) + var/text_channel = num2text(channel) + var/using = using_channels[text_channel] + using_channels -= text_channel + if(using != TRUE) // datum channel + using_channels_by_datum[using] -= channel + if(!length(using_channels_by_datum[using])) + using_channels_by_datum -= using + free_channel(channel) + +/// Frees all the channels a datum is using. +/datum/controller/subsystem/sounds/proc/free_datum_channels(datum/D) + var/list/L = using_channels_by_datum[D] + if(!L) + return + for(var/channel in L) + using_channels -= num2text(channel) + free_channel(channel) + using_channels_by_datum -= D + +/// Frees all datumless channels +/datum/controller/subsystem/sounds/proc/free_datumless_channels() + free_datum_channels(DATUMLESS) + +/// NO AUTOMATIC CLEANUP - If you use this, you better manually free it later! Returns an integer for channel. +/datum/controller/subsystem/sounds/proc/reserve_sound_channel_datumless() + . = reserve_channel() + if(!.) //oh no.. + return FALSE + var/text_channel = num2text(.) + using_channels[text_channel] = DATUMLESS + LAZYINITLIST(using_channels_by_datum[DATUMLESS]) + using_channels_by_datum[DATUMLESS] += . + +/// Reserves a channel for a datum. Automatic cleanup only when the datum is deleted. Returns an integer for channel. +/datum/controller/subsystem/sounds/proc/reserve_sound_channel(datum/D) + if(!D) //i don't like typechecks but someone will fuck it up + CRASH("Attempted to reserve sound channel without datum using the managed proc.") + .= reserve_channel() + if(!.) + return FALSE + var/text_channel = num2text(.) + using_channels[text_channel] = D + LAZYINITLIST(using_channels_by_datum[D]) + using_channels_by_datum[D] += . + +/** + * Reserves a channel and updates the datastructure. Private proc. + */ +/datum/controller/subsystem/sounds/proc/reserve_channel() + PRIVATE_PROC(TRUE) + if(channel_reserve_high <= random_channels_min) // out of channels + return + var/channel = channel_list[channel_reserve_high] + reserved_channels[num2text(channel)] = channel_reserve_high-- + return channel + +/** + * Frees a channel and updates the datastructure. Private proc. + */ +/datum/controller/subsystem/sounds/proc/free_channel(number) + PRIVATE_PROC(TRUE) + var/text_channel = num2text(number) + var/index = reserved_channels[text_channel] + if(!index) + CRASH("Attempted to (internally) free a channel that wasn't reserved.") + reserved_channels -= text_channel + // push reserve index up, which makes it now on a channel that is reserved + channel_reserve_high++ + // swap the reserved channel wtih the unreserved channel so the reserve index is now on an unoccupied channel and the freed channel is next to be used. + channel_list.Swap(channel_reserve_high, index) + // now, an existing reserved channel will likely (exception: unreserving last reserved channel) be at index + // get it, and update position. + var/text_reserved = num2text(channel_list[index]) + if(!reserved_channels[text_reserved]) //if it isn't already reserved make sure we don't accidently mistakenly put it on reserved list! + return + reserved_channels[text_reserved] = index + +/// Random available channel, returns text. +/datum/controller/subsystem/sounds/proc/random_available_channel_text() + if(channel_random_low > channel_reserve_high) + channel_random_low = 1 + . = "[channel_list[channel_random_low++]]" + +/// Random available channel, returns number +/datum/controller/subsystem/sounds/proc/random_available_channel() + if(channel_random_low > channel_reserve_high) + channel_random_low = 1 + . = channel_list[channel_random_low++] + +/// How many channels we have left. +/datum/controller/subsystem/sounds/proc/available_channels_left() + return length(channel_list) - random_channels_min + +#undef DATUMLESS diff --git a/code/datums/looping_sounds/_looping_sound.dm b/code/datums/looping_sounds/_looping_sound.dm index b16f9ddc35..be6ccd4fa5 100644 --- a/code/datums/looping_sounds/_looping_sound.dm +++ b/code/datums/looping_sounds/_looping_sound.dm @@ -80,7 +80,7 @@ var/list/atoms_cache = output_atoms var/sound/S = sound(soundfile) if(direct) - S.channel = open_sound_channel() + S.channel = SSsounds.random_available_channel() S.volume = volume for(var/i in 1 to atoms_cache.len) var/atom/thing = atoms_cache[i] diff --git a/code/datums/supplypacks/musical.dm b/code/datums/supplypacks/musical.dm new file mode 100644 index 0000000000..61401863bf --- /dev/null +++ b/code/datums/supplypacks/musical.dm @@ -0,0 +1,39 @@ +/datum/supply_pack/musical/strings + contains = list( + /obj/item/instrument/violin, + /obj/item/instrument/banjo, + /obj/item/instrument/guitar, + /obj/item/instrument/eguitar, + ) + name = "string instruments" + cost = 50 + containertype = /obj/structure/closet/crate + containername = "string instrument crate" + +/datum/supply_pack/musical/wind + contains = list( + /obj/item/instrument/accordion, + /obj/item/instrument/trumpet, + /obj/item/instrument/saxophone, + /obj/item/instrument/trombone, + /obj/item/instrument/recorder, + /obj/item/instrument/harmonica, + /obj/item/instrument/bikehorn, + ) + name = "wind instruments" + cost = 50 + containertype = /obj/structure/closet/crate + containername = "wind instrument crate" + +/datum/supply_pack/musical/keys + contains = list( + /obj/item/instrument/piano_synth, + /obj/item/instrument/glockenspiel, // cough + /obj/item/instrument/musicalmoth + ) + name = "keyed instruments" + cost = 50 + containertype = /obj/structure/closet/crate + containername = "keyed instruments crate" + +// /obj/item/instrument/piano_synth/headphones \ No newline at end of file diff --git a/code/datums/supplypacks/recreation_yw.dm b/code/datums/supplypacks/recreation_yw.dm index 5a3a86462e..7e2ba0ebb0 100644 --- a/code/datums/supplypacks/recreation_yw.dm +++ b/code/datums/supplypacks/recreation_yw.dm @@ -1,15 +1,15 @@ /datum/supply_pack/recreation/bigband name = "Instrument bundle" contains = list( - /obj/item/device/instrument/guitar = 1, - /obj/item/device/instrument/keytar = 1, - /obj/item/device/instrument/eguitar = 1, - /obj/item/device/instrument/xylophone = 1, - /obj/item/device/instrument/accordion = 1, - /obj/item/device/instrument/saxophone = 1, - /obj/item/device/instrument/glockenspiel = 1, - /obj/item/device/instrument/harmonica = 1, - /obj/item/device/instrument/trombone = 1, + /obj/item/instrument/guitar = 1, + /obj/item/instrument/keytar = 1, + /obj/item/instrument/eguitar = 1, + /obj/item/instrument/xylophone = 1, + /obj/item/instrument/accordion = 1, + /obj/item/instrument/saxophone = 1, + /obj/item/instrument/glockenspiel = 1, + /obj/item/instrument/harmonica = 1, + /obj/item/instrument/trombone = 1, ) cost = 100 containertype = /obj/structure/closet/crate diff --git a/code/game/area/Space Station 13 areas.dm b/code/game/area/Space Station 13 areas.dm index f6abc7ac06..93becacd94 100755 --- a/code/game/area/Space Station 13 areas.dm +++ b/code/game/area/Space Station 13 areas.dm @@ -339,7 +339,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station icon_state = "thunder" requires_power = 0 dynamic_lighting = 0 - sound_env = ARENA + sound_env = SOUND_ENVIRONMENT_ARENA flags = AREA_FLAG_IS_NOT_PERSISTENT /area/tdome/tdome1 @@ -1289,28 +1289,28 @@ NOTE: there are two lists of areas in the end of this file: centcom and station /area/holodeck/source_emptycourt name = "\improper Holodeck - Empty Court" - sound_env = ARENA + sound_env = SOUND_ENVIRONMENT_ARENA /area/holodeck/source_boxingcourt name = "\improper Holodeck - Boxing Court" - sound_env = ARENA + sound_env = SOUND_ENVIRONMENT_ARENA /area/holodeck/source_basketball name = "\improper Holodeck - Basketball Court" - sound_env = ARENA + sound_env = SOUND_ENVIRONMENT_ARENA /area/holodeck/source_thunderdomecourt name = "\improper Holodeck - Thunderdome Court" requires_power = 0 - sound_env = ARENA + sound_env = SOUND_ENVIRONMENT_ARENA /area/holodeck/source_courtroom name = "\improper Holodeck - Courtroom" - sound_env = AUDITORIUM + sound_env = SOUND_ENVIRONMENT_AUDITORIUM /area/holodeck/source_beach name = "\improper Holodeck - Beach" - sound_env = PLAIN + sound_env = SOUND_ENVIRONMENT_PLAIN /area/holodeck/source_burntest name = "\improper Holodeck - Atmospheric Burn Test" @@ -1320,23 +1320,23 @@ NOTE: there are two lists of areas in the end of this file: centcom and station /area/holodeck/source_meetinghall name = "\improper Holodeck - Meeting Hall" - sound_env = AUDITORIUM + sound_env = SOUND_ENVIRONMENT_AUDITORIUM /area/holodeck/source_theatre name = "\improper Holodeck - Theatre" - sound_env = CONCERT_HALL + sound_env = SOUND_ENVIRONMENT_CONCERT_HALL /area/holodeck/source_picnicarea name = "\improper Holodeck - Picnic Area" - sound_env = PLAIN + sound_env = SOUND_ENVIRONMENT_PLAIN /area/holodeck/source_snowfield name = "\improper Holodeck - Snow Field" - sound_env = FOREST + sound_env = SOUND_ENVIRONMENT_FOREST /area/holodeck/source_desert name = "\improper Holodeck - Desert" - sound_env = PLAIN + sound_env = SOUND_ENVIRONMENT_PLAIN /area/holodeck/source_space name = "\improper Holodeck - Space" diff --git a/code/game/atoms.dm b/code/game/atoms.dm index fc27bb9f4e..daf2596ced 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -669,3 +669,6 @@ /atom/proc/get_visible_gender() return gender + +/atom/proc/interact(mob/user) + return diff --git a/code/game/machinery/computer/computer.dm b/code/game/machinery/computer/computer.dm index cae1788af1..9b230cc3d2 100644 --- a/code/game/machinery/computer/computer.dm +++ b/code/game/machinery/computer/computer.dm @@ -16,9 +16,6 @@ clicksound = "keyboard" -/obj/machinery/computer/New() - ..() - /obj/machinery/computer/Initialize() . = ..() power_change() diff --git a/code/game/machinery/vending_machines_vr.dm b/code/game/machinery/vending_machines_vr.dm index ba18891036..3a726018e8 100644 --- a/code/game/machinery/vending_machines_vr.dm +++ b/code/game/machinery/vending_machines_vr.dm @@ -1054,7 +1054,9 @@ /obj/item/device/radio/headset = 10, /obj/item/device/flashlight = 5, /obj/item/device/laser_pointer = 3, - /obj/item/clothing/glasses/omnihud = 10) + /obj/item/clothing/glasses/omnihud = 10, + /obj/item/instrument/piano_synth/headphones = 2, // You're making a subsystem do work, I don't want it TOO busy + /obj/item/instrument/piano_synth/headphones/spacepods = 2) prices = list(/obj/item/clothing/suit/circuitry = 100, /obj/item/clothing/head/circuitry = 100, /obj/item/clothing/shoes/circuitry = 100, @@ -1074,7 +1076,9 @@ /obj/item/device/radio/headset = 50, /obj/item/device/flashlight = 100, /obj/item/device/laser_pointer = 200, - /obj/item/clothing/glasses/omnihud = 100) + /obj/item/clothing/glasses/omnihud = 100, + /obj/item/instrument/piano_synth/headphones = 200, + /obj/item/instrument/piano_synth/headphones/spacepods = 600) premium = list(/obj/item/device/perfect_tele/one_beacon = 1) contraband = list(/obj/item/weapon/disk/nifsoft/compliance = 1) diff --git a/code/game/objects/effects/confetti_vr.dm b/code/game/objects/effects/confetti_vr.dm index 0430938705..a54733c126 100644 --- a/code/game/objects/effects/confetti_vr.dm +++ b/code/game/objects/effects/confetti_vr.dm @@ -3,8 +3,8 @@ icon = 'icons/effects/effects_vr.dmi' icon_state = "confetti" -/obj/effect/effect/sparks/New() - ..() +/obj/effect/effect/sparks/Initialize() + . = ..() playsound(src, "sounds/items/confetti.ogg ", 100, 1) /datum/effect/effect/system/confetti_spread diff --git a/code/game/objects/effects/effect_system.dm b/code/game/objects/effects/effect_system.dm index 0ec3f40036..7033648dea 100644 --- a/code/game/objects/effects/effect_system.dm +++ b/code/game/objects/effects/effect_system.dm @@ -99,15 +99,12 @@ steam.start() -- spawns the effect anchored = 1.0 mouse_opacity = 0 -/obj/effect/effect/sparks/New() - ..() +/obj/effect/effect/sparks/Initialize() + . = ..() playsound(src, "sparks", 100, 1) var/turf/T = src.loc if (istype(T, /turf)) T.hotspot_expose(1000,100) - -/obj/effect/effect/sparks/Initialize() - . = ..() QDEL_IN(src, 5 SECONDS) /obj/effect/effect/sparks/Destroy() diff --git a/code/game/objects/items/devices/instruments.dm b/code/game/objects/items/devices/instruments.dm deleted file mode 100644 index d273995fae..0000000000 --- a/code/game/objects/items/devices/instruments.dm +++ /dev/null @@ -1,105 +0,0 @@ -//copy pasta of the space violin, don't hurt me -RF - -/obj/item/device/instrument/guitar - name = "guitar" - desc = "It's made of wood and has bronze strings." - icon = 'icons/obj/musician_yw.dmi' - icon_state = "guitar" - item_state = "guitar" - attack_verb = list("smashed") - instrumentId = "guitar" - instrumentExt = "ogg" - -/obj/item/device/instrument/keytar - name = "portable keyboard" - desc = "A keyboard, for those interested in the piano on the go! " - icon = 'icons/obj/musician_yw.dmi' - icon_state = "keyboard" - item_state = "keyboard" - attack_verb = list("smashed") - instrumentId = "piano" - instrumentExt = "ogg" - -/obj/item/device/instrument/eguitar - name = "electrica guitar" - desc = "A metallic musical instrument with strings, made for all your shredding needs." - icon = 'icons/obj/musician_yw.dmi' - icon_state = "eguitar" - item_state = "eguitar" - attack_verb = list("smashed") - instrumentId = "eguitar" - instrumentExt = "ogg" - -/obj/item/device/instrument/xylophone - name = "xylophone" - desc = "A percussion instrument consisting of a series of wooden bars graduated in length." - icon = 'icons/obj/musician_yw.dmi' - icon_state = "xylophone" - attack_verb = list("smashed") - instrumentId = "xylophone" - instrumentExt = "mid" - -/obj/item/device/instrument/accordion - name = "accordion" - desc = "A musical instrument played by blowing and pressing keys. Someone detached Pun-Pun's hands!" - icon = 'icons/obj/musician_yw.dmi' - icon_state = "accordion" - attack_verb = list("smashed") - instrumentId = "accordion" - instrumentExt = "mid" - -/obj/item/device/instrument/saxophone - name = "saxophone" - desc = "A metal wind instruments with a single-reed mouthpiece known for it's soothing tones." - icon = 'icons/obj/musician_yw.dmi' - icon_state = "saxophone" - attack_verb = list("smashed") - instrumentId = "saxophone" - instrumentExt = "mid" - -/obj/item/device/instrument/glockenspiel - name = "glockenspiel" - desc = "A percussion instrument composed of a set of tuned metal bars perfect for any marching band." - icon = 'icons/obj/musician_yw.dmi' - icon_state = "glockenspiel" - attack_verb = list("smashed") - instrumentId = "glockenspiel" - instrumentExt = "mid" - -/obj/item/device/instrument/recorder - name = "recorder" - desc = "A depressing version of a flute. Does anyone even play this?" - icon = 'icons/obj/musician_yw.dmi' - icon_state = "recorder" - attack_verb = list("smashed") - instrumentId = "recorder" - instrumentExt = "mid" - -/obj/item/device/instrument/trombone - name = "trombone" - desc = "A large brass wind instrument. Seems to call for incidental music." - icon = 'icons/obj/musician_yw.dmi' - icon_state = "trombone" - attack_verb = list("smashed") - instrumentId = "trombone" - instrumentExt = "mid" - -/obj/item/device/instrument/harmonica - name = "harmonica" - desc = "A literal mouth organ, it just smells of the frontier!" - icon = 'icons/obj/musician_yw.dmi' - icon_state = "harmonica" - attack_verb = list("smashed") - instrumentId = "harmonica" - instrumentExt = "mid" - w_class = ITEMSIZE_SMALL - -/obj/item/device/instrument/bikehorn - name = "bike horn" - desc = "Why... why would you even play this?!" - icon = 'icons/obj/musician_yw.dmi' - icon_state = "bike_horn" - attack_verb = list("smashed") - instrumentId = "bikehorn" - instrumentExt = "ogg" - diff --git a/code/game/objects/items/devices/violin.dm b/code/game/objects/items/devices/violin.dm deleted file mode 100644 index ce6b929f94..0000000000 --- a/code/game/objects/items/devices/violin.dm +++ /dev/null @@ -1,53 +0,0 @@ -//copy pasta of the space piano, don't hurt me -Pete -/obj/item/device/instrument - name = "generic instrument" - var/datum/song/handheld/song - var/instrumentId = "generic" - var/instrumentExt = "mid" - icon = 'icons/obj/musician.dmi' - force = 10 - item_icons = list( - slot_l_hand_str = 'icons/mob/items/lefthand_instruments.dmi', - slot_r_hand_str = 'icons/mob/items/righthand_instruments.dmi', - ) - -/obj/item/device/instrument/New() - ..() - song = new(instrumentId, src) - song.instrumentExt = instrumentExt - -/obj/item/device/instrument/Destroy() - qdel(song) - song = null - ..() - -/obj/item/device/instrument/attack_self(mob/user as mob) - if(!user.IsAdvancedToolUser()) - to_chat(user, "You don't have the dexterity to do this!") - return 1 - interact(user) - -/obj/item/device/instrument/interact(mob/user as mob) - if(!user) - return - - if(user.incapacitated() || user.lying) - return - - user.set_machine(src) - song.interact(user) - -/obj/item/device/instrument/violin - name = "violin" - desc = "A wooden musical instrument with four strings and a bow. A true classic." - icon_state = "violin" - attack_verb = list("smashed") - instrumentId = "violin" - item_state = "violin" - -/obj/item/device/instrument/violin/gold - name = "golden violin" - desc = "A wooden musical instrument with four strings and a bow. \"The devil went down to space, he was looking for an assistant to grief.\"" - icon = 'icons/obj/musician_yw.dmi' - icon_state = "golden_violin" - attack_verb = list("smashed") diff --git a/code/game/objects/items/weapons/gift_wrappaper.dm b/code/game/objects/items/weapons/gift_wrappaper.dm index cd48a4a78a..e4d96a0c79 100644 --- a/code/game/objects/items/weapons/gift_wrappaper.dm +++ b/code/game/objects/items/weapons/gift_wrappaper.dm @@ -104,7 +104,7 @@ /obj/item/weapon/reagent_containers/food/snacks/grown/ambrosiadeus, /obj/item/weapon/reagent_containers/food/snacks/grown/ambrosiavulgaris, /obj/item/device/paicard, - /obj/item/device/instrument/violin, + /obj/item/instrument/violin, /obj/item/weapon/storage/belt/utility/full, /obj/item/clothing/accessory/tie/horrible) diff --git a/code/game/objects/objs.dm b/code/game/objects/objs.dm index 046958a915..2432e79008 100644 --- a/code/game/objects/objs.dm +++ b/code/game/objects/objs.dm @@ -120,9 +120,6 @@ tgui_interact(user) ..() -/obj/proc/interact(mob/user) - return - /mob/proc/unset_machine() machine?.remove_visual(src) src.machine = null diff --git a/code/game/objects/structures/crates_lockers/largecrate_yw.dm b/code/game/objects/structures/crates_lockers/largecrate_yw.dm index b680e5fde3..3a2336a01a 100644 --- a/code/game/objects/structures/crates_lockers/largecrate_yw.dm +++ b/code/game/objects/structures/crates_lockers/largecrate_yw.dm @@ -1,9 +1,8 @@ /obj/structure/largecrate/piano name = "piano crate" - starts_with = list(/obj/structure/device/piano) + starts_with = list(/obj/structure/musician/piano) desc = "*Grand piano may end up being a minimoog." /obj/structure/largecrate/piano/Initialize() //This is nessesary to get a random one each time. - starts_with = list(pick(/obj/structure/device/piano/minimoog, - /obj/structure/device/piano)) - return ..() \ No newline at end of file + starts_with = list(/obj/structure/musician/piano) + return ..() diff --git a/code/game/objects/structures/musician.dm b/code/game/objects/structures/musician.dm deleted file mode 100644 index 40e7b5e01c..0000000000 --- a/code/game/objects/structures/musician.dm +++ /dev/null @@ -1,377 +0,0 @@ -//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:32 - -#define MUSICIAN_HEARCHECK_MINDELAY 4 -#define INSTRUMENT_MAX_LINE_LENGTH 300 -#define INSTRUMENT_MAX_LINE_NUMBER 400 - -/datum/song - var/name = "Untitled" - var/list/lines = new() - var/tempo = 5 // delay between notes - - var/playing = 0 // if we're playing - var/help = 0 // if help is open - var/edit = 1 // if we're in editing mode - var/repeat = 0 // number of times remaining to repeat - var/max_repeats = 10 // maximum times we can repeat - - var/instrumentDir = "piano" // the folder with the sounds - var/instrumentExt = "ogg" // the file extension - var/obj/instrumentObj = null // the associated obj playing the sound - var/last_hearcheck = 0 - var/list/hearing_mobs - -/datum/song/New(dir, obj, ext = "ogg") - instrumentDir = dir - instrumentObj = obj - instrumentExt = ext - -/datum/song/Destroy() - instrumentObj = null - return ..() - -/obj/structure/device/piano - name = "space minimoog" - icon = 'icons/obj/musician.dmi' - icon_state = "minimoog" - anchored = 1 - density = 1 - var/datum/song/song - var/playing = 0 - var/help = 0 - var/edit = 1 - var/repeat = 0 - var/linelimit = INSTRUMENT_MAX_LINE_NUMBER - -// note is a number from 1-7 for A-G -// acc is either "b", "n", or "#" -// oct is 1-8 (or 9 for C) -/datum/song/proc/playnote(note, acc as text, oct) - // handle accidental -> B<>C of E<>F - if(acc == "b" && (note == 3 || note == 6)) // C or F - if(note == 3) - oct-- - note-- - acc = "n" - else if(acc == "#" && (note == 2 || note == 5)) // B or E - if(note == 2) - oct++ - note++ - acc = "n" - else if(acc == "#" && (note == 7)) //G# - note = 1 - acc = "b" - else if(acc == "#") // mass convert all sharps to flats, octave jump already handled - acc = "b" - note++ - - // check octave, C is allowed to go to 9 - if(oct < 1 || (note == 3 ? oct > 9 : oct > 8)) - return - - // now generate name - var/soundfile = "sound/instruments/[instrumentDir]/[ascii2text(note+64)][acc][oct].[instrumentExt]" - soundfile = file(soundfile) - // make sure the note exists - if(!fexists(soundfile)) - return - // and play - var/turf/source = get_turf(instrumentObj) - if((world.time - MUSICIAN_HEARCHECK_MINDELAY) > last_hearcheck) - LAZYCLEARLIST(hearing_mobs) - for(var/mob/M in hearers(15, source)) - if(!M.client || !(M.is_preference_enabled(/datum/client_preference/instrument_toggle))) - continue - LAZYSET(hearing_mobs, M, TRUE) - last_hearcheck = world.time - var/sound/music_played = sound(soundfile) - for(var/i in hearing_mobs) - var/mob/M = i - M.playsound_local(source, null, 100, falloff = 0.5, S = music_played) - -/datum/song/proc/updateDialog(mob/user) - instrumentObj.updateDialog() // assumes it's an object in world, override if otherwise - -/datum/song/proc/shouldStopPlaying(mob/user) - if(instrumentObj) - if(!instrumentObj.Adjacent(user) || user.stat) - return 1 - return !instrumentObj.anchored // add special cases to stop in subclasses - else - return 1 - -/datum/song/proc/playsong(mob/user) - while(repeat >= 0) - var/cur_oct[7] - var/cur_acc[7] - for(var/i = 1 to 7) - cur_oct[i] = 3 - cur_acc[i] = "n" - - for(var/line in lines) - for(var/beat in splittext(lowertext(line), ",")) - var/list/notes = splittext(beat, "/") - for(var/note in splittext(notes[1], "-")) - if(!playing || shouldStopPlaying(user))//If the instrument is playing, or special case - playing = 0 - return - if(length(note) == 0) - continue - var/cur_note = text2ascii(note) - 96 - if(cur_note < 1 || cur_note > 7) - continue - for(var/i=2 to length(note)) - var/ni = copytext(note,i,i+1) - if(!text2num(ni)) - if(ni == "#" || ni == "b" || ni == "n") - cur_acc[cur_note] = ni - else if(ni == "s") - cur_acc[cur_note] = "#" // so shift is never required - else - cur_oct[cur_note] = text2num(ni) - playnote(cur_note, cur_acc[cur_note], cur_oct[cur_note]) - if(notes.len >= 2 && text2num(notes[2])) - sleep(sanitize_tempo(tempo / text2num(notes[2]))) - else - sleep(tempo) - repeat-- - playing = 0 - repeat = 0 - updateDialog(user) - -/datum/song/proc/interact(mob/user) - var/dat = "" - if(lines.len > 0) - dat += "

Playback

" - if(!playing) - dat += {"Play Stop

- Repeat Song: - [repeat > 0 ? "--" : "--"] - [repeat] times - [repeat < max_repeats ? "++" : "++"] -
"} - else - dat += {"Play Stop
- Repeats left: [repeat]
"} - if(!edit) - dat += "
Show Editor
" - else - var/bpm = round(600 / tempo) - dat += {"

Editing

- Hide Editor - Start a New Song - Import a Song

- Tempo: - [bpm] BPM +

"} - var/linecount = 0 - for(var/line in lines) - linecount += 1 - dat += "Line [linecount]: Edit X [line]
" - dat += "Add Line

" - if(help) - dat += {"Hide Help
- Lines are a series of chords, separated by commas (,), each with notes seperated by hyphens (-).
- Every note in a chord will play together, with chord timed by the tempo.
-
- Notes are played by the names of the note, and optionally, the accidental, and/or the octave number.
- By default, every note is natural and in octave 3. Defining otherwise is remembered for each note.
- Example: C,D,E,F,G,A,B will play a C major scale.
- After a note has an accidental placed, it will be remembered: C,C4,C,C3 is C3,C4,C4,C3
- Chords can be played simply by seperating each note with a hyphon: A-C#,Cn-E,E-G#,Gn-B
- A pause may be denoted by an empty chord: C,E,,C,G
- To make a chord be a different time, end it with /x, where the chord length will be length
- defined by tempo / x: C,G/2,E/4
- Combined, an example is: E-E4/4,F#/2,G#/8,B/8,E3-E4/4 -
- Lines may be up to 50 characters.
- A song may only contain up to 50 lines.
- "} - else - dat += "Show Help
" - var/datum/browser/popup = new(user, "instrument", instrumentObj.name, 700, 500) - popup.set_content(dat) - popup.set_title_image(user.browse_rsc_icon(instrumentObj.icon, instrumentObj.icon_state)) - popup.open() - -/datum/song/Topic(href, href_list) - if(!instrumentObj.Adjacent(usr) || usr.stat) - usr << browse(null, "window=instrument") - usr.unset_machine() - return - instrumentObj.add_fingerprint(usr) - if(href_list["newsong"]) - lines = new() - tempo = sanitize_tempo(5) // default 120 BPM - name = "" - else if(href_list["import"]) - var/t = "" - do - t = html_encode(input(usr, "Please paste the entire song, formatted:", text("[]", name), t) as message) - if(!in_range(instrumentObj, usr)) - return - if(length(t) >= INSTRUMENT_MAX_LINE_LENGTH*INSTRUMENT_MAX_LINE_NUMBER) - var/cont = input(usr, "Your message is too long! Would you like to continue editing it?", "", "yes") in list("yes", "no") - if(cont == "no") - break - while(length(t) > INSTRUMENT_MAX_LINE_LENGTH*INSTRUMENT_MAX_LINE_NUMBER) - //split into lines - spawn() - lines = splittext(t, "\n") - if(copytext(lines[1],1,6) == "BPM: ") - tempo = sanitize_tempo(600 / text2num(copytext(lines[1],6))) - lines.Cut(1,2) - else - tempo = sanitize_tempo(5) // default 120 BPM - if(lines.len > INSTRUMENT_MAX_LINE_NUMBER) - to_chat(usr, "Too many lines!") - lines.Cut(INSTRUMENT_MAX_LINE_NUMBER+1) - var/linenum = 1 - for(var/l in lines) - if(length(l) > INSTRUMENT_MAX_LINE_LENGTH) - to_chat(usr, "Line [linenum] too long!") - lines.Remove(l) - else - linenum++ - updateDialog(usr) // make sure updates when complete - else if(href_list["help"]) - help = text2num(href_list["help"]) - 1 - else if(href_list["edit"]) - edit = text2num(href_list["edit"]) - 1 - if(href_list["repeat"]) //Changing this from a toggle to a number of repeats to avoid infinite loops. - if(playing) - return //So that people cant keep adding to repeat. If the do it intentionally, it could result in the server crashing. - repeat += round(text2num(href_list["repeat"])) - if(repeat < 0) - repeat = 0 - if(repeat > max_repeats) - repeat = max_repeats - else if(href_list["tempo"]) - tempo = sanitize_tempo(tempo + text2num(href_list["tempo"])) - else if(href_list["play"]) - playing = 1 - spawn() - playsong(usr) - else if(href_list["newline"]) - var/newline = html_encode(input("Enter your line: ", instrumentObj.name) as text|null) - if(!newline || !in_range(instrumentObj, usr)) - return - if(lines.len > INSTRUMENT_MAX_LINE_NUMBER) - return - if(length(newline) > INSTRUMENT_MAX_LINE_LENGTH) - newline = copytext(newline, 1, INSTRUMENT_MAX_LINE_LENGTH) - lines.Add(newline) - else if(href_list["deleteline"]) - var/num = round(text2num(href_list["deleteline"])) - if(num > lines.len || num < 1) - return - lines.Cut(num, num+1) - else if(href_list["modifyline"]) - var/num = round(text2num(href_list["modifyline"]),1) - var/content = html_encode(input("Enter your line: ", instrumentObj.name, lines[num]) as text|null) - if(!content || !in_range(instrumentObj, usr)) - return - if(length(content) > INSTRUMENT_MAX_LINE_LENGTH) - content = copytext(content, 1, INSTRUMENT_MAX_LINE_LENGTH) - if(num > lines.len || num < 1) - return - lines[num] = content - else if(href_list["stop"]) - playing = 0 - updateDialog(usr) - return - -/datum/song/proc/sanitize_tempo(new_tempo) - new_tempo = abs(new_tempo) - return max(round(new_tempo, world.tick_lag), world.tick_lag) - -// subclass for handheld instruments, like violin -/datum/song/handheld - -/datum/song/handheld/updateDialog(mob/user) - instrumentObj.interact(user) - -/datum/song/handheld/shouldStopPlaying() - if(instrumentObj) - return !isliving(instrumentObj.loc) - else - return 1 - -////////////////////////////////////////////////////////////////////////// -/obj/structure/device/piano - name = "space piano" - desc = "This is a space piano; just like a regular piano, but always in tune! Even if the musician isn't." - icon = 'icons/obj/musician.dmi' - icon_state = "piano" - anchored = 1 - density = 1 - -/obj/structure/device/piano/minimoog - name = "space minimoog" - icon_state = "minimoog" - desc = "This is a minimoog; just like a space piano, but more spacey!" - -/obj/structure/device/piano/New() - ..() - song = new("piano", src) - - if(prob(50)) - name = "space minimoog" - desc = "This is a minimoog, like a space piano, but more spacey!" - icon_state = "minimoog" - else - name = "space piano" - desc = "This is a space piano, like a regular piano, but always in tune! Even if the musician isn't." - icon_state = "piano" - -/obj/structure/device/piano/Destroy() - qdel(song) - song = null - ..() - -/obj/structure/device/piano/verb/rotate_clockwise() - set name = "Rotate Piano Clockwise" - set category = "Object" - set src in oview(1) - - if(ismouse(usr)) - return - if(!usr || !isturf(usr.loc) || usr.stat || usr.restrained()) - return - if (isobserver(usr) && !config.ghost_interaction) - return - src.set_dir(turn(src.dir, 270)) - -/obj/structure/device/piano/attack_hand(mob/user) - if(!user.IsAdvancedToolUser()) - to_chat(user, "You don't have the dexterity to do this!") - return 1 - interact(user) - -/obj/structure/device/piano/interact(mob/user) - if(!user || !anchored) - return - - user.set_machine(src) - song.interact(user) - -/obj/structure/device/piano/attackby(obj/item/O as obj, mob/user as mob) - if(O.is_wrench()) - if(anchored) - playsound(src, O.usesound, 50, 1) - to_chat(user, "You begin to loosen \the [src]'s casters...") - if (do_after(user, 40 * O.toolspeed)) - user.visible_message( \ - "[user] loosens \the [src]'s casters.", \ - "You have loosened \the [src]. Now it can be pulled somewhere else.", \ - "You hear ratchet.") - src.anchored = 0 - else - playsound(src, O.usesound, 50, 1) - to_chat(user, "You begin to tighten \the [src] to the floor...") - if (do_after(user, 20 * O.toolspeed)) - user.visible_message( \ - "[user] tightens \the [src]'s casters.", \ - "You have tightened \the [src]'s casters. Now it can be played again.", \ - "You hear ratchet.") - src.anchored = 1 - else - ..() diff --git a/code/game/sound.dm b/code/game/sound.dm index 5b1214c675..61fc50368c 100644 --- a/code/game/sound.dm +++ b/code/game/sound.dm @@ -9,7 +9,7 @@ var/area/area_source = turf_source.loc //allocate a channel if necessary now so its the same for everyone - channel = channel || open_sound_channel() + channel = channel || SSsounds.random_available_channel() // Looping through the player list has the added bonus of working for mobs inside containers var/sound/S = sound(get_sfx(soundin)) @@ -43,7 +43,7 @@ S = sound(get_sfx(soundin)) S.wait = 0 //No queue - S.channel = channel || open_sound_channel() + S.channel = channel || SSsounds.random_available_channel() // I'm not sure if you can modify S.volume, but I'd rather not try to find out what // horrible things lurk in BYOND's internals, so we're just gonna do vol *= @@ -109,15 +109,14 @@ var/mob/MO = M MO.playsound_local(get_turf(MO), sound, volume, vary, pressure_affected = FALSE) -/proc/open_sound_channel() - var/static/next_channel = 1 //loop through the available 1024 - (the ones we reserve) channels and pray that its not still being used - . = ++next_channel - if(next_channel > CHANNEL_HIGHEST_AVAILABLE) - next_channel = 1 - /mob/proc/stop_sound_channel(chan) src << sound(null, repeat = 0, wait = 0, channel = chan) +/mob/proc/set_sound_channel_volume(channel, volume) + var/sound/S = sound(null, FALSE, FALSE, channel, volume) + S.status = SOUND_UPDATE + src << S + /proc/get_rand_frequency() return rand(32000, 55000) //Frequency stuff only works with 45kbps oggs. diff --git a/code/modules/instruments/instrument_data/_instrument_data.dm b/code/modules/instruments/instrument_data/_instrument_data.dm new file mode 100644 index 0000000000..39d16e499f --- /dev/null +++ b/code/modules/instruments/instrument_data/_instrument_data.dm @@ -0,0 +1,113 @@ +/** + * Get all non admin_only instruments as a list of text ids. + */ +/proc/get_allowed_instrument_ids() + . = list() + for(var/id in SSinstruments.instrument_data) + var/datum/instrument/I = SSinstruments.instrument_data[id] + if(!I.admin_only) + . += I.id + +/** + * # Instrument Datums + * + * Instrument datums hold the data for any given instrument, as well as data on how to play it and what bounds there are to playing it. + * + * The datums themselves are kept in SSinstruments in a list by their unique ID. The reason it uses ID instead of typepath is to support the runtime creation of instruments. + * Since songs cache them while playing, there isn't realistic issues regarding performance from accessing. + */ +/datum/instrument + /// Name of the instrument + var/name = "Generic instrument" + /// Uniquely identifies this instrument so runtime changes are possible as opposed to paths. If this is unset, things will use path instead. + var/id + /// Category + var/category = "Unsorted" + /// Used for categorization subtypes + var/abstract_type = /datum/instrument + /// Write here however many samples, follow this syntax: "%note num%"='%sample file%' eg. "27"='synthesizer/e2.ogg'. Key must never be lower than 0 and higher than 127 + var/list/real_samples + /// assoc list key = /datum/instrument_key. do not fill this yourself! + var/list/samples + /// See __DEFINES/flags/instruments.dm + var/instrument_flags = NONE + /// For legacy instruments, the path to our notes + var/legacy_instrument_path + /// For legacy instruments, our file extension + var/legacy_instrument_ext + /// What songs are using us + var/list/datum/song/songs_using = list() + /// Don't touch this + var/static/HIGHEST_KEY = 127 + /// Don't touch this x2 + var/static/LOWEST_KEY = 0 + /// Oh no - For truly troll instruments. + var/admin_only = FALSE + /// Volume multiplier. Synthesized instruments are quite loud and I don't like to cut off potential detail via editing. (someone correct me if this isn't a thing) + var/volume_multiplier = 0.33 + +/datum/instrument/New() + if(isnull(id)) + id = "[type]" + +/** + * Initializes the instrument, calculating its samples if necessary. + */ +/datum/instrument/proc/Initialize() + if(instrument_flags & (INSTRUMENT_LEGACY | INSTRUMENT_DO_NOT_AUTOSAMPLE)) + return + calculate_samples() + +/** + * Checks if this instrument is ready to play. + */ +/datum/instrument/proc/ready() + if(instrument_flags & INSTRUMENT_LEGACY) + return legacy_instrument_path && legacy_instrument_ext + else if(instrument_flags & INSTRUMENT_DO_NOT_AUTOSAMPLE) + return length(samples) + return (length(samples) >= 128) + +/datum/instrument/Destroy() + SSinstruments.instrument_data -= id + for(var/i in songs_using) + var/datum/song/S = i + S.set_instrument(null) + real_samples = null + samples = null + songs_using = null + return ..() + +/** + * For synthesized instruments, this is how the instrument generates the "keys" that a [/datum/song] uses to play notes. + * Calculating them on the fly would be unperformant, so we do it during init and keep it all cached in a list. + */ +/datum/instrument/proc/calculate_samples() + if(!length(real_samples)) + CRASH("No real samples defined for [id] [type] on calculate_samples() call.") + var/list/real_keys = list() + samples = list() + for(var/key in real_samples) + real_keys += text2num(key) + sortTim(real_keys, /proc/cmp_numeric_asc, associative = FALSE) + + for(var/i in 1 to (length(real_keys) - 1)) + var/from_key = real_keys[i] + var/to_key = real_keys[i+1] + var/sample1 = real_samples[num2text(from_key)] + var/sample2 = real_samples[num2text(to_key)] + var/pivot = FLOOR((from_key + to_key) / 2, 1) //original code was a round but I replaced it because that's effectively a floor, thanks Baystation! who knows what was intended. + for(var/key in from_key to pivot) + samples[num2text(key)] = new /datum/instrument_key(sample1, key, key - from_key) + for(var/key in (pivot + 1) to to_key) + samples[num2text(key)] = new /datum/instrument_key(sample2, key, key - to_key) + + // Fill in 0 to first key and last key to 127 + var/first_key = real_keys[1] + var/last_key = real_keys[length(real_keys)] + var/first_sample = real_samples[num2text(first_key)] + var/last_sample = real_samples[num2text(last_key)] + for(var/key in LOWEST_KEY to (first_key - 1)) + samples[num2text(key)] = new /datum/instrument_key(first_sample, key, key - first_key) + for(var/key in last_key to HIGHEST_KEY) + samples[num2text(key)] = new /datum/instrument_key(last_sample, key, key - last_key) diff --git a/code/modules/instruments/instrument_data/_instrument_key.dm b/code/modules/instruments/instrument_data/_instrument_key.dm new file mode 100644 index 0000000000..6038b7b76b --- /dev/null +++ b/code/modules/instruments/instrument_data/_instrument_key.dm @@ -0,0 +1,31 @@ +/** + * Instrument key datums contain everything needed to know how to play a specific + * note of an instrument.* + */ +/datum/instrument_key + /// The numerical key of what this is, from 1 to 127 on a standard piano keyboard. + var/key + /// The actual sample file that will be loaded when playing. + var/sample + /// The frequency to play the sample to get our desired note. + var/frequency + /// Deviation up/down from the pivot point that uses its sample. Used to calculate frequency. + var/deviation + +/datum/instrument_key/New(sample = src.sample, key = src.key, deviation = src.deviation, frequency = src.frequency) + src.sample = sample + src.key = key + src.deviation = deviation + src.frequency = frequency + if(!frequency && deviation) + calculate() + +/** + * Calculates and stores our deviation. + */ +/datum/instrument_key/proc/calculate() + if(!deviation) + CRASH("Invalid calculate call: No deviation or sample in instrument_key") + #define KEY_TWELTH (1/12) + frequency = 2 ** (KEY_TWELTH * deviation) + #undef KEY_TWELTH diff --git a/code/modules/instruments/instrument_data/brass.dm b/code/modules/instruments/instrument_data/brass.dm new file mode 100644 index 0000000000..7f8f103831 --- /dev/null +++ b/code/modules/instruments/instrument_data/brass.dm @@ -0,0 +1,26 @@ +/datum/instrument/brass + name = "Generic brass instrument" + category = "Brass" + abstract_type = /datum/instrument/brass + +/datum/instrument/brass/crisis_section + name = "Crisis Brass Section" + id = "crbrass" + real_samples = list("36"='sound/instruments/synthesis_samples/brass/crisis_brass/c2.ogg', + "48"='sound/instruments/synthesis_samples/brass/crisis_brass/c3.ogg', + "60"='sound/instruments/synthesis_samples/brass/crisis_brass/c4.ogg', + "72"='sound/instruments/synthesis_samples/brass/crisis_brass/c5.ogg') + +/datum/instrument/brass/crisis_trombone + name = "Crisis Trombone" + id = "crtrombone" + real_samples = list("36"='sound/instruments/synthesis_samples/brass/crisis_trombone/c2.ogg', + "48"='sound/instruments/synthesis_samples/brass/crisis_trombone/c3.ogg', + "60"='sound/instruments/synthesis_samples/brass/crisis_trombone/c4.ogg', + "72"='sound/instruments/synthesis_samples/brass/crisis_trombone/c5.ogg') + +/datum/instrument/brass/crisis_trumpet + name = "Crisis Trumpet" + id = "crtrumpet" + real_samples = list("60"='sound/instruments/synthesis_samples/brass/crisis_trumpet/c4.ogg', + "72"='sound/instruments/synthesis_samples/brass/crisis_trumpet/c5.ogg') diff --git a/code/modules/instruments/instrument_data/chromatic_percussion.dm b/code/modules/instruments/instrument_data/chromatic_percussion.dm new file mode 100644 index 0000000000..cafa9e31ed --- /dev/null +++ b/code/modules/instruments/instrument_data/chromatic_percussion.dm @@ -0,0 +1,31 @@ +/datum/instrument/chromatic + name = "Generic chromatic percussion instrument" + category = "Chromatic percussion" + abstract_type = /datum/instrument/chromatic + +/datum/instrument/chromatic/vibraphone1 + name = "Crisis Vibraphone" + id = "crvibr" + real_samples = list("36"='sound/instruments/synthesis_samples/chromatic/vibraphone1/c2.ogg', + "48"='sound/instruments/synthesis_samples/chromatic/vibraphone1/c3.ogg', + "60"='sound/instruments/synthesis_samples/chromatic/vibraphone1/c4.ogg', + "72"='sound/instruments/synthesis_samples/chromatic/vibraphone1/c5.ogg') + +/datum/instrument/chromatic/musicbox1 + name = "SGM Music Box" + id = "sgmmbox" + real_samples = list("36"='sound/instruments/synthesis_samples/chromatic/sgmbox/c2.ogg', + "48"='sound/instruments/synthesis_samples/chromatic/sgmbox/c3.ogg', + "60"='sound/instruments/synthesis_samples/chromatic/sgmbox/c4.ogg', + "72"='sound/instruments/synthesis_samples/chromatic/sgmbox/c5.ogg') + +/datum/instrument/chromatic/fluid_celeste + name = "FluidR3 Celeste" + id = "r3celeste" + real_samples = list("36"='sound/instruments/synthesis_samples/chromatic/fluid_celeste/c2.ogg', + "48"='sound/instruments/synthesis_samples/chromatic/fluid_celeste/c3.ogg', + "60"='sound/instruments/synthesis_samples/chromatic/fluid_celeste/c4.ogg', + "72"='sound/instruments/synthesis_samples/chromatic/fluid_celeste/c5.ogg', + "84"='sound/instruments/synthesis_samples/chromatic/fluid_celeste/c6.ogg', + "96"='sound/instruments/synthesis_samples/chromatic/fluid_celeste/c7.ogg', + "108"='sound/instruments/synthesis_samples/chromatic/fluid_celeste/c8.ogg') diff --git a/code/modules/instruments/instrument_data/fun.dm b/code/modules/instruments/instrument_data/fun.dm new file mode 100644 index 0000000000..790abe4647 --- /dev/null +++ b/code/modules/instruments/instrument_data/fun.dm @@ -0,0 +1,25 @@ +/datum/instrument/fun + name = "Generic Fun Instrument" + category = "Fun" + abstract_type = /datum/instrument/fun + +/datum/instrument/fun/honk + name = "!!HONK!!" + id = "honk" + real_samples = list("74"='sound/items/bikehorn.ogg') // Cluwne Heaven + +/datum/instrument/fun/signal + name = "Ping" + id = "ping" + real_samples = list("79"='sound/machines/ping.ogg') + +/datum/instrument/fun/chime + name = "Chime" + id = "chime" + real_samples = list("79"='sound/machines/chime.ogg') + +/datum/instrument/fun/mothscream + name = "Moth Scream" + id = "mothscream" + real_samples = list("60"='sound/voice/moth/scream_moth.ogg') + admin_only = TRUE diff --git a/code/modules/instruments/instrument_data/guitar.dm b/code/modules/instruments/instrument_data/guitar.dm new file mode 100644 index 0000000000..be7cfbe467 --- /dev/null +++ b/code/modules/instruments/instrument_data/guitar.dm @@ -0,0 +1,36 @@ +/datum/instrument/guitar + name = "Generic guitar-like instrument" + category = "Guitar" + abstract_type = /datum/instrument/guitar + +/datum/instrument/guitar/steel_crisis + name = "Crisis Steel String Guitar" + id = "csteelgt" + real_samples = list("36"='sound/instruments/synthesis_samples/guitar/crisis_steel/c2.ogg', + "48"='sound/instruments/synthesis_samples/guitar/crisis_steel/c3.ogg', + "60"='sound/instruments/synthesis_samples/guitar/crisis_steel/c4.ogg', + "72"='sound/instruments/synthesis_samples/guitar/crisis_steel/c5.ogg') + +/datum/instrument/guitar/nylon_crisis + name = "Crisis Nylon String Guitar" + id = "cnylongt" + real_samples = list("36"='sound/instruments/synthesis_samples/guitar/crisis_nylon/c2.ogg', + "48"='sound/instruments/synthesis_samples/guitar/crisis_nylon/c3.ogg', + "60"='sound/instruments/synthesis_samples/guitar/crisis_nylon/c4.ogg', + "72"='sound/instruments/synthesis_samples/guitar/crisis_nylon/c5.ogg') + +/datum/instrument/guitar/clean_crisis + name = "Crisis Clean Guitar" + id = "ccleangt" + real_samples = list("36"='sound/instruments/synthesis_samples/guitar/crisis_clean/c2.ogg', + "48"='sound/instruments/synthesis_samples/guitar/crisis_clean/c3.ogg', + "60"='sound/instruments/synthesis_samples/guitar/crisis_clean/c4.ogg', + "72"='sound/instruments/synthesis_samples/guitar/crisis_clean/c5.ogg') + +/datum/instrument/guitar/muted_crisis + name = "Crisis Muted Guitar" + id = "cmutedgt" + real_samples = list("36"='sound/instruments/synthesis_samples/guitar/crisis_muted/c2.ogg', + "48"='sound/instruments/synthesis_samples/guitar/crisis_muted/c3.ogg', + "60"='sound/instruments/synthesis_samples/guitar/crisis_muted/c4.ogg', + "72"='sound/instruments/synthesis_samples/guitar/crisis_muted/c5.ogg') diff --git a/code/modules/instruments/instrument_data/hardcoded.dm b/code/modules/instruments/instrument_data/hardcoded.dm new file mode 100644 index 0000000000..c770f9569e --- /dev/null +++ b/code/modules/instruments/instrument_data/hardcoded.dm @@ -0,0 +1,86 @@ +//THESE ARE HARDCODED INSTRUMENT SAMPLES. +//SONGS WILL BE AUTOMATICALLY SWITCHED TO LEGACY MODE IF THEY USE THIS KIND OF INSTRUMENT! +//I'd prefer these stayed. They sound different from the mechanical synthesis of synthed instruments, and I quite like them that way. It's not legacy, it's hardcoded, old style. - kevinz000 +/datum/instrument/hardcoded + abstract_type = /datum/instrument/hardcoded + category = "Non-Synthesized" + instrument_flags = INSTRUMENT_LEGACY + volume_multiplier = 1 //not as loud as synth'd + +/datum/instrument/hardcoded/accordion + name = "Accordion" + id = "accordion" + legacy_instrument_ext = "mid" + legacy_instrument_path = "accordion" + +/datum/instrument/hardcoded/bikehorn + name = "Bike Horn" + id = "bikehorn" + legacy_instrument_ext = "ogg" + legacy_instrument_path = "bikehorn" + +/datum/instrument/hardcoded/eguitar + name = "Electric Guitar" + id = "eguitar" + legacy_instrument_ext = "ogg" + legacy_instrument_path = "eguitar" + +/datum/instrument/hardcoded/glockenspiel + name = "Glockenspiel" + id = "glockenspiel" + legacy_instrument_ext = "mid" + legacy_instrument_path = "glockenspiel" + +/datum/instrument/hardcoded/guitar + name = "Guitar" + id = "guitar" + legacy_instrument_ext = "ogg" + legacy_instrument_path = "guitar" + +/datum/instrument/hardcoded/harmonica + name = "Harmonica" + id = "harmonica" + legacy_instrument_ext = "mid" + legacy_instrument_path = "harmonica" + +/datum/instrument/hardcoded/piano + name = "Piano" + id = "piano" + legacy_instrument_ext = "ogg" + legacy_instrument_path = "piano" + +/datum/instrument/hardcoded/recorder + name = "Recorder" + id = "recorder" + legacy_instrument_ext = "mid" + legacy_instrument_path = "recorder" + +/datum/instrument/hardcoded/saxophone + name = "Saxophone" + id = "saxophone" + legacy_instrument_ext = "mid" + legacy_instrument_path = "saxophone" + +/datum/instrument/hardcoded/trombone + name = "Trombone" + id = "trombone" + legacy_instrument_ext = "mid" + legacy_instrument_path = "trombone" + +/datum/instrument/hardcoded/violin + name = "Violin" + id = "violin" + legacy_instrument_ext = "mid" + legacy_instrument_path = "violin" + +/datum/instrument/hardcoded/xylophone + name = "Xylophone" + id = "xylophone" + legacy_instrument_ext = "mid" + legacy_instrument_path = "xylophone" + +/datum/instrument/hardcoded/banjo + name = "Banjo" + id = "banjo" + legacy_instrument_ext = "ogg" + legacy_instrument_path = "banjo" diff --git a/code/modules/instruments/instrument_data/organ.dm b/code/modules/instruments/instrument_data/organ.dm new file mode 100644 index 0000000000..25da740998 --- /dev/null +++ b/code/modules/instruments/instrument_data/organ.dm @@ -0,0 +1,43 @@ +/datum/instrument/organ + name = "Generic organ" + category = "Organ" + abstract_type = /datum/instrument/organ + +/datum/instrument/organ/crisis_church + name = "Crisis Church Organ" + id = "crichugan" + real_samples = list("36"='sound/instruments/synthesis_samples/organ/crisis_church/c2.ogg', + "48"='sound/instruments/synthesis_samples/organ/crisis_church/c3.ogg', + "60"='sound/instruments/synthesis_samples/organ/crisis_church/c4.ogg', + "72"='sound/instruments/synthesis_samples/organ/crisis_church/c5.ogg') + +/datum/instrument/organ/crisis_hammond + name = "Crisis Hammond Organ" + id = "crihamgan" + real_samples = list("36"='sound/instruments/synthesis_samples/organ/crisis_hammond/c2.ogg', + "48"='sound/instruments/synthesis_samples/organ/crisis_hammond/c3.ogg', + "60"='sound/instruments/synthesis_samples/organ/crisis_hammond/c4.ogg', + "72"='sound/instruments/synthesis_samples/organ/crisis_hammond/c5.ogg') + +/datum/instrument/organ/crisis_accordian + name = "Crisis Accordian" + id = "crack" + real_samples = list("36"='sound/instruments/synthesis_samples/organ/crisis_accordian/c2.ogg', + "48"='sound/instruments/synthesis_samples/organ/crisis_accordian/c3.ogg', + "60"='sound/instruments/synthesis_samples/organ/crisis_accordian/c4.ogg', + "72"='sound/instruments/synthesis_samples/organ/crisis_accordian/c5.ogg') + +/datum/instrument/organ/crisis_harmonica + name = "Crisis Harmonica" + id = "crharmony" + real_samples = list("48"='sound/instruments/synthesis_samples/organ/crisis_harmonica/c3.ogg', + "60"='sound/instruments/synthesis_samples/organ/crisis_harmonica/c4.ogg', + "72"='sound/instruments/synthesis_samples/organ/crisis_harmonica/c5.ogg') + +/datum/instrument/organ/crisis_tango_accordian + name = "Crisis Tango Accordian" + id = "crtango" + real_samples = list("36"='sound/instruments/synthesis_samples/organ/crisis_tangaccordian/c2.ogg', + "48"='sound/instruments/synthesis_samples/organ/crisis_tangaccordian/c3.ogg', + "60"='sound/instruments/synthesis_samples/organ/crisis_tangaccordian/c4.ogg', + "72"='sound/instruments/synthesis_samples/organ/crisis_tangaccordian/c5.ogg') diff --git a/code/modules/instruments/instrument_data/piano.dm b/code/modules/instruments/instrument_data/piano.dm new file mode 100644 index 0000000000..fdd2f6e938 --- /dev/null +++ b/code/modules/instruments/instrument_data/piano.dm @@ -0,0 +1,56 @@ +/datum/instrument/piano + name = "Generic piano" + category = "Piano" + abstract_type = /datum/instrument/piano + +/datum/instrument/piano/fluid_piano + name = "FluidR3 Grand Piano" + id = "r3grand" + real_samples = list("36"='sound/instruments/synthesis_samples/piano/fluid_piano/c2.ogg', + "48"='sound/instruments/synthesis_samples/piano/fluid_piano/c3.ogg', + "60"='sound/instruments/synthesis_samples/piano/fluid_piano/c4.ogg', + "72"='sound/instruments/synthesis_samples/piano/fluid_piano/c5.ogg', + "84"='sound/instruments/synthesis_samples/piano/fluid_piano/c6.ogg', + "96"='sound/instruments/synthesis_samples/piano/fluid_piano/c7.ogg', + "108"='sound/instruments/synthesis_samples/piano/fluid_piano/c8.ogg') + +/datum/instrument/piano/fluid_harpsichord + name = "FluidR3 Harpsichord" + id = "r3harpsi" + real_samples = list("36"='sound/instruments/synthesis_samples/piano/fluid_harpsi/c2.ogg', + "48"='sound/instruments/synthesis_samples/piano/fluid_harpsi/c3.ogg', + "60"='sound/instruments/synthesis_samples/piano/fluid_harpsi/c4.ogg', + "72"='sound/instruments/synthesis_samples/piano/fluid_harpsi/c5.ogg', + "84"='sound/instruments/synthesis_samples/piano/fluid_harpsi/c6.ogg', + "96"='sound/instruments/synthesis_samples/piano/fluid_harpsi/c7.ogg', + "108"='sound/instruments/synthesis_samples/piano/fluid_harpsi/c8.ogg') + +/datum/instrument/piano/crisis_harpsichord + name = "Crisis Harpsichord" + id = "crharpsi" + real_samples = list("36"='sound/instruments/synthesis_samples/piano/crisis_harpsichord/c2.ogg', + "48"='sound/instruments/synthesis_samples/piano/crisis_harpsichord/c3.ogg', + "60"='sound/instruments/synthesis_samples/piano/crisis_harpsichord/c4.ogg', + "72"='sound/instruments/synthesis_samples/piano/crisis_harpsichord/c5.ogg') + +/datum/instrument/piano/crisis_grandpiano_uni + name = "Crisis Grand Piano One" + id = "crgrand1" + real_samples = list("36"='sound/instruments/synthesis_samples/piano/crisis_grand_piano/c2.ogg', + "48"='sound/instruments/synthesis_samples/piano/crisis_grand_piano/c3.ogg', + "60"='sound/instruments/synthesis_samples/piano/crisis_grand_piano/c4.ogg', + "72"='sound/instruments/synthesis_samples/piano/crisis_grand_piano/c5.ogg', + "84"='sound/instruments/synthesis_samples/piano/crisis_grand_piano/c6.ogg', + "96"='sound/instruments/synthesis_samples/piano/crisis_grand_piano/c7.ogg', + "108"='sound/instruments/synthesis_samples/piano/crisis_grand_piano/c8.ogg') + +/datum/instrument/piano/crisis_brightpiano_uni + name = "Crisis Bright Piano One" + id = "crbright1" + real_samples = list("36"='sound/instruments/synthesis_samples/piano/crisis_bright_piano/c2.ogg', + "48"='sound/instruments/synthesis_samples/piano/crisis_bright_piano/c3.ogg', + "60"='sound/instruments/synthesis_samples/piano/crisis_bright_piano/c4.ogg', + "72"='sound/instruments/synthesis_samples/piano/crisis_bright_piano/c5.ogg', + "84"='sound/instruments/synthesis_samples/piano/crisis_bright_piano/c6.ogg', + "96"='sound/instruments/synthesis_samples/piano/crisis_bright_piano/c7.ogg', + "108"='sound/instruments/synthesis_samples/piano/crisis_bright_piano/c8.ogg') diff --git a/code/modules/instruments/instrument_data/synth_tones.dm b/code/modules/instruments/instrument_data/synth_tones.dm new file mode 100644 index 0000000000..9ad9250f40 --- /dev/null +++ b/code/modules/instruments/instrument_data/synth_tones.dm @@ -0,0 +1,19 @@ +/datum/instrument/tones + name = "Ideal tone" + category = "Tones" + abstract_type = /datum/instrument/tones + +/datum/instrument/tones/square_wave + name = "Ideal square wave" + id = "square" + real_samples = list("81"='sound/instruments/synthesis_samples/tones/Square.ogg') + +/datum/instrument/tones/sine_wave + name = "Ideal sine wave" + id = "sine" + real_samples = list("81"='sound/instruments/synthesis_samples/tones/Sine.ogg') + +/datum/instrument/tones/saw_wave + name = "Ideal sawtooth wave" + id = "saw" + real_samples = list("81"='sound/instruments/synthesis_samples/tones/Sawtooth.ogg') diff --git a/code/modules/instruments/items.dm b/code/modules/instruments/items.dm new file mode 100644 index 0000000000..455c10e5cb --- /dev/null +++ b/code/modules/instruments/items.dm @@ -0,0 +1,312 @@ +//copy pasta of the space piano, don't hurt me -Pete +/obj/item/instrument + name = "generic instrument" + force = 10 + health = 100 + //resistance_flags = FLAMMABLE + icon = 'icons/obj/musician.dmi' + item_icons = list( + slot_l_hand_str = 'icons/mob/items/lefthand_instruments.dmi', + slot_r_hand_str = 'icons/mob/items/righthand_instruments.dmi', + ) + + /// Our song datum. + var/datum/song/handheld/song + /// Our allowed list of instrument ids. This is nulled on initialize. + var/list/allowed_instrument_ids + /// How far away our song datum can be heard. + var/instrument_range = 15 + +/obj/item/instrument/Initialize(mapload) + . = ..() + song = new(src, allowed_instrument_ids, instrument_range) + allowed_instrument_ids = null //We don't need this clogging memory after it's used. + +/obj/item/instrument/Destroy() + QDEL_NULL(song) + return ..() + +/obj/item/instrument/proc/should_stop_playing(mob/user) + return user.incapacitated() || !((loc == user) || (isturf(loc) && Adjacent(user))) // sorry, no more TK playing. + +/obj/item/instrument/suicide_act(mob/user) + var/datum/gender/T = gender_datums[user.get_visible_gender()] + user.visible_message("[user] begins to play 'Gloomy Sunday'! It looks like [T.hes] trying to commit suicide!") + return (BRUTELOSS) + +/obj/item/instrument/attack_self(mob/user) + if(!user.IsAdvancedToolUser()) + to_chat(user, "You don't have the dexterity to do this!") + return TRUE + interact(user) + +/obj/item/instrument/interact(mob/living/user) + if(!isliving(user) || user.incapacitated()) + return + + user.set_machine(src) + song.interact(user) + +/obj/item/instrument/violin + name = "space violin" + desc = "A wooden musical instrument with four strings and a bow. \"The devil went down to space, he was looking for an assistant to grief.\"" + icon_state = "violin" + hitsound = "swing_hit" + allowed_instrument_ids = "violin" + +/obj/item/instrument/violin/golden + name = "golden violin" + desc = "A golden musical instrument with four strings and a bow. \"The devil went down to space, he was looking for an assistant to grief.\"" + icon_state = "golden_violin" + +/obj/item/instrument/piano_synth + name = "synthesizer" + desc = "An advanced electronic synthesizer that can be used as various instruments." + icon_state = "synth" + allowed_instrument_ids = "piano" + +/obj/item/instrument/piano_synth/Initialize(mapload) + . = ..() + song.allowed_instrument_ids = SSinstruments.synthesizer_instrument_ids + +/obj/item/instrument/piano_synth/headphones + name = "headphones" + desc = "Unce unce unce unce. Boop!" + icon_state = "headphones" + slot_flags = SLOT_EARS | SLOT_HEAD + force = 0 + w_class = ITEMSIZE_SMALL + instrument_range = 1 + +/obj/item/instrument/piano_synth/headphones/Initialize() + . = ..() + RegisterSignal(src, COMSIG_SONG_START, .proc/start_playing) + RegisterSignal(src, COMSIG_SONG_END, .proc/stop_playing) + +/** + * Called by a component signal when our song starts playing. + */ +/obj/item/instrument/piano_synth/headphones/proc/start_playing() + SIGNAL_HANDLER + + icon_state = "[initial(icon_state)]_on" + if(ishuman(loc)) + var/mob/living/carbon/human/H = loc + if(H.l_ear == src || H.r_ear == src) + H.update_inv_ears() + else if(H.head == src) + H.update_inv_head() + +/** + * Called by a component signal when our song stops playing. + */ +/obj/item/instrument/piano_synth/headphones/proc/stop_playing() + SIGNAL_HANDLER + + icon_state = "[initial(icon_state)]" + if(ishuman(loc)) + var/mob/living/carbon/human/H = loc + if(H.l_ear == src || H.r_ear == src) + H.update_inv_ears() + else if(H.head == src) + H.update_inv_head() + + +/obj/item/instrument/piano_synth/headphones/spacepods + name = "\improper Nanotrasen space pods" + desc = "Flex your money, AND ignore what everyone else says, all at once!" + icon_state = "spacepods" + slot_flags = SLOT_EARS + //strip_delay = 100 //air pods don't fall out + instrument_range = 0 //you're paying for quality here + +/obj/item/instrument/banjo + name = "banjo" + desc = "A 'Mura' brand banjo. It's pretty much just a drum with a neck and strings." + icon_state = "banjo" + attack_verb = list("scruggs-styled", "hum-diggitied", "shin-dug", "clawhammered") + hitsound = 'sound/weapons/banjoslap.ogg' + allowed_instrument_ids = "banjo" + +/obj/item/instrument/guitar + name = "guitar" + desc = "It's made of wood and has bronze strings." + icon_state = "guitar" + attack_verb = list("played metal on", "serenaded", "crashed", "smashed") + hitsound = 'sound/weapons/stringsmash.ogg' + allowed_instrument_ids = list("guitar","csteelgt","cnylongt", "ccleangt", "cmutedgt") + +/obj/item/instrument/eguitar + name = "electric guitar" + desc = "Makes all your shredding needs possible." + icon_state = "eguitar" + force = 12 + attack_verb = list("played metal on", "shreded", "crashed", "smashed") + hitsound = 'sound/weapons/stringsmash.ogg' + allowed_instrument_ids = "eguitar" + +/obj/item/instrument/glockenspiel + name = "glockenspiel" + desc = "Smooth metal bars perfect for any marching band." + icon_state = "glockenspiel" + allowed_instrument_ids = list("glockenspiel","crvibr", "sgmmbox", "r3celeste") + +/obj/item/instrument/accordion + name = "accordion" + desc = "Pun-Pun not included." + icon_state = "accordion" + allowed_instrument_ids = list("crack", "crtango", "accordion") + +/obj/item/instrument/trumpet + name = "trumpet" + desc = "To announce the arrival of the king!" + icon_state = "trumpet" + allowed_instrument_ids = "crtrumpet" + +/obj/item/instrument/trumpet/spectral + name = "spectral trumpet" + desc = "Things are about to get spooky!" + icon_state = "spectral_trumpet" + force = 0 + attack_verb = list("played", "jazzed", "trumpeted", "mourned", "dooted", "spooked") + +/* +/obj/item/instrument/trumpet/spectral/Initialize() + . = ..() + AddComponent(/datum/component/spooky) +*/ +/obj/item/instrument/trumpet/spectral/attack(mob/living/carbon/C, mob/user) + playsound (src, 'sound/instruments/trombone/En4.mid', 100,1,-1) + ..() + +/obj/item/instrument/saxophone + name = "saxophone" + desc = "This soothing sound will be sure to leave your audience in tears." + icon_state = "saxophone" + allowed_instrument_ids = "saxophone" + +/obj/item/instrument/saxophone/spectral + name = "spectral saxophone" + desc = "This spooky sound will be sure to leave mortals in bones." + icon_state = "saxophone" + force = 0 + attack_verb = list("played", "jazzed", "saxed", "mourned", "dooted", "spooked") + +/* +/obj/item/instrument/saxophone/spectral/Initialize() + . = ..() + AddComponent(/datum/component/spooky) +*/ + +/obj/item/instrument/saxophone/spectral/attack(mob/living/carbon/C, mob/user) + playsound (src, 'sound/instruments/saxophone/En4.mid', 100,1,-1) + ..() + +/obj/item/instrument/trombone + name = "trombone" + desc = "How can any pool table ever hope to compete?" + icon_state = "trombone" + allowed_instrument_ids = list("crtrombone", "crbrass", "trombone") + +/obj/item/instrument/trombone/spectral + name = "spectral trombone" + desc = "A skeleton's favorite instrument. Apply directly on the mortals." + icon_state = "trombone" + force = 0 + attack_verb = list("played", "jazzed", "tromboneed", "mourned", "dooted", "spooked") + +/* +/obj/item/instrument/trombone/spectral/Initialize() + . = ..() + AddComponent(/datum/component/spooky) +*/ + +/obj/item/instrument/trombone/spectral/attack(mob/living/carbon/C, mob/user) + playsound (src, 'sound/instruments/trombone/Cn4.mid', 100,1,-1) + ..() + +/obj/item/instrument/recorder + name = "recorder" + desc = "Just like in school, playing ability and all." + force = 5 + icon_state = "recorder" + allowed_instrument_ids = "recorder" + +/obj/item/instrument/harmonica + name = "harmonica" + desc = "For when you get a bad case of the space blues." + icon_state = "harmonica" + allowed_instrument_ids = list("crharmony", "harmonica") + slot_flags = SLOT_MASK + force = 5 + w_class = ITEMSIZE_SMALL +/* + actions_types = list(/datum/action/item_action/instrument) + +/obj/item/instrument/harmonica/proc/handle_speech(datum/source, list/speech_args) + SIGNAL_HANDLER + if(song.playing && ismob(loc)) + to_chat(loc, "You stop playing the harmonica to talk...") + song.playing = FALSE + +/obj/item/instrument/harmonica/equipped(mob/M, slot) + . = ..() + RegisterSignal(M, COMSIG_MOB_SAY, .proc/handle_speech) + +/obj/item/instrument/harmonica/dropped(mob/M) + . = ..() + UnregisterSignal(M, COMSIG_MOB_SAY) +*/ +/obj/item/instrument/bikehorn + name = "gilded bike horn" + desc = "An exquisitely decorated bike horn, capable of honking in a variety of notes." + icon_state = "bike_horn" + item_icons = list( + slot_l_hand_str = 'icons/mob/items/lefthand_horns.dmi', + slot_r_hand_str = 'icons/mob/items/righthand_horns.dmi', + ) + allowed_instrument_ids = list("bikehorn", "honk") + attack_verb = list("beautifully honked") + w_class = ITEMSIZE_SMALL + force = 0 + throw_speed = 3 + throw_range = 15 + hitsound = 'sound/items/bikehorn.ogg' +/* +/obj/item/choice_beacon/music + name = "instrument delivery beacon" + desc = "Summon your tool of art." + icon_state = "gangtool-red" + +/obj/item/choice_beacon/music/generate_display_names() + var/static/list/instruments + if(!instruments) + instruments = list() + var/list/templist = list(/obj/item/instrument/violin, + /obj/item/instrument/piano_synth, + /obj/item/instrument/banjo, + /obj/item/instrument/guitar, + /obj/item/instrument/eguitar, + /obj/item/instrument/glockenspiel, + /obj/item/instrument/accordion, + /obj/item/instrument/trumpet, + /obj/item/instrument/saxophone, + /obj/item/instrument/trombone, + /obj/item/instrument/recorder, + /obj/item/instrument/harmonica, + /obj/item/instrument/piano_synth/headphones + ) + for(var/V in templist) + var/atom/A = V + instruments[initial(A.name)] = A + return instruments +*/ +/obj/item/instrument/musicalmoth + name = "musical moth" + desc = "Despite its popularity, this controversial musical toy was eventually banned due to its unethically sampled sounds of moths screaming in agony." + icon_state = "mothsician" + allowed_instrument_ids = "mothscream" + attack_verb = list("fluttered", "flaped") + w_class = ITEMSIZE_SMALL + force = 0 + hitsound = 'sound/voice/moth/scream_moth.ogg' diff --git a/code/modules/instruments/items_ch.dm b/code/modules/instruments/items_ch.dm new file mode 100644 index 0000000000..1d392114d8 --- /dev/null +++ b/code/modules/instruments/items_ch.dm @@ -0,0 +1,16 @@ +/obj/item/instrument/keytar + name = "portable keyboard" + desc = "A keyboard, for those interested in the piano on the go! " + icon = 'icons/obj/musician_yw.dmi' + icon_state = "keyboard" + item_state = "keyboard" + attack_verb = list("smashed") + allowed_instrument_ids = "piano" + +/obj/item/instrument/xylophone + name = "xylophone" + desc = "A percussion instrument consisting of a series of wooden bars graduated in length." + icon = 'icons/obj/musician_yw.dmi' + icon_state = "xylophone" + attack_verb = list("smashed") + allowed_instrument_ids = "xylophone" diff --git a/code/modules/instruments/songs/_song.dm b/code/modules/instruments/songs/_song.dm new file mode 100644 index 0000000000..dc4ccfe8b3 --- /dev/null +++ b/code/modules/instruments/songs/_song.dm @@ -0,0 +1,405 @@ +#define MUSICIAN_HEARCHECK_MINDELAY 4 +#define MUSIC_MAXLINES 1000 +#define MUSIC_MAXLINECHARS 300 + +/** + * # Song datum + * + * These are the actual backend behind instruments. + * They attach to an atom and provide the editor + playback functionality. + */ +/datum/song + /// Name of the song + var/name = "Untitled" + + /// The atom we're attached to/playing from + var/atom/parent + + /// Our song lines + var/list/lines + + /// delay between notes in deciseconds + var/tempo = 5 + + /// How far we can be heard + var/instrument_range = 15 + + /// Are we currently playing? + var/playing = FALSE + + /// Are we currently editing? + var/editing = TRUE + /// Is the help screen open? + var/help = FALSE + + /// Repeats left + var/repeat = 0 + /// Maximum times we can repeat + var/max_repeats = 10 + + /// Our volume + var/volume = 35 + /// Max volume + var/max_volume = 75 + /// Min volume - This is so someone doesn't decide it's funny to set it to 0 and play invisible songs. + var/min_volume = 1 + + /// What instruments our built in picker can use. The picker won't show unless this is longer than one. + var/list/allowed_instrument_ids = list("r3grand") + + //////////// Cached instrument variables ///////////// + /// Instrument we are currently using + var/datum/instrument/using_instrument + /// Cached legacy ext for legacy instruments + var/cached_legacy_ext + /// Cached legacy dir for legacy instruments + var/cached_legacy_dir + /// Cached list of samples, referenced directly from the instrument for synthesized instruments + var/list/cached_samples + /// Are we operating in legacy mode (so if the instrument is a legacy instrument) + var/legacy = FALSE + ////////////////////////////////////////////////////// + + /////////////////// Playing variables //////////////// + /** + * Build by compile_chords() + * Must be rebuilt on instrument switch. + * Compilation happens when we start playing and is cleared after we finish playing. + * Format: list of chord lists, with chordlists having (key1, key2, key3, tempodiv) + */ + var/list/compiled_chords + /// Current section of a long chord we're on, so we don't need to make a billion chords, one for every unit ticklag. + var/elapsed_delay + /// Amount of delay to wait before playing the next chord + var/delay_by + /// Current chord we're on. + var/current_chord + /// Channel as text = current volume percentage but it's 0 to 100 instead of 0 to 1. + var/list/channels_playing = list() + /// List of channels that aren't being used, as text. This is to prevent unnecessary freeing and reallocations from SSsounds/SSinstruments. + var/list/channels_idle = list() + /// Person playing us + var/mob/user_playing + ////////////////////////////////////////////////////// + + /// Last world.time we checked for who can hear us + var/last_hearcheck = 0 + /// The list of mobs that can hear us + var/list/hearing_mobs + /// If this is enabled, some things won't be strictly cleared when they usually are (liked compiled_chords on play stop) + var/debug_mode = FALSE + /// Max sound channels to occupy + var/max_sound_channels = CHANNELS_PER_INSTRUMENT + /// Current channels, so we can save a length() call. + var/using_sound_channels = 0 + /// Last channel to play. text. + var/last_channel_played + /// Should we not decay our last played note? + var/full_sustain_held_note = TRUE + + /////////////////////// DO NOT TOUCH THESE /////////////////// + var/octave_min = INSTRUMENT_MIN_OCTAVE + var/octave_max = INSTRUMENT_MAX_OCTAVE + var/key_min = INSTRUMENT_MIN_KEY + var/key_max = INSTRUMENT_MAX_KEY + var/static/list/note_offset_lookup = list(9, 11, 0, 2, 4, 5, 7) + var/static/list/accent_lookup = list("b" = -1, "s" = 1, "#" = 1, "n" = 0) + ////////////////////////////////////////////////////////////// + + ///////////// !!FUN!! - Only works in synthesized mode! ///////////////// + /// Note numbers to shift. + var/note_shift = 0 + var/note_shift_min = -100 + var/note_shift_max = 100 + var/can_noteshift = TRUE + /// The kind of sustain we're using + var/sustain_mode = SUSTAIN_LINEAR + /// When a note is considered dead if it is below this in volume + var/sustain_dropoff_volume = 0 + /// Total duration of linear sustain for 100 volume note to get to SUSTAIN_DROPOFF + var/sustain_linear_duration = 5 + /// Exponential sustain dropoff rate per decisecond + var/sustain_exponential_dropoff = 1.4 + ////////// DO NOT DIRECTLY SET THESE! + /// Do not directly set, use update_sustain() + var/cached_linear_dropoff = 10 + /// Do not directly set, use update_sustain() + var/cached_exponential_dropoff = 1.045 + ///////////////////////////////////////////////////////////////////////// + +/datum/song/New(atom/parent, list/instrument_ids, new_range) + SSinstruments.on_song_new(src) + lines = list() + tempo = sanitize_tempo(tempo) + src.parent = parent + if(instrument_ids) + allowed_instrument_ids = islist(instrument_ids)? instrument_ids : list(instrument_ids) + if(length(allowed_instrument_ids)) + set_instrument(allowed_instrument_ids[1]) + hearing_mobs = list() + volume = clamp(volume, min_volume, max_volume) + update_sustain() + if(new_range) + instrument_range = new_range + +/datum/song/Destroy() + stop_playing() + SSinstruments.on_song_del(src) + lines = null + if(using_instrument) + using_instrument.songs_using -= src + using_instrument = null + allowed_instrument_ids = null + parent = null + return ..() + +/** + * Checks and stores which mobs can hear us. Terminates sounds for mobs that leave our range. + */ +/datum/song/proc/do_hearcheck() + last_hearcheck = world.time + var/list/old = hearing_mobs.Copy() + hearing_mobs.len = 0 + var/turf/source = get_turf(parent) + var/list/in_range = get_mobs_and_objs_in_view_fast(source, instrument_range) + for(var/mob/M in in_range["mobs"]) + hearing_mobs[M] = get_dist(M, source) + var/list/exited = old - hearing_mobs + for(var/i in exited) + terminate_sound_mob(i) + +/** + * Sets our instrument, caching anything necessary for faster accessing. Accepts an ID, typepath, or instantiated instrument datum. + */ +/datum/song/proc/set_instrument(datum/instrument/I) + terminate_all_sounds() + var/old_legacy + if(using_instrument) + using_instrument.songs_using -= src + old_legacy = (using_instrument.instrument_flags & INSTRUMENT_LEGACY) + using_instrument = null + cached_samples = null + cached_legacy_ext = null + cached_legacy_dir = null + legacy = null + if(istext(I) || ispath(I)) + I = SSinstruments.instrument_data[I] + if(istype(I)) + using_instrument = I + I.songs_using += src + var/instrument_legacy = (I.instrument_flags & INSTRUMENT_LEGACY) + if(instrument_legacy) + cached_legacy_ext = I.legacy_instrument_ext + cached_legacy_dir = I.legacy_instrument_path + legacy = TRUE + else + cached_samples = I.samples + legacy = FALSE + if(isnull(old_legacy) || (old_legacy != instrument_legacy)) + if(playing) + compile_chords() + +/** + * Attempts to start playing our song. + */ +/datum/song/proc/start_playing(mob/user) + if(playing) + return + if(!using_instrument?.ready()) + to_chat(user, "An error has occured with [src]. Please reset the instrument.") + return + compile_chords() + if(!length(compiled_chords)) + to_chat(user, "Song is empty.") + return + playing = TRUE + updateDialog(user_playing) + //we can not afford to runtime, since we are going to be doing sound channel reservations and if we runtime it means we have a channel allocation leak. + //wrap the rest of the stuff to ensure stop_playing() is called. + do_hearcheck() + SEND_SIGNAL(parent, COMSIG_SONG_START) + elapsed_delay = 0 + delay_by = 0 + current_chord = 1 + user_playing = user + START_PROCESSING(SSinstruments, src) + +/** + * Stops playing, terminating all sounds if in synthesized mode. Clears hearing_mobs. + */ +/datum/song/proc/stop_playing() + if(!playing) + return + playing = FALSE + if(!debug_mode) + compiled_chords = null + STOP_PROCESSING(SSinstruments, src) + SEND_SIGNAL(parent, COMSIG_SONG_END) + terminate_all_sounds(TRUE) + hearing_mobs.len = 0 + user_playing = null + +/** + * Processes our song. + */ +/datum/song/proc/process_song(wait) + if(!length(compiled_chords) || should_stop_playing(user_playing)) + stop_playing() + return + var/list/chord = compiled_chords[current_chord] + if(++elapsed_delay >= delay_by) + play_chord(chord) + elapsed_delay = 0 + delay_by = tempodiv_to_delay(chord[length(chord)]) + current_chord++ + if(current_chord > length(compiled_chords)) + if(repeat) + repeat-- + current_chord = 1 + return + else + stop_playing() + return + +/** + * Converts a tempodiv to ticks to elapse before playing the next chord, taking into account our tempo. + */ +/datum/song/proc/tempodiv_to_delay(tempodiv) + if(!tempodiv) + tempodiv = 1 // no division by 0. some song converters tend to use 0 for when it wants to have no div, for whatever reason. + return max(1, round((tempo/tempodiv) / world.tick_lag, 1)) + +/** + * Compiles chords. + */ +/datum/song/proc/compile_chords() + legacy ? compile_legacy() : compile_synthesized() + +/** + * Plays a chord. + */ +/datum/song/proc/play_chord(list/chord) + // last value is timing information + for(var/i in 1 to (length(chord) - 1)) + legacy? playkey_legacy(chord[i][1], chord[i][2], chord[i][3], user_playing) : playkey_synth(chord[i], user_playing) + +/** + * Checks if we should halt playback. + */ +/datum/song/proc/should_stop_playing(mob/user) + return QDELETED(parent) || !using_instrument || !playing + +/** + * Sanitizes tempo to a value that makes sense and fits the current world.tick_lag. + */ +/datum/song/proc/sanitize_tempo(new_tempo) + new_tempo = abs(new_tempo) + return clamp(round(new_tempo, world.tick_lag), world.tick_lag, 5 SECONDS) + +/** + * Gets our beats per minute based on our tempo. + */ +/datum/song/proc/get_bpm() + return 600 / tempo + +/** + * Sets our tempo from a beats-per-minute, sanitizing it to a valid number first. + */ +/datum/song/proc/set_bpm(bpm) + tempo = sanitize_tempo(600 / bpm) + +/** + * Updates the window for our users. Override down the line. + */ +/datum/song/proc/updateDialog(mob/user) + interact(user) + +/datum/song/process(wait) + if(!playing) + return PROCESS_KILL + // it's expected this ticks at every world.tick_lag. if it lags, do not attempt to catch up. + process_song(world.tick_lag) + process_decay(world.tick_lag) + +/** + * Updates our cached linear/exponential falloff stuff, saving calculations down the line. + */ +/datum/song/proc/update_sustain() + // Exponential is easy + cached_exponential_dropoff = sustain_exponential_dropoff + // Linear, not so much, since it's a target duration from 100 volume rather than an exponential rate. + var/target_duration = sustain_linear_duration + var/volume_diff = max(0, 100 - sustain_dropoff_volume) + var/volume_decrease_per_decisecond = volume_diff / target_duration + cached_linear_dropoff = volume_decrease_per_decisecond + +/** + * Setter for setting output volume. + */ +/datum/song/proc/set_volume(volume) + src.volume = clamp(volume, max(0, min_volume), min(100, max_volume)) + update_sustain() + updateDialog() + +/** + * Setter for setting how low the volume has to get before a note is considered "dead" and dropped + */ +/datum/song/proc/set_dropoff_volume(volume) + sustain_dropoff_volume = clamp(volume, INSTRUMENT_MIN_SUSTAIN_DROPOFF, 100) + update_sustain() + updateDialog() + +/** + * Setter for setting exponential falloff factor. + */ +/datum/song/proc/set_exponential_drop_rate(drop) + sustain_exponential_dropoff = clamp(drop, INSTRUMENT_EXP_FALLOFF_MIN, INSTRUMENT_EXP_FALLOFF_MAX) + update_sustain() + updateDialog() + +/** + * Setter for setting linear falloff duration. + */ +/datum/song/proc/set_linear_falloff_duration(duration) + sustain_linear_duration = clamp(duration, 0.1, INSTRUMENT_MAX_TOTAL_SUSTAIN) + update_sustain() + updateDialog() + +/datum/song/vv_edit_var(var_name, var_value) + . = ..() + if(.) + switch(var_name) + if(NAMEOF(src, volume)) + set_volume(var_value) + if(NAMEOF(src, sustain_dropoff_volume)) + set_dropoff_volume(var_value) + if(NAMEOF(src, sustain_exponential_dropoff)) + set_exponential_drop_rate(var_value) + if(NAMEOF(src, sustain_linear_duration)) + set_linear_falloff_duration(var_value) + +// subtype for handheld instruments, like violin +/datum/song/handheld + +/datum/song/handheld/updateDialog(mob/user) + parent.interact(user || usr) + +/datum/song/handheld/should_stop_playing(mob/user) + . = ..() + if(.) + return TRUE + var/obj/item/instrument/I = parent + return I.should_stop_playing(user) + +// subtype for stationary structures, like pianos +/datum/song/stationary + +/datum/song/stationary/updateDialog(mob/user) + parent.interact(user || usr) + +/datum/song/stationary/should_stop_playing(mob/user) + . = ..() + if(.) + return TRUE + var/obj/structure/musician/M = parent + return M.should_stop_playing(user) diff --git a/code/modules/instruments/songs/editor.dm b/code/modules/instruments/songs/editor.dm new file mode 100644 index 0000000000..9435ed8163 --- /dev/null +++ b/code/modules/instruments/songs/editor.dm @@ -0,0 +1,251 @@ +/** + * Returns the HTML for the status UI for this song datum. + */ +/datum/song/proc/instrument_status_ui() + . = list() + . += "
" + . += "Current instrument: " + if(!using_instrument) + . += "No instrument loaded!
" + else + . += "[using_instrument.name]
" + . += "Playback Settings:
" + if(can_noteshift) + . += "Note Shift/Note Transpose: [note_shift] keys / [round(note_shift / 12, 0.01)] octaves
" + var/smt + var/modetext = "" + switch(sustain_mode) + if(SUSTAIN_LINEAR) + smt = "Linear" + modetext = "Linear Sustain Duration: [sustain_linear_duration / 10] seconds
" + if(SUSTAIN_EXPONENTIAL) + smt = "Exponential" + modetext = "Exponential Falloff Factor: [sustain_exponential_dropoff]% per decisecond
" + . += "Sustain Mode: [smt]
" + . += modetext + . += using_instrument?.ready()? "Status: Ready
" : "Status: !Instrument Definition Error!
" + . += "Instrument Type: [legacy? "Legacy" : "Synthesized"]
" + . += "Volume: [volume]
" + . += "Volume Dropoff Threshold: [sustain_dropoff_volume]
" + . += "Sustain indefinitely last held note: [full_sustain_held_note? "Enabled" : "Disabled"].
" + . += "
" + +/datum/song/proc/interact(mob/user) + var/list/dat = list() + + dat += instrument_status_ui() + + if(lines.len > 0) + dat += "

Playback

" + if(!playing) + dat += "Play Stop

" + dat += "Repeat Song: " + dat += repeat > 0 ? "--" : "--" + dat += " [repeat] times " + dat += repeat < max_repeats ? "++" : "++" + dat += "
" + else + dat += "Play Stop
" + dat += "Repeats left: [repeat]
" + if(!editing) + dat += "
Show Editor
" + else + dat += "

Editing

" + dat += "Hide Editor" + dat += " Start a New Song" + dat += " Import a Song

" + var/bpm = round(600 / tempo) + dat += "Tempo: - [bpm] BPM +

" + var/linecount = 0 + for(var/line in lines) + linecount += 1 + dat += "Line [linecount]: Edit X [line]
" + dat += "Add Line

" + if(help) + dat += "Hide Help
" + dat += {" + Lines are a series of chords, separated by commas (,), each with notes separated by hyphens (-).
+ Every note in a chord will play together, with chord timed by the tempo.
+
+ Notes are played by the names of the note, and optionally, the accidental, and/or the octave number.
+ By default, every note is natural and in octave 3. Defining otherwise is remembered for each note.
+ Example: C,D,E,F,G,A,B will play a C major scale.
+ After a note has an accidental placed, it will be remembered: C,C4,C,C3 is C3,C4,C4,C3
+ Chords can be played simply by seperating each note with a hyphon: A-C#,Cn-E,E-G#,Gn-B
+ A pause may be denoted by an empty chord: C,E,,C,G
+ To make a chord be a different time, end it with /x, where the chord length will be length
+ defined by tempo / x: C,G/2,E/4
+ Combined, an example is: E-E4/4,F#/2,G#/8,B/8,E3-E4/4 +
+ Lines may be up to [MUSIC_MAXLINECHARS] characters.
+ A song may only contain up to [MUSIC_MAXLINES] lines.
+ "} + else + dat += "Show Help
" + + var/datum/browser/popup = new(user, "instrument", parent?.name || "instrument", 700, 500) + popup.set_content(dat.Join("")) + popup.open() + +/** + * Parses a song the user has input into lines and stores them. + */ +/datum/song/proc/ParseSong(text) + set waitfor = FALSE + //split into lines + lines = splittext(text, "\n") + if(lines.len) + var/bpm_string = "BPM: " + if(findtext(lines[1], bpm_string, 1, length(bpm_string) + 1)) + var/divisor = text2num(copytext(lines[1], length(bpm_string) + 1)) || 120 // default + tempo = sanitize_tempo(600 / round(divisor, 1)) + lines.Cut(1, 2) + else + tempo = sanitize_tempo(5) // default 120 BPM + if(lines.len > MUSIC_MAXLINES) + to_chat(usr, "Too many lines!") + lines.Cut(MUSIC_MAXLINES + 1) + var/linenum = 1 + for(var/l in lines) + if(length_char(l) > MUSIC_MAXLINECHARS) + to_chat(usr, "Line [linenum] too long!") + lines.Remove(l) + else + linenum++ + updateDialog(usr) // make sure updates when complete + +/datum/song/Topic(href, href_list) + if(!parent.CanUseTopic(usr)) + usr << browse(null, "window=instrument") + usr.unset_machine() + return + + parent.add_fingerprint(usr) + + if(href_list["newsong"]) + lines = new() + tempo = sanitize_tempo(5) // default 120 BPM + name = "" + + else if(href_list["import"]) + var/t = "" + do + t = html_encode(input(usr, "Please paste the entire song, formatted:", text("[]", name), t) as message) + if(!in_range(parent, usr)) + return + + if(length_char(t) >= MUSIC_MAXLINES * MUSIC_MAXLINECHARS) + var/cont = input(usr, "Your message is too long! Would you like to continue editing it?", "", "yes") in list("yes", "no") + if(cont == "no") + break + while(length_char(t) > MUSIC_MAXLINES * MUSIC_MAXLINECHARS) + ParseSong(t) + + else if(href_list["help"]) + help = text2num(href_list["help"]) - 1 + + else if(href_list["edit"]) + editing = text2num(href_list["edit"]) - 1 + + if(href_list["repeat"]) //Changing this from a toggle to a number of repeats to avoid infinite loops. + if(playing) + return //So that people cant keep adding to repeat. If the do it intentionally, it could result in the server crashing. + repeat += round(text2num(href_list["repeat"])) + if(repeat < 0) + repeat = 0 + if(repeat > max_repeats) + repeat = max_repeats + + else if(href_list["tempo"]) + tempo = sanitize_tempo(tempo + text2num(href_list["tempo"])) + + else if(href_list["play"]) + INVOKE_ASYNC(src, .proc/start_playing, usr) + + else if(href_list["newline"]) + var/newline = html_encode(input("Enter your line: ", parent.name) as text|null) + if(!newline || !in_range(parent, usr)) + return + if(lines.len > MUSIC_MAXLINES) + return + if(length(newline) > MUSIC_MAXLINECHARS) + newline = copytext(newline, 1, MUSIC_MAXLINECHARS) + lines.Add(newline) + + else if(href_list["deleteline"]) + var/num = round(text2num(href_list["deleteline"])) + if(num > lines.len || num < 1) + return + lines.Cut(num, num+1) + + else if(href_list["modifyline"]) + var/num = round(text2num(href_list["modifyline"]),1) + var/content = stripped_input(usr, "Enter your line: ", parent.name, lines[num], MUSIC_MAXLINECHARS) + if(!content || !in_range(parent, usr)) + return + if(num > lines.len || num < 1) + return + lines[num] = content + + else if(href_list["stop"]) + stop_playing() + + else if(href_list["setlinearfalloff"]) + var/amount = input(usr, "Set linear sustain duration in seconds", "Linear Sustain Duration") as null|num + if(!isnull(amount)) + set_linear_falloff_duration(round(amount * 10, world.tick_lag)) + + else if(href_list["setexpfalloff"]) + var/amount = input(usr, "Set exponential sustain factor", "Exponential sustain factor") as null|num + if(!isnull(amount)) + set_exponential_drop_rate(round(amount, 0.00001)) + + else if(href_list["setvolume"]) + var/amount = input(usr, "Set volume", "Volume") as null|num + if(!isnull(amount)) + set_volume(round(amount, 1)) + + else if(href_list["setdropoffvolume"]) + var/amount = input(usr, "Set dropoff threshold", "Dropoff Threshold Volume") as null|num + if(!isnull(amount)) + set_dropoff_volume(round(amount, 0.01)) + + else if(href_list["switchinstrument"]) + if(!length(allowed_instrument_ids)) + return + else if(length(allowed_instrument_ids) == 1) + set_instrument(allowed_instrument_ids[1]) + return + var/list/categories = list() + for(var/i in allowed_instrument_ids) + var/datum/instrument/I = SSinstruments.get_instrument(i) + if(I) + LAZYSET(categories[I.category || "ERROR CATEGORY"], I.name, I.id) + var/cat = input(usr, "Select Category", "Instrument Category") as null|anything in categories + if(!cat) + return + var/list/instruments = categories[cat] + var/choice = input(usr, "Select Instrument", "Instrument Selection") as null|anything in instruments + if(!choice) + return + choice = instruments[choice] //get id + if(choice) + set_instrument(choice) + + else if(href_list["setnoteshift"]) + var/amount = input(usr, "Set note shift", "Note Shift") as null|num + if(!isnull(amount)) + note_shift = clamp(amount, note_shift_min, note_shift_max) + + else if(href_list["setsustainmode"]) + var/choice = input(usr, "Choose a sustain mode", "Sustain Mode") as null|anything in list("Linear", "Exponential") + switch(choice) + if("Linear") + sustain_mode = SUSTAIN_LINEAR + if("Exponential") + sustain_mode = SUSTAIN_EXPONENTIAL + + else if(href_list["togglesustainhold"]) + full_sustain_held_note = !full_sustain_held_note + + updateDialog() diff --git a/code/modules/instruments/songs/play_legacy.dm b/code/modules/instruments/songs/play_legacy.dm new file mode 100644 index 0000000000..e8666f7867 --- /dev/null +++ b/code/modules/instruments/songs/play_legacy.dm @@ -0,0 +1,91 @@ +/** + * Compiles our lines into "chords" with filenames for legacy playback. This makes there have to be a bit of lag at the beginning of the song, but repeats will not have to parse it again, and overall playback won't be impacted by as much lag. + */ +/datum/song/proc/compile_legacy() + if(!length(src.lines)) + return + var/list/lines = src.lines //cache for hyepr speed! + compiled_chords = list() + var/list/octaves = list(3, 3, 3, 3, 3, 3, 3) + var/list/accents = list("n", "n", "n", "n", "n", "n", "n") + for(var/line in lines) + var/list/chords = splittext(lowertext(line), ",") + for(var/chord in chords) + var/list/compiled_chord = list() + var/tempodiv = 1 + var/list/notes_tempodiv = splittext(chord, "/") + var/len = length(notes_tempodiv) + if(len >= 2) + tempodiv = text2num(notes_tempodiv[2]) + if(len) //some dunkass is going to do ,,,, to make 3 rests instead of ,/1 because there's no standardization so let's be prepared for that. + var/list/notes = splittext(notes_tempodiv[1], "-") + for(var/note in notes) + if(length(note) == 0) + continue + // 1-7, A-G + var/key = text2ascii(note) - 96 + if((key < 1) || (key > 7)) + continue + for(var/i in 2 to length(note)) + var/oct_acc = copytext(note, i, i + 1) + var/num = text2num(oct_acc) + if(!num) //it's an accidental + accents[key] = oct_acc //if they misspelled it/fucked up that's on them lmao, no safety checks. + else //octave + octaves[key] = clamp(num, octave_min, octave_max) + compiled_chord[++compiled_chord.len] = list(key, accents[key], octaves[key]) + compiled_chord += tempodiv //this goes last + if(length(compiled_chord)) + compiled_chords[++compiled_chords.len] = compiled_chord + +/** + * Proc to play a legacy note. Just plays the sound to hearing mobs (and does hearcheck if necessary), no fancy channel/sustain/management. + * + * Arguments: + * * note is a number from 1-7 for A-G + * * acc is either "b", "n", or "#" + * * oct is 1-8 (or 9 for C) + */ +/datum/song/proc/playkey_legacy(note, acc as text, oct, mob/user) + // handle accidental -> B<>C of E<>F + if(acc == "b" && (note == 3 || note == 6)) // C or F + if(note == 3) + oct-- + note-- + acc = "n" + else if(acc == "#" && (note == 2 || note == 5)) // B or E + if(note == 2) + oct++ + note++ + acc = "n" + else if(acc == "#" && (note == 7)) //G# + note = 1 + acc = "b" + else if(acc == "#") // mass convert all sharps to flats, octave jump already handled + acc = "b" + note++ + + // check octave, C is allowed to go to 9 + if(oct < 1 || (note == 3 ? oct > 9 : oct > 8)) + return + + // now generate name + var/soundfile = "sound/instruments/[cached_legacy_dir]/[ascii2text(note+64)][acc][oct].[cached_legacy_ext]" + soundfile = file(soundfile) + // make sure the note exists + if(!fexists(soundfile)) + return + // and play + var/turf/source = get_turf(parent) + if((world.time - MUSICIAN_HEARCHECK_MINDELAY) > last_hearcheck) + do_hearcheck() + var/sound/music_played = sound(soundfile) + for(var/i in hearing_mobs) + var/mob/M = i + /* Would be nice + if(user && HAS_TRAIT(user, TRAIT_MUSICIAN) && isliving(M)) + var/mob/living/L = M + L.apply_status_effect(STATUS_EFFECT_GOOD_MUSIC) + */ + M.playsound_local(source, null, volume * using_instrument.volume_multiplier, S = music_played, preference = /datum/client_preference/instrument_toggle, volume_channel = VOLUME_CHANNEL_INSTRUMENTS) + // Could do environment and echo later but not for now diff --git a/code/modules/instruments/songs/play_synthesized.dm b/code/modules/instruments/songs/play_synthesized.dm new file mode 100644 index 0000000000..dae69c2782 --- /dev/null +++ b/code/modules/instruments/songs/play_synthesized.dm @@ -0,0 +1,150 @@ +/** + * Compiles our lines into "chords" with numbers. This makes there have to be a bit of lag at the beginning of the song, but repeats will not have to parse it again, and overall playback won't be impacted by as much lag. + */ +/datum/song/proc/compile_synthesized() + if(!length(src.lines)) + return + var/list/lines = src.lines //cache for hyepr speed! + compiled_chords = list() + var/list/octaves = list(3, 3, 3, 3, 3, 3, 3) + var/list/accents = list("n", "n", "n", "n", "n", "n", "n") + for(var/line in lines) + var/list/chords = splittext(lowertext(line), ",") + for(var/chord in chords) + var/list/compiled_chord = list() + var/tempodiv = 1 + var/list/notes_tempodiv = splittext(chord, "/") + var/len = length(notes_tempodiv) + if(len >= 2) + tempodiv = text2num(notes_tempodiv[2]) + if(len) //some dunkass is going to do ,,,, to make 3 rests instead of ,/1 because there's no standardization so let's be prepared for that. + var/list/notes = splittext(notes_tempodiv[1], "-") + for(var/note in notes) + if(length(note) == 0) + continue + // 1-7, A-G + var/key = text2ascii(note) - 96 + if((key < 1) || (key > 7)) + continue + for(var/i in 2 to length(note)) + var/oct_acc = copytext(note, i, i + 1) + var/num = text2num(oct_acc) + if(!num) //it's an accidental + accents[key] = oct_acc //if they misspelled it/fucked up that's on them lmao, no safety checks. + else //octave + octaves[key] = clamp(num, octave_min, octave_max) + compiled_chord += clamp((note_offset_lookup[key] + octaves[key] * 12 + accent_lookup[accents[key]]), key_min, key_max) + compiled_chord += tempodiv //this goes last + if(length(compiled_chord)) + compiled_chords[++compiled_chords.len] = compiled_chord + +/** + * Plays a specific numerical key from our instrument to anyone who can hear us. + * Does a hearing check if enough time has passed. + */ +/datum/song/proc/playkey_synth(key, mob/user) + if(can_noteshift) + key = clamp(key + note_shift, key_min, key_max) + if((world.time - MUSICIAN_HEARCHECK_MINDELAY) > last_hearcheck) + do_hearcheck() + var/datum/instrument_key/K = using_instrument.samples[num2text(key)] //See how fucking easy it is to make a number text? You don't need a complicated 9 line proc! + //Should probably add channel limiters here at some point but I don't care right now. + var/channel = pop_channel() + if(isnull(channel)) + return FALSE + . = TRUE + var/sound/copy = sound(K.sample) + var/volume = src.volume * using_instrument.volume_multiplier + copy.frequency = K.frequency + copy.volume = volume + var/channel_text = num2text(channel) + channels_playing[channel_text] = 100 + last_channel_played = channel_text + for(var/i in hearing_mobs) + var/mob/M = i + /* Maybe someday + if(user && HAS_TRAIT(user, TRAIT_MUSICIAN) && isliving(M)) + var/mob/living/L = M + L.apply_status_effect(STATUS_EFFECT_GOOD_MUSIC) + */ + // Jeez + M.playsound_local( + turf_source = get_turf(parent), + soundin = null, + vol = volume, + vary = FALSE, + frequency = K.frequency, + falloff = null, + is_global = null, + channel = channel, + pressure_affected = null, + S = copy, + preference = /datum/client_preference/instrument_toggle, + volume_channel = VOLUME_CHANNEL_INSTRUMENTS) + // Could do environment and echo later but not for now + +/** + * Stops all sounds we are "responsible" for. Only works in synthesized mode. + */ +/datum/song/proc/terminate_all_sounds(clear_channels = TRUE) + for(var/i in hearing_mobs) + terminate_sound_mob(i) + if(clear_channels) + channels_playing.len = 0 + channels_idle.len = 0 + SSinstruments.current_instrument_channels -= using_sound_channels + using_sound_channels = 0 + SSsounds.free_datum_channels(src) + +/** + * Stops all sounds we are responsible for in a given person. Only works in synthesized mode. + */ +/datum/song/proc/terminate_sound_mob(mob/M) + for(var/channel in channels_playing) + M.stop_sound_channel(text2num(channel)) + +/** + * Pops a channel we have reserved so we don't have to release and re-request them from SSsounds every time we play a note. This is faster. + */ +/datum/song/proc/pop_channel() + if(length(channels_idle)) //just pop one off of here if we have one available + . = text2num(channels_idle[1]) + channels_idle.Cut(1,2) + return + if(using_sound_channels >= max_sound_channels) + return + . = SSinstruments.reserve_instrument_channel(src) + if(!isnull(.)) + using_sound_channels++ + +/** + * Decays our channels and updates their volumes to mobs who can hear us. + * + * Arguments: + * * wait_ds - the deciseconds we should decay by. This is to compensate for any lag, as otherwise songs would get pretty nasty during high time dilation. + */ +/datum/song/proc/process_decay(wait_ds) + var/linear_dropoff = cached_linear_dropoff * wait_ds + var/exponential_dropoff = cached_exponential_dropoff ** wait_ds + for(var/channel in channels_playing) + if(full_sustain_held_note && (channel == last_channel_played)) + continue + var/current_volume = channels_playing[channel] + switch(sustain_mode) + if(SUSTAIN_LINEAR) + current_volume -= linear_dropoff + if(SUSTAIN_EXPONENTIAL) + current_volume /= exponential_dropoff + channels_playing[channel] = current_volume + var/dead = current_volume <= sustain_dropoff_volume + var/channelnumber = text2num(channel) + if(dead) + channels_playing -= channel + channels_idle += channel + for(var/i in hearing_mobs) + var/mob/M = i + M.stop_sound_channel(channelnumber) + else + for(var/i in hearing_mobs) + var/mob/M = i + M.set_sound_channel_volume(channelnumber, (current_volume * 0.01) * volume * using_instrument.volume_multiplier) diff --git a/code/modules/instruments/stationary.dm b/code/modules/instruments/stationary.dm new file mode 100644 index 0000000000..62e9d500dc --- /dev/null +++ b/code/modules/instruments/stationary.dm @@ -0,0 +1,59 @@ +/obj/structure/musician + name = "Not A Piano" + desc = "Something broke, contact coderbus." + var/can_play_unanchored = FALSE + var/list/allowed_instrument_ids = list("r3grand","r3harpsi","crharpsi","crgrand1","crbright1", "crichugan", "crihamgan","piano") + var/datum/song/song + +/obj/structure/musician/Initialize(mapload) + . = ..() + song = new(src, allowed_instrument_ids) + allowed_instrument_ids = null + +/obj/structure/musician/Destroy() + QDEL_NULL(song) + return ..() + +/obj/structure/musician/attack_hand(mob/M) + if(!M.IsAdvancedToolUser()) + return + + interact(M) + +/obj/structure/musician/proc/should_stop_playing(mob/user) + if(!(anchored || can_play_unanchored)) + return TRUE + if(!user) + return FALSE + return !CanUseTopic(user) + +/obj/structure/musician/interact(mob/user) + . = ..() + song.interact(user) + +/* +/obj/structure/musician/wrench_act(mob/living/user, obj/item/I) + default_unfasten_wrench(user, I, 40) + return TRUE +*/ + +/obj/structure/musician/piano + name = "space minimoog" + icon = 'icons/obj/musician.dmi' + icon_state = "minimoog" + anchored = TRUE + density = TRUE + +/obj/structure/musician/piano/unanchored + anchored = FALSE + +/obj/structure/musician/piano/Initialize(mapload) + . = ..() + if(prob(50) && icon_state == initial(icon_state)) + name = "space minimoog" + desc = "This is a minimoog, like a space piano, but more spacey!" + icon_state = "minimoog" + else + name = "space piano" + desc = "This is a space piano, like a regular piano, but always in tune! Even if the musician isn't." + icon_state = "piano" diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index 954cb9d31e..c86d237832 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -1059,15 +1059,15 @@ /mob/living/get_sound_env(var/pressure_factor) if (hallucination) - return PSYCHOTIC + return SOUND_ENVIRONMENT_PSYCHOTIC else if (druggy) - return DRUGGED + return SOUND_ENVIRONMENT_DRUGGED else if (drowsyness) - return DIZZY + return SOUND_ENVIRONMENT_DIZZY else if (confused) - return DIZZY + return SOUND_ENVIRONMENT_DIZZY else if (sleeping) - return UNDERWATER + return SOUND_ENVIRONMENT_UNDERWATER else return ..() diff --git a/code/modules/power/apc.dm b/code/modules/power/apc.dm index 868e3e4349..3b228d5ad7 100644 --- a/code/modules/power/apc.dm +++ b/code/modules/power/apc.dm @@ -189,9 +189,7 @@ GLOBAL_LIST_EMPTY(apcs) pixel_x = (dir & 3)? 0 : (dir == 4 ? 26 : -26) //VOREStation Edit -> 24 to 26 pixel_y = (dir & 3)? (dir ==1 ? 26 : -26) : 0 //VOREStation Edit -> 24 to 26 - if(building==0) - init() - else + if(building) area = get_area(src) area.apc = src opened = 1 @@ -200,6 +198,16 @@ GLOBAL_LIST_EMPTY(apcs) stat |= MAINT update_icon() +/obj/machinery/power/apc/Initialize(mapload, ndir, building) + . = ..() + if(!building) + init() + return INITIALIZE_HINT_LATELOAD + +/obj/machinery/power/apc/LateInitialize() + . = ..() + update() + /obj/machinery/power/apc/Destroy() GLOB.apcs -= src update() @@ -268,9 +276,6 @@ GLOBAL_LIST_EMPTY(apcs) make_terminal() - spawn(5) - update() - /obj/machinery/power/apc/examine(mob/user) . = ..() if(Adjacent(user)) diff --git a/code/modules/power/lighting.dm b/code/modules/power/lighting.dm index 3b15faca72..6f3d3144e8 100644 --- a/code/modules/power/lighting.dm +++ b/code/modules/power/lighting.dm @@ -288,8 +288,8 @@ var/global/list/light_type_cache = list() shows_alerts = FALSE //VOREStation Edit var/lamp_shade = 1 -/obj/machinery/light/flamp/New(atom/newloc, obj/machinery/light_construct/construct = null) - ..(newloc, construct) +/obj/machinery/light/flamp/Initialize(mapload, obj/machinery/light_construct/construct = null) + . = ..() if(construct) start_with_cell = FALSE lamp_shade = 0 @@ -322,15 +322,13 @@ var/global/list/light_type_cache = list() auto_flicker = TRUE //VOREStation Add - Shadeless! -/obj/machinery/light/flamp/noshade/New() +/obj/machinery/light/flamp/noshade lamp_shade = 0 - update(0) - ..() //VOREStation Add End // create a new lighting fixture -/obj/machinery/light/New(atom/newloc, obj/machinery/light_construct/construct = null) - ..(newloc) +/obj/machinery/light/Initialize(mapload, obj/machinery/light_construct/construct = null) + . =..() if(start_with_cell && !no_emergency) cell = new/obj/item/weapon/cell/emergency_light(src) diff --git a/icons/mob/head.dmi b/icons/mob/head.dmi index a61d7e9173..08bf51b4fd 100644 Binary files a/icons/mob/head.dmi and b/icons/mob/head.dmi differ diff --git a/icons/mob/items/lefthand_horns.dmi b/icons/mob/items/lefthand_horns.dmi new file mode 100644 index 0000000000..af8a5e7d22 Binary files /dev/null and b/icons/mob/items/lefthand_horns.dmi differ diff --git a/icons/mob/items/lefthand_instruments.dmi b/icons/mob/items/lefthand_instruments.dmi index e73ddd9d43..54f8b47b2f 100644 Binary files a/icons/mob/items/lefthand_instruments.dmi and b/icons/mob/items/lefthand_instruments.dmi differ diff --git a/icons/mob/items/righthand_horns.dmi b/icons/mob/items/righthand_horns.dmi new file mode 100644 index 0000000000..8d0be6d0aa Binary files /dev/null and b/icons/mob/items/righthand_horns.dmi differ diff --git a/icons/mob/items/righthand_instruments.dmi b/icons/mob/items/righthand_instruments.dmi index 66831d5f86..725b4de636 100644 Binary files a/icons/mob/items/righthand_instruments.dmi and b/icons/mob/items/righthand_instruments.dmi differ diff --git a/icons/obj/musician.dmi b/icons/obj/musician.dmi index 67b1a44eb2..8415c1051e 100644 Binary files a/icons/obj/musician.dmi and b/icons/obj/musician.dmi differ diff --git a/maps/southern_cross/southern_cross-8.dmm b/maps/southern_cross/southern_cross-8.dmm index 8bc4db0993..f3841270e9 100644 --- a/maps/southern_cross/southern_cross-8.dmm +++ b/maps/southern_cross/southern_cross-8.dmm @@ -1317,7 +1317,7 @@ "mQJ" = (/obj/item/toy/chess/bishop_white{color = "teal"},/turf/simulated/floor/holofloor/wmarble,/area/holodeck/source_chess) "mRE" = (/obj/structure/urinal{pixel_y = 32},/obj/structure/window/reinforced/tinted{dir = 8},/turf/unsimulated/floor{icon_state = "freezerfloor"},/area/centcom/specops) "mRN" = (/obj/machinery/chemical_dispenser/full,/obj/item/weapon/reagent_containers/glass/beaker/large,/obj/structure/table/reinforced,/turf/unsimulated/floor{dir = 5; icon_state = "vault"},/area/centcom/specops) -"mSB" = (/obj/structure/device/piano{dir = 4},/obj/effect/floor_decal/corner/yellow/diagonal,/obj/effect/floor_decal/corner/blue/diagonal{dir = 4},/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/living) +"mSB" = (/obj/structure/musician/piano{dir = 4},/obj/effect/floor_decal/corner/yellow/diagonal,/obj/effect/floor_decal/corner/blue/diagonal{dir = 4},/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/living) "mSP" = (/turf/simulated/shuttle/wall/dark{join_group = "shuttle_ert"},/area/shuttle/response_ship) "mSQ" = (/obj/machinery/door/window/holowindoor{base_state = "right"; dir = 2; icon_state = "right"; name = "Green Team"},/turf/simulated/floor/holofloor/tiled/dark,/area/holodeck/source_basketball) "mTk" = (/obj/machinery/portable_atmospherics/canister/oxygen/prechilled,/obj/machinery/atmospherics/portables_connector,/obj/effect/floor_decal/corner/paleblue{dir = 5},/turf/unsimulated/floor{icon_state = "white"},/area/centcom/medical) diff --git a/maps/submaps/surface_submaps/wilderness/chasm.dmm b/maps/submaps/surface_submaps/wilderness/chasm.dmm index 670969f351..07ded25f79 100644 --- a/maps/submaps/surface_submaps/wilderness/chasm.dmm +++ b/maps/submaps/surface_submaps/wilderness/chasm.dmm @@ -96,7 +96,7 @@ "YR" = (/obj/structure/cliff/automatic/corner{dir = 10},/obj/structure/loot_pile/maint/technical,/turf/simulated/floor/outdoors/rocks{outdoors = 0},/area/submap/Chasm) "YU" = (/obj/effect/floor_decal/rust,/obj/effect/floor_decal/rust/color_rustedcee,/obj/effect/decal/cleanable/dirt,/obj/random/humanoidremains,/turf/simulated/floor/tiled/asteroid_steel,/area/submap/Chasm) "Za" = (/obj/structure/cliff/automatic{dir = 10},/turf/simulated/floor/outdoors/rocks{outdoors = 0},/area/submap/Chasm) -"Zd" = (/obj/item/device/instrument/trombone,/turf/simulated/floor/outdoors/rocks{outdoors = 0},/area/submap/Chasm) +"Zd" = (/obj/item/instrument/trombone,/turf/simulated/floor/outdoors/rocks{outdoors = 0},/area/submap/Chasm) "Zn" = (/mob/living/simple_mob/animal/space/jelly{health = 150; maxHealth = 150; name = "Cavern jelly blob"},/obj/item/weapon/bone/skull,/turf/simulated/floor/outdoors/rocks{outdoors = 0},/area/submap/Chasm) "ZS" = (/mob/living/simple_mob/animal/space/jelly{health = 150; maxHealth = 150; name = "Cavern jelly blob"},/turf/simulated/floor/outdoors/rocks{outdoors = 0},/area/submap/Chasm) diff --git a/maps/tether/tether-03-surface3.dmm b/maps/tether/tether-03-surface3.dmm index 4b6a2fff03..33cb52b98b 100644 --- a/maps/tether/tether-03-surface3.dmm +++ b/maps/tether/tether-03-surface3.dmm @@ -20880,10 +20880,10 @@ /turf/simulated/floor/tiled/white, /area/crew_quarters/kitchen) "aHz" = ( -/obj/structure/device/piano, /obj/effect/floor_decal/spline/plain{ dir = 1 }, +/obj/structure/musician/piano, /turf/simulated/floor/lino, /area/tether/surfacebase/entertainment/stage) "aHA" = ( @@ -32556,10 +32556,12 @@ dir = 4 }, /obj/structure/table/rack/steel, -/obj/item/device/instrument/violin, /obj/effect/floor_decal/spline/plain{ dir = 1 }, +/obj/item/instrument/violin, +/obj/item/instrument/piano_synth, +/obj/item/instrument/recorder, /turf/simulated/floor/lino, /area/tether/surfacebase/entertainment/stage) "bcW" = ( diff --git a/maps/tether/tether_areas.dm b/maps/tether/tether_areas.dm index 51f1fc7c56..4a263a02d3 100644 --- a/maps/tether/tether_areas.dm +++ b/maps/tether/tether_areas.dm @@ -142,7 +142,7 @@ /area/tether/surfacebase/outside name = "Outside - Surface" - sound_env = MOUNTAINS + sound_env = SOUND_ENVIRONMENT_MOUNTAINS /area/tether/surfacebase/outside/outside1 icon_state = "outside1" /area/tether/surfacebase/outside/outside2 @@ -541,7 +541,7 @@ /area/tether/surfacebase/security/solitary name = "\improper Surface Security Solitary Confinement" lightswitch = 0 - sound_env =PADDED_CELL + sound_env = SOUND_ENVIRONMENT_PADDED_CELL /area/tether/surfacebase/security/gasstorage name = "\improper Surface Security Gas Storage" lightswitch = 0 @@ -639,7 +639,7 @@ /area/engineering/atmos_intake name = "\improper Atmospherics Intake" icon_state = "atmos" - sound_env = MOUNTAINS + sound_env = SOUND_ENVIRONMENT_MOUNTAINS /area/engineering/atmos/hallway name = "\improper Atmospherics Main Hallway" @@ -1360,7 +1360,7 @@ name = "\improper Virology Maintenance" /area/maintenance/station/ai name = "\improper AI Maintenance" - sound_env = SEWER_PIPE + sound_env = SOUND_ENVIRONMENT_SEWER_PIPE /area/maintenance/station/exploration name = "\improper Exploration Maintenance" /area/maintenance/abandonedlibrary @@ -1372,7 +1372,7 @@ /area/maintenance/station/spacecommandmaint name = "\improper Secondary Command Maintenance" icon_state = "bridge" - sound_env = SEWER_PIPE + sound_env = SOUND_ENVIRONMENT_SEWER_PIPE /area/maintenance/substation/spacecommand name = "\improper Secondary Command Substation" icon_state = "substation" diff --git a/sound/instruments/banjo/Ab3.ogg b/sound/instruments/banjo/Ab3.ogg new file mode 100644 index 0000000000..66e263bd61 Binary files /dev/null and b/sound/instruments/banjo/Ab3.ogg differ diff --git a/sound/instruments/banjo/Ab4.ogg b/sound/instruments/banjo/Ab4.ogg new file mode 100644 index 0000000000..f003e03233 Binary files /dev/null and b/sound/instruments/banjo/Ab4.ogg differ diff --git a/sound/instruments/banjo/Ab5.ogg b/sound/instruments/banjo/Ab5.ogg new file mode 100644 index 0000000000..c405725208 Binary files /dev/null and b/sound/instruments/banjo/Ab5.ogg differ diff --git a/sound/instruments/banjo/An3.ogg b/sound/instruments/banjo/An3.ogg new file mode 100644 index 0000000000..1700704c9c Binary files /dev/null and b/sound/instruments/banjo/An3.ogg differ diff --git a/sound/instruments/banjo/An4.ogg b/sound/instruments/banjo/An4.ogg new file mode 100644 index 0000000000..eb7279f869 Binary files /dev/null and b/sound/instruments/banjo/An4.ogg differ diff --git a/sound/instruments/banjo/An5.ogg b/sound/instruments/banjo/An5.ogg new file mode 100644 index 0000000000..d9cf57c0fe Binary files /dev/null and b/sound/instruments/banjo/An5.ogg differ diff --git a/sound/instruments/banjo/Bb3.ogg b/sound/instruments/banjo/Bb3.ogg new file mode 100644 index 0000000000..d3f757c0ac Binary files /dev/null and b/sound/instruments/banjo/Bb3.ogg differ diff --git a/sound/instruments/banjo/Bb4.ogg b/sound/instruments/banjo/Bb4.ogg new file mode 100644 index 0000000000..a9d869091b Binary files /dev/null and b/sound/instruments/banjo/Bb4.ogg differ diff --git a/sound/instruments/banjo/Bb5.ogg b/sound/instruments/banjo/Bb5.ogg new file mode 100644 index 0000000000..a56e6c2500 Binary files /dev/null and b/sound/instruments/banjo/Bb5.ogg differ diff --git a/sound/instruments/banjo/Bn2.ogg b/sound/instruments/banjo/Bn2.ogg new file mode 100644 index 0000000000..3154f97419 Binary files /dev/null and b/sound/instruments/banjo/Bn2.ogg differ diff --git a/sound/instruments/banjo/Bn3.ogg b/sound/instruments/banjo/Bn3.ogg new file mode 100644 index 0000000000..6c72ec2fd5 Binary files /dev/null and b/sound/instruments/banjo/Bn3.ogg differ diff --git a/sound/instruments/banjo/Bn4.ogg b/sound/instruments/banjo/Bn4.ogg new file mode 100644 index 0000000000..b0e9a2b3b2 Binary files /dev/null and b/sound/instruments/banjo/Bn4.ogg differ diff --git a/sound/instruments/banjo/Bn5.ogg b/sound/instruments/banjo/Bn5.ogg new file mode 100644 index 0000000000..1b002140b8 Binary files /dev/null and b/sound/instruments/banjo/Bn5.ogg differ diff --git a/sound/instruments/banjo/Cn3.ogg b/sound/instruments/banjo/Cn3.ogg new file mode 100644 index 0000000000..6ef414d9d0 Binary files /dev/null and b/sound/instruments/banjo/Cn3.ogg differ diff --git a/sound/instruments/banjo/Cn4.ogg b/sound/instruments/banjo/Cn4.ogg new file mode 100644 index 0000000000..4a26a6741d Binary files /dev/null and b/sound/instruments/banjo/Cn4.ogg differ diff --git a/sound/instruments/banjo/Cn5.ogg b/sound/instruments/banjo/Cn5.ogg new file mode 100644 index 0000000000..901ed3bc08 Binary files /dev/null and b/sound/instruments/banjo/Cn5.ogg differ diff --git a/sound/instruments/banjo/Cn6.ogg b/sound/instruments/banjo/Cn6.ogg new file mode 100644 index 0000000000..5cdbbb17ce Binary files /dev/null and b/sound/instruments/banjo/Cn6.ogg differ diff --git a/sound/instruments/banjo/Db3.ogg b/sound/instruments/banjo/Db3.ogg new file mode 100644 index 0000000000..1ebffdf502 Binary files /dev/null and b/sound/instruments/banjo/Db3.ogg differ diff --git a/sound/instruments/banjo/Db4.ogg b/sound/instruments/banjo/Db4.ogg new file mode 100644 index 0000000000..5b93936508 Binary files /dev/null and b/sound/instruments/banjo/Db4.ogg differ diff --git a/sound/instruments/banjo/Db5.ogg b/sound/instruments/banjo/Db5.ogg new file mode 100644 index 0000000000..6ee4dde947 Binary files /dev/null and b/sound/instruments/banjo/Db5.ogg differ diff --git a/sound/instruments/banjo/Db6.ogg b/sound/instruments/banjo/Db6.ogg new file mode 100644 index 0000000000..fd73894fda Binary files /dev/null and b/sound/instruments/banjo/Db6.ogg differ diff --git a/sound/instruments/banjo/Dn3.ogg b/sound/instruments/banjo/Dn3.ogg new file mode 100644 index 0000000000..77491b01b8 Binary files /dev/null and b/sound/instruments/banjo/Dn3.ogg differ diff --git a/sound/instruments/banjo/Dn4.ogg b/sound/instruments/banjo/Dn4.ogg new file mode 100644 index 0000000000..11f68b5a15 Binary files /dev/null and b/sound/instruments/banjo/Dn4.ogg differ diff --git a/sound/instruments/banjo/Dn5.ogg b/sound/instruments/banjo/Dn5.ogg new file mode 100644 index 0000000000..2e9ebe4989 Binary files /dev/null and b/sound/instruments/banjo/Dn5.ogg differ diff --git a/sound/instruments/banjo/Dn6.ogg b/sound/instruments/banjo/Dn6.ogg new file mode 100644 index 0000000000..89ae62361d Binary files /dev/null and b/sound/instruments/banjo/Dn6.ogg differ diff --git a/sound/instruments/banjo/Eb3.ogg b/sound/instruments/banjo/Eb3.ogg new file mode 100644 index 0000000000..1d1e43049d Binary files /dev/null and b/sound/instruments/banjo/Eb3.ogg differ diff --git a/sound/instruments/banjo/Eb4.ogg b/sound/instruments/banjo/Eb4.ogg new file mode 100644 index 0000000000..2722655f5a Binary files /dev/null and b/sound/instruments/banjo/Eb4.ogg differ diff --git a/sound/instruments/banjo/Eb5.ogg b/sound/instruments/banjo/Eb5.ogg new file mode 100644 index 0000000000..7a109dfdf7 Binary files /dev/null and b/sound/instruments/banjo/Eb5.ogg differ diff --git a/sound/instruments/banjo/En3.ogg b/sound/instruments/banjo/En3.ogg new file mode 100644 index 0000000000..4610efdd4f Binary files /dev/null and b/sound/instruments/banjo/En3.ogg differ diff --git a/sound/instruments/banjo/En4.ogg b/sound/instruments/banjo/En4.ogg new file mode 100644 index 0000000000..64c14daf91 Binary files /dev/null and b/sound/instruments/banjo/En4.ogg differ diff --git a/sound/instruments/banjo/En5.ogg b/sound/instruments/banjo/En5.ogg new file mode 100644 index 0000000000..8e0b6c1637 Binary files /dev/null and b/sound/instruments/banjo/En5.ogg differ diff --git a/sound/instruments/banjo/Fn3.ogg b/sound/instruments/banjo/Fn3.ogg new file mode 100644 index 0000000000..5cdc4f13fb Binary files /dev/null and b/sound/instruments/banjo/Fn3.ogg differ diff --git a/sound/instruments/banjo/Fn4.ogg b/sound/instruments/banjo/Fn4.ogg new file mode 100644 index 0000000000..78d5454f18 Binary files /dev/null and b/sound/instruments/banjo/Fn4.ogg differ diff --git a/sound/instruments/banjo/Fn5.ogg b/sound/instruments/banjo/Fn5.ogg new file mode 100644 index 0000000000..b21559b465 Binary files /dev/null and b/sound/instruments/banjo/Fn5.ogg differ diff --git a/sound/instruments/banjo/Gb3.ogg b/sound/instruments/banjo/Gb3.ogg new file mode 100644 index 0000000000..fd055b7471 Binary files /dev/null and b/sound/instruments/banjo/Gb3.ogg differ diff --git a/sound/instruments/banjo/Gb4.ogg b/sound/instruments/banjo/Gb4.ogg new file mode 100644 index 0000000000..f2c62510ed Binary files /dev/null and b/sound/instruments/banjo/Gb4.ogg differ diff --git a/sound/instruments/banjo/Gb5.ogg b/sound/instruments/banjo/Gb5.ogg new file mode 100644 index 0000000000..ab17347912 Binary files /dev/null and b/sound/instruments/banjo/Gb5.ogg differ diff --git a/sound/instruments/banjo/Gn3.ogg b/sound/instruments/banjo/Gn3.ogg new file mode 100644 index 0000000000..ad52ef85c0 Binary files /dev/null and b/sound/instruments/banjo/Gn3.ogg differ diff --git a/sound/instruments/banjo/Gn4.ogg b/sound/instruments/banjo/Gn4.ogg new file mode 100644 index 0000000000..2ddb13b86b Binary files /dev/null and b/sound/instruments/banjo/Gn4.ogg differ diff --git a/sound/instruments/banjo/Gn5.ogg b/sound/instruments/banjo/Gn5.ogg new file mode 100644 index 0000000000..d5a7886c4c Binary files /dev/null and b/sound/instruments/banjo/Gn5.ogg differ diff --git a/sound/instruments/synthesis_samples/brass/crisis_brass/c2.ogg b/sound/instruments/synthesis_samples/brass/crisis_brass/c2.ogg new file mode 100644 index 0000000000..aaa1e27ab8 Binary files /dev/null and b/sound/instruments/synthesis_samples/brass/crisis_brass/c2.ogg differ diff --git a/sound/instruments/synthesis_samples/brass/crisis_brass/c3.ogg b/sound/instruments/synthesis_samples/brass/crisis_brass/c3.ogg new file mode 100644 index 0000000000..ce50e76aae Binary files /dev/null and b/sound/instruments/synthesis_samples/brass/crisis_brass/c3.ogg differ diff --git a/sound/instruments/synthesis_samples/brass/crisis_brass/c4.ogg b/sound/instruments/synthesis_samples/brass/crisis_brass/c4.ogg new file mode 100644 index 0000000000..22f34d6759 Binary files /dev/null and b/sound/instruments/synthesis_samples/brass/crisis_brass/c4.ogg differ diff --git a/sound/instruments/synthesis_samples/brass/crisis_brass/c5.ogg b/sound/instruments/synthesis_samples/brass/crisis_brass/c5.ogg new file mode 100644 index 0000000000..eb5bb7c295 Binary files /dev/null and b/sound/instruments/synthesis_samples/brass/crisis_brass/c5.ogg differ diff --git a/sound/instruments/synthesis_samples/brass/crisis_trombone/C2.ogg b/sound/instruments/synthesis_samples/brass/crisis_trombone/C2.ogg new file mode 100644 index 0000000000..bd299e321a Binary files /dev/null and b/sound/instruments/synthesis_samples/brass/crisis_trombone/C2.ogg differ diff --git a/sound/instruments/synthesis_samples/brass/crisis_trombone/C3.ogg b/sound/instruments/synthesis_samples/brass/crisis_trombone/C3.ogg new file mode 100644 index 0000000000..0519d2d20d Binary files /dev/null and b/sound/instruments/synthesis_samples/brass/crisis_trombone/C3.ogg differ diff --git a/sound/instruments/synthesis_samples/brass/crisis_trombone/C4.ogg b/sound/instruments/synthesis_samples/brass/crisis_trombone/C4.ogg new file mode 100644 index 0000000000..3b969a34b1 Binary files /dev/null and b/sound/instruments/synthesis_samples/brass/crisis_trombone/C4.ogg differ diff --git a/sound/instruments/synthesis_samples/brass/crisis_trombone/C5.ogg b/sound/instruments/synthesis_samples/brass/crisis_trombone/C5.ogg new file mode 100644 index 0000000000..75f709c16f Binary files /dev/null and b/sound/instruments/synthesis_samples/brass/crisis_trombone/C5.ogg differ diff --git a/sound/instruments/synthesis_samples/brass/crisis_trumpet/C4.ogg b/sound/instruments/synthesis_samples/brass/crisis_trumpet/C4.ogg new file mode 100644 index 0000000000..ba347f8003 Binary files /dev/null and b/sound/instruments/synthesis_samples/brass/crisis_trumpet/C4.ogg differ diff --git a/sound/instruments/synthesis_samples/brass/crisis_trumpet/C5.ogg b/sound/instruments/synthesis_samples/brass/crisis_trumpet/C5.ogg new file mode 100644 index 0000000000..cee89761d0 Binary files /dev/null and b/sound/instruments/synthesis_samples/brass/crisis_trumpet/C5.ogg differ diff --git a/sound/instruments/synthesis_samples/chromatic/fluid_celeste/C2.ogg b/sound/instruments/synthesis_samples/chromatic/fluid_celeste/C2.ogg new file mode 100644 index 0000000000..105f767655 Binary files /dev/null and b/sound/instruments/synthesis_samples/chromatic/fluid_celeste/C2.ogg differ diff --git a/sound/instruments/synthesis_samples/chromatic/fluid_celeste/C3.ogg b/sound/instruments/synthesis_samples/chromatic/fluid_celeste/C3.ogg new file mode 100644 index 0000000000..4aa33b6cde Binary files /dev/null and b/sound/instruments/synthesis_samples/chromatic/fluid_celeste/C3.ogg differ diff --git a/sound/instruments/synthesis_samples/chromatic/fluid_celeste/C4.ogg b/sound/instruments/synthesis_samples/chromatic/fluid_celeste/C4.ogg new file mode 100644 index 0000000000..d661e8d758 Binary files /dev/null and b/sound/instruments/synthesis_samples/chromatic/fluid_celeste/C4.ogg differ diff --git a/sound/instruments/synthesis_samples/chromatic/fluid_celeste/C5.ogg b/sound/instruments/synthesis_samples/chromatic/fluid_celeste/C5.ogg new file mode 100644 index 0000000000..bf650f1a6f Binary files /dev/null and b/sound/instruments/synthesis_samples/chromatic/fluid_celeste/C5.ogg differ diff --git a/sound/instruments/synthesis_samples/chromatic/fluid_celeste/C6.ogg b/sound/instruments/synthesis_samples/chromatic/fluid_celeste/C6.ogg new file mode 100644 index 0000000000..c00f7949b7 Binary files /dev/null and b/sound/instruments/synthesis_samples/chromatic/fluid_celeste/C6.ogg differ diff --git a/sound/instruments/synthesis_samples/chromatic/fluid_celeste/C7.ogg b/sound/instruments/synthesis_samples/chromatic/fluid_celeste/C7.ogg new file mode 100644 index 0000000000..72588e9ca4 Binary files /dev/null and b/sound/instruments/synthesis_samples/chromatic/fluid_celeste/C7.ogg differ diff --git a/sound/instruments/synthesis_samples/chromatic/fluid_celeste/C8.ogg b/sound/instruments/synthesis_samples/chromatic/fluid_celeste/C8.ogg new file mode 100644 index 0000000000..b2a0b445b9 Binary files /dev/null and b/sound/instruments/synthesis_samples/chromatic/fluid_celeste/C8.ogg differ diff --git a/sound/instruments/synthesis_samples/chromatic/sgmbox/c2.ogg b/sound/instruments/synthesis_samples/chromatic/sgmbox/c2.ogg new file mode 100644 index 0000000000..ecf6778343 Binary files /dev/null and b/sound/instruments/synthesis_samples/chromatic/sgmbox/c2.ogg differ diff --git a/sound/instruments/synthesis_samples/chromatic/sgmbox/c3.ogg b/sound/instruments/synthesis_samples/chromatic/sgmbox/c3.ogg new file mode 100644 index 0000000000..867e9ce00d Binary files /dev/null and b/sound/instruments/synthesis_samples/chromatic/sgmbox/c3.ogg differ diff --git a/sound/instruments/synthesis_samples/chromatic/sgmbox/c4.ogg b/sound/instruments/synthesis_samples/chromatic/sgmbox/c4.ogg new file mode 100644 index 0000000000..446d45993e Binary files /dev/null and b/sound/instruments/synthesis_samples/chromatic/sgmbox/c4.ogg differ diff --git a/sound/instruments/synthesis_samples/chromatic/sgmbox/c5.ogg b/sound/instruments/synthesis_samples/chromatic/sgmbox/c5.ogg new file mode 100644 index 0000000000..54d56400c0 Binary files /dev/null and b/sound/instruments/synthesis_samples/chromatic/sgmbox/c5.ogg differ diff --git a/sound/instruments/synthesis_samples/chromatic/vibraphone1/c2.ogg b/sound/instruments/synthesis_samples/chromatic/vibraphone1/c2.ogg new file mode 100644 index 0000000000..f3770c1f1a Binary files /dev/null and b/sound/instruments/synthesis_samples/chromatic/vibraphone1/c2.ogg differ diff --git a/sound/instruments/synthesis_samples/chromatic/vibraphone1/c3.ogg b/sound/instruments/synthesis_samples/chromatic/vibraphone1/c3.ogg new file mode 100644 index 0000000000..28954fbb47 Binary files /dev/null and b/sound/instruments/synthesis_samples/chromatic/vibraphone1/c3.ogg differ diff --git a/sound/instruments/synthesis_samples/chromatic/vibraphone1/c4.ogg b/sound/instruments/synthesis_samples/chromatic/vibraphone1/c4.ogg new file mode 100644 index 0000000000..1233f5314a Binary files /dev/null and b/sound/instruments/synthesis_samples/chromatic/vibraphone1/c4.ogg differ diff --git a/sound/instruments/synthesis_samples/chromatic/vibraphone1/c5.ogg b/sound/instruments/synthesis_samples/chromatic/vibraphone1/c5.ogg new file mode 100644 index 0000000000..00daf33135 Binary files /dev/null and b/sound/instruments/synthesis_samples/chromatic/vibraphone1/c5.ogg differ diff --git a/sound/instruments/synthesis_samples/guitar/crisis_clean/C2.ogg b/sound/instruments/synthesis_samples/guitar/crisis_clean/C2.ogg new file mode 100644 index 0000000000..13ad54bff0 Binary files /dev/null and b/sound/instruments/synthesis_samples/guitar/crisis_clean/C2.ogg differ diff --git a/sound/instruments/synthesis_samples/guitar/crisis_clean/C3.ogg b/sound/instruments/synthesis_samples/guitar/crisis_clean/C3.ogg new file mode 100644 index 0000000000..17bf392c4b Binary files /dev/null and b/sound/instruments/synthesis_samples/guitar/crisis_clean/C3.ogg differ diff --git a/sound/instruments/synthesis_samples/guitar/crisis_clean/C4.ogg b/sound/instruments/synthesis_samples/guitar/crisis_clean/C4.ogg new file mode 100644 index 0000000000..feda419a0a Binary files /dev/null and b/sound/instruments/synthesis_samples/guitar/crisis_clean/C4.ogg differ diff --git a/sound/instruments/synthesis_samples/guitar/crisis_clean/C5.ogg b/sound/instruments/synthesis_samples/guitar/crisis_clean/C5.ogg new file mode 100644 index 0000000000..bd088dd850 Binary files /dev/null and b/sound/instruments/synthesis_samples/guitar/crisis_clean/C5.ogg differ diff --git a/sound/instruments/synthesis_samples/guitar/crisis_muted/C2.ogg b/sound/instruments/synthesis_samples/guitar/crisis_muted/C2.ogg new file mode 100644 index 0000000000..09cdbeec42 Binary files /dev/null and b/sound/instruments/synthesis_samples/guitar/crisis_muted/C2.ogg differ diff --git a/sound/instruments/synthesis_samples/guitar/crisis_muted/C3.ogg b/sound/instruments/synthesis_samples/guitar/crisis_muted/C3.ogg new file mode 100644 index 0000000000..f82c39cee5 Binary files /dev/null and b/sound/instruments/synthesis_samples/guitar/crisis_muted/C3.ogg differ diff --git a/sound/instruments/synthesis_samples/guitar/crisis_muted/C4.ogg b/sound/instruments/synthesis_samples/guitar/crisis_muted/C4.ogg new file mode 100644 index 0000000000..23bfd113d6 Binary files /dev/null and b/sound/instruments/synthesis_samples/guitar/crisis_muted/C4.ogg differ diff --git a/sound/instruments/synthesis_samples/guitar/crisis_muted/C5.ogg b/sound/instruments/synthesis_samples/guitar/crisis_muted/C5.ogg new file mode 100644 index 0000000000..e5ec38d5ab Binary files /dev/null and b/sound/instruments/synthesis_samples/guitar/crisis_muted/C5.ogg differ diff --git a/sound/instruments/synthesis_samples/guitar/crisis_nylon/c2.ogg b/sound/instruments/synthesis_samples/guitar/crisis_nylon/c2.ogg new file mode 100644 index 0000000000..42a6cdfad3 Binary files /dev/null and b/sound/instruments/synthesis_samples/guitar/crisis_nylon/c2.ogg differ diff --git a/sound/instruments/synthesis_samples/guitar/crisis_nylon/c3.ogg b/sound/instruments/synthesis_samples/guitar/crisis_nylon/c3.ogg new file mode 100644 index 0000000000..cd6414c0aa Binary files /dev/null and b/sound/instruments/synthesis_samples/guitar/crisis_nylon/c3.ogg differ diff --git a/sound/instruments/synthesis_samples/guitar/crisis_nylon/c4.ogg b/sound/instruments/synthesis_samples/guitar/crisis_nylon/c4.ogg new file mode 100644 index 0000000000..e536601865 Binary files /dev/null and b/sound/instruments/synthesis_samples/guitar/crisis_nylon/c4.ogg differ diff --git a/sound/instruments/synthesis_samples/guitar/crisis_nylon/c5.ogg b/sound/instruments/synthesis_samples/guitar/crisis_nylon/c5.ogg new file mode 100644 index 0000000000..6038222837 Binary files /dev/null and b/sound/instruments/synthesis_samples/guitar/crisis_nylon/c5.ogg differ diff --git a/sound/instruments/synthesis_samples/guitar/crisis_steel/c2.ogg b/sound/instruments/synthesis_samples/guitar/crisis_steel/c2.ogg new file mode 100644 index 0000000000..648549d594 Binary files /dev/null and b/sound/instruments/synthesis_samples/guitar/crisis_steel/c2.ogg differ diff --git a/sound/instruments/synthesis_samples/guitar/crisis_steel/c3.ogg b/sound/instruments/synthesis_samples/guitar/crisis_steel/c3.ogg new file mode 100644 index 0000000000..01ba59a908 Binary files /dev/null and b/sound/instruments/synthesis_samples/guitar/crisis_steel/c3.ogg differ diff --git a/sound/instruments/synthesis_samples/guitar/crisis_steel/c4.ogg b/sound/instruments/synthesis_samples/guitar/crisis_steel/c4.ogg new file mode 100644 index 0000000000..7cfaa8ca72 Binary files /dev/null and b/sound/instruments/synthesis_samples/guitar/crisis_steel/c4.ogg differ diff --git a/sound/instruments/synthesis_samples/guitar/crisis_steel/c5.ogg b/sound/instruments/synthesis_samples/guitar/crisis_steel/c5.ogg new file mode 100644 index 0000000000..b4ca49dc04 Binary files /dev/null and b/sound/instruments/synthesis_samples/guitar/crisis_steel/c5.ogg differ diff --git a/sound/instruments/synthesis_samples/organ/crisis_accordian/c2.ogg b/sound/instruments/synthesis_samples/organ/crisis_accordian/c2.ogg new file mode 100644 index 0000000000..7c9870a7c3 Binary files /dev/null and b/sound/instruments/synthesis_samples/organ/crisis_accordian/c2.ogg differ diff --git a/sound/instruments/synthesis_samples/organ/crisis_accordian/c3.ogg b/sound/instruments/synthesis_samples/organ/crisis_accordian/c3.ogg new file mode 100644 index 0000000000..5723c2edd2 Binary files /dev/null and b/sound/instruments/synthesis_samples/organ/crisis_accordian/c3.ogg differ diff --git a/sound/instruments/synthesis_samples/organ/crisis_accordian/c4.ogg b/sound/instruments/synthesis_samples/organ/crisis_accordian/c4.ogg new file mode 100644 index 0000000000..329f14f6fe Binary files /dev/null and b/sound/instruments/synthesis_samples/organ/crisis_accordian/c4.ogg differ diff --git a/sound/instruments/synthesis_samples/organ/crisis_accordian/c5.ogg b/sound/instruments/synthesis_samples/organ/crisis_accordian/c5.ogg new file mode 100644 index 0000000000..5e8ac69de2 Binary files /dev/null and b/sound/instruments/synthesis_samples/organ/crisis_accordian/c5.ogg differ diff --git a/sound/instruments/synthesis_samples/organ/crisis_church/c2.ogg b/sound/instruments/synthesis_samples/organ/crisis_church/c2.ogg new file mode 100644 index 0000000000..ddc44c69c2 Binary files /dev/null and b/sound/instruments/synthesis_samples/organ/crisis_church/c2.ogg differ diff --git a/sound/instruments/synthesis_samples/organ/crisis_church/c3.ogg b/sound/instruments/synthesis_samples/organ/crisis_church/c3.ogg new file mode 100644 index 0000000000..2855747528 Binary files /dev/null and b/sound/instruments/synthesis_samples/organ/crisis_church/c3.ogg differ diff --git a/sound/instruments/synthesis_samples/organ/crisis_church/c4.ogg b/sound/instruments/synthesis_samples/organ/crisis_church/c4.ogg new file mode 100644 index 0000000000..906fff5bd8 Binary files /dev/null and b/sound/instruments/synthesis_samples/organ/crisis_church/c4.ogg differ diff --git a/sound/instruments/synthesis_samples/organ/crisis_church/c5.ogg b/sound/instruments/synthesis_samples/organ/crisis_church/c5.ogg new file mode 100644 index 0000000000..96d28a7206 Binary files /dev/null and b/sound/instruments/synthesis_samples/organ/crisis_church/c5.ogg differ diff --git a/sound/instruments/synthesis_samples/organ/crisis_hammond/c2.ogg b/sound/instruments/synthesis_samples/organ/crisis_hammond/c2.ogg new file mode 100644 index 0000000000..9b917b7eb5 Binary files /dev/null and b/sound/instruments/synthesis_samples/organ/crisis_hammond/c2.ogg differ diff --git a/sound/instruments/synthesis_samples/organ/crisis_hammond/c3.ogg b/sound/instruments/synthesis_samples/organ/crisis_hammond/c3.ogg new file mode 100644 index 0000000000..c68410d6f0 Binary files /dev/null and b/sound/instruments/synthesis_samples/organ/crisis_hammond/c3.ogg differ diff --git a/sound/instruments/synthesis_samples/organ/crisis_hammond/c4.ogg b/sound/instruments/synthesis_samples/organ/crisis_hammond/c4.ogg new file mode 100644 index 0000000000..df84ba99e8 Binary files /dev/null and b/sound/instruments/synthesis_samples/organ/crisis_hammond/c4.ogg differ diff --git a/sound/instruments/synthesis_samples/organ/crisis_hammond/c5.ogg b/sound/instruments/synthesis_samples/organ/crisis_hammond/c5.ogg new file mode 100644 index 0000000000..af8c178efe Binary files /dev/null and b/sound/instruments/synthesis_samples/organ/crisis_hammond/c5.ogg differ diff --git a/sound/instruments/synthesis_samples/organ/crisis_harmonica/c3.ogg b/sound/instruments/synthesis_samples/organ/crisis_harmonica/c3.ogg new file mode 100644 index 0000000000..268b41f1fc Binary files /dev/null and b/sound/instruments/synthesis_samples/organ/crisis_harmonica/c3.ogg differ diff --git a/sound/instruments/synthesis_samples/organ/crisis_harmonica/c4.ogg b/sound/instruments/synthesis_samples/organ/crisis_harmonica/c4.ogg new file mode 100644 index 0000000000..04ceb54bfc Binary files /dev/null and b/sound/instruments/synthesis_samples/organ/crisis_harmonica/c4.ogg differ diff --git a/sound/instruments/synthesis_samples/organ/crisis_harmonica/c5.ogg b/sound/instruments/synthesis_samples/organ/crisis_harmonica/c5.ogg new file mode 100644 index 0000000000..b321983e74 Binary files /dev/null and b/sound/instruments/synthesis_samples/organ/crisis_harmonica/c5.ogg differ diff --git a/sound/instruments/synthesis_samples/organ/crisis_tangaccordian/c2.ogg b/sound/instruments/synthesis_samples/organ/crisis_tangaccordian/c2.ogg new file mode 100644 index 0000000000..250a5c08e0 Binary files /dev/null and b/sound/instruments/synthesis_samples/organ/crisis_tangaccordian/c2.ogg differ diff --git a/sound/instruments/synthesis_samples/organ/crisis_tangaccordian/c3.ogg b/sound/instruments/synthesis_samples/organ/crisis_tangaccordian/c3.ogg new file mode 100644 index 0000000000..8b1c23007b Binary files /dev/null and b/sound/instruments/synthesis_samples/organ/crisis_tangaccordian/c3.ogg differ diff --git a/sound/instruments/synthesis_samples/organ/crisis_tangaccordian/c4.ogg b/sound/instruments/synthesis_samples/organ/crisis_tangaccordian/c4.ogg new file mode 100644 index 0000000000..098587183b Binary files /dev/null and b/sound/instruments/synthesis_samples/organ/crisis_tangaccordian/c4.ogg differ diff --git a/sound/instruments/synthesis_samples/organ/crisis_tangaccordian/c5.ogg b/sound/instruments/synthesis_samples/organ/crisis_tangaccordian/c5.ogg new file mode 100644 index 0000000000..81b60ef4c2 Binary files /dev/null and b/sound/instruments/synthesis_samples/organ/crisis_tangaccordian/c5.ogg differ diff --git a/sound/instruments/synthesis_samples/piano/crisis_bright_piano/c2.ogg b/sound/instruments/synthesis_samples/piano/crisis_bright_piano/c2.ogg new file mode 100644 index 0000000000..39e992fbd8 Binary files /dev/null and b/sound/instruments/synthesis_samples/piano/crisis_bright_piano/c2.ogg differ diff --git a/sound/instruments/synthesis_samples/piano/crisis_bright_piano/c3.ogg b/sound/instruments/synthesis_samples/piano/crisis_bright_piano/c3.ogg new file mode 100644 index 0000000000..04aa985281 Binary files /dev/null and b/sound/instruments/synthesis_samples/piano/crisis_bright_piano/c3.ogg differ diff --git a/sound/instruments/synthesis_samples/piano/crisis_bright_piano/c4.ogg b/sound/instruments/synthesis_samples/piano/crisis_bright_piano/c4.ogg new file mode 100644 index 0000000000..aff97942e9 Binary files /dev/null and b/sound/instruments/synthesis_samples/piano/crisis_bright_piano/c4.ogg differ diff --git a/sound/instruments/synthesis_samples/piano/crisis_bright_piano/c5.ogg b/sound/instruments/synthesis_samples/piano/crisis_bright_piano/c5.ogg new file mode 100644 index 0000000000..19fd937707 Binary files /dev/null and b/sound/instruments/synthesis_samples/piano/crisis_bright_piano/c5.ogg differ diff --git a/sound/instruments/synthesis_samples/piano/crisis_bright_piano/c6.ogg b/sound/instruments/synthesis_samples/piano/crisis_bright_piano/c6.ogg new file mode 100644 index 0000000000..452e7485be Binary files /dev/null and b/sound/instruments/synthesis_samples/piano/crisis_bright_piano/c6.ogg differ diff --git a/sound/instruments/synthesis_samples/piano/crisis_bright_piano/c7.ogg b/sound/instruments/synthesis_samples/piano/crisis_bright_piano/c7.ogg new file mode 100644 index 0000000000..66c88185a7 Binary files /dev/null and b/sound/instruments/synthesis_samples/piano/crisis_bright_piano/c7.ogg differ diff --git a/sound/instruments/synthesis_samples/piano/crisis_bright_piano/c8.ogg b/sound/instruments/synthesis_samples/piano/crisis_bright_piano/c8.ogg new file mode 100644 index 0000000000..d93c5176ce Binary files /dev/null and b/sound/instruments/synthesis_samples/piano/crisis_bright_piano/c8.ogg differ diff --git a/sound/instruments/synthesis_samples/piano/crisis_grand_piano/c2.ogg b/sound/instruments/synthesis_samples/piano/crisis_grand_piano/c2.ogg new file mode 100644 index 0000000000..fabd90d2e6 Binary files /dev/null and b/sound/instruments/synthesis_samples/piano/crisis_grand_piano/c2.ogg differ diff --git a/sound/instruments/synthesis_samples/piano/crisis_grand_piano/c3.ogg b/sound/instruments/synthesis_samples/piano/crisis_grand_piano/c3.ogg new file mode 100644 index 0000000000..e4cda1487a Binary files /dev/null and b/sound/instruments/synthesis_samples/piano/crisis_grand_piano/c3.ogg differ diff --git a/sound/instruments/synthesis_samples/piano/crisis_grand_piano/c4.ogg b/sound/instruments/synthesis_samples/piano/crisis_grand_piano/c4.ogg new file mode 100644 index 0000000000..c596994b3e Binary files /dev/null and b/sound/instruments/synthesis_samples/piano/crisis_grand_piano/c4.ogg differ diff --git a/sound/instruments/synthesis_samples/piano/crisis_grand_piano/c5.ogg b/sound/instruments/synthesis_samples/piano/crisis_grand_piano/c5.ogg new file mode 100644 index 0000000000..d265514e27 Binary files /dev/null and b/sound/instruments/synthesis_samples/piano/crisis_grand_piano/c5.ogg differ diff --git a/sound/instruments/synthesis_samples/piano/crisis_grand_piano/c6.ogg b/sound/instruments/synthesis_samples/piano/crisis_grand_piano/c6.ogg new file mode 100644 index 0000000000..3e17b3f99a Binary files /dev/null and b/sound/instruments/synthesis_samples/piano/crisis_grand_piano/c6.ogg differ diff --git a/sound/instruments/synthesis_samples/piano/crisis_grand_piano/c7.ogg b/sound/instruments/synthesis_samples/piano/crisis_grand_piano/c7.ogg new file mode 100644 index 0000000000..b57a8a9109 Binary files /dev/null and b/sound/instruments/synthesis_samples/piano/crisis_grand_piano/c7.ogg differ diff --git a/sound/instruments/synthesis_samples/piano/crisis_grand_piano/c8.ogg b/sound/instruments/synthesis_samples/piano/crisis_grand_piano/c8.ogg new file mode 100644 index 0000000000..ce4d9535e8 Binary files /dev/null and b/sound/instruments/synthesis_samples/piano/crisis_grand_piano/c8.ogg differ diff --git a/sound/instruments/synthesis_samples/piano/crisis_harpsichord/c2.ogg b/sound/instruments/synthesis_samples/piano/crisis_harpsichord/c2.ogg new file mode 100644 index 0000000000..bb02363fff Binary files /dev/null and b/sound/instruments/synthesis_samples/piano/crisis_harpsichord/c2.ogg differ diff --git a/sound/instruments/synthesis_samples/piano/crisis_harpsichord/c3.ogg b/sound/instruments/synthesis_samples/piano/crisis_harpsichord/c3.ogg new file mode 100644 index 0000000000..1a532ac8d4 Binary files /dev/null and b/sound/instruments/synthesis_samples/piano/crisis_harpsichord/c3.ogg differ diff --git a/sound/instruments/synthesis_samples/piano/crisis_harpsichord/c4.ogg b/sound/instruments/synthesis_samples/piano/crisis_harpsichord/c4.ogg new file mode 100644 index 0000000000..16ff313baa Binary files /dev/null and b/sound/instruments/synthesis_samples/piano/crisis_harpsichord/c4.ogg differ diff --git a/sound/instruments/synthesis_samples/piano/crisis_harpsichord/c5.ogg b/sound/instruments/synthesis_samples/piano/crisis_harpsichord/c5.ogg new file mode 100644 index 0000000000..04161d2571 Binary files /dev/null and b/sound/instruments/synthesis_samples/piano/crisis_harpsichord/c5.ogg differ diff --git a/sound/instruments/synthesis_samples/piano/fluid_harpsi/C2.ogg b/sound/instruments/synthesis_samples/piano/fluid_harpsi/C2.ogg new file mode 100644 index 0000000000..30a3c653a1 Binary files /dev/null and b/sound/instruments/synthesis_samples/piano/fluid_harpsi/C2.ogg differ diff --git a/sound/instruments/synthesis_samples/piano/fluid_harpsi/C3.ogg b/sound/instruments/synthesis_samples/piano/fluid_harpsi/C3.ogg new file mode 100644 index 0000000000..f6bc891506 Binary files /dev/null and b/sound/instruments/synthesis_samples/piano/fluid_harpsi/C3.ogg differ diff --git a/sound/instruments/synthesis_samples/piano/fluid_harpsi/C4.ogg b/sound/instruments/synthesis_samples/piano/fluid_harpsi/C4.ogg new file mode 100644 index 0000000000..ab47f6940c Binary files /dev/null and b/sound/instruments/synthesis_samples/piano/fluid_harpsi/C4.ogg differ diff --git a/sound/instruments/synthesis_samples/piano/fluid_harpsi/C5.ogg b/sound/instruments/synthesis_samples/piano/fluid_harpsi/C5.ogg new file mode 100644 index 0000000000..5dfb9aa529 Binary files /dev/null and b/sound/instruments/synthesis_samples/piano/fluid_harpsi/C5.ogg differ diff --git a/sound/instruments/synthesis_samples/piano/fluid_harpsi/C6.ogg b/sound/instruments/synthesis_samples/piano/fluid_harpsi/C6.ogg new file mode 100644 index 0000000000..7bc8784207 Binary files /dev/null and b/sound/instruments/synthesis_samples/piano/fluid_harpsi/C6.ogg differ diff --git a/sound/instruments/synthesis_samples/piano/fluid_harpsi/C7.ogg b/sound/instruments/synthesis_samples/piano/fluid_harpsi/C7.ogg new file mode 100644 index 0000000000..185b4d3db6 Binary files /dev/null and b/sound/instruments/synthesis_samples/piano/fluid_harpsi/C7.ogg differ diff --git a/sound/instruments/synthesis_samples/piano/fluid_harpsi/C8.ogg b/sound/instruments/synthesis_samples/piano/fluid_harpsi/C8.ogg new file mode 100644 index 0000000000..f358ef0810 Binary files /dev/null and b/sound/instruments/synthesis_samples/piano/fluid_harpsi/C8.ogg differ diff --git a/sound/instruments/synthesis_samples/piano/fluid_piano/c2.ogg b/sound/instruments/synthesis_samples/piano/fluid_piano/c2.ogg new file mode 100644 index 0000000000..048f9640bf Binary files /dev/null and b/sound/instruments/synthesis_samples/piano/fluid_piano/c2.ogg differ diff --git a/sound/instruments/synthesis_samples/piano/fluid_piano/c3.ogg b/sound/instruments/synthesis_samples/piano/fluid_piano/c3.ogg new file mode 100644 index 0000000000..f1083d7dcb Binary files /dev/null and b/sound/instruments/synthesis_samples/piano/fluid_piano/c3.ogg differ diff --git a/sound/instruments/synthesis_samples/piano/fluid_piano/c4.ogg b/sound/instruments/synthesis_samples/piano/fluid_piano/c4.ogg new file mode 100644 index 0000000000..244ebc3d5f Binary files /dev/null and b/sound/instruments/synthesis_samples/piano/fluid_piano/c4.ogg differ diff --git a/sound/instruments/synthesis_samples/piano/fluid_piano/c5.ogg b/sound/instruments/synthesis_samples/piano/fluid_piano/c5.ogg new file mode 100644 index 0000000000..d3c68d64e9 Binary files /dev/null and b/sound/instruments/synthesis_samples/piano/fluid_piano/c5.ogg differ diff --git a/sound/instruments/synthesis_samples/piano/fluid_piano/c6.ogg b/sound/instruments/synthesis_samples/piano/fluid_piano/c6.ogg new file mode 100644 index 0000000000..2666ee6613 Binary files /dev/null and b/sound/instruments/synthesis_samples/piano/fluid_piano/c6.ogg differ diff --git a/sound/instruments/synthesis_samples/piano/fluid_piano/c7.ogg b/sound/instruments/synthesis_samples/piano/fluid_piano/c7.ogg new file mode 100644 index 0000000000..050e463c0d Binary files /dev/null and b/sound/instruments/synthesis_samples/piano/fluid_piano/c7.ogg differ diff --git a/sound/instruments/synthesis_samples/piano/fluid_piano/c8.ogg b/sound/instruments/synthesis_samples/piano/fluid_piano/c8.ogg new file mode 100644 index 0000000000..4793c5b7fd Binary files /dev/null and b/sound/instruments/synthesis_samples/piano/fluid_piano/c8.ogg differ diff --git a/sound/instruments/synthesis_samples/tones/Sawtooth.ogg b/sound/instruments/synthesis_samples/tones/Sawtooth.ogg new file mode 100644 index 0000000000..10b1930a64 Binary files /dev/null and b/sound/instruments/synthesis_samples/tones/Sawtooth.ogg differ diff --git a/sound/instruments/synthesis_samples/tones/Sine.ogg b/sound/instruments/synthesis_samples/tones/Sine.ogg new file mode 100644 index 0000000000..96a09d501b Binary files /dev/null and b/sound/instruments/synthesis_samples/tones/Sine.ogg differ diff --git a/sound/instruments/synthesis_samples/tones/Square.ogg b/sound/instruments/synthesis_samples/tones/Square.ogg new file mode 100644 index 0000000000..71029c07f9 Binary files /dev/null and b/sound/instruments/synthesis_samples/tones/Square.ogg differ diff --git a/sound/weapons/banjoslap.ogg b/sound/weapons/banjoslap.ogg new file mode 100644 index 0000000000..06a86a535d Binary files /dev/null and b/sound/weapons/banjoslap.ogg differ diff --git a/sound/weapons/stringsmash.ogg b/sound/weapons/stringsmash.ogg new file mode 100644 index 0000000000..1c3e8971dc Binary files /dev/null and b/sound/weapons/stringsmash.ogg differ diff --git a/vorestation.dme b/vorestation.dme index 201d242f47..7b2affc82b 100644 --- a/vorestation.dme +++ b/vorestation.dme @@ -51,6 +51,7 @@ #include "code\__defines\gamemode.dm" #include "code\__defines\holomap.dm" #include "code\__defines\hoses.dm" +#include "code\__defines\instruments.dm" #include "code\__defines\integrated_circuits.dm" #include "code\__defines\inventory_sizes.dm" #include "code\__defines\is_helpers.dm" @@ -300,6 +301,7 @@ #include "code\controllers\subsystems\reflect_ch.dm" #include "code\controllers\subsystems\shuttles.dm" #include "code\controllers\subsystems\skybox.dm" +#include "code\controllers\subsystems\sounds.dm" #include "code\controllers\subsystems\sqlite.dm" #include "code\controllers\subsystems\sun.dm" #include "code\controllers\subsystems\supply.dm" @@ -313,6 +315,7 @@ #include "code\controllers\subsystems\xenoarch.dm" #include "code\controllers\subsystems\processing\bellies_vr.dm" #include "code\controllers\subsystems\processing\fastprocess.dm" +#include "code\controllers\subsystems\processing\instruments.dm" #include "code\controllers\subsystems\processing\obj.dm" #include "code\controllers\subsystems\processing\processing.dm" #include "code\controllers\subsystems\processing\projectiles.dm" @@ -470,6 +473,7 @@ #include "code\datums\supplypacks\misc_vr.dm" #include "code\datums\supplypacks\munitions.dm" #include "code\datums\supplypacks\munitions_vr.dm" +#include "code\datums\supplypacks\musical.dm" #include "code\datums\supplypacks\recreation.dm" #include "code\datums\supplypacks\recreation_vr.dm" #include "code\datums\supplypacks\recreation_yw.dm" @@ -1220,7 +1224,6 @@ #include "code\game\objects\items\devices\gps.dm" #include "code\game\objects\items\devices\hacktool.dm" #include "code\game\objects\items\devices\holowarrant.dm" -#include "code\game\objects\items\devices\instruments.dm" #include "code\game\objects\items\devices\laserpointer.dm" #include "code\game\objects\items\devices\lightreplacer.dm" #include "code\game\objects\items\devices\megaphone.dm" @@ -1245,7 +1248,6 @@ #include "code\game\objects\items\devices\tvcamera.dm" #include "code\game\objects\items\devices\uplink.dm" #include "code\game\objects\items\devices\uplink_random_lists.dm" -#include "code\game\objects\items\devices\violin.dm" #include "code\game\objects\items\devices\whistle.dm" #include "code\game\objects\items\devices\communicator\cartridge.dm" #include "code\game\objects\items\devices\communicator\communicator.dm" @@ -1540,7 +1542,6 @@ #include "code\game\objects\structures\mop_bucket.dm" #include "code\game\objects\structures\morgue.dm" #include "code\game\objects\structures\morgue_vr.dm" -#include "code\game\objects\structures\musician.dm" #include "code\game\objects\structures\new_signs.dm" #include "code\game\objects\structures\plasticflaps.dm" #include "code\game\objects\structures\railing.dm" @@ -2532,6 +2533,23 @@ #include "code\modules\hydroponics\trays\tray_update_icons.dm" #include "code\modules\identification\identification.dm" #include "code\modules\identification\item_procs.dm" +#include "code\modules\instruments\items.dm" +#include "code\modules\instruments\items_ch.dm" +#include "code\modules\instruments\stationary.dm" +#include "code\modules\instruments\instrument_data\_instrument_data.dm" +#include "code\modules\instruments\instrument_data\_instrument_key.dm" +#include "code\modules\instruments\instrument_data\brass.dm" +#include "code\modules\instruments\instrument_data\chromatic_percussion.dm" +#include "code\modules\instruments\instrument_data\fun.dm" +#include "code\modules\instruments\instrument_data\guitar.dm" +#include "code\modules\instruments\instrument_data\hardcoded.dm" +#include "code\modules\instruments\instrument_data\organ.dm" +#include "code\modules\instruments\instrument_data\piano.dm" +#include "code\modules\instruments\instrument_data\synth_tones.dm" +#include "code\modules\instruments\songs\_song.dm" +#include "code\modules\instruments\songs\editor.dm" +#include "code\modules\instruments\songs\play_legacy.dm" +#include "code\modules\instruments\songs\play_synthesized.dm" #include "code\modules\integrated_electronics\_defines.dm" #include "code\modules\integrated_electronics\core\assemblies.dm" #include "code\modules\integrated_electronics\core\detailer.dm"