diff --git a/code/game/objects/items/stacks/sheets/sheet_types.dm b/code/game/objects/items/stacks/sheets/sheet_types.dm
index 95efb496eca..8f3da041c7a 100644
--- a/code/game/objects/items/stacks/sheets/sheet_types.dm
+++ b/code/game/objects/items/stacks/sheets/sheet_types.dm
@@ -68,6 +68,9 @@ var/global/list/datum/stack_recipe/metal_recipes = list ( \
/obj/item/stack/sheet/metal/fifty
amount = 50
+/obj/item/stack/sheet/metal/five
+ amount = 5
+
/obj/item/stack/sheet/metal/cyborg
materials = list()
is_cyborg = 1
diff --git a/code/modules/mining/fulton.dm b/code/modules/mining/fulton.dm
new file mode 100644
index 00000000000..09c612b4f18
--- /dev/null
+++ b/code/modules/mining/fulton.dm
@@ -0,0 +1,188 @@
+var/list/total_extraction_beacons = list()
+
+/obj/item/weapon/extraction_pack
+ name = "fulton material extraction pack"
+ desc = "A balloon that can be used to extract a target to a Fulton Recovery Beacon. Anything not bolted down can be moved. Link the pack to a beacon by using the pack in hand."
+ icon = 'icons/obj/fulton.dmi'
+ icon_state = "extraction_pack"
+ w_class = 3
+ var/obj/structure/extraction_point/beacon
+ var/list/beacon_networks = list("station")
+ var/uses_left = 3
+ var/can_use_indoors
+ var/safe_for_living_creatures = 0
+
+/obj/item/weapon/extraction_pack/medivac
+ name = "fulton medivac extraction pack"
+ desc = "A specialized extraction balloon capable of safely extracting living targets."
+ uses_left = 1
+ safe_for_living_creatures = 1
+
+/obj/item/weapon/extraction_pack/examine()
+ . = ..()
+ usr.show_message("It has [uses_left] uses remaining.", 1)
+
+/obj/item/weapon/extraction_pack/attack_self(mob/user)
+ var/list/possible_beacons = list()
+ for(var/B in total_extraction_beacons)
+ var/obj/structure/extraction_point/EP = B
+ if(EP.beacon_network in beacon_networks)
+ possible_beacons += EP
+
+ if(!possible_beacons.len)
+ user << "There are no extraction beacons in existance!"
+ return
+
+ else
+ var/A
+
+ A = input("Select a beacon to connect to", "Balloon Extraction Pack", A) in possible_beacons
+
+ if(!A)
+ return
+ beacon = A
+
+/obj/item/weapon/extraction_pack/afterattack(atom/movable/A, mob/living/carbon/human/user, flag, params)
+ if(!beacon)
+ user << "[src] is not linked to a beacon, and cannot be used."
+ return
+ if(!can_use_indoors)
+ var/area/area = get_area(A)
+ if(!area.outdoors)
+ user << "[src] can only be used on things that are outdoors!"
+ return
+ if(!flag)
+ return
+ if(!istype(A))
+ return
+ else
+ if(!safe_for_living_creatures && check_for_living_mobs(A))
+ user << "[src] is not safe for use with living creatures, they wouldn't survive the trip back!"
+ if(A.loc == user || A == user) // no extracting stuff you're holding in your hands/yourself
+ return
+ if(A.anchored)
+ return
+ user << "You start attaching the pack to [A]..."
+ if(do_after(user,50,target=A))
+ user << "You attach the pack to [A] and activate it."
+ uses_left--
+ if(uses_left <= 0)
+ user.drop_item(src)
+ loc = A
+ var/image/balloon
+ var/image/balloon2
+ var/image/balloon3
+ if(istype(A, /mob/living))
+ var/mob/living/M = A
+ M.Weaken(16) // Keep them from moving during the duration of the extraction
+ M.buckled = 0 // Unbuckle them to prevent anchoring problems
+ else
+ A.anchored = 1
+ A.density = 0
+ var/obj/effect/extraction_holder/holder_obj = new(A.loc)
+ holder_obj.appearance = A.appearance
+ A.loc = holder_obj
+ balloon2 = image('icons/obj/fulton_balloon.dmi',"fulton_expand")
+ balloon2.pixel_y = 10
+ balloon2.appearance_flags = RESET_COLOR | RESET_ALPHA | RESET_TRANSFORM
+ holder_obj.overlays += balloon2
+ sleep(4)
+ balloon = image('icons/obj/fulton_balloon.dmi',"fulton_balloon")
+ balloon.pixel_y = 10
+ balloon.appearance_flags = RESET_COLOR | RESET_ALPHA | RESET_TRANSFORM
+ holder_obj.overlays -= balloon2
+ holder_obj.overlays += balloon
+ playsound(holder_obj.loc, 'sound/items/fulext_deploy.wav', 50, 1, -3)
+ animate(holder_obj, pixel_z = 10, time = 20)
+ sleep(20)
+ animate(holder_obj, pixel_z = 15, time = 10)
+ sleep(10)
+ animate(holder_obj, pixel_z = 10, time = 10)
+ sleep(10)
+ animate(holder_obj, pixel_z = 15, time = 10)
+ sleep(10)
+ animate(holder_obj, pixel_z = 10, time = 10)
+ sleep(10)
+ playsound(holder_obj.loc, 'sound/items/fultext_launch.wav', 50, 1, -3)
+ animate(holder_obj, pixel_z = 1000, time = 30)
+ if(istype(A, /mob/living/carbon/human))
+ var/mob/living/carbon/human/L = A
+ L.SetParalysis(0)
+ L.drowsyness = 0
+ L.sleeping = 0
+ sleep(30)
+ var/list/flooring_near_beacon = list()
+ for(var/turf/open/floor in orange(1, beacon))
+ flooring_near_beacon += floor
+ holder_obj.loc = pick(flooring_near_beacon)
+ animate(holder_obj, pixel_z = 10, time = 50)
+ sleep(50)
+ animate(holder_obj, pixel_z = 15, time = 10)
+ sleep(10)
+ animate(holder_obj, pixel_z = 10, time = 10)
+ sleep(10)
+ balloon3 = image('icons/obj/fulton_balloon.dmi',"fulton_retract")
+ balloon3.pixel_y = 10
+ balloon3.appearance_flags = RESET_COLOR | RESET_ALPHA | RESET_TRANSFORM
+ holder_obj.overlays -= balloon
+ holder_obj.overlays += balloon3
+ sleep(4)
+ holder_obj.overlays -= balloon3
+ A.anchored = 0 // An item has to be unanchored to be extracted in the first place.
+ A.density = initial(A.density)
+ animate(holder_obj, pixel_z = 0, time = 5)
+ sleep(5)
+ A.loc = holder_obj.loc
+ qdel(holder_obj)
+ if(uses_left <= 0)
+ qdel(src)
+
+
+/obj/item/fulton_core
+ name = "extraction beacon signaller"
+ desc = "Emits a signal which fulton recovery devices can lock on to. Craft with metal to create a beacon."
+ icon = 'icons/obj/stock_parts.dmi'
+ icon_state = "subspace_amplifier"
+
+/datum/crafting_recipe/fulton
+ name = "Fulton Recovery Beacon"
+ result = /obj/structure/extraction_point
+ reqs = list(/obj/item/fulton_core = 1, /obj/item/stack/sheet/metal = 5)
+ time = 15
+ category = CAT_MISC
+
+/obj/structure/extraction_point
+ name = "fulton recovery beacon"
+ desc = "A beacon for the fulton recovery system. Hit a beacon with a pack to link the pack to a beacon."
+ icon = 'icons/obj/fulton.dmi'
+ icon_state = "extraction_point"
+ anchored = 1
+ density = 0
+ var/beacon_network = "station"
+
+/obj/structure/extraction_point/New()
+ var/area/area_name = get_area(src)
+ name += " ([rand(100,999)]) ([area_name.name])"
+ total_extraction_beacons += src
+ ..()
+
+/obj/structure/extraction_point/Destroy()
+ total_extraction_beacons -= src
+ ..()
+
+/obj/effect/extraction_holder
+ name = "extraction holder"
+ desc = "you shouldnt see this"
+ var/atom/movable/stored_obj
+
+/obj/item/weapon/extraction_pack/proc/check_for_living_mobs(atom/A)
+ if(istype(A, /mob/living))
+ var/mob/living/L = A
+ if(L.stat != DEAD)
+ return 1
+ for(var/thing in A.GetAllContents())
+ if(istype(A, /mob/living))
+ var/mob/living/L = A
+ if(L.stat != DEAD)
+ return 1
+ return 0
\ No newline at end of file
diff --git a/code/modules/mining/machine_vending.dm b/code/modules/mining/machine_vending.dm
index 17f2c8c2668..c2644d89b95 100644
--- a/code/modules/mining/machine_vending.dm
+++ b/code/modules/mining/machine_vending.dm
@@ -19,6 +19,7 @@
new /datum/data/mining_equipment("Alien Toy", /obj/item/clothing/mask/facehugger/toy, 300),
new /datum/data/mining_equipment("Advanced Scanner", /obj/item/device/t_scanner/adv_mining_scanner, 800),
new /datum/data/mining_equipment("Hivelord Stabilizer", /obj/item/weapon/hivelordstabilizer , 400),
+ new /datum/data/mining_equipment("Fulton Beacon", /obj/item/fulton_core , 400),
new /datum/data/mining_equipment("Shelter Capsule", /obj/item/weapon/survivalcapsule , 400),
new /datum/data/mining_equipment("GAR scanners", /obj/item/clothing/glasses/meson/gar, 500),
new /datum/data/mining_equipment("Explorer's Webbing", /obj/item/weapon/storage/belt/mining, 500),
@@ -28,6 +29,8 @@
new /datum/data/mining_equipment("Jaunter", /obj/item/device/wormhole_jaunter, 750),
new /datum/data/mining_equipment("Kinetic Accelerator", /obj/item/weapon/gun/energy/kinetic_accelerator, 750),
new /datum/data/mining_equipment("Resonator", /obj/item/weapon/resonator, 800),
+ new /datum/data/mining_equipment("Medivac Balloon", /obj/item/weapon/extraction_pack/medivac, 800),
+ new /datum/data/mining_equipment("Fulton Pack", /obj/item/weapon/extraction_pack, 1000),
new /datum/data/mining_equipment("Lazarus Injector", /obj/item/weapon/lazarus_injector, 1000),
new /datum/data/mining_equipment("Silver Pickaxe", /obj/item/weapon/pickaxe/silver, 1000),
new /datum/data/mining_equipment("Jetpack Upgrade", /obj/item/hardsuit_jetpack, 2000),
@@ -155,20 +158,28 @@
return ..()
/obj/machinery/mineral/equipment_vendor/proc/RedeemVoucher(obj/item/weapon/mining_voucher/voucher, mob/redeemer)
- var/selection = input(redeemer, "Pick your equipment", "Mining Voucher Redemption") as null|anything in list("Survival Capsule and Explorer's Webbing", "Resonator", "Mining Drone", "Advanced Scanner")
+ var/selection = input(redeemer, "Pick your equipment", "Mining Voucher Redemption") as null|anything in list("Survival Capsule and Explorer's Webbing", "Resonator and Advanced Scanner", "Mining Drone", "Medivac Kit", "Extraction Kit")
if(!selection || !Adjacent(redeemer) || qdeleted(voucher) || voucher.loc != redeemer)
return
switch(selection)
if("Survival Capsule and Explorer's Webbing")
new /obj/item/weapon/storage/belt/mining(src.loc)
new /obj/item/weapon/survivalcapsule(src.loc)
- if("Resonator")
+ if("Resonator and Advanced Scanner")
new /obj/item/weapon/resonator(src.loc)
+ new /obj/item/device/t_scanner/adv_mining_scanner(src.loc)
if("Mining Drone")
new /mob/living/simple_animal/hostile/mining_drone(src.loc)
new /obj/item/weapon/weldingtool/hugetank(src.loc)
- if("Advanced Scanner")
- new /obj/item/device/t_scanner/adv_mining_scanner(src.loc)
+ if("Medivac Kit")
+ new /obj/item/stack/sheet/metal/five(loc)
+ new /obj/item/fulton_core(loc)
+ new /obj/item/weapon/extraction_pack/medivac(loc)
+ new /obj/item/weapon/reagent_containers/hypospray/medipen/survival(loc)
+ if("Extraction Kit")
+ new /obj/item/stack/sheet/metal/five(loc)
+ new /obj/item/weapon/extraction_pack(loc)
+ new /obj/item/fulton_core(loc)
feedback_add_details("mining_voucher_redeemed", selection)
qdel(voucher)
diff --git a/icons/obj/fulton.dmi b/icons/obj/fulton.dmi
new file mode 100644
index 00000000000..c56c275b3b1
Binary files /dev/null and b/icons/obj/fulton.dmi differ
diff --git a/icons/obj/fulton_balloon.dmi b/icons/obj/fulton_balloon.dmi
new file mode 100644
index 00000000000..5a1fa98e148
Binary files /dev/null and b/icons/obj/fulton_balloon.dmi differ
diff --git a/sound/items/fulext_deploy.wav b/sound/items/fulext_deploy.wav
new file mode 100644
index 00000000000..9fbcb7e3f85
Binary files /dev/null and b/sound/items/fulext_deploy.wav differ
diff --git a/sound/items/fultext_launch.wav b/sound/items/fultext_launch.wav
new file mode 100644
index 00000000000..a623a89ada4
Binary files /dev/null and b/sound/items/fultext_launch.wav differ
diff --git a/tgstation.dme b/tgstation.dme
index b0ab0ac29f6..b4e0e9dad69 100644
--- a/tgstation.dme
+++ b/tgstation.dme
@@ -1224,6 +1224,7 @@
#include "code\modules\lighting\lighting_system.dm"
#include "code\modules\mining\abandoned_crates.dm"
#include "code\modules\mining\equipment.dm"
+#include "code\modules\mining\fulton.dm"
#include "code\modules\mining\machine_input_output_plates.dm"
#include "code\modules\mining\machine_processing.dm"
#include "code\modules\mining\machine_redemption.dm"