diff --git a/code/__defines/misc.dm b/code/__defines/misc.dm index 6fb13b6e23e..07385e2391d 100644 --- a/code/__defines/misc.dm +++ b/code/__defines/misc.dm @@ -71,18 +71,19 @@ // ASFX and SFX Toggles // (ASFX = Ambient Sound Effects; SFX = Sound Effects) -#define ASFX_AMBIENCE 1 -#define ASFX_FOOTSTEPS 2 -#define ASFX_VOTE 4 -#define ASFX_VOX 8 -#define ASFX_DROPSOUND 16 -#define ASFX_ARCADE 32 -#define ASFX_RADIO 64 -#define ASFX_INSTRUMENT 128 -#define ASFX_HUM 256 -#define ASFX_MUSIC 512 +#define ASFX_AMBIENCE BITFLAG(0) +#define ASFX_FOOTSTEPS BITFLAG(1) +#define ASFX_VOTE BITFLAG(2) +#define ASFX_VOX BITFLAG(3) +#define ASFX_DROPSOUND BITFLAG(4) +#define ASFX_ARCADE BITFLAG(5) +#define ASFX_RADIO BITFLAG(6) +#define ASFX_INSTRUMENT BITFLAG(7) +#define ASFX_HUM BITFLAG(8) +#define ASFX_MUSIC BITFLAG(9) +#define ASFX_CONSOLE_AMBIENCE BITFLAG(10) -#define ASFX_DEFAULT (ASFX_AMBIENCE | ASFX_FOOTSTEPS | ASFX_VOTE | ASFX_VOX | ASFX_DROPSOUND | ASFX_ARCADE | ASFX_RADIO | ASFX_INSTRUMENT | ASFX_HUM | ASFX_MUSIC) +#define ASFX_DEFAULT (ASFX_AMBIENCE | ASFX_FOOTSTEPS | ASFX_VOTE | ASFX_VOX | ASFX_DROPSOUND | ASFX_ARCADE | ASFX_RADIO | ASFX_INSTRUMENT | ASFX_HUM | ASFX_MUSIC | ASFX_CONSOLE_AMBIENCE) // For secHUDs and medHUDs and variants. The number is the location of the image on the list hud_list of humans. #define HEALTH_HUD 1 // A simple line reading the pulse. diff --git a/code/modules/client/preferences_ambience.dm b/code/modules/client/preferences_ambience.dm index b18846164b0..52d9c2e707c 100644 --- a/code/modules/client/preferences_ambience.dm +++ b/code/modules/client/preferences_ambience.dm @@ -65,6 +65,17 @@ src << sound(null, repeat = 0, wait = 0, volume = 0, channel = 4) // Music plays on channel 4. to_chat(src, SPAN_INFO("You will [(prefs.sfx_toggles & ASFX_MUSIC) ? "now" : "no longer"] hear music (such as from jukeboxes).")) +/client/verb/toggle_asfx_console() + set name = "Toggle Console Ambience SFX" + set category = "Preferences" + set desc = "Toggles hearing ambient sound effects from consoles" + + prefs.sfx_toggles ^= ASFX_CONSOLE_AMBIENCE + prefs.save_preferences() + if(prefs.sfx_toggles & ASFX_CONSOLE_AMBIENCE) + to_chat(src, SPAN_INFO("You will now hear ambient sounds from consoles.")) + else + to_chat(src, SPAN_INFO("You will no longer hear ambient sounds from consoles.")) // // SFX Toggles // @@ -130,4 +141,4 @@ prefs.sfx_toggles ^= ASFX_INSTRUMENT prefs.save_preferences() - to_chat(src, SPAN_INFO("You will [(prefs.sfx_toggles & ASFX_INSTRUMENT) ? "now" : "no longer"] hear instrument sounds.")) \ No newline at end of file + to_chat(src, SPAN_INFO("You will [(prefs.sfx_toggles & ASFX_INSTRUMENT) ? "now" : "no longer"] hear instrument sounds.")) diff --git a/code/modules/mob/living/carbon/human/species/species.dm b/code/modules/mob/living/carbon/human/species/species.dm index 4c2a62e4a94..06fc7541eb9 100644 --- a/code/modules/mob/living/carbon/human/species/species.dm +++ b/code/modules/mob/living/carbon/human/species/species.dm @@ -520,10 +520,16 @@ var/list/vision = H.get_accumulated_vision_handlers() H.update_sight() if(H.machine && H.machine.check_eye(H) >= 0 && H.client.eye != H) + var/sight_flags = H.sight + // we inherit sight flags from the machine - H.sight &= ~(get_vision_flags(H)) - H.sight &= ~(H.equipment_vision_flags) - H.sight &= ~(vision[1]) + sight_flags &= ~(get_vision_flags(H)) + sight_flags &= ~(H.equipment_vision_flags) + sight_flags &= ~(vision[1]) + + sight_flags |= H.machine.check_eye(H) + + H.set_sight(sight_flags) else H.set_sight(H.sight|get_vision_flags(H)|H.equipment_vision_flags|vision[1]) diff --git a/code/modules/overmap/contacts/contact_sensors.dm b/code/modules/overmap/contacts/contact_sensors.dm index d9406d93223..16c24714528 100644 --- a/code/modules/overmap/contacts/contact_sensors.dm +++ b/code/modules/overmap/contacts/contact_sensors.dm @@ -39,7 +39,9 @@ /obj/machinery/computer/ship/sensors/process() ..() + update_sound() + if(!linked) return @@ -51,12 +53,13 @@ sensor_range = round(sensors.range,1) var/datum/overmap_contact/self_record = contact_datums[linked] self_record.update_marker_icon() - self_record.ping_radar(sensor_range) self_record.show() // Update our 'sensor range' (ie. overmap lighting) if(!sensors || !sensors.use_power || (stat & (NOPOWER|BROKEN))) - datalink_remove_all_ships_datalink() + if(length(datalink_contacts)) + var/remove_link = !sensors || HAS_FLAG(stat, BROKEN) + datalink_remove_all_ships_datalink(remove_link) for(var/key in contact_datums) var/datum/overmap_contact/record = contact_datums[key] if(record.effect == linked) @@ -64,40 +67,27 @@ qdel(record) // Immediately cut records if power is lost. objects_in_view.Cut() - return + else + self_record.ping_radar(sensor_range) - // What can we see? - var/list/objects_in_current_view = list() + // What can we see? + var/list/objects_in_current_view = list() - // Find all sectors with a tracker on their z-level. Only works on ships when they are in space. - for(var/obj/item/ship_tracker/tracker in trackers) - if(tracker.enabled) - var/obj/effect/overmap/visitable/tracked_effect = overmap_sectors["[GET_Z(tracker)]"] - if(tracked_effect && istype(tracked_effect) && tracked_effect != linked && tracked_effect.requires_contact) - objects_in_current_view[tracked_effect] = TRUE - objects_in_view[tracked_effect] = 100 + // Find all sectors with a tracker on their z-level. Only works on ships when they are in space. + for(var/obj/item/ship_tracker/tracker in trackers) + if(tracker.enabled) + var/obj/effect/overmap/visitable/tracked_effect = overmap_sectors["[GET_Z(tracker)]"] + if(tracked_effect && istype(tracked_effect) && tracked_effect != linked && tracked_effect.requires_contact) + objects_in_current_view[tracked_effect] = TRUE + objects_in_view[tracked_effect] = 100 - // Handle datalinked view - datalink_process() + // Handle datalinked view + datalink_process() - for(var/obj/effect/overmap/contact in view(sensor_range, linked)) - if(contact == linked) - continue - if(!contact.requires_contact) // Only some effects require contact for visibility. - continue + var/turf/overmap_grid_turf = get_turf(linked) - objects_in_current_view[contact] = TRUE - - if(contact.instant_contact) // Instantly identify the object in range. - objects_in_view[contact] = 100 - else if(!(contact in objects_in_view)) - objects_in_view[contact] = 0 - - if(sensors.deep_scan_toggled) - for(var/obj/effect/overmap/contact in range(sensors.deep_scan_range, linked)) - if(!contact.sensor_range_override) - continue + for(var/obj/effect/overmap/contact in view(sensor_range, overmap_grid_turf)) if(contact == linked) continue if(!contact.requires_contact) // Only some effects require contact for visibility. @@ -110,58 +100,74 @@ else if(!(contact in objects_in_view)) objects_in_view[contact] = 0 - for(var/obj/effect/overmap/contact in objects_in_view) //Update everything. + if(sensors.deep_scan_toggled) + for(var/obj/effect/overmap/contact in range(sensors.deep_scan_range, overmap_grid_turf)) + if(!contact.sensor_range_override) + continue + if(contact == linked) + continue + if(!contact.requires_contact) // Only some effects require contact for visibility. + continue - // Are we already aware of this object? - var/datum/overmap_contact/record = contact_datums[contact] + objects_in_current_view[contact] = TRUE - // Fade out and remove anything that is out of range. - if(QDELETED(contact) || !objects_in_current_view[contact]) // Object has exited sensor range. - if(record) - animate(record.marker, alpha=0, 2 SECOND, 1, LINEAR_EASING) - QDEL_IN(record, 2 SECOND) // Need to restart the search if you've lost contact with the object. - if(contact.scannable) // Scannable objects are the only ones that give off notifications to prevent spam - visible_message(SPAN_NOTICE("\The [src] states, \"Contact lost with [record.name].\"")) - playsound(loc, "sound/machines/sensors/contact_lost.ogg", 30, 1) - objects_in_view -= contact - continue + if(contact.instant_contact) // Instantly identify the object in range. + objects_in_view[contact] = 100 + else if(!(contact in objects_in_view)) + objects_in_view[contact] = 0 - // Generate contact information for this overmap object. - var/bearing = round(90 - Atan2(contact.x - linked.x, contact.y - linked.y),5) - if(bearing < 0) - bearing += 360 - if(!record) // Begin attempting to identify ship. - // The chance of detection decreases with distance to the target ship. - if(contact.scannable && prob((SENSORS_DISTANCE_COEFFICIENT * contact.sensor_visibility)/max(get_dist(linked, contact), 0.5))) - var/bearing_variability = round(30/sensors.sensor_strength, 5) - var/bearing_estimate = round(rand(bearing-bearing_variability, bearing+bearing_variability), 5) - if(bearing_estimate < 0) - bearing_estimate += 360 - // Give the player an idea of where the ship is in relation to the ship. - if(objects_in_view[contact] <= 0) - if(!muted) - visible_message(SPAN_NOTICE("\The [src] states, \"Unknown contact designation '[contact.unknown_id]' detected nearby, bearing [bearing_estimate], error +/- [bearing_variability]. Beginning trace.\"")) - objects_in_view[contact] = round(sensors.sensor_strength**2) - else - objects_in_view[contact] += round(sensors.sensor_strength**2) - if(!muted) - visible_message(SPAN_NOTICE("\The [src] states, \"Contact '[contact.unknown_id]' tracing [objects_in_view[contact]]% complete, bearing [bearing_estimate], error +/- [bearing_variability].\"")) - playsound(loc, "sound/machines/sensors/contactgeneric.ogg", 10, 1) //Let players know there's something nearby. - if(objects_in_view[contact] >= 100) // Identification complete. - record = new /datum/overmap_contact(src, contact) - contact_datums[contact] = record - if(contact.scannable) - playsound(loc, "sound/machines/sensors/newcontact.ogg", 30, 1) - visible_message(SPAN_NOTICE("\The [src] states, \"New contact identified, designation [record.name], bearing [bearing].\"")) - record.show() - animate(record.marker, alpha=255, 2 SECOND, 1, LINEAR_EASING) - continue - // Update identification information for this record. - record.update_marker_icon() + for(var/obj/effect/overmap/contact in objects_in_view) //Update everything. - var/time_delay = max((SENSOR_TIME_DELAY * get_dist(linked, contact)),1) - if(!record.pinged) - addtimer(CALLBACK(record, PROC_REF(ping)), time_delay) + // Are we already aware of this object? + var/datum/overmap_contact/record = contact_datums[contact] + + // Fade out and remove anything that is out of range. + if(QDELETED(contact) || !objects_in_current_view[contact]) // Object has exited sensor range. + if(record) + animate(record.marker, alpha=0, 2 SECOND, 1, LINEAR_EASING) + QDEL_IN(record, 2 SECOND) // Need to restart the search if you've lost contact with the object. + if(contact.scannable) // Scannable objects are the only ones that give off notifications to prevent spam + visible_message(SPAN_NOTICE("\The [src] states, \"Contact lost with [record.name].\"")) + playsound(loc, "sound/machines/sensors/contact_lost.ogg", 30, 1) + objects_in_view -= contact + continue + + // Generate contact information for this overmap object. + var/bearing = round(90 - Atan2(contact.x - linked.x, contact.y - linked.y),5) + if(bearing < 0) + bearing += 360 + if(!record) // Begin attempting to identify ship. + // The chance of detection decreases with distance to the target ship. + if(contact.scannable && prob((SENSORS_DISTANCE_COEFFICIENT * contact.sensor_visibility)/max(get_dist(linked, contact), 0.5))) + var/bearing_variability = round(30/sensors.sensor_strength, 5) + var/bearing_estimate = round(rand(bearing-bearing_variability, bearing+bearing_variability), 5) + if(bearing_estimate < 0) + bearing_estimate += 360 + // Give the player an idea of where the ship is in relation to the ship. + if(objects_in_view[contact] <= 0) + if(!muted) + visible_message(SPAN_NOTICE("\The [src] states, \"Unknown contact designation '[contact.unknown_id]' detected nearby, bearing [bearing_estimate], error +/- [bearing_variability]. Beginning trace.\"")) + objects_in_view[contact] = round(sensors.sensor_strength**2) + else + objects_in_view[contact] += round(sensors.sensor_strength**2) + if(!muted) + visible_message(SPAN_NOTICE("\The [src] states, \"Contact '[contact.unknown_id]' tracing [objects_in_view[contact]]% complete, bearing [bearing_estimate], error +/- [bearing_variability].\"")) + playsound(loc, "sound/machines/sensors/contactgeneric.ogg", 10, 1) //Let players know there's something nearby. + if(objects_in_view[contact] >= 100) // Identification complete. + record = new /datum/overmap_contact(src, contact) + contact_datums[contact] = record + if(contact.scannable) + playsound(loc, "sound/machines/sensors/newcontact.ogg", 30, 1) + visible_message(SPAN_NOTICE("\The [src] states, \"New contact identified, designation [record.name], bearing [bearing].\"")) + record.show() + animate(record.marker, alpha=255, 2 SECOND, 1, LINEAR_EASING) + continue + // Update identification information for this record. + record.update_marker_icon() + + var/time_delay = max((SENSOR_TIME_DELAY * get_dist(linked, contact)),1) + if(!record.pinged) + addtimer(CALLBACK(record, PROC_REF(ping)), time_delay) /obj/machinery/computer/ship/sensors/attackby(var/obj/item/I, var/mob/user) . = ..() @@ -271,12 +277,13 @@ datalink_ship.datalinked |= src.connected src.connected.datalinked |= datalink_ship -/obj/machinery/computer/ship/sensors/proc/datalink_remove_ship_datalink(var/obj/effect/overmap/visitable/datalink_ship) +/obj/machinery/computer/ship/sensors/proc/datalink_remove_ship_datalink(var/obj/effect/overmap/visitable/datalink_ship, var/remove_link) if(datalink_contacts[datalink_ship]) for(var/obj/machinery/computer/ship/sensors/sensor_console in datalink_ship.consoles) // Remove the two ships from each other's datalinked list - src.connected.datalinked -= datalink_ship - datalink_ship.datalinked -= src.connected + if(remove_link) + src.connected.datalinked -= datalink_ship + datalink_ship.datalinked -= src.connected // Removes the ship contact itself from the contacts @@ -294,14 +301,14 @@ datalink_contacts.Remove(datalink_ship) // Recurse the function on the other ship's instance - sensor_console.datalink_remove_ship_datalink(src.connected) + sensor_console.datalink_remove_ship_datalink(src.connected, remove_link) visible_message(SPAN_NOTICE("\The [src] states, \"A datalink contact was severed! Recalibrating...\"")) -/obj/machinery/computer/ship/sensors/proc/datalink_remove_all_ships_datalink() +/obj/machinery/computer/ship/sensors/proc/datalink_remove_all_ships_datalink(var/remove_link) for(var/obj/effect/overmap/visitable/datalink_ship in linked.datalinked) for(var/obj/machinery/computer/ship/sensors/sensor_console in datalink_ship.consoles) - sensor_console.datalink_remove_ship_datalink(linked) + sensor_console.datalink_remove_ship_datalink(linked, remove_link) break diff --git a/code/modules/overmap/ships/computers/sensors.dm b/code/modules/overmap/ships/computers/sensors.dm index e73fbbdd496..5d6caedba89 100644 --- a/code/modules/overmap/ships/computers/sensors.dm +++ b/code/modules/overmap/ships/computers/sensors.dm @@ -11,7 +11,7 @@ var/contact_details = null var/contact_name = null - var/working_sound = 'sound/machines/sensors/dradis.ogg' + var/working_sound = 'sound/machines/sensors/ping.ogg' var/datum/sound_token/sound_token var/sound_id @@ -61,9 +61,9 @@ var/obj/machinery/shipsensors/sensors = get_sensors() if(linked && sensors?.use_power && !(sensors.stat & NOPOWER)) - var/volume = 10 + var/volume = 15 if(!sound_token) - sound_token = sound_player.PlayLoopingSound(src, sound_id, working_sound, volume = volume, range = 10) + sound_token = sound_player.PlayLoopingSound(src, sound_id, working_sound, volume = volume, range = 10, sound_type = ASFX_CONSOLE_AMBIENCE) sound_token.SetVolume(volume) else if(sound_token) QDEL_NULL(sound_token) @@ -134,7 +134,7 @@ var/bearing = round(90 - Atan2(O.x - linked.x, O.y - linked.y),5) if(bearing < 0) bearing += 360 - contacts.Add(list(list("name"=O.name, "ref"="\ref[O]", "bearing"=bearing))) + contacts.Add(list(list("name"=O.name, "ref"="\ref[O]", "bearing"=bearing, "can_datalink"=(!(O in connected.datalinked))))) if(length(contacts)) data["contacts"] = contacts @@ -304,7 +304,7 @@ if (href_list["remove_datalink"]) var/obj/effect/overmap/visitable/O = locate(href_list["remove_datalink"]) for(var/obj/machinery/computer/ship/sensors/rescinder_sensor_console in src.connected.consoles) // Get sensor console from the rescinder - rescinder_sensor_console.datalink_remove_ship_datalink(O) + rescinder_sensor_console.datalink_remove_ship_datalink(O, TRUE) return TOPIC_HANDLED if (href_list["play_message"]) diff --git a/code/modules/overmap/ships/computers/ship.dm b/code/modules/overmap/ships/computers/ship.dm index 64206b86417..e057cd39d9c 100644 --- a/code/modules/overmap/ships/computers/ship.dm +++ b/code/modules/overmap/ships/computers/ship.dm @@ -110,7 +110,7 @@ somewhere on that shuttle. Subtypes of these can be then used to perform ship ov if (use_check_and_message(user, flags) || user.blinded || inoperable() || !linked) return -1 else - return 0 + return SEE_THRU /obj/machinery/computer/ship/Destroy() if(linked) diff --git a/code/modules/overmap/ships/landable.dm b/code/modules/overmap/ships/landable.dm index a1feba11fad..564ceb4d0bd 100644 --- a/code/modules/overmap/ships/landable.dm +++ b/code/modules/overmap/ships/landable.dm @@ -66,6 +66,12 @@ shuttle_moved_event.register(shuttle_datum, src, PROC_REF(on_shuttle_jump)) on_landing(landmark, shuttle_datum.current_location) // We "land" at round start to properly place ourselves on the overmap. + var/obj/effect/overmap/visitable/mothership = map_sectors["[shuttle_datum.current_location.z]"] + if(mothership) + for(var/obj/machinery/computer/ship/sensors/sensor_console in consoles) + sensor_console.datalink_add_ship_datalink(mothership) + break + /obj/effect/shuttle_landmark/ship name = "Open Space" landmark_tag = "ship" diff --git a/html/changelogs/geeves-sensor_tweaks.yml b/html/changelogs/geeves-sensor_tweaks.yml new file mode 100644 index 00000000000..e8639f9c788 --- /dev/null +++ b/html/changelogs/geeves-sensor_tweaks.yml @@ -0,0 +1,11 @@ +author: Geeves + +delete-after: True + +changes: + - tweak: "Opaque objects on the overmap no longer block your mob's vision, meaning you'll be able to see other datalinked ship's detected objects. However, your sensors will still only be able to detect what it can see." + - tweak: "Replaced the repeating sound that sensors make with a gentler sonar sound, also added a Console Ambience preferences to turn it on and off (make sure you toggle it on if you want to hear it)." + - tweak: "Ships no longer lose their datalink unless the sensors get destroyed." + - tweak: "The contact list no longer shows the datalink button for ships you're already linked to." + - rscadd: "Shuttles now automatically datalink to their mothership." + - rscadd: "Docked shuttles' sensors now work." \ No newline at end of file diff --git a/nano/templates/shipsensors.tmpl b/nano/templates/shipsensors.tmpl index c48b6107d76..bd080ab0e2e 100644 --- a/nano/templates/shipsensors.tmpl +++ b/nano/templates/shipsensors.tmpl @@ -123,7 +123,11 @@ {{for data.contacts}} {{:helper.link('Scan', 'search' ,{ 'scan' : value.ref }, null, null)}} - {{:helper.link('Datalink', 'search' ,{ 'request_datalink' : value.ref }, null, null)}} + + {{if value.can_datalink}} + {{:helper.link('Datalink', 'search' ,{ 'request_datalink' : value.ref }, null, null)}} + {{/if}} + {{:value.name}}, bearing {{:value.bearing}} {{/for}} diff --git a/sound/attributions.txt b/sound/attributions.txt index 511afb91075..76c219690ed 100644 --- a/sound/attributions.txt +++ b/sound/attributions.txt @@ -62,4 +62,8 @@ ATTRIBUTIONS SECTION END ATTRIBUTIONS SECTION START sound/machines/switch_chain.ogg - "Chain_switch_2.wav", licensed under CC-BY 3.0. Obtained and edited from https://freesound.org/people/DCElliott/sounds/386422/ sound/machines/switch_flashlight.ogg - "Flashlight Switch", licensed under CC0. Obtained and edited from https://freesound.org/people/Kinoton/sounds/352092/ +ATTRIBUTIONS SECTION END + +ATTRIBUTIONS SECTION START +sound/machines/sensors/ping.ogg - "archi_sonar_05.wav", licensed under CC0. Obtained and edited from https://freesound.org/people/ElanHickler/sounds/38704 ATTRIBUTIONS SECTION END \ No newline at end of file diff --git a/sound/machines/sensors/ping.ogg b/sound/machines/sensors/ping.ogg new file mode 100644 index 00000000000..2c4b8376f43 Binary files /dev/null and b/sound/machines/sensors/ping.ogg differ