diff --git a/code/modules/mining/equipment_locker.dm b/code/modules/mining/equipment_locker.dm index c821bf84baa..e6a4330943c 100644 --- a/code/modules/mining/equipment_locker.dm +++ b/code/modules/mining/equipment_locker.dm @@ -413,7 +413,7 @@ new /datum/data/mining_equipment("Stabilizing Serum", /obj/item/hivelordstabilizer, 400), new /datum/data/mining_equipment("Space Cash", /obj/item/stack/spacecash/c1000, 2000), new /datum/data/mining_equipment("Point Transfer Card", /obj/item/card/mining_point_card, 500), -// new /datum/data/mining_equipment("Fulton Beacon", /obj/item/fulton_core, 400), + new /datum/data/mining_equipment("Fulton Beacon", /obj/item/fulton_core, 400), new /datum/data/mining_equipment("Shelter Capsule", /obj/item/survivalcapsule, 400), new /datum/data/mining_equipment("GAR Meson Scanners", /obj/item/clothing/glasses/meson/gar, 500), new /datum/data/mining_equipment("Explorer's Webbing", /obj/item/storage/belt/mining, 500), @@ -425,7 +425,7 @@ new /datum/data/mining_equipment("Kinetic Accelerator", /obj/item/gun/energy/kinetic_accelerator, 750), new /datum/data/mining_equipment("Advanced Scanner", /obj/item/t_scanner/adv_mining_scanner, 800), new /datum/data/mining_equipment("Resonator", /obj/item/resonator, 800), -// new /datum/data/mining_equipment("Fulton Pack", /obj/item/extraction_pack, 1000), + new /datum/data/mining_equipment("Fulton Pack", /obj/item/extraction_pack, 1000), new /datum/data/mining_equipment("Lazarus Injector", /obj/item/lazarus_injector, 1000), new /datum/data/mining_equipment("Silver Pickaxe", /obj/item/pickaxe/silver, 1000), new /datum/data/mining_equipment("Mining Conscription Kit", /obj/item/storage/backpack/duffel/mining_conscript, 1500), @@ -602,7 +602,7 @@ ..() /obj/machinery/mineral/equipment_vendor/proc/RedeemVoucher(obj/item/mining_voucher/voucher, mob/redeemer) - var/items = list("Survival Capsule and Explorer's Webbing", "Resonator Kit", "Minebot Kit", "Crusher Kit", "Mining Conscription Kit") + var/items = list("Survival Capsule and Explorer's Webbing", "Resonator Kit", "Minebot Kit", "Extraction and Rescue Kit", "Crusher Kit", "Mining Conscription Kit") var/selection = input(redeemer, "Pick your equipment", "Mining Voucher Redemption") as null|anything in items if(!selection || !Adjacent(redeemer) || QDELETED(voucher) || voucher.loc != redeemer) @@ -619,10 +619,10 @@ new /obj/item/mining_drone_cube(drop_location) new /obj/item/weldingtool/hugetank(drop_location) new /obj/item/clothing/head/welding(drop_location) -// if("Extraction and Rescue Kit") -// new /obj/item/extraction_pack(drop_location) -// new /obj/item/fulton_core(drop_location) -// new /obj/item/stack/marker_beacon/thirty(drop_location) + if("Extraction and Rescue Kit") + new /obj/item/extraction_pack(drop_location) + new /obj/item/fulton_core(drop_location) + new /obj/item/stack/marker_beacon/thirty(drop_location) if("Crusher Kit") new /obj/item/extinguisher/mini(drop_location) new /obj/item/twohanded/required/kinetic_crusher(drop_location) diff --git a/code/modules/mining/fulton.dm b/code/modules/mining/fulton.dm new file mode 100644 index 00000000000..2d09c6a8e7a --- /dev/null +++ b/code/modules/mining/fulton.dm @@ -0,0 +1,195 @@ +GLOBAL_LIST_EMPTY(total_extraction_beacons) + +/obj/item/extraction_pack + name = "fulton extraction pack" + desc = "A balloon that can be used to extract equipment or personnel 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 = WEIGHT_CLASS_NORMAL + 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 = TRUE + var/max_force_fulton = MOVE_FORCE_STRONG + +/obj/item/extraction_pack/examine(mob/user) + ..() + to_chat(user, "It has [uses_left] use\s remaining.") + +/obj/item/extraction_pack/attack_self(mob/user) + var/list/possible_beacons = list() + for(var/B in GLOB.total_extraction_beacons) + var/obj/structure/extraction_point/EP = B + if(EP.beacon_network in beacon_networks) + possible_beacons += EP + + if(!possible_beacons.len) + to_chat(user, "There are no extraction beacons in existence!") + return + + else + var/A + + A = input("Select a beacon to connect to", "Balloon Extraction Pack", A) as null|anything in possible_beacons + + if(!A) + return + beacon = A + to_chat(user, "You link the extraction pack to the beacon system.") + +/obj/item/extraction_pack/afterattack(atom/movable/A, mob/living/carbon/human/user, flag, params) + . = ..() + if(!beacon) + to_chat(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) + to_chat(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)) + to_chat(user, "[src] is not safe for use with living creatures, they wouldn't survive the trip back!") + return + if(!isturf(A.loc)) // no extracting stuff inside other stuff + return + if(A.anchored || (A.move_resist > max_force_fulton)) + return + to_chat(user, "You start attaching the pack to [A]...") + if(do_after(user, 50, target = A)) + to_chat(user, "You attach the pack to [A] and activate it.") + if(loc == user && istype(user.back, /obj/item/storage/backpack)) + var/obj/item/storage/backpack/B = user.back + if(B.can_be_inserted(src, stop_messages = TRUE)) + B.handle_item_insertion(src) + uses_left-- + if(uses_left <= 0) + user.drop_item(src) + forceMove(A) + var/mutable_appearance/balloon + var/mutable_appearance/balloon2 + var/mutable_appearance/balloon3 + if(isliving(A)) + 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 = TRUE + A.density = FALSE + var/obj/effect/extraction_holder/holder_obj = new(A.loc) + holder_obj.appearance = A.appearance + A.forceMove(holder_obj) + balloon2 = mutable_appearance('icons/obj/fulton_balloon.dmi', "fulton_expand") + balloon2.pixel_y = 10 + balloon2.appearance_flags = RESET_COLOR | RESET_ALPHA | RESET_TRANSFORM + holder_obj.add_overlay(balloon2) + sleep(4) + balloon = mutable_appearance('icons/obj/fulton_balloon.dmi', "fulton_balloon") + balloon.pixel_y = 10 + balloon.appearance_flags = RESET_COLOR | RESET_ALPHA | RESET_TRANSFORM + holder_obj.cut_overlay(balloon2) + holder_obj.add_overlay(balloon) + playsound(holder_obj.loc, 'sound/items/fultext_deploy.ogg', 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.ogg', 50, 1, -3) + animate(holder_obj, pixel_z = 1000, time = 30) + if(ishuman(A)) + var/mob/living/carbon/human/L = A + L.SetParalysis(0) + L.drowsyness = 0 + L.SetSleeping(0) + sleep(30) + var/list/flooring_near_beacon = list() + for(var/turf/floor in orange(1, beacon)) + if(floor.density) + continue + flooring_near_beacon += floor + holder_obj.forceMove(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 = mutable_appearance('icons/obj/fulton_balloon.dmi', "fulton_retract") + balloon3.pixel_y = 10 + balloon3.appearance_flags = RESET_COLOR | RESET_ALPHA | RESET_TRANSFORM + holder_obj.cut_overlay(balloon) + holder_obj.add_overlay(balloon3) + sleep(4) + holder_obj.cut_overlay(balloon3) + A.anchored = FALSE // 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.forceMove(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 onto. Activate in hand to create a beacon." + icon = 'icons/obj/stock_parts.dmi' + icon_state = "subspace_amplifier" + +/obj/item/fulton_core/attack_self(mob/user) + if(do_after(user, 15, target = user) && !QDELETED(src)) + new /obj/structure/extraction_point(get_turf(user)) + qdel(src) + +/obj/structure/extraction_point + name = "fulton recovery beacon" + desc = "A beacon for the fulton recovery system. Activate a pack in your hand to link it to a beacon." + icon = 'icons/obj/fulton.dmi' + icon_state = "extraction_point" + anchored = TRUE + density = FALSE + var/beacon_network = "station" + +/obj/structure/extraction_point/New() + ..() + name += " ([rand(100,999)]) ([get_location_name(src)])" + GLOB.total_extraction_beacons += src + +/obj/structure/extraction_point/Destroy() + GLOB.total_extraction_beacons -= src + return ..() + +/obj/effect/extraction_holder + name = "extraction holder" + desc = "you shouldnt see this" + var/atom/movable/stored_obj + +/obj/item/extraction_pack/proc/check_for_living_mobs(atom/A) + if(isliving(A)) + var/mob/living/L = A + if(L.stat != DEAD) + return TRUE + for(var/thing in A.GetAllContents()) + if(isliving(A)) + var/mob/living/L = A + if(L.stat != DEAD) + return TRUE + return FALSE + +/obj/effect/extraction_holder/singularity_pull() + return + +/obj/effect/extraction_holder/singularity_pull() + return \ No newline at end of file diff --git a/code/modules/shuttle/supply.dm b/code/modules/shuttle/supply.dm index b6a7e7bb28f..9da43d08fbf 100644 --- a/code/modules/shuttle/supply.dm +++ b/code/modules/shuttle/supply.dm @@ -247,7 +247,8 @@ /obj/machinery/clonepod, /obj/effect/hierophant, /obj/item/warp_cube, - /obj/machinery/quantumpad + /obj/machinery/quantumpad, + /obj/structure/extraction_point ) if(A) if(is_type_in_list(A, blacklist)) 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/paradise.dme b/paradise.dme index 86eb2825b04..665095fe782 100644 --- a/paradise.dme +++ b/paradise.dme @@ -1641,6 +1641,7 @@ #include "code\modules\mining\coins.dm" #include "code\modules\mining\equipment_locker.dm" #include "code\modules\mining\explorer_gear.dm" +#include "code\modules\mining\fulton.dm" #include "code\modules\mining\machine_processing.dm" #include "code\modules\mining\machine_stacking.dm" #include "code\modules\mining\machine_unloading.dm" diff --git a/sound/items/fultext_deploy.ogg b/sound/items/fultext_deploy.ogg new file mode 100644 index 00000000000..2433b9e0fe3 Binary files /dev/null and b/sound/items/fultext_deploy.ogg differ diff --git a/sound/items/fultext_launch.ogg b/sound/items/fultext_launch.ogg new file mode 100644 index 00000000000..2c874419927 Binary files /dev/null and b/sound/items/fultext_launch.ogg differ