diff --git a/code/controllers/voting.dm b/code/controllers/voting.dm
index 613f06dfcf..c884243443 100644
--- a/code/controllers/voting.dm
+++ b/code/controllers/voting.dm
@@ -39,12 +39,12 @@ datum/controller/vote
result()
for(var/client/C in voting)
if(C)
- C << browse(null,"window=vote;can_close=0")
+ C << browse(null,"window=vote")
reset()
else
for(var/client/C in voting)
if(C)
- C << browse(vote.interface(C),"window=vote;can_close=0")
+ C << browse(vote.interface(C),"window=vote")
voting.Cut()
@@ -392,4 +392,4 @@ datum/controller/vote
set name = "Vote"
if(vote)
- src << browse(vote.interface(client),"window=vote;can_close=0")
+ src << browse(vote.interface(client),"window=vote")
diff --git a/code/game/gamemodes/blob/blobs/shield.dm b/code/game/gamemodes/blob/blobs/shield.dm
index c47696c72e..6829672449 100644
--- a/code/game/gamemodes/blob/blobs/shield.dm
+++ b/code/game/gamemodes/blob/blobs/shield.dm
@@ -21,4 +21,13 @@
CanPass(atom/movable/mover, turf/target, height=0, air_group=0)
if(istype(mover) && mover.checkpass(PASSBLOB)) return 1
- return 0
+ return !density
+
+/obj/effect/blob/shield/New()
+ ..()
+ update_nearby_tiles()
+
+/obj/effect/blob/shield/Destroy()
+ density = 0
+ update_nearby_tiles()
+ ..()
diff --git a/code/game/gamemodes/game_mode.dm b/code/game/gamemodes/game_mode.dm
index a256a41edd..3c31664dea 100644
--- a/code/game/gamemodes/game_mode.dm
+++ b/code/game/gamemodes/game_mode.dm
@@ -16,6 +16,8 @@ var/global/list/additional_antag_types = list()
var/ert_disabled = 0 // ERT cannot be called.
var/deny_respawn = 0 // Disable respawn during this round.
+ var/list/disabled_jobs = list() // Mostly used for Malf. This check is performed in job_controller so it doesn't spawn a regular AI.
+
var/shuttle_delay = 1 // Shuttle transit time is multiplied by this.
var/auto_recall_shuttle = 0 // Will the shuttle automatically be recalled?
diff --git a/code/game/gamemodes/malfunction/malfunction.dm b/code/game/gamemodes/malfunction/malfunction.dm
index b4409316fe..c7b76d9507 100644
--- a/code/game/gamemodes/malfunction/malfunction.dm
+++ b/code/game/gamemodes/malfunction/malfunction.dm
@@ -8,3 +8,4 @@
end_on_antag_death = 0
auto_recall_shuttle = 0
antag_tags = list(MODE_MALFUNCTION)
+ disabled_jobs = list("AI")
diff --git a/code/game/jobs/job_controller.dm b/code/game/jobs/job_controller.dm
index fb7c4b586c..3749a1d574 100644
--- a/code/game/jobs/job_controller.dm
+++ b/code/game/jobs/job_controller.dm
@@ -185,36 +185,6 @@ var/global/datum/controller/occupations/job_master
return
- proc/FillAIPosition()
- var/ai_selected = 0
- var/datum/job/job = GetJob("AI")
- if(!job) return 0
- if((job.title == "AI") && (config) && (!config.allow_ai)) return 0
-
- for(var/i = job.total_positions, i > 0, i--)
- for(var/level = 1 to 3)
- var/list/candidates = list()
- if(ticker.mode.name == "AI malfunction")//Make sure they want to malf if its malf
- candidates = FindOccupationCandidates(job, level, BE_MALF)
- else
- candidates = FindOccupationCandidates(job, level)
- if(candidates.len)
- var/mob/new_player/candidate = pick(candidates)
- if(AssignRole(candidate, "AI"))
- ai_selected++
- break
- //Malf NEEDS an AI so force one if we didn't get a player who wanted it
- if((ticker.mode.name == "AI malfunction")&&(!ai_selected))
- unassigned = shuffle(unassigned)
- for(var/mob/new_player/player in unassigned)
- if(jobban_isbanned(player, "AI")) continue
- if(AssignRole(player, "AI"))
- ai_selected++
- break
- if(ai_selected) return 1
- return 0
-
-
/** Proc DivideOccupations
* fills var "assigned_role" for all ready players.
* This proc must not have any side effect besides of modifying "assigned_role".
@@ -260,11 +230,6 @@ var/global/datum/controller/occupations/job_master
FillHeadPosition()
Debug("DO, Head Check end")
- //Check for an AI
- Debug("DO, Running AI Check")
- FillAIPosition()
- Debug("DO, AI Check end")
-
//Other jobs are now checked
Debug("DO, Running Standard Check")
@@ -275,6 +240,7 @@ var/global/datum/controller/occupations/job_master
// Loop through all levels from high to low
var/list/shuffledoccupations = shuffle(occupations)
+ // var/list/disabled_jobs = ticker.mode.disabled_jobs // So we can use .Find down below without a colon.
for(var/level = 1 to 3)
//Check the head jobs first each level
CheckHeadPositions(level)
@@ -284,7 +250,7 @@ var/global/datum/controller/occupations/job_master
// Loop through all jobs
for(var/datum/job/job in shuffledoccupations) // SHUFFLE ME BABY
- if(!job)
+ if(!job || ticker.mode.disabled_jobs.Find(job.title) )
continue
if(jobban_isbanned(player, job.title))
diff --git a/code/game/objects/items/weapons/grenades/chem_grenade.dm b/code/game/objects/items/weapons/grenades/chem_grenade.dm
index f84d0dc866..92f7322f14 100644
--- a/code/game/objects/items/weapons/grenades/chem_grenade.dm
+++ b/code/game/objects/items/weapons/grenades/chem_grenade.dm
@@ -163,7 +163,7 @@
playsound(src.loc, 'sound/effects/bamf.ogg', 50, 1)
for(var/obj/item/weapon/reagent_containers/glass/G in beakers)
- G.reagents.trans_to(src, G.reagents.total_volume)
+ G.reagents.trans_to_obj(src, G.reagents.total_volume)
if(src.reagents.total_volume) //The possible reactions didnt use up all reagents.
var/datum/effect/effect/system/steam_spread/steam = new /datum/effect/effect/system/steam_spread()
diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm
index aaf184604a..f73258868e 100644
--- a/code/modules/admin/admin.dm
+++ b/code/modules/admin/admin.dm
@@ -1395,7 +1395,7 @@ proc/admin_notice(var/message, var/rights)
if (!istype(src,/datum/admins))
src = usr.client.holder
- if (!istype(src,/datum/admins))
+ if (!istype(src,/datum/admins) || !check_rights(R_ADMIN))
usr << "Error: you are not an admin!"
return
@@ -1403,5 +1403,21 @@ proc/admin_notice(var/message, var/rights)
usr << "Mode has not started."
return
- message_admins("[key_name(usr)] attempting to force mode autospawn.")
+ log_and_message_admins("attempting to force mode autospawn.")
ticker.mode.process_autoantag()
+
+/datum/admins/proc/paralyze_mob(mob/living/H as mob)
+ set category = "Admin"
+ set name = "Toggle Paralyze"
+ set desc = "Paralyzes a player. Or unparalyses them."
+
+ var/msg
+
+ if(check_rights(R_ADMIN))
+ if (H.paralysis == 0)
+ H.paralysis = 8000
+ msg = "has paralyzed [key_name(H)]."
+ else
+ H.paralysis = 0
+ msg = "has unparalyzed [key_name(H)]."
+ log_and_message_admins(msg)
diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm
index 0a4a60c476..2d3ce468ae 100644
--- a/code/modules/admin/admin_verbs.dm
+++ b/code/modules/admin/admin_verbs.dm
@@ -91,7 +91,8 @@ var/list/admin_verbs_admin = list(
/client/proc/change_human_appearance_self, /* Allows the human-based mob itself change its basic appearance */
/client/proc/change_security_level,
/client/proc/view_chemical_reaction_logs,
- /client/proc/makePAI
+ /client/proc/makePAI,
+ /datum/admins/proc/paralyze_mob
)
var/list/admin_verbs_ban = list(
/client/proc/unban_panel,
@@ -287,7 +288,8 @@ var/list/admin_verbs_mod = list(
/datum/admins/proc/show_player_panel,
/client/proc/check_antagonists,
/client/proc/jobbans,
- /client/proc/cmd_admin_subtle_message /*send an message to somebody as a 'voice in their head'*/
+ /client/proc/cmd_admin_subtle_message, /*send an message to somebody as a 'voice in their head'*/
+ /datum/admins/proc/paralyze_mob
)
var/list/admin_verbs_mentor = list(
diff --git a/code/modules/mob/living/carbon/human/examine.dm b/code/modules/mob/living/carbon/human/examine.dm
index ce8b637236..517012babb 100644
--- a/code/modules/mob/living/carbon/human/examine.dm
+++ b/code/modules/mob/living/carbon/human/examine.dm
@@ -271,9 +271,9 @@
var/obj/item/organ/external/E = organs_by_name[organ_tag]
if(!E)
- wound_flavor_text["[organ_descriptor]"] = "[t_He] is missing [t_his] [organ_descriptor].\n"
+ wound_flavor_text["[organ_descriptor]"] = "[t_He] [t_is] missing [t_his] [organ_descriptor].\n"
else if(E.is_stump())
- wound_flavor_text["[organ_descriptor]"] = "[t_He] has a stump where [t_his] [organ_descriptor] should be.\n"
+ wound_flavor_text["[organ_descriptor]"] = "[t_He] [t_has] a stump where [t_his] [organ_descriptor] should be.\n"
else
continue
@@ -284,13 +284,13 @@
wound_flavor_text["[temp.name]"] = "[t_He] has a robot [temp.name]!\n"
continue
else
- wound_flavor_text["[temp.name]"] = "[t_He] has a robot [temp.name]. It has[temp.get_wounds_desc()]!\n"
+ wound_flavor_text["[temp.name]"] = "[t_He] [t_has] a robot [temp.name]. It has[temp.get_wounds_desc()]!\n"
else if(temp.wounds.len > 0 || temp.open)
if(temp.is_stump() && temp.parent_organ && organs_by_name[temp.parent_organ])
var/obj/item/organ/external/parent = organs_by_name[temp.parent_organ]
- wound_flavor_text["[temp.name]"] = "[t_He] has [temp.get_wounds_desc()] on [t_his] [parent.name].
"
+ wound_flavor_text["[temp.name]"] = "[t_He] [t_has] [temp.get_wounds_desc()] on [t_his] [parent.name].
"
else
- wound_flavor_text["[temp.name]"] = "[t_He] has [temp.get_wounds_desc()] on [t_his] [temp.name].
"
+ wound_flavor_text["[temp.name]"] = "[t_He] [t_has] [temp.get_wounds_desc()] on [t_his] [temp.name].
"
if(temp.status & ORGAN_BLEEDING)
is_bleeding["[temp.name]"] = "[capitalize(t_his)] [temp.name] is bleeding!
"
else