diff --git a/code/__defines/items_clothing.dm b/code/__defines/items_clothing.dm index 0dfdd39696b..7e165d6c6a7 100644 --- a/code/__defines/items_clothing.dm +++ b/code/__defines/items_clothing.dm @@ -37,6 +37,7 @@ #define NOSLIP 0x8 // Prevents from slipping on wet floors, in space, etc. #define BLOCK_GAS_SMOKE_EFFECT 0x10 // Blocks the effect that chemical clouds would have on a mob -- glasses, mask and helmets ONLY! (NOTE: flag shared with ONESIZEFITSALL) #define FLEXIBLEMATERIAL 0x20 // At the moment, masks with this flag will not prevent eating even if they are covering your face. +#define SOUNDPROTECTION 0x40 // whether wearing this item will protect you from loud noises such as flashbangs | this only works for ear slots or the head slot // Flags for pass_flags. #define PASSTABLE 0x1 diff --git a/code/datums/uplink/devices and tools.dm b/code/datums/uplink/devices and tools.dm index cf9bb0c3e4e..6761a2f2a49 100644 --- a/code/datums/uplink/devices and tools.dm +++ b/code/datums/uplink/devices and tools.dm @@ -206,4 +206,10 @@ name = "Optical Material Scanner" desc = "These glasses make use of scanning technology to allow the wearer to see objects through solid walls and floors." item_cost = 2 - path = /obj/item/clothing/glasses/material \ No newline at end of file + path = /obj/item/clothing/glasses/material + +/datum/uplink_item/item/tools/earmuff_headset + name = "Earmuff Headset" + desc = "This set of earmuffs has a secret compartment housing radio gear, allowing it to function as a standard headset." + item_cost = 2 + path = /obj/item/device/radio/headset/earmuff \ No newline at end of file diff --git a/code/game/gamemodes/vampire/vampire_powers.dm b/code/game/gamemodes/vampire/vampire_powers.dm index 6f0fa7164d0..795264fcc65 100644 --- a/code/game/gamemodes/vampire/vampire_powers.dm +++ b/code/game/gamemodes/vampire/vampire_powers.dm @@ -342,7 +342,7 @@ var/list/victims = list() for(var/mob/living/carbon/human/T in hearers(4, src) - src) - if(istype(T) && (T.l_ear || T.r_ear) && istype((T.l_ear || T.r_ear), /obj/item/clothing/ears/earmuffs)) + if(T.protected_from_sound()) continue if(!vampire_can_affect_target(T, 0)) continue diff --git a/code/game/machinery/jukebox.dm b/code/game/machinery/jukebox.dm index 4e328b42e96..f393b6d8fca 100644 --- a/code/game/machinery/jukebox.dm +++ b/code/game/machinery/jukebox.dm @@ -95,7 +95,7 @@ datum/track/New(var/title_name, var/audio) for(var/mob/living/carbon/M in ohearers(6, src)) if(istype(M, /mob/living/carbon/human)) var/mob/living/carbon/human/H = M - if(istype(H.l_ear, /obj/item/clothing/ears/earmuffs) || istype(H.r_ear, /obj/item/clothing/ears/earmuffs)) + if(H.protected_from_sound()) continue M.sleeping = 0 M.stuttering += 20 diff --git a/code/game/objects/items/devices/radio/headset.dm b/code/game/objects/items/devices/radio/headset.dm index 3f44991f230..c338d9d7a97 100644 --- a/code/game/objects/items/devices/radio/headset.dm +++ b/code/game/objects/items/devices/radio/headset.dm @@ -71,6 +71,18 @@ return ..(freq, level) return -1 +/obj/item/device/radio/headset/attack_hand(mob/user) + if(ishuman(user)) + var/mob/living/carbon/human/H = user + if(H.l_ear != src && H.r_ear != src) + return ..() + + if(slot_flags & SLOT_TWOEARS) + var/obj/item/clothing/ears/OE = (H.l_ear == src ? H.r_ear : H.l_ear) + qdel(OE) + + ..() + /obj/item/device/radio/headset/attackby(obj/item/W, mob/user) if(W.isscrewdriver()) if(keyslot1 || keyslot2) @@ -388,6 +400,16 @@ translate_hivenet = 1 ks2type = /obj/item/device/encryptionkey/hivenet +/obj/item/device/radio/headset/earmuff + name = "earmuffs" + desc = "Protects your hearing from loud noises, and quiet ones as well." + desc_antag = "This set of earmuffs has a secret compartment housing radio gear, allowing it to function as a standard headset." + icon = 'icons/obj/clothing/ears.dmi' + icon_state = "earmuffs" + item_state = "earmuffs" + item_flags = SOUNDPROTECTION + slot_flags = SLOT_EARS | SLOT_TWOEARS + /obj/item/device/radio/headset/syndicate name = "military headset" icon_state = "syn_headset" diff --git a/code/game/objects/items/weapons/grenades/flashbang.dm b/code/game/objects/items/weapons/grenades/flashbang.dm index 2ea699b0c8b..8f4b57841cc 100644 --- a/code/game/objects/items/weapons/grenades/flashbang.dm +++ b/code/game/objects/items/weapons/grenades/flashbang.dm @@ -41,7 +41,7 @@ eye_safety = M.eyecheck(TRUE) if(ishuman(M)) var/mob/living/carbon/human/H = M - if(istype(H.l_ear, /obj/item/clothing/ears/earmuffs) || istype(H.r_ear, /obj/item/clothing/ears/earmuffs)) + if(H.protected_from_sound()) ear_safety += 2 if(HULK in H.mutations) ear_safety += 1 diff --git a/code/game/objects/structures/crates_lockers/closets/fitness.dm b/code/game/objects/structures/crates_lockers/closets/fitness.dm index 1fbee573020..74174128e33 100644 --- a/code/game/objects/structures/crates_lockers/closets/fitness.dm +++ b/code/game/objects/structures/crates_lockers/closets/fitness.dm @@ -52,6 +52,8 @@ icon_closed = "red" /obj/structure/closet/lasertag/red/fill() + new /obj/item/clothing/ears/earmuffs(src) + new /obj/item/clothing/ears/earmuffs(src) new /obj/item/gun/energy/lasertag/red(src) new /obj/item/gun/energy/lasertag/red(src) new /obj/item/clothing/suit/redtag(src) @@ -65,7 +67,9 @@ icon_closed = "blue" /obj/structure/closet/lasertag/blue/fill() + new /obj/item/clothing/ears/earmuffs(src) + new /obj/item/clothing/ears/earmuffs(src) new /obj/item/gun/energy/lasertag/blue(src) new /obj/item/gun/energy/lasertag/blue(src) new /obj/item/clothing/suit/bluetag(src) - new /obj/item/clothing/suit/bluetag(src) + new /obj/item/clothing/suit/bluetag(src) \ No newline at end of file diff --git a/code/game/sound.dm b/code/game/sound.dm index 36554906d67..ffd6cd7139b 100644 --- a/code/game/sound.dm +++ b/code/game/sound.dm @@ -164,6 +164,19 @@ else return ..() +/mob/living/carbon/human/playsound_get_environment(pressure_factor = 1.0) + if(protected_from_sound()) + return PADDED_CELL + return ..() + +/mob/proc/check_sound_equipment_volume() + return 1 + +/mob/living/carbon/human/check_sound_equipment_volume() + if(protected_from_sound()) + return 0.6 + return 1 + /mob/proc/playsound_to(turf/source_turf, sound/original_sound, use_random_freq, modify_environment = TRUE, use_pressure = TRUE, required_preferences = 0, required_asfx_toggles = 0) var/sound/S = copy_sound(original_sound) @@ -209,8 +222,9 @@ if (modify_environment) S.environment = playsound_get_environment(pressure_factor) - sound_to(src, S) + S.volume *= check_sound_equipment_volume() + sound_to(src, S) return S.volume /mob/proc/playsound_simple(source, soundin, volume, use_random_freq = FALSE, frequency = 0, falloff = 0, use_pressure = TRUE, required_preferences = 0, required_asfx_toggles = 0) diff --git a/code/modules/clothing/clothing.dm b/code/modules/clothing/clothing.dm index 64d50573cb5..c980b4f2578 100644 --- a/code/modules/clothing/clothing.dm +++ b/code/modules/clothing/clothing.dm @@ -284,24 +284,13 @@ if(!canremove) return - var/obj/item/clothing/ears/O - if(slot_flags & SLOT_TWOEARS ) - O = (H.l_ear == src ? H.r_ear : H.l_ear) - user.u_equip(O) - if(!istype(src,/obj/item/clothing/ears/offear)) - qdel(O) - O = src - else - O = src + if(slot_flags & SLOT_TWOEARS) + var/obj/item/clothing/ears/OE = (H.l_ear == src ? H.r_ear : H.l_ear) + qdel(OE) user.u_equip(src) - - if (O) - user.put_in_hands(O) - O.add_fingerprint(user) - - if(istype(src,/obj/item/clothing/ears/offear)) - qdel(src) + user.put_in_hands(src) + src.add_fingerprint(user) /obj/item/clothing/ears/update_clothing_icon() if (ismob(src.loc)) @@ -315,12 +304,22 @@ icon_state = "blocked" slot_flags = SLOT_EARS | SLOT_TWOEARS - New(var/obj/O) - name = O.name - desc = O.desc - icon = O.icon - icon_state = O.icon_state - set_dir(O.dir) +/obj/item/clothing/ears/offear/proc/copy_ear(var/obj/O) + name = O.name + desc = O.desc + icon = O.icon + icon_state = O.icon_state + set_dir(O.dir) + +/obj/item/clothing/ears/offear/attack_hand(mob/living/carbon/human/H) + var/obj/item/clothing/ears/OE = (H.l_ear == src ? H.r_ear : H.l_ear) + OE.attack_hand(H) + qdel(src) + +/obj/item/clothing/ears/offear/attackby(obj/item/I, mob/user) + var/mob/living/carbon/human/H = loc // we will never not be on a humanoid + var/obj/item/clothing/ears/OE = (H.l_ear == src ? H.r_ear : H.l_ear) + OE.attackby(I, user) /////////////////////////////////////////////////////////////////////// //Gloves diff --git a/code/modules/clothing/ears/earmuffs.dm b/code/modules/clothing/ears/earmuffs.dm index 7a7a0e7e67b..c3925077b24 100644 --- a/code/modules/clothing/ears/earmuffs.dm +++ b/code/modules/clothing/ears/earmuffs.dm @@ -4,6 +4,7 @@ icon = 'icons/obj/clothing/ears.dmi' icon_state = "earmuffs" item_state = "earmuffs" + item_flags = SOUNDPROTECTION slot_flags = SLOT_EARS | SLOT_TWOEARS /obj/item/clothing/ears/earmuffs/headphones @@ -12,7 +13,6 @@ var/headphones_on = 0 icon_state = "headphones_off" item_state = "headphones" - slot_flags = SLOT_EARS | SLOT_TWOEARS /obj/item/clothing/ears/earmuffs/headphones/attack_self(mob/user) togglemusic() diff --git a/code/modules/mob/living/carbon/human/human_helpers.dm b/code/modules/mob/living/carbon/human/human_helpers.dm index 2fbc6571cd9..ef7dc248d5f 100644 --- a/code/modules/mob/living/carbon/human/human_helpers.dm +++ b/code/modules/mob/living/carbon/human/human_helpers.dm @@ -256,4 +256,7 @@ return species.icon_x_offset /mob/living/carbon/human/get_standard_pixel_y() - return species.icon_y_offset \ No newline at end of file + return species.icon_y_offset + +/mob/living/carbon/human/proc/protected_from_sound() + return (l_ear?.item_flags & SOUNDPROTECTION) || (r_ear?.item_flags & SOUNDPROTECTION) || (head?.item_flags & SOUNDPROTECTION) \ No newline at end of file diff --git a/code/modules/mob/living/carbon/human/human_powers.dm b/code/modules/mob/living/carbon/human/human_powers.dm index 1eaa3406861..585059e9b55 100644 --- a/code/modules/mob/living/carbon/human/human_powers.dm +++ b/code/modules/mob/living/carbon/human/human_powers.dm @@ -787,11 +787,8 @@ mob/living/carbon/human/proc/change_monitor() var/list/victims = list() - for (var/mob/living/carbon/human/T in hearers(2, src)) - if (T == src) - continue - - if (istype(T) && (T:l_ear || T:r_ear) && istype((T:l_ear || T:r_ear), /obj/item/clothing/ears/earmuffs)) + for (var/mob/living/carbon/human/T in hearers(2, src) - src) + if(T.protected_from_sound()) continue to_chat(T, "You hear an ear piercing shriek and feel your senses go dull!") diff --git a/code/modules/mob/living/carbon/human/inventory.dm b/code/modules/mob/living/carbon/human/inventory.dm index c3ee862b0ad..0ef82d26ed3 100644 --- a/code/modules/mob/living/carbon/human/inventory.dm +++ b/code/modules/mob/living/carbon/human/inventory.dm @@ -232,8 +232,8 @@ This saves us from having to call add_fingerprint() any time something is put in if(slot_l_ear) src.l_ear = W if(l_ear.slot_flags & SLOT_TWOEARS) - var/obj/item/clothing/ears/offear/O = new(W) - O.forceMove(src) + var/obj/item/clothing/ears/offear/O = new /obj/item/clothing/ears/offear(src) + O.copy_ear(W) src.r_ear = O O.layer = SCREEN_LAYER+0.01 W.equipped(src, slot) @@ -241,8 +241,8 @@ This saves us from having to call add_fingerprint() any time something is put in if(slot_r_ear) src.r_ear = W if(r_ear.slot_flags & SLOT_TWOEARS) - var/obj/item/clothing/ears/offear/O = new(W) - O.forceMove(src) + var/obj/item/clothing/ears/offear/O = new /obj/item/clothing/ears/offear(src) + O.copy_ear(W) src.l_ear = O O.layer = SCREEN_LAYER+0.01 W.equipped(src, slot) diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm index 0a58e9f7e52..b1ef44240d7 100644 --- a/code/modules/mob/living/carbon/human/life.dm +++ b/code/modules/mob/living/carbon/human/life.dm @@ -1292,9 +1292,9 @@ if(ear_deaf <= 1 && (sdisabilities & DEAF) && has_hearing_aid()) setEarDamage(-1, max(ear_deaf-1, 0)) - if(istype(l_ear, /obj/item/clothing/ears/earmuffs) || istype(r_ear, /obj/item/clothing/ears/earmuffs)) //resting your ears with earmuffs heals ear damage faster + if(protected_from_sound()) // resting your ears make them heal faster adjustEarDamage(-0.15, 0) - setEarDamage(-1, max(ear_deaf, 1)) + setEarDamage(-1) else if(ear_damage < HEARING_DAMAGE_SLOW_HEAL) //ear damage heals slowly under this threshold. otherwise you'll need earmuffs adjustEarDamage(-0.05, 0) diff --git a/code/modules/mob/living/carbon/human/stripping.dm b/code/modules/mob/living/carbon/human/stripping.dm index 76094b14c7c..57830a9252d 100644 --- a/code/modules/mob/living/carbon/human/stripping.dm +++ b/code/modules/mob/living/carbon/human/stripping.dm @@ -7,6 +7,8 @@ return FALSE var/obj/item/target_slot = get_equipped_item(text2num(slot_to_strip)) + if(istype(target_slot, /obj/item/clothing/ears/offear)) + target_slot = (l_ear == target_slot ? r_ear : l_ear) switch(slot_to_strip) // Handle things that are part of this interface but not removing/replacing a given item. @@ -88,6 +90,9 @@ if(stripping) admin_attack_log(user, src, "Attempted to remove \a [target_slot]", "Target of an attempt to remove \a [target_slot].", "attempted to remove \a [target_slot] from") + if((l_ear == target_slot || r_ear == target_slot) && (target_slot.slot_flags & SLOT_TWOEARS)) + var/obj/item/clothing/ears/OE = (l_ear == target_slot ? r_ear : l_ear) + qdel(OE) unEquip(target_slot) else if(user.unEquip(held)) equip_to_slot_if_possible(held, text2num(slot_to_strip), 0, 1, 1) diff --git a/html/changelogs/geeves-earmuffs.yml b/html/changelogs/geeves-earmuffs.yml new file mode 100644 index 00000000000..4839b4cd6c0 --- /dev/null +++ b/html/changelogs/geeves-earmuffs.yml @@ -0,0 +1,9 @@ +author: Geeves + +delete-after: True + +changes: + - bugfix: "Items that occupy both ear slots, such as earmuffs or headphones, have had their double-ear code improved, making it less likely to bug out and keep one fake item on the ear." + - tweak: "Earmuffs no longer make you unable to hear things such as speech, instead it just reduces the volume of actual in-game sounds by 60%, as well as giving it a padded room reverb." + - rscadd: "Added two earmuffs to the laser tag locker." + - rscadd: "Added a traitor set of earmuffs to the uplink for 2 TC, which work like earmuffs and a headset, but the latter functionality is kept hidden from non-antags." \ No newline at end of file