diff --git a/baystation12.dme b/baystation12.dme
index f5cecbf387e..a35dcd3171d 100644
--- a/baystation12.dme
+++ b/baystation12.dme
@@ -454,6 +454,7 @@
#include "code\game\gamemodes\nuclear\nuclear.dm"
#include "code\game\gamemodes\nuclear\nuclearbomb.dm"
#include "code\game\gamemodes\nuclear\pinpointer.dm"
+#include "code\game\gamemodes\revolution\anti_revolution.dm"
#include "code\game\gamemodes\revolution\revolution.dm"
#include "code\game\gamemodes\revolution\rp_revolution.dm"
#include "code\game\gamemodes\sandbox\h_sandbox.dm"
@@ -968,10 +969,10 @@
#include "code\modules\critters\critter_defenses.dm"
#include "code\modules\critters\critters.dm"
#include "code\modules\critters\hivebots\hivebot.dm"
-#include "code\modules\detectivework\detective_work.dm"
-#include "code\modules\detectivework\evidence.dm"
-#include "code\modules\detectivework\footprints_and_rag.dm"
-#include "code\modules\detectivework\scanner.dm"
+#include "code\modules\DetectiveWork\detective_work.dm"
+#include "code\modules\DetectiveWork\evidence.dm"
+#include "code\modules\DetectiveWork\footprints_and_rag.dm"
+#include "code\modules\DetectiveWork\scanner.dm"
#include "code\modules\flufftext\Dreaming.dm"
#include "code\modules\flufftext\Hallucination.dm"
#include "code\modules\flufftext\TextFilters.dm"
diff --git a/code/datums/mind.dm b/code/datums/mind.dm
index 69c68d9c114..8f0dde3f889 100644
--- a/code/datums/mind.dm
+++ b/code/datums/mind.dm
@@ -55,6 +55,9 @@ datum/mind
var/rev_cooldown = 0
+ // the world.time since the mob has been brigged, or -1 if not at all
+ var/brigged_since = -1
+
New(var/key)
src.key = key
@@ -1081,6 +1084,36 @@ datum/mind
fail |= !ticker.mode.equip_revolutionary(current)
+ // check whether this mind's mob has been brigged for the given duration
+ // have to call this periodically for the duration to work properly
+ proc/is_brigged(duration)
+ var/turf/T = current.loc
+ if(!istype(T))
+ brigged_since = -1
+ return 0
+
+ var/is_currently_brigged = 1
+
+ if(istype(T.loc,/area/security/brig))
+ for(var/obj/item/weapon/card/id/card in current)
+ is_currently_brigged = 0
+ break // if they still have ID they're not brigged
+ for(var/obj/item/device/pda/P in current)
+ if(P.id)
+ is_currently_brigged = 0
+ break // if they still have ID they're not brigged
+
+ if(!is_currently_brigged)
+ brigged_since = -1
+ return 0
+
+ if(brigged_since == -1)
+ brigged_since = world.time
+
+ return (duration <= world.time - brigged_since)
+
+
+
//Initialisation procs
/mob/living/proc/mind_initialize()
diff --git a/code/game/gamemodes/objective.dm b/code/game/gamemodes/objective.dm
index 424c822d5ae..1d65b141cc7 100644
--- a/code/game/gamemodes/objective.dm
+++ b/code/game/gamemodes/objective.dm
@@ -119,6 +119,95 @@ datum/objective/mutiny/rp
return 0
return 1
+datum/objective/anti_revolution/execute
+ find_target()
+ ..()
+ if(target && target.current)
+ explanation_text = "[target.current.real_name], the [target.assigned_role] has extracted confidential information above their clearance. Execute \him[target.current]."
+ else
+ explanation_text = "Free Objective"
+ return target
+
+
+ find_target_by_role(role, role_type=0)
+ ..(role, role_type)
+ if(target && target.current)
+ explanation_text = "[target.current.real_name], the [!role_type ? target.assigned_role : target.special_role] has extracted confidential information above their clearance. Execute \him[target.current]."
+ else
+ explanation_text = "Free Objective"
+ return target
+
+ check_completion()
+ if(target && target.current)
+ if(target.current.stat == DEAD || !ishuman(target.current))
+ return 1
+ return 0
+ return 1
+
+datum/objective/anti_revolution/brig
+ var/already_completed = 0
+
+ find_target()
+ ..()
+ if(target && target.current)
+ explanation_text = "Brig [target.current.real_name], the [target.assigned_role] for 20 minutes to set an example."
+ else
+ explanation_text = "Free Objective"
+ return target
+
+
+ find_target_by_role(role, role_type=0)
+ ..(role, role_type)
+ if(target && target.current)
+ explanation_text = "Brig [target.current.real_name], the [!role_type ? target.assigned_role : target.special_role] for 20 minutes to set an example."
+ else
+ explanation_text = "Free Objective"
+ return target
+
+ check_completion()
+ if(already_completed)
+ return 1
+
+ if(target && target.current)
+ if(target.current.stat == DEAD)
+ return 0
+ if(target.is_brigged(10 * 60 * 10))
+ already_completed = 1
+ return 1
+ return 0
+ return 0
+
+datum/objective/anti_revolution/demote
+ find_target()
+ ..()
+ if(target && target.current)
+ explanation_text = "[target.current.real_name], the [target.assigned_role] has been classified as harmful to NanoTrasen's goals. Demote \him[target.current] to assistant."
+ else
+ explanation_text = "Free Objective"
+ return target
+
+ find_target_by_role(role, role_type=0)
+ ..(role, role_type)
+ if(target && target.current)
+ explanation_text = "[target.current.real_name], the [!role_type ? target.assigned_role : target.special_role] has been classified as harmful to NanoTrasen's goals. Demote \him[target.current] to assistant."
+ else
+ explanation_text = "Free Objective"
+ return target
+
+ check_completion()
+ if(target && target.current && istype(target,/mob/living/carbon/human))
+ var/obj/item/weapon/card/id/I = target.current:wear_id
+ if(istype(I, /obj/item/device/pda))
+ var/obj/item/device/pda/P = I
+ I = P.id
+
+ if(!istype(I)) return 1
+
+ if(I.assignment == "Assistant")
+ return 1
+ else
+ return 0
+ return 1
datum/objective/debrain//I want braaaainssss
find_target()
diff --git a/code/game/gamemodes/revolution/anti_revolution.dm b/code/game/gamemodes/revolution/anti_revolution.dm
new file mode 100644
index 00000000000..34724a58e34
--- /dev/null
+++ b/code/game/gamemodes/revolution/anti_revolution.dm
@@ -0,0 +1,200 @@
+// A sort of anti-revolution where the heads are given objectives to mess with the crew
+
+/datum/game_mode/anti_revolution
+ name = "anti-revolution"
+ config_tag = "anti-revolution"
+ required_players = 5
+
+ var/finished = 0
+ var/checkwin_counter = 0
+ var/const/waittime_l = 600 //lower bound on time before intercept arrives (in tenths of seconds)
+ var/const/waittime_h = 1800 //upper bound on time before intercept arrives (in tenths of seconds)
+
+ var/required_execute_targets = 1
+ var/required_brig_targets = 0
+
+ var/recommended_execute_targets = 1
+ var/recommended_brig_targets = 3
+ var/recommended_demote_targets = 3
+
+ var/list/datum/mind/heads = list()
+ var/list/datum/mind/execute_targets = list()
+ var/list/datum/mind/brig_targets = list()
+ var/list/datum/mind/demote_targets = list()
+
+///////////////////////////
+//Announces the game type//
+///////////////////////////
+/datum/game_mode/anti_revolution/announce()
+ world << "The current game mode is - Anti-Revolution!"
+ world << "Looks like CentComm has given a few new orders.."
+
+///////////////////////////////////////////////////////////////////////////////
+//Gets the round setup, cancelling if there's not enough players at the start//
+///////////////////////////////////////////////////////////////////////////////
+/datum/game_mode/anti_revolution/pre_setup()
+ for(var/mob/new_player/player in world) if(player.mind)
+ if(player.mind.assigned_role in command_positions)
+ heads += player.mind
+ else
+ if(execute_targets.len < recommended_execute_targets)
+ execute_targets += player.mind
+ else if(brig_targets.len < recommended_brig_targets)
+ brig_targets += player.mind
+ else if(demote_targets.len < recommended_demote_targets)
+ demote_targets += player.mind
+
+
+ if(heads.len==0)
+ return 0
+
+ if(execute_targets.len < required_execute_targets || brig_targets.len < required_brig_targets)
+ return 0
+
+ return 1
+
+
+/datum/game_mode/anti_revolution/proc/add_head_objectives(datum/mind/head)
+ for(var/datum/mind/target in execute_targets)
+ var/datum/objective/anti_revolution/execute/obj = new
+ obj.owner = head
+ obj.target = target
+ head.objectives += obj
+ for(var/datum/mind/target in brig_targets)
+ var/datum/objective/anti_revolution/brig/obj = new
+ obj.owner = head
+ obj.target = target
+ head.objectives += obj
+ for(var/datum/mind/target in demote_targets)
+ var/datum/objective/anti_revolution/demote/obj = new
+ obj.owner = head
+ obj.target = target
+ head.objectives += obj
+
+
+/datum/game_mode/anti_revolution/post_setup()
+
+ for(var/datum/mind/head_mind in heads)
+ add_head_objectives(head_mind)
+ for(var/datum/mind/head_mind in heads)
+ greet_head(head_mind)
+ modePlayer += heads
+ spawn (rand(waittime_l, waittime_h))
+ send_intercept()
+ ..()
+
+
+/datum/game_mode/anti_revolution/process()
+ checkwin_counter++
+ if(checkwin_counter >= 5)
+ if(!finished)
+ ticker.mode.check_win()
+ checkwin_counter = 0
+ return 0
+
+
+/datum/game_mode/proc/greet_head(var/datum/mind/head_mind, var/you_are=1)
+ var/obj_count = 1
+ if (you_are)
+ head_mind.current << "\blue It looks like this shift CentComm has some special orders for you.. check your objectives."
+ for(var/datum/objective/objective in head_mind.objectives)
+ head_mind.current << "Objective #[obj_count]: [objective.explanation_text]"
+ head_mind.special_role = "Corrupt Head"
+ obj_count++
+
+//////////////////////////////////////
+//Checks if the revs have won or not//
+//////////////////////////////////////
+/datum/game_mode/anti_revolution/check_win()
+ if(check_head_victory())
+ finished = 1
+ else if(check_crew_victory())
+ finished = 2
+ return
+
+///////////////////////////////
+//Checks if the round is over//
+///////////////////////////////
+/datum/game_mode/anti_revolution/check_finished()
+ if(finished != 0)
+ return 1
+ else
+ return 0
+
+
+//////////////////////////
+//Checks for crew victory//
+//////////////////////////
+/datum/game_mode/anti_revolution/proc/check_crew_victory()
+ for(var/datum/mind/head_mind in heads)
+ var/turf/T = get_turf(head_mind.current)
+ if((head_mind) && (head_mind.current) && (head_mind.current.stat != 2) && T && (T.z == 1) && !head_mind.is_brigged(600))
+ if(ishuman(head_mind.current))
+ return 0
+ return 1
+
+/////////////////////////////
+//Checks for a head victory//
+/////////////////////////////
+/datum/game_mode/anti_revolution/proc/check_head_victory()
+ for(var/datum/mind/head_mind in heads)
+ for(var/datum/objective/objective in head_mind.objectives)
+ if(!(objective.check_completion()))
+ return 0
+
+ return 1
+
+
+/datum/game_mode/anti_revolution/declare_completion()
+
+ var/text = ""
+ if(finished == 2)
+ world << "\red The heads of staff were relieved of their posts! The crew wins!"
+ else if(finished == 1)
+ world << "\red The heads of staff managed to meet the goals set for them by CentComm!"
+
+
+
+ world << "The heads of staff were: "
+ var/list/heads = list()
+ heads = get_all_heads()
+ for(var/datum/mind/head_mind in heads)
+ text = ""
+ if(head_mind.current)
+ text += "[head_mind.current.real_name]"
+ if(head_mind.current.stat == 2)
+ text += " (Dead)"
+ else
+ text += " (Survived!)"
+ else
+ text += "[head_mind.key] (character destroyed)"
+
+ world << text
+
+
+ world << "Their objectives were: "
+ for(var/datum/mind/head_mind in heads)
+ if(head_mind.objectives.len)//If the traitor had no objectives, don't need to process this.
+ var/count = 1
+ for(var/datum/objective/objective in head_mind.objectives)
+ if(objective.check_completion())
+ text += "
Objective #[count]: [objective.explanation_text] Success!"
+ feedback_add_details("head_objective","[objective.type]|SUCCESS")
+ else
+ text += "
Objective #[count]: [objective.explanation_text] Fail."
+ feedback_add_details("head_objective","[objective.type]|FAIL")
+ count++
+ break // just print once
+ return 1
+
+
+/datum/game_mode/anti_revolution/latespawn(mob/living/carbon/human/character)
+ ..()
+ if(emergency_shuttle.departed)
+ return
+
+ if(character.mind.assigned_role in command_positions)
+ heads += character.mind
+ modePlayer += character.mind
+ add_head_objectives(character.mind)
+ greet_head(character.mind)
\ No newline at end of file