diff --git a/code/__defines/atoms_movable.dm b/code/__defines/atoms_movable.dm index 6d8b3c4569..634d92c2a7 100644 --- a/code/__defines/atoms_movable.dm +++ b/code/__defines/atoms_movable.dm @@ -2,6 +2,10 @@ ** Holds defines for code\game\atoms_movable.dm to avoid magic numbers and potential unexpected overwrites down the line */ +#define NON_LISTENING_ATOM 0 +#define LISTENING_ATOM 1 +#define LISTENING_PLAYER 2 + #define DEFAULT_ICON_SCALE_X 1 #define DEFAULT_ICON_SCALE_Y 1 #define DEFAULT_ICON_ROTATION 0 diff --git a/code/__defines/misc.dm b/code/__defines/misc.dm index 362d72ecf2..e0411079ee 100644 --- a/code/__defines/misc.dm +++ b/code/__defines/misc.dm @@ -80,8 +80,7 @@ #define WAIT_FINISH 4 #define DO_AUTOPILOT 5 -// Setting this much higher than 1024 could allow spammers to DOS the server easily. -#define MAX_MESSAGE_LEN 4096 //VOREStation Edit - I'm not sure about "easily". It can be a little longer. +#define MAX_MESSAGE_LEN 4096 #define MAX_PAPER_MESSAGE_LEN 6144 #define MAX_BOOK_MESSAGE_LEN 24576 #define MAX_RECORD_LENGTH 24576 @@ -269,15 +268,15 @@ // Second argument is the path the list is expected to contain. Note that children will also get added to the global list. // If the GLOB system is ever ported, you can change this macro in one place and have less work to do than you otherwise would. #define GLOBAL_LIST_BOILERPLATE(LIST_NAME, PATH)\ -var/global/list/##LIST_NAME = list();\ +GLOBAL_LIST_EMPTY(##LIST_NAME);\ ##PATH/Initialize(mapload, ...)\ {\ - ##LIST_NAME += src;\ + GLOB.##LIST_NAME += src;\ return ..();\ }\ ##PATH/Destroy(force, ...)\ {\ - ##LIST_NAME -= src;\ + GLOB.##LIST_NAME -= src;\ return ..();\ }\ @@ -444,6 +443,13 @@ var/global/list/##LIST_NAME = list();\ #define VOLUME_CHANNEL_VORE "Vore" #define VOLUME_CHANNEL_DOORS "Doors" #define VOLUME_CHANNEL_INSTRUMENTS "Instruments" +#define VOLUME_CHANNEL_WEATHER "Weather" +#define VOLUME_CHANNEL_SPECIES_SOUNDS "Species Sounds (Verbal Injury Feedback)" +#define VOLUME_CHANNEL_HUD_WARNINGS "SS13 HUD (Clientside-only sounds)" //NYI +#define VOLUME_CHANNEL_DEATH_SOUNDS "Death Sounds" +#define VOLUME_CHANNEL_INJURY_SOUNDS "Mob Injury Sounds (Non-Verbal Feedback)" //NYI +#define VOLUME_CHANNEL_MACHINERY "Machinery Noises" +#define VOLUME_CHANNEL_MACHINERY_IDLE "Machinery Idle Noises" // Make sure you update this or clients won't be able to adjust the channel GLOBAL_LIST_INIT(all_volume_channels, list( @@ -452,7 +458,14 @@ GLOBAL_LIST_INIT(all_volume_channels, list( VOLUME_CHANNEL_ALARMS, VOLUME_CHANNEL_VORE, VOLUME_CHANNEL_DOORS, - VOLUME_CHANNEL_INSTRUMENTS + VOLUME_CHANNEL_INSTRUMENTS, + VOLUME_CHANNEL_WEATHER, + VOLUME_CHANNEL_SPECIES_SOUNDS, + VOLUME_CHANNEL_HUD_WARNINGS, + VOLUME_CHANNEL_DEATH_SOUNDS, + VOLUME_CHANNEL_INJURY_SOUNDS, + VOLUME_CHANNEL_MACHINERY, + VOLUME_CHANNEL_MACHINERY_IDLE )) #define APPEARANCECHANGER_CHANGED_RACE "Race" diff --git a/code/_helpers/game.dm b/code/_helpers/game.dm index f0cd6a8e9b..8d969f45af 100644 --- a/code/_helpers/game.dm +++ b/code/_helpers/game.dm @@ -68,6 +68,7 @@ return heard + /proc/isStationLevel(var/level) return level in using_map.station_levels @@ -218,25 +219,22 @@ return hear - /proc/get_mobs_in_radio_ranges(var/list/obj/item/radio/radios) . = list() // Returns a list of mobs who can hear any of the radios given in @radios - var/list/speaker_coverage = list() for(var/obj/item/radio/R as anything in radios) - var/turf/speaker = get_turf(R) - if(speaker) - for(var/turf/T in hear(R.canhear_range,speaker)) - speaker_coverage[T] = R + if(get_turf(R)) + for(var/turf/T in R.can_broadcast_to()) + for (var/atom/movable/hearing in T) + if (hearing.recursive_listeners) + . |= hearing.recursive_listeners - - // Try to find all the players who can hear the message - for(var/i = 1; i <= player_list.len; i++) - var/mob/M = player_list[i] - if(M.can_hear_radio(speaker_coverage)) - . += M - return . + for (var/mob/M as anything in .) + if (!istype(M) || !M.client) + . -= M + for (var/mob/observer/O in player_list) + . |= O /mob/proc/can_hear_radio(var/list/hearturfs) return FALSE diff --git a/code/coalesce.dm b/code/coalesce.dm new file mode 100644 index 0000000000..2d40ccff9c --- /dev/null +++ b/code/coalesce.dm @@ -0,0 +1,5 @@ +/proc/coalesce(...) + for (var/arg in args) + if (arg) + return arg + return null diff --git a/code/controllers/subsystems/plants.dm b/code/controllers/subsystems/plants.dm index 3f278da422..dbcc40e8f9 100644 --- a/code/controllers/subsystems/plants.dm +++ b/code/controllers/subsystems/plants.dm @@ -71,7 +71,7 @@ SUBSYSTEM_DEF(plants) // Make sure any seed packets that were mapped in are updated // correctly (since the seed datums did not exist a tick ago). - for(var/obj/item/seeds/S in all_seed_packs) + for(var/obj/item/seeds/S in GLOB.all_seed_packs) S.update_seed() //Might as well mask the gene types while we're at it. diff --git a/code/datums/looping_sounds/_looping_sound.dm b/code/datums/looping_sounds/_looping_sound.dm index d842dd8336..e00e495ae3 100644 --- a/code/datums/looping_sounds/_looping_sound.dm +++ b/code/datums/looping_sounds/_looping_sound.dm @@ -34,6 +34,7 @@ var/opacity_check var/pref_check var/exclusive + var/volume_chan var/timerid var/started diff --git a/code/datums/looping_sounds/weather_sounds.dm b/code/datums/looping_sounds/weather_sounds.dm index 41210df105..f893f20a19 100644 --- a/code/datums/looping_sounds/weather_sounds.dm +++ b/code/datums/looping_sounds/weather_sounds.dm @@ -1,5 +1,6 @@ /datum/looping_sound/weather pref_check = /datum/preference/toggle/weather_sounds + volume_chan = VOLUME_CHANNEL_WEATHER /datum/looping_sound/weather/outside_blizzard mid_sounds = list( diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm index 2f9946c9e7..1c855aa9ee 100644 --- a/code/game/atoms_movable.dm +++ b/code/game/atoms_movable.dm @@ -31,6 +31,8 @@ var/image/cloaked_selfimage //The image we use for our client to let them see where we are var/belly_cycles = 0 // Counting current belly process cycles for autotransfer. var/autotransferable = TRUE // Toggle for autotransfer mechanics. + var/recursive_listeners + var/listening_recursive = NON_LISTENING_ATOM /atom/movable/Initialize(mapload) . = ..() @@ -57,6 +59,9 @@ AddComponent(/datum/component/overlay_lighting, starts_on = light_on) if(MOVABLE_LIGHT_DIRECTIONAL) AddComponent(/datum/component/overlay_lighting, is_directional = TRUE, starts_on = light_on) + if (listening_recursive) + set_listening(listening_recursive) + /atom/movable/Destroy() if(em_block) @@ -84,7 +89,8 @@ if(orbiting) stop_orbit() - QDEL_NULL(riding_datum) //VOREStation Add + QDEL_NULL(riding_datum) + set_listening(NON_LISTENING_ATOM) /atom/movable/vv_edit_var(var_name, var_value) if(var_name in GLOB.VVpixelmovement) //Pixel movement is not yet implemented, changing this will break everything irreversibly. @@ -674,3 +680,45 @@ /atom/movable/proc/exit_belly(obj/belly/B) return + +/atom/movable/proc/set_listening(var/set_to) + if (listening_recursive && !set_to) + LAZYREMOVE(recursive_listeners, src) + if (!LAZYLEN(recursive_listeners)) + for (var/atom/movable/location as anything in get_nested_locs(src)) + LAZYREMOVE(location.recursive_listeners, src) + if (!listening_recursive && set_to) + LAZYOR(recursive_listeners, src) + for (var/atom/movable/location as anything in get_nested_locs(src)) + LAZYOR(location.recursive_listeners, src) + listening_recursive = set_to + +///Returns a list of all locations (except the area) the movable is within. +/proc/get_nested_locs(atom/movable/atom_on_location, include_turf = FALSE) + . = list() + var/atom/location = atom_on_location.loc + var/turf/our_turf = get_turf(atom_on_location) + while(location && location != our_turf) + . += location + location = location.loc + if(our_turf && include_turf) //At this point, only the turf is left, provided it exists. + . += our_turf + +/atom/movable/Exited(atom/movable/gone, atom/new_loc) + . = ..() + + if (!LAZYLEN(gone.recursive_listeners)) + return + for (var/atom/movable/location as anything in get_nested_locs(src)|src) + LAZYREMOVE(location.recursive_listeners, gone.recursive_listeners) + +/atom/movable/Entered(atom/movable/arrived, atom/old_loc) + . = ..() + + if (!LAZYLEN(arrived.recursive_listeners)) + return + for (var/atom/movable/location as anything in get_nested_locs(src)|src) + LAZYOR(location.recursive_listeners, arrived.recursive_listeners) + +/atom/movable/proc/show_message(msg, type, alt, alt_type)//Message, type of message (1 or 2), alternative message, alt message type (1 or 2) + return diff --git a/code/game/machinery/computer/ai_core.dm b/code/game/machinery/computer/ai_core.dm index e9f8800bbf..21880fda24 100644 --- a/code/game/machinery/computer/ai_core.dm +++ b/code/game/machinery/computer/ai_core.dm @@ -265,7 +265,7 @@ GLOBAL_LIST_BOILERPLATE(all_deactivated_AI_cores, /obj/structure/AIcore/deactiva set category = "Admin.Silicon" var/list/cores = list() - for(var/obj/structure/AIcore/deactivated/D in all_deactivated_AI_cores) + for(var/obj/structure/AIcore/deactivated/D in GLOB.all_deactivated_AI_cores) cores["[D] ([D.loc.loc])"] = D var/id = tgui_input_list(usr, "Which core?", "Toggle AI Core Latejoin", cores) diff --git a/code/game/machinery/computer/prisoner.dm b/code/game/machinery/computer/prisoner.dm index 96c73dde76..a3f03dcd9c 100644 --- a/code/game/machinery/computer/prisoner.dm +++ b/code/game/machinery/computer/prisoner.dm @@ -33,7 +33,7 @@ var/list/chemImplants = list() var/list/trackImplants = list() if(screen) - for(var/obj/item/implant/chem/C in all_chem_implants) + for(var/obj/item/implant/chem/C in GLOB.all_chem_implants) var/turf/T = get_turf(C) if(!T) continue @@ -44,7 +44,7 @@ "units" = C.reagents.total_volume, "ref" = "\ref[C]" ))) - for(var/obj/item/implant/tracking/track in all_tracking_implants) + for(var/obj/item/implant/tracking/track in GLOB.all_tracking_implants) var/turf/T = get_turf(track) if(!T) continue diff --git a/code/game/machinery/doors/brigdoors.dm b/code/game/machinery/doors/brigdoors.dm index 06a57d1099..4697c98675 100644 --- a/code/game/machinery/doors/brigdoors.dm +++ b/code/game/machinery/doors/brigdoors.dm @@ -49,7 +49,7 @@ if(F.id == id) LAZYADD(targets,F) - for(var/obj/structure/closet/secure_closet/brig/C in all_brig_closets) + for(var/obj/structure/closet/secure_closet/brig/C in GLOB.all_brig_closets) if(C.id == id) LAZYADD(targets,C) diff --git a/code/game/machinery/newscaster.dm b/code/game/machinery/newscaster.dm index 0c2e10ce8f..fd9f20f43f 100644 --- a/code/game/machinery/newscaster.dm +++ b/code/game/machinery/newscaster.dm @@ -99,7 +99,7 @@ alert_readers(FC.announcement) /datum/feed_network/proc/alert_readers(var/annoncement) - for(var/obj/machinery/newscaster/NEWSCASTER in allCasters) + for(var/obj/machinery/newscaster/NEWSCASTER in GLOB.allCasters) NEWSCASTER.newsAlert(annoncement) NEWSCASTER.update_icon() @@ -173,7 +173,7 @@ GLOBAL_LIST_BOILERPLATE(allCasters, /obj/machinery/newscaster) /obj/machinery/newscaster/Initialize(mapload) ..() - allCasters += src + GLOB.allCasters += src unit_no = ++unit_no_cur paper_remaining = 15 update_icon() @@ -184,7 +184,7 @@ GLOBAL_LIST_BOILERPLATE(allCasters, /obj/machinery/newscaster) update_icon() /obj/machinery/newscaster/Destroy() - allCasters -= src + GLOB.allCasters -= src node = null return ..() @@ -541,7 +541,7 @@ GLOBAL_LIST_BOILERPLATE(allCasters, /obj/machinery/newscaster) var/choice = tgui_alert(ui.user, "Please confirm Wanted Issue removal","Network Security Handler",list("Confirm","Cancel")) if(choice=="Confirm") news_network.wanted_issue = null - for(var/obj/machinery/newscaster/NEWSCASTER in allCasters) + for(var/obj/machinery/newscaster/NEWSCASTER in GLOB.allCasters) NEWSCASTER.update_icon() set_temp("Wanted issue taken down.", "success", FALSE) return TRUE diff --git a/code/game/machinery/pointdefense.dm b/code/game/machinery/pointdefense.dm index d17bad63f7..edaf6e2625 100644 --- a/code/game/machinery/pointdefense.dm +++ b/code/game/machinery/pointdefense.dm @@ -22,7 +22,7 @@ GLOBAL_LIST_BOILERPLATE(pointdefense_turrets, /obj/machinery/power/pointdefense) . = ..() if(id_tag) //No more than 1 controller please. - for(var/obj/machinery/pointdefense_control/PC as anything in pointdefense_controllers) + for(var/obj/machinery/pointdefense_control/PC as anything in GLOB.pointdefense_controllers) if(PC != src && PC.id_tag == id_tag) warning("Two [src] with the same id_tag of [id_tag]") id_tag = null @@ -72,8 +72,8 @@ GLOBAL_LIST_BOILERPLATE(pointdefense_turrets, /obj/machinery/power/pointdefense) var/list/turrets = list() if(id_tag) var/list/connected_z_levels = GetConnectedZlevels(get_z(src)) - for(var/i = 1 to LAZYLEN(pointdefense_turrets)) - var/obj/machinery/power/pointdefense/PD = pointdefense_turrets[i] + for(var/i = 1 to LAZYLEN(GLOB.pointdefense_turrets)) + var/obj/machinery/power/pointdefense/PD = GLOB.pointdefense_turrets[i] if(!(PD.id_tag == id_tag && (get_z(PD) in connected_z_levels))) continue var/list/turret = list() @@ -95,7 +95,7 @@ GLOBAL_LIST_BOILERPLATE(pointdefense_turrets, /obj/machinery/power/pointdefense) new_ident = sanitize(new_ident,MAX_NAME_LEN) if(new_ident && new_ident != id_tag && user.Adjacent(src) && CanInteract(user, GLOB.tgui_physical_state)) // Check for duplicate controllers with this ID - for(var/obj/machinery/pointdefense_control/PC as anything in pointdefense_controllers) + for(var/obj/machinery/pointdefense_control/PC as anything in GLOB.pointdefense_controllers) if(PC != src && PC.id_tag == id_tag) to_chat(user, span_warning("The [new_ident] network already has a controller.")) return @@ -200,7 +200,7 @@ GLOBAL_LIST_BOILERPLATE(pointdefense_turrets, /obj/machinery/power/pointdefense) if(!id_tag) return null var/list/connected_z_levels = GetConnectedZlevels(get_z(src)) - for(var/obj/machinery/pointdefense_control/PDC as anything in pointdefense_controllers) + for(var/obj/machinery/pointdefense_control/PDC as anything in GLOB.pointdefense_controllers) if(PDC.id_tag == id_tag && (get_z(PDC) in connected_z_levels)) return PDC diff --git a/code/game/machinery/syndicatebeacon.dm b/code/game/machinery/syndicatebeacon.dm index e02a530974..04513432e8 100644 --- a/code/game/machinery/syndicatebeacon.dm +++ b/code/game/machinery/syndicatebeacon.dm @@ -92,7 +92,7 @@ if(user) to_chat(user, span_notice("The connected wire doesn't have enough current.")) return - for(var/obj/singularity/singulo in all_singularities) + for(var/obj/singularity/singulo in GLOB.all_singularities) if(singulo.z == z) singulo.target = src icon_state = "[icontype]1" @@ -102,7 +102,7 @@ to_chat(user, span_notice("You activate the beacon.")) /obj/machinery/power/singularity_beacon/proc/Deactivate(mob/user = null) - for(var/obj/singularity/singulo in all_singularities) + for(var/obj/singularity/singulo in GLOB.all_singularities) if(singulo.target == src) singulo.target = null icon_state = "[icontype]0" diff --git a/code/game/objects/items/devices/radio/radio.dm b/code/game/objects/items/devices/radio/radio.dm index da9c2f0556..746af7fa58 100644 --- a/code/game/objects/items/devices/radio/radio.dm +++ b/code/game/objects/items/devices/radio/radio.dm @@ -1,5 +1,5 @@ +#define CANBROADCAST_INNERBOX 0.7071067811865476 //This is sqrt(2)/2 // Access check is of the type requires one. These have been carefully selected to avoid allowing the janitor to see channels he shouldn't -//VOREStation Edit Start - Updating this for Virgo var/global/list/default_internal_channels = list( num2text(PUB_FREQ) = list(), num2text(AI_FREQ) = list(access_synth), @@ -14,7 +14,7 @@ var/global/list/default_internal_channels = list( num2text(SCI_FREQ) = list(access_tox, access_robotics, access_xenobiology), num2text(SUP_FREQ) = list(access_cargo, access_mining_station), num2text(SRV_FREQ) = list(access_janitor, access_library, access_hydroponics, access_bar, access_kitchen), - num2text(EXP_FREQ) = list(access_explorer) //VOREStation Edit + num2text(EXP_FREQ) = list(access_explorer) ) var/global/list/default_medbay_channels = list( @@ -22,7 +22,6 @@ var/global/list/default_medbay_channels = list( num2text(MED_FREQ) = list(), num2text(MED_I_FREQ) = list() ) -//VOREStation Edit End /obj/item/radio icon = 'icons/obj/radio_vr.dmi' @@ -298,7 +297,7 @@ var/global/list/default_medbay_channels = list( GLOBAL_DATUM(autospeaker, /mob/living/silicon/ai/announcer) -/obj/item/radio/proc/autosay(var/message, var/from, var/channel, var/list/zlevels, var/states) //VOREStation Edit +/obj/item/radio/proc/autosay(var/message, var/from, var/channel, var/list/zlevels, var/states) if(!GLOB.autospeaker) return @@ -315,15 +314,13 @@ GLOBAL_DATUM(autospeaker, /mob/living/silicon/ai/announcer) if(!LAZYLEN(zlevels)) zlevels = list(0) - //VOREStation Edit Start if(!states) states = "states" - //VOREStation Edit End GLOB.autospeaker.SetName(from) Broadcast_Message(connection, GLOB.autospeaker, 0, "*garbled automated announcement*", src, message_to_multilingual(message, GLOB.all_languages[LANGUAGE_GALCOM]), from, "Automated Announcement", from, "synthesized voice", - DATA_FAKE, 0, zlevels, connection.frequency, states) //VOREStation Edit + DATA_FAKE, 0, zlevels, connection.frequency, states) // Interprets the message mode when talking into a radio, possibly returning a connection datum /obj/item/radio/proc/handle_message_mode(mob/living/M as mob, list/message_pieces, message_mode) @@ -769,3 +766,78 @@ GLOBAL_DATUM(autospeaker, /mob/living/silicon/ai/announcer) /obj/item/radio/phone/medbay/Initialize(mapload) . = ..() internal_channels = default_medbay_channels.Copy() + +/obj/item/radio/proc/can_broadcast_to() + var/list/output = list() + var/turf/T = get_turf(src) + var/dnumber = canhear_range*CANBROADCAST_INNERBOX + for(var/cand_x = max(0, T.x - canhear_range), cand_x <= T.x + canhear_range, cand_x++) + for(var/cand_y = max(0, T.y - canhear_range), cand_y <= T.y + canhear_range, cand_y++) + var/turf/cand_turf = locate(cand_x,cand_y,T.z) + if(!cand_turf) + continue + if((abs(T.x - cand_x) < dnumber) || (abs(T.y - cand_y) < dnumber)) + output += cand_turf + continue + if(sqrt((T.x - cand_x)**2 + (T.y - cand_y)**2) <= canhear_range) + output += cand_turf + continue + return output +/obj/item/radio/intercom + var/list/broadcast_tiles + +/obj/item/radio/intercom/proc/update_broadcast_tiles() + var/list/output = list() + var/turf/T = get_turf(src) + if(!T) + return + var/dnumber = canhear_range*CANBROADCAST_INNERBOX + for(var/cand_x = max(0, T.x - canhear_range), cand_x <= T.x + canhear_range, cand_x++) + for(var/cand_y = max(0, T.y - canhear_range), cand_y <= T.y + canhear_range, cand_y++) + var/turf/cand_turf = locate(cand_x,cand_y,T.z) + if(!cand_turf) + continue + if((abs(T.x - cand_x) < dnumber) || (abs(T.y - cand_y) < dnumber)) + output += cand_turf + continue + if(sqrt((T.x - cand_x)**2 + (T.y - cand_y)**2) <= canhear_range) + output += cand_turf + continue + broadcast_tiles = output + +/obj/item/radio/intercom/forceMove(atom/destination) + . = ..() + update_broadcast_tiles() + +/obj/item/radio/intercom/Initialize(mapload) + . = ..() + update_broadcast_tiles() + +/obj/item/radio/intercom/can_broadcast_to() + if(!broadcast_tiles) + update_broadcast_tiles() + return broadcast_tiles + +//*Subspace Radio*// +/obj/item/radio/subspace + adhoc_fallback = 1 + canhear_range = 8 + desc = "A heavy duty radio that can pick up all manor of shortwave and subspace frequencies. It's a bit bulkier than a normal radio thanks to the extra hardware." + description_info = "This radio can broadcast over any headset frequency that the user has access to. It has a shortwave fallback to directly broadcast to all radio equipment on the same Z-Level/Map in the event of a telecommunications failure. This device requires a functioning Telecommunications Network/Relay to send and receive signals meant for headsets. Additionally, the volume knob seems to be stuck on the max setting. You could hear this thing clear across a room... Not good for discretely listening in on secure channels or being stealthy!" + icon_state = "radio" + name = "subspace radio" + subspace_transmission = 1 + throwforce = 5 + throw_range = 7 + throw_speed = 1 + +//* Bluespace Radio *// +/obj/item/bluespaceradio/southerncross_prelinked + name = "bluespace radio (southerncross)" + handset = /obj/item/radio/bluespacehandset/linked/southerncross_prelinked + +/obj/item/radio/bluespacehandset/linked/southerncross_prelinked + bs_tx_preload_id = "Receiver A" //Transmit to a receiver + bs_rx_preload_id = "Broadcaster A" //Recveive from a transmitter + +#undef CANBROADCAST_INNERBOX diff --git a/code/game/objects/items/devices/translocator_vr.dm b/code/game/objects/items/devices/translocator_vr.dm index 9eec1ba589..233744c69e 100644 --- a/code/game/objects/items/devices/translocator_vr.dm +++ b/code/game/objects/items/devices/translocator_vr.dm @@ -116,7 +116,7 @@ /obj/item/perfect_tele/attack_self(mob/user, var/radial_menu_anchor = src) if(loc_network) - for(var/obj/item/perfect_tele_beacon/stationary/nb in premade_tele_beacons) + for(var/obj/item/perfect_tele_beacon/stationary/nb in GLOB.premade_tele_beacons) if(nb.tele_network == loc_network) beacons[nb.tele_name] = nb loc_network = null //Consumed diff --git a/code/game/objects/items/weapons/teleportation.dm b/code/game/objects/items/weapons/teleportation.dm index fa03a626e2..c0dd107cda 100644 --- a/code/game/objects/items/weapons/teleportation.dm +++ b/code/game/objects/items/weapons/teleportation.dm @@ -61,7 +61,7 @@ Frequency: if (sr) src.temp += span_bold("Located Beacons:") + "
" - for(var/obj/item/radio/beacon/W in all_beacons) + for(var/obj/item/radio/beacon/W in GLOB.all_beacons) if (W.frequency == src.frequency) var/turf/tr = get_turf(W) if (tr.z == sr.z && tr) @@ -79,7 +79,7 @@ Frequency: src.temp += "[W.code]-[dir2text(get_dir(sr, tr))]-[direct]
" src.temp += span_bold("Extraneous Signals:") + "
" - for (var/obj/item/implant/tracking/W in all_tracking_implants) + for (var/obj/item/implant/tracking/W in GLOB.all_tracking_implants) if (!W.implanted || !(istype(W.loc,/obj/item/organ/external) || ismob(W.loc) || W.malfunction)) continue @@ -168,7 +168,7 @@ Frequency: if ((user.get_active_hand() != src || user.stat || user.restrained())) return var/count = 0 //num of portals from this teleport in world - for(var/obj/effect/portal/PO in all_portals) + for(var/obj/effect/portal/PO in GLOB.all_portals) if(PO.creator == src) count++ if(count >= 3) user.show_message(span_notice("\The [src] is recharging!")) diff --git a/code/game/objects/objs.dm b/code/game/objects/objs.dm index 7da409041d..9a232296e5 100644 --- a/code/game/objects/objs.dm +++ b/code/game/objects/objs.dm @@ -186,9 +186,6 @@ /obj/proc/see_emote(mob/M as mob, text, var/emote_type) return -/obj/proc/show_message(msg, type, alt, alt_type)//Message, type of message (1 or 2), alternative message, alt message type (1 or 2) - return - // Used to mark a turf as containing objects that are dangerous to step onto. /obj/proc/register_dangerous_to_step() var/turf/T = get_turf(src) diff --git a/code/game/objects/structures/morgue.dm b/code/game/objects/structures/morgue.dm index 97fc49c33c..25fbdb9fdb 100644 --- a/code/game/objects/structures/morgue.dm +++ b/code/game/objects/structures/morgue.dm @@ -343,7 +343,7 @@ GLOBAL_LIST_BOILERPLATE(all_crematoriums, /obj/structure/morgue/crematorium) if(..()) return if(src.allowed(user)) - for (var/obj/structure/morgue/crematorium/C in all_crematoriums) + for (var/obj/structure/morgue/crematorium/C in GLOB.all_crematoriums) if (C.id == id) if (!C.cremating) C.cremate(user) diff --git a/code/game/sound.dm b/code/game/sound.dm index c9b48f619c..63266b2939 100644 --- a/code/game/sound.dm +++ b/code/game/sound.dm @@ -302,6 +302,10 @@ 'sound/items/pickup/generic1.ogg', 'sound/items/pickup/generic2.ogg', 'sound/items/pickup/generic3.ogg') + if ("powerloaderstep") + soundin = pick( + 'sound/effects/mech/powerloader_step.ogg', + 'sound/effects/mech/powerloader_step2.ogg') return soundin //Are these even used? //Yes @@ -323,3 +327,135 @@ GLOBAL_LIST_INIT(goon_speak_pug_sound, list('sound/talksounds/goon/pug.ogg', 'so GLOBAL_LIST_INIT(goon_speak_pugg_sound, list('sound/talksounds/goon/pugg.ogg', 'sound/talksounds/goon/pugg_ask.ogg', 'sound/talksounds/goon/pugg_exclaim.ogg')) GLOBAL_LIST_INIT(goon_speak_roach_sound, list('sound/talksounds/goon/roach.ogg', 'sound/talksounds/goon/roach_ask.ogg', 'sound/talksounds/goon/roach_exclaim.ogg')) GLOBAL_LIST_INIT(goon_speak_skelly_sound, list('sound/talksounds/goon/skelly.ogg', 'sound/talksounds/goon/skelly_ask.ogg', 'sound/talksounds/goon/skelly_exclaim.ogg')) + + +#define canine_sounds list("cough" = null, "sneeze" = null, "scream" = list('sound/voice/scream/canine/wolf_scream.ogg', 'sound/voice/scream/canine/wolf_scream2.ogg', 'sound/voice/scream/canine/wolf_scream3.ogg', 'sound/voice/scream/canine/wolf_scream4.ogg', 'sound/voice/scream/canine/wolf_scream5.ogg', 'sound/voice/scream/canine/wolf_scream6.ogg'), "pain" = list('sound/voice/pain/canine/wolf_pain.ogg', 'sound/voice/pain/canine/wolf_pain2.ogg', 'sound/voice/pain/canine/wolf_pain3.ogg', 'sound/voice/pain/canine/wolf_pain4.ogg'), "gasp" = list('sound/voice/gasp/canine/wolf_gasp.ogg'), "death" = list('sound/voice/death/canine/wolf_death1.ogg', 'sound/voice/death/canine/wolf_death2.ogg', 'sound/voice/death/canine/wolf_death3.ogg', 'sound/voice/death/canine/wolf_death4.ogg', 'sound/voice/death/canine/wolf_death5.ogg')) +#define feline_sounds list("cough" = null, "sneeze" = null, "scream" = list('sound/voice/scream/feline/feline_scream.ogg'), "pain" = list('sound/voice/pain/feline/feline_pain.ogg'), "gasp" = list('sound/voice/gasp/feline/feline_gasp.ogg'), "death" = list('sound/voice/death/feline/feline_death.ogg')) +#define cervine_sounds list("cough" = null, "sneeze" = null, "scream" = list('sound/voice/scream/cervine/cervine_scream.ogg'), "pain" = null, "gasp" = null, "death" = list('sound/voice/death/cervine/cervine_death.ogg')) +#define robot_sounds list("cough" = list('sound/effects/mob_effects/m_machine_cougha.ogg', 'sound/effects/mob_effects/m_machine_coughb.ogg', 'sound/effects/mob_effects/m_machine_coughc.ogg'), "sneeze" = list('sound/effects/mob_effects/machine_sneeze.ogg'), "scream" = list('sound/voice/scream_silicon.ogg', 'sound/voice/android_scream.ogg', 'sound/voice/scream/robotic/robot_scream1.ogg', 'sound/voice/scream/robotic/robot_scream2.ogg', 'sound/voice/scream/robotic/robot_scream3.ogg'), "pain" = list('sound/voice/pain/robotic/robot_pain1.ogg', 'sound/voice/pain/robotic/robot_pain2.ogg', 'sound/voice/pain/robotic/robot_pain3.ogg'), "gasp" = null, "death" = list('sound/voice/borg_deathsound.ogg')) +#define male_generic_sounds list("cough" = list('sound/effects/mob_effects/m_cougha.ogg','sound/effects/mob_effects/m_coughb.ogg', 'sound/effects/mob_effects/m_coughc.ogg'), "sneeze" = list('sound/effects/mob_effects/sneeze.ogg'), "scream" = list('sound/voice/scream/generic/male/male_scream_1.ogg', 'sound/voice/scream/generic/male/male_scream_2.ogg', 'sound/voice/scream/generic/male/male_scream_3.ogg', 'sound/voice/scream/generic/male/male_scream_4.ogg', 'sound/voice/scream/generic/male/male_scream_5.ogg', 'sound/voice/scream/generic/male/male_scream_6.ogg'), "pain" = list('sound/voice/pain/generic/male/male_pain_1.ogg', 'sound/voice/pain/generic/male/male_pain_2.ogg', 'sound/voice/pain/generic/male/male_pain_3.ogg', 'sound/voice/pain/generic/male/male_pain_4.ogg', 'sound/voice/pain/generic/male/male_pain_5.ogg', 'sound/voice/pain/generic/male/male_pain_6.ogg', 'sound/voice/pain/generic/male/male_pain_7.ogg', 'sound/voice/pain/generic/male/male_pain_8.ogg'), "gasp" = list('sound/voice/gasp/generic/male/male_gasp1.ogg', 'sound/voice/gasp/generic/male/male_gasp2.ogg', 'sound/voice/gasp/generic/male/male_gasp3.ogg'), "death" = list('sound/voice/death/generic/male/male_death_1.ogg', 'sound/voice/death/generic/male/male_death_2.ogg', 'sound/voice/death/generic/male/male_death_3.ogg', 'sound/voice/death/generic/male/male_death_4.ogg', 'sound/voice/death/generic/male/male_death_5.ogg', 'sound/voice/death/generic/male/male_death_6.ogg', 'sound/voice/death/generic/male/male_death_7.ogg')) +#define female_generic_sounds list("cough" = list('sound/effects/mob_effects/f_cougha.ogg','sound/effects/mob_effects/f_coughb.ogg'), "sneeze" = list('sound/effects/mob_effects/f_sneeze.ogg'), "scream" = list('sound/voice/scream/generic/female/female_scream_1.ogg', 'sound/voice/scream/generic/female/female_scream_2.ogg', 'sound/voice/scream/generic/female/female_scream_3.ogg', 'sound/voice/scream/generic/female/female_scream_4.ogg', 'sound/voice/scream/generic/female/female_scream_5.ogg'), "pain" = list('sound/voice/pain/generic/female/female_pain_1.ogg', 'sound/voice/pain/generic/female/female_pain_2.ogg', 'sound/voice/pain/generic/female/female_pain_3.ogg'), "gasp" = list('sound/voice/gasp/generic/female/female_gasp1.ogg', 'sound/voice/gasp/generic/female/female_gasp2.ogg'), "death" = list('sound/voice/death/generic/female/female_death_1.ogg', 'sound/voice/death/generic/female/female_death_2.ogg', 'sound/voice/death/generic/female/female_death_3.ogg', 'sound/voice/death/generic/female/female_death_4.ogg', 'sound/voice/death/generic/female/female_death_5.ogg', 'sound/voice/death/generic/female/female_death_6.ogg')) +#define spider_sounds list("cough" = null, "sneeze" = null, "scream" = list('sound/voice/spiderchitter.ogg'), "pain" = list('sound/voice/spiderchitter.ogg'), "gasp" = null, "death" = list('sound/voice/death/spider/spider_death.ogg')) +#define mouse_sounds list("cough" = list('sound/effects/mouse_squeak.ogg'), "sneeze" = list('sound/effects/mouse_squeak.ogg'), "scream" = list('sound/effects/mouse_squeak_loud.ogg'), "pain" = list('sound/effects/mouse_squeak.ogg'), "gasp" = list('sound/effects/mouse_squeak.ogg'), "death" = list('sound/effects/mouse_squeak_loud.ogg')) +#define lizard_sounds list("cough" = null, "sneeze" = null, "scream" = list('sound/effects/mob_effects/una_scream1.ogg','sound/effects/mob_effects/una_scream2.ogg'), "pain" = list('sound/voice/pain/lizard/lizard_pain.ogg'), "gasp" = null, "death" = list('sound/voice/death/lizard/lizard_death.ogg')) +#define vox_sounds list("cough" = list('sound/voice/shriekcough.ogg'), "sneeze" = list('sound/voice/shrieksneeze.ogg'), "scream" = list('sound/voice/shriek1.ogg'), "pain" = list('sound/voice/shriek1.ogg'), "gasp" = null, "death" = null) +#define slime_sounds list("cough" = list('sound/effects/slime_squish.ogg'), "sneeze" = null, "scream" = null, "pain" = null, "gasp" = null, "death" = null) +#define xeno_sounds list("cough" = null, "sneeze" = null, "scream" = list('sound/effects/mob_effects/x_scream1.ogg','sound/effects/mob_effects/x_scream2.ogg','sound/effects/mob_effects/x_scream3.ogg'), "pain" = list('sound/voice/pain/xeno/alien_roar1.ogg', 'sound/voice/pain/xeno/alien_roar2.ogg', 'sound/voice/pain/xeno/alien_roar3.ogg', 'sound/voice/pain/xeno/alien_roar4.ogg', 'sound/voice/pain/xeno/alien_roar5.ogg', 'sound/voice/pain/xeno/alien_roar6.ogg', 'sound/voice/pain/xeno/alien_roar7.ogg', 'sound/voice/pain/xeno/alien_roar8.ogg', 'sound/voice/pain/xeno/alien_roar9.ogg', 'sound/voice/pain/xeno/alien_roar10.ogg', 'sound/voice/pain/xeno/alien_roar11.ogg', 'sound/voice/pain/xeno/alien_roar12.ogg'), "gasp" = list('sound/voice/gasp/xeno/alien_hiss1.ogg'), "death" = list('sound/voice/death/xeno/xeno_death.ogg', 'sound/voice/death/xeno/xeno_death2.ogg')) +#define teshari_sounds list("cough" = list('sound/effects/mob_effects/tesharicougha.ogg','sound/effects/mob_effects/tesharicoughb.ogg'), "sneeze" = list('sound/effects/mob_effects/tesharisneeze.ogg'), "scream" = list('sound/effects/mob_effects/teshariscream.ogg'), "pain" = null, "gasp" = null, "death" = null) +#define raccoon_sounds list("cough" = null, "sneeze" = null, "scream" = list('sound/voice/raccoon.ogg'), "pain" = list('sound/voice/raccoon.ogg'), "gasp" = null, "death" = list('sound/voice/raccoon.ogg')) +#define metroid_sounds list("cough" = list('sound/metroid/metroid_cough.ogg'), "sneeze" = list('sound/metroid/metroid_sneeze.ogg'), "scream" = list('sound/metroid/metroid_scream.ogg'), "pain" = list('sound/metroid/metroidsee.ogg'), "gasp" = list('sound/metroid/metroid_gasp.ogg'), "death" = list('sound/metroid/metroiddeath.ogg')) +#define vulpine_sounds list("cough" = null, "sneeze" = null, "scream" = list('sound/voice/scream/vulpine/fox_yip1.ogg', 'sound/voice/scream/vulpine/fox_yip2.ogg', 'sound/voice/scream/vulpine/fox_yip3.ogg'), "pain" = list('sound/voice/pain/vulpine/fox_pain1.ogg', 'sound/voice/pain/vulpine/fox_pain2.ogg', 'sound/voice/pain/vulpine/fox_pain3.ogg', 'sound/voice/pain/vulpine/fox_pain4.ogg'), "gasp" = list('sound/voice/gasp/canine/wolf_gasp.ogg'), "death" = list('sound/voice/death/canine/wolf_death1.ogg', 'sound/voice/death/canine/wolf_death2.ogg', 'sound/voice/death/canine/wolf_death3.ogg', 'sound/voice/death/canine/wolf_death4.ogg', 'sound/voice/death/canine/wolf_death5.ogg')) +#define no_sounds list("cough" = null, "sneeze" = null, "scream" = null, "pain" = null, "gasp" = null, "death" = null) +#define use_default list("cough" = null, "sneeze" = null, "scream" = null, "pain" = null, "gasp" = null, "death" = null) +/* + * TBD Sound Defines below +*/ +/* +#define avian_sounds list( + "scream" = list(), + "pain" = list(), + "gasp" = list(), + "death" = list() +) +#define slime_sounds list( + "scream" = list(), + "pain" = list(), + "gasp" = list(), + "death" = list() +) +#define vulpine_sounds list( + "scream" = list(), + "pain" = list(), + "gasp" = list(), + "death" = list() +) +#define lizard_sounds list( + "scream" = list(), + "pain" = list(), + "gasp" = list(), + "death" = list() +) +*/ + +// Not sure we even really need this +// var/list/species_sounds = list() + +// Global list containing all of our sound options. +var/list/species_sound_map = list( + "Canine" = canine_sounds, + "Cervine" = cervine_sounds, + "Feline" = feline_sounds, + "Human Male" = male_generic_sounds, + "Human Female" = female_generic_sounds, + "Lizard" = lizard_sounds, + "Metroid" = metroid_sounds, + "Mouse" = mouse_sounds, + "Raccoon" = raccoon_sounds, + "Robotic" = robot_sounds, + "Slime" = slime_sounds, + "Spider" = spider_sounds, + "Teshari" = teshari_sounds, + "Vox" = vox_sounds, + "Vulpine" = vulpine_sounds, + "Xeno" = xeno_sounds, + "None" = no_sounds, + "Unset" = use_default +) + +/* // Not sure we even really need this +/hook/startup/proc/Init_species_sounds() // The entries we're checking over MUST have unique keys. + for(var/i in species_sound_map) + species_sounds |= species_sound_map[i] + return 1 +*/ + +/* + * Call this for when you need a sound from an already-identified list - IE, "Canine". pick() cannot parse procs. + * Indexes must be pre-calculated by the time it reaches here - for instance; + * var/mob/living/M = user + * get_species_sound(M.client.pref.species_sound)["scream"] will return get_species_sound("Robotic")["scream"] + * This can be paired with get_gendered_sound, like so: get_species_sound(get_gendered_sound(M))["emote"] <- get_gendered_sound will return whatever we have of the 3 valid options, and then get_species_sound will match that to the actual sound list. + * The get_species_sound proc will retrieve and return the list based on the key given - get_species_sound("Robotic")["scream"] will return list('sound/voice/scream_silicon.ogg', 'sound/voice/android_scream.ogg', etc) + * If you are adding new calls of this, follow the syntax of get_species_sound(species)["scream"] - you must attach ["emote"] to the end, outside the () + * If your species has a gendered sound, DON'T PANIC. Simply set the gender_specific_species_sounds var on the species to true, and when you call this, do it like so: + * get_species_sound(H.species.species_sounds_male)["emote"] // If we're male, and want an emote sound gendered correctly. +*/ +/proc/get_species_sound(var/sounds) + if(!islist(species_sound_map[sounds])) // We check here if this list actually has anything in it, or if we're about to return a null index + return null // Shitty failsafe but better than rewriting an entire litany of procs rn when I'm low on time - Rykka // list('sound/voice/silence.ogg') + return species_sound_map[sounds] // Otherwise, successfully return our sound + +/* + * The following helper proc will select a species' default sounds - useful for if we're set to "Unset" + * This is ONLY called by Unset, meaning we haven't chosen a species sound. +*/ +/proc/select_default_species_sound(var/datum/preferences/pref) // Called in character setup. This is similar to check_gendered_sounds, except here we pull from the prefs. + // First, we determine if we're custom-choosing a body or if we're a base game species. + var/datum/species/valid = GLOB.all_species[pref.species] + if(valid.selects_bodytype == (SELECTS_BODYTYPE_CUSTOM || SELECTS_BODYTYPE_SHAPESHIFTER)) // Custom species or xenochimera handling here + valid = coalesce(GLOB.all_species[pref.custom_base], GLOB.all_species[pref.species]) + // Now we start getting our sounds. + if(valid.gender_specific_species_sounds) // Do we have gender-specific sounds? + if(pref.identifying_gender == FEMALE && valid.species_sounds_female) + return valid.species_sounds_female + else if(pref.identifying_gender == MALE && valid.species_sounds_male) + return valid.species_sounds_male + else // Failsafe. Update if there's ever gendered sounds for HERM/Neuter/etc + return valid.species_sounds + else + return valid.species_sounds + +/proc/get_gendered_sound(var/mob/living/user) // Called anywhere we need gender-specific species sounds. Gets the gender-specific sound if one exists, but otherwise, will return the species-generic sound list. + var/mob/living/carbon/human/H = user + if(ishuman(H)) + if(H.species.gender_specific_species_sounds) // Do we have gender-specific sounds? + if(H.identifying_gender == FEMALE && H.species.species_sounds_female) + return H.species.species_sounds_female + else if(H.identifying_gender == MALE && H.species.species_sounds_male) + return H.species.species_sounds_male + else // Failsafe. Update if there's ever gendered sounds for HERM/Neuter/etc + return H.species.species_sounds + else + return H.species.species_sounds + else + return user.species_sounds diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm index 4b33f90d99..ec9b48ac7f 100644 --- a/code/modules/admin/topic.dm +++ b/code/modules/admin/topic.dm @@ -1837,7 +1837,7 @@ WANTED.backup_author = src.admincaster_signature //Submitted by WANTED.is_admin_message = 1 news_network.wanted_issue = WANTED - for(var/obj/machinery/newscaster/NEWSCASTER in allCasters) + for(var/obj/machinery/newscaster/NEWSCASTER in GLOB.allCasters) NEWSCASTER.newsAlert() NEWSCASTER.update_icon() src.admincaster_screen = 15 @@ -1853,7 +1853,7 @@ var/choice = tgui_alert(usr, "Please confirm Wanted Issue removal","Network Security Handler",list("Confirm","Cancel")) if(choice=="Confirm") news_network.wanted_issue = null - for(var/obj/machinery/newscaster/NEWSCASTER in allCasters) + for(var/obj/machinery/newscaster/NEWSCASTER in GLOB.allCasters) NEWSCASTER.update_icon() src.admincaster_screen=17 src.access_news_network() diff --git a/code/modules/admin/verbs/mapping.dm b/code/modules/admin/verbs/mapping.dm index f0a4f82493..9db6d3042c 100644 --- a/code/modules/admin/verbs/mapping.dm +++ b/code/modules/admin/verbs/mapping.dm @@ -55,7 +55,7 @@ GLOBAL_LIST_BOILERPLATE(all_debugging_effects, /obj/effect/debugging) - for(var/obj/effect/debugging/camera_range/C in all_debugging_effects) + for(var/obj/effect/debugging/camera_range/C in GLOB.all_debugging_effects) qdel(C) if(camera_range_display_status) @@ -114,7 +114,7 @@ GLOBAL_LIST_BOILERPLATE(all_debugging_effects, /obj/effect/debugging) else intercom_range_display_status = 1 - for(var/obj/effect/debugging/marker/M in all_debugging_effects) + for(var/obj/effect/debugging/marker/M in GLOB.all_debugging_effects) qdel(M) if(intercom_range_display_status) diff --git a/code/modules/admin/verbs/randomverbs.dm b/code/modules/admin/verbs/randomverbs.dm index a90d50b504..81677625d1 100644 --- a/code/modules/admin/verbs/randomverbs.dm +++ b/code/modules/admin/verbs/randomverbs.dm @@ -1,3 +1,5 @@ +GLOBAL_VAR_INIT(global_vantag_hud, 0) + /client/proc/cmd_admin_drop_everything(mob/M as mob in mob_list) set category = null set name = "Drop Everything" @@ -1175,3 +1177,17 @@ Traitors and the like can also be revived with the previous role mostly intact. new /obj/structure/drop_pod/polite(get_turf(usr), L, autoopen == "Yes" ? TRUE : FALSE) feedback_add_details("admin_verb","DPD") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + +/client/proc/toggle_vantag_hud_global(mob/target as mob) + set category = "Fun.Event Kit" + set name = "Toggle Global Event HUD" + set desc = "Give everyone the Event HUD." + + GLOB.global_vantag_hud = !GLOB.global_vantag_hud + if(GLOB.global_vantag_hud) + for(var/mob/living/L in living_mob_list) + if(L.ckey) + L.vantag_hud = TRUE + L.recalculate_vis() + + to_chat(src, span_warning("Global Event HUD has been turned [GLOB.global_vantag_hud ? "on" : "off"].")) diff --git a/code/modules/ai/say_list.dm b/code/modules/ai/say_list.dm index 370545374a..576ab7c652 100644 --- a/code/modules/ai/say_list.dm +++ b/code/modules/ai/say_list.dm @@ -8,6 +8,13 @@ /mob/living var/datum/say_list/say_list = null var/say_list_type = /datum/say_list // Type to give us on initialization. Default has empty lists, so the mob will be silent. + var/can_pain_emote = TRUE + var/datum/looping_sound/mob/deafened/deaf_loop //NYI + var/pain_emote_1p = null + var/pain_emote_3p = null + var/species_sounds = "None" // By default, we have nothing. + var/death_sound_override = null + var/datum/looping_sound/mob/on_fire/firesoundloop /mob/living/Initialize(mapload) if(say_list_type) diff --git a/code/modules/client/preference_setup/vore/02_size.dm b/code/modules/client/preference_setup/vore/02_size.dm index c86bf06078..acc41101cd 100644 --- a/code/modules/client/preference_setup/vore/02_size.dm +++ b/code/modules/client/preference_setup/vore/02_size.dm @@ -11,10 +11,11 @@ var/weight_loss = 50 // Weight loss rate. var/fuzzy = 0 // Preference toggle for sharp/fuzzy icon. Default sharp. var/offset_override = FALSE - var/voice_freq = 0 - var/voice_sound = "beep-boop" + var/voice_freq = 42500 + var/voice_sound = "goon speak 1" var/custom_speech_bubble = "default" var/custom_footstep = "Default" + var/species_sound = "Unset" // Definition of the stuff for Sizing /datum/category_item/player_setup_item/vore/size diff --git a/code/modules/client/preference_setup/vore/07_traits.dm b/code/modules/client/preference_setup/vore/07_traits.dm index 53b03f0ec0..c15eb7c519 100644 --- a/code/modules/client/preference_setup/vore/07_traits.dm +++ b/code/modules/client/preference_setup/vore/07_traits.dm @@ -267,6 +267,15 @@ var/global/list/valid_bloodreagents = list("default",REAGENT_ID_IRON,REAGENT_ID_ if(!(pref.blood_reagents == "default")) new_S.blood_reagents = pref.blood_reagents + //Any additional non-trait settings can be applied here + new_S.blood_color = pref.blood_color + + var/species_sounds_to_copy = pref.species_sound // What sounds are we using? + if(species_sounds_to_copy == "Unset") // Are we unset? + species_sounds_to_copy = select_default_species_sound(pref) // This will also grab gendered versions of the sounds, if they exist. + + new_S.species_sounds = species_sounds_to_copy // Now we send our sounds over to the mob + if(pref.species == SPECIES_CUSTOM) //Statistics for this would be nice var/english_traits = english_list(new_S.traits, and_text = ";", comma_text = ";") @@ -286,6 +295,7 @@ var/global/list/valid_bloodreagents = list("default",REAGENT_ID_IRON,REAGENT_ID_ var/points_left = pref.starting_trait_points + for(var/T in pref.pos_traits + pref.neg_traits) points_left -= GLOB.traits_costs[T] if(T in pref.pos_traits) @@ -295,21 +305,21 @@ var/global/list/valid_bloodreagents = list("default",REAGENT_ID_IRON,REAGENT_ID_ if(points_left < 0 || traits_left < 0 || (!pref.custom_species && pref.species == SPECIES_CUSTOM)) . += span_red(span_bold("^ Fix things! ^")) + "
" - . += "Positive Trait +
" + . += "Positive Trait(s) (Limited) +
" . += "" - . += "Neutral Trait +
" + . += "Neutral Trait(s) (No Limit) +
" . += "" - . += "Negative Trait +
" + . += "Negative Trait(s) (No Limit) +
" . += "