diff --git a/code/datums/uplink_item.dm b/code/datums/uplink_item.dm
index a663a616313..4a677ab1d4b 100644
--- a/code/datums/uplink_item.dm
+++ b/code/datums/uplink_item.dm
@@ -1,6 +1,6 @@
var/list/uplink_items = list()
-/proc/get_uplink_items()
+/proc/get_uplink_items(var/gamemode_override=null)
// If not already initialized..
if(!uplink_items.len)
@@ -13,10 +13,6 @@ var/list/uplink_items = list()
var/datum/uplink_item/I = new item()
if(!I.item)
continue
- if(I.gamemodes.len && ticker && !(ticker.mode.type in I.gamemodes))
- continue
- if(I.excludefrom.len && ticker && (ticker.mode.type in I.excludefrom))
- continue
if(I.last)
last += I
continue
@@ -33,7 +29,26 @@ var/list/uplink_items = list()
uplink_items[I.category] += I
- return uplink_items
+ //Filtered version
+ var/list/filtered_uplink_items = list()
+
+ for(var/category in uplink_items)
+ for(var/datum/uplink_item/I in uplink_items[category])
+ if(I.gamemodes.len)
+ if(!gamemode_override && ticker && !(ticker.mode.type in I.gamemodes))
+ continue
+ if(gamemode_override && !(gamemode_override in I.gamemodes))
+ continue
+ if(I.excludefrom.len)
+ if(!gamemode_override && ticker && (ticker.mode.type in I.excludefrom))
+ continue
+ if(gamemode_override && (gamemode_override in I.excludefrom))
+ continue
+ if(!filtered_uplink_items[I.category])
+ filtered_uplink_items[I.category] = list()
+ filtered_uplink_items[category] += I
+
+ return filtered_uplink_items
// You can change the order of the list by putting datums before/after one another OR
// you can use the last variable to make sure it appears last, well have the category appear last.
diff --git a/code/game/gamemodes/nuclear/nuclear.dm b/code/game/gamemodes/nuclear/nuclear.dm
index 939cce46b06..91dc864f261 100644
--- a/code/game/gamemodes/nuclear/nuclear.dm
+++ b/code/game/gamemodes/nuclear/nuclear.dm
@@ -159,33 +159,7 @@
/datum/game_mode/proc/equip_syndicate(mob/living/carbon/human/synd_mob)
- var/radio_freq = SYND_FREQ
-
- var/obj/item/device/radio/R = new /obj/item/device/radio/headset/syndicate/alt(synd_mob)
- R.set_frequency(radio_freq)
- R.freqlock = 1
- synd_mob.equip_to_slot_or_del(R, slot_ears)
-
- synd_mob.equip_to_slot_or_del(new /obj/item/clothing/under/syndicate(synd_mob), slot_w_uniform)
- synd_mob.equip_to_slot_or_del(new /obj/item/clothing/shoes/combat(synd_mob), slot_shoes)
- synd_mob.equip_to_slot_or_del(new /obj/item/clothing/gloves/combat(synd_mob), slot_gloves)
- synd_mob.equip_to_slot_or_del(new /obj/item/weapon/card/id/syndicate(synd_mob), slot_wear_id)
- if(synd_mob.backbag == 1) synd_mob.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack(synd_mob), slot_back)
- if(synd_mob.backbag == 2) synd_mob.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel_norm(synd_mob), slot_back)
- synd_mob.equip_to_slot_or_del(new /obj/item/weapon/gun/projectile/automatic/pistol(synd_mob), slot_belt)
- synd_mob.equip_to_slot_or_del(new /obj/item/weapon/storage/box/engineer(synd_mob.back), slot_in_backpack)
-
- var/obj/item/device/radio/uplink/U = new /obj/item/device/radio/uplink(synd_mob)
- U.hidden_uplink.uplink_owner="[synd_mob.key]"
- U.hidden_uplink.uses = 20
- synd_mob.equip_to_slot_or_del(U, slot_in_backpack)
-
- var/obj/item/weapon/implant/weapons_auth/W = new/obj/item/weapon/implant/weapons_auth(synd_mob)
- W.implant(synd_mob)
- var/obj/item/weapon/implant/explosive/E = new/obj/item/weapon/implant/explosive(synd_mob)
- E.implant(synd_mob)
- synd_mob.faction |= "syndicate"
- synd_mob.update_icons()
+ synd_mob.equipOutfit(/datum/outfit/syndicate)
return 1
@@ -313,4 +287,63 @@
var/mob/living/carbon/human/H = synd_mind.current
synd_mind.name = H.dna.species.random_name(H.gender,0,lastname)
synd_mind.current.real_name = synd_mind.name
- return
\ No newline at end of file
+ return
+
+/datum/outfit/syndicate
+ name = "Syndicate Operative - Basic"
+
+ uniform = /obj/item/clothing/under/syndicate
+ shoes = /obj/item/clothing/shoes/combat
+ gloves = /obj/item/clothing/gloves/combat
+ back = /obj/item/weapon/storage/backpack
+ ears = /obj/item/device/radio/headset/syndicate/alt
+ id = /obj/item/weapon/card/id/syndicate
+ belt = /obj/item/weapon/gun/projectile/automatic/pistol
+ backpack_contents = list(/obj/item/weapon/storage/box/engineer=1)
+
+ var/tc = 20
+
+/datum/outfit/syndicate/post_equip(mob/living/carbon/human/H)
+ var/obj/item/device/radio/R = H.ears
+ R.set_frequency(SYND_FREQ)
+ R.freqlock = 1
+
+ var/obj/item/device/radio/uplink/U = new /obj/item/device/radio/uplink(H)
+ U.hidden_uplink.uplink_owner="[H.key]"
+ U.hidden_uplink.uses = tc
+ U.hidden_uplink.mode_override = /datum/game_mode/nuclear //Goodies
+ H.equip_to_slot_or_del(U, slot_in_backpack)
+
+ var/obj/item/weapon/implant/weapons_auth/W = new/obj/item/weapon/implant/weapons_auth(H)
+ W.implant(H)
+ var/obj/item/weapon/implant/explosive/E = new/obj/item/weapon/implant/explosive(H)
+ E.implant(H)
+ H.faction |= "syndicate"
+ H.update_icons()
+
+/datum/outfit/syndicate/full
+ name = "Syndicate Operative - Full Kit"
+
+ glasses = /obj/item/clothing/glasses/night
+ mask = /obj/item/clothing/mask/gas/syndicate
+ suit = /obj/item/clothing/suit/space/hardsuit/syndi
+ l_pocket = /obj/item/weapon/tank/internals/emergency_oxygen/engi
+ r_pocket = /obj/item/weapon/gun/projectile/automatic/pistol
+ belt = /obj/item/weapon/storage/belt/military
+ r_hand = /obj/item/weapon/gun/projectile/automatic/shotgun/bulldog
+ backpack_contents = list(/obj/item/weapon/storage/box/engineer=1,\
+ /obj/item/weapon/tank/jetpack/oxygen/harness=1,\
+ /obj/item/weapon/pinpointer/nukeop=1)
+
+ tc = 30
+
+/datum/outfit/syndicate/full/post_equip(mob/living/carbon/human/H)
+ ..()
+
+
+ var/obj/item/clothing/suit/space/hardsuit/syndi/suit = H.wear_suit
+ suit.ToggleHelmet()
+ var/obj/item/clothing/head/helmet/space/hardsuit/syndi/helmet = H.head
+ helmet.attack_self(H)
+
+ H.internal = H.l_store
\ No newline at end of file
diff --git a/code/game/gamemodes/objective.dm b/code/game/gamemodes/objective.dm
index 47ddaa84213..90eeaf2a609 100644
--- a/code/game/gamemodes/objective.dm
+++ b/code/game/gamemodes/objective.dm
@@ -380,6 +380,11 @@
explanation_text = "Destroy the station with a nuclear device."
martyr_compatible = 1
+/datum/objective/nuclear/check_completion()
+ if(ticker && ticker.mode && ticker.mode.station_was_nuked)
+ return 1
+ return 0
+
var/global/list/possible_items = list()
/datum/objective/steal
diff --git a/code/game/objects/items/devices/uplinks.dm b/code/game/objects/items/devices/uplinks.dm
index b0cc74e33d2..de4801caf63 100644
--- a/code/game/objects/items/devices/uplinks.dm
+++ b/code/game/objects/items/devices/uplinks.dm
@@ -19,6 +19,8 @@ var/list/world_uplinks = list()
var/uplink_owner = null//text-only
var/used_TC = 0
+ var/mode_override = null
+
/obj/item/device/uplink/New()
..()
world_uplinks+=src
@@ -36,7 +38,7 @@ var/list/world_uplinks = list()
dat += "Request item:
"
dat += "Each item costs a number of tele-crystals as indicated by the number following their name.
"
- var/list/buyable_items = get_uplink_items()
+ var/list/buyable_items = get_uplink_items(mode_override)
// Loop through categories
var/index = 0
@@ -100,7 +102,7 @@ var/list/world_uplinks = list()
var/category = split[1]
var/number = text2num(split[2])
- var/list/buyable_items = get_uplink_items()
+ var/list/buyable_items = get_uplink_items(mode_override)
var/list/uplink = buyable_items[category]
if(uplink && uplink.len >= number)
diff --git a/code/modules/events/operative.dm b/code/modules/events/operative.dm
new file mode 100644
index 00000000000..f11961388b7
--- /dev/null
+++ b/code/modules/events/operative.dm
@@ -0,0 +1,80 @@
+/datum/round_event_control/operative
+ name = "Lone Operative"
+ typepath = /datum/round_event/operative
+ weight = 0 //Admin only
+ max_occurrences = 1
+
+/datum/round_event/operative
+ var/key_of_operative
+
+/datum/round_event/operative/proc/get_operative(end_if_fail = 0)
+ key_of_operative = null
+ if(!key_of_operative)
+ var/list/candidates = get_candidates(BE_OPERATIVE)
+ if(!candidates.len)
+ if(end_if_fail)
+ return 0
+ return find_operative()
+ var/client/C = pick(candidates)
+ key_of_operative = C.key
+ if(!key_of_operative)
+ if(end_if_fail)
+ return 0
+ return find_operative()
+ var/datum/mind/player_mind = new /datum/mind(key_of_operative)
+ player_mind.active = 1
+ var/list/spawn_locs = list()
+ for(var/obj/effect/landmark/L in landmarks_list)
+ if(L.name in list("ninjaspawn","carpspawn"))
+ spawn_locs += L.loc
+ if(!spawn_locs.len)
+ return kill()
+
+ var/mob/living/carbon/human/operative = new(pick(spawn_locs))
+ var/datum/preferences/A = new
+ A.copy_to(operative)
+ operative.dna.update_dna_identity()
+
+ operative.equipOutfit(/datum/outfit/syndicate/full)
+
+ var/datum/mind/Mind = new /datum/mind(key_of_operative)
+ Mind.assigned_role = "Lone Operative"
+ Mind.special_role = "Lone Operative"
+ ticker.mode.traitors |= Mind
+ Mind.active = 1
+
+ var/obj/machinery/nuclearbomb/selfdestruct/nuke = locate() in machines
+ if(nuke)
+ var/nuke_code
+ if(!nuke.r_code || nuke.r_code == "ADMIN")
+ nuke_code = "[rand(10000, 99999)]"
+ nuke.r_code = nuke_code
+ else
+ nuke_code = nuke.r_code
+
+ Mind.store_memory("Station Self-Destruct Device Code: [nuke_code]", 0, 0)
+ Mind.current << "The nuclear authorization code is: [nuke_code]"
+
+ var/datum/objective/nuclear/O = new()
+ O.owner = Mind
+ Mind.objectives += O
+
+ Mind.transfer_to(operative)
+
+ message_admins("[key_of_operative] has been made into lone operative by an event.")
+ log_game("[key_of_operative] was spawned as a lone operative by an event.")
+ return 1
+
+/datum/round_event/operative/start()
+ get_operative()
+
+
+/datum/round_event/operative/proc/find_operative()
+ message_admins("Attempted to spawn a operative but there was no players available. Will try again momentarily.")
+ spawn(50)
+ if(get_operative(1))
+ message_admins("Situation has been resolved, [key_of_operative] has been spawned as a operative.")
+ log_game("[key_of_operative] was spawned as a operative by an event.")
+ return 0
+ message_admins("Unfortunately, no candidates were available for becoming a operative. Shutting down.")
+ return kill()
\ No newline at end of file
diff --git a/html/changelogs/AnturK-Loneop.yml b/html/changelogs/AnturK-Loneop.yml
new file mode 100644
index 00000000000..5062aa42403
--- /dev/null
+++ b/html/changelogs/AnturK-Loneop.yml
@@ -0,0 +1,7 @@
+author: AnturK
+
+delete-after: True
+
+changes:
+ - rscadd: "Syndicate Lone Operatives spotted near the nanotrasen stations! Keep the disk safe!"
+ - tweak: "Admin spawned nuclear operatives will now have access to nukeop equipment"
\ No newline at end of file
diff --git a/tgstation.dme b/tgstation.dme
index d4344bc7986..6b79d37fa3f 100644
--- a/tgstation.dme
+++ b/tgstation.dme
@@ -995,6 +995,7 @@
#include "code\modules\events\mass_hallucination.dm"
#include "code\modules\events\meateor_wave.dm"
#include "code\modules\events\meteor_wave.dm"
+#include "code\modules\events\operative.dm"
#include "code\modules\events\prison_break.dm"
#include "code\modules\events\radiation_storm.dm"
#include "code\modules\events\shuttle_loan.dm"