diff --git a/code/__DEFINES/citadel_defines.dm b/code/__DEFINES/citadel_defines.dm
index d6822a37c6..261e7c7586 100644
--- a/code/__DEFINES/citadel_defines.dm
+++ b/code/__DEFINES/citadel_defines.dm
@@ -110,6 +110,11 @@
#define CITADEL_MENTOR_OOC_COLOUR "#224724"
+//xenobio console upgrade stuff
+#define XENOBIO_UPGRADE_MONKEYS 1
+#define XENOBIO_UPGRADE_SLIMEBASIC 2
+#define XENOBIO_UPGRADE_SLIMEADV 4
+
//stamina stuff
#define STAMINA_SOFTCRIT 100 //softcrit for stamina damage. prevents standing up, prevents performing actions that cost stamina, etc, but doesn't force a rest or stop movement
#define STAMINA_CRIT 140 //crit for stamina damage. forces a rest, and stops movement until stamina goes back to stamina softcrit
diff --git a/code/modules/research/xenobiology/xenobio_camera.dm b/code/modules/research/xenobiology/xenobio_camera.dm
index 382fe6beae..b4b626dab2 100644
--- a/code/modules/research/xenobiology/xenobio_camera.dm
+++ b/code/modules/research/xenobiology/xenobio_camera.dm
@@ -49,22 +49,22 @@
/obj/machinery/computer/camera_advanced/xenobio/GrantActions(mob/living/user)
..()
- if(slime_up_action)
+ if(slime_up_action && (upgradetier & XENOBIO_UPGRADE_SLIMEBASIC)) //CIT CHANGE - makes slime-related actions require XENOBIO_UPGRADE_SLIMEBASIC
slime_up_action.target = src
slime_up_action.Grant(user)
actions += slime_up_action
- if(slime_place_action)
+ if(slime_place_action && (upgradetier & XENOBIO_UPGRADE_SLIMEBASIC)) //CIT CHANGE - makes slime-related actions require XENOBIO_UPGRADE_SLIMEBASIC
slime_place_action.target = src
slime_place_action.Grant(user)
actions += slime_place_action
- if(feed_slime_action)
+ if(feed_slime_action && (upgradetier & XENOBIO_UPGRADE_MONKEYS)) //CIT CHANGE - makes monkey-related actions require XENOBIO_UPGRADE_MONKEYS
feed_slime_action.target = src
feed_slime_action.Grant(user)
actions += feed_slime_action
- if(monkey_recycle_action)
+ if(monkey_recycle_action && (upgradetier & XENOBIO_UPGRADE_MONKEYS)) //CIT CHANGE - makes remote monkey recycling require XENOBIO_UPGRADE_MONKEYS
monkey_recycle_action.target = src
monkey_recycle_action.Grant(user)
actions += monkey_recycle_action
@@ -74,18 +74,18 @@
scan_action.Grant(user)
actions += scan_action
- if(potion_action)
+ if(potion_action && (upgradetier & XENOBIO_UPGRADE_SLIMEADV)) // CIT CHANGE - makes giving slimes potions via console require XENOBIO_UPGRADE_SLIMEADV
potion_action.target = src
potion_action.Grant(user)
actions += potion_action
/obj/machinery/computer/camera_advanced/xenobio/attackby(obj/item/O, mob/user, params)
- if(istype(O, /obj/item/reagent_containers/food/snacks/monkeycube))
+ if(istype(O, /obj/item/reagent_containers/food/snacks/monkeycube) && (upgradetier & XENOBIO_UPGRADE_MONKEYS)) //CIT CHANGE - makes monkey-related actions require XENOBIO_UPGRADE_MONKEYS
monkeys++
to_chat(user, "You feed [O] to [src]. It now has [monkeys] monkey cubes stored.")
qdel(O)
return
- else if(istype(O, /obj/item/storage/bag))
+ else if(istype(O, /obj/item/storage/bag) && (upgradetier & XENOBIO_UPGRADE_MONKEYS)) //CIT CHANGE - makes monkey-related actions require XENOBIO_UPGRADE_MONKEYS
var/obj/item/storage/P = O
var/loaded = 0
for(var/obj/G in P.contents)
@@ -96,7 +96,7 @@
if (loaded)
to_chat(user, "You fill [src] with the monkey cubes stored in [O]. [src] now has [monkeys] monkey cubes stored.")
return
- else if(istype(O, /obj/item/slimepotion/slime))
+ else if(istype(O, /obj/item/slimepotion/slime) && (upgradetier & XENOBIO_UPGRADE_SLIMEADV)) // CIT CHANGE - makes giving slimes potions via console require XENOBIO_UPGRADE_SLIMEADV
var/replaced = FALSE
if(user && !user.transferItemToLoc(O, src))
return
diff --git a/modular_citadel/code/modules/research/designs/xenobio_designs.dm b/modular_citadel/code/modules/research/designs/xenobio_designs.dm
new file mode 100644
index 0000000000..45ed8e83a0
--- /dev/null
+++ b/modular_citadel/code/modules/research/designs/xenobio_designs.dm
@@ -0,0 +1,25 @@
+/datum/design/xenobio_upgrade
+ name = "owo"
+ desc = "someone's bussin"
+ build_type = PROTOLATHE
+ materials = list(MAT_METAL = 300, MAT_GLASS = 100)
+ category = list("Electronics")
+ departmental_flags = DEPARTMENTAL_FLAG_SCIENCE
+
+/datum/design/xenobio_upgrade/xenobiomonkeys
+ name = "Xenobiology console monkey upgrade disk"
+ desc = "This disk will add the ability to remotely recycle monkeys via the Xenobiology console."
+ id = "xenobio_monkeys"
+ build_path = /obj/item/disk/xenobio_console_upgrade/monkey
+
+/datum/design/xenobio_upgrade/xenobioslimebasic
+ name = "Xenobiology console basic slime upgrade disk"
+ desc = "This disk will add the ability to remotely manipulate slimes via the Xenobiology console."
+ id = "xenobio_slimebasic"
+ build_path = /obj/item/disk/xenobio_console_upgrade/slimebasic
+
+/datum/design/xenobio_upgrade/xenobioslimeadv
+ name = "Xenobiology console advanced slime upgrade disk"
+ desc = "This disk will add the ability to remotely feed slimes potions via the Xenobiology console, and lift the restrictions on the number of slimes that can be stored inside the Xenobiology console. This includes the contents of the basic slime upgrade disk."
+ id = "xenobio_slimeadv"
+ build_path = /obj/item/disk/xenobio_console_upgrade/slimeadv
diff --git a/modular_citadel/code/modules/research/techweb/all_nodes.dm b/modular_citadel/code/modules/research/techweb/all_nodes.dm
index d8babf011b..9f1cd650b5 100644
--- a/modular_citadel/code/modules/research/techweb/all_nodes.dm
+++ b/modular_citadel/code/modules/research/techweb/all_nodes.dm
@@ -1,3 +1,15 @@
+/datum/techweb_node/bluespace_basic/New()
+ . = ..()
+ design_ids += "xenobio_monkeys"
+
+/datum/techweb_node/practical_bluespace/New()
+ . = ..()
+ design_ids += "xenobio_slimebasic"
+
+/datum/techweb_node/adv_bluespace/New()
+ . = ..()
+ design_ids += "xenobio_slimeadv"
+
/datum/techweb_node/computer_board_gaming
id = "computer_board_gaming"
display_name = "Games and Toys"
diff --git a/modular_citadel/code/modules/research/xenobiology/xenobio_camera.dm b/modular_citadel/code/modules/research/xenobiology/xenobio_camera.dm
new file mode 100644
index 0000000000..b700626a1d
--- /dev/null
+++ b/modular_citadel/code/modules/research/xenobiology/xenobio_camera.dm
@@ -0,0 +1,48 @@
+/obj/machinery/computer/camera_advanced/xenobio
+ max_slimes = 1
+ var/upgradetier = 0
+
+/obj/machinery/computer/camera_advanced/xenobio/attackby(obj/item/O, mob/user, params)
+ if(istype(O, /obj/item/disk/xenobio_console_upgrade))
+ var/obj/item/disk/xenobio_console_upgrade/diskthing = O
+ var/successfulupgrade = FALSE
+ for(var/I in diskthing.upgradetypes)
+ if(upgradetier & I)
+ continue
+ else
+ upgradetier |= I
+ successfulupgrade = TRUE
+ if(I == XENOBIO_UPGRADE_SLIMEADV)
+ max_slimes = 10
+ if(successfulupgrade)
+ to_chat(user, "You have successfully upgraded [src] with [O].")
+ else
+ to_chat(user, "[src] already has the contents of [O] installed!")
+ return
+ . = ..()
+
+/obj/item/disk/xenobio_console_upgrade
+ name = "Xenobiology console upgrade disk"
+ desc = "Allan please add detail."
+ icon_state = "datadisk5"
+ var/list/upgradetypes = list()
+
+/obj/item/disk/xenobio_console_upgrade/admin
+ name = "Xenobio all access thing"
+ desc = "'the consoles are literally useless!!!!!!!!!!!!!!!'"
+ upgradetypes = list(XENOBIO_UPGRADE_SLIMEBASIC, XENOBIO_UPGRADE_SLIMEADV, XENOBIO_UPGRADE_MONKEYS)
+
+/obj/item/disk/xenobio_console_upgrade/monkey
+ name = "Xenobiology console monkey upgrade disk"
+ desc = "This disk will add the ability to remotely recycle monkeys via the Xenobiology console."
+ upgradetypes = list(XENOBIO_UPGRADE_MONKEYS)
+
+/obj/item/disk/xenobio_console_upgrade/slimebasic
+ name = "Xenobiology console basic slime upgrade disk"
+ desc = "This disk will add the ability to remotely manipulate slimes via the Xenobiology console."
+ upgradetypes = list(XENOBIO_UPGRADE_SLIMEBASIC)
+
+/obj/item/disk/xenobio_console_upgrade/slimeadv
+ name = "Xenobiology console advanced slime upgrade disk"
+ desc = "This disk will add the ability to remotely feed slimes potions via the Xenobiology console, and lift the restrictions on the number of slimes that can be stored inside the Xenobiology console. This includes the contents of the basic slime upgrade disk."
+ upgradetypes = list(XENOBIO_UPGRADE_SLIMEBASIC, XENOBIO_UPGRADE_SLIMEADV)
diff --git a/tgstation.dme b/tgstation.dme
index b52ba0bc2f..295a352612 100755
--- a/tgstation.dme
+++ b/tgstation.dme
@@ -2757,8 +2757,10 @@
#include "modular_citadel\code\modules\recycling\disposal\bin.dm"
#include "modular_citadel\code\modules\research\designs\autoylathe_designs.dm"
#include "modular_citadel\code\modules\research\designs\machine_designs.dm"
+#include "modular_citadel\code\modules\research\designs\xenobio_designs.dm"
#include "modular_citadel\code\modules\research\techweb\_techweb.dm"
#include "modular_citadel\code\modules\research\techweb\all_nodes.dm"
+#include "modular_citadel\code\modules\research\xenobiology\xenobio_camera.dm"
#include "modular_citadel\code\modules\uplink\uplink_items.dm"
#include "modular_citadel\code\modules\vore\hook-defs_vr.dm"
#include "modular_citadel\code\modules\vore\persistence.dm"