diff --git a/code/datums/mind.dm b/code/datums/mind.dm
index 6287bd5a1d7..56d8fac2d57 100644
--- a/code/datums/mind.dm
+++ b/code/datums/mind.dm
@@ -53,6 +53,7 @@
var/has_been_rev = 0//Tracks if this mind has been a rev or not
+ var/miming = 0 // Mime's vow of silence
var/datum/faction/faction //associated faction
var/datum/changeling/changeling //changeling holder
var/datum/vampire/vampire //vampire holder
diff --git a/code/datums/spell.dm b/code/datums/spell.dm
index 236b7c8e9b1..f129f085bdc 100644
--- a/code/datums/spell.dm
+++ b/code/datums/spell.dm
@@ -19,6 +19,7 @@ var/list/spells = typesof(/obj/effect/proc_holder/spell) //needed for the badmin
var/charge_max = 100 //recharge time in deciseconds if charge_type = "recharge" or starting charges if charge_type = "charges"
var/charge_counter = 0 //can only cast spells if it equals recharge, ++ each decisecond if charge_type = "recharge" or -- each cast if charge_type = "charges"
+ var/still_recharging_msg = "The spell is still recharging."
var/holder_var_type = "bruteloss" //only used if charge_type equals to "holder_var"
var/holder_var_amount = 20 //same. The amount adjusted with the mob's var when the spell is used
@@ -27,6 +28,7 @@ var/list/spells = typesof(/obj/effect/proc_holder/spell) //needed for the badmin
var/clothes_req = 1 //see if it requires clothes
var/stat_allowed = 0 //see if it requires being conscious/alive, need to set to 1 for ghostpells
var/invocation = "HURP DURP" //what is uttered when the wizard casts the spell
+ var/invocation_emote_self = null
var/invocation_type = "none" //can be none, whisper and shout
var/range = 7 //the range of the spell; outer radius for aoe spells
var/message = "" //whatever it says to the guy affected by it
@@ -74,7 +76,7 @@ var/list/spells = typesof(/obj/effect/proc_holder/spell) //needed for the badmin
switch(charge_type)
if("recharge")
if(charge_counter < charge_max)
- user << "[name] is still recharging."
+ user << still_recharging_msg
return 0
if("charges")
if(!charge_counter)
@@ -128,10 +130,13 @@ var/list/spells = typesof(/obj/effect/proc_holder/spell) //needed for the badmin
user.whisper(invocation)
else
user.whisper(replacetext(invocation," ","`"))
+ if("emote")
+ user.visible_message(invocation, invocation_emote_self) //same style as in mob/living/emote.dm
/obj/effect/proc_holder/spell/New()
..()
+ still_recharging_msg = "[name] is still recharging."
charge_counter = charge_max
/obj/effect/proc_holder/spell/Destroy()
diff --git a/code/datums/spells/mime.dm b/code/datums/spells/mime.dm
new file mode 100644
index 00000000000..5e5ddb91db2
--- /dev/null
+++ b/code/datums/spells/mime.dm
@@ -0,0 +1,59 @@
+/obj/effect/proc_holder/spell/aoe_turf/conjure/mime_wall
+ name = "Invisible wall"
+ desc = "The mime's performance transmutates into physical reality."
+ school = "mime"
+ panel = "Mime"
+ summon_type = list(/obj/effect/forcefield/mime)
+ invocation_type = "emote"
+ invocation_emote_self = "You form a wall in front of yourself."
+ summon_lifespan = 300
+ charge_max = 300
+ clothes_req = 0
+ range = 0
+
+ action_icon_state = "mime"
+ action_background_icon_state = "bg_mime"
+
+/obj/effect/proc_holder/spell/aoe_turf/conjure/mime_wall/Click()
+ if(usr && usr.mind)
+ if(!usr.mind.miming)
+ usr << "You must dedicate yourself to silence first."
+ return
+ invocation = "[usr.real_name] looks as if a wall is in front of them."
+ else
+ invocation_type ="none"
+ ..()
+
+
+/obj/effect/proc_holder/spell/targeted/mime/speak
+ name = "Speech"
+ desc = "Make or break a vow of silence."
+ school = "mime"
+ panel = "Mime"
+ clothes_req = 0
+ charge_max = 3000
+ range = -1
+ include_user = 1
+
+ action_icon_state = "mime"
+ action_background_icon_state = "bg_mime"
+
+/obj/effect/proc_holder/spell/targeted/mime/speak/Click()
+ if(!usr)
+ return
+ if(!ishuman(usr))
+ return
+ var/mob/living/carbon/human/H = usr
+ if(H.mind.miming)
+ still_recharging_msg = "You can't break your vow of silence that fast!"
+ else
+ still_recharging_msg = "You'll have to wait before you can give your vow of silence again!"
+ ..()
+
+/obj/effect/proc_holder/spell/targeted/mime/speak/cast(list/targets,mob/user = usr)
+ for(var/mob/living/carbon/human/H in targets)
+ H.mind.miming=!H.mind.miming
+ if(H.mind.miming)
+ H << "You make a vow of silence."
+ else
+ H << "You break your vow of silence."
\ No newline at end of file
diff --git a/code/game/jobs/job/support.dm b/code/game/jobs/job/support.dm
index 156ca4c29f4..ebe252a9c08 100644
--- a/code/game/jobs/job/support.dm
+++ b/code/game/jobs/job/support.dm
@@ -282,11 +282,10 @@
H.equip_or_collect(new /obj/item/weapon/storage/box/survival(H.back), slot_in_backpack)
H.equip_or_collect(new /obj/item/toy/crayon/mime(H), slot_in_backpack)
H.equip_or_collect(new /obj/item/weapon/reagent_containers/food/drinks/bottle/bottleofnothing(H), slot_in_backpack)
- H.verbs += /client/proc/mimespeak
- H.verbs += /client/proc/mimewall
- H.mind.special_verbs += /client/proc/mimespeak
- H.mind.special_verbs += /client/proc/mimewall
- H.miming = 1
+ if(H.mind)
+ H.mind.AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/conjure/mime_wall(null))
+ H.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/mime/speak(null))
+ H.mind.miming = 1
return 1
diff --git a/code/game/jobs/jobprocs.dm b/code/game/jobs/jobprocs.dm
deleted file mode 100644
index 4a885005c78..00000000000
--- a/code/game/jobs/jobprocs.dm
+++ /dev/null
@@ -1,45 +0,0 @@
-
-
-//TODO: put these somewhere else
-/client/proc/mimewall()
- set category = "Mime"
- set name = "Invisible wall"
- set desc = "Create an invisible wall on your location."
- if(usr.stat)
- usr << "Not when you're incapicated."
- return
- if(!ishuman(usr))
- return
-
- var/mob/living/carbon/human/H = usr
-
- if(!H.miming)
- usr << "You still haven't atoned for your speaking transgression. Wait."
- return
- H.verbs -= /client/proc/mimewall
- spawn(300)
- H.verbs += /client/proc/mimewall
- for (var/mob/V in viewers(H))
- if(V!=usr)
- V.show_message("[H] looks as if a wall is in front of them.", 3, "", 2)
- usr << "You form a wall in front of yourself."
- new /obj/effect/forcefield/mime(locate(usr.x,usr.y,usr.z))
- return
-
-/client/proc/mimespeak()
- set category = "Mime"
- set name = "Speech"
- set desc = "Toggle your speech."
- if(!ishuman(usr))
- return
-
- var/mob/living/carbon/human/H = usr
-
- if(H.miming)
- H.miming = 0
- else
- H << "You'll have to wait if you want to atone for your sins."
- spawn(3000)
- H.miming = 1
- return
-
diff --git a/code/game/objects/effects/forcefields.dm b/code/game/objects/effects/forcefields.dm
index df83d69f3b5..f6643a5506a 100644
--- a/code/game/objects/effects/forcefields.dm
+++ b/code/game/objects/effects/forcefields.dm
@@ -3,14 +3,13 @@
name = "FORCEWALL"
icon = 'icons/effects/effects.dmi'
icon_state = "m_shield"
- anchored = 1.0
+ anchored = 1
opacity = 0
density = 1
unacidable = 1
-
-
-
+/obj/effect/forcefield/CanAtmosPass(turf/T)
+ return !density
///////////Mimewalls///////////
@@ -18,7 +17,7 @@
icon_state = "empty"
name = "invisible wall"
desc = "You have a bad feeling about this."
- var/timeleft = 50
+ var/timeleft = 300
var/last_process = 0
/obj/effect/forcefield/mime/New()
diff --git a/code/game/objects/items/devices/megaphone.dm b/code/game/objects/items/devices/megaphone.dm
index 6d7c7a26ed6..af299225238 100644
--- a/code/game/objects/items/devices/megaphone.dm
+++ b/code/game/objects/items/devices/megaphone.dm
@@ -19,13 +19,19 @@
if(!ishuman(user))
user << "\red You don't know how to use this!"
return
- if(user:miming || user.silent)
- user << "\red You find yourself unable to speak at all."
+ if(user.silent)
+ user << "You find yourself unable to speak at all."
return
+ if(ishuman(user))
+ var/mob/living/carbon/human/H = user
+ if(H & H.mind)
+ if(H.mind.miming)
+ user << "Your vow of silence prevents you from speaking."
+ return
if(spamcheck)
user << "\red \The [src] needs to recharge!"
return
-
+
var/message = input(user, "Shout a message:", "Megaphone") as text|null
if(!message)
return
diff --git a/code/game/objects/items/devices/radio/radio.dm b/code/game/objects/items/devices/radio/radio.dm
index 078a3f3d58d..168f448ba4d 100644
--- a/code/game/objects/items/devices/radio/radio.dm
+++ b/code/game/objects/items/devices/radio/radio.dm
@@ -285,6 +285,9 @@ var/global/list/default_medbay_channels = list(
if(wires.IsIndexCut(WIRE_TRANSMIT)) // The device has to have all its wires and shit intact
return 0
+ if(!M.IsVocal())
+ return 0
+
M.last_target_click = world.time
/* Quick introduction:
diff --git a/code/modules/mob/living/carbon/human/emote.dm b/code/modules/mob/living/carbon/human/emote.dm
index f35bda25cd4..14013b59294 100644
--- a/code/modules/mob/living/carbon/human/emote.dm
+++ b/code/modules/mob/living/carbon/human/emote.dm
@@ -21,6 +21,10 @@
if (I.implanted)
I.trigger(act, src)
+ var/miming = 0
+ if(mind)
+ miming = mind.miming
+
//Emote Cooldown System (it's so simple!)
// proc/handle_emote_CD() located in [code\modules\mob\emote.dm]
var/on_CD = 0
diff --git a/code/modules/mob/living/carbon/human/human_defines.dm b/code/modules/mob/living/carbon/human/human_defines.dm
index 2e24edb8518..afbe24be5ac 100644
--- a/code/modules/mob/living/carbon/human/human_defines.dm
+++ b/code/modules/mob/living/carbon/human/human_defines.dm
@@ -72,7 +72,6 @@
var/datum/martial_art/martial_art = null
- var/miming = null //Toggle for the mime's abilities.
var/special_voice = "" // For changing our voice. Used by a symptom.
var/said_last_words=0
diff --git a/code/modules/mob/living/carbon/human/say.dm b/code/modules/mob/living/carbon/human/say.dm
index 569d5247edb..f736a17af22 100644
--- a/code/modules/mob/living/carbon/human/say.dm
+++ b/code/modules/mob/living/carbon/human/say.dm
@@ -90,6 +90,11 @@
return GetSpecialVoice()
return real_name
+/mob/living/carbon/human/IsVocal()
+ if(mind)
+ return !mind.miming
+ return 1
+
/mob/living/carbon/human/proc/SetSpecialVoice(var/new_voice)
if(new_voice)
special_voice = new_voice
diff --git a/code/modules/mob/living/say.dm b/code/modules/mob/living/say.dm
index 72035ee078b..daa0f9571fc 100644
--- a/code/modules/mob/living/say.dm
+++ b/code/modules/mob/living/say.dm
@@ -71,6 +71,8 @@ proc/get_radio_key_from_channel(var/channel)
var/list/returns[3]
var/speech_problem_flag = 0
+
+
if((HULK in mutations) && health >= 25 && length(message))
message = "[uppertext(message)]!!!"
verb = pick("yells","roars","hollers")
@@ -91,6 +93,9 @@ proc/get_radio_key_from_channel(var/channel)
else if(COMIC in mutations)
message = "[message]"
+ if(!IsVocal())
+ message = ""
+ speech_problem_flag = 1
returns[1] = message
returns[2] = verb
diff --git a/code/modules/mob/living/silicon/ai/say.dm b/code/modules/mob/living/silicon/ai/say.dm
index acf3a2db3c0..5e47030f373 100644
--- a/code/modules/mob/living/silicon/ai/say.dm
+++ b/code/modules/mob/living/silicon/ai/say.dm
@@ -1,5 +1,3 @@
-/mob/living/silicon/ai/proc/IsVocal()
-
var/announcing_vox = 0 // Stores the time of the last announcement
var/const/VOX_CHANNEL = 200
var/const/VOX_DELAY = 100
@@ -30,7 +28,7 @@ var/const/VOX_PATH = "sound/vox_fem/"
/mob/living/silicon/ai/proc/ai_announcement()
if(check_unable(AI_CHECK_WIRELESS | AI_CHECK_RADIO))
return
-
+
if(announcing_vox > world.time)
src << "Please wait [round((announcing_vox - world.time) / 10)] seconds."
return
@@ -38,7 +36,7 @@ var/const/VOX_PATH = "sound/vox_fem/"
var/message = input(src, "WARNING: Misuse of this verb can result in you being job banned. More help is available in 'Announcement Help'", "Announcement", last_announcement) as text|null
last_announcement = message
-
+
if(check_unable(AI_CHECK_WIRELESS | AI_CHECK_RADIO))
return
diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm
index 02e8fb50ef4..3f765e1dfd0 100644
--- a/code/modules/mob/mob.dm
+++ b/code/modules/mob/mob.dm
@@ -1448,4 +1448,7 @@ mob/proc/yank_out_object()
//Can this mob leave its location without breaking things terrifically?
/mob/proc/can_safely_leave_loc()
- return 1 // Yes, you can
\ No newline at end of file
+ return 1 // Yes, you can
+
+/mob/proc/IsVocal()
+ return 1
\ No newline at end of file
diff --git a/icons/mob/actions.dmi b/icons/mob/actions.dmi
index 7f5f8925b17..814d9bf3153 100644
Binary files a/icons/mob/actions.dmi and b/icons/mob/actions.dmi differ
diff --git a/paradise.dme b/paradise.dme
index c30ca7e5c0f..627900f7b96 100644
--- a/paradise.dme
+++ b/paradise.dme
@@ -223,6 +223,7 @@
#include "code\datums\spells\lichdom.dm"
#include "code\datums\spells\lightning.dm"
#include "code\datums\spells\magnet.dm"
+#include "code\datums\spells\mime.dm"
#include "code\datums\spells\mind_transfer.dm"
#include "code\datums\spells\projectile.dm"
#include "code\datums\spells\summonitem.dm"
@@ -396,7 +397,6 @@
#include "code\game\jobs\access.dm"
#include "code\game\jobs\job_controller.dm"
#include "code\game\jobs\job_objective.dm"
-#include "code\game\jobs\jobprocs.dm"
#include "code\game\jobs\jobs.dm"
#include "code\game\jobs\whitelist.dm"
#include "code\game\jobs\job\civilian.dm"