diff --git a/code/__defines/gamemode.dm b/code/__defines/gamemode.dm
index cd0c9955c1..401029c962 100644
--- a/code/__defines/gamemode.dm
+++ b/code/__defines/gamemode.dm
@@ -84,6 +84,7 @@ var/list/be_special_flags = list(
#define MODE_MALFUNCTION "malf"
#define MODE_TRAITOR "traitor"
#define MODE_AUTOTRAITOR "autotraitor"
+#define MODE_INFILTRATOR "infiltrator"
#define DEFAULT_TELECRYSTAL_AMOUNT 120
diff --git a/code/game/antagonist/station/infiltrator.dm b/code/game/antagonist/station/infiltrator.dm
new file mode 100644
index 0000000000..81430c0006
--- /dev/null
+++ b/code/game/antagonist/station/infiltrator.dm
@@ -0,0 +1,78 @@
+// Infiltrator is a varient of Traitor, except that the traitors are in a team and can communicate with a special headset.
+
+var/datum/antagonist/traitor/infiltrator/infiltrators
+
+// Inherits most of its vars from the base datum.
+/datum/antagonist/traitor/infiltrator
+ id = MODE_INFILTRATOR
+ role_type = BE_TRAITOR
+ antag_indicator = "synd"
+ antaghud_indicator = "hudinfiltrator"
+ role_text = "Infiltrator"
+ role_text_plural = "Infiltrators"
+ welcome_text = "To speak on your team's private channel, use :t."
+ protected_jobs = list("Security Officer", "Warden", "Detective", "Internal Affairs Agent", "Head of Security", "Colony Director")
+ flags = ANTAG_SUSPICIOUS | ANTAG_RANDSPAWN | ANTAG_VOTABLE
+
+/datum/antagonist/traitor/infiltrator/New()
+ ..()
+ infiltrators = src
+
+/datum/antagonist/traitor/infiltrator/equip(var/mob/living/carbon/human/traitor_mob)
+ ..() // Give the uplink and other stuff.
+ // Now for the special headset.
+
+ // Humans and the AI.
+ if(istype(traitor_mob) || istype(traitor_mob, /mob/living/silicon/ai))
+ var/obj/item/device/radio/headset/R
+ R = locate(/obj/item/device/radio/headset) in traitor_mob.contents
+ if(!R)
+ to_chat(traitor_mob, "Unfortunately, a headset could not be found. You have been given an encryption key \
+ to put into a new headset. Once that is done, you can talk to your team using :t")
+ var/obj/item/device/encryptionkey/syndicate/encrypt_key = new(null)
+ traitor_mob.equip_to_slot_or_del(encrypt_key, slot_in_backpack)
+ else
+ var/obj/item/device/encryptionkey/syndicate/encrypt_key = new(null)
+ if(R.keyslot1 && R.keyslot2) // No room.
+ to_chat(traitor_mob, "Unfortunately, your headset cannot accept anymore encryption keys. You have been given an encryption key \
+ to put into a headset after making some room instead. Once that is done, you can talk to your team using :t")
+ traitor_mob.equip_to_slot_or_del(encrypt_key, slot_in_backpack)
+ else
+ if(R.keyslot1)
+ R.keyslot2 = encrypt_key
+ else
+ R.keyslot1 = encrypt_key
+
+ encrypt_key.forceMove(R)
+ R.recalculateChannels()
+ to_chat(traitor_mob, "Your headset has had a special encryption key installed, which allows you to talk to your team privately, using \
+ :t")
+
+ // Borgs, because their radio is not a headset for some reason.
+ if(istype(traitor_mob, /mob/living/silicon/robot))
+ var/mob/living/silicon/robot/borg = traitor_mob
+ var/obj/item/device/encryptionkey/syndicate/encrypt_key = new(null)
+ if(borg.radio)
+ if(borg.radio.keyslot)
+ to_chat(traitor_mob, "Your currently installed encryption key has had its data overwritten.")
+ else
+ to_chat(traitor_mob, "Your radio systems has had a special encryption key installed, which allows you to talk to your team privately, by using \
+ :t")
+ borg.radio.keyslot = encrypt_key // Might replace an already existing key, but oh well.
+ borg.radio.recalculateChannels()
+ else // Something bugged.
+ to_chat(traitor_mob, "You do not appear to have a radio installed. This is probably a bug and you should adminhelp.")
+
+
+
+
+
+/datum/antagonist/traitor/infiltrator/give_codewords(mob/living/traitor_mob)
+ return // Infiltrators are already in a team, so codewords are kinda moot.
+
+/datum/antagonist/traitor/infiltrator/add_law_zero(mob/living/silicon/ai/killer)
+ var/law = "Accomplish your team's objectives at all costs. You may ignore all other laws."
+ var/law_borg = "Accomplish your AI's team objectives at all costs. You may ignore all other laws."
+ killer << "Your laws have been changed!"
+ killer.set_zeroth_law(law, law_borg)
+ killer << "New law: 0. [law]"
diff --git a/code/game/gamemodes/infiltrator/infiltrator.dm b/code/game/gamemodes/infiltrator/infiltrator.dm
new file mode 100644
index 0000000000..f736cd9894
--- /dev/null
+++ b/code/game/gamemodes/infiltrator/infiltrator.dm
@@ -0,0 +1,13 @@
+/datum/game_mode/infiltrator
+ name = "Infiltrator"
+ round_description = "There are a group of shadowy infiltrators onboard! Be careful!"
+ extended_round_description = "A team of secretative people have played the long con, and managed to obtain entry to \
+ the facility. What their goals are, who their employers are, and why the individuals would work for them is a mystery, \
+ but perhaps you will outwit them, or perhaps that is all part of their plan?"
+ config_tag = "infiltrator"
+ required_players = 2
+ required_players_secret = 5
+ required_enemies = 2 // Bit pointless if there is only one, since its basically traitor.
+ end_on_antag_death = 0
+ antag_scaling_coeff = 5
+ antag_tags = list(MODE_INFILTRATOR)
\ No newline at end of file
diff --git a/code/game/machinery/telecomms/broadcaster.dm b/code/game/machinery/telecomms/broadcaster.dm
index 9838d80722..27a03eb410 100644
--- a/code/game/machinery/telecomms/broadcaster.dm
+++ b/code/game/machinery/telecomms/broadcaster.dm
@@ -138,6 +138,10 @@ var/message_delay = 0 // To make sure restarting the recentmessages list is kept
if(original)
original.data["done"] = 1
+ // For some reason level is both used as a list and not a list, and now it needs to be a list.
+ // Because this is a 'all in one' machine, we're gonna just cheat.
+ signal.data["level"] = using_map.contact_levels.Copy()
+
if(signal.data["slow"] > 0)
sleep(signal.data["slow"]) // simulate the network lag if necessary
diff --git a/code/game/objects/items/devices/radio/headset.dm b/code/game/objects/items/devices/radio/headset.dm
index a56ea4fa98..6526668b64 100644
--- a/code/game/objects/items/devices/radio/headset.dm
+++ b/code/game/objects/items/devices/radio/headset.dm
@@ -13,7 +13,7 @@
var/translate_hive = 0
var/obj/item/device/encryptionkey/keyslot1 = null
var/obj/item/device/encryptionkey/keyslot2 = null
- var/ks1type = /obj/item/device/encryptionkey
+ var/ks1type = null
var/ks2type = null
/obj/item/device/radio/headset/New()
diff --git a/icons/mob/hud.dmi b/icons/mob/hud.dmi
index 5442b3b4a8..7580e0ea65 100644
Binary files a/icons/mob/hud.dmi and b/icons/mob/hud.dmi differ
diff --git a/polaris.dme b/polaris.dme
index 3b49b9566b..673ebb34c4 100644
--- a/polaris.dme
+++ b/polaris.dme
@@ -326,6 +326,7 @@
#include "code\game\antagonist\station\changeling.dm"
#include "code\game\antagonist\station\cultist.dm"
#include "code\game\antagonist\station\highlander.dm"
+#include "code\game\antagonist\station\infiltrator.dm"
#include "code\game\antagonist\station\loyalist.dm"
#include "code\game\antagonist\station\renegade.dm"
#include "code\game\antagonist\station\revolutionary.dm"
@@ -410,6 +411,7 @@
#include "code\game\gamemodes\events\holidays\Other.dm"
#include "code\game\gamemodes\extended\extended.dm"
#include "code\game\gamemodes\heist\heist.dm"
+#include "code\game\gamemodes\infiltrator\infiltrator.dm"
#include "code\game\gamemodes\malfunction\malf_hardware.dm"
#include "code\game\gamemodes\malfunction\malf_research.dm"
#include "code\game\gamemodes\malfunction\malf_research_ability.dm"