diff --git a/code/game/gamemodes/cult/ritual.dm b/code/game/gamemodes/cult/ritual.dm
index cba7a96ef4..d8c41eea42 100644
--- a/code/game/gamemodes/cult/ritual.dm
+++ b/code/game/gamemodes/cult/ritual.dm
@@ -105,7 +105,7 @@ var/global/list/rnwords = list("ire","ego","nahlizet","certum","veri","jatkaa","
if(!iscultist(user))
user << "You can't mouth the arcane scratchings without fumbling over them."
return
- if(istype(user.wear_mask, /obj/item/clothing/mask/muzzle))
+ if(user.is_muzzled())
user << "You are unable to speak the words of the rune."
return
if(!word1 || !word2 || !word3 || prob(user.getBrainLoss()))
diff --git a/code/game/objects/items/weapons/grenades/chem_grenade.dm b/code/game/objects/items/weapons/grenades/chem_grenade.dm
index c3d97c47be..d022c335e0 100644
--- a/code/game/objects/items/weapons/grenades/chem_grenade.dm
+++ b/code/game/objects/items/weapons/grenades/chem_grenade.dm
@@ -6,6 +6,7 @@
w_class = 2.0
force = 2.0
det_time = null
+
var/stage = 0
var/state = 0
var/path = 0
diff --git a/code/game/objects/items/weapons/grenades/grenade.dm b/code/game/objects/items/weapons/grenades/grenade.dm
index 16d8a620f9..c5a0607315 100644
--- a/code/game/objects/items/weapons/grenades/grenade.dm
+++ b/code/game/objects/items/weapons/grenades/grenade.dm
@@ -8,7 +8,8 @@
throw_speed = 4
throw_range = 20
flags = CONDUCT
- slot_flags = SLOT_BELT
+ slot_flags = SLOT_MASK|SLOT_BELT
+
var/active = 0
var/det_time = 50
diff --git a/code/game/objects/items/weapons/grenades/spawnergrenade.dm b/code/game/objects/items/weapons/grenades/spawnergrenade.dm
index 9677a73345..5ca0bd3845 100644
--- a/code/game/objects/items/weapons/grenades/spawnergrenade.dm
+++ b/code/game/objects/items/weapons/grenades/spawnergrenade.dm
@@ -9,27 +9,25 @@
var/spawner_type = null // must be an object path
var/deliveryamt = 1 // amount of type to deliver
- prime() // Prime now just handles the two loops that query for people in lockers and people who can see it.
+// Prime now just handles the two loops that query for people in lockers and people who can see it.
+/obj/item/weapon/grenade/spawnergrenade/prime()
- if(spawner_type && deliveryamt)
- // Make a quick flash
- var/turf/T = get_turf(src)
- playsound(T, 'sound/effects/phasein.ogg', 100, 1)
- for(var/mob/living/carbon/human/M in viewers(T, null))
- if(M:eyecheck() <= 0)
- flick("e_flash", M.flash)
+ if(spawner_type && deliveryamt)
+ // Make a quick flash
+ var/turf/T = get_turf(src)
+ playsound(T, 'sound/effects/phasein.ogg', 100, 1)
+ for(var/mob/living/carbon/human/M in viewers(T, null))
+ if(M:eyecheck() <= 0)
+ flick("e_flash", M.flash)
- for(var/i=1, i<=deliveryamt, i++)
- var/atom/movable/x = new spawner_type
- x.loc = T
- if(prob(50))
- for(var/j = 1, j <= rand(1, 3), j++)
- step(x, pick(NORTH,SOUTH,EAST,WEST))
-
- // Spawn some hostile syndicate critters
-
- qdel(src)
- return
+ // Spawn some hostile syndicate critters
+ for(var/i=1, i<=deliveryamt, i++)
+ var/atom/movable/x = new spawner_type(T)
+ if(prob(50))
+ for(var/j = 1, j <= rand(1, 3), j++)
+ step(x, pick(NORTH,SOUTH,EAST,WEST))
+ qdel(src)
+ return
/obj/item/weapon/grenade/spawnergrenade/manhacks
name = "manhack delivery grenade"
diff --git a/code/game/objects/items/weapons/tape.dm b/code/game/objects/items/weapons/tape.dm
index f87000dd87..0eea22ea52 100644
--- a/code/game/objects/items/weapons/tape.dm
+++ b/code/game/objects/items/weapons/tape.dm
@@ -56,6 +56,7 @@
return
user.visible_message("\The [user] has taped up \the [H]'s mouth!")
+
H.equip_to_slot_or_del(new /obj/item/clothing/mask/muzzle/tape(H), slot_wear_mask)
else if(user.zone_sel.selecting == "r_hand" || user.zone_sel.selecting == "l_hand")
diff --git a/code/modules/mob/emote.dm b/code/modules/mob/emote.dm
index 54f31d5b5b..9908a6378f 100644
--- a/code/modules/mob/emote.dm
+++ b/code/modules/mob/emote.dm
@@ -7,7 +7,7 @@
usr << "You are unable to emote."
return
- var/muzzled = istype(src.wear_mask, /obj/item/clothing/mask/muzzle)
+ var/muzzled = is_muzzled()
if(m_type == 2 && muzzled) return
var/input
diff --git a/code/modules/mob/living/carbon/alien/emote.dm b/code/modules/mob/living/carbon/alien/emote.dm
index b3b0ae53c1..62fa2cf108 100644
--- a/code/modules/mob/living/carbon/alien/emote.dm
+++ b/code/modules/mob/living/carbon/alien/emote.dm
@@ -8,7 +8,7 @@
if(findtext(act,"s",-1) && !findtext(act,"_",-2))//Removes ending s's unless they are prefixed with a '_'
act = copytext(act,1,length(act))
- var/muzzled = istype(src.wear_mask, /obj/item/clothing/mask/muzzle)
+ var/muzzled = is_muzzled()
switch(act)
if ("me")
diff --git a/code/modules/mob/living/carbon/human/emote.dm b/code/modules/mob/living/carbon/human/emote.dm
index 94c7f4600a..e98022acfd 100644
--- a/code/modules/mob/living/carbon/human/emote.dm
+++ b/code/modules/mob/living/carbon/human/emote.dm
@@ -9,7 +9,7 @@
if(findtext(act,"s",-1) && !findtext(act,"_",-2))//Removes ending s's unless they are prefixed with a '_'
act = copytext(act,1,length(act))
- var/muzzled = istype(src.wear_mask, /obj/item/clothing/mask/muzzle)
+ var/muzzled = is_muzzled()
//var/m_type = 1
for (var/obj/item/weapon/implant/I in src)
diff --git a/code/modules/mob/living/carbon/human/examine.dm b/code/modules/mob/living/carbon/human/examine.dm
index c6501aae7c..d9a6850c3a 100644
--- a/code/modules/mob/living/carbon/human/examine.dm
+++ b/code/modules/mob/living/carbon/human/examine.dm
@@ -150,10 +150,14 @@
//mask
if(wear_mask && !skipmask)
+ var/descriptor = "on [T.his] face"
+ if(istype(wear_mask, /obj/item/weapon/grenade) && check_has_mouth())
+ descriptor = "in [T.his] mouth"
+
if(wear_mask.blood_DNA)
- msg += "[T.He] [T.has] \icon[wear_mask] [wear_mask.gender==PLURAL?"some":"a"] [(wear_mask.blood_color != SYNTH_BLOOD_COLOUR) ? "blood" : "oil"]-stained [wear_mask.name] on [T.his] face!\n"
+ msg += "[T.He] [T.has] \icon[wear_mask] [wear_mask.gender==PLURAL?"some":"a"] [(wear_mask.blood_color != SYNTH_BLOOD_COLOUR) ? "blood" : "oil"]-stained [wear_mask.name] [descriptor]!\n"
else
- msg += "[T.He] [T.has] \icon[wear_mask] \a [wear_mask] on [T.his] face.\n"
+ msg += "[T.He] [T.has] \icon[wear_mask] \a [wear_mask] [descriptor].\n"
//eyes
if(glasses && !skipeyes)
diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm
index 303e4a565e..4495ed4175 100644
--- a/code/modules/mob/living/carbon/human/human.dm
+++ b/code/modules/mob/living/carbon/human/human.dm
@@ -1407,3 +1407,7 @@
return 0
return check_organ.can_feel_pain()
return !(species.flags & NO_PAIN)
+
+/mob/living/carbon/human/is_muzzled()
+ return (wear_mask && (istype(wear_mask, /obj/item/clothing/mask/muzzle) || istype(src.wear_mask, /obj/item/weapon/grenade)))
+
diff --git a/code/modules/mob/living/carbon/human/human_attackhand.dm b/code/modules/mob/living/carbon/human/human_attackhand.dm
index ae262677c8..cea8035a84 100644
--- a/code/modules/mob/living/carbon/human/human_attackhand.dm
+++ b/code/modules/mob/living/carbon/human/human_attackhand.dm
@@ -118,6 +118,16 @@
if(I_HURT)
+ if(M.zone_sel.selecting == "mouth" && wear_mask && istype(wear_mask, /obj/item/weapon/grenade))
+ var/obj/item/weapon/grenade/G = wear_mask
+ if(!G.active)
+ visible_message("\The [M] pulls the pin from \the [src]'s [G.name]!")
+ G.activate(M)
+ update_inv_wear_mask()
+ else
+ M << "\The [G] is already primed! Run!"
+ return
+
if(!istype(H))
attack_generic(H,rand(1,3),"punched")
return
diff --git a/code/modules/mob/living/carbon/human/stripping.dm b/code/modules/mob/living/carbon/human/stripping.dm
index 3ebef9e127..26efe8ee90 100644
--- a/code/modules/mob/living/carbon/human/stripping.dm
+++ b/code/modules/mob/living/carbon/human/stripping.dm
@@ -69,7 +69,10 @@
if(stripping)
visible_message("\The [user] is trying to remove \the [src]'s [target_slot.name]!")
else
- visible_message("\The [user] is trying to put \a [held] on \the [src]!")
+ if(slot_to_strip == slot_wear_mask && istype(held, /obj/item/weapon/grenade))
+ visible_message("\The [user] is trying to put \a [held] in \the [src]'s mouth!")
+ else
+ visible_message("\The [user] is trying to put \a [held] on \the [src]!")
if(!do_after(user,HUMAN_STRIP_DELAY))
return
diff --git a/code/modules/mob/living/carbon/human/unarmed_attack.dm b/code/modules/mob/living/carbon/human/unarmed_attack.dm
index b5a78b642c..e56158904f 100644
--- a/code/modules/mob/living/carbon/human/unarmed_attack.dm
+++ b/code/modules/mob/living/carbon/human/unarmed_attack.dm
@@ -112,7 +112,7 @@ var/global/list/sparring_attack_cache = list()
/datum/unarmed_attack/bite/is_usable(var/mob/living/carbon/human/user, var/mob/living/carbon/human/target, var/zone)
- if (user.wear_mask && istype(user.wear_mask, /obj/item/clothing/mask/muzzle))
+ if (user.is_muzzled())
return 0
if (user == target && (zone == BP_HEAD || zone == O_EYES || zone == O_MOUTH))
return 0
diff --git a/code/modules/mob/living/carbon/human/update_icons.dm b/code/modules/mob/living/carbon/human/update_icons.dm
index 8d7b0aeeae..868c7913b3 100644
--- a/code/modules/mob/living/carbon/human/update_icons.dm
+++ b/code/modules/mob/living/carbon/human/update_icons.dm
@@ -788,7 +788,7 @@ var/global/list/damage_icon_parts = list()
/mob/living/carbon/human/update_inv_wear_mask(var/update_icons=1)
- if( wear_mask && ( istype(wear_mask, /obj/item/clothing/mask) || istype(wear_mask, /obj/item/clothing/accessory) ) && !(head && head.flags_inv & HIDEMASK))
+ if( wear_mask && ( istype(wear_mask, /obj/item/clothing/mask) || istype(wear_mask, /obj/item/clothing/accessory) || istype(wear_mask, /obj/item/weapon/grenade) ) && !(head && head.flags_inv & HIDEMASK))
wear_mask.screen_loc = ui_mask //TODO
var/image/standing
diff --git a/code/modules/mob/living/carbon/human/whisper.dm b/code/modules/mob/living/carbon/human/whisper.dm
index 7336189e11..4d59841cd6 100644
--- a/code/modules/mob/living/carbon/human/whisper.dm
+++ b/code/modules/mob/living/carbon/human/whisper.dm
@@ -37,7 +37,7 @@
//This is used by both the whisper verb and human/say() to handle whispering
/mob/living/carbon/human/proc/whisper_say(var/message, var/datum/language/speaking = null, var/alt_name="", var/verb="whispers")
- if (istype(src.wear_mask, /obj/item/clothing/mask/muzzle))
+ if (is_muzzled())
src << "You're muzzled and cannot speak!"
return
diff --git a/code/modules/mob/living/say.dm b/code/modules/mob/living/say.dm
index 460a16d3df..fe33cfdcb9 100644
--- a/code/modules/mob/living/say.dm
+++ b/code/modules/mob/living/say.dm
@@ -82,9 +82,6 @@ proc/get_radio_key_from_channel(var/channel)
/mob/living/proc/get_default_language()
return default_language
-/mob/living/proc/is_muzzled()
- return 0
-
/mob/living/proc/handle_speech_problems(var/message, var/verb)
var/list/returns[3]
var/speech_problem_flag = 0
@@ -167,7 +164,7 @@ proc/get_radio_key_from_channel(var/channel)
speaking.broadcast(src,trim(message))
return 1
- verb = say_quote(message, speaking)
+ verb = say_quote(message, speaking)
if(is_muzzled())
src << "You're muzzled and cannot speak!"
diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm
index ff45cb71d0..e6a0b277f6 100644
--- a/code/modules/mob/mob.dm
+++ b/code/modules/mob/mob.dm
@@ -1131,3 +1131,7 @@ mob/proc/yank_out_object()
/mob/proc/isSynthetic()
return 0
+
+/mob/proc/is_muzzled()
+ return 0
+
diff --git a/code/modules/spells/spell_code.dm b/code/modules/spells/spell_code.dm
index 1e8274757e..6b648fb392 100644
--- a/code/modules/spells/spell_code.dm
+++ b/code/modules/spells/spell_code.dm
@@ -213,7 +213,7 @@ var/list/spells = typesof(/spell) //needed for the badmin verb for now
return 0
if(ishuman(user) && !(invocation_type in list(SpI_EMOTE, SpI_NONE)))
- if(istype(user.wear_mask, /obj/item/clothing/mask/muzzle))
+ if(user.is_muzzled())
user << "Mmmf mrrfff!"
return 0
diff --git a/html/changelogs/Zuhayr-grenades.yml b/html/changelogs/Zuhayr-grenades.yml
new file mode 100644
index 0000000000..f68cc2e536
--- /dev/null
+++ b/html/changelogs/Zuhayr-grenades.yml
@@ -0,0 +1,4 @@
+author: Zuhayr
+delete-after: True
+changes:
+ - rscadd: "Added the ability to equip grenades to the mask slot, and to prime them by clicking someone with harm intent targeting the mouth."
diff --git a/icons/mob/mask.dmi b/icons/mob/mask.dmi
index 7ff6b43cb8..f8ce408041 100644
Binary files a/icons/mob/mask.dmi and b/icons/mob/mask.dmi differ