diff --git a/code/__DEFINES/flags.dm b/code/__DEFINES/flags.dm
index 04a20338c1f..9c9b8db5727 100644
--- a/code/__DEFINES/flags.dm
+++ b/code/__DEFINES/flags.dm
@@ -66,6 +66,7 @@
#define HAS_MARKINGS 256
#define TAIL_WAGGING 512
#define NO_EYES 1024
+#define HAS_FUR 2048
//Species Diet Flags
#define DIET_CARN 1
diff --git a/code/game/objects/items/trash.dm b/code/game/objects/items/trash.dm
index e573215dcaa..159b4014bf4 100644
--- a/code/game/objects/items/trash.dm
+++ b/code/game/objects/items/trash.dm
@@ -7,62 +7,85 @@
w_class = 1.0
desc = "This is rubbish."
- raisins
+/obj/item/trash/raisins
name = "4no raisins"
icon_state= "4no_raisins"
- candy
+
+/obj/item/trash/candy
name = "Candy"
icon_state= "candy"
- cheesie
+
+/obj/item/trash/cheesie
name = "Cheesie honkers"
icon_state = "cheesie_honkers"
- chips
+
+/obj/item/trash/chips
name = "Chips"
icon_state = "chips"
- popcorn
+
+/obj/item/trash/popcorn
name = "Popcorn"
icon_state = "popcorn"
- sosjerky
+
+/obj/item/trash/sosjerky
name = "Scaredy's Private Reserve Beef Jerky"
icon_state = "sosjerky"
- syndi_cakes
+
+/obj/item/trash/syndi_cakes
name = "Syndi cakes"
icon_state = "syndi_cakes"
- waffles
+
+/obj/item/trash/waffles
name = "Waffles"
icon_state = "waffles"
- plate
+
+/obj/item/trash/plate
name = "Plate"
icon_state = "plate"
- snack_bowl
+
+/obj/item/trash/snack_bowl
name = "Snack bowl"
icon_state = "snack_bowl"
- pistachios
+
+/obj/item/trash/pistachios
name = "Pistachios pack"
icon_state = "pistachios_pack"
- semki
+
+/obj/item/trash/semki
name = "Semki pack"
icon_state = "semki_pack"
- tray
+
+/obj/item/trash/tray
name = "Tray"
icon_state = "tray"
- candle
+
+/obj/item/trash/candle
name = "candle"
icon = 'icons/obj/candle.dmi'
icon_state = "candle4"
- liquidfood
+
+/obj/item/trash/liquidfood
name = "\improper \"LiquidFood\" ration"
icon_state = "liquidfood"
- can
+
+/obj/item/trash/can
name = "crushed can"
icon_state = "cola"
- gum
+
+/obj/item/trash/gum
name = "chewed gum"
desc = "NOT free candy."
icon_state = "gum"
- tastybread
+
+/obj/item/trash/tastybread
name = "bread tube"
icon_state = "tastybread"
+/obj/item/trash/tapetrash
+ name = "old duct tape"
+ icon_state = "tape"
+ desc = "Not sticky anymore."
+ throw_range = 1
+
/obj/item/trash/attack(mob/M as mob, mob/living/user as mob)
return
diff --git a/code/game/objects/items/weapons/tape.dm b/code/game/objects/items/weapons/tape.dm
index a6c7841e020..067bacaef4b 100644
--- a/code/game/objects/items/weapons/tape.dm
+++ b/code/game/objects/items/weapons/tape.dm
@@ -12,6 +12,35 @@
update_icon()
+/obj/item/stack/tape_roll/attack(mob/living/carbon/human/M as mob, mob/living/user as mob)
+ if(M.wear_mask)
+ to_chat(user, "Remove their mask first!")
+ else if(amount < 2)
+ to_chat(user, "You'll need more tape for this!")
+ else if(!M.check_has_mouth())
+ to_chat(user, "They have no mouth to tape over!")
+ else
+ if(M == user)
+ to_chat(user, "You try to tape your own mouth shut.")
+ else
+ to_chat(user, "You try to tape [M]'s mouth shut.")
+ M.visible_message("[user] tries to tape [M]'s mouth closed!")
+ if(do_after(user, 50, target = M))
+ if(M == user)
+ to_chat(user, "You cover your own mouth with a piece of duct tape.")
+ else
+ to_chat(user, "You cover [M]'s mouth with a piece of duct tape. That will shut them up!")
+ M.visible_message("[user] tapes [M]'s mouth shut!")
+ var/obj/item/clothing/mask/muzzle/G = new /obj/item/clothing/mask/muzzle/tapegag
+ M.equip_to_slot(G, slot_wear_mask)
+ G.add_fingerprint(user)
+ amount = amount - 2
+ if(amount <= 0)
+ user.unEquip(src, 1)
+ qdel(src)
+
+
+
/* -- Disabled for now until it has a use --
/obj/item/stack/tape_roll/attack_self(mob/user as mob)
to_chat(user, "You remove a length of tape from [src].")
@@ -110,4 +139,4 @@
if(dir_offset & NORTH)
pixel_y += 32
else if(dir_offset & SOUTH)
- pixel_y -= 32
\ No newline at end of file
+ pixel_y -= 32
diff --git a/code/modules/clothing/masks/miscellaneous.dm b/code/modules/clothing/masks/miscellaneous.dm
index 93e8dc6cd79..d9817add99f 100644
--- a/code/modules/clothing/masks/miscellaneous.dm
+++ b/code/modules/clothing/masks/miscellaneous.dm
@@ -7,6 +7,8 @@
w_class = 2
gas_transfer_coefficient = 0.90
put_on_delay = 20
+ var/resist_time = 0 //deciseconds of how long you need to gnaw to get rid of the gag, 0 to make it impossible to remove
+ var/mute = 1 // 1 - completely mutes you, 0 - muffles everything you say "MHHPHHMMM!!!"
species_fit = list("Vox")
sprite_sheets = list(
"Vox" = 'icons/mob/species/vox/mask.dmi'
@@ -24,6 +26,34 @@
icon_state = "gag"
w_class = 1
+/obj/item/clothing/mask/muzzle/tapegag
+ name = "tape gag"
+ desc = "MHPMHHH!"
+ icon_state = "tapegag"
+ item_state = null
+ w_class = 1
+ resist_time = 150
+ mute = 0
+ species_fit = list("Vox", "Unathi", "Tajaran", "Vulpkanin")
+ sprite_sheets = list(
+ "Vox" = 'icons/mob/species/vox/mask.dmi',
+ "Unathi" = 'icons/mob/species/unathi/mask.dmi',
+ "Tajaran" = 'icons/mob/species/tajaran/mask.dmi',
+ "Vulpkanin" = 'icons/mob/species/vulpkanin/mask.dmi'
+ )
+
+/obj/item/clothing/mask/muzzle/tapegag/dropped(mob/living/carbon/human/user)
+ var/atom/movable/R = new /obj/item/trash/tapetrash
+ if(user.species.bodyflags & HAS_FUR)
+ R.desc += " Is that...fur?"
+ var/turf/T = get_turf(src)
+ R.loc = T
+ transfer_fingerprints_to(R)
+ playsound(src,'sound/items/poster_ripped.ogg',40,1)
+ spawn(0) // Because of how dropping is done, if the muzzle gets deleted now, icons won't properly update and the whole unEquip() proc will break stuff.
+ qdel(src) // This makes sure it gets deleted AFTER all that has to be done is done.
+ user.emote("scream")
+
/obj/item/clothing/mask/surgical
name = "sterile mask"
desc = "A sterile mask designed to help prevent the spread of diseases."
@@ -244,4 +274,4 @@ obj/item/clothing/mask/bandana/purple
name = "black bandana"
icon_state = "bandblack"
item_color = "black"
- desc = "It's a black bandana."
\ No newline at end of file
+ desc = "It's a black bandana."
diff --git a/code/modules/mob/inventory.dm b/code/modules/mob/inventory.dm
index 7a8e608c224..8d68373e3f4 100644
--- a/code/modules/mob/inventory.dm
+++ b/code/modules/mob/inventory.dm
@@ -124,7 +124,6 @@
I.dropped(src)
if(I)
I.layer = initial(I.layer)
-
return 1
@@ -173,4 +172,4 @@
return l_hand
if(slot_r_hand)
return r_hand
- return null
\ No newline at end of file
+ return null
diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm
index 70a1d635ff1..5a641a81689 100644
--- a/code/modules/mob/living/carbon/carbon.dm
+++ b/code/modules/mob/living/carbon/carbon.dm
@@ -746,6 +746,8 @@ var/list/ventcrawl_machinery = list(/obj/machinery/atmospherics/unary/vent_pump,
spintime -= speed
/mob/living/carbon/resist_buckle()
+ spawn(0)
+ resist_muzzle()
if(restrained())
changeNext_move(CLICK_CD_BREAKOUT)
last_special = world.time + CLICK_CD_BREAKOUT
@@ -776,6 +778,8 @@ var/list/ventcrawl_machinery = list(/obj/machinery/atmospherics/unary/vent_pump,
/mob/living/carbon/resist_restraints()
+ spawn(0)
+ resist_muzzle()
var/obj/item/I = null
if(handcuffed)
I = handcuffed
@@ -786,6 +790,21 @@ var/list/ventcrawl_machinery = list(/obj/machinery/atmospherics/unary/vent_pump,
last_special = world.time + CLICK_CD_BREAKOUT
cuff_resist(I)
+/mob/living/carbon/resist_muzzle()
+ if(!istype(wear_mask, /obj/item/clothing/mask/muzzle))
+ return
+ var/obj/item/clothing/mask/muzzle/I = wear_mask
+ var/time = I.resist_time
+ if(I.resist_time == 0)//if it's 0, you can't get out of it
+ to_chat(src, "[I] is too well made, you'll need hands for this one!")
+ else
+ visible_message("[src] gnaws on [I], trying to remove it!")
+ to_chat(src, "You attempt to remove [I]... (This will take around [time/10] seconds and you need to stand still.)")
+ if(do_after(src, time, 0, target = src))
+ visible_message("[src] removes [I]!")
+ to_chat(src, "You get rid of [I]!")
+ unEquip(I)
+
/mob/living/carbon/proc/cuff_resist(obj/item/I, breakouttime = 600, cuff_break = 0)
breakouttime = I.breakouttime
diff --git a/code/modules/mob/living/carbon/human/inventory.dm b/code/modules/mob/living/carbon/human/inventory.dm
index 2ddcb3d0f15..f9d9ae27442 100644
--- a/code/modules/mob/living/carbon/human/inventory.dm
+++ b/code/modules/mob/living/carbon/human/inventory.dm
@@ -607,4 +607,4 @@
return 0
return 1
- return 0 //Unsupported slot
\ No newline at end of file
+ return 0 //Unsupported slot
diff --git a/code/modules/mob/living/carbon/human/species/station.dm b/code/modules/mob/living/carbon/human/species/station.dm
index 26c6ddb0c57..bccd2a1ffdf 100644
--- a/code/modules/mob/living/carbon/human/species/station.dm
+++ b/code/modules/mob/living/carbon/human/species/station.dm
@@ -104,7 +104,7 @@
flags = HAS_LIPS | CAN_BE_FAT
clothing_flags = HAS_UNDERWEAR | HAS_UNDERSHIRT | HAS_SOCKS
- bodyflags = FEET_PADDED | HAS_TAIL | HAS_HEAD_ACCESSORY | HAS_MARKINGS | HAS_SKIN_COLOR | TAIL_WAGGING
+ bodyflags = FEET_PADDED | HAS_TAIL | HAS_HEAD_ACCESSORY | HAS_MARKINGS | HAS_SKIN_COLOR | TAIL_WAGGING | HAS_FUR
dietflags = DIET_OMNI
reagent_tag = PROCESS_ORG
flesh_color = "#AFA59E"
@@ -148,7 +148,7 @@
flags = HAS_LIPS
clothing_flags = HAS_UNDERWEAR | HAS_UNDERSHIRT | HAS_SOCKS
- bodyflags = FEET_PADDED | HAS_TAIL | HAS_HEAD_ACCESSORY | HAS_MARKINGS | HAS_SKIN_COLOR | TAIL_WAGGING
+ bodyflags = FEET_PADDED | HAS_TAIL | HAS_HEAD_ACCESSORY | HAS_MARKINGS | HAS_SKIN_COLOR | TAIL_WAGGING | HAS_FUR
dietflags = DIET_OMNI
reagent_tag = PROCESS_ORG
flesh_color = "#966464"
@@ -793,4 +793,4 @@
/datum/species/machine/handle_death(var/mob/living/carbon/human/H)
H.h_style = ""
spawn(100)
- if(H) H.update_hair()
\ No newline at end of file
+ if(H) H.update_hair()
diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm
index 175f3d186c4..12473f1d9e8 100644
--- a/code/modules/mob/living/living.dm
+++ b/code/modules/mob/living/living.dm
@@ -580,12 +580,19 @@
return
/mob/living/proc/resist_buckle()
+ spawn(0)
+ resist_muzzle()
buckled.user_unbuckle_mob(src,src)
+/mob/living/proc/resist_muzzle()
+ return
+
/mob/living/proc/resist_fire()
return
/mob/living/proc/resist_restraints()
+ spawn(0)
+ resist_muzzle()
return
/*//////////////////////
@@ -835,4 +842,4 @@
if(slowed)
tally += 10
- return tally
\ No newline at end of file
+ return tally
diff --git a/code/modules/mob/living/say.dm b/code/modules/mob/living/say.dm
index 9e27c836be2..c6d0d8e3ee0 100644
--- a/code/modules/mob/living/say.dm
+++ b/code/modules/mob/living/say.dm
@@ -166,8 +166,13 @@ proc/get_radio_key_from_channel(var/channel)
verb = say_quote(message, speaking)
if(is_muzzled())
- to_chat(src, "You're muzzled and cannot speak!")
- return
+ var/obj/item/clothing/mask/muzzle/G = wear_mask
+ if(G.mute) //if the mask is supposed to mute you completely or just muffle you
+ to_chat(src, "You're muzzled and cannot speak!")
+ return
+ else
+ message = muffledspeech(message)
+ verb = "mumbles"
message = trim_left(message)
@@ -356,7 +361,10 @@ proc/get_radio_key_from_channel(var/channel)
return
if(is_muzzled())
- to_chat(src, "You're muzzled and cannot speak!")
+ if(istype(wear_mask, /obj/item/clothing/mask/muzzle/tapegag)) //just for tape
+ to_chat(src, "Your mouth is taped and you cannot speak!")
+ else
+ to_chat(src, "You're muzzled and cannot speak!")
return
var/message_range = 1
diff --git a/code/modules/mob/mob_helpers.dm b/code/modules/mob/mob_helpers.dm
index 63080b30ada..6e0645866d5 100644
--- a/code/modules/mob/mob_helpers.dm
+++ b/code/modules/mob/mob_helpers.dm
@@ -233,6 +233,24 @@ proc/Gibberish(t, p)//t is the inputted message, and any value higher than 70 fo
return returntext
+proc/muffledspeech(phrase)
+ phrase = html_decode(phrase)
+ var/leng=lentext(phrase)
+ var/counter=lentext(phrase)
+ var/newphrase=""
+ var/newletter=""
+ while(counter>=1)
+ newletter=copytext(phrase,(leng-counter)+1,(leng-counter)+2)
+ if(newletter in list(" ", "!", "?", ".", ","))
+ //do nothing
+ else if(lowertext(newletter) in list("a", "e", "i", "o", "u", "y"))
+ newletter = "ph"
+ else
+ newletter = "m"
+ newphrase+="[newletter]"
+ counter-=1
+ return newphrase
+
/proc/shake_camera(mob/M, duration, strength=1)
if(!M || !M.client || M.shakecamera)
diff --git a/icons/mob/mask.dmi b/icons/mob/mask.dmi
index d6dacdce500..ceedd8011b9 100644
Binary files a/icons/mob/mask.dmi and b/icons/mob/mask.dmi differ
diff --git a/icons/mob/species/tajaran/mask.dmi b/icons/mob/species/tajaran/mask.dmi
index 9c3339e29e0..be155741185 100644
Binary files a/icons/mob/species/tajaran/mask.dmi and b/icons/mob/species/tajaran/mask.dmi differ
diff --git a/icons/mob/species/unathi/mask.dmi b/icons/mob/species/unathi/mask.dmi
index a37b45b4e96..db8c09807ef 100644
Binary files a/icons/mob/species/unathi/mask.dmi and b/icons/mob/species/unathi/mask.dmi differ
diff --git a/icons/mob/species/vox/mask.dmi b/icons/mob/species/vox/mask.dmi
index df31a6851ae..cd9c224051b 100644
Binary files a/icons/mob/species/vox/mask.dmi and b/icons/mob/species/vox/mask.dmi differ
diff --git a/icons/mob/species/vulpkanin/mask.dmi b/icons/mob/species/vulpkanin/mask.dmi
index 37aedd13592..d6baae8ab67 100644
Binary files a/icons/mob/species/vulpkanin/mask.dmi and b/icons/mob/species/vulpkanin/mask.dmi differ
diff --git a/icons/obj/clothing/masks.dmi b/icons/obj/clothing/masks.dmi
index 1e033f6746d..ff0fc2384c0 100644
Binary files a/icons/obj/clothing/masks.dmi and b/icons/obj/clothing/masks.dmi differ
diff --git a/icons/obj/trash.dmi b/icons/obj/trash.dmi
index 4b713b2129e..faea5fe4180 100644
Binary files a/icons/obj/trash.dmi and b/icons/obj/trash.dmi differ