diff --git a/code/modules/admin/game_master/game_master.dm b/code/modules/admin/game_master/game_master.dm
index b3502c3322..b589df55e9 100644
--- a/code/modules/admin/game_master/game_master.dm
+++ b/code/modules/admin/game_master/game_master.dm
@@ -58,6 +58,7 @@ GLOBAL_VAR_INIT(radio_communication_clarity, 100)
var/list/submenu_types = list(
/obj/structure/pipes/vents = /datum/game_master_submenu/ambush/vents,
/obj/structure/tunnel = /datum/game_master_submenu/ambush/tunnels,
+ /mob/living/carbon/human = /datum/game_master_submenu/infest,
)
/// List of current submenus
diff --git a/code/modules/admin/game_master/game_master_submenu/infest.dm b/code/modules/admin/game_master/game_master_submenu/infest.dm
new file mode 100644
index 0000000000..4d64e66e0b
--- /dev/null
+++ b/code/modules/admin/game_master/game_master_submenu/infest.dm
@@ -0,0 +1,97 @@
+#define DEFAULT_SPAWN_HIVE_STRING XENO_HIVE_NORMAL
+
+/datum/game_master_submenu/infest
+ tgui_menu_name = "GameMasterSubmenuInfest"
+ tgui_menu_title = "Infest Control"
+
+ /// Current selected hive for the embryo
+ var/selected_hive = DEFAULT_SPAWN_HIVE_STRING
+
+ /// Target growth stage for the embryo
+ var/embryo_stage = 0
+
+/datum/game_master_submenu/infest/ui_data(mob/user)
+ . = ..()
+
+ var/list/data = list()
+
+ data["selected_hive"] = selected_hive
+ data["embryo_stage"] = embryo_stage
+
+ return data
+
+/datum/game_master_submenu/infest/ui_static_data(mob/user)
+ . = ..()
+
+ var/list/data = list()
+
+ data["selectable_hives"] = ALL_XENO_HIVES
+
+ return data
+
+/datum/game_master_submenu/infest/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state)
+ . = ..()
+
+ switch(action)
+ if("set_selected_hive")
+ selected_hive = params["new_hive"]
+ return TRUE
+
+ if("set_embryo_stage")
+ embryo_stage = params["stage"]
+ return TRUE
+
+ if("infest")
+ setup_embryo()
+ return TRUE
+
+ if("clear_infest")
+ remove_embryo()
+ return TRUE
+
+ if("burst")
+ force_burst()
+ return TRUE
+
+/datum/game_master_submenu/infest/proc/setup_embryo()
+ var/obj/item/alien_embryo/infesting_embryo
+ for(var/obj/item/alien_embryo/embryo in referenced_atom) //if this hive's embryo already exists, convert to larva and use it
+ if(embryo.hivenumber == selected_hive)
+ infesting_embryo = embryo
+ else
+ qdel(embryo)
+
+ if(!infesting_embryo) //else, make a new one
+ infesting_embryo = new /obj/item/alien_embryo(referenced_atom)
+ infesting_embryo.hivenumber = selected_hive
+
+ var/mob/living/carbon/human/infested_host = referenced_atom
+ infested_host.species?.larva_impregnated(infesting_embryo) //Yautja handling
+
+ infesting_embryo.stage = embryo_stage
+
+/datum/game_master_submenu/infest/proc/remove_embryo()
+ for(var/obj/item/alien_embryo/embryo in referenced_atom)
+ qdel(embryo)
+
+/datum/game_master_submenu/infest/proc/force_burst()
+ var/mob/living/carbon/xenomorph/larva/infesting_larva = locate() in referenced_atom //if a larva already exists, use it
+ if(infesting_larva)
+ infesting_larva.chest_burst(referenced_atom)
+ return
+
+ for(var/obj/item/alien_embryo/embryo in referenced_atom) //else if this hive's embryo already exists, convert to larva and use it
+ if(embryo.hivenumber == selected_hive)
+ embryo.become_larva()
+ infesting_larva = locate() in referenced_atom
+ break
+ if(infesting_larva)
+ infesting_larva.chest_burst(referenced_atom)
+ return
+
+ infesting_larva = new /mob/living/carbon/xenomorph/larva(referenced_atom, null, selected_hive) //else, make a new larva
+ var/mob/living/carbon/human/infested_host = referenced_atom
+ infesting_larva.ckey = infested_host.ckey
+ infesting_larva.chest_burst(referenced_atom)
+
+#undef DEFAULT_SPAWN_HIVE_STRING
diff --git a/colonialmarines.dme b/colonialmarines.dme
index 276767ade3..52bb268b5b 100644
--- a/colonialmarines.dme
+++ b/colonialmarines.dme
@@ -1390,6 +1390,7 @@
#include "code\modules\admin\game_master\extra_buttons\toggle_join_xeno.dm"
#include "code\modules\admin\game_master\extra_buttons\toggle_vehicle_blockers.dm"
#include "code\modules\admin\game_master\game_master_submenu\ambush.dm"
+#include "code\modules\admin\game_master\game_master_submenu\infest.dm"
#include "code\modules\admin\game_master\game_master_submenu\tunnels.dm"
#include "code\modules\admin\game_master\game_master_submenu\vents.dm"
#include "code\modules\admin\medal_panel\medals_panel.dm"
diff --git a/tgui/packages/tgui/interfaces/GameMasterSubmenuInfest.js b/tgui/packages/tgui/interfaces/GameMasterSubmenuInfest.js
new file mode 100644
index 0000000000..05514969d2
--- /dev/null
+++ b/tgui/packages/tgui/interfaces/GameMasterSubmenuInfest.js
@@ -0,0 +1,85 @@
+import { useBackend } from '../backend';
+import { Stack, Dropdown, Button, Section, Slider } from '../components';
+import { Window } from '../layouts';
+
+export const GameMasterSubmenuInfest = (props, context) => {
+ const { data, act } = useBackend(context);
+
+ return (
+
+
+
+
+
+
+
+ );
+};
+
+export const GameMasterSubmenuInfestInfestingPanel = (props, context) => {
+ const { data, act } = useBackend(context);
+
+ return (
+
+
+
+
+
+ {
+ act('set_selected_hive', { new_hive });
+ }}
+ />
+
+
+
+ Embryo Stage
+
+ {
+ act('set_embryo_stage', { stage });
+ }}
+ />
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+};